xref: /csrg-svn/old/as.vax/asparse.c (revision 15235)
1 /*
2  *	Copyright (c) 1982 Regents of the University of California
3  */
4 #ifndef lint
5 static char sccsid[] = "@(#)asparse.c 4.18 10/14/83";
6 #endif not lint
7 
8 #include <stdio.h>
9 #include "as.h"
10 #include "asscan.h"
11 #include "assyms.h"
12 #include "asexpr.h"
13 
14 int	lgensym[10];
15 char	genref[10];
16 
17 long	bitfield;
18 int	bitoff;
19 int	curlen;			/* current length of literals */
20 
21 /*
22  *	The following three variables are communication between various
23  *	modules to special case a number of things.  They are properly
24  *	categorized as hacks.
25  */
26 extern	struct	symtab *lastnam;/*last name seen by the lexical analyzer*/
27 int	exprisname;		/*last factor in an expression was a name*/
28 int	droppedLP;		/*one is analyzing an expression beginning with*/
29 				/*a left parenthesis, which has already been*/
30 				/*shifted. (Used to parse (<expr>)(rn)*/
31 
32 char	yytext[NCPName+2];	/*the lexical image*/
33 int	yylval;			/*the lexical value; sloppy typing*/
34 struct	Opcode		yyopcode;	/* lexical value for an opcode */
35 Bignum	yybignum;		/* lexical value for a big number */
36 /*
37  *	Expression and argument managers
38  */
39 struct	exp	*xp;		/*next free expression slot, used by expr.c*/
40 struct	exp	explist[NEXP];	/*max of 20 expressions in one opcode*/
41 struct	arg	arglist[NARG];	/*building up operands in instructions*/
42 /*
43  *	Sets to accelerate token discrimination
44  */
45 char	tokensets[(LASTTOKEN) - (FIRSTTOKEN) + 1];
46 
47 static	char	UDotsname[64];	/*name of the assembly source*/
48 
49 yyparse()
50 {
51 	reg	struct	exp	*locxp;
52 		/*
53 		 *	loc1xp and ptrloc1xp are used in the
54 		 * 	expression lookahead
55 		 */
56 		struct	exp	*loc1xp;	/*must be non register*/
57 		struct	exp	**ptrloc1xp = & loc1xp;
58 		struct	exp	*pval;		/*hacking expr:expr*/
59 
60 	reg	struct	symtab	*np;
61 	reg	int		argcnt;
62 
63 	reg	inttoktype	val;		/*what yylex gives*/
64 	reg	inttoktype	auxval;		/*saves val*/
65 
66 	reg	struct 	arg	*ap;		/*first free argument*/
67 
68 	reg	struct	symtab	*p;
69 	reg	struct	symtab	*stpt;
70 
71 		struct	strdesc *stringp;	/*handles string lists*/
72 
73 		int	regno;		/*handles arguments*/
74 		int	*ptrregno = &regno;
75 		int	sawmul;		/*saw * */
76 		int	sawindex;	/*saw [rn]*/
77 		int	sawsize;
78 		int	seg_type; 	/*the kind of segment: data or text*/
79 		int	seg_number;	/*the segment number*/
80 		int	space_value;	/*how much .space needs*/
81 		int	fill_rep;	/*how many reps for .fill */
82 		int	fill_size;	/*how many bytes for .fill */
83 
84 		int	field_width;	/*how wide a field is to be*/
85 		int	field_value;	/*the value to stuff in a field*/
86 		char	*stabname;	/*name of stab dealing with*/
87 		ptrall	stabstart;	/*where the stab starts in the buffer*/
88 		int	reloc_how;	/* how to relocate expressions */
89 		int	toconv;		/* how to convert bignums */
90 		int	incasetable;	/* set if in a case table */
91 
92 	incasetable = 0;
93 	xp = explist;
94 	ap = arglist;
95 
96 	val = yylex();
97 
98     while (val != PARSEEOF){	/* primary loop */
99 
100 	while (INTOKSET(val, LINSTBEGIN)){
101 		if (val == INT) {
102 			int i = ((struct exp *)yylval)->e_xvalue;
103 			shift;
104 			if (val != COLON){
105 				yyerror("Local label %d is not followed by a ':' for a label definition",
106 					i);
107 				goto  errorfix;
108 			}
109 			if (i < 0 || i > 9) {
110 				yyerror("Local labels are 0-9");
111 				goto errorfix;
112 			}
113 			(void)sprintf(yytext, "L%d\001%d", i, lgensym[i]);
114 			lgensym[i]++;
115 			genref[i] = 0;
116 			yylval = (int)*lookup(passno == 1);
117 			val = NAME;
118 			np = (struct symtab *)yylval;
119 			goto restlab;
120 		}
121 		if (val == NL){
122 			lineno++;
123 			shift;
124 		} else
125 		if (val == SEMI)
126 			shift;
127 		else {	/*its a name, so we have a label or def */
128 			if (val != NAME){
129 				ERROR("Name expected for a label");
130 			}
131 			np = (struct symtab *)yylval;
132 			shiftover(NAME);
133 			if (val != COLON) {
134 				yyerror("\"%s\" is not followed by a ':' for a label definition",
135 					FETCHNAME(np));
136 				goto  errorfix;
137 			}
138 restlab:
139 			shift;
140 			flushfield(NBPW/4);
141 			if ((np->s_type&XTYPE)!=XUNDEF) {
142 				if (  (np->s_type&XTYPE) != dotp->e_xtype
143 				   || np->s_value != dotp->e_xvalue
144 				   || (   passno == 1
145 				       && np->s_index != dotp->e_xloc) ) {
146 					if (passno == 1)
147 						yyerror("%s redefined",
148 							FETCHNAME(np));
149 					else
150 						yyerror("%s redefined: PHASE ERROR, 1st: %d, 2nd: %d",
151 							FETCHNAME(np),
152 							np->s_value,
153 							dotp->e_xvalue);
154 				}
155 			}
156 			np->s_type &= ~(XTYPE|XFORW);
157 			np->s_type |= dotp->e_xtype;
158 			np->s_value = dotp->e_xvalue;
159 			if (passno == 1){
160 				np->s_index = dotp-usedot;
161 				if (FETCHNAME(np)[0] == 'L'){
162 					nlabels++;
163 				}
164 				np->s_tag = LABELID;
165 			}
166 		}	/*end of this being a label*/
167 	}	/*end of consuming all labels, NLs and SEMIS */
168 
169 	xp = explist;
170 	ap = arglist;
171 
172 	/*
173 	 *	process the INSTRUCTION body
174 	 */
175 	switch(val){
176 
177     default:
178 	ERROR("Unrecognized instruction or directive");
179 
180    case IABORT:
181 	shift;
182 	sawabort();
183 	/*NOTREACHED*/
184 	break;
185 
186    case PARSEEOF:
187 	tokptr -= sizeof(bytetoktype);
188 	*tokptr++ = VOID;
189 	tokptr[1] = VOID;
190 	tokptr[2] = PARSEEOF;
191 	break;
192 
193    case IFILE:
194 	shift;
195 	stringp = (struct strdesc *)yylval;
196 	shiftover(STRING);
197 	dotsname = &UDotsname[0];
198 	movestr(dotsname, stringp->sd_string,
199 		min(stringp->sd_strlen, sizeof(UDotsname)));
200 	break;
201 
202    case ILINENO:
203 	shift;		/*over the ILINENO*/
204 	expr(locxp, val);
205 	lineno = locxp->e_xvalue;
206 	break;
207 
208    case ISET: 	/* .set  <name> , <expr> */
209 	shift;
210 	np = (struct symtab *)yylval;
211 	shiftover(NAME);
212 	shiftover(CM);
213 	expr(locxp, val);
214 	np->s_type &= (XXTRN|XFORW);
215 	np->s_type |= locxp->e_xtype&(XTYPE|XFORW);
216 	np->s_value = locxp->e_xvalue;
217 	if (passno==1)
218 		np->s_index = locxp->e_xloc;
219 	if ((locxp->e_xtype&XTYPE) == XUNDEF)
220 		yyerror("Illegal set?");
221 	break;
222 
223    case ILSYM: 	/*.lsym name , expr */
224 	shift;
225 	np = (struct symtab *)yylval;
226 	shiftover(NAME);
227 	shiftover(CM);
228 	expr(locxp, val);
229 	/*
230 	 *	Build the unique occurance of the
231 	 *	symbol.
232 	 *	The character scanner will have
233 	 *	already entered it into the symbol
234 	 *	table, but we should remove it
235 	 */
236 	if (passno == 1){
237 		stpt = (struct symtab *)symalloc();
238 		stpt->s_name = np->s_name;
239 		np->s_tag = OBSOLETE;	/*invalidate original */
240 		nforgotten++;
241 		np = stpt;
242 		if ( (locxp->e_xtype & XTYPE) != XABS)
243 			yyerror("Illegal second argument to lsym");
244 		np->s_value = locxp->e_xvalue;
245 		np->s_type = XABS;
246 		np->s_tag = ILSYM;
247 	}
248 	break;
249 
250    case IGLOBAL: 	/*.globl <name> */
251 	shift;
252 	np = (struct symtab *)yylval;
253 	shiftover(NAME);
254 	np->s_type |= XXTRN;
255 	break;
256 
257    case IDATA: 	/*.data [ <expr> ] */
258    case ITEXT: 	/*.text [ <expr> ] */
259 	seg_type = -val;
260 	shift;
261 	if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){
262 		expr(locxp, val);
263 		seg_type = -seg_type;   /*now, it is positive*/
264 	}
265 
266 	if (seg_type < 0) {	/*there wasn't an associated expr*/
267 		seg_number = 0;
268 		seg_type = -seg_type;
269 	} else {
270 		if (   ((locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
271 		    || (seg_number = locxp->e_xvalue) >= NLOC) {
272 			yyerror("illegal location counter");
273 			seg_number = 0;
274 		}
275 	}
276 	if (seg_type == IDATA)
277 		seg_number += NLOC;
278 	flushfield(NBPW/4);
279 	dotp = &usedot[seg_number];
280 	if (passno==2) {	/* go salt away in pass 2*/
281 		txtfil = usefile[seg_number];
282 		relfil = rusefile[seg_number];
283 	}
284 	break;
285 
286 	/*
287 	 *	Storage filler directives:
288 	 *
289 	 *	.byte	[<exprlist>]
290 	 *
291 	 *	exprlist:  empty | exprlist outexpr
292 	 *	outexpr:   <expr> | <expr> : <expr>
293 	 */
294    case IBYTE:	curlen = NBPW/4; goto elist;
295    case IWORD:	curlen = NBPW/2; goto elist;
296    case IINT:	curlen = NBPW;   goto elist;
297    case ILONG:	curlen = NBPW;   goto elist;
298 
299    elist:
300 	seg_type = val;
301 	shift;
302 
303 	/*
304 	 *	Expression List processing
305 	 */
306 	if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){
307 	    do{
308 		/*
309 		 *	expression list consists of a list of :
310 		 *	<expr>
311 		 *	<expr> : <expr>
312 		 *		(pack expr2 into expr1 bits
313 		 */
314 		expr(locxp, val);
315 		/*
316 		 *	now, pointing at the next token
317 		 */
318 		if (val == COLON){
319 			shiftover(COLON);
320 			expr(pval, val);
321 			if ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */
322 				yyerror("Width not absolute");
323 			field_width = locxp->e_xvalue;
324 			locxp = pval;
325 			if (bitoff + field_width > curlen)
326 				flushfield(curlen);
327 			if (field_width > curlen)
328 				yyerror("Expression crosses field boundary");
329 		} else {
330 			field_width = curlen;
331 			flushfield(curlen);
332 		}
333 
334 		if ((locxp->e_xtype & XTYPE) != XABS) {
335 			if (bitoff)
336 				yyerror("Illegal relocation in field");
337 			switch(curlen){
338 				case NBPW/4:	reloc_how = TYPB; break;
339 				case NBPW/2:	reloc_how = TYPW; break;
340 				case NBPW:	reloc_how = TYPL; break;
341 			}
342 			if (passno == 1){
343 				dotp->e_xvalue += ty_nbyte[reloc_how];
344 			} else {
345 				outrel(locxp, reloc_how);
346 			}
347 		} else {
348 			/*
349 			 *
350 			 *	See if we are doing a case instruction.
351 			 *	If so, then see if the branch distance,
352 			 *	stored as a word,
353 			 *	is going to loose sig bits.
354 			 */
355 			if (passno == 2 && incasetable){
356 				if (  (locxp->e_xvalue < -32768)
357 				    ||(locxp->e_xvalue > 32767)){
358 					yyerror("Case will branch too far");
359 				}
360 			}
361 			field_value = locxp->e_xvalue & ( (1L << field_width)-1);
362 			bitfield |= field_value << bitoff;
363 			bitoff += field_width;
364 		}
365 		xp = explist;
366 		if (auxval = (val == CM))
367 			shift;
368 	    } while (auxval);
369 	}	/* there existed an expression at all */
370 
371 	flushfield(curlen);
372 	if ( ( curlen == NBPW/4) && bitoff)
373 		dotp->e_xvalue ++;
374 	break;
375 	/*end of case IBYTE, IWORD, ILONG, IINT*/
376 
377    case ISPACE: 	/* .space <expr> */
378 	shift;
379 	expr(locxp, val);
380 	if ((locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
381 		yyerror("Space size not absolute");
382 	space_value = locxp->e_xvalue;
383   ospace:
384 	flushfield(NBPW/4);
385 	{
386 		static char spacebuf[128];
387 		while (space_value > sizeof(spacebuf)){
388 			outs(spacebuf, sizeof(spacebuf));
389 			space_value -= sizeof(spacebuf);
390 		}
391 		outs(spacebuf, space_value);
392 	}
393 	break;
394 
395 	/*
396 	 *	.fill rep, size, value
397 	 *	repeat rep times: fill size bytes with (truncated) value
398 	 *	size must be between 1 and 8
399 	 */
400    case	IFILL:
401 	shift;
402 	expr(locxp, val);
403 	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
404 		yyerror("Fill repetition count not absolute");
405 	fill_rep = locxp->e_xvalue;
406 	shiftover(CM);
407 	expr(locxp, val);
408 	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
409 		yyerror("Fill size not absolute");
410 	fill_size = locxp->e_xvalue;
411 	if (fill_size <= 0 || fill_size > 8)
412 		yyerror("Fill count not in in 1..8");
413 	shiftover(CM);
414 	expr(locxp, val);
415 	if (passno == 2 && (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
416 		yyerror("Fill value not absolute");
417 	flushfield(NBPW/4);
418 	if (passno == 1) {
419 		dotp->e_xvalue += fill_rep * fill_size;
420 	} else {
421 		while(fill_rep-- > 0)
422 			bwrite((char *)&locxp->e_xvalue, fill_size, txtfil);
423 	}
424 	break;
425 
426    case IASCII:		/* .ascii [ <stringlist> ] */
427    case IASCIZ: 	/* .asciz [ <stringlist> ] */
428 	auxval = val;
429 	shift;
430 	/*
431 	 *	Code to consume a string list
432 	 *
433 	 *	stringlist: empty | STRING | stringlist STRING
434 	 */
435 	while (val == STRING){
436 		int	mystrlen;
437 		flushfield(NBPW/4);
438 		if (bitoff)
439 			dotp->e_xvalue++;
440 		stringp = (struct strdesc *)yylval;
441 		/*
442 		 *	utilize the string scanner cheat;
443 		 *	the scanner appended a null byte on the string,
444 		 *	but didn't charge it to sd_strlen
445 		 */
446 		mystrlen = stringp->sd_strlen;
447 		mystrlen += (auxval == IASCIZ) ? 1 : 0;
448 		if (passno == 2){
449 			if (stringp->sd_place & STR_CORE){
450 				outs(stringp->sd_string, mystrlen);
451 			} else {
452 				int	i, nread;
453 				fseek(strfile, stringp->sd_stroff, 0);
454 				for (i = 0; i < mystrlen;/*VOID*/){
455 					nread = fread(yytext, 1,
456 						min(mystrlen - i,
457 						  sizeof(yytext)), strfile);
458 					outs(yytext, nread);
459 					i += nread;
460 				}
461 			}
462 		} else {
463 			dotp->e_xvalue += mystrlen;
464 		}
465 		shift;		/*over the STRING*/
466 		if (val == CM)	/*could be a split string*/
467 			shift;
468 	}
469 	break;
470 
471    case IORG: 	/* .org <expr> */
472 	shift;
473 	expr(locxp, val);
474 
475 	if ((locxp->e_xtype & XTYPE) == XABS)	/* tekmdp */
476 		orgwarn++;
477 	else if ((locxp->e_xtype & ~XXTRN) != dotp->e_xtype)
478 		yyerror("Illegal expression to set origin");
479 	space_value = locxp->e_xvalue - dotp->e_xvalue;
480 	if (space_value < 0)
481 		yyerror("Backwards 'org'");
482 	goto ospace;
483 	break;
484 
485 /*
486  *
487  *	Process stabs.  Stabs are created only by the f77
488  *	and the C compiler with the -g flag set.
489  *	We only look at the stab ONCE, during pass 1, and
490  *	virtually remove the stab from the intermediate file
491  *	so it isn't seen during pass2.  This makes for some
492  *	hairy processing to handle labels occuring in
493  *	stab entries, but since most expressions in the
494  *	stab are integral we save lots of time in the second
495  *	pass by not looking at the stabs.
496  *	A stab that is tagged floating will be bumped during
497  *	the jxxx resolution phase.  A stab tagged fixed will
498  *	not be be bumped.
499  *
500  *	.stab:	Old fashioned stabs
501  *	.stabn: For stabs without names
502  *	.stabs:	For stabs with string names
503  *	.stabd: For stabs for line numbers or bracketing,
504  *		without a string name, without
505  *		a final expression.  The value of the
506  *		final expression is taken to be  the current
507  *		location counter, and is patched by the 2nd pass
508  *
509  *	.stab{<expr>,}*NCPName,<expr>, <expr>, <expr>, <expr>
510  *	.stabn		 <expr>, <expr>, <expr>, <expr>
511  *	.stabs   STRING, <expr>, <expr>, <expr>, <expr>
512  *	.stabd		 <expr>, <expr>, <expr> # .
513  */
514    case ISTAB:
515 	yyerror(".stab directive no longer supported");
516 	goto errorfix;
517 
518   tailstab:
519 	expr(locxp, val);
520 	if (! (locxp->e_xvalue & STABTYPS)){
521 		yyerror("Invalid type in %s", stabname);
522 		goto errorfix;
523 	}
524 	stpt->s_ptype = locxp->e_xvalue;
525 	shiftover(CM);
526 	expr(locxp, val);
527 	stpt->s_other = locxp->e_xvalue;
528 	shiftover(CM);
529 	expr(locxp, val);
530 	stpt->s_desc = locxp->e_xvalue;
531 	shiftover(CM);
532 	exprisname = 0;
533 	expr(locxp, val);
534 	p = locxp->e_xname;
535 	if (p == NULL) {	/*absolute expr to begin with*/
536 		stpt->s_value = locxp->e_xvalue;
537 		stpt->s_index = dotp - usedot;
538 		if (exprisname){
539 			switch(stpt->s_ptype){
540 				case N_GSYM:
541 				case N_FNAME:
542 				case N_RSYM:
543 				case N_SSYM:
544 				case N_LSYM:
545 				case N_PSYM:
546 				case N_BCOMM:
547 				case N_ECOMM:
548 				case N_LENG:
549 					stpt->s_tag = STABFIXED;
550 					break;
551 				default:
552 					stpt->s_tag = STABFLOATING;
553 					break;
554 			}
555 		} else
556 			stpt->s_tag = STABFIXED;
557 	}
558 	else {		/*really have a name*/
559 		stpt->s_dest = locxp->e_xname;
560 		stpt->s_index = p->s_index;
561 		stpt->s_type = p->s_type | STABFLAG;
562 		/*
563 		 *	We will assign a more accruate
564 		 *	guess of locxp's location when
565 		 *	we sort the symbol table
566 		 *	The final value of value is
567 		 *	given by stabfix()
568 		 */
569 /*
570  * For exprs of the form (name + value) one needs to remember locxp->e_xvalue
571  * for use in stabfix. The right place to keep this is in stpt->s_value
572  * however this gets corrupted at an unknown point.
573  * As a bandaid hack the value is preserved in s_desc and s_other (a
574  * short and a char). This destroys these two values and will
575  * be fixed. May 19 ,1983 Alastair Fyfe
576  */
577 		if(locxp->e_xvalue) {
578 			stpt->s_other = (locxp->e_xvalue >> 16);
579 			stpt->s_desc =  (locxp->e_xvalue  & 0x0000ffff);
580 			stpt->s_tag = STABFLOATING;
581 		}
582 	}
583 	/*
584 	 *	tokptr now points at one token beyond
585 	 *	the current token stored in val and yylval,
586 	 *	which are the next tokens after the end of
587 	 *	this .stab directive.  This next token must
588 	 *	be either a SEMI or NL, so is of width just
589 	 *	one.  Therefore, to point to the next token
590 	 *	after the end of this stab, just back up one..
591 	 */
592 	buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));
593 	break;	/*end of the .stab*/
594 
595    case ISTABDOT:
596 	stabname = ".stabd";
597 	stpt = (struct symtab *)yylval;
598 	/*
599 	 *	We clobber everything after the
600 	 *	.stabd and its pointer... we MUST
601 	 *	be able to get back to this .stabd
602 	 *	so that we can resolve its final value
603 	 */
604 	stabstart = tokptr;
605 	shift;		/*over the ISTABDOT*/
606 	if (passno == 1){
607 		expr(locxp, val);
608 		if (! (locxp->e_xvalue & STABTYPS)){
609 			yyerror("Invalid type in .stabd");
610 			goto errorfix;
611 		}
612 		stpt->s_ptype = locxp->e_xvalue;
613 		shiftover(CM);
614 		expr(locxp, val);
615 		stpt->s_other = locxp->e_xvalue;
616 		shiftover(CM);
617 		expr(locxp, val);
618 		stpt->s_desc = locxp->e_xvalue;
619 		/*
620 		 *
621 		 *	Now, clobber everything but the
622 		 *	.stabd pseudo and the pointer
623 		 *	to its symbol table entry
624 		 *	tokptr points to the next token,
625 		 *	build the skip up to this
626 		 */
627 		buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));
628 	}
629 	/*
630 	 *	pass 1:	Assign a good guess for its position
631 	 *		(ensures they are sorted into right place)/
632 	 *	pass 2:	Fix the actual value
633 	 */
634 	stpt->s_value = dotp->e_xvalue;
635 	stpt->s_index = dotp - usedot;
636 	stpt->s_tag = STABFLOATING;	/*although it has no effect in pass 2*/
637 	break;
638 
639    case ISTABNONE:	stabname = ".stabn"; goto shortstab;
640 
641    case ISTABSTR: 	stabname = ".stabs";
642    shortstab:
643 	auxval = val;
644 	if (passno == 2) goto errorfix;
645 	stpt = (struct symtab *)yylval;
646 	stabstart = tokptr;
647 	(bytetoktype *)stabstart -= sizeof(struct symtab *);
648 	(bytetoktype *)stabstart -= sizeof(bytetoktype);
649 	shift;
650 	if (auxval == ISTABSTR){
651 		stringp = (struct strdesc *)yylval;
652 		shiftover(STRING);
653 		stpt->s_name = (char *)stringp;
654 		/*
655 		 *	We want the trailing null included in this string.
656 		 *	We utilize the cheat the string scanner used,
657 		 *	and merely increment the string length
658 		 */
659 		stringp->sd_strlen += 1;
660 		shiftover(CM);
661 	} else {
662 		stpt->s_name = (char *)savestr("\0", 0, STR_BOTH);
663 	}
664 	goto tailstab;
665 	break;
666 
667    case ICOMM:		/* .comm  <name> , <expr> */
668    case ILCOMM: 	/* .lcomm <name> , <expr> */
669 	auxval = val;
670 	shift;
671 	np = (struct symtab *)yylval;
672 	shiftover(NAME);
673 	shiftover(CM);
674 	expr(locxp, val);
675 
676 	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
677 		yyerror("comm size not absolute");
678 	if (passno == 1 && (np->s_type&XTYPE) != XUNDEF)
679 		yyerror("Redefinition of %s", FETCHNAME(np));
680 	if (passno==1) {
681 		np->s_value = locxp->e_xvalue;
682 		if (auxval == ICOMM)
683 			np->s_type |= XXTRN;
684 		else {
685 			np->s_type &= ~XTYPE;
686 			np->s_type |= XBSS;
687 		}
688 	}
689 	break;
690 
691    case IALIGN: 		/* .align <expr> */
692 	stpt = (struct symtab *)yylval;
693 	shift;
694 	expr(locxp, val);
695 	jalign(locxp, stpt);
696 	break;
697 
698    case INST0: 		/* instructions w/o arguments*/
699 	incasetable = 0;
700 	insout(yyopcode, (struct arg *)0, 0);
701 	shift;
702 	break;
703 
704    case INSTn:		/* instructions with arguments*/
705    case IJXXX: 		/* UNIX style jump instructions */
706 	auxval = val;
707 	/*
708 	 *	Code to process an argument list
709 	 */
710 	ap = arglist;
711 	xp = explist;
712 
713 	shift;		/* bring in the first token for the arg list*/
714 
715 	for (argcnt = 1; argcnt <= 6; argcnt++, ap++){
716 		/*
717 		 *	code to process an argument proper
718 		 */
719 	    sawindex  = sawmul = sawsize = 0;
720 	    {
721 		switch(val) {
722 
723 		   default:
724 		     disp:
725 			if( !(INTOKSET(val,
726 				 EBEGOPS
727 				+YUKKYEXPRBEG
728 				+SAFEEXPRBEG)) ) {
729 				ERROR("expression expected");
730 			}
731 			expr(ap->a_xp,val);
732 		     overdisp:
733 			if ( val == LP || sawsize){
734 				shiftover(LP);
735 				findreg(regno);
736 				shiftover(RP);
737 				ap->a_atype = ADISP;
738 				ap->a_areg1 = regno;
739 			} else {
740 				ap->a_atype = AEXP;
741 				ap->a_areg1 = 0;
742 			}
743 			goto index;
744 
745 		   case SIZESPEC:
746 		     sizespec:
747 			sawsize = yylval;
748 			shift;
749 			goto disp;
750 
751 		   case REG:
752 		   case REGOP:
753 			findreg(regno);
754 			ap->a_atype = AREG;
755 			ap->a_areg1 = regno;
756 			break;
757 
758 		   case MUL:
759 			sawmul = 1;
760 			shift;
761 			if (val == LP) goto base;
762 			if (val == LITOP) goto imm;
763 			if (val == SIZESPEC) goto sizespec;
764 			if (INTOKSET(val,
765 				 EBEGOPS
766 				+YUKKYEXPRBEG
767 				+SAFEEXPRBEG)) goto disp;
768 			ERROR("expression, '(' or '$' expected");
769 			break;
770 
771 		   case LP:
772 		     base:
773 			shift;	/*consume the LP*/
774 			/*
775 			 *	hack the ambiguity of
776 			 *	movl (expr) (rn), ...
777 			 *	note that (expr) could also
778 			 *	be (rn) (by special hole in the
779 			 *	grammar), which we ensure
780 			 *	means register indirection, instead
781 			 *	of an expression with value n
782 			 */
783 			if (val != REG && val != REGOP){
784 				droppedLP = 1;
785 				val = exprparse(val, &(ap->a_xp));
786 				droppedLP = 0;
787 				goto overdisp;
788 			}
789 			findreg(regno);
790 			shiftover(RP);
791 			if (val == PLUS){
792 				shift;
793 				ap->a_atype = AINCR;
794 			} else
795 				ap->a_atype = ABASE;
796 			ap->a_areg1 = regno;
797 			goto index;
798 
799 		   case LITOP:
800 		      imm:
801 			shift;
802 			expr(locxp, val);
803 			ap->a_atype = AIMM;
804 			ap->a_areg1 = 0;
805 			ap->a_xp = locxp;
806 			goto index;
807 
808 		   case MP:
809 			shift;	/* -(reg) */
810 			findreg(regno);
811 			shiftover(RP);
812 			ap->a_atype = ADECR;
813 			ap->a_areg1 = regno;
814 	  index:			/*look for [reg] */
815 			if (val == LB){
816 				shift;
817 				findreg(regno);
818 				shiftover(RB);
819 				sawindex = 1;
820 				ap->a_areg2 = regno;
821 			}
822 			break;
823 
824 		}	/*end of the switch to process an arg*/
825 	    }	/*end of processing an argument*/
826 
827 	    if (sawmul){
828 			/*
829 			 * Make a concession for *(%r)
830 			 * meaning *0(%r)
831 			 */
832 			if (ap->a_atype == ABASE) {
833 				ap->a_atype = ADISP;
834 				xp->e_xtype = XABS;
835 				xp->e_number = Znumber;
836 				xp->e_number.num_tag = TYPL;
837 				xp->e_xloc = 0;
838 				ap->a_xp = xp++;
839 			}
840 			ap->a_atype |= ASTAR;
841 			sawmul = 0;
842 	    }
843 	    if (sawindex){
844 		ap->a_atype |= AINDX;
845 		sawindex = 0;
846 	    }
847 	    ap->a_dispsize = sawsize == 0 ? d124 : sawsize;
848 		if (val != CM) break;
849 		shiftover(CM);
850 	}	/*processing all the arguments*/
851 
852 	if (argcnt > 6){
853 		yyerror("More than 6 arguments");
854 		goto errorfix;
855 	}
856 
857 	/*
858 	 *	See if this is a case instruction,
859 	 *	so we can set up tests on the following
860 	 *	vector of branch displacements
861 	 */
862 	if (yyopcode.Op_eopcode == CORE){
863 		switch(yyopcode.Op_popcode){
864 		case 0x8f:	/* caseb */
865 		case 0xaf:	/* casew */
866 		case 0xcf:	/* casel */
867 			incasetable++;
868 			break;
869 		default:
870 			incasetable = 0;
871 			break;
872 		}
873 	}
874 
875 	insout(yyopcode, arglist,
876 		auxval == INSTn ? argcnt : - argcnt);
877 	break;
878 
879    case IQUAD:		toconv = TYPQ;	goto bignumlist;
880    case IOCTA:		toconv = TYPO;	goto bignumlist;
881 
882    case IFFLOAT:	toconv = TYPF;	goto bignumlist;
883    case IDFLOAT:	toconv = TYPD;	goto bignumlist;
884    case IGFLOAT:	toconv = TYPG;	goto bignumlist;
885    case IHFLOAT:	toconv = TYPH;	goto bignumlist;
886    bignumlist:
887 	/*
888 	 *	eat a list of non 32 bit numbers.
889 	 *	IQUAD and IOCTA can, possibly, return
890 	 *	INT's, if the numbers are "small".
891 	 *
892 	 *	The value of the numbers is coming back
893 	 *	as an expression, NOT in yybignum.
894 	 */
895 	shift;	/* over the opener */
896 	if ((val == BIGNUM) || (val == INT)){
897 		do{
898 			if ((val != BIGNUM) && (val != INT)){
899 				ERROR(ty_float[toconv]
900 				   ? "floating number expected"
901 				   : "integer number expected" );
902 			}
903 			dotp->e_xvalue += ty_nbyte[toconv];
904 			if (passno == 2){
905 				bignumwrite(
906 					((struct exp *)yylval)->e_number,
907 					toconv);
908 			}
909 			xp = explist;
910 			shift;		/* over this number */
911 			if (auxval = (val == CM))
912 				shift;	/* over the comma */
913 		} while (auxval);	/* as long as there are commas */
914 	}
915 	break;
916 	/* end of the case for initialized big numbers */
917     }	/*end of the switch for looking at each reserved word*/
918 
919 	continue;
920 
921    errorfix:
922 	/*
923 	 *	got here by either requesting to skip to the
924 	 *	end of this statement, or by erroring out and
925 	 *	wanting to apply panic mode recovery
926 	 */
927 	while (    (val != NL)
928 		&& (val != SEMI)
929 		&& (val != PARSEEOF)
930 	      ){
931 		shift;
932 	}
933 	if (val == NL)
934 		lineno++;
935 	shift;
936 
937     }	/*end of the loop to read the entire file, line by line*/
938 
939 }	/*end of yyparse*/
940 
941 /*
942  *	Process a register declaration of the form
943  *	% <expr>
944  *
945  *	Note:
946  *		The scanner has already processed funny registers of the form
947  *	%dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional
948  *	preceding zero digit).  If there was any space between the % and
949  *	the digit, the scanner wouldn't have recognized it, so we
950  *	hack it out here.
951  */
952 inttoktype funnyreg(val, regnoback)	/*what the read head will sit on*/
953 	inttoktype	val;		/*what the read head is sitting on*/
954 	int	*regnoback;		/*call by return*/
955 {
956 	reg	struct	exp *locxp;
957 		struct	exp *loc1xp;
958 		struct	exp **ptrloc1xp = & loc1xp;
959 
960 	expr(locxp, val);	/*and leave the current read head with value*/
961 	if ( (passno == 2) &&
962 	    (   (locxp->e_xtype & XTYPE) != XABS
963 	     || (locxp->e_xvalue < 0)
964 	     || (locxp->e_xvalue >= 16)
965 	    )
966 	  ){
967 		yyerror("Illegal register");
968 		return(0);
969 	}
970 	*regnoback = locxp->e_xvalue;
971 	return(val);
972 }
973 /*
974  *	Shift over error
975  */
976 shiftoerror(token)
977 	int	token;
978 {
979 	char	*tok_to_name();
980 	yyerror("%s expected", tok_to_name(token));
981 }
982 
983 /*VARARGS1*/
984 yyerror(s, a1, a2,a3,a4,a5)
985 	char	*s;
986 {
987 
988 #define	sink stdout
989 
990 	if (anyerrs == 0 && anywarnings == 0 && ! silent)
991 		fprintf(sink, "Assembler:\n");
992 	anyerrs++;
993 	if (silent)
994 		return;
995 	fprintf(sink, "\"%s\", line %d: ", dotsname, lineno);
996 	fprintf(sink, s, a1, a2,a3,a4,a5);
997 	fprintf(sink, "\n");
998 #undef sink
999 }
1000 
1001 /*VARARGS1*/
1002 yywarning(s, a1, a2,a3,a4,a5)
1003 	char	*s;
1004 {
1005 #define	sink stdout
1006 	if (anyerrs == 0 && anywarnings == 0 && ! silent)
1007 		fprintf(sink, "Assembler:\n");
1008 	anywarnings++;
1009 	if (silent)
1010 		return;
1011 	fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno);
1012 	fprintf(sink, s, a1, a2,a3,a4,a5);
1013 	fprintf(sink, "\n");
1014 #undef sink
1015 }
1016