|
|
1.1 ! root 1: #include "asm.h" ! 2: ! 3: expr(esp, n) ! 4: register struct expr *esp; ! 5: { ! 6: register c, p; ! 7: address lv, rv; ! 8: int lt, rt; ! 9: struct expr re; ! 10: ! 11: term(esp); ! 12: for (;;) { ! 13: c = getnb(); ! 14: if (ctype[c] != BINOP) ! 15: break; ! 16: if (c == '|') ! 17: p = 10; ! 18: else if (c == '*') ! 19: p = 9; ! 20: else ! 21: p = 8; ! 22: if (p <= n) ! 23: break; ! 24: expr(&re, p); ! 25: lt = esp->e_type; ! 26: lv = esp->e_addr; ! 27: rt = re.e_type; ! 28: rv = re.e_addr; ! 29: if (c == '|') { ! 30: if (rt != E_ACON) ! 31: aerr("non constant in segment construction"); ! 32: switch (lt) { ! 33: case E_ACON: ! 34: esp->e_type = E_ASEG; ! 35: esp->e_base.e_segn = lv; ! 36: break; ! 37: ! 38: case E_SYM: ! 39: esp->e_type = E_SEG; ! 40: break; ! 41: ! 42: default: ! 43: aerr("bad segment construction"); ! 44: } ! 45: esp->e_addr = rv; ! 46: continue; ! 47: } ! 48: if (c == '^') { ! 49: if ((esp->e_type = rt) == E_DIR) ! 50: esp->e_base.e_lp = re.e_base.e_lp; ! 51: else if (rt==E_SYM || rt==E_SEG) ! 52: esp->e_base.e_sp = re.e_base.e_sp; ! 53: else if (rt == E_ASEG) ! 54: esp->e_base.e_segn = re.e_base.e_segn; ! 55: continue; ! 56: } ! 57: if (c == '+') { ! 58: if (lt == E_ACON) { ! 59: esp->e_type = rt; ! 60: if (rt == E_ASEG) ! 61: esp->e_base.e_segn = re.e_base.e_segn; ! 62: else if (rt == E_DIR) ! 63: esp->e_base.e_lp = re.e_base.e_lp; ! 64: else if (rt==E_SYM || rt==E_SEG) ! 65: esp->e_base.e_sp = re.e_base.e_sp; ! 66: } else if (rt != E_ACON) ! 67: rerr("add of 2 non constants"); ! 68: esp->e_addr += rv; ! 69: continue; ! 70: } ! 71: if (c == '-') { ! 72: if (lt == E_ACON) { ! 73: if (rt != E_ACON) ! 74: rerr("constant - non-constant"); ! 75: } else if (rt != E_ACON) { ! 76: if (lt!=E_DIR || rt!=E_DIR || ! 77: esp->e_base.e_lp!=re.e_base.e_lp) ! 78: rerr("cannot fold this expression"); ! 79: esp->e_type = E_ACON; ! 80: } ! 81: esp->e_addr -= rv; ! 82: continue; ! 83: } ! 84: if (c == '*') { ! 85: if (lt!=E_ACON || rt!=E_ACON) ! 86: aerr("non-constant in multiply"); ! 87: esp->e_addr *= rv; ! 88: continue; ! 89: } ! 90: fprintf(stderr, "Internal error, c=%d in expr.\n", c); ! 91: exit( 1); ! 92: } ! 93: unget(c); ! 94: } ! 95: ! 96: address ! 97: absexpr() ! 98: { ! 99: struct expr e; ! 100: ! 101: expr(&e, 0); ! 102: abscheck(&e); ! 103: return (e.e_addr); ! 104: } ! 105: ! 106: term(esp) ! 107: register struct expr *esp; ! 108: { ! 109: register c; ! 110: address n; ! 111: char id[NCPLN]; ! 112: struct sym *sp; ! 113: struct tsym *tp; ! 114: int r, v; ! 115: ! 116: if ((c=getnb()) == '[') { ! 117: expr(esp, 0); ! 118: if (getnb() != ']') ! 119: qerr("missing ']'"); ! 120: return; ! 121: } ! 122: if (c == '-') { ! 123: expr(esp, 100); ! 124: abscheck(esp); ! 125: esp->e_addr = -esp->e_addr; ! 126: return; ! 127: } ! 128: if (c == '~') { ! 129: expr(esp, 100); ! 130: abscheck(esp); ! 131: esp->e_addr = ~esp->e_addr; ! 132: return; ! 133: } ! 134: if (c == '\'') { ! 135: esp->e_type = E_ACON; ! 136: esp->e_addr = getmap(-1); ! 137: return; ! 138: } ! 139: esp->e_type = E_ACON; ! 140: esp->e_addr = 0; ! 141: if (ctype[c] == DIGIT) { ! 142: r = 10; ! 143: if (c == '0') { ! 144: r = 8; ! 145: if ((c = *ip) != 0) ! 146: ++ip; ! 147: if (c == 'x') { ! 148: r = 16; ! 149: if ((c = *ip) != 0) ! 150: ++ip; ! 151: } ! 152: } ! 153: n = 0; ! 154: while ((v=digit(c, r)) >= 0) { ! 155: n = r*n + v; ! 156: if ((c = *ip) != 0) ! 157: ++ip; ! 158: } ! 159: if (c=='f' || c=='b') { ! 160: if (n < 10) { ! 161: if (c == 'f') ! 162: tp = tsymp[n].tp_fp; else ! 163: tp = tsymp[n].tp_bp; ! 164: if (tp != NULL) { ! 165: esp->e_type = E_DIR; ! 166: esp->e_base.e_lp = tp->t_lp; ! 167: esp->e_addr = tp->t_addr; ! 168: return; ! 169: } ! 170: } ! 171: err('u', "undefined local symbol"); ! 172: return; ! 173: } ! 174: if (c != 0) ! 175: --ip; ! 176: esp->e_addr = n; ! 177: return; ! 178: } ! 179: if (ctype[c] == LETTER) { ! 180: getid(id, c); ! 181: if ((sp=lookup(id, gflag)) != NULL) { ! 182: if (sp->s_kind == S_NEW) { ! 183: if ((sp->s_flag&S_GBL) != 0) { ! 184: esp->e_type = E_SYM; ! 185: esp->e_base.e_sp = sp; ! 186: return; ! 187: } ! 188: uerr(id); ! 189: return; ! 190: } ! 191: esp->e_type = sp->s_type; ! 192: esp->e_addr = sp->s_addr; ! 193: if (sp->s_type == E_ASEG) ! 194: esp->e_base.e_segn = sp->s_base.s_segn; ! 195: else if (sp->s_type == E_DIR) ! 196: esp->e_base.e_lp = sp->s_base.s_lp; ! 197: else if (sp->s_type==E_SYM || sp->s_type==E_SEG) ! 198: esp->e_base.e_sp = sp->s_base.s_sp; ! 199: return; ! 200: } ! 201: uerr(id); ! 202: return; ! 203: } ! 204: qerr("invalid symbol"); ! 205: } ! 206: ! 207: /* ! 208: * Look for an optional floating point register specification ! 209: * and store an appropriate e_mode value through ep. ! 210: * No operand: store ST and return 0. ! 211: * One operand: store reg and return 1. ! 212: */ ! 213: fp_reg(ep) ! 214: register struct expr *ep; ! 215: { ! 216: register c; ! 217: char id[NCPLN]; ! 218: struct sym *sp; ! 219: ! 220: ep->e_mode = ST; ! 221: if (ctype[c=getnb()] == LETTER) { ! 222: getid(id, c); ! 223: if ((sp=lookup(id, 0)) != NULL) { ! 224: if ((sp->s_addr&MMASK) != ST) { ! 225: qerr("invalid floating-point register"); ! 226: return(0); ! 227: } ! 228: ep->e_mode = sp->s_addr; ! 229: return(1); ! 230: } ! 231: uerr(id); ! 232: return(0); ! 233: } ! 234: unget(c); ! 235: return(0); ! 236: } ! 237: ! 238: /* ! 239: * Look for one or two optional floating point register operands ! 240: * and store appropriate e_mode values through ep1, ep2. ! 241: * Return a flag indicating whether any operands were supplied. ! 242: * No operand: store ST1, ST, return 0. ! 243: * One operand: store reg1, ST, return 1. ! 244: * Two operands: store reg1, reg2, return 1; at least one must be ST. ! 245: */ ! 246: fp_reg2(ep1, ep2) ! 247: register struct expr *ep1, *ep2; ! 248: { ! 249: register int c; ! 250: ! 251: ep2->e_mode = ST; ! 252: if (fp_reg(ep1)) { ! 253: if ((c = getnb()) == ',') { ! 254: if (!fp_reg(ep2) ! 255: || (ep1->e_mode != ST && ep2->e_mode != ST)) ! 256: qerr("invalid floating-point register"); ! 257: } ! 258: else ! 259: unget(c); ! 260: return(1); ! 261: } ! 262: else { ! 263: ep1->e_mode = ST1; ! 264: return(0); ! 265: } ! 266: } ! 267: ! 268: digit(c, r) ! 269: register c, r; ! 270: { ! 271: if (r == 16) { ! 272: if (c>='A' && c<='F') ! 273: return (c-'A'+10); ! 274: if (c>='a' && c<='f') ! 275: return (c-'a'+10); ! 276: } ! 277: if (c>='0' && c<='9') ! 278: return (c - '0'); ! 279: return (-1); ! 280: } ! 281: ! 282: abscheck(esp) ! 283: register struct expr *esp; ! 284: { ! 285: if (esp->e_type != E_ACON) { ! 286: rerr("expected constant"); ! 287: esp->e_type = E_ACON; ! 288: } ! 289: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.