|
|
1.1 root 1: /*
2: * Copyright (c) 1982 Regents of the University of California
3: */
4: #ifndef lint
5: static char sccsid[] = "@(#)asexpr.c 4.5 6/30/83";
6:
7: #endif not lint
8: #include <stdio.h>
9: #include "as.h"
10: #include "asscan.h"
11: #include "asexpr.h"
12:
13: /*
14: * Tables for combination of operands.
15: */
16: #define XTXRN 5<<1 /* indexes last row/column when right shifted */
17:
18: /*
19: * table for +
20: */
21: readonly char pltab[6][6] = {
22: /* UND ABS TXT DAT BSS EXT */
23:
24: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
25: /*ABS*/ XUNDEF, XABS, XTEXT, XDATA, XBSS, XXTRN,
26: /*TXT*/ XUNDEF, XTEXT, ERR, ERR, ERR, ERR,
27: /*DAT*/ XUNDEF, XDATA, ERR, ERR, ERR, ERR,
28: /*BSS*/ XUNDEF, XBSS, ERR, ERR, ERR, ERR,
29: /*EXT*/ XUNDEF, XXTRN, ERR, ERR, ERR, ERR,
30: };
31:
32: /*
33: * table for -
34: */
35: readonly char mintab[6][6] = {
36: /* UND ABS TXT DAT BSS EXT */
37:
38: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
39: /*ABS*/ XUNDEF, XABS, ERR, ERR, ERR, ERR,
40: /*TXT*/ XUNDEF, XTEXT, XABS, ERR, ERR, ERR,
41: /*DAT*/ XUNDEF, XDATA, ERR, XABS, ERR, ERR,
42: /*BSS*/ XUNDEF, XBSS, ERR, ERR, XABS, ERR,
43: /*EXT*/ XUNDEF, XXTRN, ERR, ERR, ERR, ERR,
44: };
45:
46: /*
47: * table for other operators
48: */
49: readonly char othtab[6][6] = {
50: /* UND ABS TXT DAT BSS EXT */
51:
52: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF,
53: /*ABS*/ XUNDEF, XABS, ERR, ERR, ERR, ERR,
54: /*TXT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR,
55: /*DAT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR,
56: /*BSS*/ XUNDEF, ERR, ERR, ERR, ERR, ERR,
57: /*EXT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR,
58: };
59:
60: struct exp *combine(op, exp1, exp2)
61: reg struct exp *exp1, *exp2;
62: {
63: reg e1_type, e2_type;
64: reg back_type;
65: char *btype = "The assembler can only do arithmetic on 1,2, or 4 byte integers";
66:
67: lastnam=0; /* kludge for jxxx instructions */
68:
69: e1_type = exp1->e_xtype&XTYPE;
70: e2_type = exp2->e_xtype&XTYPE;
71:
72: if (exp1->e_xtype==XXTRN+XUNDEF)
73: e1_type = XTXRN;
74: if (exp2->e_xtype==XXTRN+XUNDEF)
75: e2_type = XTXRN;
76: if (passno==1)
77: if (exp1->e_xloc!=exp2->e_xloc && e1_type==e2_type)
78: e1_type = e2_type = XTXRN; /* error on != loc ctrs */
79: e1_type >>= 1; /*dispose of the external (XXTRN) bit*/
80: e2_type >>= 1;
81:
82: switch(exp1->e_number.num_tag){
83: case TYPB:
84: case TYPW:
85: case TYPL:
86: break;
87: default:
88: yyerror(btype);
89: return(exp1);
90: }
91: switch(exp2->e_number.num_tag){
92: case TYPB:
93: case TYPW:
94: case TYPL:
95: break;
96: default:
97: yyerror(btype);
98: return(exp1);
99: }
100: switch (op){
101: case PLUS:
102: exp1->e_xvalue += exp2->e_xvalue;
103: back_type = pltab[e1_type][e2_type];
104: break;
105: case MINUS:
106: exp1->e_xvalue -= exp2->e_xvalue;
107: back_type = mintab[e1_type][e2_type];
108: break;
109: case IOR:
110: exp1->e_xvalue |= exp2->e_xvalue;
111: goto comm;
112: case XOR:
113: exp1->e_xvalue ^= exp2->e_xvalue;
114: goto comm;
115: case AND:
116: exp1->e_xvalue &= exp2->e_xvalue;
117: goto comm;
118: case ORNOT:
119: exp1->e_xvalue |= ~exp2->e_xvalue;
120: goto comm;
121: case LSH:
122: exp1->e_xvalue <<= exp2->e_xvalue;
123: goto comm;
124: case RSH:
125: exp1->e_xvalue >>= exp2->e_xvalue;
126: goto comm;
127: case TILDE:
128: exp1->e_xvalue |= ~ exp2->e_xvalue;
129: goto comm;
130: case MUL:
131: exp1->e_xvalue *= exp2->e_xvalue;
132: goto comm;
133: case DIV:
134: if (exp2->e_xvalue == 0)
135: yyerror("Divide check");
136: else
137: exp1->e_xvalue /= exp2->e_xvalue;
138: goto comm;
139: case REGOP:
140: if (exp2->e_xvalue == 0)
141: yyerror("Divide check (modulo)");
142: else
143: exp1->e_xvalue %= exp2->e_xvalue;
144: goto comm;
145:
146: comm:
147: back_type = othtab[e1_type][e2_type];
148: break;
149: default:
150: yyerror("Internal error: unknown operator");
151: }
152:
153: if (e2_type==(XTXRN>>1))
154: exp1->e_xname = exp2->e_xname;
155: exp1->e_xtype = back_type | (
156: (exp1->e_xtype|exp2->e_xtype) & (XFORW|XXTRN) );
157: if (back_type==ERR)
158: yyerror("Relocation error");
159: return(exp1);
160: }
161:
162: buildtokensets()
163: {
164: #define clobber(val, set) tokensets[(val)] |= (set)
165:
166: clobber(SEMI, LINSTBEGIN);
167: clobber(NL, LINSTBEGIN);
168: clobber(INT, LINSTBEGIN);
169:
170: clobber(NAME, YUKKYEXPRBEG + LINSTBEGIN);
171: clobber(INSTn, YUKKYEXPRBEG);
172: clobber(INST0, YUKKYEXPRBEG);
173: clobber(REG, YUKKYEXPRBEG);
174: clobber(BFINT, YUKKYEXPRBEG);
175:
176: clobber(INT, SAFEEXPRBEG);
177: clobber(BIGNUM, SAFEEXPRBEG);
178:
179: clobber(PLUS, ADDOPS);
180: clobber(MINUS, ADDOPS + EBEGOPS);
181:
182: clobber(LP, EBEGOPS);
183:
184: clobber(IOR, BOOLOPS);
185: clobber(XOR, BOOLOPS);
186: clobber(AND, BOOLOPS);
187: clobber(ORNOT, BOOLOPS);
188:
189: clobber(TILDE, MULOPS + EBEGOPS);
190: clobber(LSH, MULOPS);
191: clobber(RSH, MULOPS);
192: clobber(MUL, MULOPS);
193: clobber(DIV, MULOPS);
194: clobber(REGOP, MULOPS); /* % */
195:
196: }
197:
198: /*
199: * We keep the current token class in this global variable, so
200: * the recursive descent expression analyzers can talk amongst
201: * themselves, and so that we may use the macros shift and shift over
202: */
203:
204: extern int yylval; /*the value of the lexical value*/
205: extern struct exp *xp; /*the next free expression slot*/
206:
207: static inttoktype val;
208:
209: /*
210: * return the value the read head is sitting on
211: */
212: inttoktype exprparse(inval, backexpr)
213: inttoktype inval;
214: struct exp **backexpr;
215: {
216: reg struct exp *lexpr;
217: inttoktype op;
218:
219: val = inval;
220: lexpr = boolterm();
221: while (INTOKSET(val, ADDOPS)){
222: op = val;
223: shift;
224: lexpr = combine(op, lexpr, boolterm());
225: }
226: *backexpr = lexpr;
227: return(val);
228: }
229:
230: struct exp *boolterm()
231: {
232: reg struct exp *lexpr;
233: inttoktype op;
234:
235: lexpr = term();
236: while(INTOKSET(val, BOOLOPS)){
237: op = val;
238: shift;
239: lexpr = combine(op, lexpr, term());
240: }
241: return(lexpr);
242: }
243:
244: struct exp *term()
245: {
246: reg struct exp *lexpr;
247: inttoktype op;
248:
249: lexpr = factor();
250: while(INTOKSET(val, MULOPS)){
251: op = val;
252: shift;
253: lexpr = combine(op, lexpr, factor());
254: }
255: return(lexpr);
256: }
257:
258: struct exp *factor()
259: {
260: struct exp *lexpr;
261: inttoktype op;
262: extern int droppedLP; /*called exprparse after consuming an LP*/
263:
264: if (val == LP || droppedLP){
265: if (droppedLP)
266: droppedLP = 0;
267: else
268: shift; /*the LP*/
269: val = exprparse(val, &lexpr);
270: if (val != RP)
271: yyerror("right parenthesis expected");
272: else
273: shift;
274: } else
275: if (INTOKSET(val, YUKKYEXPRBEG)){
276: lexpr = yukkyexpr(val, yylval);
277: shift;
278: }
279: else if (INTOKSET(val, SAFEEXPRBEG)){
280: lexpr = (struct exp *)yylval;
281: shift;
282: }
283: else if ( (val == TILDE) || (val == MINUS) ){
284: op = val;
285: shift;
286: lexpr = xp++;
287: lexpr->e_xtype = XABS;
288: lexpr->e_number = Znumber;
289: lexpr->e_number.num_tag = TYPL;
290: lexpr = combine(op, lexpr, factor());
291: } else {
292: yyerror("Bad expression syntax");
293: lexpr = xp++;
294: lexpr->e_xtype = XABS;
295: lexpr->e_number = Znumber;
296: lexpr->e_number.num_tag = TYPL;
297: }
298: return(lexpr);
299: }
300:
301: struct exp *yukkyexpr(val, np)
302: int val;
303: reg np;
304: {
305: reg struct exp *locxp;
306: extern int exprisname; /*last factor is a name*/
307: int off = 0;
308:
309: exprisname = 0;
310: locxp = xp++;
311: locxp->e_number = Znumber;
312: locxp->e_number.num_tag = TYPL;
313:
314: switch(val){
315: case BFINT:
316: yylval = ((struct exp *)np)->e_xvalue;
317: if (yylval < 0) {
318: yylval = -yylval;
319: yylval--;
320: off = -1;
321: if (lgensym[yylval] == 1)
322: yyerror("Reference to undefined local label %db", yylval);
323: } else {
324: yylval--;
325: genref[yylval] = 1;
326: }
327: (void)sprintf(yytext, "L%d\001%d", yylval, lgensym[yylval] + off);
328: yylval = np = (int)*lookup(passno == 1);
329: lastnam = (struct symtab *)np;
330: /* FALLTHROUGH */
331: case NAME:
332: exprisname++;
333: locxp->e_xtype = ((struct symtab *)np)->s_type;
334: if (( ((struct symtab *)np)->s_type&XTYPE)==XUNDEF) { /*forward*/
335: locxp->e_xname = (struct symtab *)np;
336: locxp->e_xvalue = 0;
337: if (passno==1)
338: ((struct symtab *)np)->s_type |= XFORW;
339: } else { /*otherwise, just get the value*/
340: locxp->e_xvalue = ((struct symtab *)np)->s_value;
341: locxp->e_xname = NULL;
342: }
343: break;
344: default:
345: yyerror("Internal Error in yukkyexpr");
346: /* FALLTHROUGH */
347:
348: case INSTn:
349: case INST0:
350: case REG:
351: locxp->e_xtype = XABS;
352: locxp->e_xvalue = ( (int)np) & 0xFF;
353: locxp->e_xloc = 0;
354: locxp->e_xname = NULL;
355: break;
356: }
357:
358: return(locxp);
359: }
360:
361: /*
362: * Print definitions for token kinds
363: */
364: static char pdirect[] = "directive";
365: static char pinstr[] = "instruction";
366: static char phunk[] = "lexeme";
367: static char psmall[] = "small symbol";
368: static char pcntrl[] = "control token";
369:
370: #define DIRECT pdirect
371: #define INSTR pinstr
372: #define HUNK phunk
373: #define SMALL psmall
374: #define CNTRL pcntrl
375:
376: struct Tok_Desc{
377: int tok_which;
378: char *tok_kind;
379: char *tok_name;
380: };
381: struct Tok_Desc *tok_name[LASTTOKEN - FIRSTTOKEN + 1];
382:
383: struct Tok_Desc tok_desc[] = {
384: FIRSTTOKEN, DIRECT, "first token",
385:
386: IBYTE, DIRECT, ".byte",
387: IWORD, DIRECT, ".word",
388: IINT, DIRECT, ".int",
389: ILONG, DIRECT, ".long",
390: IQUAD, DIRECT, ".quad",
391: IOCTA, DIRECT, ".octa",
392: IFFLOAT, DIRECT, ".ffloat",
393: IDFLOAT, DIRECT, ".dfloat",
394: IGFLOAT, DIRECT, ".gfloat",
395: IHFLOAT, DIRECT, ".hfloat",
396: IASCII, DIRECT, ".ascii",
397: IASCIZ, DIRECT, ".asciz",
398: IFILL, DIRECT, ".fill",
399: ISPACE, DIRECT, ".space",
400:
401: IDATA, DIRECT, ".data",
402: ITEXT, DIRECT, ".text",
403: IGLOBAL, DIRECT, ".global",
404: IALIGN, DIRECT, ".align",
405:
406: ISET, DIRECT, ".set",
407: ICOMM, DIRECT, ".comm",
408: ILCOMM, DIRECT, ".lcomm",
409: IORG, DIRECT, ".org",
410: ILSYM, DIRECT, ".lsym",
411:
412: ISTAB, DIRECT, ".stab",
413: ISTABSTR, DIRECT, ".stabstr",
414: ISTABNONE, DIRECT, ".stabnone",
415: ISTABDOT, DIRECT, ".stabdot",
416:
417: IFILE, DIRECT, ".file",
418: ILINENO, DIRECT, ".lineno",
419: IABORT, DIRECT, ".abort",
420:
421: IJXXX, INSTR, "jump pseudo",
422: INST0, INSTR, "0 argument inst",
423: INSTn, INSTR, "n argument inst",
424:
425: PARSEEOF, CNTRL, "parse end of file",
426: ILINESKIP, CNTRL, "skip lines",
427: VOID, CNTRL, "void",
428: SKIP, CNTRL, "skip",
429: NL, CNTRL, "new line",
430: SCANEOF, CNTRL, "scanner end of file",
431: BADCHAR, CNTRL, "bad character",
432: SH, CNTRL, "comment, #",
433:
434: INT, HUNK, "int",
435: BFINT, HUNK, "local label",
436: BIGNUM, HUNK, "big number",
437: NAME, HUNK, "name",
438: STRING, HUNK, "string",
439: REG, HUNK, "register specifier",
440:
441: SIZESPEC, SMALL, "size specifier, [BWLbwl]",
442: SIZEQUOTE, SMALL, "sizequote, [^']",
443: LITOP, SMALL, "litop",
444:
445: MP, SMALL, "minus parenthesis, -(",
446: REGOP, SMALL, "register operator, %",
447:
448: SP, SMALL, "space",
449: ALPH, SMALL, "alphabetic character, [A-Za-z_]",
450: DIG, SMALL, "digit character, [A-Fa-f0-9]",
451:
452: SQ, SMALL, "single quote, '",
453: DQ, SMALL, "double quote, \"",
454:
455: LSH, SMALL, "arithmetic left shift, <",
456: RSH, SMALL, "arithmetic right shift, >",
457: XOR, SMALL, "exclusive or, ^",
458:
459: PLUS, SMALL, "plus, +",
460: MINUS, SMALL, "minus, -",
461: MUL, SMALL, "multiply, *",
462: DIV, SMALL, "divide, /",
463: SEMI, SMALL, "semi colon, ;",
464: COLON, SMALL, "colon, :",
465: IOR, SMALL, "inclusive or, |",
466: AND, SMALL, "and, &",
467:
468: TILDE, SMALL, "one's complement, ~",
469: ORNOT, SMALL, "ornot, !",
470: CM, SMALL, "comma",
471:
472: LB, SMALL, "left bracket, [",
473: RB, SMALL, "right bracket, ]",
474: LP, SMALL, "left parenthesis, (",
475: RP, SMALL, "right parentheis, )",
476:
477: LASTTOKEN, SMALL, "last token",
478: };
479: /*
480: * turn a token type into a string
481: */
482: char *tok_to_name(token)
483: {
484: static int fixed = 0;
485: static char buf[64];
486: static struct Tok_Desc NA = {0, (char *)0, "NOT ASSIGNED"};
487: int i;
488: char *cp;
489:
490: if (!fixed){
491: for (i = FIRSTTOKEN; i <= LASTTOKEN; i++)
492: tok_name[i] = &NA;
493: for (i = 0; i <= sizeof(tok_desc)/sizeof(struct Tok_Desc); i++){
494: tok_name[tok_desc[i].tok_which] = &tok_desc[i];
495: }
496: fixed = 1;
497: }
498: if (FIRSTTOKEN <= token && token <= LASTTOKEN){
499: sprintf(buf, "%s %s", tok_name[token]->tok_kind,
500: tok_name[token]->tok_name);
501: return(buf);
502: } else {
503: panic("Unknown token number, %d\n", token);
504: /*NOTREACHED*/
505: }
506: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.