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