Mercurial > hg > CbC > old > device
changeset 736:d7a976af188a
i64 continue...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 07 Nov 2010 22:52:33 +0900 |
parents | 31e5641bd7c7 |
children | d8b207cfbafe |
files | mc-code-i64.c |
diffstat | 1 files changed, 196 insertions(+), 574 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-code-i64.c Sat Nov 06 18:43:29 2010 +0900 +++ b/mc-code-i64.c Sun Nov 07 22:52:33 2010 +0900 @@ -1343,8 +1343,7 @@ code_crlvar(int e2,int reg,int sign,int sz) { use_int(reg); printf("\t%s ",cload(sign,sz)); lvar(e2); - printf(",%s\n",register_name(reg,SIZE_OF_INT)); - + printf(",%s\n",register_name(reg,sz<=SIZE_OF_INT?SIZE_OF_INT:0)); } @@ -2266,7 +2265,7 @@ } void -tosop(int op,int reg,int oreg) +tosop1(int op,int reg,int oreg,int sz) { int ox=0; char *orn,*crn; @@ -2278,7 +2277,10 @@ error(-1); } else if (oreg<= -REG_LVAR_OFFSET) { ox = get_register(); if (ox<0) error(-1); - code_rlvar(oreg+REG_LVAR_OFFSET,ox); + if (sz<=SIZE_OF_INT) + code_rlvar(oreg+REG_LVAR_OFFSET,ox); + else + code_lrlvar(oreg+REG_LVAR_OFFSET,ox); free_lvar(oreg+REG_LVAR_OFFSET); oreg = ox; } @@ -2286,43 +2288,44 @@ switch(op) { case LSHIFT: case ULSHIFT: - shift("sall",oreg,reg); + shift(sz<=SIZE_OF_INT?"sall":"salq",oreg,reg); if(ox) free_register(ox); return; case RSHIFT: - shift("sarl",oreg,reg); + shift(sz<=SIZE_OF_INT?"sarl":"sarq",oreg,reg); if(ox) free_register(ox); return; case URSHIFT: - shift("shrl",oreg,reg); + shift(sz<=SIZE_OF_INT?"shrl":"shrq",oreg,reg); if(ox) free_register(ox); return; } // regs[oreg]=1; - orn = register_name(oreg,SIZE_OF_INT); - crn = register_name(reg,SIZE_OF_INT); + orn = register_name(oreg,sz<=SIZE_OF_INT?SIZE_OF_INT:0); + crn = register_name(reg,sz<=SIZE_OF_INT?SIZE_OF_INT:0); + char *q = sz<=SIZE_OF_INT?"l":"q"; switch(op) { case ADD: - printf("\taddl %s,%s\n",orn,crn); + printf("\tadd%s %s,%s\n",q,orn,crn); break; case SUB: - printf("\tsubl %s,%s\n",orn,crn); + printf("\tsub%s %s,%s\n",q,orn,crn); break; case CMP: - printf("\tcmpl %s,%s\n",orn,crn); + printf("\tcmp%s %s,%s\n",q,orn,crn); break; case BAND: - printf("\tandl %s,%s\n",orn,crn); + printf("\tand%s %s,%s\n",q,orn,crn); break; case EOR: - printf("\txorl %s,%s\n",orn,crn); + printf("\txor%s %s,%s\n",q,orn,crn); break; case BOR: - printf("\torl %s,%s\n",orn,crn); + printf("\tor%s %s,%s\n",q,orn,crn); break; case MUL: case UMUL: - printf("\t%s %s,%s\n","imull",orn,crn); + printf("\t%s %s,%s\n","imul%s",q,orn,crn); break; case DIV: case UDIV: @@ -2338,10 +2341,17 @@ use_register(oreg,REG_ECX,1); oreg = REG_ECX; } - orn = register_name(oreg,0); - printf((op==DIV||op==MOD)? - "\tcltd\n\tidivl %s\n": - "\txor %%edx,%%edx\n\tdivl %s\n",orn); + if (sz<=SIZE_OF_INT) { + orn = register_name(oreg,SIZE_OF_INT); + printf((op==DIV||op==MOD)? + "\tcltd\n\tidivl %s\n": + "\txorl %%edx,%%edx\n\tdivl %s\n",orn); + } else { + orn = register_name(oreg,0); + printf((op==DIV||op==MOD)? + "\tcltq\n\tidivq %s\n": + "\txorl %%edx,%%edx\n\tdivq %s\n",orn); + } set_ireg((op==MOD||op==UMOD)?REG_EDX:REG_EAX,0); set_ireg(reg,1); break; @@ -2349,6 +2359,12 @@ if(ox && ox!=ireg) free_register(ox); } +void +tosop(int op,int reg,int oreg) +{ + tosop1(op,reg,oreg,SIZE_OF_INT); +} + int code_const_op_p(int op,int e) { @@ -2359,67 +2375,82 @@ } void -oprtc(int op,int reg,int orn) +oprtc1(int op,int reg,int orn1,int sz) { char *crn; int datareg; use_int(reg); - crn = register_name(reg,SIZE_OF_INT); - orn = cadr(orn); + char *q = sz<SIZE_OF_INT?"l":"q"; + crn = register_name(reg,sz<=SIZE_OF_INT?SIZE_OF_INT:0); + long orn ; + if (car(orn1)==CONST) orn = cadr(orn1); + else if (car(orn1)==LCONST) orn = lcadr(orn1); + else error(-1); + datareg=is_data_reg(reg); switch(op) { case LSHIFT: case ULSHIFT: - printf("\tsall $%d,%s\n",orn,crn); + printf("\tsal%s $%ld,%s\n",q,orn,crn); return; case DIV: orn = ilog(orn); case RSHIFT: - printf("\tsarl $%d,%s\n",orn,crn); + printf("\tsar%s $%ld,%s\n",q,orn,crn); return; case UDIV: orn = ilog(orn); case URSHIFT: - printf("\tshrl $%d,%s\n",orn,crn); + printf("\tshr%s $%ld,%s\n",q,orn,crn); return; case ADD: - printf("\taddl $%d,%s\n",orn,crn); + printf("\tadd%s $%ld,%s\n",q,orn,crn); break; case SUB: case CMP: - printf("\tsubl $%d,%s\n",orn,crn); + printf("\tsub%s $%ld,%s\n",q,orn,crn); break; case BAND: if (datareg&&(orn & ~255)==~255) - printf("\tandb $%d,%s\n",orn,register_name(reg,1)); + printf("\tandb $%ld,%s\n",orn,register_name(reg,1)); else if (datareg&&(orn & ~65535)==~65535) - printf("\tandw $%d,%s\n",orn,register_name(reg,2)); + printf("\tandw $%ld,%s\n",orn,register_name(reg,2)); + else if (sz<=SIZE_OF_INT||(datareg&&(orn & ~0xffffffff)==~0xffffffff)) + printf("\tandl $%ld,%s\n",orn,register_name(reg,4)); else - printf("\tandl $%d,%s\n",orn,crn); + printf("\tandq $%ld,%s\n",orn,crn); break; case EOR: - printf("\txorl $%d,%s\n",orn,crn); + printf("\txor%s $%ld,%s\n",q,orn,crn); break; case BOR: if (datareg&&(orn & ~255)==0) - printf("\tor $%d,%s\n",orn,register_name(reg,1)); + printf("\tor $%ld,%s\n",orn,register_name(reg,1)); else if (datareg&&(orn & ~65535)==0) - printf("\tor $%d,%s\n",orn,register_name(reg,2)); + printf("\tor $%ld,%s\n",orn,register_name(reg,2)); + else if (sz<=SIZE_OF_INT||(datareg&&(orn & ~0xffffffff)==0)) + printf("\torl $%ld,%s\n",orn,register_name(reg,4)); else - printf("\torl $%d,%s\n",orn,crn); + printf("\torq $%ld,%s\n",orn,crn); break; case MUL: case UMUL: if (ilog(orn)) { - printf("\tsall $%d,%s\n",ilog(orn),crn); + printf("\tsal%s $%ld,%s\n",q,ilog(orn),crn); } else - printf("\t%s $%d,%s\n","imull",orn,crn); + printf("\t%s%s $%ld,%s\n","imul",q,orn,crn); break; default: error(-1); } } +void +oprtc(int op,int reg,int orn) +{ + oprtc1(op,reg,orn,SIZE_OF_INT); +} + void shift(char *op, int oreg,int reg) @@ -3213,7 +3244,7 @@ void code_dneg(int freg,int d) { - int reg = get_dregister(); + int reg = get_dregister(d); if (d) { printf("\txorpd %s,%s\n",register_name(freg,0),register_name(reg,0)); printf("\tmovapd %s,%s\n",register_name(reg,0),register_name(freg,0)); @@ -3253,7 +3284,7 @@ char *t = get_regsiter_name(tmp); use_int(reg); char *d = get_regsiter_name(reg); - int td = get_dregsiter(); + int td = get_dregsiter(d); char *dbs = db?"d":"s"; printf(" cmpq $0, %s\n",u); printf(" js f1\n"); @@ -3324,7 +3355,7 @@ { char *db = d?"d":"s"; char *f = get_register_name(reg,0); - int t = get_dregister(); + int t = get_dregister(d); #ifdef __APPLE__ int r = get_ptr_cache(ncaddr(e2)); if (cadr(e2)) @@ -3545,29 +3576,30 @@ default: return 0; } } - s = "e"; + s = "a"; + int cmp = FCMP; switch(op) { case DOP+GE: + cmp = DCMP; case FOP+GE: - g_expr(list3(DCMP,e1,e2)); - printf("\ttestb\t$5,%%ah\n"); + g_expr(list3(cmp,e1,e2)); + s = "ae"; break; case DOP+GT: + cmp = DCMP; case FOP+GT: - g_expr(list3(DCMP,e1,e2)); - printf("\ttestb\t$69,%%ah\n"); + g_expr(list3(cmp,e1,e2)); break; case DOP+EQ: + cmp = DCMP; case FOP+EQ: - g_expr(list3(DCMP,e1,e2)); - printf("\tandb\t$69,%%ah\n"); - printf("\txorb\t$64,%%ah\n"); + s = "e"; + g_expr(list3(cmp,e1,e2)); break; case DOP+NEQ: + cmp = DCMP; case FOP+NEQ: - g_expr(list3(DCMP,e1,e2)); - printf("\tandb\t$69,%%ah\n"); - printf("\txorb\t$64,%%ah\n"); + g_expr(list3(cmp,e1,e2)); s = "ne"; break; default: @@ -3607,54 +3639,55 @@ void code_cmp_dregister(int e2,int d,int label,int cond) { - if (e2!=USE_CREG) - error(-1); + use_float(d,e2); #ifdef __APPLE__ if (regs[REG_EAX]==PTRC_REG) clear_ptr_cache_reg(REG_EAX); #endif - printf("\tfldz\n"); - printf("\tfucompp\n"); - printf("\tfnstsw\t%%ax\n"); - printf("\tandb\t$69,%%ah\n"); - printf("\txorb\t$64,%%ah\n"); + int tmp = get_dregister(d); + char *n = register_name(tmp,0); + char *c = register_name(creg,0); + char *sd = d?"d":"s"; + printf("\txorp%s %s,%s\n",sd,n,n); + printf("\tucomis%s %s,%s\n",sd,register_name(ca),s); jcond(label,cond); } int pop_fregister() { if (freg_sp<0) { error(-1); return -1;} - // printf("## fpop: %d\n",freg_sp-1); return freg_stack[--freg_sp]; } -int -emit_dpop(int d) -{ - int xreg; - if ((xreg=pop_fregister())==-1) { - } else if (xreg<= -REG_LVAR_OFFSET) { - code_drlvar(REG_LVAR_OFFSET+xreg,1,freg); - free_lvar(xreg+REG_LVAR_OFFSET); - /* pushed order is reversed. We don't need this for commutable - operator, but it is ok to do this. */ - printf("\tfxch\t%%st(1)\n"); - } +int emit_dpop(int d) +{ + int xreg,reg; + xreg=pop_fregister(); + if (xreg<= -REG_LVAR_OFFSET) { + reg = get_dregister(d); + code_drlvar(REG_LVAR_OFFSET+xreg,d,reg); + free_lvar(REG_LVAR_OFFSET+xreg); + xreg=reg; + } return xreg; } - void emit_dpop_free(int e1,int d) { -} - -void emit_dpush(int type) + free_register(e1); +} + +void +emit_dpush(int d) { - if (freg_sp>=MAX_FPU_STACK) code_save_fstacks(); + int new_reg; + if (!is_float_reg(creg)) error(-1); if (freg_sp>MAX_MAX) error(-1); - freg_stack[freg_sp++]=-1; - // printf("## fpush:%d\n",freg_sp); -} + new_reg = get_dregister(d); /* 絶対に取れる */ + freg_stack[freg_sp++] = freg; /* push するかわりにレジスタを使う */ + creg = freg = new_reg; +} + #endif @@ -3672,7 +3705,14 @@ } } #if FLOAT_CODE - code_save_fstacks(); + for(i=0;i<freg_sp;i++) { + if ((reg=freg_stack[i])>=0) { + code_dassign_lvar( + (freg_stack[i]=new_lvar(SIZE_OF_FLOAT)),reg,0); + freg_stack[i]= freg_stack[i]-REG_LVAR_OFFSET; + free_register(reg); + } + } #endif } @@ -3695,386 +3735,113 @@ } } -#if FLOAT_CODE -void -code_save_fstacks() -{ - /* stacks in fpu are saved in local variable */ - int xreg,sp,uses; - uses = use; use = 0; - sp=freg_sp; - while(sp-->0) { - if ((xreg=freg_stack[sp])==-1) { - code_dassign_lvar( - (freg_stack[sp]=new_lvar(SIZE_OF_DOUBLE)),freg,1); - freg_stack[sp]= freg_stack[sp]-REG_LVAR_OFFSET; - } - } - use = uses; -} -#endif - - #if LONGLONG_CODE -/* 64bit int part */ - -static void -pcond(char *s,int l1) -{ - printf("\tj%s\t_%d\n",s,l1); -} +/* 64bit int part + In INTEL64 mode, basically save as 32bit operatoin + */ int lrexpr(int e1, int e2,int l1, int op,int cond) { - int l2; - code_save_stacks(); - g_expr(e1); - emit_lpush(); - g_expr(e2); - // we are sure %ecx is free - // %ebx is used in Intel Mac - stack_depth -= SIZE_OF_INT * 2; - printf("\tpopl %%ecx\n"); // LSW - printf("\tcmpl %%edx,(%%esp)\n"); // MSW - printf("\tpopl %%edx\n"); - l2 = fwdlabel(); - // cond==0 jump on false condtion ( if(x) => rexpr(.. cond=0 ...) ) - switch(op) { - case LOP+GT: - case LOP+GE: - pcond(code_gt(1),cond?l1:l2); - pcond(code_eq(0),cond?l2:l1); - break; - case LOP+UGT: - case LOP+UGE: - pcond(code_ugt(1),cond?l1:l2); - pcond(code_eq(0), cond?l2:l1); - break; - case LOP+EQ: - pcond(code_eq(0),(cond?l2:l1)); - break; - case LOP+NEQ: - pcond(code_eq(0),(cond?l1:l2)); - break; - default: - error(-1); - } - printf("\tsubl %%eax,%%ecx\n"); - switch(op) { - case LOP+GT: pcond(code_gt(cond), l1); break; - case LOP+GE: pcond(code_ge(cond), l1); break; - case LOP+UGT: pcond(code_ugt(cond), l1); break; - case LOP+UGE: pcond(code_uge(cond), l1); break; - case LOP+EQ: pcond(code_eq(cond),l1); break; - case LOP+NEQ: pcond(code_eq(!cond),l1); break; - } - fwddef(l2); + g_expr(list3(LCMP,cadr(e1),caddr(e1))); + printf("\tj%s\t_%d\n",code_cond(car(e1),cond),l1); return l1; } int emit_lpop() { - return 0; + return emit_pop(0); } void code_lregister(int e2,int reg) { - use_longlong(reg); - if (reg!=REG_L) { - printf("\tmovl %%esi,%s\n",l_eax(reg)); - printf("\tmovl %%edi,%s\n",l_edx(reg)); - } + return code_register(e2,reg); } void code_cmp_lregister(int reg,int label,int cond) { - char *crn; - use_int(reg); - crn = register_name(reg,0); - printf("\tmovl %%esi,%s\n",crn); - printf("\torl %%edi,%s\n",crn); - printf("\ttestl %s,%s\n",crn,crn); + use_longlong(e2); + printf("\tcmpq $0,%s\n",register_name(e2,0)); jcond(label,cond); } void code_cmp_lrgvar(int e1,int e2,int label,int cond) { - char *n,*crn; - use_int(e2); - crn = register_name(e2,0); + use_longlong(reg); #ifdef __APPLE__ int r = get_ptr_cache(ncaddr(e1)); - n = register_name(r,0); - if (cadr(e1)) { - printf("\tmovl %d(%s),%s\n",cadr(e1),n,crn); - printf("\torl %d(%s),%s\n",cadr(e1)+4,n,crn); - } else { - printf("\tmovl (%s),%s\n",n,crn); - printf("\torl 4(%s),%s\n",n,crn); - } + if (cadr(e1)) + printf("\tcmpq $0,%d(%s)\n",cadr(e1),register_name(r,0)); + else + printf("\tcmpq $0,(%s)\n",register_name(r,0)); #else - n = (ncaddr(e1))->nm; - if (cadr(e1)) { - printf("\tmovl %s+%d,%s\n",n,cadr(e1),crn); - printf("\torl %s+%d,%s\n",n,cadr(e1)+4,crn); - } else { - printf("\tmovl %s,%s\n",n,crn); - printf("\torl %s+4,%s\n",n,crn); - } + if (cadr(e1)) + printf("\tcmpq $0,%s+%d\n",(ncaddr(e1))->nm,cadr(e1)); + else + printf("\tcmpq $0,%s\n",(ncaddr(e1))->nm); #endif - printf("\ttestl %s,%s\n",crn,crn); jcond(label,cond); } void code_cmp_lrlvar(int e1,int e2,int label,int cond) { - char *crn; - use_int(e2); - crn = register_name(e2,0); - printf("\tmovl "); lvar(e1); printf(",%s\n",crn); - printf("\torl "); lvar(e1+4); printf(",%s\n",crn); - printf("\ttestl %s,%s\n",crn,crn); + use_longlong(reg); + printf("\tcmpq $0,"); lvar(e1); printf("\n"); jcond(label,cond); } void code_lassign(int e1,int e2) { - char *rn; - // e1 = e2 use_longlong(e2); - rn = register_name(e1,0); -#if ENDIAN_L==0 - printf("\tmovl %s,(%s)\n",l_eax(e2),rn); - printf("\tmovl %s,4(%s)\n",l_edx(e2),rn); -#endif + use_longlong(creg); + printf("\tmovq %s,(%s)\n",register_name(creg,0),register_name(e2,0)); } void code_lassign_gvar(int e1,int e2) { - char *n; - use_longlong(e2); -#if ENDIAN_L==0 -#ifdef __APPLE__ - int r = get_ptr_cache(ncaddr(e1)); - n = register_name(r,0); - if (cadr(e1)) { - printf("\tmovl %s,%d(%s)\n",l_eax(e2),cadr(e1),n); - printf("\tmovl %s,%d(%s)\n",l_edx(e2),cadr(e1)+4,n); - } else { - printf("\tmovl %s,(%s)\n",l_eax(e2),n); - printf("\tmovl %s,4(%s)\n",l_edx(e2),n); - } -#else - n = (ncaddr(e1))->nm; - if (cadr(e1)) { - printf("\tmovl %s,%s+%d\n",l_eax(e2),n,cadr(e1)); - printf("\tmovl %s,%s+%d\n",l_edx(e2),n,cadr(e1)+4); - } else { - printf("\tmovl %s,%s\n",l_eax(e2),n); - printf("\tmovl %s,%s+4\n",l_edx(e2),n); - } -#endif -#endif + code_assign_gvar(e1,e2,SIZE_OF_LONGLONG); } void code_lassign_lvar(int e1,int e2) { - use_longlong(e2); -#if ENDIAN_L==0 - printf("\tmovl %s,",l_eax(e2)); lvar(e1); printf("\n"); - printf("\tmovl %s,",l_edx(e2)); lvar(e1+4); printf("\n"); -#endif + code_assign_lvar(e1,e2,SIZE_OF_LONGLONG) } void code_lassign_lregister(int e2,int reg) { - // e2 = reg - use_longlong(reg); - if (e2!=reg) { - printf("\tmovl %s,%s\n",l_eax(reg),l_eax(e2)); - printf("\tmovl %s,%s\n",l_edx(reg),l_edx(e2)); - } + code_lassign_lregister(e2,SIZE_OF_LONGLONG,reg) } void code_lconst(int e1,int creg) { use_longlong(creg); -#if ENDIAN_L==0 - printf("\tmovl $%d,%s\n",code_l1(lcadr(e1)),l_eax(creg)); - printf("\tmovl $%d,%s\n",code_l2(lcadr(e1)),l_edx(creg)); -#endif + printf("\tmovq $%ld,%s\n",lcadr(e1),l_eax(creg)); } void code_lneg(int e1) { use_longlong(e1); - printf("\tnegl %s\n",l_eax(e1)); - printf("\tadcl $0,%s\n",l_edx(e1)); - printf("\tnegl %s\n",l_edx(e1)); + printf("\tnegq %s\n",register_name(e1,0)); } void code_lrgvar(int e1,int e2) { - char *n; - use_longlong(e2); -#if ENDIAN_L==0 -#ifdef __APPLE__ - int r = get_ptr_cache(ncaddr(e1)); - n = register_name(r,0); - if (cadr(e1)) { - printf("\tmovl %d(%s),%s\n",cadr(e1),n,l_eax(e2)); - printf("\tmovl %d(%s),%s\n",cadr(e1)+4,n,l_edx(e2)); - } else { - printf("\tmovl (%s),%s\n",n,l_eax(e2)); - printf("\tmovl 4(%s),%s\n",n,l_edx(e2)); - } -#else - n = (ncaddr(e1))->nm; - if (cadr(e1)) { - printf("\tmovl %s+%d,%s\n",n,cadr(e1),l_eax(e2)); - printf("\tmovl %s+%d,%s\n",n,cadr(e1)+4,l_edx(e2)); - } else { - printf("\tmovl %s,%s\n",n,l_eax(e2)); - printf("\tmovl %s+4,%s\n",n,l_edx(e2)); - } -#endif -#endif + code_crgvar(e1,e2,0,SIZE_OF_LONGLONG); } void code_lrlvar(int e1,int e2) { - use_longlong(e2); -#if ENDIAN_L==0 - printf("\tmovl "); lvar(e1); printf(",%s\n",l_eax(e2)); - printf("\tmovl "); lvar(e1+4); printf(",%s\n",l_edx(e2)); -#endif -} - -#define check_lreg(reg) if (reg==REG_L) code_lassign_lregister(reg,REG_LCREG) + code_crlvar(e1,e2,0,SIZE_OF_LONGLONG); +} void ltosop(int op,int reg,int e2) { - char *opl,*oph,*call; - int lb; - - // e2 (operand) is on the top of the stack - use_longlong(reg); - opl = 0; call=0; - stack_depth -= SIZE_OF_INT * 2; - - 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"); - check_lreg(reg); - return; - case LRSHIFT: - printf("\tmovl %%ecx,4(%%esp)\n"); - printf("\tpopl %%ecx\n"); - printf("\tshrdl %%edx,%%eax\n"); - printf("\tsarl %%cl,%%edx\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"); - check_lreg(reg); - return; - case LURSHIFT: - printf("\tmovl %%ecx,4(%%esp)\n"); - printf("\tpopl %%ecx\n"); - printf("\tshrdl %%edx,%%eax\n"); - printf("\tshrl %%cl,%%edx\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"); - check_lreg(reg); - return; - } - switch(op) { - case LADD: opl="addl";oph="adcl"; break; - case LSUB: opl="subl";oph="sbbl"; 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"); - // 0 saved ecx - // 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"); // %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"); // %edx+%ecx->%edx - printf("\tpopl %%ecx\n"); - // printf("\taddl $8,%%esp\n"); - printf("\tlea 16(%%esp),%%esp\n"); - return; -#ifdef __APPLE__ - case LDIV: call="L___divdi3$stub"; - extern_define("__divdi3",0,FUNCTION,1); break; - case LUDIV: call="L___udivdi3$stub"; - extern_define("__udivdi3",0,FUNCTION,1); break; - case LMOD: call="L___moddi3$stub"; - extern_define("__moddi3",0,FUNCTION,1); break; - case LUMOD: call="L___umoddi3$stub"; - extern_define("__umoddi3",0,FUNCTION,1); break; -#else - case LDIV: call="__divdi3"; break; - case LUDIV: call="__udivdi3"; break; - case LMOD: call="__moddi3"; break; - case LUMOD: call="__umoddi3"; break; -#endif - default: error(-1); - } - if (opl) { - printf("\t%s (%%esp),%%eax\n\t%s 4(%%esp),%%edx\n",opl,oph); - printf("\tlea 8(%%esp),%%esp\n"); - check_lreg(reg); - } else if (call) { -#ifdef __APPLE__ - clear_ptr_cache(); - printf("\tpushl %%edx\n"); - printf("\tpushl %%eax\n"); - printf("\tcall %s\n",call); - printf("\tlea 16(%%esp),%%esp\n"); -#else - printf("\tpushl %%edx\n"); - printf("\tpushl %%eax\n"); - printf("\tcall %s\n",call); - printf("\tlea 16(%%esp),%%esp\n"); -#endif - check_lreg(reg); - } else { - error(-1); - } + tosop1(op,reg,e2,"q"); } int code_lconst_op_p(int op,int e) { @@ -4106,96 +3873,17 @@ } void loprtc(int op,int reg,int e) { - char *opl,*oph=0; - int vl,il; - int vh; - long long l=0; - - if (car(e)==CONST) l = cadr(e); - else if (car(e)==LCONST) l = lcadr(e); - else error(-1); - - vl = code_l1(l); - vh = code_l2(l); - il = l; - - use_longlong(reg); - opl = 0; - - switch(op) { - case LMUL: case LUMUL: - vl=il=ilog(il); - case LLSHIFT: - case LULSHIFT: - if (il==0) return; - else if (il==32) { - code_register(regv_l(reg),regv_h(reg)); - code_const(0,regv_l(reg)); - return; - } else if (il>32) { - code_register(regv_l(reg),regv_h(reg)); - printf("\tsall $%d,%s\n",(int)il-32,l_edx(reg)); - code_const(0,regv_l(reg)); - return; - } - printf("\tshldl $%d,%s,%s\n",vl,l_eax(reg),l_edx(reg)); - printf("\tsall $%d,%s\n",(int)il,l_eax(reg)); return; - case LRSHIFT: - if (il==0) return; - else if (il==32) { - code_register(regv_h(reg),regv_l(reg)); - creg = ireg = REG_EAX; - code_i2ll(reg); - return; - } else if (il>32) { - code_register(regv_h(reg),regv_l(reg)); - printf("\tsarl $%d,%s\n",(int)il-32,l_eax(reg)); - creg = ireg = REG_EAX; - code_i2ll(reg); - return; - } - printf("\tshrdl $%d,%s,%s\n",(int)il,l_edx(reg),l_eax(reg)); - printf("\tsarl $%d,%s\n",(int)il,l_edx(reg)); - return; - case LUDIV: - il=ilog(il); - case LURSHIFT: - if (il==0) return; - else if (il==32) { - code_register(regv_h(reg),regv_l(reg)); - code_const(0,regv_h(reg)); - return; - } else if (il>32) { - if (il>64) error(-1); - code_register(regv_h(reg),regv_l(reg)); - printf("\tsarl $%d,%s\n",(int)il-32,l_eax(reg)); - code_const(0,regv_h(reg)); - return; - } - printf("\tshrdl $%d,%s,%s\n",(int)il,l_edx(reg),l_eax(reg)); - printf("\tshrl $%d,%s\n",(int)il,l_edx(reg)); - return; - } - switch(op) { - case LADD: opl="addl";oph="adcl"; break; - case LSUB: opl="subl";oph="sbbl"; break; - case LEOR: opl=oph="xorl"; break; - case LBOR: opl=oph="orl"; break; - case LBAND: opl=oph="andl"; break; - default: error(-1); - } - printf("\t%s $%d,%s\n\t%s $%d,%s\n",opl,vl,l_eax(reg),oph,vh,l_edx(reg)); + oprtc(op,reg,e,SIZE_OF_LONGLONG); } void emit_lpop_free(int e1) { -// printf("\taddl $8,%%esp\n"); + emit_pop_free(e1); } void emit_lpush() { - stack_depth += SIZE_OF_INT * 2; - printf("\tpushl %%edx\n\tpushl %%eax\n"); + emit_push(); } void code_i2ll(int reg) @@ -4206,8 +3894,7 @@ use_longlong(reg0); use_register(creg0,REG_EAX,1); - printf("\tcltd\n"); - check_lreg(reg); + printf("\tcltq\n"); lreg = creg = reg0; } @@ -4218,16 +3905,8 @@ void code_u2ll(int reg) { - int reg0 = USE_CREG; - int creg0 = creg; - - use_longlong(reg0); - use_register(creg0,REG_EAX,1); - - use_longlong(reg0); - printf("\txorl %%edx,%%edx\n"); - check_lreg(reg); - lreg = creg = reg0; + printf("\tshlq $32,%s",regisnter_name(reg,0)); + printf("\tshrq $32,%s",regisnter_name(reg,0)); } void code_u2ull(int reg) @@ -4237,104 +3916,55 @@ void code_ll2i(int reg) { - use_int(reg); - if (REG_EAX!=reg) - printf("\tmovl %%eax,%s\n",register_name(creg,0)); } void code_ll2u(int reg) { - code_ll2i(reg); } void code_ull2i(int reg) { - code_ll2i(reg); } void code_ull2u(int reg) { - code_ll2i(reg); } #if FLOAT_CODE void code_d2ll(int reg) { + char *f = register_name(reg,0); use_longlong(reg); -#if 1 - printf("\tsubl $64, %%esp\n"); - printf("\tfnstcw 34(%%esp)\n"); - printf("\tmovzwl 34(%%esp), %%eax\n"); - printf("\tmovb $12, %%ah\n"); - printf("\tmovw %%ax, 32(%%esp)\n"); - printf("\tfldcw 32(%%esp)\n"); - printf("\tfistpll 52(%%esp)\n"); - printf("\tfldcw 34(%%esp)\n"); - printf("\tmovl 52(%%esp), %%eax\n"); - printf("\tmovl 56(%%esp), %%edx\n"); - printf("\taddl $64, %%esp\n"); -#else - 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"); -#endif - check_lreg(reg); + printf("\tcvttsd2siq %s,%s\n",f,register_name(reg,0)); } void code_d2ull(int reg) { + char *f = register_name(reg,0); use_longlong(reg); -#ifdef __APPLE__ - clear_ptr_cache(); -#endif - printf("\tsubl $16,%%esp\n"); - printf("\tfstpl (%%esp)\n"); -#ifdef __APPLE__ - printf("\tcall L___fixunsdfdi$stub\n"); - extern_define("__fixunsdfdi",0,FUNCTION,1); -#else - printf("\tcall __fixunsdfdi\n"); -#endif - printf("\taddl $16,%%esp\n"); + printf("\tcvttsd2siq %s,%s\n",f,register_name(reg,0)); + use_longlong(reg); } void code_f2ll(int reg) { - code_d2ll(reg); + char *f = register_name(reg,0); + use_longlong(reg); + printf("\tcvttss2siq %s,%s\n",f,register_name(reg,0)); } void code_f2ull(int reg) { + char *f = register_name(reg,0); use_longlong(reg); -#ifdef __APPLE__ - clear_ptr_cache(); -#endif - printf("\tsubl $16,%%esp\n"); - printf("\tfstps (%%esp)\n"); -#ifdef __APPLE__ - printf("\tcall L___fixunssfdi$stub\n"); - extern_define("__fixunssfdi",0,FUNCTION,1); -#else - printf("\tcall __fixunssfdi\n"); -#endif - printf("\taddl $16,%%esp\n"); + printf("\tcvttss2siq %s,%s\n",f,register_name(reg,0)); } void code_ll2d(int reg) { - 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"); + char *f = register_name(reg,0); + use_float(reg,1); + printf("\tcvtsi2sdq %s,%s\n",f,register_name(reg,0)); } void code_ll2f(int reg) @@ -4357,50 +3987,42 @@ void code_lpreinc(int e1,int e2,int reg) { - int dir = caddr(e1); - int creg0; - char *crn; - if (car(e2)==LREGISTER) { - use_longlong(reg); - printf("\taddl $%d,%%esi\n",dir); - printf("\tadcl $%d,%%edi\n",dir>0?0:-1); - if (use && reg!=REG_L) { - code_lregister(REG_L,reg); - } + char *xrn; + if (car(e2)==REGISTER) { + use_int(reg); + printf("\taddq $%d,%s\n",dir,register_name(cadr(e2),0)); + if (use) + printf("\tmovq %s,%s\n",register_name(cadr(e2),0),register_name(reg,0)); return; } g_expr(e2); - crn = register_name(creg0=creg,0); - printf("\taddl $%d,(%s)\n",dir,crn); - printf("\tadcl $%d,4(%s)\n",dir>0?0:-1,crn); - use_longlong(reg); - lload(creg0,0,reg); + xrn = register_name(creg,0); + use_int(reg); + printf("\taddq $%d,(%s)\n",dir,xrn) +; + if (use) + printf("\t%s (%s),%s\n",cload(sign,SIZE_OF_LONGLONG),xrn,register_name(reg,0)); } void code_lpostinc(int e1,int e2,int reg) { - int dir = caddr(e1); - int creg0; - char *crn; - if (car(e2)==LREGISTER) { - use_longlong(reg); - if (use && reg!=REG_L) { - code_lregister(REG_L,reg); - } - printf("\taddl $%d,%%esi\n",dir); - printf("\tadcl $%d,%%edi\n",dir>0?0:-1); + char *xrn; + if (car(e2)==REGISTER) { + use_int(reg); + if (use) + printf("\tmovq %s,%s\n",register_name(cadr(e2),0),register_name(reg,0)); + printf("\taddq $%d,%s\n",dir,register_name(cadr(e2),0)); + return; } g_expr(e2); - crn = register_name(creg0=creg,0); - printf("\taddl $%d,(%s)\n",dir,crn); - printf("\tadcl $%d,4(%s)\n",dir>0?0:-1,crn); - if (use) { - use_longlong(reg); - lload(creg0,0,reg); - printf("\taddl $%d,%s\n",-dir,l_eax(reg)); - printf("\tadcl $%d,%s\n",-dir>0?0:-1,l_edx(reg)); - } + emit_push(); + xrn = register_name((e2=emit_pop(0)),0); + use_int(reg); + if (use) + printf("\t%s (%s),%s\n",cload(sign,SIZE_OF_LONGLONG),xrn,register_name(reg,0)); + printf("\taddq $%d,(%s)\n",dir,xrn) + emit_pop_free(e2); } void code_lassop(int op,int reg)