# HG changeset patch # User kono # Date 1083293271 -32400 # Node ID 1933266f1efa0b7700b8c5e4f5c6572e1d9a69da # Parent 7353a818858c732c78b868455399724098e81f12 long long ia32 (imcomplete) diff -r 7353a818858c -r 1933266f1efa mc-code-ia32.c --- a/mc-code-ia32.c Thu Apr 29 23:53:31 2004 +0900 +++ b/mc-code-ia32.c Fri Apr 30 11:47:51 2004 +0900 @@ -150,7 +150,7 @@ static void shift(char *op, int reg,int creg); static void ld_indexx(int byte, int n, int xreg,int reg,int sign); static void data_mode(char *name); -static int edx_setup(); +static int edx_setup(int rreg); static void edx_cleanup(); static void local_table(void); #if FLOAT_CODE @@ -1026,6 +1026,9 @@ #ifdef SAVE_STACKS code_save_stacks(); +#if FLOAT_CODE + code_save_fstacks(); +#endif #endif if (free_register_count(0)<1) { for(save = 0;save==dreg||save==creg;save++); @@ -1044,6 +1047,9 @@ if(scalar(t)) { g_expr(e4); printf("\tpushl %s\n",register_name(creg,0)); + } else if (t==LONGLONG||t==ULONGLONG) { + g_expr(e4); + printf("\tpushl %%edx\n\tpushl %%eax\n"); } else if (t==DOUBLE) { g_expr(e4); printf("\tleal\t-8(%%esp),%%esp\n\tfstpl\t(%%esp)\n"); @@ -1095,6 +1101,8 @@ regv[save]=0; if (ret_type==DOUBLE||ret_type==FLOAT) { fregv[freg]=1; regv[creg]=0; + } else if (ret_type==LONGLONG||ret_tpye==ULONGLONG) { + fregv[freg]=0; regv[creg]=0; } else if (ret_type==VOID) { fregv[freg]=0; regv[creg]=0; } else { @@ -1177,9 +1185,27 @@ #endif #if LONGLONG_CODE + +static void +lload(int creg,int offset) +{ + char *crn = register_name(creg,0); + if(rname[creg]==REG_EAX) { + printf("\tmovl %d(%s),%%edx\n",op,offset+size_of_int,crn); + printf("\tmovl %d(%s),%%eax\n",op,offset,crn); + } else { + printf("\tmovl %d(%s),%%eax\n",op,offset,crn); + printf("\tmovl %d(%s),%%edx\n",op,offset+size_of_int,crn); + } +} + int code_lrindirect(int e1, int reg, int offset, int us) { + char *crn; + g_expr(e1); + use_longlong(reg); + lload(creg,offset); return LONGLONG; } #endif @@ -1235,7 +1261,7 @@ code_assop(int op,int reg,int byte,int sign) { char *xrn; int xreg; - int edx = edx_setup(); + int edx = edx_setup(-1); use_int(reg); xrn = register_name(xreg = emit_pop(0),0); /* pop e3 value */ regv[xreg]=regs[xreg]=1; @@ -1308,7 +1334,7 @@ case DIV: case UDIV: use_register(creg,REG_EAX,1); - edx_setup(); + edx_setup(REG_EDX); orn = register_name(oreg,0); if (op==DIV) printf("\tcltd\n\tidivl %s\n",orn); @@ -1319,7 +1345,7 @@ case MOD: case UMOD: use_register(creg,REG_EAX,1); - edx_setup(); + edx_setup(REG_EDX); orn = register_name(oreg,0); if (op==MOD) printf("\tcltd\n\tidivl %s\n",orn); @@ -1392,7 +1418,7 @@ static int edx_stack=0; int -edx_setup() +edx_setup(int rreg) { int edx_save; /* make real EDX register empty */ @@ -1405,7 +1431,8 @@ edx_stack = list3(edx_save,edx_stack,1); } regv[edx_save]=0; - use_register(edx_save,REG_EDX,0); + if (rreg!=-1) + use_register(edx_save,rreg,0); return edx_save; } @@ -2154,9 +2181,6 @@ creg=screg; } } -#if FLOAT_CODE - code_save_fstacks(); -#endif } #if FLOAT_CODE @@ -2184,102 +2208,340 @@ /* 64bit int part */ -void lrexpr(int e1, int e2,int l1, int op,int cond) +static void +pcond(char *s,int l1) { + printf("\tj%s\t_%d\n",s,l1); } -int lpop_register() +void lrexpr(int e1, int e2,int l1, int op,int cond) { - return 0; + int reg; + int e3; + g_expr(e1); + emit_lpush(); + g_expr(e2); + e3 = emit_lpop(); + reg = lreg; + + printf("\tsubl %edx,4(%%esp)\n"); + switch(op) { + case LOP+GT: + pcond(code_gt(cond),l1); break; + case LOP+GE: + pcond(code_ge(cond),l1); break; + case LOP+EQ: + pcond(code_eq(cond),l1); break; + case LOP+NEQ: + pcond(code_eq(!cond),l1); break; + case LOP+LT: + pcond(code_ge(!cond),l1); break; + case LOP+LE: + pcond(code_gt(!cond),l1); break; + case LOP+UGT: + pcond(code_ugt(cond),l1); break; + case LOP+UGE: + pcond(code_uge(cond),l1); break; + default: + error(-1); + } + printf("\tsubl %eax,(%%esp)\n"); + switch(op) { + case LOP+GT: + pcond(code_gt(cond),l1); break; + case LOP+GE: + pcond(code_ge(cond),l1); break; + case LOP+EQ: + pcond(code_eq(cond),l1); break; + case LOP+NEQ: + pcond(code_eq(!cond),l1); break; + case LOP+LT: + pcond(code_ge(!cond),l1); break; + case LOP+LE: + pcond(code_gt(!cond),l1); break; + case LOP+UGT: + pcond(code_ugt(cond),l1); break; + case LOP+UGE: + pcond(code_uge(cond),l1); break; + default: + error(-1); + } + emit_lpop_free(e3); } int emit_lpop() { - return 0; + return 0; } void code_lregister(int e2,int reg) { - + error(-1); } void code_cmp_lregister(int reg) { - + error(-1); } void code_cmp_lrgvar(int e1,int e2) { - + char *n,*crn; + n = ((NMTBL*)cadr(e1))->nm; + use_int(e2); + crn = register_name(e2,0); + printf("\tmovl %s,%s\n",n,crn); + printf("\torl %s+4,%s\n",n,crn); + printf("\ttestl %s,%s\n",crn); } void code_cmp_lrlvar(int e1,int e2) { - + char *crn; + use_int(e2); + crn = register_name(e2,0); + printf("\tmovl %s,%d(%%dbp)\n",crn,lvar(e1)); + printf("\trol %s,%d(%%dbp)\n",crn,lvar(e1)+4); + printf("\ttestl %s,%s\n",crn); } void code_lassign(int e1,int e2) { - + char *rn; + // e1 = e2 + use_longlong(e2); + rn = register_name(e1); + printf("\tmovl %%eax,(%s)\n",rn); + printf("\tmovl %%edx,4(%s)\n",rn); } void code_lassign_gvar(int e1,int e2) { - + char *n,*crn; + n = ((NMTBL*)cadr(e1))->nm; + use_longlong(e2); + printf("\tmovl %%eax,%s\n",n); + printf("\tmovl %%edx,%s+4\n",n); } void code_lassign_lvar(int e1,int e2) { - + use_longlong(e2); + printf("\tmovl %%eax,%d(%%dbp)\n",lvar(e1)); + printf("\tmovl %%edx,%d(%%dbp)\n",lvar(e1)+4); } void code_lassign_lregister(int e2,int reg) { + error(-1); +} +static int +code_l1(long long d) +{ + int *i = (int *)&ll0; int *j = (int *)&d; + return (i[1] == 1)?j[1]:j[0]; } -void code_lconst(int e1,int e2) +static int +code_l2(long long d) { + int *i = (int *)&ll0; int *j = (int *)&d; + return (i[1] == 1)?j[0]:j[1]; +} +void +code_lconst(int e1,int creg) +{ + use_longlong(creg); + code_const(code_l1(lcadr(e1)),virtual(REG_EAX)); + code_const(code_l2(lcadr(e1)),virtual(REG_EDX)); } void code_lneg(int e1) { - + // use_longlong(creg); + printf("\tnegl %%eax\n"); + printf("\tadcl $0,%%edx\n"); + printf("\tnegl %%edx\n"); } void code_lrgvar(int e1,int e2) { - + char *n,*crn; + n = ((NMTBL*)cadr(e1))->nm; + use_longlong(e2); + printf("\tmovl %s,%%eax\n",n); + printf("\tmovl %s+4,%%edx\n",n); } void code_lrlvar(int e1,int e2) { - + use_longlong(e2); + printf("\tmovl %d(%%dbp),%%eax\n",lvar(e1)); + printf("\tmovl %d(%%dbp),%%edx\n",lvar(e1)+4); } void ltosop(int e1,int reg,int e2) { + char *opl,*oph,*call; + int lb; + use_longlong(reg); + opl = 0; call=0; + + switch(op) { + case LLSHIFT: + case LULSHIFT: + printf("\tmovl %%ecx,4(%%esp)\n";); + printf("\tpopl %%ecx\n";); + printf("\tshldl %%eax,%%edx\n"); + printf("\tsall %%cl,%%eax\n"); + printf("\ttestb $32,%%cl\n"); + printf("\tje\t_%d\n",(lb=fwdlabel())); + printf("\tmovl %%eax,%%edx\n"); + printf("\txorl %%eax,%%eax\n"); + fwddef(lb); + printf("\tpopl %%ecx\n"); + return; + case LRSHIFT: + printf("\tmovl %%ecx,4(%%esp)\n";); + printf("\tpopl %%ecx\n";); + printf("\tshrdl %%eax,%%edx\n"); + printf("\tsarl %%cl,%%eax\n"); + printf("\ttestb $32,%%cl\n"); + printf("\tje\t_%d\n",(lb=fwdlabel())); + printf("\tmovl %%edx,%%eax\n"); + printf("\tsarl $31,%%edx\n"); + fwddef(lb); + printf("\tpopl %%ecx\n"); + return; + case LURSHIFT: + printf("\tmovl %%ecx,4(%%esp)\n";); + printf("\tpopl %%ecx\n";); + printf("\tshrdl %%eax,%%edx\n"); + printf("\tshrl %%cl,%%eax\n"); + printf("\ttestb $32,%%cl\n"); + printf("\tje\t_%d\n",(lb=fwdlabel())); + printf("\tmovl %%edx,%%eax\n"); + printf("\txorl %%edx,%%edx\n"); + fwddef(lb); + printf("\tpopl %%ecx\n"); + return; + } + switch(op) { + case LADD: opl="addl";oph="adcl"; break; + case LSUB: opl="subl";oph="bbl"; break; + case LBAND: opl=oph="andl"; break; + case LEOR: opl=oph="xorl"; break; + case LBOR: opl=oph="orl"; break; + case LMUL: + case LUMUL: + printf("\tpushl %%edx\n";); + printf("\tpushl %%eax\n";); + printf("\tpushl %%ecx\n";); + // 4 c_l + // 8 c_h + // 12 o_l + // 16 o_h + printf("\tmull 12(%%esp)\n"); // c_l*o_l -> %edx,%eax + printf("\tmovl 4(%%esp),%%ecx\n"); // c_l->%ecx + printf("\timull 16(%%esp),%%ecx\n"); // c_l*o_h->%ecx + printf("\taddl %%ecx,%%edx\n",h); // %edx+%ecx->%edx + printf("\tmovl 8(%%esp),%%ecx\n"); // c_h->%ecx + printf("\timull 12(%%esp),%%ecx\n"); // c_h*o_l->%ecx + printf("\taddl %%ecx,%%edx\n",h); // %edx+%ecx->%edx + printf("\tpopl %%ecx\n"); + printf("\tladd $16,%%esp\n"); + return; + case LDIV: call="__divdi3"; break; + case LUDIV: call="__udivdi3"; break; + case LMOD: call="__moddi3"; break; + case LUMOD: call="__umoddi3"; break; + default: error(-1); + } + if (opl) { + printf("\t%s (%%esp),%%eax\n\t%s 4(%%esp),%%edx\n",opl,oph); + emit_lpop_free(e2); + } eles if (call) { + printf("\tcall %s\n",call); + printf("\tladd $16,%esp\n"); + } } -int code_lconst_op_p(int op,int e) {return 0;} -void loprtc(int op,int reg,int e) {} +int code_lconst_op_p(int op,int e) { + long long l = lcadr(e); + switch(op) { + case LLSHIFT: + case LULSHIFT: + case LRSHIFT: + case LURSHIFT: + return (0<=l&&l<=32); + case LADD: + case LSUB: + case LBAND + case LEOR: + case LBOR: + return 1; + default: + return 0; + } +} + +void loprtc(int op,int reg,int e) { + char *opl,*oph; + int lb; + int vl = code_l1(lcadr(e)); + int vh = code_l2(lcadr(e)); + + use_longlong(reg); + opl = 0; + + switch(op) { + case LLSHIFT: + case LULSHIFT: + printf("\tshldl $%d,%%eax,%%edx\n",vl); + printf("\tsall $%d,%%eax\n",vl); + return; + case LRSHIFT: + printf("\tshrdl $%d,%%eax,%%edx\n",vl); + printf("\tsarl $%d,%%eax\n",vl); + return; + case LURSHIFT: + printf("\tshrdl $%d,%%eax,%%edx\n",vl); + printf("\tshrl $%d,%%eax\n",vl); + return; + } + switch(op) { + case LADD: opl="addl";oph="adcl"; break; + case LSUB: opl="subl";oph="bbl"; break; + case LBAND: opl=oph="andl"; break; + case LEOR: opl=oph="xorl"; break; + case LBOR: opl=oph="orl"; break; + default: error(-1); + } + if (opl) { + printf("\t%s $%d,%%eax\n\t%s $%d,%%edx\n",opl,vl,oph,vh); + } +} void emit_lpop_free(int e1) { - + printf("\taddl $8,%%esp\n"); } void emit_lpush() { - + printf("\tpush %edx\n\tpushl %eax\n"); } void code_i2ll() { - use_int0(); - + int reg = USE_CREG; + if (virtual(REG_EAX)!=creg) + printf("\tmovl %s,%%eax\n",register_name(creg,0)); + use_longlong0(); + printf("\tcltd\n"); } void code_i2ull() @@ -2289,7 +2551,11 @@ void code_u2ll() { - + int reg = USE_CREG; + if (virtual(REG_EAX)!=creg) + printf("\tmovl %s,%%eax\n",register_name(creg,0)); + use_longlong0(); + printf("\txorl %%edx,%%edx\n"); } void code_u2ull() @@ -2299,73 +2565,89 @@ void code_ll2i() { - + int reg = USE_CREG; + reg = use_int0(); + if (virtual(REG_EAX)!=reg) + printf("\tmovl %%eax,%s\n",register_name(creg,0)); } void code_ll2u() { - + code_ll2i(); } void code_ull2i() { - + code_ll2i(); } void code_ull2u() { - + code_ll2i(); } #if FLOAT_CODE void code_d2ll() { - + use_longlong0(); + printf("\tsubl $40,%%esp\n"); + printf("\tfnstcw 2(%%esp)\n"); + printf("\tmovw 2(%%esp),%%ax\n"); + printf("\torw $3072,%%ax\n"); + printf("\tmovw %%ax,0(%%esp)\n"); + printf("\tfldcw 0(%%esp)\n"); + printf("\tfistpll 12(%%esp)\n"); + printf("\tfldcw 2(%%esp)\n"); + printf("\tmovl 12(%esp),%%eax\n"); + printf("\tmovl 16(%esp),%%edx\n"); + printf("\taddl $40,%%esp\n"); } void code_d2ull() { - + use_longlong0(); + printf("\tsubl $16,%%esp\n"); + printf("\tfstpl (%%esp)\n"); + printf("\tcall __fixunsdfdi\n"); + printf("\taddl $16,%%esp\n"); } void code_f2ll() { - + code_d2ll(); } void code_f2ull() { - + use_longlong0(); + printf("\tsubl $16,%%esp\n"); + printf("\tfstpl (%%esp)\n"); + printf("\tcall __fixunssfdi\n"); + printf("\taddl $16,%%esp\n"); } void code_ll2d() { - + printf("\tsubl $8,%%esp\n"); + printf("\tmovl %%eax,(%%esp)\n"); + printf("\tmovl %%edx,4(%%esp)\n"); + printf("\tfildll (%%esp)\n"); + printf("\taddl $8,%%esp\n"); } void code_ll2f() { - + code_ll2d(); } void code_ull2d() { - + code_ll2d(); } void code_ull2f() { - -} - -void code_ull2ll() -{ - -} - -void code_ull2ull() -{ - + code_ll2d(); } #endif diff -r 7353a818858c -r 1933266f1efa mc-code-powerpc.c --- a/mc-code-powerpc.c Thu Apr 29 23:53:31 2004 +0900 +++ b/mc-code-powerpc.c Fri Apr 30 11:47:51 2004 +0900 @@ -3409,16 +3409,10 @@ } int -lpop_register() -{ - return lreg_stack[--lreg_sp]; -} - -int emit_lpop() { int xreg,reg; - xreg=lpop_register(); + xreg=lreg_stack[--lreg_sp]; if (xreg<= -REG_LVAR_OFFSET) { reg = get_lregister(); code_lrlvar(REG_LVAR_OFFSET+xreg,reg); diff -r 7353a818858c -r 1933266f1efa mc.h --- a/mc.h Thu Apr 29 23:53:31 2004 +0900 +++ b/mc.h Fri Apr 30 11:47:51 2004 +0900 @@ -11,7 +11,7 @@ #endif #define FLOAT_CODE 1 -#define LONGLONG_CODE 0 +#define LONGLONG_CODE 1 #define SIZE_INT 4 diff -r 7353a818858c -r 1933266f1efa test/code-gen.c --- a/test/code-gen.c Thu Apr 29 23:53:31 2004 +0900 +++ b/test/code-gen.c Fri Apr 30 11:47:51 2004 +0900 @@ -2,7 +2,7 @@ /* $Id$ */ #define FLOAT_CODE 1 -#define LONGLONG_CODE 0 +#define LONGLONG_CODE 1 // code_lvar(int e2,int creg)