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