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