xref: /csrg-svn/old/as.vax/asexpr.c (revision 593)
1*593Sbill /* Copyright (c) 1980 Regents of the University of California */
2*593Sbill static	char sccsid[] = "@(#)asexpr.c 4.1 08/13/80";
3*593Sbill #include <stdio.h>
4*593Sbill #include <sys/types.h>
5*593Sbill #include "as.h"
6*593Sbill #include "asexpr.h"
7*593Sbill 
8*593Sbill /*
9*593Sbill  * Tables for combination of operands.
10*593Sbill  */
11*593Sbill #define	XTXRN	5<<1		/* indexes last row/column when right shifted */
12*593Sbill 
13*593Sbill /*
14*593Sbill  *	table for +
15*593Sbill  */
16*593Sbill readonly char pltab[6][6] = {
17*593Sbill /*		UND	ABS	TXT	DAT	BSS	EXT */
18*593Sbill 
19*593Sbill /*UND*/		XUNDEF,	XUNDEF,	XUNDEF,	XUNDEF,	XUNDEF,	XUNDEF,
20*593Sbill /*ABS*/		XUNDEF,	XABS,	XTEXT,	XDATA,	XBSS,	XXTRN,
21*593Sbill /*TXT*/		XUNDEF,	XTEXT,	ERR,	ERR,	ERR,	ERR,
22*593Sbill /*DAT*/		XUNDEF,	XDATA,	ERR,	ERR,	ERR,	ERR,
23*593Sbill /*BSS*/		XUNDEF,	XBSS,	ERR,	ERR,	ERR,	ERR,
24*593Sbill /*EXT*/		XUNDEF,	XXTRN,	ERR,	ERR,	ERR,	ERR,
25*593Sbill };
26*593Sbill 
27*593Sbill /*
28*593Sbill  *	table for -
29*593Sbill  */
30*593Sbill readonly char mintab[6][6] = {
31*593Sbill /*		UND	ABS	TXT	DAT	BSS	EXT */
32*593Sbill 
33*593Sbill /*UND*/		XUNDEF,	XUNDEF,	XUNDEF,	XUNDEF,	XUNDEF,	XUNDEF,
34*593Sbill /*ABS*/		XUNDEF,	XABS,	ERR,	ERR,	ERR,	ERR,
35*593Sbill /*TXT*/		XUNDEF,	XTEXT,	XABS,	ERR,	ERR,	ERR,
36*593Sbill /*DAT*/		XUNDEF,	XDATA,	ERR,	XABS,	ERR,	ERR,
37*593Sbill /*BSS*/		XUNDEF,	XBSS,	ERR,	ERR,	XABS,	ERR,
38*593Sbill /*EXT*/		XUNDEF,	XXTRN,	ERR,	ERR,	ERR,	ERR,
39*593Sbill };
40*593Sbill 
41*593Sbill /*
42*593Sbill  *	table for other operators
43*593Sbill  */
44*593Sbill readonly char othtab[6][6] = {
45*593Sbill /*		UND	ABS	TXT	DAT	BSS	EXT */
46*593Sbill 
47*593Sbill /*UND*/		XUNDEF,	XUNDEF,	XUNDEF,	XUNDEF,	XUNDEF,	XUNDEF,
48*593Sbill /*ABS*/		XUNDEF,	XABS,	ERR,	ERR,	ERR,	ERR,
49*593Sbill /*TXT*/		XUNDEF,	ERR,	ERR,	ERR,	ERR,	ERR,
50*593Sbill /*DAT*/		XUNDEF,	ERR,	ERR,	ERR,	ERR,	ERR,
51*593Sbill /*BSS*/		XUNDEF,	ERR,	ERR,	ERR,	ERR,	ERR,
52*593Sbill /*EXT*/		XUNDEF,	ERR,	ERR,	ERR,	ERR,	ERR,
53*593Sbill };
54*593Sbill 
55*593Sbill struct exp *
56*593Sbill combine(op, exp1, exp2)
57*593Sbill 	register struct exp *exp1, *exp2;
58*593Sbill {
59*593Sbill 	register 	e1_type, e2_type;
60*593Sbill 	register	type;
61*593Sbill 
62*593Sbill 	lastnam=0; 			/* kludge for jxxx instructions */
63*593Sbill 
64*593Sbill 	e1_type = exp1->xtype&XTYPE;
65*593Sbill 	e2_type = exp2->xtype&XTYPE;
66*593Sbill 
67*593Sbill 	if (exp1->xtype==XXTRN+XUNDEF)
68*593Sbill 		e1_type = XTXRN;
69*593Sbill 	if (exp2->xtype==XXTRN+XUNDEF)
70*593Sbill 		e2_type = XTXRN;
71*593Sbill 	if (passno==1)
72*593Sbill 		if (exp1->xloc!=exp2->xloc && e1_type==e2_type)
73*593Sbill 			e1_type = e2_type = XTXRN;	/* error on != loc ctrs */
74*593Sbill 	e1_type >>= 1;		/*dispose of the external (XXTRN) bit*/
75*593Sbill 	e2_type >>= 1;
76*593Sbill 
77*593Sbill 	switch (op) {
78*593Sbill 	case PLUS:
79*593Sbill 		exp1->xvalue += exp2->xvalue;
80*593Sbill 		type = pltab[e1_type][e2_type];
81*593Sbill 		break;
82*593Sbill 	case MINUS:
83*593Sbill 		exp1->xvalue -= exp2->xvalue;
84*593Sbill 		type = mintab[e1_type][e2_type];
85*593Sbill 		break;
86*593Sbill 	case IOR:
87*593Sbill 		exp1->xvalue |= exp2->xvalue;
88*593Sbill 		goto comm;
89*593Sbill 	case XOR:
90*593Sbill 		exp1->xvalue ^= exp2->xvalue;
91*593Sbill 		goto comm;
92*593Sbill 	case AND:
93*593Sbill 		exp1->xvalue &= exp2->xvalue;
94*593Sbill 		goto comm;
95*593Sbill 	case ORNOT:
96*593Sbill 		exp1->xvalue |= ~exp2->xvalue;
97*593Sbill 		goto comm;
98*593Sbill 	case LSH:
99*593Sbill 		exp1->xvalue <<= exp2->xvalue;
100*593Sbill 		goto comm;
101*593Sbill 	case RSH:
102*593Sbill 		exp1->xvalue >>= exp2->xvalue;
103*593Sbill 		goto comm;
104*593Sbill 	case TILDE:
105*593Sbill 		exp1->xvalue |= ~ exp2->xvalue;
106*593Sbill 		goto comm;
107*593Sbill 	case MUL:
108*593Sbill 		exp1->xvalue *= exp2->xvalue;
109*593Sbill 		goto comm;
110*593Sbill 	case DIV:
111*593Sbill 		if (exp2->xvalue == 0)
112*593Sbill 			yyerror("Divide check");
113*593Sbill 		else
114*593Sbill 			exp1->xvalue /= exp2->xvalue;
115*593Sbill 		goto comm;
116*593Sbill 	case REGOP:
117*593Sbill 		if (exp2->xvalue == 0)
118*593Sbill 			yyerror("Divide check (modulo)");
119*593Sbill 		else
120*593Sbill 			exp1->xvalue %= exp2->xvalue;
121*593Sbill 		goto comm;
122*593Sbill 
123*593Sbill 	comm:
124*593Sbill 		type = othtab[e1_type][e2_type];
125*593Sbill 		break;
126*593Sbill 	default:
127*593Sbill 		yyerror("Internal error: unknown operator");
128*593Sbill 	}
129*593Sbill 
130*593Sbill 	if (e2_type==(XTXRN>>1))
131*593Sbill 		exp1->xname = exp2->xname;
132*593Sbill 	exp1->xtype = type | (
133*593Sbill 			(exp1->xtype|exp2->xtype) & (XFORW|XXTRN) );
134*593Sbill 	if (type==ERR)
135*593Sbill 		yyerror("Relocation error");
136*593Sbill 	return(exp1);
137*593Sbill }
138*593Sbill 
139*593Sbill buildtokensets()
140*593Sbill {
141*593Sbill #define clobber(val, set) tokensets[(val)] |= (set)
142*593Sbill 
143*593Sbill 	clobber(SEMI,	LINSTBEGIN);
144*593Sbill 	clobber(NL,	LINSTBEGIN);
145*593Sbill 	clobber(INT,	LINSTBEGIN);
146*593Sbill 
147*593Sbill 	clobber(NAME,	YUKKYEXPRBEG + LINSTBEGIN);
148*593Sbill 	clobber(INSTn,	YUKKYEXPRBEG);
149*593Sbill 	clobber(INST0,	YUKKYEXPRBEG);
150*593Sbill 	clobber(REG,	YUKKYEXPRBEG);
151*593Sbill 	clobber(BFINT,	YUKKYEXPRBEG);
152*593Sbill 
153*593Sbill 	clobber(INT,	SAFEEXPRBEG);
154*593Sbill 	clobber(FLTNUM,	SAFEEXPRBEG);
155*593Sbill 
156*593Sbill 	clobber(PLUS,	ADDOPS);
157*593Sbill 	clobber(MINUS,	ADDOPS + EBEGOPS);
158*593Sbill 
159*593Sbill 	clobber(LP,	EBEGOPS);
160*593Sbill 
161*593Sbill 	clobber(IOR,	BOOLOPS);
162*593Sbill 	clobber(XOR,	BOOLOPS);
163*593Sbill 	clobber(AND,	BOOLOPS);
164*593Sbill 	clobber(ORNOT,	BOOLOPS);
165*593Sbill 
166*593Sbill 	clobber(TILDE,	MULOPS + EBEGOPS);
167*593Sbill 	clobber(LSH,	MULOPS);
168*593Sbill 	clobber(RSH,	MULOPS);
169*593Sbill 	clobber(MUL,	MULOPS);
170*593Sbill 	clobber(DIV,	MULOPS);
171*593Sbill 	clobber(REGOP,	MULOPS);	/* % */
172*593Sbill 
173*593Sbill }
174*593Sbill 
175*593Sbill /*
176*593Sbill  *	We keep the current token class in this global variable, so
177*593Sbill  *	the recursive descent expression analyzers can talk amongst
178*593Sbill  *	themselves, and so that we may use the macros shift and shift over
179*593Sbill  */
180*593Sbill 
181*593Sbill extern	int	yylval;		/*the value of the lexical value*/
182*593Sbill extern	struct	exp	*xp;	/*the next free expression slot*/
183*593Sbill 
184*593Sbill static int	val;
185*593Sbill int exprparse(inval, backexpr)	/*return the value the read head is sitting on*/
186*593Sbill 	int	inval;
187*593Sbill 	struct	exp **backexpr;
188*593Sbill {
189*593Sbill 	register struct exp *lexpr;
190*593Sbill 	int	op;
191*593Sbill 
192*593Sbill 	val = inval;
193*593Sbill 	lexpr = boolterm();
194*593Sbill 	while (INTOKSET(val, ADDOPS)){
195*593Sbill 		op = val;
196*593Sbill 		shift;
197*593Sbill 		lexpr = combine(op, lexpr, boolterm());
198*593Sbill 	}
199*593Sbill 	*backexpr = lexpr;
200*593Sbill 	return(val);
201*593Sbill }
202*593Sbill 
203*593Sbill struct exp *boolterm()
204*593Sbill {
205*593Sbill 	register	struct exp *lexpr;
206*593Sbill 	int	op;
207*593Sbill 
208*593Sbill 	lexpr = term();
209*593Sbill 	while(INTOKSET(val, BOOLOPS)){
210*593Sbill 		op = val;
211*593Sbill 		shift;
212*593Sbill 		lexpr = combine(op, lexpr, term());
213*593Sbill 	}
214*593Sbill 	return(lexpr);
215*593Sbill }
216*593Sbill 
217*593Sbill struct exp *term()
218*593Sbill {
219*593Sbill 	register	struct	exp	*lexpr;
220*593Sbill 	int		op;
221*593Sbill 
222*593Sbill 	lexpr = factor();
223*593Sbill 	while(INTOKSET(val, MULOPS)){
224*593Sbill 		op = val;
225*593Sbill 		shift;
226*593Sbill 		lexpr = combine(op, lexpr, factor());
227*593Sbill 	}
228*593Sbill 	return(lexpr);
229*593Sbill }
230*593Sbill 
231*593Sbill struct exp *factor()
232*593Sbill {
233*593Sbill 	struct	exp *lexpr;
234*593Sbill 	int		op;
235*593Sbill 	extern		int	droppedLP;	/*called exprparse after consuming an LP*/
236*593Sbill 
237*593Sbill 	if (val == LP || droppedLP){
238*593Sbill 		if (droppedLP)
239*593Sbill 			droppedLP = 0;
240*593Sbill 		else
241*593Sbill 			shift;		/*the LP*/
242*593Sbill 		val = exprparse(val, &lexpr);
243*593Sbill 		if (val != RP)
244*593Sbill 			yyerror("right parenthesis expected");
245*593Sbill 		else
246*593Sbill 			shift;
247*593Sbill 	} else
248*593Sbill 	if (INTOKSET(val, YUKKYEXPRBEG)){
249*593Sbill 		lexpr = yukkyexpr(val, yylval);
250*593Sbill 		shift;
251*593Sbill 	}
252*593Sbill 	else if (INTOKSET(val, SAFEEXPRBEG)){
253*593Sbill 		lexpr = (struct exp *)yylval;
254*593Sbill 		shift;
255*593Sbill 	}
256*593Sbill 	else if ( (val == TILDE) || (val == MINUS) ){
257*593Sbill 		op = val;
258*593Sbill 		shift;
259*593Sbill 		lexpr = xp++;
260*593Sbill 		lexpr->xtype = XABS;
261*593Sbill 		lexpr->xvalue = 0;
262*593Sbill 		lexpr = combine(op, lexpr, factor());
263*593Sbill 	}
264*593Sbill 	else {
265*593Sbill 		yyerror("Bad expression syntax");
266*593Sbill 		lexpr = xp++;
267*593Sbill 		lexpr->xtype = XABS;
268*593Sbill 		lexpr->xvalue = 0;
269*593Sbill 	}
270*593Sbill 	return(lexpr);
271*593Sbill }
272*593Sbill 
273*593Sbill struct exp *yukkyexpr(val, np)
274*593Sbill 	int	val;
275*593Sbill 	register	np;
276*593Sbill {
277*593Sbill 	register	struct exp *locxp;
278*593Sbill 	extern		int	exprisname;	/*last factor is a name*/
279*593Sbill 
280*593Sbill 	exprisname = 0;
281*593Sbill 	locxp = xp++;
282*593Sbill 	if (val == NAME || val == BFINT){
283*593Sbill 		if (val == BFINT) {
284*593Sbill 			int off = 0;
285*593Sbill 			yylval = ((struct exp *)np)->xvalue;
286*593Sbill 			if (yylval < 0) {
287*593Sbill 				yylval = -yylval;
288*593Sbill 				yylval--;
289*593Sbill 				off = -1;
290*593Sbill 				if (lgensym[yylval] == 1)
291*593Sbill 					yyerror("Reference to undefined local label %db", yylval);
292*593Sbill 			} else {
293*593Sbill 				yylval--;
294*593Sbill 				genref[yylval] = 1;
295*593Sbill 			}
296*593Sbill 			sprintf(yytext, "L%d\001%d", yylval, lgensym[yylval] + off);
297*593Sbill 			yylval = np = (int)*lookup(passno == 1);
298*593Sbill 			lastnam = (struct symtab *)np;
299*593Sbill 		}
300*593Sbill 		exprisname++;
301*593Sbill 		locxp->xtype = ((struct symtab *)np)->type;
302*593Sbill 		if (( ((struct symtab *)np)->type&XTYPE)==XUNDEF) { /*forward*/
303*593Sbill 			locxp->xname = (struct symtab *)np;
304*593Sbill 			locxp->xvalue = 0;
305*593Sbill 			if (passno==1)
306*593Sbill 				((struct symtab *)np)->type |= XFORW;
307*593Sbill 		} else {	/*otherwise, just get the value*/
308*593Sbill 			locxp->xvalue = ((struct symtab *)np)->value;
309*593Sbill 			locxp->xname = NULL;
310*593Sbill 		}
311*593Sbill 	} else {	/*INSTn or INST0 or REG*/
312*593Sbill 		locxp->xtype = XABS;
313*593Sbill 		locxp->xvalue = ( (int)np) & 0xFF;
314*593Sbill 		locxp->xloc = 0;
315*593Sbill 		locxp->xname = NULL;
316*593Sbill 	}
317*593Sbill 
318*593Sbill 	return(locxp);
319*593Sbill }
320*593Sbill 
321*593Sbill 
322*593Sbill #ifdef DEBUG
323*593Sbill char	*tok_name[LASTTOKEN - FIRSTTOKEN + 1];
324*593Sbill struct Tok_Desc{
325*593Sbill 	int		tok_which;
326*593Sbill 	char		*tok_name;
327*593Sbill } tok_desc[] = {
328*593Sbill 	FIRSTTOKEN,	"firsttoken",	/* 0 */
329*593Sbill 	ISPACE,		"ispace", 	/* 1 */
330*593Sbill 	IBYTE,		"ibyte", 	/* 2 */
331*593Sbill 	IWORD,		"iword", 	/* 3 */
332*593Sbill 	IINT,		"iint", 	/* 4 */
333*593Sbill 	ILONG,		"ilong", 	/* 5 */
334*593Sbill 	IDATA,		"idata", 	/* 6 */
335*593Sbill 	IGLOBAL,	"iglobal", 	/* 7 */
336*593Sbill 	ISET,		"iset", 	/* 8 */
337*593Sbill 	ITEXT,		"itext", 	/* 9 */
338*593Sbill 	ICOMM,		"icomm", 	/* 10 */
339*593Sbill 	ILCOMM,		"ilcomm", 	/* 11 */
340*593Sbill 	IFLOAT,		"ifloat", 	/* 12 */
341*593Sbill 	IDOUBLE,	"idouble", 	/* 13 */
342*593Sbill 	IORG,		"iorg", 	/* 14 */
343*593Sbill 	IASCII,		"iascii", 	/* 15 */
344*593Sbill 	IASCIZ,		"iasciz", 	/* 16 */
345*593Sbill 	ILSYM,		"ilsym", 	/* 17 */
346*593Sbill 	IFILE,		"ifile", 	/* 18 */
347*593Sbill 	ILINENO,	"ilineno", 	/* 19 */
348*593Sbill 	IABORT,		"iabort", 	/* 20 */
349*593Sbill 	ISTAB,		"istab", 	/* 23 */
350*593Sbill 	ISTABSTR,	"istabstr", 	/* 24 */
351*593Sbill 	ISTABNONE,	"istabnone", 	/* 25 */
352*593Sbill 	ISTABDOT,	"istabdot", 	/* 26 */
353*593Sbill 	IJXXX,		"ijxxx", 	/* 27 */
354*593Sbill 	IALIGN,		"ialign", 	/* 28 */
355*593Sbill 	INST0,		"inst0", 	/* 29 */
356*593Sbill 	INSTn,		"instn", 	/* 30 */
357*593Sbill 	BFINT,		"bfint",	/* 31 */
358*593Sbill 	PARSEEOF,	"parseeof",	/* 32 */
359*593Sbill 	ILINESKIP,	"ilineskip",	/* 33 */
360*593Sbill 	VOID,		"void",		/* 34 */
361*593Sbill 	SKIP,		"skip",		/* 35 */
362*593Sbill 	INT,		"int",		/* 36 */
363*593Sbill 	FLTNUM,		"fltnum",	/* 37 */
364*593Sbill 	NAME,		"name",		/* 38 */
365*593Sbill 	STRING,		"string",	/* 39 */
366*593Sbill 	QUAD,		"quad",		/* 40 */
367*593Sbill 	SIZESPEC,	"sizespec", 	/* 41 */
368*593Sbill 	REG,		"reg",		/* 42 */
369*593Sbill 	MUL,		"mul",		/* 43 */
370*593Sbill 	LITOP,		"litop",	/* 44 */
371*593Sbill 	LP,		"lp",		/* 45 */
372*593Sbill 	MP,		"mp",		/* 46 */
373*593Sbill 	NEEDSBUF,	"needsbuf",	/* 48 */
374*593Sbill 	REGOP,		"regop",	/* 49 */
375*593Sbill 	NL,		"nl",		/* 50 */
376*593Sbill 	SCANEOF,	"scaneof",	/* 51 */
377*593Sbill 	BADCHAR,	"badchar",	/* 52 */
378*593Sbill 	SP,		"sp",		/* 53 */
379*593Sbill 	ALPH,		"alph",		/* 54 */
380*593Sbill 	DIG,		"dig",		/* 55 */
381*593Sbill 	SQ,		"sq",		/* 56 */
382*593Sbill 	DQ,		"dq",		/* 57 */
383*593Sbill 	SH,		"sh",		/* 58 */
384*593Sbill 	LSH,		"lsh",		/* 59 */
385*593Sbill 	RSH,		"rsh",		/* 60 */
386*593Sbill 	MINUS,		"minus",	/* 61 */
387*593Sbill 	SIZEQUOTE,	"sizequote",	/* 62 */
388*593Sbill 	XOR,		"xor",		/* 64 */
389*593Sbill 	DIV,		"div",		/* 65 */
390*593Sbill 	SEMI,		"semi",		/* 66 */
391*593Sbill 	COLON,		"colon",	/* 67 */
392*593Sbill 	PLUS,		"plus",		/* 68 */
393*593Sbill 	IOR,		"ior",		/* 69 */
394*593Sbill 	AND,		"and",		/* 70 */
395*593Sbill 	TILDE,		"tilde",	/* 71 */
396*593Sbill 	ORNOT,		"ornot",	/* 72 */
397*593Sbill 	CM,		"cm",		/* 73 */
398*593Sbill 	LB,		"lb",		/* 74 */
399*593Sbill 	RB,		"rb",		/* 75 */
400*593Sbill 	RP,		"rp",		/* 76 */
401*593Sbill 	LASTTOKEN,	"lasttoken"	/* 80 */
402*593Sbill };
403*593Sbill /*
404*593Sbill  *	turn a token type into a string
405*593Sbill  */
406*593Sbill static	int	fixed = 0;
407*593Sbill char *tok_to_name(token)
408*593Sbill {
409*593Sbill 	if (!fixed){
410*593Sbill 		int	i;
411*593Sbill 		for (i = FIRSTTOKEN; i <= LASTTOKEN; i++)
412*593Sbill 			tok_name[i] = "NOT ASSIGNED";
413*593Sbill 		for (i = FIRSTTOKEN; i <= sizeof(tok_desc)/sizeof(struct Tok_Desc); i++){
414*593Sbill 			tok_name[tok_desc[i].tok_which] = tok_desc[i].tok_name;
415*593Sbill 		}
416*593Sbill 		fixed = 1;
417*593Sbill 	}
418*593Sbill 	if (FIRSTTOKEN <= token && token <= LASTTOKEN)
419*593Sbill 		return(tok_name[token]);
420*593Sbill 	else
421*593Sbill 		panic("Unknown token number, %d\n", token);
422*593Sbill 	/*NOTREACHED*/
423*593Sbill }
424*593Sbill #endif DEBUG
425