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