Mercurial > hg > CbC > old > device
annotate mc-codegen.c @ 256:d80e6387c539
powerpc function call complex arugment pre computation.
(incomplete)
author | kono |
---|---|
date | Sat, 15 May 2004 12:04:56 +0900 |
parents | 8cd8d72286ae |
children | 22949117768f |
rev | line source |
---|---|
61 | 1 /* Micro-C Generic Code Generatation Part */ |
2 /* $Id$ */ | |
3 | |
4 #define EXTERN extern | |
5 #include "mc.h" | |
6 #include "mc-codegen.h" | |
7 #include "mc-code.h" | |
8 | |
83 | 9 int use; /* generated value will be used */ |
81 | 10 |
105 | 11 static void remove0(int *parent,int e) ; |
12 /* static void remove0_all(int *parent,int e) ; */ | |
13 static int is_same_type(int e1,int e2); | |
14 static void jump(int e1, int env); | |
15 static void machinop(int e1); | |
16 static void sassign(int e1); | |
17 static void assign(int e1); | |
18 static void assop(int e1); | |
19 static int g_expr0(int e1); | |
20 static int register_to_lvar(int e); | |
61 | 21 |
195 | 22 #if FLOAT_CODE |
23 | |
24 /* floating point */ | |
25 | |
26 static void dassop(int e1); | |
27 static void dmachinop(int e1,int d); | |
28 static void dassign(int e1); | |
29 | |
30 #endif | |
31 #if LONGLONG_CODE | |
32 static void lassop(int e1); | |
33 static void lmachinop(int e1); | |
34 static void lassign(int e1); | |
35 #endif | |
36 | |
37 | |
102 | 38 void |
39 codegen_init() | |
40 { | |
41 code_init(); | |
42 } | |
43 | |
137 | 44 void |
45 arg_register(NMTBL *fnptr) | |
46 { | |
47 code_arg_register(fnptr); | |
48 } | |
49 | |
94 | 50 int |
83 | 51 gexpr(int e1,int use0) |
61 | 52 { |
94 | 53 if (chk) return INT; |
61 | 54 gexpr_init(); |
83 | 55 use = use0; |
61 | 56 #if 0 |
57 if(lineno==2862) { | |
94 | 58 return g_expr0(e1); /*break here*/ |
61 | 59 } |
60 #endif | |
94 | 61 return g_expr0(e1); |
61 | 62 } |
63 | |
64 int | |
83 | 65 g_expr_u(int e1) |
66 { | |
94 | 67 int t; |
83 | 68 int suse = use; use=0; |
94 | 69 t=g_expr0(e1); |
147 | 70 code_gexpr(e1); |
71 | |
83 | 72 use=suse; |
94 | 73 return t; |
83 | 74 } |
75 | |
94 | 76 int |
61 | 77 g_expr(int e1) |
78 { | |
94 | 79 int t; |
83 | 80 int suse = use; use=1; |
94 | 81 t=g_expr0(e1); |
147 | 82 code_gexpr(e1); |
83 | |
83 | 84 use=suse; |
94 | 85 return t; |
83 | 86 } |
87 | |
94 | 88 int |
83 | 89 g_expr0(int e1) |
90 { | |
191 | 91 int e2,e3,t,d,t1; |
61 | 92 NMTBL *n; |
93 | |
147 | 94 code_gexpr(e1); |
95 | |
61 | 96 e2 = cadr(e1); |
97 switch (car(e1)){ | |
98 case GVAR: | |
221 | 99 code_gvar(e1,USE_CREG); |
94 | 100 return ADDRESS; |
61 | 101 case RGVAR: |
221 | 102 code_rgvar(e1,USE_CREG); |
94 | 103 return INT; |
61 | 104 case CRGVAR: |
221 | 105 code_crgvar(e1,USE_CREG,1,1); |
94 | 106 return CHAR; |
162 | 107 case CURGVAR: |
221 | 108 code_crgvar(e1,USE_CREG,0,1); |
165 | 109 return UCHAR; |
110 case SRGVAR: | |
221 | 111 code_crgvar(e1,USE_CREG,1,size_of_short); |
165 | 112 return CHAR; |
113 case SURGVAR: | |
221 | 114 code_crgvar(e1,USE_CREG,0,size_of_short); |
162 | 115 return UCHAR; |
61 | 116 case LVAR: |
221 | 117 code_lvar(e2,USE_CREG); |
94 | 118 return ADDRESS; |
61 | 119 case REGISTER: |
221 | 120 code_register(e2,USE_CREG); |
94 | 121 return INT; |
195 | 122 #if FLOAT_CODE |
94 | 123 case DREGISTER: |
221 | 124 code_dregister(e2,USE_CREG,1); |
94 | 125 return DOUBLE; |
137 | 126 case FREGISTER: |
221 | 127 code_dregister(e2,USE_CREG,0); |
137 | 128 return FLOAT; |
195 | 129 #endif |
219 | 130 #if LONGLONG_CODE |
131 case LREGISTER: | |
221 | 132 code_lregister(e2,USE_CREG); |
219 | 133 return LONGLONG; |
134 #endif | |
61 | 135 case RLVAR: |
221 | 136 code_rlvar(e2,USE_CREG); |
94 | 137 return INT; |
61 | 138 case CRLVAR: |
221 | 139 code_crlvar(e2,USE_CREG,1,1); |
94 | 140 return CHAR; |
162 | 141 case CURLVAR: |
221 | 142 code_crlvar(e2,USE_CREG,0,1); |
165 | 143 return UCHAR; |
144 case SRLVAR: | |
221 | 145 code_crlvar(e2,USE_CREG,1,size_of_short); |
165 | 146 return CHAR; |
147 case SURLVAR: | |
221 | 148 code_crlvar(e2,USE_CREG,0,size_of_short); |
162 | 149 return UCHAR; |
195 | 150 #if FLOAT_CODE |
81 | 151 case FRLVAR: |
221 | 152 code_drlvar(e2,0,USE_CREG); |
94 | 153 return FLOAT; |
81 | 154 case FRGVAR: |
221 | 155 code_drgvar(e1,0,USE_CREG); |
94 | 156 return FLOAT; |
81 | 157 case DRLVAR: |
221 | 158 code_drlvar(e2,1,USE_CREG); |
94 | 159 return DOUBLE; |
81 | 160 case DRGVAR: |
221 | 161 code_drgvar(e1,1,USE_CREG); |
94 | 162 return DOUBLE; |
195 | 163 #endif |
202 | 164 #if LONGLONG_CODE |
165 case LRLVAR: | |
221 | 166 code_lrlvar(e2,USE_CREG); |
202 | 167 return LONGLONG; |
168 case LRGVAR: | |
221 | 169 code_lrgvar(e1,USE_CREG); |
202 | 170 return LONGLONG; |
171 case LURLVAR: | |
221 | 172 code_lrlvar(e2,USE_CREG); |
202 | 173 return ULONGLONG; |
174 case LURGVAR: | |
221 | 175 code_lrgvar(e1,USE_CREG); |
202 | 176 return ULONGLONG; |
177 #endif | |
61 | 178 case FNAME: |
221 | 179 code_fname((NMTBL *)(e2),USE_CREG); |
94 | 180 return ADDRESS; |
61 | 181 case CONST: /* ÂåÆþ¤¹¤ëÃͤ¬0¤Ç¤âÆÃÊ̤ʽèÍý¤Ï¤·¤Ê¤¤ */ |
221 | 182 code_const(e2,USE_CREG); |
94 | 183 return INT; |
195 | 184 #if FLOAT_CODE |
81 | 185 case DCONST: |
221 | 186 code_dconst(e1,USE_CREG,1); |
94 | 187 return DOUBLE; |
133 | 188 case FCONST: |
221 | 189 code_dconst(e1,USE_CREG,0); |
133 | 190 return FLOAT; |
195 | 191 #endif |
206 | 192 #if LONGLONG_CODE |
202 | 193 case LCONST: |
221 | 194 code_lconst(e1,USE_CREG); |
202 | 195 return LONGLONG; |
196 #endif | |
61 | 197 case STRING: |
221 | 198 code_string(e1,USE_CREG); |
94 | 199 return ADDRESS; |
61 | 200 case FUNCTION: |
94 | 201 t = function(e1); |
202 return t; | |
61 | 203 case CODE: |
204 jump(e2,caddr(e1)); | |
94 | 205 return VOID; |
61 | 206 case INDIRECT: |
94 | 207 return g_expr0(e2); |
196 | 208 case RINDIRECT: |
245 | 209 return code_rindirect(e2,USE_CREG,caddr(e1),1); |
196 | 210 case URINDIRECT: |
245 | 211 return code_rindirect(e2,USE_CREG,caddr(e1),0); |
196 | 212 case CRINDIRECT: |
245 | 213 return code_crindirect(e2,USE_CREG,caddr(e1),1); |
196 | 214 case CURINDIRECT: |
245 | 215 return code_crindirect(e2,USE_CREG,caddr(e1),0); |
196 | 216 case SRINDIRECT: |
245 | 217 return code_srindirect(e2,USE_CREG,caddr(e1),1); |
218 case SURINDIRECT: | |
221 | 219 return code_srindirect(e2,USE_CREG,caddr(e1),0); |
195 | 220 #if FLOAT_CODE |
197 | 221 case FRINDIRECT: |
221 | 222 return code_drindirect(e2,USE_CREG,caddr(e1),0); |
196 | 223 case DRINDIRECT: |
221 | 224 return code_drindirect(e2,USE_CREG,caddr(e1),1); |
195 | 225 #endif |
196 | 226 #if LONGLONG_CODE |
227 case LRINDIRECT: | |
221 | 228 return code_lrindirect(e2,USE_CREG,caddr(e1),0); |
196 | 229 case LURINDIRECT: |
221 | 230 return code_lrindirect(e2,USE_CREG,caddr(e1),1); |
196 | 231 #endif |
61 | 232 case ADDRESS: |
138 | 233 if (car(e2)==REGISTER||car(e2)==DREGISTER||car(e2)==FREGISTER) |
234 return register_to_lvar(e2); /* too late? */ | |
105 | 235 else |
236 return g_expr0(e2); | |
61 | 237 case MINUS: /* ¥ì¥¸¥¹¥¿¤ËÂФ·¡¢negl¤ò¼Â¹Ô¤¹¤ì¤Ð¼Â¸½²Äǽ */ |
221 | 238 g_expr0(e2); code_neg(USE_CREG); |
94 | 239 return INT; |
212 | 240 #if LONGLONG_CODE |
241 case LMINUS: | |
221 | 242 g_expr0(e2); code_lneg(USE_CREG); |
212 | 243 return LONGLONG; |
244 #endif | |
195 | 245 #if FLOAT_CODE |
81 | 246 case DMINUS: |
221 | 247 g_expr0(e2); code_dneg(USE_CREG,1); |
94 | 248 return DOUBLE; |
133 | 249 case FMINUS: |
221 | 250 g_expr0(e2); code_dneg(USE_CREG,0); |
133 | 251 return FLOAT; |
195 | 252 #endif |
108 | 253 case CONV: |
254 g_expr0(e2); | |
255 switch(caddr(e1)) { | |
195 | 256 #if FLOAT_CODE |
221 | 257 case I2D: code_i2d(USE_CREG); return DOUBLE; |
258 case D2I: code_d2i(USE_CREG); return INT; | |
259 case U2D: code_u2d(USE_CREG); return DOUBLE; | |
260 case F2U: code_f2u(USE_CREG); return UNSIGNED; | |
261 case I2F: code_i2f(USE_CREG); return FLOAT; | |
262 case F2I: code_f2i(USE_CREG); return INT; | |
263 case U2F: code_u2f(USE_CREG); return FLOAT; | |
264 case D2U: code_d2u(USE_CREG); return UNSIGNED; | |
265 case D2F: code_d2f(USE_CREG); return FLOAT; | |
266 case F2D: code_f2d(USE_CREG); return DOUBLE; | |
195 | 267 #endif |
268 #if LONGLONG_CODE | |
221 | 269 case I2LL: code_i2ll(USE_CREG); return LONGLONG; |
270 case I2ULL: code_i2ull(USE_CREG); return ULONGLONG; | |
271 case U2LL: code_u2ll(USE_CREG); return LONGLONG; | |
272 case U2ULL: code_u2ull(USE_CREG); return ULONGLONG; | |
273 case LL2I: code_ll2i(USE_CREG); return INT; | |
274 case LL2U: code_ll2u(USE_CREG); return UNSIGNED; | |
275 case ULL2I: code_ull2i(USE_CREG); return INT; | |
276 case ULL2U: code_ull2u(USE_CREG); return UNSIGNED; | |
195 | 277 #if FLOAT_CODE |
221 | 278 case D2LL: code_d2ll(USE_CREG); return LONGLONG; |
279 case D2ULL: code_d2ull(USE_CREG); return ULONGLONG; | |
280 case F2LL: code_f2ll(USE_CREG); return LONGLONG; | |
281 case F2ULL: code_f2ull(USE_CREG); return ULONGLONG; | |
282 case LL2D: code_ll2d(USE_CREG); return DOUBLE; | |
283 case LL2F: code_ll2f(USE_CREG); return FLOAT; | |
284 case ULL2D: code_ull2d(USE_CREG); return DOUBLE; | |
285 case ULL2F: code_ull2f(USE_CREG); return FLOAT; | |
195 | 286 #endif |
287 #endif | |
288 | |
108 | 289 default: |
290 error(-1); return INT; | |
291 } | |
61 | 292 case BNOT: /* ~ */ |
221 | 293 g_expr0(e2); code_not(USE_CREG); |
94 | 294 return INT; |
61 | 295 case LNOT: /* ! */ |
221 | 296 g_expr0(e2); code_lnot(USE_CREG); |
94 | 297 return INT; |
61 | 298 case PREINC: |
221 | 299 code_preinc(e1,e2,caddr(e1),1,cadddr(e1),USE_CREG); |
168 | 300 return INT; |
301 case UPREINC: | |
221 | 302 code_preinc(e1,e2,caddr(e1),0,cadddr(e1),USE_CREG); |
94 | 303 return INT; |
61 | 304 case POSTINC: |
221 | 305 code_postinc(e1,e2,caddr(e1),1,cadddr(e1),USE_CREG); |
168 | 306 return INT; |
307 case UPOSTINC: | |
221 | 308 code_postinc(e1,e2,caddr(e1),0,cadddr(e1),USE_CREG); |
94 | 309 return INT; |
195 | 310 #if FLOAT_CODE |
147 | 311 case DPREINC: /* ++d */ |
221 | 312 code_dpreinc(e1,e2,1,USE_CREG); |
94 | 313 return DOUBLE; |
147 | 314 case DPOSTINC: /* d++ */ |
221 | 315 code_dpostinc(e1,e2,1,USE_CREG); |
94 | 316 return DOUBLE; |
147 | 317 case FPREINC: /* ++f */ |
221 | 318 code_dpreinc(e1,e2,0,USE_CREG); |
94 | 319 return FLOAT; |
147 | 320 case FPOSTINC: /* f++ */ |
221 | 321 code_dpostinc(e1,e2,0,USE_CREG); |
94 | 322 return FLOAT; |
195 | 323 #endif |
324 #if LONGLONG_CODE | |
325 case LPREINC: /* ++d */ | |
221 | 326 code_lpreinc(e1,e2,USE_CREG); |
219 | 327 return LONGLONG; |
195 | 328 case LPOSTINC: /* d++ */ |
221 | 329 code_lpostinc(e1,e2,USE_CREG); |
219 | 330 return LONGLONG; |
331 case LUPREINC: /* ++d */ | |
221 | 332 code_lpreinc(e1,e2,USE_CREG); |
219 | 333 return ULONGLONG; |
334 case LUPOSTINC: /* d++ */ | |
221 | 335 code_lpostinc(e1,e2,USE_CREG); |
219 | 336 return ULONGLONG; |
195 | 337 #endif |
61 | 338 case MUL: case UMUL: |
339 case DIV: case UDIV: | |
340 case MOD: case UMOD: | |
341 case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT: | |
246 | 342 case ADD: case SUB: case BAND: case EOR: case BOR: case CMP: case CMPGE: |
343 case UCMP: case CMPEQ: case CMPNEQ: | |
61 | 344 machinop(e1); |
94 | 345 return INT; |
195 | 346 #if FLOAT_CODE |
81 | 347 case DMUL: case DDIV: |
348 case DADD: case DSUB: | |
250 | 349 case DCMP: case DCMPGE: case DCMPEQ: case DCMPNEQ: |
133 | 350 dmachinop(e1,1); |
94 | 351 return DOUBLE; |
133 | 352 case FMUL: case FDIV: |
353 case FADD: case FSUB: | |
250 | 354 case FCMP: case FCMPGE: case FCMPEQ: case FCMPNEQ: |
133 | 355 dmachinop(e1,0); |
356 return FLOAT; | |
195 | 357 #endif |
358 #if LONGLONG_CODE | |
359 case LMUL: case LUMUL: | |
360 case LDIV: case LUDIV: | |
361 case LMOD: case LUMOD: | |
362 case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: | |
363 case LADD: case LSUB: case LBAND: case LEOR: case LBOR: case LCMP: | |
364 lmachinop(e1); | |
365 return INT; | |
366 #endif | |
222 | 367 case LCOND: |
368 case DCOND: | |
369 case FCOND: | |
195 | 370 case COND: /* a?0:1 should consider non-brach instruction */ |
371 d = (car(e1)==LCOND?LONGLONG: | |
372 car(e1)==COND?INT:car(e1)==DCOND?DOUBLE:FLOAT); | |
108 | 373 e2=fwdlabel(); |
374 b_expr(cadr(e1),0,e2,0); | |
187 | 375 g_expr0(caddr(e1)); |
221 | 376 t = code_get_fixed_creg(USE_CREG,d); |
108 | 377 jmp(e3=fwdlabel()); |
378 fwddef(e2); | |
191 | 379 t1=g_expr0(cadddr(e1)); |
187 | 380 code_set_fixed_creg(t,1,d); |
61 | 381 fwddef(e3); |
191 | 382 return t1; |
164 | 383 case STASS: |
61 | 384 sassign(e1); |
94 | 385 return RSTRUCT; |
165 | 386 case ASS: case CASS: case SASS: |
61 | 387 assign(e1); |
94 | 388 return INT; |
162 | 389 case ASSOP: case CASSOP: case CUASSOP: |
61 | 390 assop(e1); |
94 | 391 return INT; |
195 | 392 #if FLOAT_CODE |
393 case FASS: case DASS: | |
394 dassign(e1); | |
395 return DOUBLE; | |
81 | 396 case DASSOP: case FASSOP: |
397 dassop(e1); | |
94 | 398 return DOUBLE; |
195 | 399 #endif |
400 #if LONGLONG_CODE | |
401 case LASS: | |
402 lassign(e1); | |
403 return LONGLONG; | |
404 case LASSOP: case LUASSOP: | |
405 lassop(e1); | |
406 return LONGLONG ; | |
407 #endif | |
61 | 408 case RSTRUCT: |
83 | 409 g_expr0(e2); |
94 | 410 return RSTRUCT; |
61 | 411 case COMMA: |
83 | 412 g_expr_u(e2); |
94 | 413 return g_expr0(caddr(e1)); |
61 | 414 case RETURN: |
415 n = (NMTBL *)e2; | |
416 if (retcont==0) | |
417 retcont=fwdlabel(); | |
221 | 418 code_return(USE_CREG); |
94 | 419 return VOID; |
61 | 420 case ENVIRONMENT: |
221 | 421 code_environment(USE_CREG); |
94 | 422 return ADDRESS; |
61 | 423 default: |
221 | 424 code_bool(e1,USE_CREG); /* type? */ |
94 | 425 return INT; |
61 | 426 } |
427 } | |
428 | |
94 | 429 #define dual_ops(op) \ |
430 (op==GT|| op==UGT|| op==GE|| op==UGE|| op==LT|| \ | |
431 op==ULT|| op==LE|| op==ULE|| \ | |
432 op==DOP+GT|| op==DOP+GE|| op==DOP+LT|| op==DOP+LE || \ | |
135 | 433 op==FOP+GT|| op==FOP+GE|| op==FOP+LT|| op==FOP+LE || \ |
434 op==FOP+EQ|| op==FOP+NEQ || \ | |
435 op==EQ|| op==NEQ|| op==DOP+EQ|| op==DOP+NEQ) | |
94 | 436 |
437 int | |
438 rop_dual(op) | |
439 { | |
232 | 440 // x op y => y dual(op) x |
195 | 441 switch(op) { |
442 case GT: return LT; | |
443 case UGT: return ULT; | |
444 case GE: return LE; | |
445 case UGE: return ULE; | |
446 case LT: return GT; | |
447 case ULT: return UGT; | |
448 case LE: return GE; | |
449 case ULE: return UGE; | |
450 case DOP+GT: return DOP+LT; | |
451 case DOP+GE: return DOP+LE; | |
452 case DOP+LT: return DOP+GT; | |
453 case DOP+LE: return DOP+GE; | |
454 case FOP+GT: return FOP+LT; | |
455 case FOP+GE: return FOP+LE; | |
456 case FOP+LT: return FOP+GT; | |
457 case FOP+LE: return FOP+GE; | |
458 | |
459 case LOP+GT: return LOP+LT; | |
460 case LOP+GE: return LOP+LE; | |
461 case LOP+LT: return LOP+GT; | |
462 case LOP+LE: return LOP+GE; | |
463 case LOP+UGT: return FOP+ULT; | |
464 case LOP+UGE: return FOP+ULE; | |
465 case LOP+ULT: return FOP+UGT; | |
466 case LOP+ULE: return FOP+UGE; | |
467 } | |
94 | 468 return op; |
469 } | |
470 | |
61 | 471 void |
472 bexpr(int e1, char cond, int l1) | |
473 { | |
94 | 474 int op = car(e1); |
66 | 475 if (chk) return; |
61 | 476 gexpr_init(); |
94 | 477 if (dual_ops(op) && (car(caddr(e1))==CONST||(car(caddr(e1))==DCONST))) |
478 b_expr(list3(rop_dual(op),caddr(e1),cadr(e1)),cond,l1,0); | |
479 else | |
480 b_expr(e1,cond,l1,0); | |
61 | 481 } |
482 | |
483 void | |
484 b_expr(int e1, char cond, int l1,int err) | |
485 { | |
94 | 486 int e2,l2,t; |
132 | 487 if (!control) return; |
127 | 488 l2 = 0; |
61 | 489 e2=cadr(e1); |
490 switch(car(e1)) { | |
491 case LNOT: | |
492 b_expr(e2,!cond,l1,0); | |
493 return; | |
494 case GT: | |
89 | 495 rexpr(e1,l1,code_gt(cond),INT); |
61 | 496 return; |
497 case UGT: | |
89 | 498 rexpr(e1,l1,code_ugt(cond),UNSIGNED); |
61 | 499 return; |
500 case GE: | |
89 | 501 rexpr(e1,l1,code_ge(cond),INT); |
61 | 502 return; |
503 case UGE: | |
89 | 504 rexpr(e1,l1,code_uge(cond),UNSIGNED); |
61 | 505 return; |
506 case LT: | |
89 | 507 rexpr(e1,l1,code_ge(!cond),INT); |
61 | 508 return; |
509 case ULT: | |
89 | 510 rexpr(e1,l1,code_uge(!cond),UNSIGNED); |
61 | 511 return; |
512 case LE: | |
89 | 513 rexpr(e1,l1,code_gt(!cond),INT); |
61 | 514 return; |
515 case ULE: | |
89 | 516 rexpr(e1,l1,code_ugt(!cond),UNSIGNED); |
61 | 517 return; |
518 case EQ: | |
89 | 519 rexpr(e1,l1,code_eq(cond),INT); |
61 | 520 return; |
521 case NEQ: | |
89 | 522 rexpr(e1,l1,code_eq(!cond),INT); |
61 | 523 return; |
195 | 524 #if FLOAT_CODE |
82 | 525 case DOP+GT: |
194 | 526 case DOP+GE: |
527 case DOP+EQ: | |
528 case DOP+NEQ: | |
529 case FOP+GT: | |
530 case FOP+GE: | |
531 case FOP+EQ: | |
532 case FOP+NEQ: | |
229 | 533 drexpr(cadr(e1),caddr(e1),l1,car(e1),cond); |
82 | 534 return; |
194 | 535 case FOP+LT: |
231 | 536 case FOP+LE: |
82 | 537 case DOP+LT: |
538 case DOP+LE: | |
232 | 539 drexpr(caddr(e1),cadr(e1),l1,rop_dual(car(e1)),cond); |
82 | 540 return; |
195 | 541 #endif |
542 #if LONGLONG_CODE | |
543 case LOP+GT: | |
544 case LOP+GE: | |
545 case LOP+EQ: | |
546 case LOP+NEQ: | |
210 | 547 case LOP+UGT: |
548 case LOP+UGE: | |
231 | 549 lrexpr(cadr(e1),caddr(e1),l1,car(e1),cond); |
210 | 550 return; |
232 | 551 case LOP+LT: |
552 case LOP+LE: | |
210 | 553 case LOP+ULT: |
554 case LOP+ULE: | |
232 | 555 lrexpr(caddr(e1),cadr(e1),l1,rop_dual(car(e1)),cond); |
210 | 556 return; |
195 | 557 #endif |
61 | 558 case LAND: |
559 b_expr(e2,0,cond?(l2=fwdlabel()):l1,0); | |
560 b_expr(caddr(e1),cond,l1,0); | |
561 if(cond) fwddef(l2); | |
562 return; | |
563 case LOR: | |
564 b_expr(e2,1,cond?l1:(l2=fwdlabel()),0); | |
565 b_expr(caddr(e1),cond,l1,0); | |
566 if(!cond) fwddef(l2); | |
567 return; | |
167 | 568 case CRGVAR: case CURGVAR: |
221 | 569 code_cmp_crgvar(e1,USE_CREG,1); |
61 | 570 jcond(l1,cond); |
571 return; | |
167 | 572 case SRGVAR: case SURGVAR: |
221 | 573 code_cmp_crgvar(e1,USE_CREG,size_of_short); |
167 | 574 jcond(l1,cond); |
575 return; | |
576 case CRLVAR: case CURLVAR: | |
221 | 577 code_cmp_crlvar(e2,USE_CREG,1); |
167 | 578 jcond(l1,cond); |
579 return; | |
580 case SRLVAR: case SURLVAR: | |
221 | 581 code_cmp_crlvar(e2,USE_CREG,size_of_short); |
61 | 582 jcond(l1,cond); |
583 return; | |
584 case RGVAR: | |
221 | 585 code_cmp_rgvar(e1,USE_CREG); |
61 | 586 jcond(l1,cond); |
587 return; | |
588 case RLVAR: | |
221 | 589 code_cmp_rlvar(e2,USE_CREG); |
61 | 590 jcond(l1,cond); |
591 return; | |
195 | 592 #if FLOATC_DOE |
81 | 593 case DRLVAR: |
221 | 594 code_cmp_drlvar(e2,USE_CREG,1); |
138 | 595 jcond(l1,cond); |
596 return; | |
597 case FRLVAR: | |
221 | 598 code_cmp_drlvar(e2,USE_CREG,0); |
81 | 599 jcond(l1,cond); |
600 return; | |
601 case DRGVAR: | |
221 | 602 code_cmp_drgvar(e2,USE_CREG,1); |
138 | 603 jcond(l1,cond); |
604 return; | |
605 case FRGVAR: | |
221 | 606 code_cmp_drgvar(e2,USE_CREG,0); |
81 | 607 jcond(l1,cond); |
608 return; | |
138 | 609 case FREGISTER: |
610 code_cmp_dregister(e2,0); | |
611 jcond(l1,cond); | |
612 return; | |
94 | 613 case DREGISTER: |
138 | 614 code_cmp_dregister(e2,1); |
94 | 615 jcond(l1,cond); |
616 return; | |
81 | 617 case DCONST: |
138 | 618 case FCONST: |
132 | 619 if(control&&((dcadr(e2)!=0.0)^cond)) jmp(l1); |
81 | 620 return; |
195 | 621 #endif |
622 #if LONGLONG_DOE | |
623 case LRLVAR: | |
624 code_cmp_lrlvar(e2,1); | |
625 jcond(l1,cond); | |
626 return; | |
627 case LRGVAR: | |
628 code_cmp_lrgvar(e2,1); | |
629 jcond(l1,cond); | |
630 return; | |
631 case LREGISTER: | |
632 code_cmp_lregister(e2,1); | |
633 jcond(l1,cond); | |
634 return; | |
635 case LCONST: | |
636 if(control&&((lcadr(e2)!=0)^cond)) jmp(l1); | |
637 return; | |
638 #endif | |
639 case REGISTER: | |
640 code_cmp_register(e2); | |
641 jcond(l1,cond); | |
642 return; | |
643 case CONST: | |
644 if(control&&((cond&&e2)||(!cond&&!e2))) jmp(l1); | |
645 return; | |
61 | 646 default: |
647 if(err) { | |
81 | 648 error(-1); return; /* recursive g_expr/b_expr */ |
94 | 649 } |
650 t=g_expr(e1); | |
195 | 651 if (0) ; |
652 #if FLOAT_CODE | |
653 else if(t==FLOAT) | |
221 | 654 code_cmp_dregister(USE_CREG,0); |
138 | 655 else if(t==DOUBLE) |
221 | 656 code_cmp_dregister(USE_CREG,1); |
195 | 657 #endif |
658 #if LONGLONG_CODE | |
659 else if(t==LONGLONG||t==ULONGLONG) | |
221 | 660 code_cmp_lregister(USE_CREG); |
195 | 661 #endif |
94 | 662 else |
221 | 663 code_cmp_register(USE_CREG); |
61 | 664 jcond(l1,cond); |
665 return; | |
666 } | |
667 } | |
668 | |
126 | 669 int |
670 is_code(NMTBL *fnptr) | |
671 { | |
672 int type = fnptr->ty; | |
673 return type==CODE|| (type>0 && car(type)==CODE); | |
674 } | |
675 | |
676 int | |
677 is_function(NMTBL *fnptr) | |
678 { | |
679 int type = fnptr->ty; | |
680 return type==FUNCTION || (type>0 && car(type)==FUNCTION); | |
681 } | |
682 | |
61 | 683 |
105 | 684 static int |
685 register_to_lvar(int e) | |
686 { | |
687 error(REG_ERR); | |
688 return 0; | |
689 #if 0 | |
690 ÅÓÃæ¤Ç¥ì¥¸¥¹¥¿¤«¤éLVAR¤ËÊѹ¹¤·¤Æ¤â¡¢´Ö¤Ë¹ç¤ï¤Ê¤¤¡£ | |
691 | |
692 NMTBL *n = (NMTBL*)caddr(e); | |
693 int reg = cadr(e); | |
694 int tag = car(e); | |
695 int lvar; | |
696 int t; | |
697 if (!n||n==&null_nptr) error(REG_ERR); | |
698 if (tag==REGISTER) { | |
699 n->dsp = new_lvar(size_of_int); | |
700 t = INT; | |
701 } else if (tag==DREGISTER) { | |
702 n->dsp = new_lvar(size_of_double); | |
703 t = DOUBLE; | |
138 | 704 } else if (tag==FREGISTER) { |
705 n->dsp = new_lvar(size_of_float); | |
706 t = DOUBLE; | |
195 | 707 } else if (tag==LREGISTER) { |
708 n->dsp = new_lvar(size_of_longlong); | |
709 t = LONGLONG; | |
105 | 710 } else error(-1); |
711 n->sc = LVAR; | |
712 lvar = list2(LVAR,n->dsp); | |
713 g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),t,t)); | |
195 | 714 if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER||tag==LREGISTER) { |
105 | 715 free_register(reg); |
716 return g_expr0(lvar); | |
717 #endif | |
718 } | |
719 | |
61 | 720 /* goto arguments list */ |
721 /* target list4(list2(tag,disp),cdr,ty,source_expr) */ | |
722 /* source expr=listn(tag,...) */ | |
723 /* source (after) list2(tag,disp) */ | |
724 /* source list list3(e,cdr,sz) */ | |
725 | |
726 #define DEBUG_PARALLEL_ASSIGN 1 | |
727 | |
728 int | |
729 overrap(int t,int sz,int source) | |
730 { | |
731 int s,s0,s1; | |
732 int t0=cadr(t); | |
733 int t1=t0+sz; | |
734 for(;source;source=cadr(source)) { | |
735 s=car(source); s0=cadr(s); | |
736 if(car(s)==REGISTER && car(t)==REGISTER) { | |
737 if(s0==t0) return s; | |
738 } else if (is_same_type(s,t)) { | |
739 s1=s0+caddr(source); | |
740 #if DEBUG_PARALLEL_ASSIGN>1 | |
741 printf("# ovedrrap source %d t0 %d t1 %d\n",car(car(t)),t0,t1); | |
742 printf("# ovedrrap target %d s0 %d s1 %d\n",car(car(source)),s0,s1); | |
743 printf("# ovedrrap equal = %d\n",((t0<=s0&&s0<t1)||(t0<s1&&s1<=t1))); | |
744 #endif | |
745 if((t0<=s0&&s0<t1)||(t0<s1&&s1<=t1)) return s; | |
746 } | |
747 } | |
748 return 0; | |
749 } | |
750 | |
751 void | |
752 remove_target(int *target,int t,int *use) | |
753 { | |
754 int use0=*use; | |
147 | 755 int reg; |
61 | 756 while(use0) { |
757 if (car(use0)==t) { | |
147 | 758 reg = car(caddr(use0)); |
759 if (reg==REGISTER||reg==FREGISTER||reg==DREGISTER) | |
99 | 760 free_register(cadr(caddr(use0))); |
61 | 761 break; |
762 } | |
763 use0 = cadr(use0); | |
764 } | |
765 remove0(target,t); | |
766 } | |
767 | |
768 void | |
769 save_target(int t,int s,int *target,int *use,int sz,int ty) | |
770 { | |
771 int e1; | |
772 /*¿·¤·¤¤¥ì¥¸¥¹¥¿(or ¥¹¥¿¥Ã¥¯)¤ò¼èÆÀ¤¹¤ë*/ | |
773 if (sz==size_of_int && (e1=get_register())!=-1) { | |
105 | 774 e1=list3(REGISTER,e1,0); |
61 | 775 *use=list3(t,*use,e1); |
99 | 776 g_expr_u(assign_expr0(e1,s,ty,ty)); |
777 *target = append4(*target,t,ty,e1); | |
195 | 778 #if FLOAT_CODE |
138 | 779 } else if (sz==size_of_double && (e1=get_dregister(1))!=-1) { |
105 | 780 e1=list3(DREGISTER,e1,0); |
99 | 781 *use=list3(t,*use,e1); |
83 | 782 g_expr_u(assign_expr0(e1,s,ty,ty)); |
61 | 783 *target = append4(*target,t,ty,e1); |
138 | 784 } else if (sz==size_of_float && (e1=get_dregister(0))!=-1) { |
785 e1=list3(FREGISTER,e1,0); | |
786 *use=list3(t,*use,e1); | |
787 g_expr_u(assign_expr0(e1,s,ty,ty)); | |
788 *target = append4(*target,t,ty,e1); | |
195 | 789 #endif |
205 | 790 #if LONGLONG_CODE |
791 } else if (sz==size_of_longlong && (e1=get_lregister())!=-1) { | |
792 e1=list3(LREGISTER,e1,0); | |
793 *use=list3(t,*use,e1); | |
794 g_expr_u(assign_expr0(e1,s,ty,ty)); | |
795 *target = append4(*target,t,ty,e1); | |
796 #endif | |
61 | 797 } else { |
94 | 798 g_expr_u(assign_expr0((e1=list2(LVAR,new_lvar(sz))),s,ty,ty)); |
61 | 799 *target = append4(*target,t,ty,e1); |
117 | 800 *use=list3(t,*use,e1); |
61 | 801 } |
802 } | |
803 | |
804 int | |
805 circular_dependency(int t,int s,int *target,int *source) | |
806 { | |
807 int target0=*target; | |
808 int t1,sz,ty,s1; | |
809 while(target0) { | |
810 if (cadddr(target0)==s) { | |
811 t1=car(target0); | |
812 s=cadddr(target0); | |
813 sz=size(ty=caddr(target0)); | |
814 if(t==t1) { | |
815 #if DEBUG_PARALLEL_ASSIGN | |
816 printf("# circular dependency %d ty %d+%d sz %d\n",car(t1),ty,cadr(t1),sz); | |
817 #endif | |
818 return 1; | |
819 } | |
820 if ((s1=overrap(t1,sz,*source))) { | |
821 /* another overrap start over */ | |
822 return circular_dependency(t,s1,target,source); | |
823 } | |
824 } | |
825 target0=cadr(target0); | |
826 } | |
827 return 0; | |
828 } | |
829 | |
830 void | |
831 parallel_assign(int *target,int *source,int *processing,int *use) | |
832 { | |
833 int t,s,sz,ty,target0,s1; | |
834 while(*target) { | |
835 target0=*target; | |
836 while(target0) { | |
837 t=car(target0); s=cadddr(target0); | |
838 sz=size(ty=caddr(target0)); | |
839 if(car(t)==car(s) && cadr(t)==cadr(s)) { | |
840 /*½ñ¤¹þ¤ßÀ褬¼«Ê¬¼«¿È*/ | |
841 #if DEBUG_PARALLEL_ASSIGN | |
842 printf("# remove same %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); | |
843 #endif | |
844 remove_target(target,t,use); | |
845 /* Ç˲õ¤µ¤ì¤Æ¤Ïº¤¤ë¤Î¤Ç¡¢source list¤«¤é¤Ï½ü¤«¤Ê¤¤ */ | |
846 } else if (!(s1=overrap(t,sz,*source))) { | |
847 /* ½Å¤Ê¤Ã¤Æ¤Ê¤¤¤Î¤Ç°Â¿´¤·¤Æ½ñ¤¹þ¤á¤ë */ | |
848 #if DEBUG_PARALLEL_ASSIGN | |
849 printf("# normal assign %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); | |
850 #endif | |
83 | 851 g_expr_u(assign_expr0(t,s,ty,ty)); |
61 | 852 remove_target(target,t,use); remove0(source,s); |
853 } else { | |
854 if(circular_dependency(t,s1,target,source)) { | |
855 #if DEBUG_PARALLEL_ASSIGN | |
856 printf("# saving %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); | |
857 #endif | |
858 remove_target(target,t,use); remove0(source,s); | |
859 save_target(t,s,target,use,sz,ty); | |
860 } | |
861 } | |
862 target0=cadr(target0); | |
863 } | |
864 } | |
865 } | |
866 | |
867 void | |
868 remove0(int *parent,int e) | |
869 { | |
870 int list; | |
871 while ((list=*parent)) { | |
872 if (car(list)==e) { | |
873 *parent= cadr(list); return; | |
874 } else { | |
875 parent=&cadr(list); | |
876 } | |
877 } | |
878 } | |
879 | |
105 | 880 /* |
61 | 881 void |
882 remove0_all(int *parent,int e) | |
883 { | |
884 int list; | |
885 while ((list=*parent)) { | |
886 if (car(list)==e) { | |
887 *parent= cadr(list); | |
888 } else { | |
889 parent=&cadr(list); | |
890 } | |
891 } | |
892 } | |
105 | 893 */ |
61 | 894 |
895 int | |
896 is_simple(int e1) | |
897 { | |
898 return ( | |
99 | 899 e1==CONST || e1==FNAME || e1==LVAR || e1==REGISTER ||e1==DREGISTER || |
195 | 900 e1==FREGISTER || e1==LREGISTER || |
81 | 901 e1==GVAR || e1==RGVAR || e1==RLVAR || e1==CRLVAR || e1==CRGVAR || |
195 | 902 e1==DRLVAR || e1==FRLVAR || e1==LRLVAR || |
165 | 903 e1==CURLVAR || e1==SURLVAR || e1==CURGVAR || e1==SURGVAR |
61 | 904 ); |
905 } | |
906 | |
907 int | |
908 is_same_type(int e1,int e2) | |
909 { | |
910 int ce1=car(e1); | |
911 int ce2=car(e2); | |
912 return ( | |
81 | 913 (ce1==LVAR && (ce2==RLVAR||ce2==CRLVAR||ce2==FRLVAR||ce2==DRLVAR)) |
165 | 914 || (ce1==LVAR && (ce2==SRLVAR||ce2==SURLVAR||ce2==CURLVAR)) |
81 | 915 || (ce2==LVAR && (ce1==RLVAR||ce1==CRLVAR||ce1==FRLVAR||ce1==DRLVAR)) |
165 | 916 || (ce2==LVAR && (ce1==SRLVAR||ce1==SURLVAR||ce1==CURLVAR)) |
195 | 917 || (ce2==LVAR && (ce1==LRLVAR)) |
81 | 918 || (ce1==GVAR && (ce2==RGVAR||ce2==CRGVAR||ce2==FRGVAR||ce2==DRGVAR)) |
165 | 919 || (ce1==GVAR && (ce2==SRGVAR||ce2==SURGVAR||ce2==CURGVAR)) |
81 | 920 || (ce2==GVAR && (ce1==RGVAR||ce1==CRGVAR||ce1==FRGVAR||ce1==DRGVAR)) |
165 | 921 || (ce2==GVAR && (ce1==SRGVAR||ce1==SURGVAR||ce1==CURGVAR)) |
195 | 922 || (ce2==GVAR && (ce1==LRGVAR)) |
61 | 923 ); |
924 } | |
925 | |
926 int | |
927 is_memory(int e1) | |
928 { | |
929 int ce1=car(e1); | |
930 return ( | |
195 | 931 ce1==LVAR ||ce1==RLVAR||ce1==CRLVAR || ce1==DRLVAR || ce1==LRLVAR || |
932 ce1==GVAR ||ce1==RGVAR||ce1==CRGVAR || ce1==DRGVAR || ce1==LRGVAR || | |
933 ce1==FRLVAR || ce1==FRGVAR || | |
165 | 934 ce1==CURGVAR ||ce1==SURGVAR||ce1==SRGVAR || |
219 | 935 ce1==REGISTER|| ce1==DREGISTER || ce1==FREGISTER || |
936 ce1==LREGISTER | |
61 | 937 ); |
938 } | |
939 | |
98 | 940 |
61 | 941 void |
942 jump(int e1, int env) | |
943 { | |
99 | 944 int e2,e3,e4,sz,arg_size,ty,regs,fregs; |
147 | 945 int t0,s0,r,reg; |
127 | 946 NMTBL *code0 = 0; |
61 | 947 int target = 0; |
948 int source = 0; | |
949 int processing = 0; | |
950 int use = 0; | |
951 | |
952 /* ¤Þ¤º¡¢¥µ¥¤¥º¤ò·×»»¤·¤Ê¤¬¤é¡¢·è¤Þ¤Ã¤¿·Á¤ËÍ¡£ */ | |
953 | |
99 | 954 arg_size = 0; regs = 0; |
955 fregs = 0; | |
61 | 956 for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { |
957 e2 = car(e3); sz = size(ty=caddr(e3)); | |
138 | 958 if (scalar(ty) && (r = get_input_register_var(regs,0,1))) { |
959 target=list4(r,target,ty,e2); regs++; | |
960 } else if (ty==FLOAT && (r = get_input_dregister_var(fregs,0,1,0))) { | |
961 target=list4(r, target,ty,e2); fregs++; | |
962 } else if (ty==DOUBLE && (r = get_input_dregister_var(fregs,0,1,1))) { | |
963 target=list4(r, target,ty,e2); fregs++; | |
61 | 964 } else { |
965 target=list4(list2(LVAR,0), target,ty,e2); | |
966 } | |
128 | 967 /* keep arg space for register variables */ |
968 arg_size += sz; | |
61 | 969 #if DEBUG_PARALLEL_ASSIGN |
970 printf("# target %d ty %d+%d sz %d\n",car(car(target)),ty,cadr(car(target)),sz); | |
971 #endif | |
972 } | |
973 | |
974 /* disp ¤òÈô¤ÓÀè»÷¹ç¤ï¤»¤Æ½¤Àµ */ | |
98 | 975 if (is_code(fnptr)) { |
61 | 976 if (-arg_size<disp) disp = -arg_size; |
977 } else { | |
978 if (disp_offset-arg_size<disp) disp = disp_offset-arg_size; | |
979 } | |
980 | |
981 /* Ê£»¨¤Ê¼°¤òÁ°¤â¤Ã¤Æ·×»»¤·¤Æ¤ª¤¯ */ | |
982 /* ɬÍפʤé¶É½êÊÑ¿ô¤òÍѤ¤¤ë¡£ */ | |
983 /* ¶É½êÊÑ¿ô¤Ø¤Î¥ª¥Õ¥»¥Ã¥È¤ò³Ð¤¨¤Æ¤ª¤¯ */ | |
984 | |
985 for (e2 = target; e2; e2 = cadr(e2)) { | |
986 t0=car(e2); s0=cadddr(e2); | |
987 sz=size(ty=caddr(e2)); | |
988 if(car(t0)==LVAR) { | |
989 /* ¤³¤³¤Ç¡¢½ñ¹þÀ襢¥É¥ì¥¹¤ò·è¤á¤ë */ | |
990 cadr(t0)=-arg_size; | |
991 } | |
128 | 992 arg_size-=sz; |
61 | 993 if (!is_simple(car(s0))) { |
94 | 994 g_expr_u(assign_expr0((e4=list2(LVAR,new_lvar(sz))),s0,ty,ty)); |
117 | 995 use=list3(ty,use,e1); |
61 | 996 cadddr(e2)=e4; |
997 s0=e4; | |
998 } else if (is_same_type(t0,s0)) { | |
999 if(cadr(t0)==cadr(s0)) { | |
1000 #if DEBUG_PARALLEL_ASSIGN | |
1001 printf("# remove same memory %d ty %d+%d sz %d\n",car(t0),ty,cadr(t0),sz); | |
1002 #endif | |
1003 /* we should check size also (but currently useless */ | |
1004 remove0(&target,t0); | |
1005 /* still we have source to avoid overwrite */ | |
1006 } | |
1007 } | |
1008 if(is_memory(s0)) { | |
1009 source=list3(s0,source,sz); | |
1010 #if DEBUG_PARALLEL_ASSIGN | |
1011 printf("# source %d ty %d+%d sz %d\n",car(car(source)),ty,cadr(car(source)),sz); | |
1012 #endif | |
1013 } | |
1014 } | |
1015 | |
1016 /* compute jump address */ | |
1017 e2 = cadr(e1); | |
1018 if (car(e2) == FNAME) { | |
1019 code0=(NMTBL *)cadr(e2); | |
98 | 1020 if (!is_code(code0)) { |
61 | 1021 error(TYERR); return; |
1022 } | |
1023 } else { /* indirect */ | |
1024 g_expr(e2); | |
1025 emit_push(); | |
1026 } | |
1027 if (env) { | |
1028 g_expr(env); | |
1029 emit_push(); | |
1030 } | |
1031 | |
1032 /* ÊÂÎóÂåÆþ¤ò¼Â¹Ô */ | |
1033 parallel_assign(&target,&source,&processing,&use); | |
1034 while (use) { | |
147 | 1035 reg = car(caddr(use)); |
195 | 1036 if (reg==REGISTER||reg==FREGISTER||reg==DREGISTER||reg==LREGISTER) |
99 | 1037 free_register(cadr(caddr(use))); |
117 | 1038 else if (car(caddr(use))==LVAR) |
1039 free_lvar(cadr(caddr(use))); | |
99 | 1040 use=cadr(use); |
61 | 1041 } |
1042 if(target) error(-1); | |
1043 | |
1044 if (env) { | |
1045 /* change the frame pointer */ | |
1046 e3 = emit_pop(0); | |
1047 code_frame_pointer(e3); | |
1048 emit_pop_free(e3); | |
98 | 1049 } else if (is_function(fnptr)) { |
128 | 1050 if (car(e2) != FNAME) { |
1051 e2 = emit_pop(0); | |
1052 code_fix_frame_pointer(disp_offset); | |
1053 code_indirect_jmp(e2); | |
1054 emit_pop_free(e2); | |
1055 return; | |
1056 } | |
61 | 1057 code_fix_frame_pointer(disp_offset); |
1058 } | |
1059 | |
1060 if (car(e2) == FNAME) { | |
1061 code_jmp(code0->nm); | |
1062 } else { | |
1063 e2 = emit_pop(0); | |
1064 code_indirect_jmp(e2); | |
1065 emit_pop_free(e2); | |
1066 } | |
1067 } | |
1068 | |
1069 void | |
1070 machinop(int e1) | |
1071 { | |
240 | 1072 int e2,e3,op; |
61 | 1073 |
1074 e2 = cadr(e1); | |
1075 op = car(e1); | |
1076 e3 = caddr(e1); | |
240 | 1077 if (code_const_op_p(op,e3)) { |
189 | 1078 g_expr(e2); |
240 | 1079 oprtc(op,USE_CREG,e3); |
189 | 1080 return; |
1081 } | |
61 | 1082 g_expr(e3); |
1083 emit_push(); | |
1084 g_expr(e2); | |
221 | 1085 tosop(op,USE_CREG,(e2=pop_register())); |
61 | 1086 emit_pop_free(e2); |
1087 return; | |
1088 } | |
1089 | |
195 | 1090 #if FLOAT_CODE |
81 | 1091 void |
133 | 1092 dmachinop(int e1,int d) |
81 | 1093 { |
1094 int e2,e3,op; | |
1095 | |
1096 e2 = cadr(e1); | |
1097 op = car(e1); | |
1098 e3 = caddr(e1); | |
1099 g_expr(e3); | |
133 | 1100 emit_dpush(d); |
81 | 1101 g_expr(e2); |
221 | 1102 dtosop(car(e1),USE_CREG,(e2=emit_dpop(d))); |
138 | 1103 emit_dpop_free(e2,d); |
81 | 1104 return; |
1105 } | |
195 | 1106 #endif |
1107 | |
1108 #if LONGLONG_CODE | |
1109 void | |
1110 lmachinop(int e1) | |
1111 { | |
1112 int e2,e3,op; | |
1113 | |
1114 e2 = cadr(e1); | |
1115 op = car(e1); | |
1116 e3 = caddr(e1); | |
213 | 1117 if (code_lconst_op_p(op,e3)) { |
1118 g_expr(e2); | |
221 | 1119 loprtc(op,USE_CREG,e3); |
213 | 1120 return; |
1121 } | |
195 | 1122 g_expr(e3); |
1123 emit_lpush(); | |
1124 g_expr(e2); | |
221 | 1125 ltosop(car(e1),USE_CREG,(e2=emit_lpop())); |
195 | 1126 emit_lpop_free(e2); |
1127 return; | |
1128 } | |
1129 #endif | |
81 | 1130 |
61 | 1131 void |
1132 sassign(int e1) | |
1133 { | |
1134 int e2,e3,e4,sz,xreg,det; | |
1135 | |
1136 /* structure assignment */ | |
1137 e2 = cadr(e1); /* pointer variable to the struct */ | |
1138 e3 = cadr(e2); /* offset of the variable (distination) */ | |
1139 e4 = caddr(e1); /* right value (source) */ | |
1140 sz = cadddr(e1); /* size of struct or union */ | |
1141 g_expr(e4); | |
1142 emit_push(); | |
1143 g_expr(e2); | |
1144 xreg = emit_pop(0); | |
1145 /* °ìÈÌŪ¤Ë¤Ï¥³¥Ô¡¼¤Î¥ª¡¼¥Ð¥é¥Ã¥×¤Î¾õ¶·¤Ï¼Â¹Ô»þ¤Ë¤·¤«¤ï¤«¤é¤Ê¤¤ */ | |
1146 /* ¤·¤«¤·¡¢¤ï¤«¤ë¾ì¹ç¤â¤¢¤ë */ | |
1147 if (car(e4)==RSTRUCT) e4=cadr(e4); | |
1148 if (is_same_type(e2,e4)) { | |
1149 if(cadr(e2)<cadr(e4)) sz=-sz; | |
1150 det=1; | |
1151 } else { | |
1152 det = 0; | |
1153 } | |
221 | 1154 emit_copy(xreg,USE_CREG,sz,0,1,det); |
61 | 1155 emit_pop_free(xreg); |
1156 return; | |
1157 } | |
1158 | |
1159 void | |
118 | 1160 assign_opt(int e5,int e2,int e4,int byte) |
1161 { | |
1162 int reg; | |
1163 /* e2=e4 */ | |
1164 if (e5==REGISTER) { | |
1165 reg = cadr(e4); | |
1166 switch(car(e2)) { | |
1167 case GVAR: code_assign_gvar(e2,reg,byte); return; | |
119 | 1168 case LVAR: code_assign_lvar(cadr(e2),reg,byte); return; |
118 | 1169 case REGISTER: code_assign_register(cadr(e2),byte,reg); return; |
1170 } | |
1171 g_expr(e2); | |
233 | 1172 code_assign(USE_CREG,byte,reg); |
118 | 1173 return; |
1174 } | |
1175 /* e2 is register now */ | |
1176 if (car(e2)!=REGISTER) error(-1); | |
1177 reg = cadr(e2); | |
1178 switch(e5) { | |
162 | 1179 case CRGVAR: |
165 | 1180 case CURGVAR: code_crgvar(e4,reg,e5==CRGVAR,1); return; |
1181 case SRGVAR: | |
1182 case SURGVAR: code_crgvar(e4,reg,e5==SRGVAR,size_of_short); return; | |
118 | 1183 case RGVAR: code_rgvar(e4,reg); return; |
162 | 1184 case CRLVAR: |
165 | 1185 case CURLVAR: code_crlvar(cadr(e4),reg,e5==CRLVAR,1); return; |
1186 case SRLVAR: | |
1187 case SURLVAR: code_crlvar(cadr(e4),reg,e5==SRLVAR,size_of_short); return; | |
119 | 1188 case RLVAR: code_rlvar(cadr(e4),reg); return; |
118 | 1189 case GVAR: code_gvar(e4,reg); return; |
119 | 1190 case LVAR: code_lvar(cadr(e4),reg); return; |
118 | 1191 case CONST: code_const(cadr(e4),reg); return; |
1192 case ADDRESS: | |
1193 if (car(cadr(e4))==STRING) code_string(cadr(e4),reg); | |
1194 else code_gvar(cadr(e4),reg); | |
1195 return; | |
1196 case FNAME: code_fname((NMTBL*)cadr(e4),reg); return; | |
1197 case STRING: code_string(e4,reg); return; | |
135 | 1198 default: error(-1); |
118 | 1199 } |
1200 } | |
1201 | |
1202 void | |
61 | 1203 assign(int e1) |
1204 { | |
118 | 1205 int e2,e4,byte,e5; |
61 | 1206 |
166 | 1207 byte=(car(e1) == CASS)?1:(car(e1) == SASS)?size_of_short:0; |
61 | 1208 /* e2=e4 */ |
1209 e2 = cadr(e1); | |
118 | 1210 e4 = caddr(e1);e5=car(e4); |
1211 if (!use && ( | |
1212 (e5==REGISTER) || | |
1213 (car(e2)==REGISTER&&( | |
1214 e5== CRGVAR || e5== CRLVAR || e5== RGVAR || e5== RLVAR || | |
162 | 1215 e5== CURGVAR || e5== CURLVAR || |
165 | 1216 e5== SURGVAR || e5== SURLVAR || |
118 | 1217 e5== GVAR || e5== LVAR || |
1218 e5== CONST || e5== FNAME || e5== STRING || | |
1219 (e5==ADDRESS&&car(cadr(e4))==STRING) || | |
1220 (e5==ADDRESS&&car(cadr(e4))==GVAR) )))) { | |
1221 assign_opt(e5,e2,e4,byte); | |
1222 return; | |
1223 } | |
61 | 1224 switch(car(e2)) { |
1225 case GVAR: /* i=3 */ | |
1226 g_expr(e4); | |
221 | 1227 code_assign_gvar(e2,USE_CREG,byte); |
61 | 1228 return; |
1229 case LVAR: | |
1230 g_expr(e4); | |
221 | 1231 code_assign_lvar(cadr(e2),USE_CREG,byte); |
61 | 1232 return; |
1233 case REGISTER: | |
1234 g_expr(e4); | |
221 | 1235 code_assign_register(cadr(e2),byte,USE_CREG); |
61 | 1236 return; |
1237 } | |
1238 g_expr(e2); | |
1239 emit_push(); | |
1240 g_expr(e4); | |
1241 e2 = emit_pop(0); | |
221 | 1242 code_assign(e2,byte,USE_CREG); |
61 | 1243 emit_pop_free(e2); |
1244 return; | |
1245 } | |
1246 | |
195 | 1247 #if FLOAT_CODE |
1248 | |
61 | 1249 void |
118 | 1250 dassign_opt(int e5,int e2,int e4,int d) |
1251 { | |
1252 int reg; | |
1253 /* e2=e4 */ | |
138 | 1254 if (e5==DREGISTER||e5==FREGISTER) { |
118 | 1255 reg = cadr(e4); |
1256 switch(car(e2)) { | |
1257 case GVAR: /* i=3 */ | |
1258 code_dassign_gvar(e2,reg,d); | |
1259 return; | |
1260 case LVAR: | |
119 | 1261 code_dassign_lvar(cadr(e2),reg,d); |
118 | 1262 return; |
1263 case DREGISTER: | |
138 | 1264 case FREGISTER: |
118 | 1265 if (reg!=cadr(e2)) |
138 | 1266 code_dassign_dregister(cadr(e2),d,reg); |
118 | 1267 return; |
135 | 1268 default: |
1269 error(-1); | |
118 | 1270 } |
1271 } | |
1272 /* e2 is register now */ | |
138 | 1273 if (car(e2)!=DREGISTER && car(e2)!=FREGISTER) error(-1); |
118 | 1274 reg = cadr(e2); |
1275 switch(e5) { | |
135 | 1276 case FRGVAR: |
118 | 1277 case DRGVAR: code_drgvar(e4,d,reg); return; |
135 | 1278 case FRLVAR: |
119 | 1279 case DRLVAR: code_drlvar(cadr(e4),d,reg); return; |
135 | 1280 case FCONST: |
138 | 1281 case DCONST: code_dconst(e4,reg,1); return; |
135 | 1282 default: |
118 | 1283 error(-1); |
1284 } | |
1285 } | |
1286 | |
1287 void | |
81 | 1288 dassign(int e1) |
1289 { | |
118 | 1290 int e2,e3,e4,d,e5; |
81 | 1291 |
1292 /* e2=e4 */ | |
1293 e2 = cadr(e1); | |
1294 e3 = cadr(e2); | |
118 | 1295 e4 = caddr(e1); e5=car(e4); |
249 | 1296 if (car(e1)==DASS) d=1; |
1297 else if (car(e1)==FASS) d=0; | |
1298 else error(-1); | |
118 | 1299 if (!use && ( |
138 | 1300 (e5==DREGISTER) || (e5==FREGISTER) || |
133 | 1301 (car(e2)==DREGISTER&&(e5==DRGVAR||e5==DRLVAR||e5==DCONST))|| |
249 | 1302 (car(e2)==FREGISTER&&(e5==FRGVAR||e5==FRLVAR||e5==FCONST)) |
118 | 1303 )) { |
1304 dassign_opt(e5,e2,e4,d); | |
1305 return; | |
1306 } | |
81 | 1307 switch(car(e2)) { |
82 | 1308 case GVAR: |
81 | 1309 g_expr(e4); |
221 | 1310 code_dassign_gvar(e2,USE_CREG,d); |
81 | 1311 return; |
1312 case LVAR: | |
1313 g_expr(e4); | |
221 | 1314 code_dassign_lvar(cadr(e2),USE_CREG,d); |
81 | 1315 return; |
111 | 1316 case DREGISTER: |
138 | 1317 case FREGISTER: |
111 | 1318 g_expr(e4); |
221 | 1319 code_dassign_dregister(cadr(e2),d,USE_CREG); |
111 | 1320 return; |
81 | 1321 } |
1322 g_expr(e2); | |
82 | 1323 emit_push(); |
81 | 1324 g_expr(e4); |
82 | 1325 e2 = emit_pop(0); |
221 | 1326 code_dassign(e2,USE_CREG,d); |
82 | 1327 emit_pop_free(e2); |
81 | 1328 return; |
1329 } | |
1330 | |
195 | 1331 #endif |
1332 | |
1333 #if LONGLONG_CODE | |
1334 | |
1335 void | |
1336 lassign_opt(int e5,int e2,int e4) | |
1337 { | |
1338 int reg; | |
1339 /* e2=e4 */ | |
1340 if (e5==LREGISTER) { | |
1341 reg = cadr(e4); | |
1342 switch(car(e2)) { | |
1343 case GVAR: /* i=3 */ | |
1344 code_lassign_gvar(e2,reg); | |
1345 return; | |
1346 case LVAR: | |
1347 code_lassign_lvar(cadr(e2),reg); | |
1348 return; | |
1349 case LREGISTER: | |
1350 if (reg!=cadr(e2)) | |
1351 code_lassign_lregister(cadr(e2),reg); | |
1352 return; | |
1353 default: | |
1354 error(-1); | |
1355 } | |
1356 } | |
1357 /* e2 is register now */ | |
1358 if (car(e2)!=LREGISTER) error(-1); | |
1359 reg = cadr(e2); | |
1360 switch(e5) { | |
1361 case LRGVAR: code_lrgvar(e4,reg); return; | |
1362 case LRLVAR: code_lrlvar(cadr(e4),reg); return; | |
1363 case LCONST: code_lconst(e4,reg); return; | |
1364 default: | |
1365 error(-1); | |
1366 } | |
1367 } | |
1368 | |
1369 void | |
1370 lassign(int e1) | |
1371 { | |
1372 int e2,e3,e4,e5; | |
1373 | |
1374 /* e2=e4 */ | |
1375 e2 = cadr(e1); | |
1376 e3 = cadr(e2); | |
1377 e4 = caddr(e1); e5=car(e4); | |
1378 if (!use && ( | |
1379 (e5==LREGISTER) || | |
1380 (car(e2)==LREGISTER&&(e5==LRGVAR||e5==LRLVAR||e5==LCONST)) | |
1381 )) { | |
1382 lassign_opt(e5,e2,e4); | |
1383 return; | |
1384 } | |
1385 switch(car(e2)) { | |
1386 case GVAR: | |
1387 g_expr(e4); | |
221 | 1388 code_lassign_gvar(e2,USE_CREG); |
195 | 1389 return; |
1390 case LVAR: | |
1391 g_expr(e4); | |
221 | 1392 code_lassign_lvar(cadr(e2),USE_CREG); |
195 | 1393 return; |
1394 case LREGISTER: | |
1395 g_expr(e4); | |
221 | 1396 code_lassign_lregister(cadr(e2),USE_CREG); |
195 | 1397 return; |
1398 } | |
1399 g_expr(e2); | |
219 | 1400 emit_push(); |
195 | 1401 g_expr(e4); |
219 | 1402 e2 = emit_pop(0); |
221 | 1403 code_lassign(e2,USE_CREG); |
219 | 1404 emit_pop_free(e2); |
195 | 1405 return; |
1406 } | |
1407 | |
1408 #endif | |
1409 | |
81 | 1410 void |
61 | 1411 assop(int e1) |
1412 { | |
165 | 1413 int e2,e3,byte,op,sign,size; |
255 | 1414 int n,t; |
61 | 1415 |
1416 /* e2 op= e3 */ | |
162 | 1417 if (car(e1) == CUASSOP) { |
165 | 1418 byte = 1; sign = 0; size = 1; |
162 | 1419 } else if (car(e1) == CASSOP) { |
165 | 1420 byte = 1; sign = 1; size = 1; |
1421 } else if (car(e1) == SUASSOP) { | |
1422 byte = size_of_short; sign = 0; size = size_of_short; | |
1423 } else if (car(e1) == SASSOP) { | |
1424 byte = size_of_short; sign = 1; size = size_of_short; | |
162 | 1425 } else { |
165 | 1426 byte = 0; sign = 1; size = size_of_int; |
162 | 1427 } |
61 | 1428 e2 = cadr(e1); |
1429 if (car(e2)==INDIRECT) e2=cadr(e2); | |
1430 e3 = caddr(e1); | |
1431 op = cadddr(e1); | |
1432 | |
255 | 1433 if (car(e3)==CONST) { |
1434 /* e2 = e2 op e3; */ | |
1435 t = sign?INT:UNSIGNED; | |
1436 if (car(e2)==REGISTER||car(e2)==LVAR||car(e2)==GVAR) { | |
1437 g_expr(assign_expr0(e2,list3(op,rvalue_t(e2,t),e3),t,t)); | |
1438 return; | |
1439 } | |
1440 /* new = &e2 */ | |
1441 /* *new = *new op e3 */ | |
1442 n = list2(LVAR,new_lvar(size_of_int)); | |
1443 g_expr_u(assign_expr0(n,list2(ADDRESS,e2),INT,INT)); | |
1444 g_expr(assign_expr0(list2(INDIRECT,n),list3(op,n,e3),t,t)); | |
1445 free_lvar(cadr(n)); | |
1446 return; | |
1447 } | |
1448 | |
61 | 1449 g_expr(e3); |
1450 if (car(e2)==REGISTER) { | |
221 | 1451 code_register_assop(cadr(e2),USE_CREG,op,byte); |
1452 if (use) | |
1453 code_register(cadr(e2),USE_CREG); | |
61 | 1454 return; |
1455 } | |
1456 emit_push(); | |
1457 g_expr(e2); | |
221 | 1458 code_assop(op,USE_CREG,byte,sign); |
61 | 1459 return; |
1460 } | |
1461 | |
195 | 1462 #if FLOAT_CODE |
1463 | |
81 | 1464 void |
1465 dassop(int e1) | |
1466 { | |
83 | 1467 int e2,e3,op,d; |
81 | 1468 |
83 | 1469 /* e2 op= e3 */ |
1470 d = (car(e1) == DASSOP); | |
1471 e2 = cadr(e1); | |
1472 if (car(e2)==INDIRECT) e2=cadr(e2); | |
1473 e3 = caddr(e1); | |
1474 op = cadddr(e1); | |
1475 | |
1476 g_expr(e3); | |
144 | 1477 if (car(e2)==DREGISTER||car(e2)==FREGISTER) { |
219 | 1478 code_register_dassop(cadr(e2),op,d); |
221 | 1479 if (use) |
1480 code_dregister(cadr(e2),USE_CREG,d); | |
144 | 1481 return; |
1482 } | |
238 | 1483 emit_dpush(d); |
1484 g_expr(e2); | |
221 | 1485 code_dassop(op,USE_CREG,d); |
83 | 1486 return; |
81 | 1487 } |
61 | 1488 |
195 | 1489 #endif |
1490 | |
1491 #if LONGLONG_CODE | |
1492 | |
238 | 1493 static int |
1494 long_sign(int op) | |
1495 { | |
1496 return (op==LUDIV||op==LUMOD||op==LULSHIFT||op==LURSHIFT)?ULONGLONG:LONGLONG; | |
1497 } | |
1498 | |
195 | 1499 void |
1500 lassop(int e1) | |
1501 { | |
1502 int e2,e3,op; | |
238 | 1503 int n,t; |
195 | 1504 |
1505 /* e2 op= e3 */ | |
1506 e2 = cadr(e1); | |
1507 if (car(e2)==INDIRECT) e2=cadr(e2); | |
1508 e3 = caddr(e1); | |
1509 op = cadddr(e1); | |
1510 | |
238 | 1511 if (!code_lassop_p||car(e3)==LCONST) { |
1512 /* e2 = e2 op e3; */ | |
1513 t = long_sign(op); | |
1514 if (car(e2)==LREGISTER||car(e2)==LVAR||car(e2)==GVAR) { | |
1515 g_expr(assign_expr0(e2,list3(op,rvalue_t(e2,t),e3),t,t)); | |
239 | 1516 return; |
238 | 1517 } |
1518 /* new = &e2 */ | |
1519 /* *new = *new op e3 */ | |
1520 n = list2(LVAR,new_lvar(size_of_int)); | |
239 | 1521 g_expr_u(assign_expr0(n,list2(ADDRESS,e2),INT,INT)); |
238 | 1522 g_expr(assign_expr0(list2(INDIRECT,n),list3(op,n,e3),t,t)); |
1523 free_lvar(cadr(n)); | |
1524 return; | |
1525 } | |
1526 | |
195 | 1527 g_expr(e3); |
1528 if (car(e2)==LREGISTER) { | |
255 | 1529 emit_lpush(); |
219 | 1530 code_register_lassop(cadr(e2),op); |
221 | 1531 if (use) |
1532 code_lregister(cadr(e2),USE_CREG); | |
195 | 1533 return; |
1534 } | |
238 | 1535 emit_lpush(); |
1536 g_expr(e2); | |
221 | 1537 code_lassop(op,USE_CREG); |
195 | 1538 return; |
1539 } | |
1540 | |
1541 #endif | |
1542 | |
95 | 1543 void |
1544 cmpdimm(int e, int csreg) | |
1545 { | |
1546 code_cmpdimm(e, csreg); | |
1547 } | |
1548 | |
1549 int | |
1550 csvalue() | |
1551 { | |
1552 return code_csvalue(); | |
1553 } | |
1554 | |
1555 | |
61 | 1556 int |
1557 fwdlabel(void) | |
1558 { | |
1559 return labelno++; | |
1560 } | |
1561 | |
1562 void | |
1563 fwddef(int l) | |
1564 { | |
1565 control=1; | |
66 | 1566 if (!chk) |
92 | 1567 code_label(l); |
61 | 1568 } |
1569 | |
1570 int | |
1571 backdef(void) | |
1572 { | |
1573 control=1; | |
66 | 1574 if (!chk) |
92 | 1575 code_label(labelno); |
61 | 1576 return labelno++; |
1577 } | |
1578 | |
1579 void | |
1580 def_label(int cslabel, int dlabel) | |
1581 { | |
1582 int fl; | |
1583 | |
1584 fl = 0; | |
1585 if (control) { | |
1586 jmp(fl=fwdlabel()); | |
1587 } | |
1588 fwddef(cslabel); | |
1589 if (dlabel) | |
1590 jmp(dlabel); | |
1591 if (fl) { | |
1592 fwddef(fl); | |
1593 } | |
1594 } | |
1595 | |
1596 void | |
1597 gen_source(char *s) | |
1598 { | |
1599 printf("%s",s); | |
1600 } | |
1601 | |
1602 void | |
1603 ret(void) | |
1604 { | |
107 | 1605 code_set_return_register(1); |
61 | 1606 jmp(retlabel); |
1607 } | |
1608 | |
66 | 1609 void |
1610 opening(char *filename) | |
1611 { | |
1612 emit_init(); | |
1613 if (!chk) | |
1614 code_opening(filename); | |
1615 } | |
1616 | |
1617 void | |
1618 closing() | |
1619 { | |
1620 if (!chk) | |
1621 code_closing(); | |
1622 } | |
1623 | |
99 | 1624 int |
1625 contains_in_list(int e,int type) | |
1626 { | |
1627 while(e) { | |
1628 if(contains(car(e),type)) return 1; | |
1629 e = cadr(e); | |
1630 } | |
1631 return 0; | |
1632 } | |
1633 | |
1634 int | |
1635 contains(int e,int type) | |
1636 { | |
1637 while(e) { | |
1638 if (car(e)==type) return 1; | |
256
d80e6387c539
powerpc function call complex arugment pre computation.
kono
parents:
255
diff
changeset
|
1639 if (!car(e)) return 0; |
164 | 1640 if (LIST_ARGS(car(e))){ |
99 | 1641 /* list arguments */ |
1642 return contains_in_list(caddr(e),type); | |
164 | 1643 } else if (UNARY_ARGS(car(e))) { |
99 | 1644 /* unary operators */ |
1645 e = cadr(e); | |
1646 continue; | |
164 | 1647 } else if (BINARY_ARGS(car(e))) { |
99 | 1648 /* biary operators */ |
1649 if (contains(cadr(e),type)) return 1; | |
1650 e = caddr(e); | |
1651 continue; | |
164 | 1652 } else if (TARNARY_ARGS(car(e))) { |
99 | 1653 /* tarary operators */ |
1654 if (contains(cadr(e), type)) return 1; | |
1655 if (contains(caddr(e),type)) return 1; | |
1656 e = cadddr(e); | |
1657 continue; | |
164 | 1658 } else if (NULLARY_ARGS(car(e))) { |
135 | 1659 /* nullary operators */ |
1660 return 0; | |
164 | 1661 } else { |
135 | 1662 fprintf(stderr,"Unknown Tree ID %d\n",car(e)); |
1663 error(-1); | |
99 | 1664 return 0; |
1665 } | |
1666 } | |
1667 return 0; | |
1668 } | |
1669 | |
223 | 1670 int |
1671 contains_in_list_p(int e,int (*p)(int)) | |
1672 { | |
1673 while(e) { | |
1674 if(contains_p(car(e),p)) return 1; | |
1675 e = cadr(e); | |
1676 } | |
1677 return 0; | |
1678 } | |
1679 | |
1680 int | |
1681 contains_p(int e,int (*p)(int)) | |
1682 { | |
1683 while(e) { | |
256
d80e6387c539
powerpc function call complex arugment pre computation.
kono
parents:
255
diff
changeset
|
1684 if (!car(e)) return 0; |
223 | 1685 if (p(car(e))) return 1; |
1686 if (LIST_ARGS(car(e))){ | |
1687 /* list arguments */ | |
1688 return contains_in_list_p(caddr(e),p); | |
1689 } else if (UNARY_ARGS(car(e))) { | |
1690 /* unary operators */ | |
1691 e = cadr(e); | |
1692 continue; | |
1693 } else if (BINARY_ARGS(car(e))) { | |
1694 /* biary operators */ | |
1695 if (contains_p(cadr(e),p)) return 1; | |
1696 e = caddr(e); | |
1697 continue; | |
1698 } else if (TARNARY_ARGS(car(e))) { | |
1699 /* tarary operators */ | |
1700 if (contains_p(cadr(e), p)) return 1; | |
1701 if (contains_p(caddr(e),p)) return 1; | |
1702 e = cadddr(e); | |
1703 continue; | |
1704 } else if (NULLARY_ARGS(car(e))) { | |
1705 /* nullary operators */ | |
1706 return 0; | |
1707 } else { | |
1708 fprintf(stderr,"Unknown Tree ID %d\n",car(e)); | |
1709 error(-1); | |
1710 return 0; | |
1711 } | |
1712 } | |
1713 return 0; | |
1714 } | |
1715 | |
61 | 1716 /* end */ |