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