Mercurial > hg > CbC > old > device
changeset 381:5a9a27fadb9b
ARM continue...
author | kono |
---|---|
date | Mon, 19 Jul 2004 15:16:26 +0900 |
parents | c9ae2ea267c2 |
children | 832e1f6bba82 |
files | Changes mc-code-arm.c |
diffstat | 2 files changed, 455 insertions(+), 550 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Sun Jul 18 20:47:25 2004 +0900 +++ b/Changes Mon Jul 19 15:16:26 2004 +0900 @@ -5878,3 +5878,4 @@ Sun Jul 18 20:45:48 JST 2004 なかなか終らないね。GBAとLinux Zaurus と両方だからな。 +(やっぱ ARM に手をつけたのは失敗でした)
--- a/mc-code-arm.c Sun Jul 18 20:47:25 2004 +0900 +++ b/mc-code-arm.c Mon Jul 19 15:16:26 2004 +0900 @@ -220,6 +220,9 @@ #if FLOAT_CODE + +#define dsuffix(d) (d?'d':'s') + #define use_float(d,reg) if (reg==USE_CREG) arch_mode&UseFPP?use_float0():(reg=d?use_double0():use_float0()) static int use_float0() { @@ -3732,18 +3735,18 @@ } void -code_d2i(int reg) +code_d2i0(int reg,int d) { int lreg; if (!(arch_mode&UseFPP)) { - use_float(1,reg); + use_float(d,reg); code_save_stacks(); clear_ptr_cache(); - set_dreg(DREGISTER_OPERAND,1); - extern_conv("__fixdfsi"); + set_dreg(d?DREGISTER_OPERAND:FREGISTER_OPERAND,1); + extern_conv(d?"__fixdfsi":"__fixsfsi"); set_ireg(RET_REGISTER,0); } else { - use_float(1,reg); + use_float(d,reg); lreg = get_register(); printf("\tfixz\t%s, %s\n",register_name(lreg),register_name(reg)); set_ireg(lreg,0); @@ -3752,27 +3755,28 @@ } void -code_i2d(int reg) +code_i2d0(int reg,int d) { int lreg; if (!(arch_mode&UseFPP)) { set_ireg(REGISTER_OPERAND,1); code_save_stacks(); clear_ptr_cache(); - extern_conv("__floatsidf"); - set_dreg(RET_DREGISTER,0); - use_float(1,reg); + extern_conv(d?"__floatsidf":"__floatsisf"); + set_dreg(d?RET_DREGISTER:RET_FREGISTER,0); + use_float(d,reg); } else { use_int(reg); lreg = get_dregister(1); - printf("\tfltd\t%s, %s\n",register_name(lreg),register_name(reg)); + printf("\tflt%c\t%s, %s\n",dsuffix(d), + register_name(lreg),register_name(reg)); set_dreg(lreg,0); } return; } void -code_d2u(int reg) +code_d2u0(int reg,int d) { int lreg,label,disp,reg; char *lrn,*frn,*crn; @@ -3780,11 +3784,12 @@ use_float(1,reg); code_save_stacks(); clear_ptr_cache(); - set_dreg(DREGISTER_OPERAND,1); - extern_conv("__fixunsdfsi"); + set_dreg(d?DREGISTER_OPERAND:FREGISTER_OPERAND,1); + extern_conv(d?"__fixunsdfsi":"__fixunssfsi"); set_ireg(RET_REGISTER,0); } else { // u = (d>2.1e9)?((int)(d-2.1e9)^2147483648):(int)d + if (!d) printf("\tmvfd %s, %s\n",frn,frn); emit_dpush(1); code_dconst(dlist2(DCONST,2.147483648e9),USE_CREG,1); lrn = register_name(lreg = emit_dpop()); @@ -3806,7 +3811,7 @@ } void -code_u2d(int reg) +code_u2d0(int reg,int d) { int tmp; if (!(arch_mode&UseFPP)) { @@ -3815,17 +3820,26 @@ code_assign_lvar(tmp,REGISTER_OPERAND,0); code_save_stacks(); clear_ptr_cache(); - extern_conv("__floatsidf"); + extern_conv(d?"__floatsidf":"__floatsisf"); code_rlvar(tmp,REGISTER_OPERAND); printf("\tcmp\t%s, #0\n",register_name(REGISTER_OPERAND)); printf("\tbge\t1f\n"); - code_double_lib_c("__adddf3",RET_DREGISTER,RET_DREGISTER,4.29496729600000000000e9); + if (d) + code_double_lib_c("__adddf3",RET_DREGISTER,RET_DREGISTER,4.29496729600000000000e9); + else + code_double_lib_c("__addsf3",RET_FREGISTER,RET_FREGISTER,4.29496729600000000000e9); printf("1:\n"); - set_dreg(RET_DREGISTER,0); + set_dreg(d?RET_DREGISTER:RET_FREGISTER,0); if (reg!=USE_CREG) { - use_float(1,reg); - if (reg!=RET_DREGISTER) { - lmove(reg,RET_DREGISTER); + use_float(d,reg); + if (d) { + if (reg!=RET_DREGISTER) { + lmove(reg,RET_DREGISTER); + } + } else { + if (reg!=RET_FREGISTER) { + code_register(reg,RET_FREGISTER); + } } } free_lvar(tmp); @@ -3842,6 +3856,8 @@ lrn = register_name(lreg = emit_dpop()); printf("\tadfd\t%s, %s, %s\n",frn,frn,lrn); printf("1:\n"); + if (!d) + printf("\tmvfs\t%s, %s\n",frn,frn); emit_dpop_free(lreg); } return; @@ -3882,181 +3898,107 @@ } void +code_d2i(int reg) { + code_d2i0(reg,1); +} + +void +code_d2u(int reg) { + code_d2u0(reg,1); +} + +void code_f2i(int reg) { -#if 0 - int tmp=new_lvar(SIZE_OF_INT); - use_int(reg); - printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg), - register_name(freg),register_name(ireg)); - code_dassign_lvar(tmp,freg,1); - code_rlvar(tmp,reg); - free_lvar(tmp); -#else - use_int(reg); - printf("\ttrunc.w.s %s,%s,%s\n",fregister_name(freg), - fregister_name(freg),register_name(ireg)); - printf("\tmfc1 %s,%s\n",register_name(reg),fregister_name(freg)); -#endif + code_d2i0(reg,0); } void code_f2u(int reg) { - int freg0 = freg; - int freg1 = get_dregister(0); - int freg2 = get_dregister(0); - int ireg1 = get_register(); - char *fr0 = fregister_name(freg0); - char *fr1 = fregister_name(freg1); - char *fr2 = fregister_name(freg2); - char *r1 = register_name(ireg1); - char *r0; - int lb1,lb2; - - use_int(reg); - r0 = register_name(ireg); - - printf("\tli.s %s,2.14748364800000000000e9\n",fr1); - printf("\tc.le.s %s,%s\n",fr1,fr0); - printf("\tbc1t $L_%d\n",lb1=fwdlabel()); - printf("\ttrunc.w.s %s,%s,%s\n",fr2,fr0,r0); - printf("\tmfc1 %s,%s\n",r0,fr2); - printf("\tj $L_%d\n",lb2=fwdlabel()); - printf("\t.p2align 2\n"); - fwddef(lb1); - printf("\tsub.s %s,%s,%s\n",fr0,fr0,fr1); - printf("\tli %s,-2147483648 # 0x80000000\n", - r0); - printf("\ttrunc.w.s %s,%s,%s\n",fr1,fr0,r1); - printf("\tmfc1 %s,%s\n",r1,fr1); - printf("\tor %s,%s,%s\n",r0,r1,r0); - fwddef(lb2); - free_register(freg1); - free_register(freg2); - free_register(ireg1); + code_d2u0(reg,0); +} + +void +code_i2d(int reg) { + code_i2f0(reg,1); } void code_i2f(int reg) { - int n = new_lvar(SIZE_OF_FLOAT); - use_int(reg); - code_assign_lvar(n,reg,0); - reg = USE_CREG; - use_float(0,reg); - code_drlvar(n,0,reg); - printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg)); - free_lvar(n); + code_i2f0(reg,0); +} + +void +code_u2d(int reg) { + code_u2f0(reg,1); } void code_u2f(int reg) { - // int n = new_lvar(SIZE_OF_FLOAT); - int /*reg0,*/reg1; - int lb1,lb2; - char *frn,*r0,*r1; - // code_assign_lvar(n,ireg,0); - printf("\tbltz %s,$L_%d\n",r0=register_name(ireg),lb1=fwdlabel()); - use_float(0,reg); - // code_drlvar(n,0,reg); - // r0= register_name(reg0 = get_register()); - r1= register_name(reg1 = get_register()); - frn = fregister_name(reg); - printf("\tmtc1 %s,%s\n",r0,frn); - printf("\tcvt.s.w %s,%s\n",frn,frn); - printf("\tj $L_%d\n",lb2=fwdlabel()); - printf("\t.p2align 2\n"); - fwddef(lb1); - printf("\tandi %s,%s,0x1\n",r1,r0); - printf("\tsrl %s,%s,1\n",r0,r0); - printf("\tor %s,%s,%s\n",r1,r1,r0); - printf("\tmtc1 %s,%s\n",r1,frn); - printf("\tcvt.s.w %s,%s\n",frn,frn); - printf("\tadd.s %s,%s,%s\n",frn,frn,frn); - fwddef(lb2); - // free_register(reg0); - free_register(reg1); -} + code_u2f0(reg,0); +} + +static char * +fload(int d) { return d?"ldfd":"ldfs"; } + +static char * +fstore(int d) { return d?"stfd":"stfs"; } void code_drgvar(int e2,int d,int freg) { - if (d) { - code_lrgvar(e2,freg); - set_double(freg); - return; - } - use_float(d,freg); - code_ldf("l.s",fregister_name(freg),cadr(e2), - get_ptr_cache((NMTBL*)caddr(e2))); + if (!(arch_mode&UseFPP)) { + if (d) { + code_lrgvar(e2,freg); + set_double(freg); + return; + } else { + code_rgvar(e2,freg); + set_float(freg); + return; + } + } else { + use_float(d,freg); + code_ldf(fload(d),fregister_name(freg),cadr(e2), + get_ptr_cache((NMTBL*)caddr(e2))); + } } void code_drlvar(int e2,int d,int freg) { - if (d) { - code_lrlvar(e2,freg); - set_double(freg); - return; - } - use_float(d,freg); - lvar_intro(e2); - printf("\tl.s %s,",fregister_name(freg)); lvar(e2,""); + if (!(arch_mode&UseFPP)) { + if (d) { + code_lrlvar(e2,freg); + set_double(freg); + return; + } else { + code_rlvar(e2,freg); + set_float(freg); + return; + } + } else { + use_float(d,freg); + lvar_intro(e2); + printf("\t%s\t%s,",fload(d),fregister_name(freg)); + lvar(e2,d?"@ double":"@ float"); + } } void code_cmp_drgvar(int e2,int reg,int d,int label,int cond) { - char *frn,*fr1; - int g,cmpreg; use_float(d,reg); - - if (d) { - code_save_stacks(); - set_dreg(RET_DREGISTER,0); - code_drgvar(e2,d,RET_DREGISTER); - clear_ptr_cache(); - printf("\tmove $6,$0\n"); - printf("\tmove $7,$0\n"); - extern_conv("dcmp"); - cmpreg = 2; - } else { - code_drgvar(e2,d,USE_CREG); - frn = fregister_name(freg); - fr1=fregister_name(g = get_dregister(0)); - printf("\tmtc1 $0,%s\n",fr1); - printf("\tfc.eq.s %s,%s\n",frn,fr1); - cmpreg = CMP_C1T; - free_register(g); - } - jcond(label,cond); + code_drgvar(e2,d,reg); + code_cmp_dregister(reg,d,label,cond); } void code_cmp_drlvar(int e2,int reg,int d,int label,int cond) { - char *frn,*fr1; - int g,cmpreg; use_float(d,reg); - - if (d) { - code_save_stacks(); - set_dreg(RET_DREGISTER,0); - code_drlvar(e2,d,RET_DREGISTER); - clear_ptr_cache(); - printf("\tmove $6,$0\n"); - printf("\tmove $7,$0\n"); - extern_conv("dcmp"); - cmpreg = 2; - } else { - code_drlvar(e2,d,USE_CREG); - frn = fregister_name(freg); - fr1=fregister_name(g = get_dregister(0)); - printf("\tmtc1 $0,%s\n",fr1); - printf("\tfc.eq.s %s,%s\n",frn,fr1); - cmpreg = CMP_C1T; - free_register(g); - } - jcond(label,cond); + code_drlvar(e2,d,reg); + code_cmp_dregister(reg,d,label,cond); } static void @@ -4088,7 +4030,41 @@ void -dtosop(int op,int reg,int e1) +dtosop_d(int op,int reg,int e1) +{ + char *opn=""; + char *opc=""; + char *grn,*frn; + int d; + int cmp=0; + int reg0=reg; + + d=(op<FOP); + use_float(d,reg); + switch(op) { + case DADD: opc="__adddf3"; break; + case DSUB: opc="__subdf3"; break; + case DDIV: opc="__divdf3"; break; + case DMUL: opc="__muldf3"; break; + case DCMPGE: opc="__gedf2"; break; + case DCMP: opc="__gtdf2"; break; + case FADD: opc="__addsf3"; break; + case FSUB: opc="__subsf3"; break; + case FDIV: opc="__divsf3"; break; + case FMUL: opc="__mulsf3"; break; + case FCMPGE: opc="__gesf2"; break; + case FCMP: opc="__gtsf2"; break; + default: + error(-1); return; + } + if (d) + code_double_lib(opc,reg0==USE_CREG?RET_DREGISTER:reg,reg,e1); + else + code_float_lib(opc,reg0==USE_CREG?RET_FREGISTER:reg,reg,e1); +} + +void +dtosop_f(int op,int reg,int e1) { char *opn=""; char *opc=""; @@ -4099,43 +4075,42 @@ d=(op<FOP); use_float(d,reg); - if (d) { - switch(op) { - case DADD: opc="dpadd"; break; - case DSUB: opc="dpsub"; break; - case DDIV: opc="dpdiv"; break; - case DMUL: opc="dpmul"; break; - case DCMPGE: - case DCMP: opc="dpcmp"; break; - default: - error(-1); return; - } - code_double_lib(opc,reg0==USE_CREG?RET_DREGISTER:reg,reg,e1); + switch(op) { + case DADD: opn="adfd"; break; + case DSUB: opn="sufd"; break; + case DDIV: opn="fdvd"; break; + case DMUL: opn="fmld"; break; + case DCMPGE: + case DCMP: opn="cmfe"; cmp=1; break; + case FADD: opn="adfs"; break; + case FSUB: opn="sufs"; break; + case FDIV: opn="fdvs"; break; + case FMUL: opn="fmls"; break; + case FCMPGE: + case FCMP: opn="cmfe"; cmp=1; break; + default: + error(-1); return; + } + grn = fregister_name(e1); + frn = fregister_name(reg); + if (cmp) { + printf("\t%s\t%s, %s\n",opn,frn,grn); } else { - switch(op) { - case FADD: opn="add.s"; break; - case FSUB: opn="sub.s"; break; - case FDIV: opn="div.s"; break; - case FMUL: opn="mul.s"; break; - case FCMP: opn="c.lt.s"; cmp=1; break; - case FCMPGE: opn="c.le.s"; cmp=1; break; - case FCMPEQ: opn="c.eq.s"; cmp=1; break; - default: - error(-1); return; - } - grn = fregister_name(e1); - frn = fregister_name(reg); - if (cmp) { - cmpreg=CMP_C1T; - printf("\t%s %s,%s\n",opn,frn,grn); - } else { - printf("\t%s %s,%s,%s\n",opn,frn,frn,grn); - } + printf("\t%s\t%s, %s, %s\n",opn,frn,frn,grn); } } void -code_dassop(int op,int reg,int d) { +dtosop(int op,int reg,int e1) +{ + if (!(arch_mode&UseFPP)) + dtosop_d(op,reg,e1); + else + dtosop_f(op,reg,e1); +} + +void +code_dassop_d(int op,int reg,int d) { /* we have lvalue in creg, applied floating value is in freg */ // (*creg) op = pop() int xreg; @@ -4144,56 +4119,101 @@ int edx,edx0=-1; int reg0=reg; - if (!d) { - xreg=emit_dpop(d); - crn=register_name(ireg); - use_float(d,reg); - frn =fregister_name(reg); - - printf("\tl.s %s,0(%s)\n",frn,crn); - dtosop(op,reg,xreg); - printf("\ts.s %s,0(%s)\n",frn,crn); - emit_dpop_free(xreg,d); + xreg = d?emit_pop(0):emit_lpop(0); /* pop e3 value */ + if (!is_int_reg(creg)) error(-1); + edx = ireg; + emit_push(); + use_float(d,reg); + if (d) { + if (regv_l(lreg)==edx || regv_h(lreg)==edx) { + edx0 = get_register(); if(!edx0) error(-1); + printf("# dassop\n\tmov %s,%s\n", + register_name(edx0),register_name(edx)); + edx = edx0; + } + lload(edx,reg,0); + dtosop(op,USE_CREG,xreg); + if (lreg!=RET_DREGISTER) error(-1); + use_reg(lreg); + edx = emit_pop(0); + code_lassign(edx,RET_DREGISTER); + if (edx0!=-1) + free_register(edx0); + emit_pop_free(edx); + emit_lpop_free(xreg); + if (reg0!=USE_CREG && reg!=RET_DREGISTER) + lmove(reg,RET_DREGISTER); + set_double(reg); } else { - xreg = emit_lpop(0); /* pop e3 value */ - if (!is_int_reg(creg)) error(-1); - edx = ireg; - emit_push(); - use_float(d,reg); - if (regv_l(lreg)==edx || regv_h(lreg)==edx) { - edx0 = get_register(); if(!edx0) error(-1); - printf("# dassop\n\tmove %s,%s\n",register_name(edx0),register_name(edx)); - edx = edx0; - } - lload(edx,reg,0); - dtosop(op,USE_CREG,xreg); - if (lreg!=RET_DREGISTER) error(-1); - use_reg(lreg); - edx = emit_pop(0); - code_lassign(edx,RET_DREGISTER); - if (edx0!=-1) - free_register(edx0); - emit_pop_free(edx); - emit_lpop_free(xreg); - if (reg0!=USE_CREG && reg!=RET_DREGISTER) - lmove(reg,RET_DREGISTER); - set_double(reg); - } + if (freg==edx) { + edx0 = get_register(); if(!edx0) error(-1); + printf("# dassop\n\tmov %s,%s\n", + register_name(edx0),register_name(edx)); + edx = edx0; + } + code_rindirect(edx,reg,0,0,0); + dtosop(op,USE_CREG,xreg); + use_reg(freg); + edx = emit_pop(0); + code_assign(edx,RET_FREGISTER); + if (edx0!=-1) + free_register(edx0); + emit_pop_free(edx); + emit_pop_free(xreg); + if (reg0!=USE_CREG && reg!=RET_DREGISTER) + code_register(RET_DREGISTER,reg); + set_float(reg); + } +} + +void +code_dassop_f(int op,int reg,int d) { + /* we have lvalue in creg, applied floating value is in freg */ + // (*creg) op = pop() + int xreg; + char *crn; + char *frn; + int edx,edx0=-1; + int reg0=reg; + + xreg=emit_dpop(d); + crn=register_name(ireg); + use_float(d,reg); + frn =fregister_name(reg); + + code_ldf(fload(d),fregister_name(freg),0,ireg); + dtosop(op,reg,xreg); + code_ldf(fstore(d),fregister_name(freg),0,ireg); + emit_dpop_free(xreg,d); +} + +void +code_dassop(int op,int reg,int d) { + if (!(arch_mode&UseFPP)) + code_dassop_d(op,reg,d); + else + code_dassop_d(op,reg,d); } void code_register_dassop(int reg,int op,int d) { // reg op= dpop() int xreg; - if (!d) { - xreg=emit_dpop(d); - dtosop(op,reg,xreg); - emit_dpop_free(xreg,d); + if (!(arch_mode&UseFPP)) { + if (!d) { + xreg=emit_pop(0); + dtosop(op,reg,xreg); + emit_pop_free(xreg); + } else { + xreg=emit_lpop(); + dtosop(op,reg,xreg); + emit_lpop_free(xreg); + set_double(lreg); + } } else { - xreg=emit_lpop(); - dtosop(op,reg,xreg); - emit_lpop_free(xreg); - set_double(lreg); + xreg=emit_dpop(d); + dtosop(op,reg,xreg); + emit_dpop_free(xreg,d); } } @@ -4201,15 +4221,15 @@ code_dload_1(int d) { int g = get_dregister(d); - if (d) + if (!(arch_mode&UseFPP)) { error(-1); - else - printf("\tli.s %s,1.0\n",fregister_name(g)); + } + printf("\tmvf%c\t%s,#1\n",dsuffix(d),fregister_name(g)); return g; } void -code_dpreinc(int e1,int e2,int d,int reg) { +code_dpreinc_d(int e1,int e2,int d,int reg) { char *frn; char *crn; int g,xreg; @@ -4218,36 +4238,33 @@ if (!d) { if (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",dir>0?"add.s":"sub.s",crn,crn,grn); - if (use && reg!=cadr(e2)) - printf("\tmov.s %s,%s\n",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("\tl.s %s,0(%s)\n",frn,crn); - printf("\t%s %s,%s,%s\n",dir>0?"add.s":"sub.s",frn,frn,grn); - printf("\ts.s %s,0(%s)\n",frn,crn); + use_float(d,reg); + code_save_stacks(); + code_float_lib_c("__addsf3",cadr(e2),cadr(e2),dir); + if (reg!=cadr(e2)) code_register(cadr(e2),reg); + return; + } + g_expr(e2); + if(!is_int_reg(creg)) error(-1); + xreg = ireg; + emit_push(); + code_save_stacks(); + code_rindirect(xreg,FREGISTER_OPERAND,0,0,0); + code_double_lib_c("__addsf3",DREGISTER_OPERAND,RET_DREGISTER,dir); + xreg = emit_pop(0); + code_assign_register(xreg,RET_DREGISTER); + if (use) { + if (reg==USE_CREG) + set_freg(RET_FREGISTER,0); + else + code_register(RET_DREGISTER,reg); } - free_register(g); + emit_pop_free(xreg); } else { if (car(e2)==DREGISTER) { use_float(d,reg); code_save_stacks(); - code_double_lib_c("dpadd",cadr(e2),cadr(e2),dir); + code_double_lib_c("__adddf3",cadr(e2),cadr(e2),dir); if (reg!=cadr(e2)) lmove(reg,cadr(e2)); return; } @@ -4257,7 +4274,7 @@ emit_push(); code_save_stacks(); lload(xreg,DREGISTER_OPERAND,0); - code_double_lib_c("dpadd",DREGISTER_OPERAND,RET_DREGISTER,dir); + code_float_lib_c("__adddf3",DREGISTER_OPERAND,RET_DREGISTER,dir); xreg = emit_pop(0); lstore(xreg,RET_DREGISTER); if (use) { @@ -4271,7 +4288,7 @@ } void -code_dpostinc(int e1,int e2,int d,int reg) { +code_dpostinc_d(int e1,int e2,int d,int reg) { char *frn; char *crn; int g,xreg; @@ -4280,35 +4297,45 @@ if (!d) { if (car(e2)==FREGISTER) { - crn=register_name(cadr(e2)); - grn=fregister_name(g=code_dload_1(d)); + xreg = cadr(e2); + code_float_lib_c("__addsf3",xreg,RET_DREGISTER,dir); + // xreg は increment する + // USE_CREG だと increment する前の値を creg にセット + // reg が指定されていれば、それに前の値をセット if (reg==USE_CREG) { - reg=get_dregister(d); if (!reg) error(-1); + use_float(d,reg); + if (reg==RET_FREGISTER) { + reg = get_register(d); + } set_freg(reg,0); } - frn=fregister_name(reg); - if (use && reg!=cadr(e2)) - printf("\tmov.s %s,%s\n",frn,crn); - printf("\t%s %s,%s,%s\n",dir>0?"add.s":"sub.s",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("\tl.s %s,0(%s)\n",frn,crn); - printf("\t%s %s,%s,%s\n",dir>0?"add.s":"sub.s",grn,frn,grn); - printf("\ts.s %s,0(%s)\n",grn,crn); + g = list3(reg,0,xreg); + g = list3(xreg,g,RET_FREGISTER); + parallel_rassign(g); + return; + } + g_expr(e2); + if(!is_int_reg(creg)) error(-1); + xreg = ireg; + emit_push(); + code_save_stacks(); + use_float(0,reg); + code_rindirect(xreg,FREGISTER_OPERAND,0,0,0); + code_float_lib_c("__addsf3",DREGISTER_OPERAND,RET_DREGISTER,dir); + xreg = emit_pop(0); + emit_push(); + if (use) { + use_longlong(reg); + code_rindirect(xreg,reg,0,0,0); } - free_register(g); + reg = emit_lpop(); + code_register_assign(xreg,reg); + emit_pop_free(reg); + emit_pop_free(xreg); } else { if (car(e2)==DREGISTER) { xreg = cadr(e2); - code_double_lib_c("dpadd",xreg,RET_DREGISTER,dir); + code_double_lib_c("__adddf3",xreg,RET_DREGISTER,dir); // xreg は increment する // USE_CREG だと increment する前の値を creg にセット // reg が指定されていれば、それに前の値をセット @@ -4333,7 +4360,7 @@ code_save_stacks(); use_float(1,reg); lload(xreg,DREGISTER_OPERAND,0); - code_double_lib_c("dpadd",DREGISTER_OPERAND,RET_DREGISTER,dir); + code_double_lib_c("__adddf3",DREGISTER_OPERAND,RET_DREGISTER,dir); xreg = emit_pop(0); emit_lpush(); if (use) { @@ -4348,9 +4375,106 @@ } void +code_dpreinc_f(int e1,int e2,int d,int reg) { + char *frn; + char *crn; + int g,xreg,reg0; + char *grn; + int dir=caddr(e1); + + if (car(e2)==DREGISTER) { + 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); + if (d) set_dreg(reg,0); else set_freg(reg,0); + } + frn=fregister_name(reg); + printf("\t%s%c\t%s, %s, %s\n", + dir>0?"adf":"suf",dsuffix(d), + crn,crn,grn); + if (use && reg!=cadr(e2)) + printf("\tmvf%c\t%s, %s\n",dsuffix(d),frn,crn); + } else { + g_expr(e2); + if (!is_int_reg(creg)) error(-1); + reg0 = ireg; + if (reg==USE_CREG) { + reg=get_dregister(d); if (!reg) error(-1); + if (d) set_dreg(reg,0); else set_freg(reg,0); + } + grn = fregister_name(g = code_dload_1(d)); + frn=fregister_name(reg); + code_ldf(fload(d),frn,0,reg0); + printf("\t%s%c\t%s, %s, %s\n", + dir>0?"adf":"suf",dsuffix(d), + frn,frn,grn); + code_ldf(fstore(d),frn,0,reg0); + } + free_register(g); +} + +void +code_dpostinc_f(int e1,int e2,int d,int reg) { + char *frn; + char *crn; + int g,xreg; + char *grn; + int dir=caddr(e1); + + if (car(e2)==DREGISTER) { + 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("\tmvf%c\t%s, %s\n",dsuffix(d),frn,crn); + printf("\t%s%c\t%s,%s,%s\n",dir>0?"adf":"suf", + dsuffix(d),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)); + code_ldf(fload(d),frn,0,reg0); + printf("\t%s%c\t%s, %s, %s\n", + dir>0?"adf":"suf",dsuffix(d), + grn,frn,grn); + code_ldf(fstore(d),grn,0,reg0); + } + free_register(g); +} + +void +code_dpreinc(int e1,int e2,int d,int reg) { + if (!(arch_mode&UseFPP)) + code_dpreinc_d(e1,e2,d,reg); + else + code_dpreinc_f(e1,e2,d,reg); +} + +void +code_dpostinc(int e1,int e2,int d,int reg) { + if (!(arch_mode&UseFPP)) + code_dpostinc_d(e1,e2,d,reg); + else + code_dpostinc_f(e1,e2,d,reg); +} + + +void drexpr(int e1, int e2,int l1, int op,int cond) { int op1; + char *opn; if (!cond) { switch(op) { case FOP+GT: @@ -4372,27 +4496,18 @@ } } switch(op) { - case FOP+GT: op1=FOP+CMP; break; - case FOP+GE: op1=FOP+CMPGE; break; - case FOP+EQ: op1=FOP+CMPEQ; break; - case FOP+NEQ: op1=FOP+CMPEQ; break; - case DOP+GT: op1=DOP+CMP; break; - case DOP+GE: op1=DOP+CMPGE; break; - case DOP+EQ: op1=DOP+CMP; break; - case DOP+NEQ: op1=DOP+CMP; break; + case FOP+GT: op1=FOP+CMP; opn = "bgt"; break; + case FOP+GE: op1=FOP+CMPGE; opn = "bge"; break; + case FOP+EQ: op1=FOP+CMP; opn = "beq"; break; + case FOP+NEQ: op1=FOP+CMP; opn = "bne"; break; + case DOP+GT: op1=DOP+CMP; opn = "bgt"; break; + case DOP+GE: op1=DOP+CMPGE; opn = "bge"; break; + case DOP+EQ: op1=DOP+CMP; opn = "beq"; break; + case DOP+NEQ: op1=DOP+CMP; opn = "bne"; break; default: error(-1); } g_expr(list3(op1,e2,e1)); - switch(op) { - case DOP+GT: printf("\tbltz\t$2,$L_%d\n",l1);break; - case DOP+GE: printf("\tblez\t$2,$L_%d\n",l1);break; - case DOP+EQ: printf("\tbeq\t$2,$0,$L_%d\n",l1);break; - case DOP+NEQ: printf("\tbne\t$2,$0,$L_%d\n",l1);break; - case FOP+GT: printf("\tbc1t\t$L_%d\n",l1);break; - case FOP+GE: printf("\tbc1t\t$L_%d\n",l1);break; - case FOP+EQ: printf("\tbc1t\t$L_%d\n",l1);break; - case FOP+NEQ: printf("\tbc1f\t$L_%d\n",l1);break; - } + printf("\t%s\t.L%d\n",opn,l1); } int emit_dpop(int d) @@ -4411,30 +4526,6 @@ return xreg; } -#if 0 -static int emit_lpop_regvar(); - -static -int emit_dpop_regvar(int d) -{ - int xreg,reg; - if (d) { - reg = emit_lpop_regvar(); - regs[reg] = USING_DREG; - return reg; - } - xreg=pop_fregister(); - reg = cadr(get_dregister_var(0,d)); - if (xreg<= -REG_LVAR_OFFSET) { - code_drlvar(REG_LVAR_OFFSET+xreg,1,reg); - free_lvar(REG_LVAR_OFFSET+xreg); - xreg=reg; - } else { - code_dassign_dregister(reg,d,xreg); - } - return xreg; -} -#endif void emit_dpop_free(int e1,int d) @@ -4463,20 +4554,6 @@ /* 64bit int part */ -#if 0 -static int -lcmp(int op,int cond) -{ - if (op==LOP+UGT||op==LOP+UGE) { - return UCMP; - } else if (op==LOP+LE||op==LOP+GE) { - return CMPGE; - } else { - return CMP; - } -} -#endif - void lrexpr(int e1, int e2,int l1, int op,int cond) { @@ -4517,24 +4594,6 @@ emit_lpop_free(e3); } -#if 0 -static -int emit_lpop_regvar() -{ - int xreg,reg; - xreg=lreg_stack[--lreg_sp]; - reg = cadr(get_lregister_var(0)); - if (xreg<= -REG_LVAR_OFFSET) { - code_lrlvar(REG_LVAR_OFFSET+xreg,reg); - free_lvar(REG_LVAR_OFFSET+xreg); - xreg = reg; - } else { - code_lassign_lregister(reg,xreg); - } - return xreg; -} -#endif - int emit_lpop() { @@ -4562,7 +4621,7 @@ code_cmp_lregister(int reg,int label,int cond) { use_longlong(reg); - printf("\tor %s,%s,%s\n", + printf("\torr\t%s, %s, %s\n", lregister_name_low(reg), lregister_name_low(reg), lregister_name_high(reg)); @@ -4618,11 +4677,11 @@ crn_l = lregister_name_low(creg); lvar_intro(e2); #if ENDIAN==0 - printf("\tsw %s,",crn_l);lvar(e2,""); - printf("\tsw %s,",crn_h);lvar(e2+SIZE_OF_INT,""); + printf("\tstr\t%s, ",crn_l);lvar(e2,""); + printf("\tstr\t%s, ",crn_h);lvar(e2+SIZE_OF_INT,""); #else - printf("\tsw %s,",crn_h);lvar(e2,""); - printf("\tsw %s,",crn_l);lvar(e2+SIZE_OF_INT,""); + printf("\tstr\t%s, ",crn_h);lvar(e2,""); + printf("\tstr\t%s, ",crn_l);lvar(e2+SIZE_OF_INT,""); #endif } @@ -4672,15 +4731,8 @@ use_longlong(creg); rl=lregister_name_low(creg); rh=lregister_name_high(creg); - dreg = get_lregister(); - dl=lregister_name_low(dreg); - dh=lregister_name_high(dreg); - printf("\tsubu %s,$0,%s\n",dl,rl); - printf("\tsubu %s,$0,%s\n",dh,rh); - printf("\tsltu %s,$0,%s\n",rl,dl); - printf("\tsubu %s,%s,%s\n",dh,dh,rl); - free_register(lreg); - set_lreg(dreg,0); + printf("\trsbs\t%s, %s, #0\n",rl,rl); + printf("\trsc\t%s, %s, #0\n",rh,rh); } void @@ -4694,11 +4746,11 @@ crn_l = lregister_name_low(creg); r = get_ptr_cache((NMTBL*)caddr(e1)); #if ENDIAN==0 - code_ldf("lw",crn_l,cadr(e1),r); - code_ldf("lw",crn_h,cadr(e1)+SIZE_OF_INT,r); + code_ldf("ldr",crn_l,cadr(e1),r); + code_ldf("ldr",crn_h,cadr(e1)+SIZE_OF_INT,r); #else - code_ldf("lw",crn_h,cadr(e1),r); - code_ldf("lw",crn_l,cadr(e1)+SIZE_OF_INT,r); + code_ldf("ldr",crn_h,cadr(e1),r); + code_ldf("ldr",crn_l,cadr(e1)+SIZE_OF_INT,r); #endif } @@ -4711,124 +4763,8 @@ crn_h = lregister_name_high(creg); crn_l = lregister_name_low(creg); lvar_intro(e1); - printf("\tlw %s,",crn_l); lvar(e1,""); - printf("\tlw %s,",crn_h); lvar(e1+SIZE_OF_INT,""); -} - - - -static void -code_asld_lib(int reg,int oreg) -{ - char *ch,*cl,*oh,*ol,*dh,*dl; - // 5 4 7 3 2 6 - int dreg = get_lregister(); - ch = lregister_name_high(reg); - cl = lregister_name_low(reg); - oh = lregister_name_high(oreg); - ol = lregister_name_low(oreg); - dh = lregister_name_high(dreg); - dl = lregister_name_low(dreg); - - printf("\tsll %s,%s,26\n",dh,ol); - printf("\tbgez %s,1f\n",dh); - printf("\tsll %s,%s,%s\n",oh,cl,ol); - printf("\t.set noreorder\n"); - printf("\tb 3f\n"); - printf("\tmove %s,$0\n",dl); - printf("\t.set reorder\n"); - printf("\t1:\n"); - printf("\t.set noreorder\n"); - printf("\tbeq %s,$0,2f\n",dh); - printf("\tsll %s,%s,%s\n",oh,ch,ol); - printf("\t.set reorder\n"); - printf("\tsubu %s,$0,%s\n",dh,ol); - printf("\tsrl %s,%s,%s\n",dh,cl,dh); - printf("\tor %s,%s,%s\n",oh,oh,dh); - printf("\t2:\n"); - printf("\tsll %s,%s,%s\n",dl,cl,ol); - printf("\t3:\n"); - // printf("\tmove %s,%s\n",cl,dl); - // printf("\tmove %s,%s\n",ch,oh); - printf("\tmove %s,%s\n",dh,oh); - set_lreg(dreg,0); - // free_register(dreg); -} - -static void -code_asrd_lib(int reg,int oreg) // ___ashrdi3$stub -{ - char *ch,*cl,*oh,*ol,*dh,*dl; - // 5 4 2 3 9 8 - int dreg = get_lregister(); - ch = lregister_name_high(creg); - cl = lregister_name_low(creg); - oh = lregister_name_high(oreg); - ol = lregister_name_low(oreg); - dh = lregister_name_high(dreg); - dl = lregister_name_low(dreg); - - printf("\tsll %s,%s,26\n",oh,ol); - printf("\tbgez %s,1f\n",oh); - printf("\tsra %s,%s,%s\n",dl,ch,ol); - printf("\t.set noreorder\n"); - printf("\tb 3f\n"); - printf("\tsra %s,%s,31\n",dh,ch); - printf("\t.set reorder\n"); - printf("\t1:\n"); - printf("\t.set noreorder\n"); - printf("\tbeq %s,$0,2f\n",oh); - printf("\tsrl %s,%s,%s\n",dl,cl,ol); - printf("\t.set reorder\n"); - printf("\tsubu %s,$0,%s\n",oh,ol); - printf("\tsll %s,%s,%s\n",oh,ch,oh); - printf("\tor %s,%s,%s\n",dl,dl,oh); - printf("\t2:\n"); - printf("\tsra %s,%s,%s\n",dh,ch,ol); - printf("\t3:\n"); - // printf("\tmove %s,%s\n",cl,dl); - // printf("\tmove %s,%s\n",ch,dh); - set_lreg(dreg,0); - // free_register(dreg); -} - -static void -code_lsrd_lib(int reg,int oreg) // ___lshrdi3$stub -{ - char *ch,*cl,*oh,*ol,*dh,*dl; - // 5 4 2 3 9 8 - int dreg = get_lregister(); - ch = lregister_name_high(reg); - cl = lregister_name_low(reg); - oh = lregister_name_high(oreg); - ol = lregister_name_low(oreg); - dh = lregister_name_high(dreg); - dl = lregister_name_low(dreg); - - printf("\tsll %s,%s,26\n",oh,ol); - printf("\tbgez %s,1f\n",oh); - printf("\tsrl %s,%s,%s\n",dl,ch,ol); - printf("\t.set noreorder\n"); - printf("\tb 3f\n"); - printf("\tmove %s,$0\n",dh); - printf("\t.set reorder\n"); - printf("\t\n"); - printf("\t1:\n"); - printf("\t.set noreorder\n"); - printf("\tbeq %s,$0,2f\n",oh); - printf("\tsrl %s,%s,%s\n",dl,cl,ol); - printf("\t.set reorder\n"); - printf("\t\n"); - printf("\tsubu %s,$0,%s\n",oh,ol); - printf("\tsll %s,%s,%s\n",oh,ch,oh); - printf("\tor %s,%s,%s\n",dl,dl,oh); - printf("\t2:\n"); - printf("\tsrl %s,%s,%s\n",dh,ch,ol); - printf("\t3:\n"); - // printf("\tmove %s,%s\n",cl,dl); - // printf("\tmove %s,%s\n",ch,dh); - set_lreg(dreg,0); - // free_register(dreg); + printf("\tldr\t%s, ",crn_l); lvar(e1,""); + printf("\tldr\t%s, ",crn_h); lvar(e1+SIZE_OF_INT,""); } static void @@ -4841,11 +4777,6 @@ set_lreg(RET_LREGISTER,0); } -#define code_ldiv_lib(reg,oreg) code_longlong_lib("__divdi3",reg,oreg) -#define code_ludiv_lib(reg,oreg) code_longlong_lib("__udivdi3",reg,oreg) -#define code_lmod_lib(reg,oreg) code_longlong_lib("__moddi3",reg,oreg) -#define code_lumod_lib(reg,oreg) code_longlong_lib("__umoddi3",reg,oreg) - #define check_lreg(reg) if (reg!=lreg) { lmove(reg,lreg); } void @@ -4871,17 +4802,17 @@ switch(op) { case LLSHIFT: case LULSHIFT: - code_asld_lib(reg,oreg); // ___ashldi3$stub + code_longlong_lib("__ashldi3",reg,oreg) check_lreg(reg); if(ox!=-1) free_register(ox); return; case LRSHIFT: - code_asrd_lib(reg,oreg); // ___ashrdi3$stub + code_longlong_lib("__ashrdi3",reg,oreg) check_lreg(reg); if(ox!=-1) free_register(ox); return; case LURSHIFT: - code_lsrd_lib(reg,oreg); // ___lshrdi3$stub + code_longlong_lib("__lshrdi3",reg,oreg) check_lreg(reg); if(ox!=-1) free_register(ox); return; @@ -4892,74 +4823,47 @@ crn_l = lregister_name_low(reg); switch(op) { case LADD: - drn = register_name(dx = get_register()); - printf("\taddu %s,%s,%s\n",crn_l,crn_l,orn_l); - printf("\tsltu %s,%s,%s\n",drn,crn_l,orn_l); - printf("\taddu %s,%s,%s\n",crn_h,crn_h,orn_h); - printf("\taddu %s,%s,%s\n",crn_h,crn_h,drn); + printf("\tadds\t%s, %s, %s\n",crn_l,crn_l,orn_l); + printf("\tadc\t%s, %s, %s\n",crn_h,crn_h,orn_h); break; case LSUB: - drn = register_name(dx = get_register()); - printf("\tsltu %s,%s,%s\n",drn,crn_l,orn_l); - printf("\tsubu %s,%s,%s\n",crn_l,crn_l,orn_l); - printf("\tsubu %s,%s,%s\n",crn_h,crn_h,orn_h); - printf("\tsubu %s,%s,%s\n",crn_h,crn_h,drn); + printf("\tsubs\t%s, %s, %s\n",crn_l,crn_l,orn_l); + printf("\tsbc\t%s, %s, %s\n",crn_h,crn_h,orn_h); break; case LCMP: error(-1); break; case LBAND: - printf("\tand %s,%s,%s\n",crn_l,crn_l,orn_l); - printf("\tand %s,%s,%s\n",crn_h,crn_h,orn_h); + printf("\tand\t%s, %s, %s\n",crn_l,crn_l,orn_l); + printf("\tand\t%s, %s, %s\n",crn_h,crn_h,orn_h); break; case LEOR: - printf("\txor %s,%s,%s\n",crn_l,crn_l,orn_l); - printf("\txor %s,%s,%s\n",crn_h,crn_h,orn_h); + printf("\teor\t%s, %s, %s\n",crn_l,crn_l,orn_l); + printf("\teor\t%s, %s, %s\n",crn_h,crn_h,orn_h); break; case LBOR: - printf("\tor %s,%s,%s\n",crn_l,crn_l,orn_l); - printf("\tor %s,%s,%s\n",crn_h,crn_h,orn_h); + printf("\torr\t%s, %s, %s\n",crn_l,crn_l,orn_l); + printf("\torr\t%s, %s, %s\n",crn_h,crn_h,orn_h); break; case LMUL: case LUMUL: - dx=get_lregister(); - use_reg(dx); - drn_l = lregister_name_low(dx); - drn_h = lregister_name_high(dx); - /* - drn_l 4 = l32( crn_l * orn_l); 6, 2 - drn_h 5 = h32( crn_l * orn_l); - orn_l 6 = l32( crn_h * orn_l); 7, 3 - drn_h 5 = drn_h + orn_l; 5, 6 - crn_l 2 = l32( crn_l * orn_h); 2, 6 - crn_h 5 = drn_h + crn_l; 5, 2 - crn_l = drn_l; - */ - printf("\tsra %s,%s,31\n",drn_l,orn_l); - printf("\tmultu %s,%s\n",crn_l,orn_l); - printf("\tmfhi %s\n",drn_h); - printf("\tmflo %s\n",drn_l); - printf("\tmult %s,%s,%s\n",orn_l,crn_h,orn_l); - printf("\taddu %s,%s,%s\n",drn_h,drn_h,orn_l); - printf("\tmult %s,%s,%s\n",crn_l,crn_l,orn_h); - printf("\taddu %s,%s,%s\n",crn_h,drn_h,crn_l); - printf("\tmove %s,%s\n",crn_l,drn_l); + code_longlong_lib("__muldi3",reg,oreg) + check_lreg(reg); break; case LDIV: - code_ldiv_lib(reg,oreg) -; // ___divdi3$stub + code_longlong_lib("____divdi3",reg,oreg) check_lreg(reg); break; case LUDIV: - code_ludiv_lib(reg,oreg); // ___udivdi3$stub + code_longlong_lib("___udivdi3",reg,oreg) check_lreg(reg); break; case LMOD: - code_lmod_lib(reg,oreg); // ___moddi3$stub + code_longlong_lib("___moddi3",reg,oreg) check_lreg(reg); break; case LUMOD: - code_lumod_lib(reg,oreg); // ___umoddi3$stub + code_longlong_lib("___umoddi3",reg,oreg) check_lreg(reg); break; default: