|
|
1.1 ! root 1: /* Copyright (c) 1980 Regents of the University of California */ ! 2: static char sccsid[] = "@(#)asexpr.c 4.2 8/15/80"; ! 3: #include <stdio.h> ! 4: #include "as.h" ! 5: #include "asexpr.h" ! 6: ! 7: /* ! 8: * Tables for combination of operands. ! 9: */ ! 10: #define XTXRN 5<<1 /* indexes last row/column when right shifted */ ! 11: ! 12: /* ! 13: * table for + ! 14: */ ! 15: readonly char pltab[6][6] = { ! 16: /* UND ABS TXT DAT BSS EXT */ ! 17: ! 18: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, ! 19: /*ABS*/ XUNDEF, XABS, XTEXT, XDATA, XBSS, XXTRN, ! 20: /*TXT*/ XUNDEF, XTEXT, ERR, ERR, ERR, ERR, ! 21: /*DAT*/ XUNDEF, XDATA, ERR, ERR, ERR, ERR, ! 22: /*BSS*/ XUNDEF, XBSS, ERR, ERR, ERR, ERR, ! 23: /*EXT*/ XUNDEF, XXTRN, ERR, ERR, ERR, ERR, ! 24: }; ! 25: ! 26: /* ! 27: * table for - ! 28: */ ! 29: readonly char mintab[6][6] = { ! 30: /* UND ABS TXT DAT BSS EXT */ ! 31: ! 32: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, ! 33: /*ABS*/ XUNDEF, XABS, ERR, ERR, ERR, ERR, ! 34: /*TXT*/ XUNDEF, XTEXT, XABS, ERR, ERR, ERR, ! 35: /*DAT*/ XUNDEF, XDATA, ERR, XABS, ERR, ERR, ! 36: /*BSS*/ XUNDEF, XBSS, ERR, ERR, XABS, ERR, ! 37: /*EXT*/ XUNDEF, XXTRN, ERR, ERR, ERR, ERR, ! 38: }; ! 39: ! 40: /* ! 41: * table for other operators ! 42: */ ! 43: readonly char othtab[6][6] = { ! 44: /* UND ABS TXT DAT BSS EXT */ ! 45: ! 46: /*UND*/ XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, XUNDEF, ! 47: /*ABS*/ XUNDEF, XABS, ERR, ERR, ERR, ERR, ! 48: /*TXT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR, ! 49: /*DAT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR, ! 50: /*BSS*/ XUNDEF, ERR, ERR, ERR, ERR, ERR, ! 51: /*EXT*/ XUNDEF, ERR, ERR, ERR, ERR, ERR, ! 52: }; ! 53: ! 54: struct exp * ! 55: combine(op, exp1, exp2) ! 56: register struct exp *exp1, *exp2; ! 57: { ! 58: register e1_type, e2_type; ! 59: register back_type; ! 60: ! 61: lastnam=0; /* kludge for jxxx instructions */ ! 62: ! 63: e1_type = exp1->e_xtype&XTYPE; ! 64: e2_type = exp2->e_xtype&XTYPE; ! 65: ! 66: if (exp1->e_xtype==XXTRN+XUNDEF) ! 67: e1_type = XTXRN; ! 68: if (exp2->e_xtype==XXTRN+XUNDEF) ! 69: e2_type = XTXRN; ! 70: if (passno==1) ! 71: if (exp1->e_xloc!=exp2->e_xloc && e1_type==e2_type) ! 72: e1_type = e2_type = XTXRN; /* error on != loc ctrs */ ! 73: e1_type >>= 1; /*dispose of the external (XXTRN) bit*/ ! 74: e2_type >>= 1; ! 75: ! 76: switch (op) { ! 77: case PLUS: ! 78: exp1->e_xvalue += exp2->e_xvalue; ! 79: back_type = pltab[e1_type][e2_type]; ! 80: break; ! 81: case MINUS: ! 82: exp1->e_xvalue -= exp2->e_xvalue; ! 83: back_type = mintab[e1_type][e2_type]; ! 84: break; ! 85: case IOR: ! 86: exp1->e_xvalue |= exp2->e_xvalue; ! 87: goto comm; ! 88: case XOR: ! 89: exp1->e_xvalue ^= exp2->e_xvalue; ! 90: goto comm; ! 91: case AND: ! 92: exp1->e_xvalue &= exp2->e_xvalue; ! 93: goto comm; ! 94: case ORNOT: ! 95: exp1->e_xvalue |= ~exp2->e_xvalue; ! 96: goto comm; ! 97: case LSH: ! 98: exp1->e_xvalue <<= exp2->e_xvalue; ! 99: goto comm; ! 100: case RSH: ! 101: exp1->e_xvalue >>= exp2->e_xvalue; ! 102: goto comm; ! 103: case TILDE: ! 104: exp1->e_xvalue |= ~ exp2->e_xvalue; ! 105: goto comm; ! 106: case MUL: ! 107: exp1->e_xvalue *= exp2->e_xvalue; ! 108: goto comm; ! 109: case DIV: ! 110: if (exp2->e_xvalue == 0) ! 111: yyerror("Divide check"); ! 112: else ! 113: exp1->e_xvalue /= exp2->e_xvalue; ! 114: goto comm; ! 115: case REGOP: ! 116: if (exp2->e_xvalue == 0) ! 117: yyerror("Divide check (modulo)"); ! 118: else ! 119: exp1->e_xvalue %= exp2->e_xvalue; ! 120: goto comm; ! 121: ! 122: comm: ! 123: back_type = othtab[e1_type][e2_type]; ! 124: break; ! 125: default: ! 126: yyerror("Internal error: unknown operator"); ! 127: } ! 128: ! 129: if (e2_type==(XTXRN>>1)) ! 130: exp1->e_xname = exp2->e_xname; ! 131: exp1->e_xtype = back_type | ( ! 132: (exp1->e_xtype|exp2->e_xtype) & (XFORW|XXTRN) ); ! 133: if (back_type==ERR) ! 134: yyerror("Relocation error"); ! 135: return(exp1); ! 136: } ! 137: ! 138: buildtokensets() ! 139: { ! 140: #define clobber(val, set) tokensets[(val)] |= (set) ! 141: ! 142: clobber(SEMI, LINSTBEGIN); ! 143: clobber(NL, LINSTBEGIN); ! 144: clobber(INT, LINSTBEGIN); ! 145: ! 146: clobber(NAME, YUKKYEXPRBEG + LINSTBEGIN); ! 147: clobber(INSTn, YUKKYEXPRBEG); ! 148: clobber(INST0, YUKKYEXPRBEG); ! 149: clobber(REG, YUKKYEXPRBEG); ! 150: clobber(BFINT, YUKKYEXPRBEG); ! 151: ! 152: clobber(INT, SAFEEXPRBEG); ! 153: clobber(FLTNUM, SAFEEXPRBEG); ! 154: ! 155: clobber(PLUS, ADDOPS); ! 156: clobber(MINUS, ADDOPS + EBEGOPS); ! 157: ! 158: clobber(LP, EBEGOPS); ! 159: ! 160: clobber(IOR, BOOLOPS); ! 161: clobber(XOR, BOOLOPS); ! 162: clobber(AND, BOOLOPS); ! 163: clobber(ORNOT, BOOLOPS); ! 164: ! 165: clobber(TILDE, MULOPS + EBEGOPS); ! 166: clobber(LSH, MULOPS); ! 167: clobber(RSH, MULOPS); ! 168: clobber(MUL, MULOPS); ! 169: clobber(DIV, MULOPS); ! 170: clobber(REGOP, MULOPS); /* % */ ! 171: ! 172: } ! 173: ! 174: /* ! 175: * We keep the current token class in this global variable, so ! 176: * the recursive descent expression analyzers can talk amongst ! 177: * themselves, and so that we may use the macros shift and shift over ! 178: */ ! 179: ! 180: extern int yylval; /*the value of the lexical value*/ ! 181: extern struct exp *xp; /*the next free expression slot*/ ! 182: ! 183: static int val; ! 184: int exprparse(inval, backexpr) /*return the value the read head is sitting on*/ ! 185: int inval; ! 186: struct exp **backexpr; ! 187: { ! 188: register struct exp *lexpr; ! 189: int op; ! 190: ! 191: val = inval; ! 192: lexpr = boolterm(); ! 193: while (INTOKSET(val, ADDOPS)){ ! 194: op = val; ! 195: shift; ! 196: lexpr = combine(op, lexpr, boolterm()); ! 197: } ! 198: *backexpr = lexpr; ! 199: return(val); ! 200: } ! 201: ! 202: struct exp *boolterm() ! 203: { ! 204: register struct exp *lexpr; ! 205: int op; ! 206: ! 207: lexpr = term(); ! 208: while(INTOKSET(val, BOOLOPS)){ ! 209: op = val; ! 210: shift; ! 211: lexpr = combine(op, lexpr, term()); ! 212: } ! 213: return(lexpr); ! 214: } ! 215: ! 216: struct exp *term() ! 217: { ! 218: register struct exp *lexpr; ! 219: int op; ! 220: ! 221: lexpr = factor(); ! 222: while(INTOKSET(val, MULOPS)){ ! 223: op = val; ! 224: shift; ! 225: lexpr = combine(op, lexpr, factor()); ! 226: } ! 227: return(lexpr); ! 228: } ! 229: ! 230: struct exp *factor() ! 231: { ! 232: struct exp *lexpr; ! 233: int op; ! 234: extern int droppedLP; /*called exprparse after consuming an LP*/ ! 235: ! 236: if (val == LP || droppedLP){ ! 237: if (droppedLP) ! 238: droppedLP = 0; ! 239: else ! 240: shift; /*the LP*/ ! 241: val = exprparse(val, &lexpr); ! 242: if (val != RP) ! 243: yyerror("right parenthesis expected"); ! 244: else ! 245: shift; ! 246: } else ! 247: if (INTOKSET(val, YUKKYEXPRBEG)){ ! 248: lexpr = yukkyexpr(val, yylval); ! 249: shift; ! 250: } ! 251: else if (INTOKSET(val, SAFEEXPRBEG)){ ! 252: lexpr = (struct exp *)yylval; ! 253: shift; ! 254: } ! 255: else if ( (val == TILDE) || (val == MINUS) ){ ! 256: op = val; ! 257: shift; ! 258: lexpr = xp++; ! 259: lexpr->e_xtype = XABS; ! 260: lexpr->e_xvalue = 0; ! 261: lexpr = combine(op, lexpr, factor()); ! 262: } ! 263: else { ! 264: yyerror("Bad expression syntax"); ! 265: lexpr = xp++; ! 266: lexpr->e_xtype = XABS; ! 267: lexpr->e_xvalue = 0; ! 268: } ! 269: return(lexpr); ! 270: } ! 271: ! 272: struct exp *yukkyexpr(val, np) ! 273: int val; ! 274: register np; ! 275: { ! 276: register struct exp *locxp; ! 277: extern int exprisname; /*last factor is a name*/ ! 278: ! 279: exprisname = 0; ! 280: locxp = xp++; ! 281: if (val == NAME || val == BFINT){ ! 282: if (val == BFINT) { ! 283: int off = 0; ! 284: yylval = ((struct exp *)np)->e_xvalue; ! 285: if (yylval < 0) { ! 286: yylval = -yylval; ! 287: yylval--; ! 288: off = -1; ! 289: if (lgensym[yylval] == 1) ! 290: yyerror("Reference to undefined local label %db", yylval); ! 291: } else { ! 292: yylval--; ! 293: genref[yylval] = 1; ! 294: } ! 295: sprintf(yytext, "L%d\001%d", yylval, lgensym[yylval] + off); ! 296: yylval = np = (int)*lookup(passno == 1); ! 297: lastnam = (struct symtab *)np; ! 298: } ! 299: exprisname++; ! 300: locxp->e_xtype = ((struct symtab *)np)->s_type; ! 301: if (( ((struct symtab *)np)->s_type&XTYPE)==XUNDEF) { /*forward*/ ! 302: locxp->e_xname = (struct symtab *)np; ! 303: locxp->e_xvalue = 0; ! 304: if (passno==1) ! 305: ((struct symtab *)np)->s_type |= XFORW; ! 306: } else { /*otherwise, just get the value*/ ! 307: locxp->e_xvalue = ((struct symtab *)np)->s_value; ! 308: locxp->e_xname = NULL; ! 309: } ! 310: } else { /*INSTn or INST0 or REG*/ ! 311: locxp->e_xtype = XABS; ! 312: locxp->e_xvalue = ( (int)np) & 0xFF; ! 313: locxp->e_xloc = 0; ! 314: locxp->e_xname = NULL; ! 315: } ! 316: ! 317: return(locxp); ! 318: } ! 319: ! 320: ! 321: #ifdef DEBUG ! 322: char *tok_name[LASTTOKEN - FIRSTTOKEN + 1]; ! 323: struct Tok_Desc{ ! 324: int tok_which; ! 325: char *tok_name; ! 326: } tok_desc[] = { ! 327: FIRSTTOKEN, "firsttoken", /* 0 */ ! 328: ISPACE, "ispace", /* 1 */ ! 329: IBYTE, "ibyte", /* 2 */ ! 330: IWORD, "iword", /* 3 */ ! 331: IINT, "iint", /* 4 */ ! 332: ILONG, "ilong", /* 5 */ ! 333: IDATA, "idata", /* 6 */ ! 334: IGLOBAL, "iglobal", /* 7 */ ! 335: ISET, "iset", /* 8 */ ! 336: ITEXT, "itext", /* 9 */ ! 337: ICOMM, "icomm", /* 10 */ ! 338: ILCOMM, "ilcomm", /* 11 */ ! 339: IFLOAT, "ifloat", /* 12 */ ! 340: IDOUBLE, "idouble", /* 13 */ ! 341: IORG, "iorg", /* 14 */ ! 342: IASCII, "iascii", /* 15 */ ! 343: IASCIZ, "iasciz", /* 16 */ ! 344: ILSYM, "ilsym", /* 17 */ ! 345: IFILE, "ifile", /* 18 */ ! 346: ILINENO, "ilineno", /* 19 */ ! 347: IABORT, "iabort", /* 20 */ ! 348: ISTAB, "istab", /* 23 */ ! 349: ISTABSTR, "istabstr", /* 24 */ ! 350: ISTABNONE, "istabnone", /* 25 */ ! 351: ISTABDOT, "istabdot", /* 26 */ ! 352: IJXXX, "ijxxx", /* 27 */ ! 353: IALIGN, "ialign", /* 28 */ ! 354: INST0, "inst0", /* 29 */ ! 355: INSTn, "instn", /* 30 */ ! 356: BFINT, "bfint", /* 31 */ ! 357: PARSEEOF, "parseeof", /* 32 */ ! 358: ILINESKIP, "ilineskip", /* 33 */ ! 359: VOID, "void", /* 34 */ ! 360: SKIP, "skip", /* 35 */ ! 361: INT, "int", /* 36 */ ! 362: FLTNUM, "fltnum", /* 37 */ ! 363: NAME, "name", /* 38 */ ! 364: STRING, "string", /* 39 */ ! 365: QUAD, "quad", /* 40 */ ! 366: SIZESPEC, "sizespec", /* 41 */ ! 367: REG, "reg", /* 42 */ ! 368: MUL, "mul", /* 43 */ ! 369: LITOP, "litop", /* 44 */ ! 370: LP, "lp", /* 45 */ ! 371: MP, "mp", /* 46 */ ! 372: NEEDSBUF, "needsbuf", /* 48 */ ! 373: REGOP, "regop", /* 49 */ ! 374: NL, "nl", /* 50 */ ! 375: SCANEOF, "scaneof", /* 51 */ ! 376: BADCHAR, "badchar", /* 52 */ ! 377: SP, "sp", /* 53 */ ! 378: ALPH, "alph", /* 54 */ ! 379: DIG, "dig", /* 55 */ ! 380: SQ, "sq", /* 56 */ ! 381: DQ, "dq", /* 57 */ ! 382: SH, "sh", /* 58 */ ! 383: LSH, "lsh", /* 59 */ ! 384: RSH, "rsh", /* 60 */ ! 385: MINUS, "minus", /* 61 */ ! 386: SIZEQUOTE, "sizequote", /* 62 */ ! 387: XOR, "xor", /* 64 */ ! 388: DIV, "div", /* 65 */ ! 389: SEMI, "semi", /* 66 */ ! 390: COLON, "colon", /* 67 */ ! 391: PLUS, "plus", /* 68 */ ! 392: IOR, "ior", /* 69 */ ! 393: AND, "and", /* 70 */ ! 394: TILDE, "tilde", /* 71 */ ! 395: ORNOT, "ornot", /* 72 */ ! 396: CM, "cm", /* 73 */ ! 397: LB, "lb", /* 74 */ ! 398: RB, "rb", /* 75 */ ! 399: RP, "rp", /* 76 */ ! 400: LASTTOKEN, "lasttoken" /* 80 */ ! 401: }; ! 402: /* ! 403: * turn a token type into a string ! 404: */ ! 405: static int fixed = 0; ! 406: char *tok_to_name(token) ! 407: { ! 408: if (!fixed){ ! 409: int i; ! 410: for (i = FIRSTTOKEN; i <= LASTTOKEN; i++) ! 411: tok_name[i] = "NOT ASSIGNED"; ! 412: for (i = FIRSTTOKEN; i <= sizeof(tok_desc)/sizeof(struct Tok_Desc); i++){ ! 413: tok_name[tok_desc[i].tok_which] = tok_desc[i].tok_name; ! 414: } ! 415: fixed = 1; ! 416: } ! 417: if (FIRSTTOKEN <= token && token <= LASTTOKEN) ! 418: return(tok_name[token]); ! 419: else ! 420: panic("Unknown token number, %d\n", token); ! 421: /*NOTREACHED*/ ! 422: } ! 423: #endif DEBUG
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.