Mercurial > hg > CbC > old > device
comparison mc-code-ia32.c @ 237:1933266f1efa
long long ia32 (imcomplete)
author | kono |
---|---|
date | Fri, 30 Apr 2004 11:47:51 +0900 |
parents | 7353a818858c |
children | d64e9a6a66bd |
comparison
equal
deleted
inserted
replaced
236:7353a818858c | 237:1933266f1efa |
---|---|
148 static void use_register(int virt, int real, int move); | 148 static void use_register(int virt, int real, int move); |
149 static int virtual(int real); | 149 static int virtual(int real); |
150 static void shift(char *op, int reg,int creg); | 150 static void shift(char *op, int reg,int creg); |
151 static void ld_indexx(int byte, int n, int xreg,int reg,int sign); | 151 static void ld_indexx(int byte, int n, int xreg,int reg,int sign); |
152 static void data_mode(char *name); | 152 static void data_mode(char *name); |
153 static int edx_setup(); | 153 static int edx_setup(int rreg); |
154 static void edx_cleanup(); | 154 static void edx_cleanup(); |
155 static void local_table(void); | 155 static void local_table(void); |
156 #if FLOAT_CODE | 156 #if FLOAT_CODE |
157 static char * fload(int d); | 157 static char * fload(int d); |
158 static int code_d1(double d); | 158 static int code_d1(double d); |
1024 ret_type = cadr(cadddr(e1)); | 1024 ret_type = cadr(cadddr(e1)); |
1025 if (ret_type==CHAR) ret_type=INT; | 1025 if (ret_type==CHAR) ret_type=INT; |
1026 | 1026 |
1027 #ifdef SAVE_STACKS | 1027 #ifdef SAVE_STACKS |
1028 code_save_stacks(); | 1028 code_save_stacks(); |
1029 #if FLOAT_CODE | |
1030 code_save_fstacks(); | |
1031 #endif | |
1029 #endif | 1032 #endif |
1030 if (free_register_count(0)<1) { | 1033 if (free_register_count(0)<1) { |
1031 for(save = 0;save==dreg||save==creg;save++); | 1034 for(save = 0;save==dreg||save==creg;save++); |
1032 printf("\tpushl %s\n",register_name(save,0)); | 1035 printf("\tpushl %s\n",register_name(save,0)); |
1033 saved = 1; | 1036 saved = 1; |
1042 t=caddr(e3); | 1045 t=caddr(e3); |
1043 e4 = car(e3); | 1046 e4 = car(e3); |
1044 if(scalar(t)) { | 1047 if(scalar(t)) { |
1045 g_expr(e4); | 1048 g_expr(e4); |
1046 printf("\tpushl %s\n",register_name(creg,0)); | 1049 printf("\tpushl %s\n",register_name(creg,0)); |
1050 } else if (t==LONGLONG||t==ULONGLONG) { | |
1051 g_expr(e4); | |
1052 printf("\tpushl %%edx\n\tpushl %%eax\n"); | |
1047 } else if (t==DOUBLE) { | 1053 } else if (t==DOUBLE) { |
1048 g_expr(e4); | 1054 g_expr(e4); |
1049 printf("\tleal\t-8(%%esp),%%esp\n\tfstpl\t(%%esp)\n"); | 1055 printf("\tleal\t-8(%%esp),%%esp\n\tfstpl\t(%%esp)\n"); |
1050 nargs += size_of_double/size_of_int; | 1056 nargs += size_of_double/size_of_int; |
1051 fregv[freg]=0; | 1057 fregv[freg]=0; |
1093 free_register(save); | 1099 free_register(save); |
1094 } | 1100 } |
1095 regv[save]=0; | 1101 regv[save]=0; |
1096 if (ret_type==DOUBLE||ret_type==FLOAT) { | 1102 if (ret_type==DOUBLE||ret_type==FLOAT) { |
1097 fregv[freg]=1; regv[creg]=0; | 1103 fregv[freg]=1; regv[creg]=0; |
1104 } else if (ret_type==LONGLONG||ret_tpye==ULONGLONG) { | |
1105 fregv[freg]=0; regv[creg]=0; | |
1098 } else if (ret_type==VOID) { | 1106 } else if (ret_type==VOID) { |
1099 fregv[freg]=0; regv[creg]=0; | 1107 fregv[freg]=0; regv[creg]=0; |
1100 } else { | 1108 } else { |
1101 fregv[freg]=0; regv[creg]=1; | 1109 fregv[freg]=0; regv[creg]=1; |
1102 } | 1110 } |
1175 return DOUBLE; | 1183 return DOUBLE; |
1176 } | 1184 } |
1177 #endif | 1185 #endif |
1178 | 1186 |
1179 #if LONGLONG_CODE | 1187 #if LONGLONG_CODE |
1188 | |
1189 static void | |
1190 lload(int creg,int offset) | |
1191 { | |
1192 char *crn = register_name(creg,0); | |
1193 if(rname[creg]==REG_EAX) { | |
1194 printf("\tmovl %d(%s),%%edx\n",op,offset+size_of_int,crn); | |
1195 printf("\tmovl %d(%s),%%eax\n",op,offset,crn); | |
1196 } else { | |
1197 printf("\tmovl %d(%s),%%eax\n",op,offset,crn); | |
1198 printf("\tmovl %d(%s),%%edx\n",op,offset+size_of_int,crn); | |
1199 } | |
1200 } | |
1201 | |
1180 int | 1202 int |
1181 code_lrindirect(int e1, int reg, int offset, int us) | 1203 code_lrindirect(int e1, int reg, int offset, int us) |
1182 { | 1204 { |
1205 char *crn; | |
1206 g_expr(e1); | |
1207 use_longlong(reg); | |
1208 lload(creg,offset); | |
1183 return LONGLONG; | 1209 return LONGLONG; |
1184 } | 1210 } |
1185 #endif | 1211 #endif |
1186 | 1212 |
1187 char * | 1213 char * |
1233 | 1259 |
1234 void | 1260 void |
1235 code_assop(int op,int reg,int byte,int sign) { | 1261 code_assop(int op,int reg,int byte,int sign) { |
1236 char *xrn; | 1262 char *xrn; |
1237 int xreg; | 1263 int xreg; |
1238 int edx = edx_setup(); | 1264 int edx = edx_setup(-1); |
1239 use_int(reg); | 1265 use_int(reg); |
1240 xrn = register_name(xreg = emit_pop(0),0); /* pop e3 value */ | 1266 xrn = register_name(xreg = emit_pop(0),0); /* pop e3 value */ |
1241 regv[xreg]=regs[xreg]=1; | 1267 regv[xreg]=regs[xreg]=1; |
1242 printf("\tmovl %s,%s # assop \n",register_name(reg,0),register_name(edx,0)); | 1268 printf("\tmovl %s,%s # assop \n",register_name(reg,0),register_name(edx,0)); |
1243 regv[edx]=1; | 1269 regv[edx]=1; |
1306 printf("\t%s %s,%s\n","imull",orn,crn); | 1332 printf("\t%s %s,%s\n","imull",orn,crn); |
1307 break; | 1333 break; |
1308 case DIV: | 1334 case DIV: |
1309 case UDIV: | 1335 case UDIV: |
1310 use_register(creg,REG_EAX,1); | 1336 use_register(creg,REG_EAX,1); |
1311 edx_setup(); | 1337 edx_setup(REG_EDX); |
1312 orn = register_name(oreg,0); | 1338 orn = register_name(oreg,0); |
1313 if (op==DIV) | 1339 if (op==DIV) |
1314 printf("\tcltd\n\tidivl %s\n",orn); | 1340 printf("\tcltd\n\tidivl %s\n",orn); |
1315 else | 1341 else |
1316 printf("\txor %%edx,%%edx\n\tdivl %s\n",orn); | 1342 printf("\txor %%edx,%%edx\n\tdivl %s\n",orn); |
1317 edx_cleanup(); | 1343 edx_cleanup(); |
1318 break; | 1344 break; |
1319 case MOD: | 1345 case MOD: |
1320 case UMOD: | 1346 case UMOD: |
1321 use_register(creg,REG_EAX,1); | 1347 use_register(creg,REG_EAX,1); |
1322 edx_setup(); | 1348 edx_setup(REG_EDX); |
1323 orn = register_name(oreg,0); | 1349 orn = register_name(oreg,0); |
1324 if (op==MOD) | 1350 if (op==MOD) |
1325 printf("\tcltd\n\tidivl %s\n",orn); | 1351 printf("\tcltd\n\tidivl %s\n",orn); |
1326 else | 1352 else |
1327 printf("\txor %%edx,%%edx\n\tdivl %s\n",orn); | 1353 printf("\txor %%edx,%%edx\n\tdivl %s\n",orn); |
1390 | 1416 |
1391 | 1417 |
1392 static int edx_stack=0; | 1418 static int edx_stack=0; |
1393 | 1419 |
1394 int | 1420 int |
1395 edx_setup() | 1421 edx_setup(int rreg) |
1396 { | 1422 { |
1397 int edx_save; | 1423 int edx_save; |
1398 /* make real EDX register empty */ | 1424 /* make real EDX register empty */ |
1399 if (free_register_count(0)<1) { | 1425 if (free_register_count(0)<1) { |
1400 for(edx_save = 0;edx_save==dreg||edx_save==creg;edx_save++); | 1426 for(edx_save = 0;edx_save==dreg||edx_save==creg;edx_save++); |
1403 } else { | 1429 } else { |
1404 edx_save = get_register(); | 1430 edx_save = get_register(); |
1405 edx_stack = list3(edx_save,edx_stack,1); | 1431 edx_stack = list3(edx_save,edx_stack,1); |
1406 } | 1432 } |
1407 regv[edx_save]=0; | 1433 regv[edx_save]=0; |
1408 use_register(edx_save,REG_EDX,0); | 1434 if (rreg!=-1) |
1435 use_register(edx_save,rreg,0); | |
1409 return edx_save; | 1436 return edx_save; |
1410 } | 1437 } |
1411 | 1438 |
1412 | 1439 |
1413 void | 1440 void |
2152 reg_stack[sp]= reg_stack[sp]-REG_LVAR_OFFSET; | 2179 reg_stack[sp]= reg_stack[sp]-REG_LVAR_OFFSET; |
2153 regv[xreg]=0; | 2180 regv[xreg]=0; |
2154 creg=screg; | 2181 creg=screg; |
2155 } | 2182 } |
2156 } | 2183 } |
2157 #if FLOAT_CODE | |
2158 code_save_fstacks(); | |
2159 #endif | |
2160 } | 2184 } |
2161 | 2185 |
2162 #if FLOAT_CODE | 2186 #if FLOAT_CODE |
2163 void | 2187 void |
2164 code_save_fstacks() | 2188 code_save_fstacks() |
2182 #if LONGLONG_CODE | 2206 #if LONGLONG_CODE |
2183 | 2207 |
2184 | 2208 |
2185 /* 64bit int part */ | 2209 /* 64bit int part */ |
2186 | 2210 |
2211 static void | |
2212 pcond(char *s,int l1) | |
2213 { | |
2214 printf("\tj%s\t_%d\n",s,l1); | |
2215 } | |
2216 | |
2187 void lrexpr(int e1, int e2,int l1, int op,int cond) | 2217 void lrexpr(int e1, int e2,int l1, int op,int cond) |
2188 { | 2218 { |
2189 } | 2219 int reg; |
2190 | 2220 int e3; |
2191 int lpop_register() | 2221 g_expr(e1); |
2192 { | 2222 emit_lpush(); |
2223 g_expr(e2); | |
2224 e3 = emit_lpop(); | |
2225 reg = lreg; | |
2226 | |
2227 printf("\tsubl %edx,4(%%esp)\n"); | |
2228 switch(op) { | |
2229 case LOP+GT: | |
2230 pcond(code_gt(cond),l1); break; | |
2231 case LOP+GE: | |
2232 pcond(code_ge(cond),l1); break; | |
2233 case LOP+EQ: | |
2234 pcond(code_eq(cond),l1); break; | |
2235 case LOP+NEQ: | |
2236 pcond(code_eq(!cond),l1); break; | |
2237 case LOP+LT: | |
2238 pcond(code_ge(!cond),l1); break; | |
2239 case LOP+LE: | |
2240 pcond(code_gt(!cond),l1); break; | |
2241 case LOP+UGT: | |
2242 pcond(code_ugt(cond),l1); break; | |
2243 case LOP+UGE: | |
2244 pcond(code_uge(cond),l1); break; | |
2245 default: | |
2246 error(-1); | |
2247 } | |
2248 printf("\tsubl %eax,(%%esp)\n"); | |
2249 switch(op) { | |
2250 case LOP+GT: | |
2251 pcond(code_gt(cond),l1); break; | |
2252 case LOP+GE: | |
2253 pcond(code_ge(cond),l1); break; | |
2254 case LOP+EQ: | |
2255 pcond(code_eq(cond),l1); break; | |
2256 case LOP+NEQ: | |
2257 pcond(code_eq(!cond),l1); break; | |
2258 case LOP+LT: | |
2259 pcond(code_ge(!cond),l1); break; | |
2260 case LOP+LE: | |
2261 pcond(code_gt(!cond),l1); break; | |
2262 case LOP+UGT: | |
2263 pcond(code_ugt(cond),l1); break; | |
2264 case LOP+UGE: | |
2265 pcond(code_uge(cond),l1); break; | |
2266 default: | |
2267 error(-1); | |
2268 } | |
2269 emit_lpop_free(e3); | |
2270 } | |
2271 | |
2272 int emit_lpop() | |
2273 { | |
2274 return 0; | |
2275 } | |
2276 | |
2277 void code_lregister(int e2,int reg) | |
2278 { | |
2279 error(-1); | |
2280 } | |
2281 | |
2282 void code_cmp_lregister(int reg) | |
2283 { | |
2284 error(-1); | |
2285 } | |
2286 | |
2287 void code_cmp_lrgvar(int e1,int e2) | |
2288 { | |
2289 char *n,*crn; | |
2290 n = ((NMTBL*)cadr(e1))->nm; | |
2291 use_int(e2); | |
2292 crn = register_name(e2,0); | |
2293 printf("\tmovl %s,%s\n",n,crn); | |
2294 printf("\torl %s+4,%s\n",n,crn); | |
2295 printf("\ttestl %s,%s\n",crn); | |
2296 } | |
2297 | |
2298 void code_cmp_lrlvar(int e1,int e2) | |
2299 { | |
2300 char *crn; | |
2301 use_int(e2); | |
2302 crn = register_name(e2,0); | |
2303 printf("\tmovl %s,%d(%%dbp)\n",crn,lvar(e1)); | |
2304 printf("\trol %s,%d(%%dbp)\n",crn,lvar(e1)+4); | |
2305 printf("\ttestl %s,%s\n",crn); | |
2306 } | |
2307 | |
2308 void code_lassign(int e1,int e2) | |
2309 { | |
2310 char *rn; | |
2311 // e1 = e2 | |
2312 use_longlong(e2); | |
2313 rn = register_name(e1); | |
2314 printf("\tmovl %%eax,(%s)\n",rn); | |
2315 printf("\tmovl %%edx,4(%s)\n",rn); | |
2316 } | |
2317 | |
2318 void code_lassign_gvar(int e1,int e2) | |
2319 { | |
2320 char *n,*crn; | |
2321 n = ((NMTBL*)cadr(e1))->nm; | |
2322 use_longlong(e2); | |
2323 printf("\tmovl %%eax,%s\n",n); | |
2324 printf("\tmovl %%edx,%s+4\n",n); | |
2325 } | |
2326 | |
2327 void code_lassign_lvar(int e1,int e2) | |
2328 { | |
2329 use_longlong(e2); | |
2330 printf("\tmovl %%eax,%d(%%dbp)\n",lvar(e1)); | |
2331 printf("\tmovl %%edx,%d(%%dbp)\n",lvar(e1)+4); | |
2332 } | |
2333 | |
2334 void code_lassign_lregister(int e2,int reg) | |
2335 { | |
2336 error(-1); | |
2337 } | |
2338 | |
2339 static int | |
2340 code_l1(long long d) | |
2341 { | |
2342 int *i = (int *)&ll0; int *j = (int *)&d; | |
2343 return (i[1] == 1)?j[1]:j[0]; | |
2344 } | |
2345 | |
2346 static int | |
2347 code_l2(long long d) | |
2348 { | |
2349 int *i = (int *)&ll0; int *j = (int *)&d; | |
2350 return (i[1] == 1)?j[0]:j[1]; | |
2351 } | |
2352 | |
2353 void | |
2354 code_lconst(int e1,int creg) | |
2355 { | |
2356 use_longlong(creg); | |
2357 code_const(code_l1(lcadr(e1)),virtual(REG_EAX)); | |
2358 code_const(code_l2(lcadr(e1)),virtual(REG_EDX)); | |
2359 } | |
2360 | |
2361 void code_lneg(int e1) | |
2362 { | |
2363 // use_longlong(creg); | |
2364 printf("\tnegl %%eax\n"); | |
2365 printf("\tadcl $0,%%edx\n"); | |
2366 printf("\tnegl %%edx\n"); | |
2367 } | |
2368 | |
2369 void code_lrgvar(int e1,int e2) | |
2370 { | |
2371 char *n,*crn; | |
2372 n = ((NMTBL*)cadr(e1))->nm; | |
2373 use_longlong(e2); | |
2374 printf("\tmovl %s,%%eax\n",n); | |
2375 printf("\tmovl %s+4,%%edx\n",n); | |
2376 } | |
2377 | |
2378 void code_lrlvar(int e1,int e2) | |
2379 { | |
2380 use_longlong(e2); | |
2381 printf("\tmovl %d(%%dbp),%%eax\n",lvar(e1)); | |
2382 printf("\tmovl %d(%%dbp),%%edx\n",lvar(e1)+4); | |
2383 } | |
2384 | |
2385 void ltosop(int e1,int reg,int e2) | |
2386 { | |
2387 char *opl,*oph,*call; | |
2388 int lb; | |
2389 | |
2390 use_longlong(reg); | |
2391 opl = 0; call=0; | |
2392 | |
2393 switch(op) { | |
2394 case LLSHIFT: | |
2395 case LULSHIFT: | |
2396 printf("\tmovl %%ecx,4(%%esp)\n";); | |
2397 printf("\tpopl %%ecx\n";); | |
2398 printf("\tshldl %%eax,%%edx\n"); | |
2399 printf("\tsall %%cl,%%eax\n"); | |
2400 printf("\ttestb $32,%%cl\n"); | |
2401 printf("\tje\t_%d\n",(lb=fwdlabel())); | |
2402 printf("\tmovl %%eax,%%edx\n"); | |
2403 printf("\txorl %%eax,%%eax\n"); | |
2404 fwddef(lb); | |
2405 printf("\tpopl %%ecx\n"); | |
2406 return; | |
2407 case LRSHIFT: | |
2408 printf("\tmovl %%ecx,4(%%esp)\n";); | |
2409 printf("\tpopl %%ecx\n";); | |
2410 printf("\tshrdl %%eax,%%edx\n"); | |
2411 printf("\tsarl %%cl,%%eax\n"); | |
2412 printf("\ttestb $32,%%cl\n"); | |
2413 printf("\tje\t_%d\n",(lb=fwdlabel())); | |
2414 printf("\tmovl %%edx,%%eax\n"); | |
2415 printf("\tsarl $31,%%edx\n"); | |
2416 fwddef(lb); | |
2417 printf("\tpopl %%ecx\n"); | |
2418 return; | |
2419 case LURSHIFT: | |
2420 printf("\tmovl %%ecx,4(%%esp)\n";); | |
2421 printf("\tpopl %%ecx\n";); | |
2422 printf("\tshrdl %%eax,%%edx\n"); | |
2423 printf("\tshrl %%cl,%%eax\n"); | |
2424 printf("\ttestb $32,%%cl\n"); | |
2425 printf("\tje\t_%d\n",(lb=fwdlabel())); | |
2426 printf("\tmovl %%edx,%%eax\n"); | |
2427 printf("\txorl %%edx,%%edx\n"); | |
2428 fwddef(lb); | |
2429 printf("\tpopl %%ecx\n"); | |
2430 return; | |
2431 } | |
2432 switch(op) { | |
2433 case LADD: opl="addl";oph="adcl"; break; | |
2434 case LSUB: opl="subl";oph="bbl"; break; | |
2435 case LBAND: opl=oph="andl"; break; | |
2436 case LEOR: opl=oph="xorl"; break; | |
2437 case LBOR: opl=oph="orl"; break; | |
2438 case LMUL: | |
2439 case LUMUL: | |
2440 printf("\tpushl %%edx\n";); | |
2441 printf("\tpushl %%eax\n";); | |
2442 printf("\tpushl %%ecx\n";); | |
2443 // 4 c_l | |
2444 // 8 c_h | |
2445 // 12 o_l | |
2446 // 16 o_h | |
2447 printf("\tmull 12(%%esp)\n"); // c_l*o_l -> %edx,%eax | |
2448 printf("\tmovl 4(%%esp),%%ecx\n"); // c_l->%ecx | |
2449 printf("\timull 16(%%esp),%%ecx\n"); // c_l*o_h->%ecx | |
2450 printf("\taddl %%ecx,%%edx\n",h); // %edx+%ecx->%edx | |
2451 printf("\tmovl 8(%%esp),%%ecx\n"); // c_h->%ecx | |
2452 printf("\timull 12(%%esp),%%ecx\n"); // c_h*o_l->%ecx | |
2453 printf("\taddl %%ecx,%%edx\n",h); // %edx+%ecx->%edx | |
2454 printf("\tpopl %%ecx\n"); | |
2455 printf("\tladd $16,%%esp\n"); | |
2456 return; | |
2457 case LDIV: call="__divdi3"; break; | |
2458 case LUDIV: call="__udivdi3"; break; | |
2459 case LMOD: call="__moddi3"; break; | |
2460 case LUMOD: call="__umoddi3"; break; | |
2461 default: error(-1); | |
2462 } | |
2463 if (opl) { | |
2464 printf("\t%s (%%esp),%%eax\n\t%s 4(%%esp),%%edx\n",opl,oph); | |
2465 emit_lpop_free(e2); | |
2466 } eles if (call) { | |
2467 printf("\tcall %s\n",call); | |
2468 printf("\tladd $16,%esp\n"); | |
2469 } | |
2470 } | |
2471 | |
2472 int code_lconst_op_p(int op,int e) { | |
2473 long long l = lcadr(e); | |
2474 switch(op) { | |
2475 case LLSHIFT: | |
2476 case LULSHIFT: | |
2477 case LRSHIFT: | |
2478 case LURSHIFT: | |
2479 return (0<=l&&l<=32); | |
2480 case LADD: | |
2481 case LSUB: | |
2482 case LBAND | |
2483 case LEOR: | |
2484 case LBOR: | |
2485 return 1; | |
2486 default: | |
2193 return 0; | 2487 return 0; |
2194 } | 2488 } |
2195 | 2489 } |
2196 int emit_lpop() | 2490 |
2197 { | 2491 void loprtc(int op,int reg,int e) { |
2198 return 0; | 2492 char *opl,*oph; |
2199 } | 2493 int lb; |
2200 | 2494 int vl = code_l1(lcadr(e)); |
2201 void code_lregister(int e2,int reg) | 2495 int vh = code_l2(lcadr(e)); |
2202 { | 2496 |
2203 | 2497 use_longlong(reg); |
2204 } | 2498 opl = 0; |
2205 | 2499 |
2206 void code_cmp_lregister(int reg) | 2500 switch(op) { |
2207 { | 2501 case LLSHIFT: |
2208 | 2502 case LULSHIFT: |
2209 } | 2503 printf("\tshldl $%d,%%eax,%%edx\n",vl); |
2210 | 2504 printf("\tsall $%d,%%eax\n",vl); |
2211 void code_cmp_lrgvar(int e1,int e2) | 2505 return; |
2212 { | 2506 case LRSHIFT: |
2213 | 2507 printf("\tshrdl $%d,%%eax,%%edx\n",vl); |
2214 } | 2508 printf("\tsarl $%d,%%eax\n",vl); |
2215 | 2509 return; |
2216 void code_cmp_lrlvar(int e1,int e2) | 2510 case LURSHIFT: |
2217 { | 2511 printf("\tshrdl $%d,%%eax,%%edx\n",vl); |
2218 | 2512 printf("\tshrl $%d,%%eax\n",vl); |
2219 } | 2513 return; |
2220 | 2514 } |
2221 void code_lassign(int e1,int e2) | 2515 switch(op) { |
2222 { | 2516 case LADD: opl="addl";oph="adcl"; break; |
2223 | 2517 case LSUB: opl="subl";oph="bbl"; break; |
2224 } | 2518 case LBAND: opl=oph="andl"; break; |
2225 | 2519 case LEOR: opl=oph="xorl"; break; |
2226 void code_lassign_gvar(int e1,int e2) | 2520 case LBOR: opl=oph="orl"; break; |
2227 { | 2521 default: error(-1); |
2228 | 2522 } |
2229 } | 2523 if (opl) { |
2230 | 2524 printf("\t%s $%d,%%eax\n\t%s $%d,%%edx\n",opl,vl,oph,vh); |
2231 void code_lassign_lvar(int e1,int e2) | 2525 } |
2232 { | 2526 } |
2233 | |
2234 } | |
2235 | |
2236 void code_lassign_lregister(int e2,int reg) | |
2237 { | |
2238 | |
2239 } | |
2240 | |
2241 void code_lconst(int e1,int e2) | |
2242 { | |
2243 | |
2244 } | |
2245 | |
2246 void code_lneg(int e1) | |
2247 { | |
2248 | |
2249 } | |
2250 | |
2251 void code_lrgvar(int e1,int e2) | |
2252 { | |
2253 | |
2254 } | |
2255 | |
2256 void code_lrlvar(int e1,int e2) | |
2257 { | |
2258 | |
2259 } | |
2260 | |
2261 void ltosop(int e1,int reg,int e2) | |
2262 { | |
2263 | |
2264 } | |
2265 | |
2266 int code_lconst_op_p(int op,int e) {return 0;} | |
2267 void loprtc(int op,int reg,int e) {} | |
2268 | 2527 |
2269 void emit_lpop_free(int e1) | 2528 void emit_lpop_free(int e1) |
2270 { | 2529 { |
2271 | 2530 printf("\taddl $8,%%esp\n"); |
2272 } | 2531 } |
2273 | 2532 |
2274 void emit_lpush() | 2533 void emit_lpush() |
2275 { | 2534 { |
2276 | 2535 printf("\tpush %edx\n\tpushl %eax\n"); |
2277 } | 2536 } |
2278 | 2537 |
2279 void code_i2ll() | 2538 void code_i2ll() |
2280 { | 2539 { |
2281 use_int0(); | 2540 int reg = USE_CREG; |
2282 | 2541 if (virtual(REG_EAX)!=creg) |
2542 printf("\tmovl %s,%%eax\n",register_name(creg,0)); | |
2543 use_longlong0(); | |
2544 printf("\tcltd\n"); | |
2283 } | 2545 } |
2284 | 2546 |
2285 void code_i2ull() | 2547 void code_i2ull() |
2286 { | 2548 { |
2287 code_i2ll(); | 2549 code_i2ll(); |
2288 } | 2550 } |
2289 | 2551 |
2290 void code_u2ll() | 2552 void code_u2ll() |
2291 { | 2553 { |
2292 | 2554 int reg = USE_CREG; |
2555 if (virtual(REG_EAX)!=creg) | |
2556 printf("\tmovl %s,%%eax\n",register_name(creg,0)); | |
2557 use_longlong0(); | |
2558 printf("\txorl %%edx,%%edx\n"); | |
2293 } | 2559 } |
2294 | 2560 |
2295 void code_u2ull() | 2561 void code_u2ull() |
2296 { | 2562 { |
2297 code_u2ll(); | 2563 code_u2ll(); |
2298 } | 2564 } |
2299 | 2565 |
2300 void code_ll2i() | 2566 void code_ll2i() |
2301 { | 2567 { |
2302 | 2568 int reg = USE_CREG; |
2569 reg = use_int0(); | |
2570 if (virtual(REG_EAX)!=reg) | |
2571 printf("\tmovl %%eax,%s\n",register_name(creg,0)); | |
2303 } | 2572 } |
2304 | 2573 |
2305 void code_ll2u() | 2574 void code_ll2u() |
2306 { | 2575 { |
2307 | 2576 code_ll2i(); |
2308 } | 2577 } |
2309 | 2578 |
2310 void code_ull2i() | 2579 void code_ull2i() |
2311 { | 2580 { |
2312 | 2581 code_ll2i(); |
2313 } | 2582 } |
2314 | 2583 |
2315 void code_ull2u() | 2584 void code_ull2u() |
2316 { | 2585 { |
2317 | 2586 code_ll2i(); |
2318 } | 2587 } |
2319 | 2588 |
2320 #if FLOAT_CODE | 2589 #if FLOAT_CODE |
2321 void code_d2ll() | 2590 void code_d2ll() |
2322 { | 2591 { |
2323 | 2592 use_longlong0(); |
2593 printf("\tsubl $40,%%esp\n"); | |
2594 printf("\tfnstcw 2(%%esp)\n"); | |
2595 printf("\tmovw 2(%%esp),%%ax\n"); | |
2596 printf("\torw $3072,%%ax\n"); | |
2597 printf("\tmovw %%ax,0(%%esp)\n"); | |
2598 printf("\tfldcw 0(%%esp)\n"); | |
2599 printf("\tfistpll 12(%%esp)\n"); | |
2600 printf("\tfldcw 2(%%esp)\n"); | |
2601 printf("\tmovl 12(%esp),%%eax\n"); | |
2602 printf("\tmovl 16(%esp),%%edx\n"); | |
2603 printf("\taddl $40,%%esp\n"); | |
2324 } | 2604 } |
2325 | 2605 |
2326 void code_d2ull() | 2606 void code_d2ull() |
2327 { | 2607 { |
2328 | 2608 use_longlong0(); |
2609 printf("\tsubl $16,%%esp\n"); | |
2610 printf("\tfstpl (%%esp)\n"); | |
2611 printf("\tcall __fixunsdfdi\n"); | |
2612 printf("\taddl $16,%%esp\n"); | |
2329 } | 2613 } |
2330 | 2614 |
2331 void code_f2ll() | 2615 void code_f2ll() |
2332 { | 2616 { |
2333 | 2617 code_d2ll(); |
2334 } | 2618 } |
2335 | 2619 |
2336 void code_f2ull() | 2620 void code_f2ull() |
2337 { | 2621 { |
2338 | 2622 use_longlong0(); |
2623 printf("\tsubl $16,%%esp\n"); | |
2624 printf("\tfstpl (%%esp)\n"); | |
2625 printf("\tcall __fixunssfdi\n"); | |
2626 printf("\taddl $16,%%esp\n"); | |
2339 } | 2627 } |
2340 | 2628 |
2341 void code_ll2d() | 2629 void code_ll2d() |
2342 { | 2630 { |
2343 | 2631 printf("\tsubl $8,%%esp\n"); |
2632 printf("\tmovl %%eax,(%%esp)\n"); | |
2633 printf("\tmovl %%edx,4(%%esp)\n"); | |
2634 printf("\tfildll (%%esp)\n"); | |
2635 printf("\taddl $8,%%esp\n"); | |
2344 } | 2636 } |
2345 | 2637 |
2346 void code_ll2f() | 2638 void code_ll2f() |
2347 { | 2639 { |
2348 | 2640 code_ll2d(); |
2349 } | 2641 } |
2350 | 2642 |
2351 void code_ull2d() | 2643 void code_ull2d() |
2352 { | 2644 { |
2353 | 2645 code_ll2d(); |
2354 } | 2646 } |
2355 | 2647 |
2356 void code_ull2f() | 2648 void code_ull2f() |
2357 { | 2649 { |
2358 | 2650 code_ll2d(); |
2359 } | |
2360 | |
2361 void code_ull2ll() | |
2362 { | |
2363 | |
2364 } | |
2365 | |
2366 void code_ull2ull() | |
2367 { | |
2368 | |
2369 } | 2651 } |
2370 | 2652 |
2371 #endif | 2653 #endif |
2372 | 2654 |
2373 | 2655 |