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