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