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