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