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;
|
61
|
1414
|
|
1415 /* e2 op= e3 */
|
162
|
1416 if (car(e1) == CUASSOP) {
|
165
|
1417 byte = 1; sign = 0; size = 1;
|
162
|
1418 } else if (car(e1) == CASSOP) {
|
165
|
1419 byte = 1; sign = 1; size = 1;
|
|
1420 } else if (car(e1) == SUASSOP) {
|
|
1421 byte = size_of_short; sign = 0; size = size_of_short;
|
|
1422 } else if (car(e1) == SASSOP) {
|
|
1423 byte = size_of_short; sign = 1; size = size_of_short;
|
162
|
1424 } else {
|
165
|
1425 byte = 0; sign = 1; size = size_of_int;
|
162
|
1426 }
|
61
|
1427 e2 = cadr(e1);
|
|
1428 if (car(e2)==INDIRECT) e2=cadr(e2);
|
|
1429 e3 = caddr(e1);
|
|
1430 op = cadddr(e1);
|
|
1431
|
|
1432 g_expr(e3);
|
|
1433 if (car(e2)==REGISTER) {
|
221
|
1434 code_register_assop(cadr(e2),USE_CREG,op,byte);
|
|
1435 if (use)
|
|
1436 code_register(cadr(e2),USE_CREG);
|
61
|
1437 return;
|
|
1438 }
|
|
1439 emit_push();
|
|
1440 g_expr(e2);
|
221
|
1441 code_assop(op,USE_CREG,byte,sign);
|
61
|
1442 return;
|
|
1443 }
|
|
1444
|
195
|
1445 #if FLOAT_CODE
|
|
1446
|
81
|
1447 void
|
|
1448 dassop(int e1)
|
|
1449 {
|
83
|
1450 int e2,e3,op,d;
|
81
|
1451
|
83
|
1452 /* e2 op= e3 */
|
|
1453 d = (car(e1) == DASSOP);
|
|
1454 e2 = cadr(e1);
|
|
1455 if (car(e2)==INDIRECT) e2=cadr(e2);
|
|
1456 e3 = caddr(e1);
|
|
1457 op = cadddr(e1);
|
|
1458
|
|
1459 g_expr(e3);
|
144
|
1460 if (car(e2)==DREGISTER||car(e2)==FREGISTER) {
|
219
|
1461 code_register_dassop(cadr(e2),op,d);
|
221
|
1462 if (use)
|
|
1463 code_dregister(cadr(e2),USE_CREG,d);
|
144
|
1464 return;
|
|
1465 }
|
238
|
1466 emit_dpush(d);
|
|
1467 g_expr(e2);
|
221
|
1468 code_dassop(op,USE_CREG,d);
|
83
|
1469 return;
|
81
|
1470 }
|
61
|
1471
|
195
|
1472 #endif
|
|
1473
|
|
1474 #if LONGLONG_CODE
|
|
1475
|
238
|
1476 static int
|
|
1477 long_sign(int op)
|
|
1478 {
|
|
1479 return (op==LUDIV||op==LUMOD||op==LULSHIFT||op==LURSHIFT)?ULONGLONG:LONGLONG;
|
|
1480 }
|
|
1481
|
195
|
1482 void
|
|
1483 lassop(int e1)
|
|
1484 {
|
|
1485 int e2,e3,op;
|
238
|
1486 int n,t;
|
195
|
1487
|
|
1488 /* e2 op= e3 */
|
|
1489 e2 = cadr(e1);
|
|
1490 if (car(e2)==INDIRECT) e2=cadr(e2);
|
|
1491 e3 = caddr(e1);
|
|
1492 op = cadddr(e1);
|
|
1493
|
238
|
1494 if (!code_lassop_p||car(e3)==LCONST) {
|
|
1495 /* e2 = e2 op e3; */
|
|
1496 t = long_sign(op);
|
|
1497 if (car(e2)==LREGISTER||car(e2)==LVAR||car(e2)==GVAR) {
|
|
1498 g_expr(assign_expr0(e2,list3(op,rvalue_t(e2,t),e3),t,t));
|
239
|
1499 return;
|
238
|
1500 }
|
|
1501 /* new = &e2 */
|
|
1502 /* *new = *new op e3 */
|
|
1503 n = list2(LVAR,new_lvar(size_of_int));
|
239
|
1504 g_expr_u(assign_expr0(n,list2(ADDRESS,e2),INT,INT));
|
238
|
1505 g_expr(assign_expr0(list2(INDIRECT,n),list3(op,n,e3),t,t));
|
|
1506 free_lvar(cadr(n));
|
|
1507 return;
|
|
1508 }
|
|
1509
|
195
|
1510 g_expr(e3);
|
|
1511 if (car(e2)==LREGISTER) {
|
219
|
1512 code_register_lassop(cadr(e2),op);
|
221
|
1513 if (use)
|
|
1514 code_lregister(cadr(e2),USE_CREG);
|
195
|
1515 return;
|
|
1516 }
|
238
|
1517 emit_lpush();
|
|
1518 g_expr(e2);
|
221
|
1519 code_lassop(op,USE_CREG);
|
195
|
1520 return;
|
|
1521 }
|
|
1522
|
|
1523 #endif
|
|
1524
|
95
|
1525 void
|
|
1526 cmpdimm(int e, int csreg)
|
|
1527 {
|
|
1528 code_cmpdimm(e, csreg);
|
|
1529 }
|
|
1530
|
|
1531 int
|
|
1532 csvalue()
|
|
1533 {
|
|
1534 return code_csvalue();
|
|
1535 }
|
|
1536
|
|
1537
|
61
|
1538 int
|
|
1539 fwdlabel(void)
|
|
1540 {
|
|
1541 return labelno++;
|
|
1542 }
|
|
1543
|
|
1544 void
|
|
1545 fwddef(int l)
|
|
1546 {
|
|
1547 control=1;
|
66
|
1548 if (!chk)
|
92
|
1549 code_label(l);
|
61
|
1550 }
|
|
1551
|
|
1552 int
|
|
1553 backdef(void)
|
|
1554 {
|
|
1555 control=1;
|
66
|
1556 if (!chk)
|
92
|
1557 code_label(labelno);
|
61
|
1558 return labelno++;
|
|
1559 }
|
|
1560
|
|
1561 void
|
|
1562 def_label(int cslabel, int dlabel)
|
|
1563 {
|
|
1564 int fl;
|
|
1565
|
|
1566 fl = 0;
|
|
1567 if (control) {
|
|
1568 jmp(fl=fwdlabel());
|
|
1569 }
|
|
1570 fwddef(cslabel);
|
|
1571 if (dlabel)
|
|
1572 jmp(dlabel);
|
|
1573 if (fl) {
|
|
1574 fwddef(fl);
|
|
1575 }
|
|
1576 }
|
|
1577
|
|
1578 void
|
|
1579 gen_source(char *s)
|
|
1580 {
|
|
1581 printf("%s",s);
|
|
1582 }
|
|
1583
|
|
1584 void
|
|
1585 ret(void)
|
|
1586 {
|
107
|
1587 code_set_return_register(1);
|
61
|
1588 jmp(retlabel);
|
|
1589 }
|
|
1590
|
66
|
1591 void
|
|
1592 opening(char *filename)
|
|
1593 {
|
|
1594 emit_init();
|
|
1595 if (!chk)
|
|
1596 code_opening(filename);
|
|
1597 }
|
|
1598
|
|
1599 void
|
|
1600 closing()
|
|
1601 {
|
|
1602 if (!chk)
|
|
1603 code_closing();
|
|
1604 }
|
|
1605
|
99
|
1606 int
|
|
1607 contains_in_list(int e,int type)
|
|
1608 {
|
|
1609 while(e) {
|
|
1610 if(contains(car(e),type)) return 1;
|
|
1611 e = cadr(e);
|
|
1612 }
|
|
1613 return 0;
|
|
1614 }
|
|
1615
|
|
1616 int
|
|
1617 contains(int e,int type)
|
|
1618 {
|
|
1619 while(e) {
|
|
1620 if (car(e)==type) return 1;
|
164
|
1621 if (LIST_ARGS(car(e))){
|
99
|
1622 /* list arguments */
|
|
1623 return contains_in_list(caddr(e),type);
|
164
|
1624 } else if (UNARY_ARGS(car(e))) {
|
99
|
1625 /* unary operators */
|
|
1626 e = cadr(e);
|
|
1627 continue;
|
164
|
1628 } else if (BINARY_ARGS(car(e))) {
|
99
|
1629 /* biary operators */
|
|
1630 if (contains(cadr(e),type)) return 1;
|
|
1631 e = caddr(e);
|
|
1632 continue;
|
164
|
1633 } else if (TARNARY_ARGS(car(e))) {
|
99
|
1634 /* tarary operators */
|
|
1635 if (contains(cadr(e), type)) return 1;
|
|
1636 if (contains(caddr(e),type)) return 1;
|
|
1637 e = cadddr(e);
|
|
1638 continue;
|
164
|
1639 } else if (NULLARY_ARGS(car(e))) {
|
135
|
1640 /* nullary operators */
|
|
1641 return 0;
|
164
|
1642 } else {
|
135
|
1643 fprintf(stderr,"Unknown Tree ID %d\n",car(e));
|
|
1644 error(-1);
|
99
|
1645 return 0;
|
|
1646 }
|
|
1647 }
|
|
1648 return 0;
|
|
1649 }
|
|
1650
|
223
|
1651 int
|
|
1652 contains_in_list_p(int e,int (*p)(int))
|
|
1653 {
|
|
1654 while(e) {
|
|
1655 if(contains_p(car(e),p)) return 1;
|
|
1656 e = cadr(e);
|
|
1657 }
|
|
1658 return 0;
|
|
1659 }
|
|
1660
|
|
1661 int
|
|
1662 contains_p(int e,int (*p)(int))
|
|
1663 {
|
|
1664 while(e) {
|
|
1665 if (p(car(e))) return 1;
|
|
1666 if (LIST_ARGS(car(e))){
|
|
1667 /* list arguments */
|
|
1668 return contains_in_list_p(caddr(e),p);
|
|
1669 } else if (UNARY_ARGS(car(e))) {
|
|
1670 /* unary operators */
|
|
1671 e = cadr(e);
|
|
1672 continue;
|
|
1673 } else if (BINARY_ARGS(car(e))) {
|
|
1674 /* biary operators */
|
|
1675 if (contains_p(cadr(e),p)) return 1;
|
|
1676 e = caddr(e);
|
|
1677 continue;
|
|
1678 } else if (TARNARY_ARGS(car(e))) {
|
|
1679 /* tarary operators */
|
|
1680 if (contains_p(cadr(e), p)) return 1;
|
|
1681 if (contains_p(caddr(e),p)) return 1;
|
|
1682 e = cadddr(e);
|
|
1683 continue;
|
|
1684 } else if (NULLARY_ARGS(car(e))) {
|
|
1685 /* nullary operators */
|
|
1686 return 0;
|
|
1687 } else {
|
|
1688 fprintf(stderr,"Unknown Tree ID %d\n",car(e));
|
|
1689 error(-1);
|
|
1690 return 0;
|
|
1691 }
|
|
1692 }
|
|
1693 return 0;
|
|
1694 }
|
|
1695
|
61
|
1696 /* end */
|