2 static char rcsid[] = "$Id: compute.c,v 0.16 1994/06/24 13:27:05 ceriel Exp $";
19 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
20 * See the copyright notice in the ACK home directory, in the file "Copyright".
22 * Author: Hans van Staveren
29 #define LLDEF LLEAF|LDEF
30 #define RLDEF RLEAF|RDEF
37 LLDEF|RLDEF, /* EX_SAMESIGN */
38 LLDEF|RLDEF, /* EX_SFIT */
39 LLDEF|RLDEF, /* EX_UFIT */
41 LLDEF|RLDEF, /* EX_NCPEQ */
42 LLDEF|RLDEF, /* EX_SCPEQ */
43 LLDEF|RLDEF, /* EX_RCPEQ */
44 LLDEF|RLDEF, /* EX_NCPNE */
45 LLDEF|RLDEF, /* EX_SCPNE */
46 LLDEF|RLDEF, /* EX_RCPNE */
47 LLDEF|RLDEF, /* EX_NCPGT */
48 LLDEF|RLDEF, /* EX_NCPGE */
49 LLDEF|RLDEF, /* EX_NCPLT */
50 LLDEF|RLDEF, /* EX_NCPLE */
53 LLDEF|RLDEF, /* EX_PLUS */
54 LLDEF|RLDEF, /* EX_CAT */
55 LLDEF|RLDEF, /* EX_MINUS */
56 LLDEF|RLDEF, /* EX_TIMES */
57 LLDEF|RLDEF, /* EX_DIVIDE */
58 LLDEF|RLDEF, /* EX_MOD */
59 LLDEF|RLDEF, /* EX_LSHIFT */
60 LLDEF|RLDEF, /* EX_RSHIFT */
65 LLEAF, /* EX_DEFINED */
67 LLDEF, /* EX_TOSTRING */
68 LLDEF, /* EX_UMINUS */
73 LLDEF, /* EX_REGVAR */
74 LLDEF|RLDEF, /* EX_OR */
75 LLDEF|RLDEF, /* EX_XOR */
76 LLDEF|RLDEF, /* EX_AND */
79 0, /* EX_TOPELTSIZE */
80 0, /* EX_FALLTHROUGH */
84 string salloc(),strcpy(),strcat();
86 string mycat(s1,s2) register string s1,s2; {
89 if (s1==0 || *s1=='\0') return(s2);
90 if (s2==0 || *s2=='\0') return(s1);
91 s=salloc(strlen(s1)+strlen(s2)+1);
98 string mystrcpy(s) register string s; {
108 string tostring(n) register word n; {
111 if (n>=-20 && n<=20 && (n&1)==0) {
112 if (digstr[((int)n>>1)+10][0]==0)
113 sprintf(digstr[((int)n>>1)+10],WRD_FMT,n);
114 return(digstr[((int)n>>1)+10]);
116 sprintf(buf,WRD_FMT,n);
117 return(mystrcpy(buf));
120 compute(node, presult) register node_p node; register result_t *presult; {
121 result_t leaf1,leaf2;
128 presult->e_typ = EV_UNDEF;
129 desc=opdesc[node->ex_operator];
131 compute(&enodes[node->ex_lnode], &leaf1);
132 if (desc&LDEF && leaf1.e_typ==EV_UNDEF)
136 compute(&enodes[node->ex_rnode], &leaf2);
137 if (desc&RDEF && leaf2.e_typ==EV_UNDEF)
140 presult->e_typ=EV_INT;
141 switch(node->ex_operator) {
142 default: assert(FALSE);
144 if (node->ex_lnode==0)
145 if (curtoken) tp = curtoken;
146 else tp = &fakestack[stackheight-1];
147 else tp = &fakestack[stackheight-node->ex_lnode];
148 switch(presult->e_typ = tokens[tp->t_token].t_type[node->ex_rnode-1]) {
152 presult->e_v.e_con = tp->t_att[node->ex_rnode-1].aw;
155 presult->e_v.e_addr = tp->t_att[node->ex_rnode-1].aa;
158 presult->e_v.e_reg = tp->t_att[node->ex_rnode-1].ar;
163 *presult = dollar[node->ex_lnode-1];
166 presult->e_typ = EV_INT;
167 presult->e_v.e_con = ((long) node->ex_rnode << 16) | ((long)node->ex_lnode&0xffff);
170 presult->e_typ = EV_REG;
171 presult->e_v.e_reg = node->ex_lnode;
174 presult->e_typ = EV_REG;
175 presult->e_v.e_reg = allreg[node->ex_lnode-1];
177 if (node->ex_rnode!=0)
178 presult->e_v.e_reg = machregs[presult->e_v.e_reg].
179 r_members[node->ex_rnode-1];
183 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
184 presult->e_typ = EV_INT;
185 if (leaf1.e_v.e_con>=0)
186 presult->e_v.e_con= leaf2.e_v.e_con>=0;
188 presult->e_v.e_con= leaf2.e_v.e_con<0;
191 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
193 for (i=0;i<leaf2.e_v.e_con-1;i++)
195 tmp = leaf1.e_v.e_con&mask;
196 presult->e_v.e_con = tmp==0||tmp==mask;
199 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
201 for (i=0;i<leaf2.e_v.e_con;i++)
203 presult->e_v.e_con = (leaf1.e_v.e_con&mask)==0;
206 assert(node->ex_rnode>=0 &&node->ex_rnode<MAXROM);
207 leaf2=dollar[node->ex_lnode];
208 presult->e_typ = EV_UNDEF;
209 if (leaf2.e_typ != EV_ADDR)
211 if (leaf2.e_v.e_addr.ea_off!=0)
213 gp = lookglo(leaf2.e_v.e_addr.ea_str);
214 if (gp == (glosym_p) 0)
216 if ((gp->gl_rom[MAXROM]&(1<<node->ex_rnode))==0)
218 presult->e_typ = EV_INT;
219 presult->e_v.e_con = gp->gl_rom[node->ex_rnode];
222 leaf2=dollar[node->ex_lnode];
223 if (leaf2.e_typ != EV_ADDR)
224 presult->e_v.e_con = 0;
226 presult->e_v.e_con = lookglo(leaf2.e_v.e_addr.ea_str) != 0;
229 presult->e_v.e_con = saveemp[node->ex_lnode].em_u.em_loper&0xFFFF;
232 presult->e_v.e_con = saveemp[node->ex_lnode].em_u.em_loper>>16;
235 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
236 presult->e_v.e_con = leaf1.e_v.e_con==leaf2.e_v.e_con;
239 assert(leaf1.e_typ == EV_ADDR && leaf2.e_typ == EV_ADDR);
241 (strcmp(leaf1.e_v.e_addr.ea_str,leaf2.e_v.e_addr.ea_str)==0 &&
242 leaf1.e_v.e_addr.ea_off==leaf2.e_v.e_addr.ea_off);
245 assert(leaf1.e_typ == EV_REG && leaf2.e_typ == EV_REG);
246 presult->e_v.e_con = leaf1.e_v.e_reg==leaf2.e_v.e_reg;
249 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
250 presult->e_v.e_con = leaf1.e_v.e_con!=leaf2.e_v.e_con;
253 assert(leaf1.e_typ == EV_ADDR && leaf2.e_typ == EV_ADDR);
255 !(strcmp(leaf1.e_v.e_addr.ea_str,leaf2.e_v.e_addr.ea_str)==0 &&
256 leaf1.e_v.e_addr.ea_off==leaf2.e_v.e_addr.ea_off);
259 assert(leaf1.e_typ == EV_REG && leaf2.e_typ == EV_REG);
260 presult->e_v.e_con = leaf1.e_v.e_reg!=leaf2.e_v.e_reg;
263 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
264 presult->e_v.e_con = leaf1.e_v.e_con>leaf2.e_v.e_con;
267 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
268 presult->e_v.e_con = leaf1.e_v.e_con>=leaf2.e_v.e_con;
271 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
272 presult->e_v.e_con = leaf1.e_v.e_con<leaf2.e_v.e_con;
275 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
276 presult->e_v.e_con = leaf1.e_v.e_con<=leaf2.e_v.e_con;
279 assert(leaf1.e_typ == EV_INT);
280 if (leaf1.e_v.e_con==0) {
281 compute(&enodes[node->ex_rnode], presult);
283 else *presult = leaf1;
286 assert(leaf1.e_typ == EV_INT);
287 if (leaf1.e_v.e_con!=0) {
288 compute(&enodes[node->ex_rnode], presult);
290 else *presult = leaf1;
293 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
294 presult->e_v.e_con=leaf1.e_v.e_con+leaf2.e_v.e_con;
297 assert(leaf1.e_typ == EV_ADDR && leaf2.e_typ == EV_ADDR);
298 presult->e_typ = EV_ADDR;
299 presult->e_v.e_addr.ea_str = mycat(leaf1.e_v.e_addr.ea_str,leaf2.e_v.e_addr.ea_str);
300 presult->e_v.e_addr.ea_off = leaf1.e_v.e_addr.ea_off+leaf2.e_v.e_addr.ea_off;
303 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
304 presult->e_v.e_con = leaf1.e_v.e_con - leaf2.e_v.e_con;
307 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
308 presult->e_v.e_con = leaf1.e_v.e_con | leaf2.e_v.e_con;
311 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
312 presult->e_v.e_con = leaf1.e_v.e_con ^ leaf2.e_v.e_con;
315 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
316 presult->e_v.e_con = leaf1.e_v.e_con & leaf2.e_v.e_con;
319 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
320 presult->e_v.e_con = leaf1.e_v.e_con * leaf2.e_v.e_con;
323 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
324 presult->e_v.e_con = leaf1.e_v.e_con / leaf2.e_v.e_con;
327 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
328 presult->e_v.e_con = leaf1.e_v.e_con % leaf2.e_v.e_con;
331 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
332 presult->e_v.e_con = leaf1.e_v.e_con << leaf2.e_v.e_con;
335 assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT);
336 presult->e_v.e_con = leaf1.e_v.e_con >> leaf2.e_v.e_con;
339 assert(leaf1.e_typ == EV_INT);
340 presult->e_v.e_con = !leaf1.e_v.e_con;
343 assert(leaf1.e_typ == EV_INT);
344 presult->e_v.e_con = ~leaf1.e_v.e_con;
347 presult->e_typ = EV_ADDR;
348 presult->e_v.e_addr.ea_str = codestrings[node->ex_lnode];
349 presult->e_v.e_addr.ea_off = 0;
352 presult->e_v.e_con=leaf1.e_typ!=EV_UNDEF;
355 presult->e_typ = EV_REG;
356 if (node->ex_lnode==0)
357 if (curtoken) tp = curtoken;
358 else tp = &fakestack[stackheight-1];
359 else tp = &fakestack[stackheight-node->ex_lnode];
360 assert(tp->t_token == -1);
361 tmpreg= tp->t_att[0].ar;
364 tmpreg=machregs[tmpreg].r_members[node->ex_rnode-1];
366 presult->e_v.e_reg=tmpreg;
369 assert(leaf1.e_typ == EV_INT);
370 presult->e_typ = EV_ADDR;
371 presult->e_v.e_addr.ea_str = "";
372 presult->e_v.e_addr.ea_off = leaf1.e_v.e_con;
376 assert(leaf1.e_typ == EV_INT);
377 presult->e_v.e_con = isregtyp((long) leaf1.e_v.e_con);
380 assert(leaf1.e_typ == EV_INT);
381 i = isregvar((long) leaf1.e_v.e_con);
383 presult->e_typ = EV_UNDEF;
386 presult->e_typ = EV_REG;
387 presult->e_v.e_reg=i;
391 assert(leaf1.e_typ == EV_INT);
392 presult->e_v.e_con = -leaf1.e_v.e_con;
395 case EX_TOPELTSIZE: /* Hans, new */
396 { register label_p lbl;
398 lbl = get_label(saveemp[node->ex_lnode].em_u.em_ioper);
399 if (lbl != (label_p)0) {
400 presult->e_v.e_con = lbl->lb_height;
402 presult->e_v.e_con = 0;
406 case EX_FALLTHROUGH: /* Hans, new */
407 { register label_p lbl;
409 lbl = get_label(saveemp[node->ex_lnode].em_u.em_ioper);
410 if (lbl != (label_p)0) {
411 presult->e_v.e_con = lbl->lb_fallthrough;
412 } else presult->e_v.e_con = 0;