xref: /csrg-svn/old/as.tahoe/asparse.c (revision 34579)
129832Ssam /*
229832Ssam  *	Copyright (c) 1982 Regents of the University of California
329832Ssam  */
429832Ssam #ifndef lint
5*34579Skarels static char sccsid[] = "$W$ (Berkeley) 05/31/88";
629832Ssam #endif not lint
729832Ssam 
829832Ssam #include <stdio.h>
929832Ssam #include "as.h"
1029832Ssam #include "asscan.h"
1129832Ssam #include "assyms.h"
1229832Ssam #include "asexpr.h"
1329832Ssam 
1429832Ssam int	lgensym[10];
1529832Ssam char	genref[10];
1629832Ssam 
1729832Ssam long	bitfield;
1829832Ssam int	bitoff;
1929832Ssam int	curlen;			/* current length of literals */
2029832Ssam int	printblank;
2129832Ssam 
2229832Ssam /*
2329832Ssam  *	The following three variables are communication between various
2429832Ssam  *	modules to special case a number of things.  They are properly
2529832Ssam  *	categorized as hacks.
2629832Ssam  */
2729832Ssam extern	struct	symtab *lastnam;/*last name seen by the lexical analyzer*/
2829832Ssam int	exprisname;		/*last factor in an expression was a name*/
2929832Ssam int	droppedLP;		/*one is analyzing an expression beginning with*/
3029832Ssam 				/*a left parenthesis, which has already been*/
3129832Ssam 				/*shifted. (Used to parse (<expr>)(rn)*/
3229832Ssam 
3329832Ssam char	yytext[NCPName+2];	/*the lexical image*/
3429832Ssam int	yylval;			/*the lexical value; sloppy typing*/
3529832Ssam u_char	yyopcode;		/* lexical value for an opcode */
3629832Ssam Bignum	yybignum;		/* lexical value for a big number */
3729832Ssam int	num_type;		/* type of bignums */
3829832Ssam /*
3929832Ssam  *	Expression and argument managers
4029832Ssam  */
4129832Ssam struct	exp	*xp;		/*next free expression slot, used by expr.c*/
4229832Ssam struct	exp	explist[NEXP];	/*max of 20 expressions in one opcode*/
4329832Ssam struct	arg	arglist[NARG];	/*building up operands in instructions*/
4429832Ssam /*
4529832Ssam  *	Sets to accelerate token discrimination
4629832Ssam  */
4729832Ssam char	tokensets[(LASTTOKEN) - (FIRSTTOKEN) + 1];
4829832Ssam 
4929832Ssam static	char	UDotsname[64];	/*name of the assembly source*/
5029832Ssam 
yyparse()5129832Ssam yyparse()
5229832Ssam {
5329832Ssam 	reg	struct	exp	*locxp;
5429832Ssam 		/*
5529832Ssam 		 *	loc1xp and ptrloc1xp are used in the
5629832Ssam 		 * 	expression lookahead
5729832Ssam 		 */
5829832Ssam 		struct	exp	*loc1xp;	/*must be non register*/
5929832Ssam 		struct	exp	**ptrloc1xp = & loc1xp;
6029832Ssam 		struct	exp	*pval;		/*hacking expr:expr*/
6129832Ssam 
6229832Ssam 	reg	struct	symtab	*np;
6329832Ssam 	reg	int		argcnt;
6429832Ssam 
6529832Ssam 	reg	inttoktype	val;		/*what yylex gives*/
6629832Ssam 	reg	inttoktype	auxval;		/*saves val*/
6729832Ssam 
6829832Ssam 	reg	struct 	arg	*ap;		/*first free argument*/
6929832Ssam 
7029832Ssam 	reg	struct	symtab	*p;
7129832Ssam 	reg	struct	symtab	*stpt;
7229832Ssam 
7329832Ssam 		struct	strdesc *stringp;	/*handles string lists*/
7429832Ssam 
7529832Ssam 		int	regno;		/*handles arguments*/
7629832Ssam 		int	*ptrregno = &regno;
7729832Ssam 		int	sawmul;		/*saw * */
7829832Ssam 		int	sawindex;	/*saw [rn]*/
7929832Ssam 		int	sawsize;
8029832Ssam 		int	seg_type; 	/*the kind of segment: data or text*/
8129832Ssam 		int	seg_number;	/*the segment number*/
8229832Ssam 		int	space_value;	/*how much .space needs*/
8329832Ssam 		int	fill_rep;	/*how many reps for .fill */
8429832Ssam 		int	rep_fill;	/*the same - temprary */
8529832Ssam 		int	fill_size;	/*how many bytes for .fill */
8629832Ssam 
8729832Ssam 		int	field_width;	/*how wide a field is to be*/
8829832Ssam 		int	field_value;	/*the value to stuff in a field*/
8929832Ssam 		char	*stabname;	/*name of stab dealing with*/
9029832Ssam 		ptrall	stabstart;	/*where the stab starts in the buffer*/
9129832Ssam 		int	reloc_how;	/* how to relocate expressions */
9229832Ssam 		int	incasetable;	/* set if in a case table */
9329832Ssam 		int 	j, k;
9429832Ssam 		char	ch;
9529832Ssam 		int	length;		/* for printout */
9629832Ssam 	union twolong
9729832Ssam 	{
9829832Ssam 		long lpart[2];
9929832Ssam 		char strpart [8];
10029832Ssam 	}fillval;
10129832Ssam 
10229832Ssam 
10329832Ssam 	incasetable = 0;
10429832Ssam 	xp = explist;
10529832Ssam 	ap = arglist;
10629832Ssam 
10729832Ssam 	val = yylex();
10829832Ssam 
10929832Ssam     while (val != PARSEEOF){	/* primary loop */
11029832Ssam 
11129832Ssam 	while (INTOKSET(val, LINSTBEGIN)){
11229832Ssam 		if (val == INT) {
11329832Ssam 			int i = ((struct exp *)yylval)->e_xvalue;
11429832Ssam 			shift;
11529832Ssam 			if (val != COLON){
11629832Ssam 				yyerror("Local label %d is not followed by a ':' for a label definition",
11729832Ssam 					i);
11829832Ssam 				goto  errorfix;
11929832Ssam 			}
12029832Ssam 			if (i < 0 || i > 9) {
12129832Ssam 				yyerror("Local labels are 0-9");
12229832Ssam 				goto errorfix;
12329832Ssam 			}
12429832Ssam 			(void)sprintf(yytext, "L%d\001%d", i, lgensym[i]);
12529832Ssam 			lgensym[i]++;
12629832Ssam 			genref[i] = 0;
12729832Ssam 			yylval = (int)*lookup(passno == 1);
12829832Ssam 			val = NAME;
12929832Ssam 			np = (struct symtab *)yylval;
13029832Ssam 			goto restlab;
13129832Ssam 		}
13229832Ssam 		if (val == NL){
13329832Ssam 			lineno++;
13429832Ssam 			if (liston && (passno == 2) && (! endofsource))
13529832Ssam 			{
13629832Ssam 				/* printing previous line & layout */
13729832Ssam 				length = strlen (layout);
13829832Ssam 				fprintf (listfile, "%*.*s", LHEAD, LHEAD, layout);
13929832Ssam 				if (length <= LHEAD+LLEN)
14029832Ssam 					j = LLEN;
14129832Ssam 				else {	/* break line at last blank */
14229832Ssam 					j = LHEAD+LLEN;
14329832Ssam 					while(j>LHEAD && layout[j]!= ' ')
14429832Ssam 						j--;
14529832Ssam 					if(j == LHEAD)
14629832Ssam 						j = LLEN;
14729832Ssam 					else
14829832Ssam 						j -= LHEAD;
14929832Ssam 				}
15029832Ssam 				k = LHEAD+j;
15129832Ssam 				fprintf (listfile, "%-*.*s", LLEN, j, &layout[LHEAD]);
15229832Ssam 				fprintf (listfile, "     ");
15329832Ssam 				do {
15429832Ssam 					ch = getc (source);
15529832Ssam 					putc (ch, listfile);
15629832Ssam 				} while (ch != '\n');
15729832Ssam 				while (k < length)
15829832Ssam 				{
15929832Ssam 					fprintf (listfile, "%*s", LHEAD, "");
16029832Ssam 					/* break line at last blank */
16129832Ssam 					if(layout[k] == ' ')
16229832Ssam 						k++;
16329832Ssam 					if((j = k+LLEN) >= length)
16429832Ssam 						j = length;
16529832Ssam 					else
16629832Ssam 						while(j>k && layout[j]!= ' ')
16729832Ssam 							j--;
16829832Ssam 					if(j == k)
16929832Ssam 						j = LLEN;
17029832Ssam 					else
17129832Ssam 						j -= k;
17229832Ssam 					fprintf (listfile, "%-*.*s\n", j, j, &layout[k]);
17329832Ssam 					k += j;
17429832Ssam 				}
17529832Ssam 				k = 0;
17629832Ssam 				while (layout[k] != '\0')
17729832Ssam 					layout[k++] = '\0';
17829832Ssam 				ch = getc (source);
17929832Ssam 				if (ch == EOF)
18029832Ssam 				{
18129832Ssam 					if (ind == ninfiles)
18229832Ssam 						endofsource = 1;
18329832Ssam 					else
18429832Ssam 					{
18529832Ssam 						source = fopen (innames[ind++], "r");
18629832Ssam 						lineno = 1;
18729832Ssam 					}
18829832Ssam 				}
18929832Ssam 				else
19029832Ssam 					ungetc (ch, source);
19129832Ssam 				layoutpos = layout;
19232436Sbostic 				(void)sprintf (layoutpos, "%4ld  ", lineno);
19329832Ssam 				layoutpos += 6;
19429832Ssam 				long_out (dotp->e_xvalue);
19529832Ssam 				if (dotp->e_xvalue >= datbase)
19632436Sbostic 					(void)sprintf (layoutpos," *  ");
19729832Ssam 				else
19832436Sbostic 					(void)sprintf (layoutpos,"    ");
19929832Ssam 				layoutpos += 4;
20029832Ssam 			}
20129832Ssam 			shift;
20229832Ssam 		} else
20329832Ssam 		if (val == SEMI)
20429832Ssam 			shift;
20529832Ssam 		else {	/*its a name, so we have a label or def */
20629832Ssam 			if (val != NAME){
20729832Ssam 				ERROR("Name expected for a label");
20829832Ssam 			}
20929832Ssam 			np = (struct symtab *)yylval;
21029832Ssam 			shiftover(NAME);
21129832Ssam 			if (val != COLON) {
21229832Ssam 				yyerror("\"%s\" is not followed by a ':' for a label definition",
21329832Ssam 					FETCHNAME(np));
21429832Ssam 				goto  errorfix;
21529832Ssam 			}
21629832Ssam restlab:
21729832Ssam 			shift;
21829832Ssam 			flushfield(NBPW/4);
21929832Ssam 			if ((np->s_type&XTYPE)!=XUNDEF) {
22029832Ssam 				if(  (np->s_type&XTYPE)!=dotp->e_xtype
22129832Ssam 				   || np->s_value!=dotp->e_xvalue
22229832Ssam 				   || (  (passno==1)
22329832Ssam 				       &&(np->s_index != dotp->e_xloc)
22429832Ssam 				      )
22529832Ssam 				  ){
22629832Ssam #ifndef DEBUG
22729832Ssam 					if (FETCHNAME(np)[0] != 'L')
22829832Ssam #endif not DEBUG
22929832Ssam 					{
23029832Ssam 						if (passno == 1)
23129832Ssam 						  yyerror("%s redefined",
23229832Ssam 							FETCHNAME(np));
23329832Ssam 						else
23429832Ssam 						  yyerror("%s redefined: PHASE ERROR, 1st: %d, 2nd: %d",
23529832Ssam 							FETCHNAME(np),
23629832Ssam 							np->s_value,
23729832Ssam 							dotp->e_xvalue);
23829832Ssam 					}
23929832Ssam 				}
24029832Ssam 			}
24129832Ssam 			np->s_type &= ~(XTYPE|XFORW);
24229832Ssam 			np->s_type |= dotp->e_xtype;
24329832Ssam 			np->s_value = dotp->e_xvalue;
24429832Ssam 			if (passno == 1){
24529832Ssam 				np->s_index = dotp-usedot;
24629832Ssam 				if (FETCHNAME(np)[0] == 'L'){
24729832Ssam 					nlabels++;
24829832Ssam 				}
24929832Ssam 				np->s_tag = LABELID;
25029832Ssam 			}
25129832Ssam 		}	/*end of this being a label*/
25229832Ssam 	}	/*end of to consuming all labels, NLs and SEMIS */
25329832Ssam 
25429832Ssam 	xp = explist;
25529832Ssam 	ap = arglist;
25629832Ssam 
25729832Ssam 	/*
25829832Ssam 	 *	process the INSTRUCTION body
25929832Ssam 	 */
26029832Ssam 	switch(val){
26129832Ssam 
26229832Ssam     default:
26329832Ssam 	ERROR("Unrecognized instruction or directive");
26429832Ssam 
26529832Ssam    case IABORT:
26629832Ssam 	shift;
26729832Ssam 	sawabort();
26829832Ssam 	/*NOTREACHED*/
26929832Ssam 	break;
27029832Ssam 
27129832Ssam    case PARSEEOF:
27229832Ssam 	tokptr -= sizeof(bytetoktype);
27329832Ssam 	*tokptr++ = VOID;
27429832Ssam 	tokptr[1] = VOID;
27529832Ssam 	tokptr[2] = PARSEEOF;
27629832Ssam 	break;
27729832Ssam 
27829832Ssam    case IFILE:
27929832Ssam 	shift;
28029832Ssam 	stringp = (struct strdesc *)yylval;
28129832Ssam 	shiftover(STRING);
28229832Ssam 	dotsname = &UDotsname[0];
28329832Ssam 	movestr(dotsname, stringp->sd_string,
28429832Ssam 		min(stringp->sd_strlen, sizeof(UDotsname)));
28529832Ssam 	break;
28629832Ssam 
28729832Ssam    case ILINENO:
28829832Ssam 	shift;		/*over the ILINENO*/
28929832Ssam 	expr(locxp, val);
29029832Ssam 	lineno = locxp->e_xvalue;
29129832Ssam 	break;
29229832Ssam 
29329832Ssam    case ISET: 	/* .set  <name> , <expr> */
29429832Ssam 	shift;
29529832Ssam 	np = (struct symtab *)yylval;
29629832Ssam 	shiftover(NAME);
29729832Ssam 	shiftover(CM);
29829832Ssam 	expr(locxp, val);
29929832Ssam 	np->s_type &= (XXTRN|XFORW);
30029832Ssam 	np->s_type |= locxp->e_xtype&(XTYPE|XFORW);
30129832Ssam 	np->s_value = locxp->e_xvalue;
30229832Ssam 	if (passno==1)
30329832Ssam 		np->s_index = locxp->e_xloc;
30429832Ssam 	if ((locxp->e_xtype&XTYPE) == XUNDEF)
30529832Ssam 		yyerror("Illegal set?");
30629832Ssam 	break;
30729832Ssam 
30829832Ssam    case ILSYM: 	/*.lsym name , expr */
30929832Ssam 	shift;
31029832Ssam 	np = (struct symtab *)yylval;
31129832Ssam 	shiftover(NAME);
31229832Ssam 	shiftover(CM);
31329832Ssam 	expr(locxp, val);
31429832Ssam 	/*
31529832Ssam 	 *	Build the unique occurance of the
31629832Ssam 	 *	symbol.
31729832Ssam 	 *	The character scanner will have
31829832Ssam 	 *	already entered it into the symbol
31929832Ssam 	 *	table, but we should remove it
32029832Ssam 	 */
32129832Ssam 	if (passno == 1){
32229832Ssam 		stpt = (struct symtab *)symalloc();
32329832Ssam 		stpt->s_name = np->s_name;
32429832Ssam 		np->s_tag = OBSOLETE;	/*invalidate original */
32529832Ssam 		nforgotten++;
32629832Ssam 		np = stpt;
32729832Ssam 		if ( (locxp->e_xtype & XTYPE) != XABS)
32829832Ssam 			yyerror("Illegal second argument to lsym");
32929832Ssam 		np->s_value = locxp->e_xvalue;
33029832Ssam 		np->s_type = XABS;
33129832Ssam 		np->s_tag = ILSYM;
33229832Ssam 	}
33329832Ssam 	break;
33429832Ssam 
33529832Ssam    case IGLOBAL: 	/*.globl <name> */
33629832Ssam 	shift;
33729832Ssam 	np = (struct symtab *)yylval;
33829832Ssam 	shiftover(NAME);
33929832Ssam 	np->s_type |= XXTRN;
34029832Ssam 	break;
34129832Ssam 
34229832Ssam    case IDATA: 	/*.data [ <expr> ] */
34329832Ssam    case ITEXT: 	/*.text [ <expr> ] */
34429832Ssam 	incasetable = 0;
34529832Ssam 	seg_type = -val;
34629832Ssam 	shift;
34729832Ssam 	if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){
34829832Ssam 		expr(locxp, val);
34929832Ssam 		seg_type = -seg_type;   /*now, it is positive*/
35029832Ssam 	}
35129832Ssam 
35229832Ssam 	if (seg_type < 0) {	/*there wasn't an associated expr*/
35329832Ssam 		seg_number = 0;
35429832Ssam 		seg_type = -seg_type;
35529832Ssam 	} else {
35629832Ssam 		if (   ((locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
35729832Ssam 		    || (seg_number = locxp->e_xvalue) >= NLOC) {
35829832Ssam 			yyerror("illegal location counter");
35929832Ssam 			seg_number = 0;
36029832Ssam 		}
36129832Ssam 	}
36229832Ssam 	if (seg_type == IDATA)
36329832Ssam 		seg_number += NLOC;
36429832Ssam 	flushfield(NBPW/4);
36529832Ssam 	dotp = &usedot[seg_number];
36629832Ssam 	if (passno==2) {	/* go salt away in pass 2*/
36729832Ssam 		txtfil = usefile[seg_number];
36829832Ssam 		relfil = rusefile[seg_number];
36929832Ssam 	}
37029832Ssam 	break;
37129832Ssam 
37229832Ssam 	/*
37329832Ssam 	 *	Storage filler directives:
37429832Ssam 	 *
37529832Ssam 	 *	.byte	[<exprlist>]
37629832Ssam 	 *
37729832Ssam 	 *	exprlist:  empty | exprlist outexpr
37829832Ssam 	 *	outexpr:   <expr> | <expr> : <expr>
37929832Ssam 	 */
38029832Ssam    case IBYTE:	curlen = NBPW/4; goto elist;
38129832Ssam    case IWORD:	curlen = NBPW/2; goto elist;
38229832Ssam    case IINT:	curlen = NBPW;   goto elist;
38329832Ssam    case ILONG:	curlen = NBPW;   goto elist;
38429832Ssam 
38529832Ssam    elist:
38629832Ssam 	seg_type = val;
38729832Ssam 	shift;
38829832Ssam 
38929832Ssam 	/*
39029832Ssam 	 *	Expression List processing
39129832Ssam 	 */
39229832Ssam 	if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){
39329832Ssam 	    do{
39429832Ssam 		/*
39529832Ssam 		 *	expression list consists of a list of :
39629832Ssam 		 *	<expr>
39729832Ssam 		 *	<expr> : <expr>
39829832Ssam 		 *		(pack expr2 into expr1 bits
39929832Ssam 		 */
40029832Ssam 		expr(locxp, val);
40129832Ssam 		/*
40229832Ssam 		 *	now, pointing at the next token
40329832Ssam 		 */
40429832Ssam 		/* if (val == COLON){ */
40529832Ssam 		/* 	shiftover(COLON); */
40629832Ssam 		/* 	expr(pval, val); */
40729832Ssam 		/* 	if ((locxp->e_xtype & XTYPE) != XABS)  */
40829832Ssam 		/* 		yyerror("Width not absolute"); */
40929832Ssam 		/* 	field_width = locxp->e_xvalue; */
41029832Ssam 		/* 	locxp = pval; */
41129832Ssam 		/* 	if (bitoff + field_width > curlen) */
41229832Ssam 		/* 		flushfield(curlen); */
41329832Ssam 		/* 	if (field_width > curlen) */
41429832Ssam 		/* 		yyerror("Expression crosses field boundary"); */
41529832Ssam 		/* } else { */
41629832Ssam 			field_width = curlen;
41729832Ssam 			if (bitoff == 0)	printblank = 0;
41829832Ssam 			else			printblank = 1;
41929832Ssam 			flushfield(curlen);
42029832Ssam 			if (liston && (passno == 2) && printblank)
42129832Ssam 				*layoutpos++ = ' ';
42229832Ssam 		/* } */
42329832Ssam 
42429832Ssam 		if ((locxp->e_xtype & XTYPE) != XABS) {
42529832Ssam 			if (bitoff)
42629832Ssam 				yyerror("Illegal relocation in field");
42729832Ssam 			switch(curlen){
42829832Ssam 				case NBPW/4:	reloc_how = TYPB; break;
42929832Ssam 				case NBPW/2:	reloc_how = TYPW; break;
43029832Ssam 				case NBPW:	reloc_how = TYPL; break;
43129832Ssam 			}
43229832Ssam 			if (passno == 1){
43329832Ssam 				dotp->e_xvalue += ty_nbyte[reloc_how];
43429832Ssam 			} else {
43529832Ssam 				outrel(locxp, reloc_how);
43629832Ssam 				if (liston)
43729832Ssam 					*layoutpos++ = ' ';
43829832Ssam 			}
43929832Ssam 		} else {
44029832Ssam 			/*
44129832Ssam 			 *
44229832Ssam 			 *	See if we are doing a case instruction.
44329832Ssam 			 *	If so, then see if the branch distance,
44429832Ssam 			 *	stored as a word,
44529832Ssam 			 *	is going to loose sig bits.
44629832Ssam 			 */
44729832Ssam 			if (passno == 2 && incasetable){
44829832Ssam 				if (  !(ISWORD(locxp->e_xvalue)))
44929832Ssam 					yyerror("Case will branch too far");
45029832Ssam 			}
45129832Ssam 			field_value = locxp->e_xvalue & ( (1L << field_width)-1);
45229832Ssam 			bitfield |= field_value << bitoff;
45329832Ssam 			bitoff += field_width;
45429832Ssam 		}
45529832Ssam 		xp = explist;
45629832Ssam 		if (auxval = (val == CM))
45729832Ssam 			shift;
45829832Ssam 	    } while (auxval);
45929832Ssam 	}	/* there existed an expression at all */
46029832Ssam 
46129832Ssam 	flushfield(curlen);
46229832Ssam 	if ( ( curlen == NBPW/4) && bitoff)
46329832Ssam 		dotp->e_xvalue ++;
46429832Ssam 	break;
46529832Ssam 	/*end of case IBYTE, IWORD, ILONG, IINT*/
46629832Ssam 
46729832Ssam    case ISPACE: 	/* .space <expr> */
46829832Ssam 	shift;
46929832Ssam 	expr(locxp, val);
47029832Ssam 	if ((locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
47129832Ssam 		yyerror("Space size not absolute");
47229832Ssam 	if (locxp->e_xvalue < 0)
47329832Ssam 		yyerror("Space size not positive");
47429832Ssam 	space_value = locxp->e_xvalue;
47529832Ssam   ospace:
47629832Ssam 	flushfield(NBPW/4);
47729832Ssam 	{
47829832Ssam 		static char spacebuf[128];
47929832Ssam 		while (space_value > sizeof(spacebuf)){
48029832Ssam 			outs(spacebuf, sizeof(spacebuf));
48129832Ssam 			space_value -= sizeof(spacebuf);
48229832Ssam 		}
48329832Ssam 		outs(spacebuf, space_value);
48429832Ssam 	}
48529832Ssam 	if (liston && (passno == 2))
48632436Sbostic 		(void)sprintf (layoutpos, "****");
48729832Ssam 	break;
48829832Ssam 
48929832Ssam 	/*
49029832Ssam 	 *	.fill rep, size, value
49129832Ssam 	 *	repeat rep times: fill size bytes with (truncated) value
49229832Ssam 	 *	size must be between 1 and 8
49329832Ssam 	 */
49429832Ssam    case	IFILL:
49529832Ssam 	shift;
49629832Ssam 	expr(locxp, val);
49729832Ssam 	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
49829832Ssam 		yyerror("Fill repetition count not absolute");
49929832Ssam 	rep_fill = fill_rep = locxp->e_xvalue;
50029832Ssam 	shiftover(CM);
50129832Ssam 	expr(locxp, val);
50229832Ssam 	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
50329832Ssam 		yyerror("Fill size not absolute");
50429832Ssam 	fill_size = locxp->e_xvalue;
50529832Ssam 	if (fill_size <= 0 || fill_size > 8)
50629832Ssam 		yyerror("Fill count not in in 1..8");
50729832Ssam 	shiftover(CM);
50829832Ssam 	expr(locxp, val);
50929832Ssam 	if (passno == 2 && (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
51029832Ssam 		yyerror("Fill value not absolute");
51129832Ssam 	flushfield(NBPW/4);
51229832Ssam 	dotp->e_xvalue += fill_rep * fill_size;
51329832Ssam 	if (passno == 1) {
51429832Ssam 		locxp->e_xvalue += fill_rep * fill_size;
51529832Ssam 	} else {
51629832Ssam 		fillval.lpart[0] = locxp->e_yvalue;
51729832Ssam 		fillval.lpart[1] = locxp->e_xvalue;
51829832Ssam 		while (fill_rep-- > 0)
51929832Ssam 			bwrite(&(fillval.strpart[8-fill_size]),fill_size,txtfil);
52029832Ssam 		if (liston) {
52129832Ssam 		   while (rep_fill--  > 0)
52229832Ssam 		   {
52329832Ssam 			switch (fill_size)
52429832Ssam 			{
52529832Ssam 				case 1:
52629832Ssam 					byte_out (locxp->e_xvalue);
52729832Ssam 					*layoutpos++ = ' ';
52829832Ssam 					break;
52929832Ssam 				case 2:
53029832Ssam 					word_out (locxp->e_xvalue);
53129832Ssam 					*layoutpos++ = ' ';
53229832Ssam 					break;
53329832Ssam 				case 3:
53429832Ssam 					byte_out (locxp->e_xvalue >> 16);
53529832Ssam 					byte_out (locxp->e_xvalue >>  8);
53629832Ssam 					byte_out (locxp->e_xvalue);
53729832Ssam 					*layoutpos++ = ' ';
53829832Ssam 					break;
53929832Ssam 				case 4:
54029832Ssam 					long_out (locxp->e_xvalue);
54129832Ssam 					*layoutpos++ = ' ';
54229832Ssam 					break;
54329832Ssam 				case 5:
54429832Ssam 					byte_out (locxp->e_yvalue);
54529832Ssam 					long_out (locxp->e_xvalue);
54629832Ssam 					*layoutpos++ = ' ';
54729832Ssam 					break;
54829832Ssam 				case 6:
54929832Ssam 					word_out (locxp->e_yvalue);
55029832Ssam 					long_out (locxp->e_xvalue);
55129832Ssam 					*layoutpos++ = ' ';
55229832Ssam 					break;
55329832Ssam 				case 7:
55429832Ssam 					byte_out (locxp->e_yvalue >> 16);
55529832Ssam 					byte_out (locxp->e_yvalue >>  8);
55629832Ssam 					byte_out (locxp->e_yvalue);
55729832Ssam 					long_out (locxp->e_xvalue);
55829832Ssam 					*layoutpos++ = ' ';
55929832Ssam 					break;
56029832Ssam 				case 8:
56129832Ssam 					long_out (locxp->e_yvalue);
56229832Ssam 					long_out (locxp->e_xvalue);
56329832Ssam 					*layoutpos++ = ' ';
56429832Ssam 					break;
56529832Ssam 				}
56629832Ssam 			    }
56729832Ssam 		}
56829832Ssam 	}
56929832Ssam 	break;
57029832Ssam 
57129832Ssam    case IASCII:		/* .ascii [ <stringlist> ] */
57229832Ssam    case IASCIZ: 	/* .asciz [ <stringlist> ] */
57329832Ssam 	auxval = val;
57429832Ssam 	shift;
57529832Ssam 	/*
57629832Ssam 	 *	Code to consume a string list
57729832Ssam 	 *
57829832Ssam 	 *	stringlist: empty | STRING | stringlist STRING
57929832Ssam 	 */
58029832Ssam 	while (val == STRING){
58129832Ssam 		int	mystrlen;
58229832Ssam 		flushfield(NBPW/4);
58329832Ssam 		if (bitoff)
58429832Ssam 			dotp->e_xvalue++;
58529832Ssam 		stringp = (struct strdesc *)yylval;
58629832Ssam 		/*
58729832Ssam 		 *	utilize the string scanner cheat;
58829832Ssam 		 *	the scanner appended a null byte on the string,
58929832Ssam 		 *	but didn't charge it to sd_strlen
59029832Ssam 		 */
59129832Ssam 		mystrlen = stringp->sd_strlen;
59229832Ssam 		mystrlen += (auxval == IASCIZ) ? 1 : 0;
59329832Ssam 		if (passno == 2){
59429832Ssam 			if (stringp->sd_place & STR_CORE){
59529832Ssam 				outs(stringp->sd_string, mystrlen);
59629832Ssam 				if (liston)
59729832Ssam 				{
59829832Ssam 					int i;
59929832Ssam 					for (i = 0;i < mystrlen; i++)
60029832Ssam 					{
60132436Sbostic 						(void)sprintf (layoutpos, "%02x",
60229832Ssam 						stringp->sd_string[i]);
60329832Ssam 						layoutpos += 2;
60429832Ssam 					}
60529832Ssam 				}
60629832Ssam 			} else {
60729832Ssam 				int	i, nread;
60829832Ssam 				fseek(strfile, stringp->sd_stroff, 0);
60929832Ssam 				for (i = 0; i < mystrlen;/*VOID*/){
61029832Ssam 					nread = fread(yytext, 1,
61129832Ssam 						min(mystrlen - i,
61229832Ssam 						  sizeof(yytext)), strfile);
61329832Ssam 					outs(yytext, nread);
61429832Ssam 					if (liston)
61529832Ssam 					{
61629832Ssam 						int k;
61729832Ssam 						for (k = 0;k < nread; k++)
61829832Ssam 						{
61932436Sbostic 							(void)sprintf (layoutpos,
62029832Ssam 							 "%02x", yytext[k]);
62129832Ssam 							layoutpos += 2;
62229832Ssam 						}
62329832Ssam 					}
62429832Ssam 					i += nread;
62529832Ssam 				}
62629832Ssam 			}
62729832Ssam 		} else {
62829832Ssam 			dotp->e_xvalue += mystrlen;
62929832Ssam 		}
63029832Ssam 		shift;		/*over the STRING*/
63129832Ssam 		if (val == CM)	/*could be a split string*/
63229832Ssam 			shift;
63329832Ssam 	}
63429832Ssam 	break;
63529832Ssam 
63629832Ssam    case IORG: 	/* .org <expr> */
63729832Ssam 	shift;
63829832Ssam 	expr(locxp, val);
63929832Ssam 
64029832Ssam 	if ((locxp->e_xtype & XTYPE) == XABS)	/* tekmdp */
64129832Ssam 		orgwarn++;
64229832Ssam 	else if ((locxp->e_xtype & ~XXTRN) != dotp->e_xtype)
64329832Ssam 		yyerror("Illegal expression to set origin");
64429832Ssam 	if ((unsigned)locxp->e_xvalue < (unsigned)dotp->e_xvalue)
64529832Ssam 	{
64629832Ssam 		ERROR("Backwards 'org'");
64729832Ssam 	}
64829832Ssam 	space_value = locxp->e_xvalue - dotp->e_xvalue;
64929832Ssam 	goto ospace;
65029832Ssam 	break;
65129832Ssam 
65229832Ssam /*
65329832Ssam  *
65429832Ssam  *	Process stabs.  Stabs are created only by the f77
65529832Ssam  *	and the C compiler with the -g flag set.
65629832Ssam  *	We only look at the stab ONCE, during pass 1, and
65729832Ssam  *	virtually remove the stab from the intermediate file
65829832Ssam  *	so it isn't seen during pass2.  This makes for some
65929832Ssam  *	hairy processing to handle labels occuring in
66029832Ssam  *	stab entries, but since most expressions in the
66129832Ssam  *	stab are integral we save lots of time in the second
66229832Ssam  *	pass by not looking at the stabs.
66329832Ssam  *	A stab that is tagged floating will be bumped during
66429832Ssam  *	the jxxx resolution phase.  A stab tagged fixed will
66529832Ssam  *	not be be bumped.
66629832Ssam  *
66729832Ssam  *	.stab:	Old fashioned stabs
66829832Ssam  *	.stabn: For stabs without names
66929832Ssam  *	.stabs:	For stabs with string names
67029832Ssam  *	.stabd: For stabs for line numbers or bracketing,
67129832Ssam  *		without a string name, without
67229832Ssam  *		a final expression.  The value of the
67329832Ssam  *		final expression is taken to be  the current
67429832Ssam  *		location counter, and is patched by the 2nd pass
67529832Ssam  *
67629832Ssam  *	.stab{<expr>,}*NCPName,<expr>, <expr>, <expr>, <expr>
67729832Ssam  *	.stabn		 <expr>, <expr>, <expr>, <expr>
67829832Ssam  *	.stabs   STRING, <expr>, <expr>, <expr>, <expr>
67929832Ssam  *	.stabd		 <expr>, <expr>, <expr> # .
68029832Ssam  */
68129832Ssam    case ISTAB:
68229832Ssam 	yyerror(".stab directive no longer supported");
68329832Ssam 	goto errorfix;
68429832Ssam 
68529832Ssam   tailstab:
68629832Ssam 	expr(locxp, val);
68729832Ssam 	if (! (locxp->e_xvalue & STABTYPS)){
68829832Ssam 		yyerror("Invalid type in %s", stabname);
68929832Ssam 		goto errorfix;
69029832Ssam 	}
69129832Ssam 	stpt->s_ptype = locxp->e_xvalue;
69229832Ssam 	shiftover(CM);
69329832Ssam 	expr(locxp, val);
69429832Ssam 	stpt->s_other = locxp->e_xvalue;
69529832Ssam 	shiftover(CM);
69629832Ssam 	expr(locxp, val);
69729832Ssam 	stpt->s_desc = locxp->e_xvalue;
69829832Ssam 	shiftover(CM);
69929832Ssam 	exprisname = 0;
70029832Ssam 	expr(locxp, val);
70129832Ssam 	p = locxp->e_xname;
70229832Ssam 	if (p == NULL) {	/*absolute expr to begin with*/
70329832Ssam 		stpt->s_value = locxp->e_xvalue;
70429832Ssam 		stpt->s_index = dotp - usedot;
70529832Ssam 		if (exprisname){
70634441Sdonn 			stpt->s_type = locxp->e_xtype;
70729832Ssam 			switch(stpt->s_ptype){
70831350Ssam 				case N_LCSYM:
70931350Ssam 					stpt->s_dest = (struct symtab *)exprisname;
71031350Ssam 					stpt->s_type |= STABFLAG;
71129832Ssam 				case N_GSYM:
71229832Ssam 				case N_FNAME:
71329832Ssam 				case N_RSYM:
71429832Ssam 				case N_SSYM:
71529832Ssam 				case N_LSYM:
71629832Ssam 				case N_PSYM:
71729832Ssam 				case N_BCOMM:
71829832Ssam 				case N_ECOMM:
71929832Ssam 				case N_LENG:
72029832Ssam 					stpt->s_tag = STABFIXED;
72129832Ssam 					break;
72229832Ssam 				default:
72329832Ssam 					stpt->s_tag = STABFLOATING;
72429832Ssam 					break;
72529832Ssam 			}
72629832Ssam 		} else
72729832Ssam 			stpt->s_tag = STABFIXED;
72829832Ssam 	}
72929832Ssam 	else {		/*really have a name*/
73029832Ssam 		stpt->s_dest = locxp->e_xname;
73129832Ssam 		stpt->s_index = p->s_index;
73229832Ssam 		stpt->s_type = p->s_type | STABFLAG;
73329832Ssam 		/*
73429832Ssam 		 *	We will assign a more accruate
73529832Ssam 		 *	guess of locxp's location when
73629832Ssam 		 *	we sort the symbol table
73729832Ssam 		 *	The final value of value is
73829832Ssam 		 *	given by stabfix()
73929832Ssam 		 */
74029832Ssam /*
74129832Ssam  * For exprs of the form (name + value) one needs to remember locxp->e_xvalue
74229832Ssam  * for use in stabfix. The right place to keep this is in stpt->s_value
74329832Ssam  * however this gets corrupted at an unknown point.
74429832Ssam  * As a bandaid hack the value is preserved in s_desc and s_other (a
74529832Ssam  * short and a char). This destroys these two values and will
74629832Ssam  * be fixed. May 19 ,1983 Alastair Fyfe
74729832Ssam  */
74829832Ssam 		if(locxp->e_xvalue) {
74929832Ssam 			stpt->s_other = (locxp->e_xvalue >> 16);
75029832Ssam 			stpt->s_desc =  (locxp->e_xvalue  & 0x0000ffff);
75129832Ssam 			stpt->s_tag = STABFLOATING;
75229832Ssam 		}
75329832Ssam 	}
75429832Ssam 	/*
75529832Ssam 	 *	tokptr now points at one token beyond
75629832Ssam 	 *	the current token stored in val and yylval,
75729832Ssam 	 *	which are the next tokens after the end of
75829832Ssam 	 *	this .stab directive.  This next token must
75929832Ssam 	 *	be either a SEMI or NL, so is of width just
76029832Ssam 	 *	one.  Therefore, to point to the next token
76129832Ssam 	 *	after the end of this stab, just back up one..
76229832Ssam 	 */
76329832Ssam 	buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));
76429832Ssam 	break;	/*end of the .stab*/
76529832Ssam 
76629832Ssam    case ISTABDOT:
76729832Ssam 	stabname = ".stabd";
76829832Ssam 	stpt = (struct symtab *)yylval;
76929832Ssam 	/*
77029832Ssam 	 *	We clobber everything after the
77129832Ssam 	 *	.stabd and its pointer... we MUST
77229832Ssam 	 *	be able to get back to this .stabd
77329832Ssam 	 *	so that we can resolve its final value
77429832Ssam 	 */
77529832Ssam 	stabstart = tokptr;
77629832Ssam 	shift;		/*over the ISTABDOT*/
77729832Ssam 	if (passno == 1){
77829832Ssam 		expr(locxp, val);
77929832Ssam 		if (! (locxp->e_xvalue & STABTYPS)){
78029832Ssam 			yyerror("Invalid type in .stabd");
78129832Ssam 			goto errorfix;
78229832Ssam 		}
78329832Ssam 		stpt->s_ptype = locxp->e_xvalue;
78429832Ssam 		shiftover(CM);
78529832Ssam 		expr(locxp, val);
78629832Ssam 		stpt->s_other = locxp->e_xvalue;
78729832Ssam 		shiftover(CM);
78829832Ssam 		expr(locxp, val);
78929832Ssam 		stpt->s_desc = locxp->e_xvalue;
79029832Ssam 		/*
79129832Ssam 		 *
79229832Ssam 		 *	Now, clobber everything but the
79329832Ssam 		 *	.stabd pseudo and the pointer
79429832Ssam 		 *	to its symbol table entry
79529832Ssam 		 *	tokptr points to the next token,
79629832Ssam 		 *	build the skip up to this
79729832Ssam 		 */
79829832Ssam 		buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));
79929832Ssam 	}
80029832Ssam 	/*
80129832Ssam 	 *	pass 1:	Assign a good guess for its position
80229832Ssam 	 *		(ensures they are sorted into right place)/
80329832Ssam 	 *	pass 2:	Fix the actual value
80429832Ssam 	 */
80529832Ssam 	stpt->s_value = dotp->e_xvalue;
80629832Ssam 	stpt->s_index = dotp - usedot;
80729832Ssam 	stpt->s_tag = STABFLOATING;	/*although it has no effect in pass 2*/
80829832Ssam 	break;
80929832Ssam 
81029832Ssam    case ISTABNONE:	stabname = ".stabn"; goto shortstab;
81129832Ssam 
81229832Ssam    case ISTABSTR: 	stabname = ".stabs";
81329832Ssam    shortstab:
81429832Ssam 	auxval = val;
81529832Ssam 	if (passno == 2) goto errorfix;
81629832Ssam 	stpt = (struct symtab *)yylval;
81729832Ssam 	stabstart = tokptr;
81829832Ssam 	(bytetoktype *)stabstart -= sizeof(struct symtab *);
81929832Ssam 	(bytetoktype *)stabstart -= sizeof(bytetoktype);
82029832Ssam 	shift;
82129832Ssam 	if (auxval == ISTABSTR){
82229832Ssam 		stringp = (struct strdesc *)yylval;
82329832Ssam 		shiftover(STRING);
82429832Ssam 		stpt->s_name = (char *)stringp;
82529832Ssam 		/*
82629832Ssam 		 *	We want the trailing null included in this string.
82729832Ssam 		 *	We utilize the cheat the string scanner used,
82829832Ssam 		 *	and merely increment the string length
82929832Ssam 		 */
83029832Ssam 		stringp->sd_strlen += 1;
83129832Ssam 		shiftover(CM);
83229832Ssam 	} else {
83329832Ssam 		stpt->s_name = (char *)savestr("\0", 0, STR_BOTH);
83429832Ssam 	}
83529832Ssam 	goto tailstab;
83629832Ssam 	break;
83729832Ssam 
83829832Ssam    case ICOMM:		/* .comm  <name> , <expr> */
83929832Ssam    case ILCOMM: 	/* .lcomm <name> , <expr> */
84029832Ssam 	auxval = val;
84129832Ssam 	shift;
84229832Ssam 	np = (struct symtab *)yylval;
84329832Ssam 	shiftover(NAME);
84429832Ssam 	shiftover(CM);
84529832Ssam 	expr(locxp, val);
84629832Ssam 
84729832Ssam 	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
84829832Ssam 		yyerror("comm size not absolute");
84929832Ssam 	if (passno == 1 && (np->s_type&XTYPE) != XUNDEF)
85029832Ssam 		yyerror("Redefinition of %s", FETCHNAME(np));
85129832Ssam 	if (passno==1) {
85229832Ssam 		np->s_value = locxp->e_xvalue;
85329832Ssam 		if (auxval == ICOMM)
85429832Ssam 			np->s_type |= XXTRN;
85529832Ssam 		else {
85629832Ssam 			np->s_type &= ~XTYPE;
85729832Ssam 			np->s_type |= XBSS;
85829832Ssam 		}
85929832Ssam 	}
86029832Ssam 	break;
86129832Ssam 
86229832Ssam    case IALIGN: 		/* .align <expr> */
86329832Ssam 	stpt = (struct symtab *)yylval;
86429832Ssam 	shift;
86529832Ssam 	expr(locxp, val);
86629832Ssam 	if ((dotp->e_xtype & XTYPE) == XDATA)
86729832Ssam 		djalign(locxp, stpt);
86829832Ssam 	else
86929832Ssam 		jalign(locxp, stpt);
87029832Ssam 	break;
87129832Ssam 
87229832Ssam    case INST0: 		/* instructions w/o arguments*/
87329832Ssam 	incasetable = 0;
87429832Ssam 	insout(yyopcode, (struct arg *)0, 0);
87529832Ssam 	shift;
87629832Ssam 	break;
87729832Ssam 
87829832Ssam    case INSTn:		/* instructions with arguments*/
87929832Ssam    case IJXXX: 		/* UNIX style jump instructions */
88029832Ssam 	auxval = val;
88129832Ssam 	/*
88229832Ssam 	 *	Code to process an argument list
88329832Ssam 	 */
88429832Ssam 	ap = arglist;
88529832Ssam 	xp = explist;
88629832Ssam 
88729832Ssam 	shift;		/* bring in the first token for the arg list*/
88829832Ssam 
88929832Ssam 	for (argcnt = 1; argcnt <= 6; argcnt++, ap++){
89029832Ssam 		/*
89129832Ssam 		 *	code to process an argument proper
89229832Ssam 		 */
89329832Ssam 	    sawindex  = sawmul = sawsize = 0;
89429832Ssam 	    {
89529832Ssam 		switch(val) {
89629832Ssam 
89729832Ssam 		   default:
89829832Ssam 		     disp:
89929832Ssam 			if( !(INTOKSET(val,
90029832Ssam 				 EBEGOPS
90129832Ssam 				+YUKKYEXPRBEG
90229832Ssam 				+SAFEEXPRBEG)) ) {
90329832Ssam 				ERROR("expression expected");
90429832Ssam 			}
90529832Ssam 			expr(ap->a_xp,val);
90629832Ssam 		     overdisp:
90729832Ssam 			if ( val == LP || sawsize){
90829832Ssam 				shiftover(LP);
90929832Ssam 				findreg(regno);
91029832Ssam 				shiftover(RP);
91129832Ssam 				ap->a_atype = ADISP;
91229832Ssam 				ap->a_areg1 = regno;
91329832Ssam 			} else {
91429832Ssam 				ap->a_atype = AEXP;
91529832Ssam 				ap->a_areg1 = 0;
91629832Ssam 			}
91729832Ssam 			goto index;
91829832Ssam 
91929832Ssam 		   case SIZESPEC:
92029832Ssam 		     sizespec:
92129832Ssam 			sawsize = yylval;
92229832Ssam 			shift;
92329832Ssam 			goto disp;
92429832Ssam 
92529832Ssam 		   case REG:
92629832Ssam 		   case REGOP:
92729832Ssam 			findreg(regno);
92829832Ssam 			ap->a_atype = AREG;
92929832Ssam 			ap->a_areg1 = regno;
93029832Ssam 			break;
93129832Ssam 
93229832Ssam 		   case MUL:
93329832Ssam 			sawmul = 1;
93429832Ssam 			shift;
93529832Ssam 			if (val == LP) goto base;
93629832Ssam 			if (val == LITOP) goto imm;
93729832Ssam 			if (val == SIZESPEC) goto sizespec;
93829832Ssam 			if (INTOKSET(val,
93929832Ssam 				 EBEGOPS
94029832Ssam 				+YUKKYEXPRBEG
94129832Ssam 				+SAFEEXPRBEG)) goto disp;
94229832Ssam 			ERROR("expression, '(' or '$' expected");
94329832Ssam 			break;
94429832Ssam 
94529832Ssam 		   case LP:
94629832Ssam 		     base:
94729832Ssam 			shift;	/*consume the LP*/
94829832Ssam 			/*
94929832Ssam 			 *	hack the ambiguity of
95029832Ssam 			 *	movl (expr) (rn), ...
95129832Ssam 			 *	note that (expr) could also
95229832Ssam 			 *	be (rn) (by special hole in the
95329832Ssam 			 *	grammar), which we ensure
95429832Ssam 			 *	means register indirection, instead
95529832Ssam 			 *	of an expression with value n
95629832Ssam 			 */
95729832Ssam 			if (val != REG && val != REGOP){
95829832Ssam 				droppedLP = 1;
95929832Ssam 				val = exprparse(val, &(ap->a_xp));
96029832Ssam 				droppedLP = 0;
96129832Ssam 				goto overdisp;
96229832Ssam 			}
96329832Ssam 			findreg(regno);
96429832Ssam 			shiftover(RP);
96529832Ssam 			if (val == PLUS){
96629832Ssam 				shift;
96729832Ssam 				ap->a_atype = AINCR;
96829832Ssam 				if (sawmul && regno != 0xE)
96929832Ssam 					yyerror ("Autoincrement deferred register must be SP");
97029832Ssam 				if (!(sawmul || regno == 0xE))
97129832Ssam 					yyerror ("Autoincrement register must be SP");
97229832Ssam 			} else
97329832Ssam 				ap->a_atype = ABASE;
97429832Ssam 			ap->a_areg1 = regno;
97529832Ssam 			goto index;
97629832Ssam 
97729832Ssam 		   case LITOP:
97829832Ssam 		      imm:
97929832Ssam 			shift;
98029832Ssam 			expr(locxp, val);
98129832Ssam 			ap->a_atype = AIMM;
98229832Ssam 			ap->a_areg1 = 0;
98329832Ssam 			ap->a_xp = locxp;
98429832Ssam 			goto index;
98529832Ssam 
98629832Ssam 		   case MP:
98729832Ssam 			shift;	/* -(reg) */
98829832Ssam 			findreg(regno);
98929832Ssam 			if (regno != 0xE)
99029832Ssam 				yyerror ("Autodecrement register must be SP");
99129832Ssam 			shiftover(RP);
99229832Ssam 			ap->a_atype = ADECR;
99329832Ssam 			ap->a_areg1 = regno;
99429832Ssam 	  index:			/*look for [reg] */
99529832Ssam 			if (val == LB){
99629832Ssam 				shift;
99729832Ssam 				findreg(regno);
99829832Ssam 				shiftover(RB);
99929832Ssam 				sawindex = 1;
100029832Ssam 				ap->a_areg2 = regno;
100129832Ssam 			}
100229832Ssam 			break;
100329832Ssam 
100429832Ssam 		}	/*end of the switch to process an arg*/
100529832Ssam 	    }	/*end of processing an argument*/
100629832Ssam 
100729832Ssam 	    if (sawmul){
100829832Ssam 			/*
100929832Ssam 			 * Make a concession for *(%r)
101029832Ssam 			 * meaning *0(%r)
101129832Ssam 			 */
101229832Ssam 			if (ap->a_atype == ABASE) {
101329832Ssam 				ap->a_atype = ADISP;
101429832Ssam 				xp->e_xtype = XABS;
101529832Ssam 				xp->e_number = Znumber;
101629832Ssam 				xp->e_number.num_tag = TYPL;
101729832Ssam 				xp->e_xloc = 0;
101829832Ssam 				ap->a_xp = xp++;
101929832Ssam 			}
102029832Ssam 			ap->a_atype |= ASTAR;
102129832Ssam 			sawmul = 0;
102229832Ssam 	    }
102329832Ssam 	    if (sawindex){
102429832Ssam 		ap->a_atype |= AINDX;
102529832Ssam 		sawindex = 0;
102629832Ssam 	    }
102729832Ssam 	    ap->a_dispsize = sawsize == 0 ? d124 : sawsize;
102829832Ssam 		if (val != CM) break;
102929832Ssam 		shiftover(CM);
103029832Ssam 	}	/*processing all the arguments*/
103129832Ssam 
103229832Ssam 	if (argcnt > 6){
103329832Ssam 		yyerror("More than 6 arguments");
103429832Ssam 		goto errorfix;
103529832Ssam 	}
103629832Ssam 
103729832Ssam 	/*
103829832Ssam 	 *	See if this is a case instruction,
103929832Ssam 	 *	so we can set up tests on the following
104029832Ssam 	 *	vector of branch displacements
104129832Ssam 	 */
104229832Ssam 	if (yyopcode == 0xfc)	/* 'casel' instruction */
104329832Ssam 		incasetable++;
104429832Ssam 	else
104529832Ssam 		incasetable = 0;
104629832Ssam 
104729832Ssam 	insout(yyopcode, arglist,
104829832Ssam 		auxval == INSTn ? argcnt : - argcnt);
104929832Ssam 	break;
105029832Ssam 
105129832Ssam    case IQUAD:		num_type = TYPQ;	goto bignumlist;
105229832Ssam    case IFFLOAT:	num_type = TYPF;	goto bignumlist;
105329832Ssam    case IDFLOAT:	num_type = TYPD;
105429832Ssam    bignumlist:
105529832Ssam 	/*
105629832Ssam 	 *	eat a list of non 32 bit numbers.
105729832Ssam 	 *	IQUAD can, possibly, return
105829832Ssam 	 *	INT's, if the numbers are "small".
105929832Ssam 	 *
106029832Ssam 	 *	The value of the numbers is coming back
106129832Ssam 	 *	as an expression, NOT in yybignum.
106229832Ssam 	 */
106329832Ssam 	shift;	/* over the opener */
106429832Ssam 	if ((val == BIGNUM) || (val == INT)){
106529832Ssam 		do{
106629832Ssam 			if ((val != BIGNUM) && (val != INT)){
106729832Ssam 				ERROR(ty_float[num_type]
106829832Ssam 				   ? "floating number expected"
106929832Ssam 				   : "integer number expected" );
107029832Ssam 			}
107129832Ssam 			dotp->e_xvalue += ty_nbyte[num_type];
107229832Ssam 			if (passno == 2){
107329832Ssam 			   switch (num_type) {
107429832Ssam 				case TYPF:
107534576Skarels 					bwrite(((struct exp *)yylval)->e_number.num_num.numFf_float.Ff_ulong,
107629832Ssam 						ty_nbyte[num_type], txtfil);
107729832Ssam 					if (liston)
107829832Ssam 					{
107929832Ssam 				  	 long_out(((struct exp *)yylval)->e_number.num_num.numFf_float.Ff_ulong[0]);
108029832Ssam 					 *layoutpos++ = ' ';
108129832Ssam 					}
108229832Ssam 					break;
108329832Ssam 				case TYPD:
108429832Ssam 					bwrite(&((struct exp *)yylval)->e_number.num_num.numFd_float.Fd_ulong[0],
108529832Ssam 						sizeof (long), txtfil);
108629832Ssam 					bwrite(&((struct exp *)yylval)->e_number.num_num.numFd_float.Fd_ulong[1],
108729832Ssam 						sizeof (long), txtfil);
108829832Ssam 					if (liston)
108929832Ssam 					{
109029832Ssam 				  	 long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0]);
109129832Ssam 				  	 long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1]);
109229832Ssam 					 *layoutpos++ = ' ';
109329832Ssam 					}
109429832Ssam 					break;
109529832Ssam 				case TYPQ:
109629832Ssam 					bwrite(&((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1],
109729832Ssam 						sizeof (long), txtfil);
109829832Ssam 					bwrite(&((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0],
109929832Ssam 						sizeof (long), txtfil);
110029832Ssam 					if (liston)
110129832Ssam 					{
110229832Ssam 				  	 long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[1]);
110329832Ssam 				  	 long_out(((struct exp *)yylval)->e_number.num_num.numIq_int.Iq_ulong[0]);
110429832Ssam 					 *layoutpos++ = ' ';
110529832Ssam 					}
110629832Ssam 					break;
110729832Ssam 			   }
110829832Ssam 			}
110929832Ssam 			xp = explist;
111029832Ssam 			shift;		/* over this number */
111129832Ssam 			if (auxval = (val == CM))
111229832Ssam 				shift;	/* over the comma */
111329832Ssam 		} while (auxval);	/* as long as there are commas */
111429832Ssam 	}
111529832Ssam 	break;
111629832Ssam 	/* end of the case for initialized big numbers */
111729832Ssam     }	/*end of the switch for looking at each reserved word*/
111829832Ssam 
111929832Ssam 	continue;
112029832Ssam 
112129832Ssam    errorfix:
112229832Ssam 	/*
112329832Ssam 	 *	got here by either requesting to skip to the
112429832Ssam 	 *	end of this statement, or by erroring out and
112529832Ssam 	 *	wanting to apply panic mode recovery
112629832Ssam 	 */
112729832Ssam 	while (    (val != NL)
112829832Ssam 		&& (val != SEMI)
112929832Ssam 		&& (val != PARSEEOF)
113029832Ssam 	      ){
113129832Ssam 		shift;
113229832Ssam 	}
113329832Ssam 	if (val == NL)
113429832Ssam 		lineno++;
113529832Ssam 	shift;
113629832Ssam 
113729832Ssam     }	/*end of the loop to read the entire file, line by line*/
113829832Ssam 
113929832Ssam }	/*end of yyparse*/
114029832Ssam 
114129832Ssam /*
114229832Ssam  *	Process a register declaration of the form
114329832Ssam  *	% <expr>
114429832Ssam  *
114529832Ssam  *	Note:
114629832Ssam  *		The scanner has already processed funny registers of the form
114729832Ssam  *	%dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional
114829832Ssam  *	preceding zero digit).  If there was any space between the % and
114929832Ssam  *	the digit, the scanner wouldn't have recognized it, so we
115029832Ssam  *	hack it out here.
115129832Ssam  */
funnyreg(val,regnoback)115229832Ssam inttoktype funnyreg(val, regnoback)	/*what the read head will sit on*/
115329832Ssam 	inttoktype	val;		/*what the read head is sitting on*/
115429832Ssam 	int	*regnoback;		/*call by return*/
115529832Ssam {
115629832Ssam 	reg	struct	exp *locxp;
115729832Ssam 		struct	exp *loc1xp;
115829832Ssam 		struct	exp **ptrloc1xp = & loc1xp;
115929832Ssam 
116029832Ssam 	expr(locxp, val);	/*and leave the current read head with value*/
116129832Ssam 	if ( (passno == 2) &&
116229832Ssam 	    (   (locxp->e_xtype & XTYPE) != XABS
116329832Ssam 	     || (locxp->e_xvalue < 0)
116429832Ssam 	     || (locxp->e_xvalue >= 16)
116529832Ssam 	    )
116629832Ssam 	  ){
116729832Ssam 		yyerror("Illegal register");
116829832Ssam 		return(0);
116929832Ssam 	}
117029832Ssam 	*regnoback = locxp->e_xvalue;
117129832Ssam 	return(val);
117229832Ssam }
117329832Ssam /*
117429832Ssam  *	Shift over error
117529832Ssam  */
shiftoerror(token)117629832Ssam shiftoerror(token)
117729832Ssam 	int	token;
117829832Ssam {
117929832Ssam 	char	*tok_to_name();
118029832Ssam 	yyerror("%s expected", tok_to_name(token));
118129832Ssam }
118229832Ssam 
118329832Ssam /*VARARGS1*/
yyerror(s,a1,a2,a3,a4,a5)118429832Ssam yyerror(s, a1, a2,a3,a4,a5)
118529832Ssam 	char	*s;
118629832Ssam {
118729832Ssam 
118829832Ssam #define	sink stdout
118929832Ssam 
119029832Ssam 	if (anyerrs == 0 && anywarnings == 0 && ! silent)
119129832Ssam 		fprintf(sink, "Assembler:\n");
119229832Ssam 	anyerrs++;
119329832Ssam 	if (silent)
119429832Ssam 		return;
119529832Ssam 	fprintf(sink, "\"%s\", line %d: ", dotsname, lineno);
119629832Ssam 	fprintf(sink, s, a1, a2,a3,a4,a5);
119729832Ssam 	fprintf(sink, "\n");
119829832Ssam #undef sink
119929832Ssam }
120029832Ssam 
120129832Ssam /*VARARGS1*/
yywarning(s,a1,a2,a3,a4,a5)120229832Ssam yywarning(s, a1, a2,a3,a4,a5)
120329832Ssam 	char	*s;
120429832Ssam {
120529832Ssam #define	sink stdout
120629832Ssam 	if (anyerrs == 0 && anywarnings == 0 && ! silent)
120729832Ssam 		fprintf(sink, "Assembler:\n");
120829832Ssam 	anywarnings++;
120929832Ssam 	if (silent)
121029832Ssam 		return;
121129832Ssam 	fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno);
121229832Ssam 	fprintf(sink, s, a1, a2,a3,a4,a5);
121329832Ssam 	fprintf(sink, "\n");
121429832Ssam #undef sink
121529832Ssam }
1216