xref: /csrg-svn/old/as.vax/asparse.c (revision 13446)
15827Srrh /*
25827Srrh  *	Copyright (c) 1982 Regents of the University of California
35827Srrh  */
45827Srrh #ifndef lint
5*13446Srrh static char sccsid[] = "@(#)asparse.c 4.12 06/29/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 
71*13446Srrh 		char	*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 */
9013274Srrh 		int	incasetable;	/* set if in a case table */
91597Sbill 
9213274Srrh 	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;
217*13446Srrh 	stringp = (char *)yylval;
218597Sbill 	shiftover(STRING);
219597Sbill 	dotsname = &UDotsname[0];
220*13446Srrh 	movestr(dotsname, stringp, min(STRLEN(stringp), sizeof(dotsname)));
221597Sbill 	break;
222597Sbill 
223597Sbill    case ILINENO:
224597Sbill 	shift;		/*over the ILINENO*/
225597Sbill 	expr(locxp, val);
226632Shenry 	lineno = locxp->e_xvalue;
227597Sbill 	break;
228597Sbill 
229597Sbill    case ISET: 	/* .set  <name> , <expr> */
230597Sbill 	shift;
231597Sbill 	np = (struct symtab *)yylval;
232597Sbill 	shiftover(NAME);
233597Sbill 	shiftover(CM);
234597Sbill 	expr(locxp, val);
235632Shenry 	np->s_type &= (XXTRN|XFORW);
236632Shenry 	np->s_type |= locxp->e_xtype&(XTYPE|XFORW);
237632Shenry 	np->s_value = locxp->e_xvalue;
238597Sbill 	if (passno==1)
239632Shenry 		np->s_index = locxp->e_xloc;
240632Shenry 	if ((locxp->e_xtype&XTYPE) == XUNDEF)
241597Sbill 		yyerror("Illegal set?");
242597Sbill 	break;
243597Sbill 
244597Sbill    case ILSYM: 	/*.lsym name , expr */
245597Sbill 	shift;
246597Sbill 	np = (struct symtab *)yylval;
247597Sbill 	shiftover(NAME);
248597Sbill 	shiftover(CM);
249597Sbill 	expr(locxp, val);
250597Sbill 	/*
251597Sbill 	 *	Build the unique occurance of the
252597Sbill 	 *	symbol.
253597Sbill 	 *	The character scanner will have
254597Sbill 	 *	already entered it into the symbol
255597Sbill 	 *	table, but we should remove it
256597Sbill 	 */
257597Sbill 	if (passno == 1){
258597Sbill 		stpt = (struct symtab *)symalloc();
259597Sbill #ifdef FLEXNAMES
260632Shenry 		stpt->s_name = np->s_name;
261597Sbill #else
262632Shenry 		movestr(stpt->s_name, np->s_name, NCPS);
263597Sbill #endif
264632Shenry 		np->s_tag = OBSOLETE;	/*invalidate original */
265597Sbill 		nforgotten++;
266597Sbill 		np = stpt;
2675827Srrh 		if ( (locxp->e_xtype & XTYPE) != XABS)
2685827Srrh 			yyerror("Illegal second argument to lsym");
2695827Srrh 		np->s_value = locxp->e_xvalue;
2705827Srrh 		np->s_type = XABS;
271632Shenry 		np->s_tag = ILSYM;
272597Sbill 	}
273597Sbill 	break;
274597Sbill 
275597Sbill    case IGLOBAL: 	/*.globl <name> */
276597Sbill 	shift;
277597Sbill 	np = (struct symtab *)yylval;
278597Sbill 	shiftover(NAME);
279632Shenry 	np->s_type |= XXTRN;
280597Sbill 	break;
281597Sbill 
282597Sbill    case IDATA: 	/*.data [ <expr> ] */
283597Sbill    case ITEXT: 	/*.text [ <expr> ] */
284597Sbill 	seg_type = -val;
285597Sbill 	shift;
286597Sbill 	if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){
287597Sbill 		expr(locxp, val);
288597Sbill 		seg_type = -seg_type;   /*now, it is positive*/
289597Sbill 	}
290597Sbill 
291597Sbill 	if (seg_type < 0) {	/*there wasn't an associated expr*/
292597Sbill 		seg_number = 0;
293597Sbill 		seg_type = -seg_type;
294597Sbill 	} else {
2955827Srrh 		if (   ((locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
2965827Srrh 		    || (seg_number = locxp->e_xvalue) >= NLOC) {
297597Sbill 			yyerror("illegal location counter");
298597Sbill 			seg_number = 0;
299597Sbill 		}
300597Sbill 	}
301597Sbill 	if (seg_type == IDATA)
302597Sbill 		seg_number += NLOC;
303597Sbill 	flushfield(NBPW/4);
304597Sbill 	dotp = &usedot[seg_number];
305597Sbill #ifdef UNIX
306597Sbill 	if (passno==2) {	/* go salt away in pass 2*/
307597Sbill 		txtfil = usefile[seg_number];
308597Sbill 		relfil = rusefile[seg_number];
309597Sbill 	}
310597Sbill #endif UNIX
311597Sbill #ifdef VMS
312597Sbill 	if (passno==2) {
313597Sbill 		puchar(vms_obj_ptr,6);		/*  setpl  */
314597Sbill 		puchar(vms_obj_ptr,seg_number);	/* psect # */
315632Shenry 		plong(vms_obj_ptr,dotp->e_xvalue);/*  offset */
316597Sbill 		puchar(vms_obj_ptr,80);		/*  setrb  */
317597Sbill 		if((vms_obj_ptr-sobuf) > 400){
318597Sbill 			write(objfil,sobuf,vms_obj_ptr-sobuf);
319597Sbill 			vms_obj_ptr=sobuf+1;	/*flush buf*/
320597Sbill 		}
321597Sbill 	}
322597Sbill #endif VMS
323597Sbill 	break;
324597Sbill 
325597Sbill 	/*
326597Sbill 	 *	Storage filler directives:
327597Sbill 	 *
328597Sbill 	 *	.byte	[<exprlist>]
329597Sbill 	 *
330597Sbill 	 *	exprlist:  empty | exprlist outexpr
331597Sbill 	 *	outexpr:   <expr> | <expr> : <expr>
332597Sbill 	 */
333597Sbill    case IBYTE:	curlen = NBPW/4; goto elist;
3345827Srrh    case IWORD:	curlen = NBPW/2; goto elist;
3355827Srrh    case IINT:	curlen = NBPW;   goto elist;
336597Sbill    case ILONG:	curlen = NBPW;   goto elist;
337597Sbill 
338597Sbill    elist:
339597Sbill 	seg_type = val;
340597Sbill 	shift;
341597Sbill 
342597Sbill 	/*
343597Sbill 	 *	Expression List processing
344597Sbill 	 */
345597Sbill 	if (INTOKSET(val, EBEGOPS+YUKKYEXPRBEG+SAFEEXPRBEG)){
346597Sbill 	    do{
347597Sbill 		/*
348597Sbill 		 *	expression list consists of a list of :
349597Sbill 		 *	<expr>
350597Sbill 		 *	<expr> : <expr>
351597Sbill 		 *		(pack expr2 into expr1 bits
352597Sbill 		 */
353597Sbill 		expr(locxp, val);
354597Sbill 		/*
355597Sbill 		 *	now, pointing at the next token
356597Sbill 		 */
357597Sbill 		if (val == COLON){
358597Sbill 			shiftover(COLON);
359597Sbill 			expr(pval, val);
3605827Srrh 			if ((locxp->e_xtype & XTYPE) != XABS) /* tekmdp */
3615827Srrh 				yyerror("Width not absolute");
362632Shenry 			field_width = locxp->e_xvalue;
363597Sbill 			locxp = pval;
3645827Srrh 			if (bitoff + field_width > curlen)
365597Sbill 				flushfield(curlen);
366597Sbill 			if (field_width > curlen)
367597Sbill 				yyerror("Expression crosses field boundary");
368597Sbill 		} else {
369597Sbill 			field_width = curlen;
370597Sbill 			flushfield(curlen);
371597Sbill 		}
372597Sbill 
3735827Srrh 		if ((locxp->e_xtype & XTYPE) != XABS) {
374597Sbill 			if (bitoff)
375597Sbill 				yyerror("Illegal relocation in field");
376674Shenry 			switch(curlen){
377674Shenry 				case NBPW/4:	reloc_how = TYPB; break;
378674Shenry 				case NBPW/2:	reloc_how = TYPW; break;
379674Shenry 				case NBPW:	reloc_how = TYPL; break;
380674Shenry 			}
381597Sbill 			if (passno == 1){
382674Shenry 				dotp->e_xvalue += ty_nbyte[reloc_how];
383597Sbill 			} else {
384674Shenry 				outrel(locxp, reloc_how);
385597Sbill 			}
386597Sbill 		} else {
38713274Srrh 			/*
38813274Srrh 			 *
38913274Srrh 			 *	See if we are doing a case instruction.
39013274Srrh 			 *	If so, then see if the branch distance,
39113274Srrh 			 *	stored as a word,
39213274Srrh 			 *	is going to loose sig bits.
39313274Srrh 			 */
39413274Srrh 			if (passno == 2 && incasetable){
39513274Srrh 				if (  (locxp->e_xvalue < -32768)
39613274Srrh 				    ||(locxp->e_xvalue > 32767)){
39713274Srrh 					yyerror("Case will branch too far");
39813274Srrh 				}
39913274Srrh 			}
400632Shenry 			field_value = locxp->e_xvalue & ( (1L << field_width)-1);
401597Sbill 			bitfield |= field_value << bitoff;
402597Sbill 			bitoff += field_width;
403597Sbill 		}
404597Sbill 		xp = explist;
4055827Srrh 		if (auxval = (val == CM))
4065827Srrh 			shift;
407597Sbill 	    } while (auxval);
4085827Srrh 	}	/* there existed an expression at all */
409597Sbill 
410597Sbill 	flushfield(curlen);
411597Sbill 	if ( ( curlen == NBPW/4) && bitoff)
412632Shenry 		dotp->e_xvalue ++;
413597Sbill 	break;
414597Sbill 	/*end of case IBYTE, IWORD, ILONG, IINT*/
415597Sbill 
416597Sbill    case ISPACE: 	/* .space <expr> */
417597Sbill 	shift;
418597Sbill 	expr(locxp, val);
4195827Srrh 	if ((locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
420597Sbill 		yyerror("Space size not absolute");
421632Shenry 	space_value = locxp->e_xvalue;
422597Sbill   ospace:
423597Sbill 	flushfield(NBPW/4);
424597Sbill #ifdef UNIX
425*13446Srrh 	{
426*13446Srrh 		static char spacebuf[128];
427*13446Srrh 		while (space_value > sizeof(spacebuf)){
428*13446Srrh 			outs(spacebuf, sizeof(spacebuf));
429*13446Srrh 			space_value -= sizeof(spacebuf);
430*13446Srrh 		}
431*13446Srrh 		outs(spacebuf, space_value);
432597Sbill 	}
433597Sbill #endif UNIX
434597Sbill #ifdef VMS
435632Shenry 	dotp->e_xvalue += space_value;		/*bump pc*/
436597Sbill 	if (passno==2){
437*13446Srrh 	  puchar(vms_obj_ptr,81);		/* AUGR  */
438*13446Srrh 	  pulong(vms_obj_ptr,space_value);/* incr  */
439597Sbill 	  if ((vms_obj_ptr-sobuf) > 400) {
440597Sbill 		write(objfil,sobuf,vms_obj_ptr-sobuf);
441597Sbill 		vms_obj_ptr=sobuf+1;		/*pur buf*/
442597Sbill 	  }
443597Sbill 	}
444597Sbill #endif VMS
445597Sbill 	break;
446597Sbill 
447597Sbill #ifdef UNIX
448647Shenry 	/*
449647Shenry 	 *	.fill rep, size, value
450647Shenry 	 *	repeat rep times: fill size bytes with (truncated) value
451647Shenry 	 *	size must be between 1 and 8
452647Shenry 	 */
453647Shenry    case	IFILL:
454597Sbill 	shift;
455597Sbill 	expr(locxp, val);
4565827Srrh 	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
457597Sbill 		yyerror("Fill repetition count not absolute");
458647Shenry 	fill_rep = locxp->e_xvalue;
459597Sbill 	shiftover(CM);
460597Sbill 	expr(locxp, val);
4615827Srrh 	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
462647Shenry 		yyerror("Fill size not absolute");
463647Shenry 	fill_size = locxp->e_xvalue;
464647Shenry 	if (fill_size <= 0 || fill_size > 8)
465647Shenry 		yyerror("Fill count not in in 1..8");
466647Shenry 	shiftover(CM);
467647Shenry 	expr(locxp, val);
4685827Srrh 	if (passno == 2 && (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
4695827Srrh 		yyerror("Fill value not absolute");
470597Sbill 	flushfield(NBPW/4);
471647Shenry 	if (passno == 1) {
4725827Srrh 		dotp->e_xvalue += fill_rep * fill_size;
473647Shenry 	} else {
474647Shenry 		while(fill_rep-- > 0)
4755827Srrh 			bwrite((char *)&locxp->e_xvalue, fill_size, txtfil);
476647Shenry 	}
477597Sbill 	break;
478597Sbill #endif UNIX
479597Sbill 
480*13446Srrh    case IASCII:		/* .ascii [ <stringlist> ] */
481597Sbill    case IASCIZ: 	/* .asciz [ <stringlist> ] */
482597Sbill 	auxval = val;
483597Sbill 	shift;
484597Sbill 	/*
485597Sbill 	 *	Code to consume a string list
486597Sbill 	 *
487597Sbill 	 *	stringlist: empty | STRING | stringlist STRING
488597Sbill 	 */
489*13446Srrh 	while (val == STRING){
490597Sbill 		flushfield(NBPW/4);
491597Sbill 		if (bitoff)
492*13446Srrh 			dotp->e_xvalue++;
493*13446Srrh 		stringp = (char *)yylval;
494*13446Srrh 		/*
495*13446Srrh 		 *	utilize the string scanner cheat,
496*13446Srrh 		 *	where it appended a null byte on the string,
497*13446Srrh 		 *	but didn't charge it to STRLEN
498*13446Srrh 		 */
499*13446Srrh 		STRLEN(stringp) += (auxval == IASCIZ) ? 1 : 0;
500597Sbill #ifdef UNIX
501*13446Srrh 		outs(stringp, STRLEN(stringp));
502597Sbill #endif UNIX
503597Sbill #ifdef VMS
504597Sbill 		{
5055827Srrh 			reg int i;
506597Sbill 			for (i=0; i < stringp->str_lg; i++){
507632Shenry 			  dotp->e_xvalue += 1;
508597Sbill 			    if (passno==2){
509597Sbill 				puchar(vms_obj_ptr,-1);
510597Sbill 			  	puchar(vms_obj_ptr,stringp->str[i]);
511597Sbill 			  	if (vms_obj_ptr-sobuf > 400) {
512597Sbill 				  write(objfil,sobuf,vms_obj_ptr-sobuf);
513597Sbill 				  vms_obj_ptr = sobuf + 1;
514597Sbill 			  	}
515597Sbill 			    }
516597Sbill 			}
517597Sbill 		}
518597Sbill #endif VMS
519597Sbill 		shift;		/*over the STRING*/
520597Sbill 		if (val == CM)	/*could be a split string*/
521597Sbill 			shift;
522597Sbill 	}
523597Sbill 	break;
524597Sbill 
525597Sbill    case IORG: 	/* .org <expr> */
526597Sbill 	shift;
527597Sbill 	expr(locxp, val);
528597Sbill 
5295827Srrh 	if ((locxp->e_xtype & XTYPE) == XABS)	/* tekmdp */
530597Sbill 		orgwarn++;
531632Shenry 	else if ((locxp->e_xtype & ~XXTRN) != dotp->e_xtype)
532597Sbill 		yyerror("Illegal expression to set origin");
533632Shenry 	space_value = locxp->e_xvalue - dotp->e_xvalue;
534597Sbill 	if (space_value < 0)
535597Sbill 		yyerror("Backwards 'org'");
536597Sbill 	goto ospace;
537597Sbill 	break;
538597Sbill 
539597Sbill /*
540597Sbill  *
541597Sbill  *	Process stabs.  Stabs are created only by the f77
542597Sbill  *	and the C compiler with the -g flag set.
543597Sbill  *	We only look at the stab ONCE, during pass 1, and
544597Sbill  *	virtually remove the stab from the intermediate file
545597Sbill  *	so it isn't seen during pass2.  This makes for some
546597Sbill  *	hairy processing to handle labels occuring in
547597Sbill  *	stab entries, but since most expressions in the
548597Sbill  *	stab are integral we save lots of time in the second
549597Sbill  *	pass by not looking at the stabs.
550597Sbill  *	A stab that is tagged floating will be bumped during
551597Sbill  *	the jxxx resolution phase.  A stab tagged fixed will
552597Sbill  *	not be be bumped.
553597Sbill  *
554597Sbill  *	.stab:	Old fashioned stabs
555597Sbill  *	.stabn: For stabs without names
556597Sbill  *	.stabs:	For stabs with string names
557597Sbill  *	.stabd: For stabs for line numbers or bracketing,
558597Sbill  *		without a string name, without
559597Sbill  *		a final expression.  The value of the
560597Sbill  *		final expression is taken to be  the current
561597Sbill  *		location counter, and is patched by the 2nd pass
562597Sbill  *
563674Shenry  *	.stab{<expr>,}*NCPS,<expr>, <expr>, <expr>, <expr>
564597Sbill  *	.stabn		 <expr>, <expr>, <expr>, <expr>
565597Sbill  *	.stabs   STRING, <expr>, <expr>, <expr>, <expr>
566597Sbill  *	.stabd		 <expr>, <expr>, <expr> # .
567597Sbill  */
568597Sbill    case ISTAB:
569597Sbill #ifndef FLEXNAMES
570597Sbill 	stabname = ".stab";
571597Sbill 	if (passno == 2)	goto errorfix;
572597Sbill 	stpt = (struct symtab *)yylval;
573597Sbill 	/*
574597Sbill 	 *	Make a pointer to the .stab slot.
575597Sbill 	 *	There is a pointer in the way (stpt), and
576597Sbill 	 *	tokptr points to the next token.
577597Sbill 	 */
578597Sbill 	stabstart = tokptr;
579597Sbill 	(char *)stabstart -= sizeof(struct symtab *);
5805827Srrh 	(char *)stabstart -= sizeof(bytetoktype);
581597Sbill 	shift;
582674Shenry 	for (argcnt = 0; argcnt < NCPS; argcnt++){
583597Sbill 		expr(locxp, val);
584632Shenry 		stpt->s_name[argcnt] = locxp->e_xvalue;
585597Sbill 		xp = explist;
586597Sbill 		shiftover(CM);
587597Sbill 	}
588597Sbill 	goto tailstab;
589597Sbill #else	FLEXNAMES
590597Sbill 	yyerror(".stab directive not supported in; report this compiler bug to system administrator");
591597Sbill 	goto errorfix;
592597Sbill #endif FLEXNAMES
593597Sbill 
594597Sbill   tailstab:
595597Sbill 	expr(locxp, val);
596632Shenry 	if (! (locxp->e_xvalue & STABTYPS)){
5975827Srrh 		yyerror("Invalid type in %s", stabname);
598597Sbill 		goto errorfix;
599597Sbill 	}
600632Shenry 	stpt->s_ptype = locxp->e_xvalue;
601597Sbill 	shiftover(CM);
602597Sbill 	expr(locxp, val);
603632Shenry 	stpt->s_other = locxp->e_xvalue;
604597Sbill 	shiftover(CM);
605597Sbill 	expr(locxp, val);
606632Shenry 	stpt->s_desc = locxp->e_xvalue;
607597Sbill 	shiftover(CM);
608597Sbill 	exprisname = 0;
609597Sbill 	expr(locxp, val);
610632Shenry 	p = locxp->e_xname;
611597Sbill 	if (p == NULL) {	/*absolute expr to begin with*/
612632Shenry 		stpt->s_value = locxp->e_xvalue;
613632Shenry 		stpt->s_index = dotp - usedot;
614597Sbill 		if (exprisname){
615632Shenry 			switch(stpt->s_ptype){
616597Sbill 				case N_GSYM:
617597Sbill 				case N_FNAME:
618597Sbill 				case N_RSYM:
619597Sbill 				case N_SSYM:
620597Sbill 				case N_LSYM:
621597Sbill 				case N_PSYM:
622597Sbill 				case N_BCOMM:
623597Sbill 				case N_ECOMM:
624597Sbill 				case N_LENG:
625632Shenry 					stpt->s_tag = STABFIXED;
626597Sbill 					break;
627597Sbill 				default:
628632Shenry 					stpt->s_tag = STABFLOATING;
629597Sbill 					break;
630597Sbill 			}
631597Sbill 		} else
632632Shenry 			stpt->s_tag = STABFIXED;
633597Sbill 	}
634597Sbill 	else {		/*really have a name*/
635632Shenry 		stpt->s_dest = locxp->e_xname;
636632Shenry 		stpt->s_index = p->s_index;
637632Shenry 		stpt->s_type = p->s_type | STABFLAG;
638597Sbill 		/*
639597Sbill 		 *	We will assign a more accruate
640597Sbill 		 *	guess of locxp's location when
641597Sbill 		 *	we sort the symbol table
642597Sbill 		 *	The final value of value is
643597Sbill 		 *	given by stabfix()
644597Sbill 		 */
64512591Scsvaf /*
64612591Scsvaf  * For exprs of the form (name + value) one needs to remember locxp->e_xvalue
64712591Scsvaf  * for use in stabfix. The right place to keep this is in stpt->s_value
64812591Scsvaf  * however this gets corrupted at an unknown point.
64912591Scsvaf  * As a bandaid hack the value is preserved in s_desc and s_other (a
65012591Scsvaf  * short and a char). This destroys these two values and will
65112591Scsvaf  * be fixed. May 19 ,1983 Alastair Fyfe
65212591Scsvaf  */
65312591Scsvaf 		if(locxp->e_xvalue) {
65412591Scsvaf 			stpt->s_other = (locxp->e_xvalue >> 16);
65512591Scsvaf 			stpt->s_desc =  (locxp->e_xvalue  & 0x0000ffff);
65612591Scsvaf 			stpt->s_tag = STABFLOATING;
65712591Scsvaf 		}
658597Sbill 	}
659597Sbill 	/*
660597Sbill 	 *	tokptr now points at one token beyond
661597Sbill 	 *	the current token stored in val and yylval,
662597Sbill 	 *	which are the next tokens after the end of
663597Sbill 	 *	this .stab directive.  This next token must
664597Sbill 	 *	be either a SEMI or NL, so is of width just
665597Sbill 	 *	one.  Therefore, to point to the next token
666597Sbill 	 *	after the end of this stab, just back up one..
667597Sbill 	 */
6685827Srrh 	buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));
669597Sbill 	break;	/*end of the .stab*/
670597Sbill 
671597Sbill    case ISTABDOT:
672597Sbill 	stabname = ".stabd";
673597Sbill 	stpt = (struct symtab *)yylval;
674597Sbill 	/*
675597Sbill 	 *	We clobber everything after the
676597Sbill 	 *	.stabd and its pointer... we MUST
677597Sbill 	 *	be able to get back to this .stabd
678597Sbill 	 *	so that we can resolve its final value
679597Sbill 	 */
680597Sbill 	stabstart = tokptr;
681597Sbill 	shift;		/*over the ISTABDOT*/
682597Sbill 	if (passno == 1){
683597Sbill 		expr(locxp, val);
684632Shenry 		if (! (locxp->e_xvalue & STABTYPS)){
685597Sbill 			yyerror("Invalid type in .stabd");
686597Sbill 			goto errorfix;
687597Sbill 		}
688632Shenry 		stpt->s_ptype = locxp->e_xvalue;
689597Sbill 		shiftover(CM);
690597Sbill 		expr(locxp, val);
691632Shenry 		stpt->s_other = locxp->e_xvalue;
692597Sbill 		shiftover(CM);
693597Sbill 		expr(locxp, val);
694632Shenry 		stpt->s_desc = locxp->e_xvalue;
695597Sbill 		/*
696597Sbill 		 *
697597Sbill 		 *	Now, clobber everything but the
698597Sbill 		 *	.stabd pseudo and the pointer
699597Sbill 		 *	to its symbol table entry
700597Sbill 		 *	tokptr points to the next token,
701597Sbill 		 *	build the skip up to this
702597Sbill 		 */
7035827Srrh 		buildskip(stabstart, (bytetoktype *)tokptr - sizeof(bytetoktype));
704597Sbill 	}
705597Sbill 	/*
706597Sbill 	 *	pass 1:	Assign a good guess for its position
707597Sbill 	 *		(ensures they are sorted into right place)/
708597Sbill 	 *	pass 2:	Fix the actual value
709597Sbill 	 */
710632Shenry 	stpt->s_value = dotp->e_xvalue;
711632Shenry 	stpt->s_index = dotp - usedot;
712632Shenry 	stpt->s_tag = STABFLOATING;	/*although it has no effect in pass 2*/
713597Sbill 	break;
714597Sbill 
715597Sbill    case ISTABNONE:	stabname = ".stabn"; goto shortstab;
716597Sbill 
717597Sbill    case ISTABSTR: 	stabname = ".stabs";
718597Sbill    shortstab:
719597Sbill 	auxval = val;
720597Sbill 	if (passno == 2) goto errorfix;
721597Sbill 	stpt = (struct symtab *)yylval;
722597Sbill 	stabstart = tokptr;
7235827Srrh 	(bytetoktype *)stabstart -= sizeof(struct symtab *);
7245827Srrh 	(bytetoktype *)stabstart -= sizeof(bytetoktype);
725597Sbill 	shift;
726597Sbill 	if (auxval == ISTABSTR){
727*13446Srrh 		stringp = (char *)yylval;
728597Sbill 		shiftover(STRING);
729597Sbill #ifndef FLEXNAMES
730*13446Srrh 		movestr(stpt->s_name, stringp, min(STRLEN(stringp), NCPS));
731597Sbill #else
732*13446Srrh 		stpt->s_name = stringp;
733*13446Srrh 		/*
734*13446Srrh 		 *	We want the trailing null included in this string.
735*13446Srrh 		 *	We utilize the cheat the string scanner used,
736*13446Srrh 		 *	and merely increment the string length
737*13446Srrh 		 */
738*13446Srrh 		STRLEN(stringp) += 1;
739597Sbill #endif
740597Sbill 		shiftover(CM);
741597Sbill 	} else {
742597Sbill #ifndef FLEXNAMES
743*13446Srrh 		static char nullstr[NCPS];
744*13446Srrh 		movestr(stpt->s_name, nullstr, NCPS);
745*13446Srrh #else
746*13446Srrh 		static char nullstr[1];
747*13446Srrh 		stpt->s_name = savestr(nullstr, 1);
748597Sbill #endif
749597Sbill 	}
750597Sbill 	goto tailstab;
751597Sbill 	break;
752597Sbill 
7535827Srrh    case ICOMM:		/* .comm  <name> , <expr> */
754597Sbill    case ILCOMM: 	/* .lcomm <name> , <expr> */
755597Sbill 	auxval = val;
756597Sbill 	shift;
757597Sbill 	np = (struct symtab *)yylval;
758597Sbill 	shiftover(NAME);
759597Sbill 	shiftover(CM);
760597Sbill 	expr(locxp, val);
761597Sbill 
7625827Srrh 	if ( (locxp->e_xtype & XTYPE) != XABS)	/* tekmdp */
763597Sbill 		yyerror("comm size not absolute");
7645827Srrh 	if (passno == 1 && (np->s_type&XTYPE) != XUNDEF)
765632Shenry #ifdef FLEXNAMES
766632Shenry 		yyerror("Redefinition of %s",
767632Shenry #else not FLEXNAMES
768632Shenry 		yyerror("Redefinition of %.*s",
769632Shenry 			NCPS,
770632Shenry #endif not FLEXNAMES
771632Shenry 			np->s_name);
772597Sbill 	if (passno==1) {
773632Shenry 		np->s_value = locxp->e_xvalue;
774597Sbill 		if (auxval == ICOMM)
775632Shenry 			np->s_type |= XXTRN;
776597Sbill 		else {
777632Shenry 			np->s_type &= ~XTYPE;
778632Shenry 			np->s_type |= XBSS;
779597Sbill 		}
780597Sbill 	}
781597Sbill 	break;
782597Sbill 
783597Sbill    case IALIGN: 		/* .align <expr> */
784597Sbill 	stpt = (struct symtab *)yylval;
785597Sbill 	shift;
786597Sbill 	expr(locxp, val);
787597Sbill 	jalign(locxp, stpt);
788597Sbill 	break;
789597Sbill 
790597Sbill    case INST0: 		/* instructions w/o arguments*/
79113274Srrh 	incasetable = 0;
7925827Srrh 	insout(yyopcode, (struct arg *)0, 0);
793597Sbill 	shift;
794597Sbill 	break;
795597Sbill 
796597Sbill    case INSTn:		/* instructions with arguments*/
797597Sbill    case IJXXX: 		/* UNIX style jump instructions */
798597Sbill 	auxval = val;
799597Sbill 	/*
800597Sbill 	 *	Code to process an argument list
801597Sbill 	 */
802597Sbill 	ap = arglist;
803597Sbill 	xp = explist;
804597Sbill 
805597Sbill 	shift;		/* bring in the first token for the arg list*/
806597Sbill 
807597Sbill 	for (argcnt = 1; argcnt <= 6; argcnt++, ap++){
808597Sbill 		/*
809597Sbill 		 *	code to process an argument proper
810597Sbill 		 */
811597Sbill 	    sawindex  = sawmul = sawsize = 0;
812597Sbill 	    {
813597Sbill 		switch(val) {
814597Sbill 
815597Sbill 		   default:
816597Sbill 		     disp:
817597Sbill 			if( !(INTOKSET(val,
818597Sbill 				 EBEGOPS
819597Sbill 				+YUKKYEXPRBEG
820597Sbill 				+SAFEEXPRBEG)) ) {
821597Sbill 				ERROR("expression expected");
822597Sbill 			}
823632Shenry 			expr(ap->a_xp,val);
824597Sbill 		     overdisp:
825597Sbill 			if ( val == LP || sawsize){
826597Sbill 				shiftover(LP);
827597Sbill 				findreg(regno);
828597Sbill 				shiftover(RP);
829632Shenry 				ap->a_atype = ADISP;
830632Shenry 				ap->a_areg1 = regno;
831597Sbill 			} else {
832632Shenry 				ap->a_atype = AEXP;
833632Shenry 				ap->a_areg1 = 0;
834597Sbill 			}
835597Sbill 			goto index;
836597Sbill 
837597Sbill 		   case SIZESPEC:
838597Sbill 		     sizespec:
839597Sbill 			sawsize = yylval;
840597Sbill 			shift;
841597Sbill 			goto disp;
842597Sbill 
843597Sbill 		   case REG:
844597Sbill 		   case REGOP:
845597Sbill 			findreg(regno);
846632Shenry 			ap->a_atype = AREG;
847632Shenry 			ap->a_areg1 = regno;
848597Sbill 			break;
849597Sbill 
850597Sbill 		   case MUL:
851597Sbill 			sawmul = 1;
852597Sbill 			shift;
853597Sbill 			if (val == LP) goto base;
854597Sbill 			if (val == LITOP) goto imm;
855597Sbill 			if (val == SIZESPEC) goto sizespec;
856597Sbill 			if (INTOKSET(val,
857597Sbill 				 EBEGOPS
858597Sbill 				+YUKKYEXPRBEG
859597Sbill 				+SAFEEXPRBEG)) goto disp;
860597Sbill 			ERROR("expression, '(' or '$' expected");
861597Sbill 			break;
862597Sbill 
863597Sbill 		   case LP:
864597Sbill 		     base:
865597Sbill 			shift;	/*consume the LP*/
866597Sbill 			/*
867597Sbill 			 *	hack the ambiguity of
868597Sbill 			 *	movl (expr) (rn), ...
869597Sbill 			 *	note that (expr) could also
870597Sbill 			 *	be (rn) (by special hole in the
871597Sbill 			 *	grammar), which we ensure
872597Sbill 			 *	means register indirection, instead
873597Sbill 			 *	of an expression with value n
874597Sbill 			 */
875597Sbill 			if (val != REG && val != REGOP){
876597Sbill 				droppedLP = 1;
877632Shenry 				val = exprparse(val, &(ap->a_xp));
878597Sbill 				droppedLP = 0;
879597Sbill 				goto overdisp;
880597Sbill 			}
881597Sbill 			findreg(regno);
882597Sbill 			shiftover(RP);
883597Sbill 			if (val == PLUS){
884597Sbill 				shift;
885632Shenry 				ap->a_atype = AINCR;
886597Sbill 			} else
887632Shenry 				ap->a_atype = ABASE;
888632Shenry 			ap->a_areg1 = regno;
889597Sbill 			goto index;
890597Sbill 
891597Sbill 		   case LITOP:
892597Sbill 		      imm:
893597Sbill 			shift;
894597Sbill 			expr(locxp, val);
895632Shenry 			ap->a_atype = AIMM;
896632Shenry 			ap->a_areg1 = 0;
897632Shenry 			ap->a_xp = locxp;
898597Sbill 			goto index;
899597Sbill 
900597Sbill 		   case MP:
901597Sbill 			shift;	/* -(reg) */
902597Sbill 			findreg(regno);
903597Sbill 			shiftover(RP);
904632Shenry 			ap->a_atype = ADECR;
905632Shenry 			ap->a_areg1 = regno;
906597Sbill 	  index:			/*look for [reg] */
907597Sbill 			if (val == LB){
908597Sbill 				shift;
909597Sbill 				findreg(regno);
910597Sbill 				shiftover(RB);
911597Sbill 				sawindex = 1;
912632Shenry 				ap->a_areg2 = regno;
913597Sbill 			}
914597Sbill 			break;
915597Sbill 
916597Sbill 		}	/*end of the switch to process an arg*/
917597Sbill 	    }	/*end of processing an argument*/
918597Sbill 
919597Sbill 	    if (sawmul){
920597Sbill 			/*
921597Sbill 			 * Make a concession for *(%r)
922597Sbill 			 * meaning *0(%r)
923597Sbill 			 */
924632Shenry 			if (ap->a_atype == ABASE) {
925632Shenry 				ap->a_atype = ADISP;
926632Shenry 				xp->e_xtype = XABS;
9275827Srrh 				xp->e_number = Znumber;
9285827Srrh 				xp->e_number.num_tag = TYPL;
929632Shenry 				xp->e_xloc = 0;
930632Shenry 				ap->a_xp = xp++;
931597Sbill 			}
932632Shenry 			ap->a_atype |= ASTAR;
933597Sbill 			sawmul = 0;
934597Sbill 	    }
935597Sbill 	    if (sawindex){
936632Shenry 		ap->a_atype |= AINDX;
937597Sbill 		sawindex = 0;
938597Sbill 	    }
939632Shenry 	    ap->a_dispsize = sawsize == 0 ? d124 : sawsize;
940597Sbill 		if (val != CM) break;
941597Sbill 		shiftover(CM);
942597Sbill 	}	/*processing all the arguments*/
943597Sbill 
944597Sbill 	if (argcnt > 6){
945597Sbill 		yyerror("More than 6 arguments");
946597Sbill 		goto errorfix;
947597Sbill 	}
948597Sbill 
94913274Srrh 	/*
95013274Srrh 	 *	See if this is a case instruction,
95113274Srrh 	 *	so we can set up tests on the following
95213274Srrh 	 *	vector of branch displacements
95313274Srrh 	 */
95413274Srrh 	if (yyopcode.Op_eopcode == CORE){
95513274Srrh 		switch(yyopcode.Op_popcode){
95613274Srrh 		case 0x8f:	/* caseb */
95713274Srrh 		case 0xaf:	/* casew */
95813274Srrh 		case 0xcf:	/* casel */
95913274Srrh 			incasetable++;
96013274Srrh 			break;
96113274Srrh 		default:
96213274Srrh 			incasetable = 0;
96313274Srrh 			break;
96413274Srrh 		}
96513274Srrh 	}
96613274Srrh 
9675827Srrh 	insout(yyopcode, arglist,
968597Sbill 		auxval == INSTn ? argcnt : - argcnt);
969597Sbill 	break;
970597Sbill 
9715827Srrh    case IQUAD:		toconv = TYPQ;	goto bignumlist;
9725827Srrh    case IOCTA:		toconv = TYPO;	goto bignumlist;
9735827Srrh 
9745827Srrh    case IFFLOAT:	toconv = TYPF;	goto bignumlist;
9755827Srrh    case IDFLOAT:	toconv = TYPD;	goto bignumlist;
9765827Srrh    case IGFLOAT:	toconv = TYPG;	goto bignumlist;
9775827Srrh    case IHFLOAT:	toconv = TYPH;	goto bignumlist;
9785827Srrh    bignumlist:
979597Sbill 	/*
9805827Srrh 	 *	eat a list of non 32 bit numbers.
9815827Srrh 	 *	IQUAD and IOCTA can, possibly, return
9825827Srrh 	 *	INT's, if the numbers are "small".
9835827Srrh 	 *
9845827Srrh 	 *	The value of the numbers is coming back
9855827Srrh 	 *	as an expression, NOT in yybignum.
986597Sbill 	 */
9875827Srrh 	shift;	/* over the opener */
9885827Srrh 	if ((val == BIGNUM) || (val == INT)){
989597Sbill 		do{
9905827Srrh 			if ((val != BIGNUM) && (val != INT)){
9915827Srrh 				ERROR(ty_float[toconv]
9925827Srrh 				   ? "floating number expected"
9935827Srrh 				   : "integer number expected" );
994597Sbill 			}
9955827Srrh 			dotp->e_xvalue += ty_nbyte[toconv];
9965827Srrh 			if (passno == 2){
9975827Srrh 				bignumwrite(
9985827Srrh 					((struct exp *)yylval)->e_number,
9995827Srrh 					toconv);
1000597Sbill 			}
1001597Sbill 			xp = explist;
10025827Srrh 			shift;		/* over this number */
10035827Srrh 			if (auxval = (val == CM))
10045827Srrh 				shift;	/* over the comma */
10055827Srrh 		} while (auxval);	/* as long as there are commas */
1006597Sbill 	}
1007597Sbill 	break;
10085827Srrh 	/* end of the case for initialized big numbers */
1009597Sbill     }	/*end of the switch for looking at each reserved word*/
1010597Sbill 
10115827Srrh 	continue;
1012597Sbill 
1013597Sbill    errorfix:
1014597Sbill 	/*
1015597Sbill 	 *	got here by either requesting to skip to the
1016597Sbill 	 *	end of this statement, or by erroring out and
1017597Sbill 	 *	wanting to apply panic mode recovery
1018597Sbill 	 */
1019597Sbill 	while (    (val != NL)
1020597Sbill 		&& (val != SEMI)
1021597Sbill 		&& (val != PARSEEOF)
1022597Sbill 	      ){
1023597Sbill 		shift;
1024597Sbill 	}
1025597Sbill 	if (val == NL)
1026597Sbill 		lineno++;
1027597Sbill 	shift;
1028597Sbill 
1029597Sbill     }	/*end of the loop to read the entire file, line by line*/
1030597Sbill 
1031597Sbill }	/*end of yyparse*/
1032597Sbill 
1033597Sbill /*
1034597Sbill  *	Process a register declaration of the form
1035597Sbill  *	% <expr>
1036597Sbill  *
1037597Sbill  *	Note:
1038597Sbill  *		The scanner has already processed funny registers of the form
1039597Sbill  *	%dd[+-]*, where dd is a decimal number in the range 00 to 15 (optional
1040597Sbill  *	preceding zero digit).  If there was any space between the % and
1041597Sbill  *	the digit, the scanner wouldn't have recognized it, so we
1042597Sbill  *	hack it out here.
1043597Sbill  */
10445827Srrh inttoktype funnyreg(val, regnoback)	/*what the read head will sit on*/
10455827Srrh 	inttoktype	val;		/*what the read head is sitting on*/
1046597Sbill 	int	*regnoback;		/*call by return*/
1047597Sbill {
10485827Srrh 	reg	struct	exp *locxp;
10495827Srrh 		struct	exp *loc1xp;
10505827Srrh 		struct	exp **ptrloc1xp = & loc1xp;
1051597Sbill 
1052597Sbill 	expr(locxp, val);	/*and leave the current read head with value*/
1053597Sbill 	if ( (passno == 2) &&
10545827Srrh 	    (   (locxp->e_xtype & XTYPE) != XABS
10555827Srrh 	     || (locxp->e_xvalue < 0)
10565827Srrh 	     || (locxp->e_xvalue >= 16)
1057597Sbill 	    )
1058597Sbill 	  ){
1059597Sbill 		yyerror("Illegal register");
1060597Sbill 		return(0);
1061597Sbill 	}
1062632Shenry 	*regnoback = locxp->e_xvalue;
1063597Sbill 	return(val);
1064597Sbill }
106512945Srrh /*
106612945Srrh  *	Shift over error
106712945Srrh  */
106812945Srrh shiftoerror(token)
106912945Srrh 	int	token;
107012945Srrh {
107112945Srrh 	char	*tok_to_name();
107212945Srrh 	yyerror("%s expected", tok_to_name(token));
107312945Srrh }
1074597Sbill 
1075597Sbill /*VARARGS1*/
1076597Sbill yyerror(s, a1, a2,a3,a4,a5)
1077597Sbill 	char	*s;
1078597Sbill {
1079597Sbill 
1080649Shenry #define	sink stdout
1081597Sbill 
10825827Srrh 	if (anyerrs == 0 && anywarnings == 0 && ! silent)
1083597Sbill 		fprintf(sink, "Assembler:\n");
1084597Sbill 	anyerrs++;
10855827Srrh 	if (silent)
10865827Srrh 		return;
1087597Sbill 	fprintf(sink, "\"%s\", line %d: ", dotsname, lineno);
1088597Sbill 	fprintf(sink, s, a1, a2,a3,a4,a5);
1089597Sbill 	fprintf(sink, "\n");
10905827Srrh #undef sink
1091597Sbill }
1092676Shenry 
1093676Shenry /*VARARGS1*/
1094676Shenry yywarning(s, a1, a2,a3,a4,a5)
1095676Shenry 	char	*s;
1096676Shenry {
1097676Shenry #define	sink stdout
10985827Srrh 	if (anyerrs == 0 && anywarnings == 0 && ! silent)
1099676Shenry 		fprintf(sink, "Assembler:\n");
11005827Srrh 	anywarnings++;
11015827Srrh 	if (silent)
11025827Srrh 		return;
1103676Shenry 	fprintf(sink, "\"%s\", line %d: WARNING: ", dotsname, lineno);
1104676Shenry 	fprintf(sink, s, a1, a2,a3,a4,a5);
1105676Shenry 	fprintf(sink, "\n");
11065827Srrh #undef sink
1107676Shenry }
1108