|
|
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.