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