Mercurial > hg > CbC > old > device
changeset 735:31e5641bd7c7
i64 continue...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 06 Nov 2010 18:43:29 +0900 |
parents | d2d6b1ef2cb4 |
children | d7a976af188a |
files | mc-code-i64.c |
diffstat | 1 files changed, 210 insertions(+), 72 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-code-i64.c Fri Nov 05 22:36:39 2010 +0900 +++ b/mc-code-i64.c Sat Nov 06 18:43:29 2010 +0900 @@ -3240,34 +3240,63 @@ void code_d2u(int reg) { + int f = reg; use_int(reg); - printf("\tlea -%d(%%esp),%%esp\n",SIZE_OF_INT*3); - printf("\tfnstcw (%%esp)\n"); - printf("\tmovl (%%esp), %s\n",register_name(reg,0)); - printf("\tmovb $12, 1(%%esp)\n"); - printf("\tfldcw (%%esp)\n"); - printf("\tmovl %s, (%%esp)\n",register_name(reg,0)); - printf("\tfistpll %d(%%esp)\n",SIZE_OF_INT); - printf("\tfldcw (%%esp)\n"); - printf("\tmovl %d(%%esp),%s\n",SIZE_OF_INT,register_name(reg,0)); - printf("\tlea %d(%%esp),%%esp\n",SIZE_OF_INT*3); -} - -void code_u2d(int reg) + printf("\tcvttsd2siq %s,%s\n",register_name(f,0),register_name(reg,0)); +} + +void code_u2d1(int reg,int db) { - printf("\tpushl %s\n",register_name(creg,0)); - printf("\tpushl %s\n",register_name(creg,0)); - printf("\tmovl $0, %d(%%esp)\n",SIZE_OF_INT); - printf("\tfildll (%%esp)\n"); - printf("\tlea %d(%%esp),%%esp\n",SIZE_OF_INT*2); + int i = reg; + char *u = get_regsiter_name(i); + int tmp = get_data_register(); + char *t = get_regsiter_name(tmp); + use_int(reg); + char *d = get_regsiter_name(reg); + int td = get_dregsiter(); + char *dbs = db?"d":"s"; + printf(" cmpq $0, %s\n",u); + printf(" js f1\n"); + printf(" cvtsi2%sdq %s,%s\n",dbs,u,d); + printf(" jmp f2\n"); + printf("1:\n"); + printf(" movq %s, %s\n",u,t); + printf(" shrq %s\n",get_register_name(t)); + printf(" andl $1, %s\n",get_register_name(u,SIZE_OF_INT)); + printf(" orq %s, %s\n",t,u); + printf(" cvtsi2%sdq %s, %s\n",dbs,u,d); + printf(" movap%s %s, %s\n",db,d,get_register_name(td,0)); + printf(" adds%s %s, %s\n",db,d,get_register_name(td,0)); + printf("2:\n"); + free_register(tmp); + free_register(td); +} +void code_u2d1(int reg) { + code_u2d1(reg,1); } void code_d2f(int reg) { } void code_f2d(int reg) { } -void code_f2i(int reg) { code_d2i(reg); } -void code_f2u(int reg) { code_d2u(reg); } -void code_i2f(int reg) { code_i2d(reg); } -void code_u2f(int reg) { code_u2d(reg); } +void code_f2i(int reg) { + int f = reg; + use_int(reg); + printf("\tcvttss2si %s,%s\n",register_name(f,0),register_name(creg,0)); +} + +void code_f2u(int reg) { + int f = reg; + use_int(reg); + printf("\tcvttss2siq %s,%s\n",register_name(f,0),register_name(reg,0)); +} + +void code_i2f(int reg) { + int c = reg; + use_double(reg); + printf("\tcvtsi2ss %s,%s\n",register_name(c,0),register_name(creg,0)); +} +void code_u2f(int reg) { + code_u2d1(reg,0); +} void code_drgvar(int e2,int d,int freg) { @@ -3288,23 +3317,29 @@ void code_drlvar(int e2,int d,int freg) { - printf("\t%s ",fload(d)); lvar(e2); printf("\n"); + printf("\t%s ",fload(d)); lvar(e2); printf(",%s\n", register_name(freg,0)); } void code_cmp_drgvar(int e2,int reg,int d,int label,int cond) { + char *db = d?"d":"s"; + char *f = get_register_name(reg,0); + int t = get_dregister(); #ifdef __APPLE__ int r = get_ptr_cache(ncaddr(e2)); if (cadr(e2)) - printf("\tfcomp %d(%s)\n",cadr(e2),register_name(r,0)); + printf("\tmovs%s %d(%s),%s\n",db,cadr(e2),register_name(r,0),f); else - printf("\tfcomp (%s)\n",register_name(r,0)); + printf("\tmovs%s (%s),%s\n",db,register_name(r,0),f); #else if (cadr(e2)) - printf("\tfcomp %s+%d\n",(ncaddr(e2))->nm,cadr(e2)); + printf("\tmovs%s %s+%d,%s\n",db,(ncaddr(e2))->nm,cadr(e2),f); else - printf("\tfcomp %s\n",(ncaddr(e2))->nm); + printf("\tmovs%s %s,%s\n",db,(ncaddr(e2))->nm,f); #endif + printf("\txorp%s %s,%s\n",db,f,register_name(t,0)); + printf("\tucomis%s %s,%s\n",db,f,get_register_name(t,0)); + free_register(t); jcond(label,cond); } @@ -3314,68 +3349,171 @@ jcond(label,cond); } -void dtosop(int op,int reg,int e1) -{ +dtosop(int op,int reg,int oreg) +{ + char *opn=""; + char *frn; + char *grn; + int ox = -1; + + use_float(1,reg); + if (!(oreg<= -REG_LVAR_OFFSET)) { + grn=fregister_name(oreg); + } + frn=fregister_name(reg); switch(op) { - case FADD: - case DADD: printf("\tfaddp %%st,%%st(1)\n"); break; - case FSUB: - case DSUB: printf("\tfsubp %%st,%%st(1)\n"); break; - case FDIV: - case DDIV: printf("\tfdivp %%st,%%st(1)\n"); break; - case FMUL: - case DMUL: printf("\tfmulp %%st,%%st(1)\n"); break; + case FADD: opn="addss"; break; + case DADD: opn="addsd"; break; + case FSUB: opn="subss"; break; + case DSUB: opn="subsd"; break; + case FDIV: opn="divss"; break; + case DDIV: opn="divsd"; break; + case FMUL: opn="mulss"; break; + case DMUL: opn="mulsd"; break; case FCMP: + if (oreg<= -REG_LVAR_OFFSET) { + printf("\tucomiss "); lvar(oreg); + printf(",%s\n",frn); + } else { + printf("\tucomiss %s,%s\n",frn,grn); + } + if (ox!=-1) free_register(ox); + return; case DCMP: - printf("\tfucompp\n"); - printf("\tfnstsw\t%%ax\n"); -#ifdef __APPLE__ - if (regs[REG_EAX]==PTRC_REG) - clear_ptr_cache_reg(REG_EAX); -#endif - break; + if (oreg<= -REG_LVAR_OFFSET) { + printf("\tucomisd "); lvar(oreg); + printf(",%s\n",frn); + } else { + printf("\tucomisd %s,%s\n",frn,grn); + } + if (ox!=-1) free_register(ox); + return; + case DCMPGE: + case FCMPGE: + default: + error(-1); return; } -} + if (oreg<= -REG_LVAR_OFFSET) { + printf("\t%s ",opn); + lvar(oreg); + printf(",%s\n",frn); + } else { + printf("\t%s %s,%s\n",opn,frn,grn); + } + if (ox!=-1) free_register(ox); +} + void code_dassop(int op,int reg,int d) { - /* we have lvalue in creg, applied floating value is in %st(0) */ - emit_dpop(d); /* do nothing for 387 */ - printf("\t%s (%s)\n",fload(d),register_name(creg,0)); - dtosop(op,reg,0); - printf("\t%s (%s)\n",fstore(d),register_name(creg,0)); + /* we have lvalue in creg, applied floating value is in freg */ + // (*creg) op = pop() + int xreg=emit_dpop(d); + char *crn; + char *frn; + + crn=register_name(ireg,0); + use_float(d,reg); + frn =register_name(reg,0); + + printf("\t%s %s,0(%s)\n",fload(d),frn,crn); + dtosop(op,reg,xreg); + printf("\t%s %s,0(%s)\n",fstore(d),frn,crn); + emit_dpop_free(xreg,d); } void code_register_dassop(int reg,int op,int d) { - error(-1); + // reg op= dpop() + int xreg=emit_dpop(d); + dtosop(op,reg,xreg); + emit_dpop_free(xreg,d); +} + +#define fregister_name(a) register_name(a,0) + +static int +code_dload_1(int d) +{ + int r,g; + char *drn,*grn; + // load 1 + float_one_lib_used=1; + r = get_ptr_cache(&float_one); + drn=register_name(r); + grn=fregister_name(g=get_dregister(d)); + printf("\tmovs%s %s,0(%s)\n",d?"d":"s",grn,drn); + return g; } void -code_dpreinc(int e1,int e2,int d,int freg) { - g_expr(e2); - printf("\t%s (%s)\n",fload(d),register_name(creg,0)); - printf("\tfld1\n"); - if (caddr(e1)>0) - printf("\tfaddp %%st,%%st(1)\n"); - else - printf("\tfsubrp %%st,%%st(1)\n"); - printf("\t%s (%s)\n",fstore(d),register_name(creg,0)); +code_dpreinc(int e1,int e2,int d,int reg) { + char *frn,*crn,*grn; + int g; + char *ops = (caddr(e1)>0)?(d?"addsd":"addss"):(d?"subsd":"addss"); + + if (car(e2)==DREGISTER||car(e2)==FREGISTER) { + crn=register_name(cadr(e2)); + grn = fregister_name(g = code_dload_1(d)); + if (reg==USE_CREG) { + reg=get_dregister(d); if (!reg) error(-1); + set_freg(reg,0); + } + frn=fregister_name(reg); + printf("\t%s %s,%s,%s\n",ops,crn,crn,grn); + if (use && reg!=cadr(e2)) + printf("\movap%s %s,%s\n",d?"d":"s",frn,crn); + } else { + g_expr(e2); + if (!is_int_reg(creg)) error(-1); + crn=register_name(ireg); + if (reg==USE_CREG) { + reg=get_dregister(d); if (!reg) error(-1); + set_freg(reg,0); + } + frn=fregister_name(reg); + grn = fregister_name(g = code_dload_1(d)); + printf("\t%s %s,0(%s)\n",fload(d),frn,crn); + printf("\t%s %s,%s,%s\n",ops,frn,frn,grn); + printf("\t%s %s,0(%s)\n",fstore(d),frn,crn); + } + free_register(g); } void -code_dpostinc(int e1,int e2,int d,int freg) { - g_expr(e2); - printf("\t%s (%s)\n",fload(d),register_name(creg,0)); - if (use) - printf("\t%s (%s)\n",fload(d),register_name(creg,0)); - printf("\tfld1\n"); - if (caddr(e1)>0) - printf("\tfaddp %%st,%%st(1)\n"); - else - printf("\tfsubrp %%st,%%st(1)\n"); - printf("\t%s (%s)\n",(use?fstore_u(d):fstore(d)),register_name(creg,0)); -} +code_dpostinc(int e1,int e2,int d,int reg) { + char *frn,*crn,*grn; + int g; + char *ops = (caddr(e1)>0)?(d?"addsd":"addss"):(d?"subsd":"addss"); + + if (car(e2)==DREGISTER||car(e2)==FREGISTER) { + crn=register_name(cadr(e2)); + grn = fregister_name(g = code_dload_1(d)); + if (reg==USE_CREG) { + reg=get_dregister(d); if (!reg) error(-1); + set_freg(reg,0); + } + frn=fregister_name(reg); + if (use && reg!=cadr(e2)) + printf("\tmovap%s %s,%s\n",d?"d":"s",frn,crn); + printf("\t%s %s,%s,%s\n",ops,crn,crn,grn); + } else { + g_expr(e2); + if (!is_int_reg(creg)) error(-1); + crn=register_name(ireg); + if (reg==USE_CREG) { + reg=get_dregister(d); if (!reg) error(-1); + set_freg(reg,0); + } + frn=fregister_name(reg); + grn = fregister_name(g = code_dload_1(d)); + printf("\t%s %s,0(%s)\n",fload(d),frn,crn); + printf("\t%s %s,%s,%s\n",ops,grn,frn,grn); + printf("\t%s %s,0(%s)\n",fstore(d),grn,crn); + } + free_register(g); +} + #define COND_BRANCH 1 #define COND_VALUE 2