xref: /csrg-svn/old/as.vax/asparse.c (revision 13274)
15827Srrh /*
25827Srrh  *	Copyright (c) 1982 Regents of the University of California
35827Srrh  */
45827Srrh #ifndef lint
5*13274Srrh static char sccsid[] = "@(#)asparse.c 4.11 06/24/83";
65827Srrh #endif not lint
75827Srrh 
8597Sbill #include <stdio.h>
9597Sbill #include "as.h"
10597Sbill #include "asscan.h"
11597Sbill #include "assyms.h"
125827Srrh #include "asexpr.h"
13597Sbill 
14597Sbill int	lgensym[10];
15597Sbill char	genref[10];
16597Sbill 
17597Sbill long	bitfield;
18597Sbill int	bitoff;
19597Sbill int	curlen;			/* current length of literals */
20597Sbill 
21597Sbill /*
22597Sbill  *	The following three variables are communication between various
23597Sbill  *	modules to special case a number of things.  They are properly
24597Sbill  *	categorized as hacks.
25597Sbill  */
26597Sbill extern	struct	symtab *lastnam;/*last name seen by the lexical analyzer*/
27597Sbill int	exprisname;		/*last factor in an expression was a name*/
28597Sbill int	droppedLP;		/*one is analyzing an expression beginning with*/
29597Sbill 				/*a left parenthesis, which has already been*/
30597Sbill 				/*shifted. (Used to parse (<expr>)(rn)*/
31597Sbill 
32597Sbill char	yytext[NCPS+2];		/*the lexical image*/
33597Sbill int	yylval;			/*the lexical value; sloppy typing*/
345827Srrh struct	Opcode		yyopcode;	/* lexical value for an opcode */
355827Srrh Bignum	yybignum;		/* lexical value for a big number */
36597Sbill /*
37597Sbill  *	Expression and argument managers
38597Sbill  */
39597Sbill struct	exp	*xp;		/*next free expression slot, used by expr.c*/
40597Sbill struct	exp	explist[NEXP];	/*max of 20 expressions in one opcode*/
41597Sbill struct	arg	arglist[NARG];	/*building up operands in instructions*/
42597Sbill /*
43597Sbill  *	Sets to accelerate token discrimination
44597Sbill  */
45597Sbill char	tokensets[(LASTTOKEN) - (FIRSTTOKEN) + 1];
46597Sbill 
47597Sbill static	char	UDotsname[32];	/*name of the assembly source*/
48597Sbill 
495827Srrh yyparse()
50597Sbill {
515827Srrh 	reg	struct	exp	*locxp;
525827Srrh 		/*
535827Srrh 		 *	loc1xp and ptrloc1xp are used in the
545827Srrh 		 * 	expression lookahead
555827Srrh 		 */
565827Srrh 		struct	exp	*loc1xp;	/*must be non register*/
575827Srrh 		struct	exp	**ptrloc1xp = & loc1xp;
585827Srrh 		struct	exp	*pval;		/*hacking expr:expr*/
59597Sbill 
605827Srrh 	reg	struct	symtab	*np;
615827Srrh 	reg	int		argcnt;
62597Sbill 
635827Srrh 	reg	inttoktype	val;		/*what yylex gives*/
645827Srrh 	reg	inttoktype	auxval;		/*saves val*/
65597Sbill 
665827Srrh 	reg	struct 	arg	*ap;		/*first free argument*/
67597Sbill 
685827Srrh 	reg	struct	symtab	*p;
695827Srrh 	reg	struct	symtab	*stpt;
70597Sbill 
715827Srrh 		struct	strdesc	*stringp;	/*handles string lists*/
72597Sbill 
735827Srrh 		int	regno;		/*handles arguments*/
745827Srrh 		int	*ptrregno = &regno;
755827Srrh 		int	sawmul;		/*saw * */
765827Srrh 		int	sawindex;	/*saw [rn]*/
775827Srrh 		int	sawsize;
785827Srrh 		int	seg_type; 	/*the kind of segment: data or text*/
795827Srrh 		int	seg_number;	/*the segment number*/
805827Srrh 		int	space_value;	/*how much .space needs*/
815827Srrh 		int	fill_rep;	/*how many reps for .fill */
825827Srrh 		int	fill_size;	/*how many bytes for .fill */
83597Sbill 
845827Srrh 		int	field_width;	/*how wide a field is to be*/
855827Srrh 		int	field_value;	/*the value to stuff in a field*/
865827Srrh 		char	*stabname;	/*name of stab dealing with*/
875827Srrh 		ptrall	stabstart;	/*where the stab starts in the buffer*/
885827Srrh 		int	reloc_how;	/* how to relocate expressions */
895827Srrh 		int	toconv;		/* how to convert bignums */
90*13274Srrh 		int	incasetable;	/* set if in a case table */
91597Sbill 
92*13274Srrh 	incasetable = 0;
93597Sbill 	xp = explist;
94597Sbill 	ap = arglist;
95597Sbill 
96597Sbill 	val = yylex();
97597Sbill 
98597Sbill     while (val != PARSEEOF){	/* primary loop */
99597Sbill 
100597Sbill 	while (INTOKSET(val, LINSTBEGIN)){
101597Sbill 		if (val == INT) {
102632Shenry 			int i = ((struct exp *)yylval)->e_xvalue;
103597Sbill 			shift;
1045827Srrh 			if (val != COLON){
1055827Srrh 				yyerror("Local label %d is not followed by a ':' for a label definition",
1065827Srrh 					i);
1075827Srrh 				goto  errorfix;
1085827Srrh 			}
109597Sbill 			if (i < 0 || i > 9) {
110597Sbill 				yyerror("Local labels are 0-9");
111597Sbill 				goto errorfix;
112597Sbill 			}
1135827Srrh 			(void)sprintf(yytext, "L%d\001%d", i, lgensym[i]);
114597Sbill 			lgensym[i]++;
115597Sbill 			genref[i] = 0;
116597Sbill 			yylval = (int)*lookup(passno == 1);
117597Sbill 			val = NAME;
118597Sbill 			np = (struct symtab *)yylval;
119597Sbill 			goto restlab;
120597Sbill 		}
121597Sbill 		if (val == NL){
122597Sbill 			lineno++;
123597Sbill 			shift;
124597Sbill 		} else
125597Sbill 		if (val == SEMI)
126597Sbill 			shift;
127597Sbill 		else {	/*its a name, so we have a label or def */
128597Sbill 			if (val != NAME){
129597Sbill 				ERROR("Name expected for a label");
130597Sbill 			}
131597Sbill 			np = (struct symtab *)yylval;
132597Sbill 			shiftover(NAME);
133597Sbill 			if (val != COLON) {
134632Shenry #ifdef FLEXNAMES
135597Sbill 				yyerror("\"%s\" is not followed by a ':' for a label definition",
136632Shenry #else not FLEXNAMES
137632Shenry 				yyerror("\"%.*s\" is not followed by a ':' for a label definition",
138632Shenry 					NCPS,
139632Shenry #endif not FLEXNAMES
140632Shenry 					np->s_name);
141597Sbill 				goto  errorfix;
142597Sbill 			}
143597Sbill restlab:
144597Sbill 			shift;
145597Sbill 			flushfield(NBPW/4);
146632Shenry 			if ((np->s_type&XTYPE)!=XUNDEF) {
147632Shenry 				if(  (np->s_type&XTYPE)!=dotp->e_xtype
148632Shenry 				   || np->s_value!=dotp->e_xvalue
149597Sbill 				   || (  (passno==1)
150632Shenry 				       &&(np->s_index != dotp->e_xloc)
151597Sbill 				      )
152597Sbill 				  ){
153597Sbill #ifndef DEBUG
154632Shenry 					if (np->s_name[0] != 'L')
155597Sbill #endif not DEBUG
156597Sbill 					{
157597Sbill 						if (passno == 1)
158632Shenry #ifdef FLEXNAMES
159632Shenry 						  yyerror("%s redefined",
160632Shenry #else not FLEXNAMES
161632Shenry 						  yyerror("%.*s redefined",
162632Shenry 							NCPS,
163632Shenry #endif not FLEXNAMES
164632Shenry 							np->s_name);
165597Sbill 						else
166632Shenry #ifdef FLEXNAMES
167632Shenry 						  yyerror("%s redefined: PHASE ERROR, 1st: %d, 2nd: %d",
168632Shenry #else not FLEXNAMES
169632Shenry 						  yyerror("%.*s redefined: PHASE ERROR, 1st: %d, 2nd: %d",
170632Shenry 							NCPS,
171632Shenry #endif not FLEXNAMES
172632Shenry 							np->s_name,
173632Shenry 							np->s_value,
174632Shenry 							dotp->e_xvalue);
175597Sbill 					}
176597Sbill 				}
177597Sbill 			}
178632Shenry 			np->s_type &= ~(XTYPE|XFORW);
179632Shenry 			np->s_type |= dotp->e_xtype;
180632Shenry 			np->s_value = dotp->e_xvalue;
181597Sbill 			if (passno == 1){
182632Shenry 				np->s_index = dotp-usedot;
183632Shenry 				if (np->s_name[0] == 'L'){
184597Sbill 					nlabels++;
185597Sbill 				}
186632Shenry 				np->s_tag = LABELID;
187597Sbill 			}
188597Sbill 		}	/*end of this being a label*/
189597Sbill 	}	/*end of to consuming all labels, NLs and SEMIS */
190597Sbill 
191597Sbill 	xp = explist;
192597Sbill 	ap = arglist;
193597Sbill 
194597Sbill 	/*
195597Sbill 	 *	process the INSTRUCTION body
196597Sbill 	 */
197597Sbill 	switch(val){
198597Sbill 
199597Sbill     default:
200597Sbill 	ERROR("Unrecognized instruction or directive");
201597Sbill 
202597Sbill    case IABORT:
203597Sbill 	shift;
204597Sbill 	sawabort();
205597Sbill 	/*NOTREACHED*/
206597Sbill 	break;
207597Sbill 
208597Sbill    case PARSEEOF:
2095827Srrh 	tokptr -= sizeof(bytetoktype);
210597Sbill 	*tokptr++ = VOID;
211597Sbill 	tokptr[1] = VOID;
212597Sbill 	tokptr[2] = PARSEEOF;
213597Sbill 	break;
214597Sbill 
215597Sbill    case IFILE:
216597Sbill 	shift;
217597Sbill 	stringp = (struct strdesc *)yylval;
218597Sbill 	shiftover(STRING);
219597Sbill 	dotsname = &UDotsname[0];
220597Sbill 	movestr(dotsname, stringp->str,
221597Sbill 		stringp->str_lg >= 32? 32 :stringp->str_lg);
222597Sbill 	dotsname[stringp->str_lg] = '\0';
223597Sbill 	break;
224597Sbill 
225597Sbill    case ILINENO:
226597Sbill 	shift;		/*over the ILINENO*/
227597Sbill 	expr(locxp, val);
228632Shenry 	lineno = locxp->e_xvalue;
229597Sbill 	break;
230597Sbill 
231597Sbill    case ISET: 	/* .set  <name> , <expr> */
232597Sbill 	shift;
233597Sbill 	np = (struct symtab *)yylval;
234597Sbill 	shiftover(NAME);
235597Sbill 	shiftover(CM);
236597Sbill 	expr(locxp, val);
237632Shenry 	np->s_type &= (XXTRN|XFORW);
238632Shenry 	np->s_type |= locxp->e_xtype&(XTYPE|XFORW);
239632Shenry 	np->s_value = locxp->e_xvalue;
240597Sbill 	if (passno==1)
241632Shenry 		np->s_index = locxp->e_xloc;
242632Shenry 	if ((locxp->e_xtype&XTYPE) == XUNDEF)
243597Sbill 		yyerror("Illegal set?");
244597Sbill 	break;
245597Sbill 
246597Sbill    case ILSYM: 	/*.lsym name , expr */
247597Sbill 	shift;
248597Sbill 	np = (struct symtab *)yylval;
249597Sbill 	shiftover(NAME);
250597Sbill 	shiftover(CM);
251597Sbill 	expr(locxp, val);
252597Sbill 	/*
253597Sbill 	 *	Build the unique occurance of the
254597Sbill 	 *	symbol.
255597Sbill 	 *	The character scanner will have
256597Sbill 	 *	already entered it into the symbol
257597Sbill 	 *	table, but we should remove it
258597Sbill 	 */
259597Sbill 	if (passno == 1){
260597Sbill 		stpt = (struct symtab *)symalloc();
261597Sbill #ifdef FLEXNAMES
262632Shenry 		stpt->s_name = np->s_name;
263597Sbill #else
264632Shenry 		movestr(stpt->s_name, np->s_name, NCPS);
265597Sbill #endif
266632Shenry 		np->s_tag = OBSOLETE;	/*invalidate original */
267597Sbill 		nforgotten++;
268597Sbill 		np = stpt;
2695827Srrh 		if ( (locxp->e_xtype & XTYPE) != XABS)
2705827Srrh 			yyerror("Illegal second argument to lsym");
2715827Srrh 		np->s_value = locxp->e_xvalue;
2725827Srrh 		np->s_type = XABS;
273632Shenry 		np->s_tag = ILSYM;
274597Sbill 	}
275597Sbill 	break;
276597Sbill 
277597Sbill    case IGLOBAL: 	/*.globl <name> */
278597Sbill 	shift;
279597Sbill 	np = (struct symtab *)yylval;
280597Sbill 	shiftover(NAME);
281632Shenry 	np->s_type |= XXTRN;
282597Sbill 	break;
283597Sbill 
284597Sbill    case IDATA: 	/*.data [ <expr> ] */
285597Sbill    case ITEXT: 	/*.text [ <expr> ] */
286597Sbill 	seg_type = -val;
287597Sbill 	shift;
288597Sbill 	if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){
289597Sbill 		expr(locxp, val);
290597Sbill 		seg_type = -seg_type;   /*now, it is positive*/
291597Sbill 	}
292597Sbill 
293597Sbill 	if (seg_type < 0) {	/*there wasn't an associated expr*/
294597Sbill 		seg_number = 0;
295597Sbill 		seg_type = -seg_type;
296597Sbill 	} else {
2975827Srrh 		if (   ((locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
2985827Srrh 		    || (seg_number = locxp->e_xvalue) >= NLOC) {
299597Sbill 			yyerror("illegal location counter");
300597Sbill 			seg_number = 0;
301597Sbill 		}
302597Sbill 	}
303597Sbill 	if (seg_type == IDATA)
304597Sbill 		seg_number += NLOC;
305597Sbill 	flushfield(NBPW/4);
306597Sbill 	dotp = &usedot[seg_number];
307597Sbill #ifdef UNIX
308597Sbill 	if (passno==2) {	/* go salt away in pass 2*/
309597Sbill 		txtfil = usefile[seg_number];
310597Sbill 		relfil = rusefile[seg_number];
311597Sbill 	}
312597Sbill #endif UNIX
313597Sbill #ifdef VMS
314597Sbill 	if (passno==2) {
315597Sbill 		puchar(vms_obj_ptr,6);		/*  setpl  */
316597Sbill 		puchar(vms_obj_ptr,seg_number);	/* psect # */
317632Shenry 		plong(vms_obj_ptr,dotp->e_xvalue);/*  offset */
318597Sbill 		puchar(vms_obj_ptr,80);		/*  setrb  */
319597Sbill 		if((vms_obj_ptr-sobuf) > 400){
320597Sbill 			write(objfil,sobuf,vms_obj_ptr-sobuf);
321597Sbill 			vms_obj_ptr=sobuf+1;	/*flush buf*/
322597Sbill 		}
323597Sbill 	}
324597Sbill #endif VMS
325597Sbill 	break;
326597Sbill 
327597Sbill 	/*
328597Sbill 	 *	Storage filler directives:
329597Sbill 	 *
330597Sbill 	 *	.byte	[<exprlist>]
331597Sbill 	 *
332597Sbill 	 *	exprlist:  empty | exprlist outexpr
333597Sbill 	 *	outexpr:   <expr> | <expr> : <expr>
334597Sbill 	 */
335597Sbill    case IBYTE:	curlen = NBPW/4; goto elist;
3365827Srrh    case IWORD:	curlen = NBPW/2; goto elist;
3375827Srrh    case IINT:	curlen = NBPW;   goto elist;
338597Sbill    case ILONG:	curlen = NBPW;   goto elist;
339597Sbill 
340597Sbill    elist:
341597Sbill 	seg_type = val;
342597Sbill 	shift;
343597Sbill 
344597Sbill 	/*
345597Sbill 	 *	Expression List processing
346597Sbill 	 */
347597Sbill 	if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){
348597Sbill 	    do{
349597Sbill 		/*
350597Sbill 		 *	expression list consists of a list of :
351597Sbill 		 *	<expr>
352597Sbill 		 *	<expr> : <expr>
353597Sbill 		 *		(pack expr2 into expr1 bits
354597Sbill 		 */
355597Sbill 		expr(locxp, val);
356597Sbill 		/*
357597Sbill 		 *	now, pointing at the next token
358597Sbill 		 */
359597Sbill 		if (val == COLON){
360597Sbill 			shiftover(COLON);
361597Sbill 			expr(pval, val);
3625827Srrh 			if ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */
3635827Srrh 				yyerror("Width not absolute");
364632Shenry 			field_width = locxp->e_xvalue;
365597Sbill 			locxp = pval;
3665827Srrh 			if (bitoff + field_width > curlen)
367597Sbill 				flushfield(curlen);
368597Sbill 			if (field_width > curlen)
369597Sbill 				yyerror("Expression crosses field boundary");
370597Sbill 		} else {
371597Sbill 			field_width = curlen;
372597Sbill 			flushfield(curlen);
373597Sbill 		}
374597Sbill 
3755827Srrh 		if ((locxp->e_xtype & XTYPE) != XABS) {
376597Sbill 			if (bitoff)
377597Sbill 				yyerror("Illegal relocation in field");
378674Shenry 			switch(curlen){
379674Shenry 				case NBPW/4:	reloc_how = TYPB; break;
380674Shenry 				case NBPW/2:	reloc_how = TYPW; break;
381674Shenry 				case NBPW:	reloc_how = TYPL; break;
382674Shenry 			}
383597Sbill 			if (passno == 1){
384674Shenry 				dotp->e_xvalue += ty_nbyte[reloc_how];
385597Sbill 			} else {
386674Shenry 				outrel(locxp, reloc_how);
387597Sbill 			}
388597Sbill 		} else {
389*13274Srrh 			/*
390*13274Srrh 			 *
391*13274Srrh 			 *	See if we are doing a case instruction.
392*13274Srrh 			 *	If so, then see if the branch distance,
393*13274Srrh 			 *	stored as a word,
394*13274Srrh 			 *	is going to loose sig bits.
395*13274Srrh 			 */
396*13274Srrh 			if (passno == 2 && incasetable){
397*13274Srrh 				if (  (locxp->e_xvalue < -32768)
398*13274Srrh 				    ||(locxp->e_xvalue > 32767)){
399*13274Srrh 					yyerror("Case will branch too far");
400*13274Srrh 				}
401*13274Srrh 			}
402632Shenry 			field_value = locxp->e_xvalue & ( (1L << field_width)-1);
403597Sbill 			bitfield |= field_value << bitoff;
404597Sbill 			bitoff += field_width;
405597Sbill 		}
406597Sbill 		xp = explist;
4075827Srrh 		if (auxval = (val == CM))
4085827Srrh 			shift;
409597Sbill 	    } while (auxval);
4105827Srrh 	}	/* there existed an expression at all */
411597Sbill 
412597Sbill 	flushfield(curlen);
413597Sbill 	if ( ( curlen == NBPW/4) && bitoff)
414632Shenry 		dotp->e_xvalue ++;
415597Sbill 	break;
416597Sbill 	/*end of case IBYTE, IWORD, ILONG, IINT*/
417597Sbill 
418597Sbill    case ISPACE: 	/* .space <expr> */
419597Sbill 	shift;
420597Sbill 	expr(locxp, val);
4215827Srrh 	if ((locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
422597Sbill 		yyerror("Space size not absolute");
423632Shenry 	space_value = locxp->e_xvalue;
424597Sbill   ospace:
425597Sbill 	flushfield(NBPW/4);
426597Sbill #ifdef UNIX
427597Sbill 	while (space_value > 96){
428597Sbill 		outs(strbuf[2].str, 96);
429597Sbill 		space_value -= 96;
430597Sbill 	}
431597Sbill 	outs(strbuf[2].str, space_value);
432597Sbill #endif UNIX
433597Sbill #ifdef VMS
434632Shenry 	dotp->e_xvalue += space_value;		/*bump pc*/
435597Sbill 	if (passno==2){
436597Sbill 	  if(*(strbuf[2].str)==0) {
437597Sbill 		puchar(vms_obj_ptr,81);		/* AUGR  */
438597Sbill 		pulong(vms_obj_ptr,space_value);/* incr  */
439597Sbill 	  } else yyerror("VMS, encountered non-0 .space");
440597Sbill 	  if ((vms_obj_ptr-sobuf) > 400) {
441597Sbill 		write(objfil,sobuf,vms_obj_ptr-sobuf);
442597Sbill 		vms_obj_ptr=sobuf+1;		/*pur buf*/
443597Sbill 	  }
444597Sbill 	}
445597Sbill #endif VMS
446597Sbill 	break;
447597Sbill 
448597Sbill #ifdef UNIX
449647Shenry 	/*
450647Shenry 	 *	.fill rep, size, value
451647Shenry 	 *	repeat rep times: fill size bytes with (truncated) value
452647Shenry 	 *	size must be between 1 and 8
453647Shenry 	 */
454647Shenry    case	IFILL:
455597Sbill 	shift;
456597Sbill 	expr(locxp, val);
4575827Srrh 	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
458597Sbill 		yyerror("Fill repetition count not absolute");
459647Shenry 	fill_rep = locxp->e_xvalue;
460597Sbill 	shiftover(CM);
461597Sbill 	expr(locxp, val);
4625827Srrh 	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
463647Shenry 		yyerror("Fill size not absolute");
464647Shenry 	fill_size = locxp->e_xvalue;
465647Shenry 	if (fill_size <= 0 || fill_size > 8)
466647Shenry 		yyerror("Fill count not in in 1..8");
467647Shenry 	shiftover(CM);
468647Shenry 	expr(locxp, val);
4695827Srrh 	if (passno == 2 && (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
4705827Srrh 		yyerror("Fill value not absolute");
471597Sbill 	flushfield(NBPW/4);
472647Shenry 	if (passno == 1) {
4735827Srrh 		dotp->e_xvalue += fill_rep * fill_size;
474647Shenry 	} else {
475647Shenry 		while(fill_rep-- > 0)
4765827Srrh 			bwrite((char *)&locxp->e_xvalue, fill_size, txtfil);
477647Shenry 	}
478597Sbill 	break;
479597Sbill #endif UNIX
480597Sbill 
481597Sbill    case IASCII:	/* .ascii [ <stringlist> ] */
482597Sbill    case IASCIZ: 	/* .asciz [ <stringlist> ] */
483597Sbill 	auxval = val;
484597Sbill 	shift;
485597Sbill 
486597Sbill 	/*
487597Sbill 	 *	Code to consume a string list
488597Sbill 	 *
489597Sbill 	 *	stringlist: empty | STRING | stringlist STRING
490597Sbill 	 */
491597Sbill 	while (val ==  STRING){
492597Sbill 		flushfield(NBPW/4);
493597Sbill 		if (bitoff)
494632Shenry 		  dotp->e_xvalue++;
495597Sbill 		stringp = (struct strdesc *)yylval;
496597Sbill #ifdef UNIX
497597Sbill 		outs(stringp->str, stringp->str_lg);
498597Sbill #endif UNIX
499597Sbill #ifdef VMS
500597Sbill 		{
5015827Srrh 			reg int i;
502597Sbill 			for (i=0; i < stringp->str_lg; i++){
503632Shenry 			  dotp->e_xvalue += 1;
504597Sbill 			    if (passno==2){
505597Sbill 				puchar(vms_obj_ptr,-1);
506597Sbill 			  	puchar(vms_obj_ptr,stringp->str[i]);
507597Sbill 			  	if (vms_obj_ptr-sobuf > 400) {
508597Sbill 				  write(objfil,sobuf,vms_obj_ptr-sobuf);
509597Sbill 				  vms_obj_ptr = sobuf + 1;
510597Sbill 			  	}
511597Sbill 			    }
512597Sbill 			}
513597Sbill 		}
514597Sbill #endif VMS
515597Sbill 		shift;		/*over the STRING*/
516597Sbill 		if (val == CM)	/*could be a split string*/
517597Sbill 			shift;
518597Sbill 	}
519597Sbill 
520597Sbill 	if (auxval == IASCIZ){
521597Sbill 		flushfield(NBPW/4);
522597Sbill #ifdef UNIX
523597Sbill 		outb(0);
524597Sbill #endif UNIX
525597Sbill #ifdef VMS
526597Sbill 		if (passno == 2) {
527597Sbill 			puchar(vms_obj_ptr,-1);
528597Sbill 			puchar(vms_obj_ptr,0);
529597Sbill 		}
530632Shenry 		dotp->e_xvalue += 1;
531597Sbill #endif VMS
532597Sbill 	}
533597Sbill 	break;
534597Sbill 
535597Sbill    case IORG: 	/* .org <expr> */
536597Sbill 	shift;
537597Sbill 	expr(locxp, val);
538597Sbill 
5395827Srrh 	if ((locxp->e_xtype & XTYPE) == XABS)	/* tekmdp */
540597Sbill 		orgwarn++;
541632Shenry 	else if ((locxp->e_xtype & ~XXTRN) != dotp->e_xtype)
542597Sbill 		yyerror("Illegal expression to set origin");
543632Shenry 	space_value = locxp->e_xvalue - dotp->e_xvalue;
544597Sbill 	if (space_value < 0)
545597Sbill 		yyerror("Backwards 'org'");
546597Sbill 	goto ospace;
547597Sbill 	break;
548597Sbill 
549597Sbill /*
550597Sbill  *
551597Sbill  *	Process stabs.  Stabs are created only by the f77
552597Sbill  *	and the C compiler with the -g flag set.
553597Sbill  *	We only look at the stab ONCE, during pass 1, and
554597Sbill  *	virtually remove the stab from the intermediate file
555597Sbill  *	so it isn't seen during pass2.  This makes for some
556597Sbill  *	hairy processing to handle labels occuring in
557597Sbill  *	stab entries, but since most expressions in the
558597Sbill  *	stab are integral we save lots of time in the second
559597Sbill  *	pass by not looking at the stabs.
560597Sbill  *	A stab that is tagged floating will be bumped during
561597Sbill  *	the jxxx resolution phase.  A stab tagged fixed will
562597Sbill  *	not be be bumped.
563597Sbill  *
564597Sbill  *	.stab:	Old fashioned stabs
565597Sbill  *	.stabn: For stabs without names
566597Sbill  *	.stabs:	For stabs with string names
567597Sbill  *	.stabd: For stabs for line numbers or bracketing,
568597Sbill  *		without a string name, without
569597Sbill  *		a final expression.  The value of the
570597Sbill  *		final expression is taken to be  the current
571597Sbill  *		location counter, and is patched by the 2nd pass
572597Sbill  *
573674Shenry  *	.stab{<expr>,}*NCPS,<expr>, <expr>, <expr>, <expr>
574597Sbill  *	.stabn		 <expr>, <expr>, <expr>, <expr>
575597Sbill  *	.stabs   STRING, <expr>, <expr>, <expr>, <expr>
576597Sbill  *	.stabd		 <expr>, <expr>, <expr> # .
577597Sbill  */
578597Sbill    case ISTAB:
579597Sbill #ifndef FLEXNAMES
580597Sbill 	stabname = ".stab";
581597Sbill 	if (passno == 2)	goto errorfix;
582597Sbill 	stpt = (struct symtab *)yylval;
583597Sbill 	/*
584597Sbill 	 *	Make a pointer to the .stab slot.
585597Sbill 	 *	There is a pointer in the way (stpt), and
586597Sbill 	 *	tokptr points to the next token.
587597Sbill 	 */
588597Sbill 	stabstart = tokptr;
589597Sbill 	(char *)stabstart -= sizeof(struct symtab *);
5905827Srrh 	(char *)stabstart -= sizeof(bytetoktype);
591597Sbill 	shift;
592674Shenry 	for (argcnt = 0; argcnt < NCPS; argcnt++){
593597Sbill 		expr(locxp, val);
594632Shenry 		stpt->s_name[argcnt] = locxp->e_xvalue;
595597Sbill 		xp = explist;
596597Sbill 		shiftover(CM);
597597Sbill 	}
598597Sbill 	goto tailstab;
599597Sbill #else	FLEXNAMES
600597Sbill 	yyerror(".stab directive not supported in; report this compiler bug to system administrator");
601597Sbill 	goto errorfix;
602597Sbill #endif FLEXNAMES
603597Sbill 
604597Sbill   tailstab:
605597Sbill 	expr(locxp, val);
606632Shenry 	if (! (locxp->e_xvalue & STABTYPS)){
6075827Srrh 		yyerror("Invalid type in %s", stabname);
608597Sbill 		goto errorfix;
609597Sbill 	}
610632Shenry 	stpt->s_ptype = locxp->e_xvalue;
611597Sbill 	shiftover(CM);
612597Sbill 	expr(locxp, val);
613632Shenry 	stpt->s_other = locxp->e_xvalue;
614597Sbill 	shiftover(CM);
615597Sbill 	expr(locxp, val);
616632Shenry 	stpt->s_desc = locxp->e_xvalue;
617597Sbill 	shiftover(CM);
618597Sbill 	exprisname = 0;
619597Sbill 	expr(locxp, val);
620632Shenry 	p = locxp->e_xname;
621597Sbill 	if (p == NULL) {	/*absolute expr to begin with*/
622632Shenry 		stpt->s_value = locxp->e_xvalue;
623632Shenry 		stpt->s_index = dotp - usedot;
624597Sbill 		if (exprisname){
625632Shenry 			switch(stpt->s_ptype){
626597Sbill 				case N_GSYM:
627597Sbill 				case N_FNAME:
628597Sbill 				case N_RSYM:
629597Sbill 				case N_SSYM:
630597Sbill 				case N_LSYM:
631597Sbill 				case N_PSYM:
632597Sbill 				case N_BCOMM:
633597Sbill 				case N_ECOMM:
634597Sbill 				case N_LENG:
635632Shenry 					stpt->s_tag = STABFIXED;
636597Sbill 					break;
637597Sbill 				default:
638632Shenry 					stpt->s_tag = STABFLOATING;
639597Sbill 					break;
640597Sbill 			}
641597Sbill 		} else
642632Shenry 			stpt->s_tag = STABFIXED;
643597Sbill 	}
644597Sbill 	else {		/*really have a name*/
645632Shenry 		stpt->s_dest = locxp->e_xname;
646632Shenry 		stpt->s_index = p->s_index;
647632Shenry 		stpt->s_type = p->s_type | STABFLAG;
648597Sbill 		/*
649597Sbill 		 *	We will assign a more accruate
650597Sbill 		 *	guess of locxp's location when
651597Sbill 		 *	we sort the symbol table
652597Sbill 		 *	The final value of value is
653597Sbill 		 *	given by stabfix()
654597Sbill 		 */
65512591Scsvaf /*
65612591Scsvaf  * For exprs of the form (name + value) one needs to remember locxp->e_xvalue
65712591Scsvaf  * for use in stabfix. The right place to keep this is in stpt->s_value
65812591Scsvaf  * however this gets corrupted at an unknown point.
65912591Scsvaf  * As a bandaid hack the value is preserved in s_desc and s_other (a
66012591Scsvaf  * short and a char). This destroys these two values and will
66112591Scsvaf  * be fixed. May 19 ,1983 Alastair Fyfe
66212591Scsvaf  */
66312591Scsvaf 		if(locxp->e_xvalue) {
66412591Scsvaf 			stpt->s_other = (locxp->e_xvalue >> 16);
66512591Scsvaf 			stpt->s_desc =  (locxp->e_xvalue  & 0x0000ffff);
66612591Scsvaf 			stpt->s_tag = STABFLOATING;
66712591Scsvaf 		}
668597Sbill 	}
669597Sbill 	/*
670597Sbill 	 *	tokptr now points at one token beyond
671597Sbill 	 *	the current token stored in val and yylval,
672597Sbill 	 *	which are the next tokens after the end of
673597Sbill 	 *	this .stab directive.  This next token must
674597Sbill 	 *	be either a SEMI or NL, so is of width just
675597Sbill 	 *	one.  Therefore, to point to the next token
676597Sbill 	 *	after the end of this stab, just back up one..
677597Sbill 	 */
6785827Srrh 	buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));
679597Sbill 	break;	/*end of the .stab*/
680597Sbill 
681597Sbill    case ISTABDOT:
682597Sbill 	stabname = ".stabd";
683597Sbill 	stpt = (struct symtab *)yylval;
684597Sbill 	/*
685597Sbill 	 *	We clobber everything after the
686597Sbill 	 *	.stabd and its pointer... we MUST
687597Sbill 	 *	be able to get back to this .stabd
688597Sbill 	 *	so that we can resolve its final value
689597Sbill 	 */
690597Sbill 	stabstart = tokptr;
691597Sbill 	shift;		/*over the ISTABDOT*/
692597Sbill 	if (passno == 1){
693597Sbill 		expr(locxp, val);
694632Shenry 		if (! (locxp->e_xvalue & STABTYPS)){
695597Sbill 			yyerror("Invalid type in .stabd");
696597Sbill 			goto errorfix;
697597Sbill 		}
698632Shenry 		stpt->s_ptype = locxp->e_xvalue;
699597Sbill 		shiftover(CM);
700597Sbill 		expr(locxp, val);
701632Shenry 		stpt->s_other = locxp->e_xvalue;
702597Sbill 		shiftover(CM);
703597Sbill 		expr(locxp, val);
704632Shenry 		stpt->s_desc = locxp->e_xvalue;
705597Sbill 		/*
706597Sbill 		 *
707597Sbill 		 *	Now, clobber everything but the
708597Sbill 		 *	.stabd pseudo and the pointer
709597Sbill 		 *	to its symbol table entry
710597Sbill 		 *	tokptr points to the next token,
711597Sbill 		 *	build the skip up to this
712597Sbill 		 */
7135827Srrh 		buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));
714597Sbill 	}
715597Sbill 	/*
716597Sbill 	 *	pass 1:	Assign a good guess for its position
717597Sbill 	 *		(ensures they are sorted into right place)/
718597Sbill 	 *	pass 2:	Fix the actual value
719597Sbill 	 */
720632Shenry 	stpt->s_value = dotp->e_xvalue;
721632Shenry 	stpt->s_index = dotp - usedot;
722632Shenry 	stpt->s_tag = STABFLOATING;	/*although it has no effect in pass 2*/
723597Sbill 	break;
724597Sbill 
725597Sbill    case ISTABNONE:	stabname = ".stabn"; goto shortstab;
726597Sbill 
727597Sbill    case ISTABSTR: 	stabname = ".stabs";
728597Sbill    shortstab:
729597Sbill 	auxval = val;
730597Sbill 	if (passno == 2) goto errorfix;
731597Sbill 	stpt = (struct symtab *)yylval;
732597Sbill 	stabstart = tokptr;
7335827Srrh 	(bytetoktype *)stabstart -= sizeof(struct symtab *);
7345827Srrh 	(bytetoktype *)stabstart -= sizeof(bytetoktype);
735597Sbill 	shift;
736597Sbill 	if (auxval == ISTABSTR){
737597Sbill 		stringp = (struct strdesc *)yylval;
738597Sbill 		shiftover(STRING);
739597Sbill #ifndef FLEXNAMES
740597Sbill 		auxval = stringp->str_lg > NCPS ? NCPS : stringp->str_lg;
741597Sbill #else
742597Sbill 		stringp->str[stringp->str_lg] = 0;
743597Sbill #endif
744597Sbill 		shiftover(CM);
745597Sbill 	} else {
746597Sbill 		stringp = &(strbuf[2]);
747597Sbill #ifndef FLEXNAMES
748597Sbill 		auxval = NCPS;
749597Sbill #endif
750597Sbill 	}
751597Sbill #ifndef FLEXNAMES
752632Shenry 	movestr(stpt->s_name, stringp->str, auxval);
753597Sbill #else
754632Shenry 	stpt->s_name = savestr(stringp->str);
755597Sbill #endif
756597Sbill 	goto tailstab;
757597Sbill 	break;
758597Sbill 
7595827Srrh    case ICOMM:		/* .comm  <name> , <expr> */
760597Sbill    case ILCOMM: 	/* .lcomm <name> , <expr> */
761597Sbill 	auxval = val;
762597Sbill 	shift;
763597Sbill 	np = (struct symtab *)yylval;
764597Sbill 	shiftover(NAME);
765597Sbill 	shiftover(CM);
766597Sbill 	expr(locxp, val);
767597Sbill 
7685827Srrh 	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
769597Sbill 		yyerror("comm size not absolute");
7705827Srrh 	if (passno == 1 && (np->s_type&XTYPE) != XUNDEF)
771632Shenry #ifdef FLEXNAMES
772632Shenry 		yyerror("Redefinition of %s",
773632Shenry #else not FLEXNAMES
774632Shenry 		yyerror("Redefinition of %.*s",
775632Shenry 			NCPS,
776632Shenry #endif not FLEXNAMES
777632Shenry 			np->s_name);
778597Sbill 	if (passno==1) {
779632Shenry 		np->s_value = locxp->e_xvalue;
780597Sbill 		if (auxval == ICOMM)
781632Shenry 			np->s_type |= XXTRN;
782597Sbill 		else {
783632Shenry 			np->s_type &= ~XTYPE;
784632Shenry 			np->s_type |= XBSS;
785597Sbill 		}
786597Sbill 	}
787597Sbill 	break;
788597Sbill 
789597Sbill    case IALIGN: 		/* .align <expr> */
790597Sbill 	stpt = (struct symtab *)yylval;
791597Sbill 	shift;
792597Sbill 	expr(locxp, val);
793597Sbill 	jalign(locxp, stpt);
794597Sbill 	break;
795597Sbill 
796597Sbill    case INST0: 		/* instructions w/o arguments*/
797*13274Srrh 	incasetable = 0;
7985827Srrh 	insout(yyopcode, (struct arg *)0, 0);
799597Sbill 	shift;
800597Sbill 	break;
801597Sbill 
802597Sbill    case INSTn:		/* instructions with arguments*/
803597Sbill    case IJXXX: 		/* UNIX style jump instructions */
804597Sbill 	auxval = val;
805597Sbill 	/*
806597Sbill 	 *	Code to process an argument list
807597Sbill 	 */
808597Sbill 	ap = arglist;
809597Sbill 	xp = explist;
810597Sbill 
811597Sbill 	shift;		/* bring in the first token for the arg list*/
812597Sbill 
813597Sbill 	for (argcnt = 1; argcnt <= 6; argcnt++, ap++){
814597Sbill 		/*
815597Sbill 		 *	code to process an argument proper
816597Sbill 		 */
817597Sbill 	    sawindex  = sawmul = sawsize = 0;
818597Sbill 	    {
819597Sbill 		switch(val) {
820597Sbill 
821597Sbill 		   default:
822597Sbill 		     disp:
823597Sbill 			if( !(INTOKSET(val,
824597Sbill 				 EBEGOPS
825597Sbill 				+YUKKYEXPRBEG
826597Sbill 				+SAFEEXPRBEG)) ) {
827597Sbill 				ERROR("expression expected");
828597Sbill 			}
829632Shenry 			expr(ap->a_xp,val);
830597Sbill 		     overdisp:
831597Sbill 			if ( val == LP || sawsize){
832597Sbill 				shiftover(LP);
833597Sbill 				findreg(regno);
834597Sbill 				shiftover(RP);
835632Shenry 				ap->a_atype = ADISP;
836632Shenry 				ap->a_areg1 = regno;
837597Sbill 			} else {
838632Shenry 				ap->a_atype = AEXP;
839632Shenry 				ap->a_areg1 = 0;
840597Sbill 			}
841597Sbill 			goto index;
842597Sbill 
843597Sbill 		   case SIZESPEC:
844597Sbill 		     sizespec:
845597Sbill 			sawsize = yylval;
846597Sbill 			shift;
847597Sbill 			goto disp;
848597Sbill 
849597Sbill 		   case REG:
850597Sbill 		   case REGOP:
851597Sbill 			findreg(regno);
852632Shenry 			ap->a_atype = AREG;
853632Shenry 			ap->a_areg1 = regno;
854597Sbill 			break;
855597Sbill 
856597Sbill 		   case MUL:
857597Sbill 			sawmul = 1;
858597Sbill 			shift;
859597Sbill 			if (val == LP) goto base;
860597Sbill 			if (val == LITOP) goto imm;
861597Sbill 			if (val == SIZESPEC) goto sizespec;
862597Sbill 			if (INTOKSET(val,
863597Sbill 				 EBEGOPS
864597Sbill 				+YUKKYEXPRBEG
865597Sbill 				+SAFEEXPRBEG)) goto disp;
866597Sbill 			ERROR("expression, '(' or '$' expected");
867597Sbill 			break;
868597Sbill 
869597Sbill 		   case LP:
870597Sbill 		     base:
871597Sbill 			shift;	/*consume the LP*/
872597Sbill 			/*
873597Sbill 			 *	hack the ambiguity of
874597Sbill 			 *	movl (expr) (rn), ...
875597Sbill 			 *	note that (expr) could also
876597Sbill 			 *	be (rn) (by special hole in the
877597Sbill 			 *	grammar), which we ensure
878597Sbill 			 *	means register indirection, instead
879597Sbill 			 *	of an expression with value n
880597Sbill 			 */
881597Sbill 			if (val != REG && val != REGOP){
882597Sbill 				droppedLP = 1;
883632Shenry 				val = exprparse(val, &(ap->a_xp));
884597Sbill 				droppedLP = 0;
885597Sbill 				goto overdisp;
886597Sbill 			}
887597Sbill 			findreg(regno);
888597Sbill 			shiftover(RP);
889597Sbill 			if (val == PLUS){
890597Sbill 				shift;
891632Shenry 				ap->a_atype = AINCR;
892597Sbill 			} else
893632Shenry 				ap->a_atype = ABASE;
894632Shenry 			ap->a_areg1 = regno;
895597Sbill 			goto index;
896597Sbill 
897597Sbill 		   case LITOP:
898597Sbill 		      imm:
899597Sbill 			shift;
900597Sbill 			expr(locxp, val);
901632Shenry 			ap->a_atype = AIMM;
902632Shenry 			ap->a_areg1 = 0;
903632Shenry 			ap->a_xp = locxp;
904597Sbill 			goto index;
905597Sbill 
906597Sbill 		   case MP:
907597Sbill 			shift;	/* -(reg) */
908597Sbill 			findreg(regno);
909597Sbill 			shiftover(RP);
910632Shenry 			ap->a_atype = ADECR;
911632Shenry 			ap->a_areg1 = regno;
912597Sbill 	  index:			/*look for [reg] */
913597Sbill 			if (val == LB){
914597Sbill 				shift;
915597Sbill 				findreg(regno);
916597Sbill 				shiftover(RB);
917597Sbill 				sawindex = 1;
918632Shenry 				ap->a_areg2 = regno;
919597Sbill 			}
920597Sbill 			break;
921597Sbill 
922597Sbill 		}	/*end of the switch to process an arg*/
923597Sbill 	    }	/*end of processing an argument*/
924597Sbill 
925597Sbill 	    if (sawmul){
926597Sbill 			/*
927597Sbill 			 * Make a concession for *(%r)
928597Sbill 			 * meaning *0(%r)
929597Sbill 			 */
930632Shenry 			if (ap->a_atype == ABASE) {
931632Shenry 				ap->a_atype = ADISP;
932632Shenry 				xp->e_xtype = XABS;
9335827Srrh 				xp->e_number = Znumber;
9345827Srrh 				xp->e_number.num_tag = TYPL;
935632Shenry 				xp->e_xloc = 0;
936632Shenry 				ap->a_xp = xp++;
937597Sbill 			}
938632Shenry 			ap->a_atype |= ASTAR;
939597Sbill 			sawmul = 0;
940597Sbill 	    }
941597Sbill 	    if (sawindex){
942632Shenry 		ap->a_atype |= AINDX;
943597Sbill 		sawindex = 0;
944597Sbill 	    }
945632Shenry 	    ap->a_dispsize = sawsize == 0 ? d124 : sawsize;
946597Sbill 		if (val != CM) break;
947597Sbill 		shiftover(CM);
948597Sbill 	}	/*processing all the arguments*/
949597Sbill 
950597Sbill 	if (argcnt > 6){
951597Sbill 		yyerror("More than 6 arguments");
952597Sbill 		goto errorfix;
953597Sbill 	}
954597Sbill 
955*13274Srrh 	/*
956*13274Srrh 	 *	See if this is a case instruction,
957*13274Srrh 	 *	so we can set up tests on the following
958*13274Srrh 	 *	vector of branch displacements
959*13274Srrh 	 */
960*13274Srrh 	if (yyopcode.Op_eopcode == CORE){
961*13274Srrh 		switch(yyopcode.Op_popcode){
962*13274Srrh 		case 0x8f:	/* caseb */
963*13274Srrh 		case 0xaf:	/* casew */
964*13274Srrh 		case 0xcf:	/* casel */
965*13274Srrh 			incasetable++;
966*13274Srrh 			break;
967*13274Srrh 		default:
968*13274Srrh 			incasetable = 0;
969*13274Srrh 			break;
970*13274Srrh 		}
971*13274Srrh 	}
972*13274Srrh 
9735827Srrh 	insout(yyopcode, arglist,
974597Sbill 		auxval == INSTn ? argcnt : - argcnt);
975597Sbill 	break;
976597Sbill 
9775827Srrh    case IQUAD:		toconv = TYPQ;	goto bignumlist;
9785827Srrh    case IOCTA:		toconv = TYPO;	goto bignumlist;
9795827Srrh 
9805827Srrh    case IFFLOAT:	toconv = TYPF;	goto bignumlist;
9815827Srrh    case IDFLOAT:	toconv = TYPD;	goto bignumlist;
9825827Srrh    case IGFLOAT:	toconv = TYPG;	goto bignumlist;
9835827Srrh    case IHFLOAT:	toconv = TYPH;	goto bignumlist;
9845827Srrh    bignumlist:
985597Sbill 	/*
9865827Srrh 	 *	eat a list of non 32 bit numbers.
9875827Srrh 	 *	IQUAD and IOCTA can, possibly, return
9885827Srrh 	 *	INT's, if the numbers are "small".
9895827Srrh 	 *
9905827Srrh 	 *	The value of the numbers is coming back
9915827Srrh 	 *	as an expression, NOT in yybignum.
992597Sbill 	 */
9935827Srrh 	shift;	/* over the opener */
9945827Srrh 	if ((val == BIGNUM) || (val == INT)){
995597Sbill 		do{
9965827Srrh 			if ((val != BIGNUM) && (val != INT)){
9975827Srrh 				ERROR(ty_float[toconv]
9985827Srrh 				   ? "floating number expected"
9995827Srrh 				   : "integer number expected" );
1000597Sbill 			}
10015827Srrh 			dotp->e_xvalue += ty_nbyte[toconv];
10025827Srrh 			if (passno == 2){
10035827Srrh 				bignumwrite(
10045827Srrh 					((struct exp *)yylval)->e_number,
10055827Srrh 					toconv);
1006597Sbill 			}
1007597Sbill 			xp = explist;
10085827Srrh 			shift;		/* over this number */
10095827Srrh 			if (auxval = (val == CM))
10105827Srrh 				shift;	/* over the comma */
10115827Srrh 		} while (auxval);	/* as long as there are commas */
1012597Sbill 	}
1013597Sbill 	break;
10145827Srrh 	/* end of the case for initialized big numbers */
1015597Sbill     }	/*end of the switch for looking at each reserved word*/
1016597Sbill 
10175827Srrh 	continue;
1018597Sbill 
1019597Sbill    errorfix:
1020597Sbill 	/*
1021597Sbill 	 *	got here by either requesting to skip to the
1022597Sbill 	 *	end of this statement, or by erroring out and
1023597Sbill 	 *	wanting to apply panic mode recovery
1024597Sbill 	 */
1025597Sbill 	while (    (val != NL)
1026597Sbill 		&& (val != SEMI)
1027597Sbill 		&& (val != PARSEEOF)
1028597Sbill 	      ){
1029597Sbill 		shift;
1030597Sbill 	}
1031597Sbill 	if (val == NL)
1032597Sbill 		lineno++;
1033597Sbill 	shift;
1034597Sbill 
1035597Sbill     }	/*end of the loop to read the entire file, line by line*/
1036597Sbill 
1037597Sbill }	/*end of yyparse*/
1038597Sbill 
1039597Sbill /*
1040597Sbill  *	Process a register declaration of the form
1041597Sbill  *	% <expr>
1042597Sbill  *
1043597Sbill  *	Note:
1044597Sbill  *		The scanner has already processed funny registers of the form
1045597Sbill  *	%dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional
1046597Sbill  *	preceding zero digit).  If there was any space between the % and
1047597Sbill  *	the digit, the scanner wouldn't have recognized it, so we
1048597Sbill  *	hack it out here.
1049597Sbill  */
10505827Srrh inttoktype funnyreg(val, regnoback)	/*what the read head will sit on*/
10515827Srrh 	inttoktype	val;		/*what the read head is sitting on*/
1052597Sbill 	int	*regnoback;		/*call by return*/
1053597Sbill {
10545827Srrh 	reg	struct	exp *locxp;
10555827Srrh 		struct	exp *loc1xp;
10565827Srrh 		struct	exp **ptrloc1xp = & loc1xp;
1057597Sbill 
1058597Sbill 	expr(locxp, val);	/*and leave the current read head with value*/
1059597Sbill 	if ( (passno == 2) &&
10605827Srrh 	    (   (locxp->e_xtype & XTYPE) != XABS
10615827Srrh 	     || (locxp->e_xvalue < 0)
10625827Srrh 	     || (locxp->e_xvalue >= 16)
1063597Sbill 	    )
1064597Sbill 	  ){
1065597Sbill 		yyerror("Illegal register");
1066597Sbill 		return(0);
1067597Sbill 	}
1068632Shenry 	*regnoback = locxp->e_xvalue;
1069597Sbill 	return(val);
1070597Sbill }
107112945Srrh /*
107212945Srrh  *	Shift over error
107312945Srrh  */
107412945Srrh shiftoerror(token)
107512945Srrh 	int	token;
107612945Srrh {
107712945Srrh 	char	*tok_to_name();
107812945Srrh 	yyerror("%s expected", tok_to_name(token));
107912945Srrh }
1080597Sbill 
1081597Sbill /*VARARGS1*/
1082597Sbill yyerror(s, a1, a2,a3,a4,a5)
1083597Sbill 	char	*s;
1084597Sbill {
1085597Sbill 
1086649Shenry #define	sink stdout
1087597Sbill 
10885827Srrh 	if (anyerrs == 0 && anywarnings == 0 && ! silent)
1089597Sbill 		fprintf(sink, "Assembler:\n");
1090597Sbill 	anyerrs++;
10915827Srrh 	if (silent)
10925827Srrh 		return;
1093597Sbill 	fprintf(sink, "\"%s\", line %d: ", dotsname, lineno);
1094597Sbill 	fprintf(sink, s, a1, a2,a3,a4,a5);
1095597Sbill 	fprintf(sink, "\n");
10965827Srrh #undef sink
1097597Sbill }
1098676Shenry 
1099676Shenry /*VARARGS1*/
1100676Shenry yywarning(s, a1, a2,a3,a4,a5)
1101676Shenry 	char	*s;
1102676Shenry {
1103676Shenry #define	sink stdout
11045827Srrh 	if (anyerrs == 0 && anywarnings == 0 && ! silent)
1105676Shenry 		fprintf(sink, "Assembler:\n");
11065827Srrh 	anywarnings++;
11075827Srrh 	if (silent)
11085827Srrh 		return;
1109676Shenry 	fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno);
1110676Shenry 	fprintf(sink, s, a1, a2,a3,a4,a5);
1111676Shenry 	fprintf(sink, "\n");
11125827Srrh #undef sink
1113676Shenry }
1114