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