# HG changeset patch # User kono # Date 1090385533 -32400 # Node ID 5fc059f1947d985e960cf149902bae51e9c31573 # Parent 9a3d897d58fd3d1228fdc86bd3cac095dec370a9 ARM continue... diff -r 9a3d897d58fd -r 5fc059f1947d Changes --- a/Changes Tue Jul 20 12:23:03 2004 +0900 +++ b/Changes Wed Jul 21 13:52:13 2004 +0900 @@ -5886,3 +5886,7 @@ 浮動小数点レジスタ一つっての嘘だな。レジスタは使うたびに、 毎回セーブするみたいね。 + +Wed Jul 21 13:51:56 JST 2004 + +さて、inc_inst を、どうやっていれるか.... diff -r 9a3d897d58fd -r 5fc059f1947d mc-code-arm.c --- a/mc-code-arm.c Tue Jul 20 12:23:03 2004 +0900 +++ b/mc-code-arm.c Wed Jul 21 13:52:13 2004 +0900 @@ -35,8 +35,14 @@ static void const_list_table(); static char * cstore(int sz); static void code_int_lib(char *lib,int reg,int oreg); +#if FLOAT_CODE +static int code_d1(double d); +static int code_d2(double d); static void code_float_lib(char *opc,int oreg,int in_reg,int e1); -static void code_double_lib(char *opc,int oreg,int in_reg,int e1); +static void code_float_lib_c(char *lib,int from,int to,double value); +static void code_double_lib(char *lib,int to,int reg,int oreg); +static void code_double_lib_c(char *lib,int from,int to,double value); +#endif static int creg; static int output_mode = TEXT_EMIT_MODE; @@ -115,10 +121,12 @@ #define regv_h(i) regv_h0[(i)-LREG_OFFSET] #define regv_l(i) regv_l0[(i)-LREG_OFFSET] -#define RET_REGISTER 2 -#define REGISTER_OPERAND 4 +#define RET_REGISTER 0 +#define REGISTER_OPERAND 0 +#define REGISTER_OPERAND_1 1 #define RET_FREGISTER FREG_OFFSET -#define FREGISTER_OPERAND (FREG_OFFSET +12) +#define FREGISTER_OPERAND (FREG_OFFSET) +#define FREGISTER_OPERAND_1 (FREG_OFFSET+1) #define RET_LREGISTER (LREG_OFFSET+REAL_MAX_LREGISTER) #define LREGISTER_OPERAND (LREG_OFFSET +REAL_MAX_LREGISTER +1) @@ -251,15 +259,7 @@ #endif -#if FLOAT_CODE - - -static int code_d1(double d); -static int code_d2(double d); -static void code_double_lib(char *lib,int to,int reg,int oreg); -static void code_double_lib_c(char *lib,int from,int to,double value); - -#endif + #if LONGLONG_CODE static int code_l1(long long ll); static int code_l2(long long ll); @@ -274,10 +274,10 @@ static int max_func_args; static int my_func_args; -static unsigned int code_mask(); -static int code_mask_offset(); -static unsigned int code_fmask(); -static int code_fmask_offset(); + + + + static void jcond(int l, int cond); @@ -1315,8 +1315,8 @@ } -extern void -code_const(int e2,int reg) +static void +code_const0(int e2,int reg,char *opt) { char *crn,*add,*mov; int s,p1,p2,p3; @@ -1332,8 +1332,13 @@ if (p3) printf("\t%s\t%s, %s, #%d\n",add,crn,crn,p3); } else { disp = search_const(CONST,e2,&label); - printf("\tldr\t%s, .L%d+%d\n",crn,label,disp); - } + printf("\tldr\t%s, .L%d+%d%s\n",crn,label,disp,opt); + } +} + +extern void +code_const(int e2,int reg) { + code_const0(e2,reg,""); } static void @@ -1693,7 +1698,7 @@ use_int(reg); crn = register_name(reg); lvar_intro(e2); - printf("\tldr %s,",crn); + printf("\tldr\t%s,",crn); lvar(e2,""); code_cmp_register(reg,label,cond); } @@ -1797,7 +1802,7 @@ /* creg must point top of the destination data */ /* this code is necessary for the value of assignment or function call */ /* otherwise we don't need this */ - if (fix) printf("\taddu %s,%s,%d\n",trn,trn,fix); + if (fix) code_add(to,fix,to); if(creg!=to) { free_register(creg); creg=to; ireg=to; } @@ -1824,8 +1829,8 @@ srn = register_name(sreg); code_lvar(cadr(arg),dreg); for(count=0;count0) { - printf("\tlfm\tf4, %d, [fp, #%d]!\n",freg_save); + if (freg_save>0) { i=reg_save*SIZE_OF_INT+freg_save*SIZE_OF_DOUBLE; + printf("\tlfm\tf4, %d, [fp, #%d]!\n",freg_save,i); disp -= SIZE_OF_DOUBLE*freg_save; } printf("\tldmea\tfp, {"); @@ -3474,11 +3428,26 @@ lib_args(16); } +static void +code_int_lib(char *lib,int reg,int oreg) +{ + code_save_stacks(); + clear_ptr_cache(); + if (reg!=REGISTER_OPERAND) code_dregister(REGISTER_OPERAND,reg,0); + if (oreg!=REGISTER_OPERAND_1) code_dregister(REGISTER_OPERAND_1,oreg,0); + extern_conv(lib); + set_ireg(RET_REGISTER,0); + if (oreg!=RET_REGISTER) { + code_dregister(oreg,RET_REGISTER,0); + } +} + #if FLOAT_CODE /* floating point */ #define set_double(freg) if (regs[freg]) {regs[freg]=USING_DREG;} +#define set_float(freg) if (regs[freg]) {regs[freg]=USING_DREG;} static void dconst(int l,int h,double value); @@ -3486,7 +3455,7 @@ code_cmp_dregister(int e2,int d,int label,int cond) { char *grn,*frn; - int greg,cmpreg; + int greg; use_float(d,e2); if (!(arch_mode&UseFPP)) { @@ -3499,7 +3468,7 @@ printf("\tcmp\tr0, #0\n"); } else { set_freg(FREGISTER_OPERAND,0); - fconst(REGISTER_OPERAND,0.0); + printf("\tmov\t%s, #0\n", register_name(REGISTER_OPERAND)); // fconst(REGISTER_OPERAND,0.0); extern_conv("__nesf2"); printf("\tcmp\tr0, #0\n"); } @@ -3516,20 +3485,14 @@ static char * movef(int d) { - return d?"mvfd":mvfs"; + return d?"mvfd":"mvfs"; } static char * -storef(int d) -{ - return d?"stfd":stfs"; -} +fload(int d) { return d?"ldfd":"ldfs"; } static char * -loadf(int d) -{ - return d?"ldfd":ldfs"; -} +fstore(int d) { return d?"stfd":"stfs"; } void @@ -3558,11 +3521,11 @@ if (d) { code_lassign_gvar(e2,freg); set_double(freg); return; } else { - code_assign_gvar(e2,freg); set_float(freg); return; + code_assign_gvar(e2,freg,0); set_float(freg); return; } } else { use_float(d,freg); - code_ldf(storef(d),fregister_name(freg),cadr(e2), + code_ldf(fstore(d),fregister_name(freg),cadr(e2), get_ptr_cache((NMTBL*)caddr(e2))," @ float"); } } @@ -3574,7 +3537,7 @@ if (d) { code_lassign_lvar(e2,freg); set_double(freg); return; } else { - code_assign_lvar(e2,freg); set_float(freg); return; + code_assign_lvar(e2,freg,0); set_float(freg); return; } } else { use_float(d,freg); @@ -3591,7 +3554,7 @@ if (d) { code_lassign(e2,freg); set_double(freg); return; } else { - code_assign(e2,freg); set_float(freg); return; + code_assign(e2,freg,0); set_float(freg); return; } } use_float(d,freg); @@ -3605,7 +3568,7 @@ if (d) { code_lassign_lregister(e2,freg); set_double(freg); return; } else { - code_assign_register(e2,freg); set_float(freg); return; + code_assign_register(e2,0,freg); set_float(freg); return; } } use_float(d,freg); @@ -3655,13 +3618,14 @@ fconst(int reg,double value) { float f = value; - code_const(*((int*)f),reg); + code_const(*((int*)&f),reg); } void code_dconst(int e2,int freg,int d) { double value = dcadr(e2); + float f = value; char *frn; int label,disp; @@ -3670,14 +3634,14 @@ if (d) { dconst(regv_l(freg),regv_h(freg),value); } else { - code_const0(*((int*)f),freg,"\t@ float"); + code_const0(*((int*)&f),freg,"\t@ float"); } } else { frn = register_name(freg); if (value==0 || value==1 || value==10) { - printf("\t%s\t%s, #%d\n",movef(d),(int)value); + printf("\t%s\t%s, #%d\n",movef(d),frn,(int)value); } else if (value==-1 || value==-10) { - printf("\t%s\t%s, #%d\n",d?"mnfd":"mnfs",(int)-value); + printf("\t%s\t%s, #%d\n",d?"mnfd":"mnfs",frn,(int)-value); } else if (d) { #if ENDIAN==0 disp = search_double_const(DCONST, @@ -3688,7 +3652,7 @@ #endif printf("\tldfd\t%s, .L%d+%d\n",frn,label,disp); } else { - disp = search_const(CONST,*((int*)f),freg,&label); + disp = search_const(CONST,*((int*)&f),&label); printf("\tldfs\t%s, .L%d+%d\n",frn,label,disp); } } @@ -3766,7 +3730,7 @@ void code_d2u0(int reg,int d) { - int lreg,label,disp,reg; + int lreg,reg0; char *lrn,*frn,*crn; if (!(arch_mode&UseFPP)) { use_float(1,reg); @@ -3780,10 +3744,10 @@ 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()); + lrn = register_name(lreg = emit_dpop(d)); frn = register_name(freg); - set_ireg(reg=get_register(),0); - crn = register_name(reg); + set_ireg(reg0=get_register(),0); + crn = register_name(reg0); printf("\tcmfe %s, %s\n",lrn,frn); printf("\tbge\t1f\n"); printf("\tfixz\t%s, %s\n",crn,lrn); @@ -3793,7 +3757,8 @@ printf("\tfixz\t%s, %s\n",crn,lrn); printf("\teor\t%s, %s, #-2147483648\n",crn,crn); printf("2:\n"); - emit_dpop_free(lreg); + emit_dpop_free(lreg,d); + if (reg!=USE_CREG) code_register(reg0,reg); } return; } @@ -3802,6 +3767,7 @@ code_u2d0(int reg,int d) { int tmp; + char *crn,*frn,*lrn; if (!(arch_mode&UseFPP)) { tmp=new_lvar(SIZE_OF_INT); set_ireg(REGISTER_OPERAND,1); @@ -3832,7 +3798,7 @@ } free_lvar(tmp); } else { - use_int(reg,1); + use_int(reg); crn = register_name(reg); set_dreg(reg=get_dregister(1),0); frn = register_name(reg); @@ -3841,12 +3807,12 @@ printf("\tbge\t1f\n"); emit_dpush(1); code_dconst(dlist2(DCONST,2.147483648e9),USE_CREG,1); - lrn = register_name(lreg = emit_dpop()); + lrn = register_name(lreg = emit_dpop(d)); 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); + emit_dpop_free(lreg,d); } return; } @@ -3907,29 +3873,23 @@ void code_i2d(int reg) { - code_i2f0(reg,1); + code_i2d0(reg,1); } void code_i2f(int reg) { - code_i2f0(reg,0); + code_i2d0(reg,0); } void code_u2d(int reg) { - code_u2f0(reg,1); + code_u2d0(reg,1); } void code_u2f(int reg) { - code_u2f0(reg,0); -} - -static char * -fload(int d) { return d?"ldfd":"ldfs"; } - -static char * -fstore(int d) { return d?"stfd":"stfs"; } + code_u2d0(reg,0); +} void code_drgvar(int e2,int d,int freg) @@ -3947,7 +3907,7 @@ } else { use_float(d,freg); code_ldf(fload(d),fregister_name(freg),cadr(e2), - get_ptr_cache((NMTBL*)caddr(e2))); + get_ptr_cache((NMTBL*)caddr(e2)),""); } } @@ -4016,16 +3976,44 @@ } } +static void +code_float_lib(char *lib,int to,int reg,int oreg) +{ + code_save_stacks(); + clear_ptr_cache(); + if (reg!=FREGISTER_OPERAND) code_dregister(FREGISTER_OPERAND,reg,0); + if (to!=FREGISTER_OPERAND_1) code_dregister(FREGISTER_OPERAND_1,to,0); + extern_conv(lib); + set_freg(RET_FREGISTER,0); + if (to!=RET_FREGISTER) { + code_dregister(to,RET_FREGISTER,0); + } +} + +static void +code_float_lib_c(char *lib,int from,int to,double value) +{ + code_save_stacks(); + clear_ptr_cache(); + set_dreg_operand(from,1); + fconst(FREGISTER_OPERAND_1,value); + extern_conv(lib); + set_freg(RET_FREGISTER,0); + if (to!=RET_FREGISTER) { + code_dregister(to,RET_FREGISTER,0); + } +} + void dtosop_d(int op,int reg,int e1) { - char *opn=""; + char *opc=""; - char *grn,*frn; - int d; - int cmp=0; - int reg0=reg; + + int d,reg0=reg; + + d=(op0?"adf":"suf",dsuffix(d), frn,frn,grn); - code_ldf(fstore(d),frn,0,reg0); + code_ldf(fstore(d),frn,0,reg0,""); } free_register(g); } @@ -4406,7 +4394,7 @@ code_dpostinc_f(int e1,int e2,int d,int reg) { char *frn; char *crn; - int g,xreg; + int g,reg0; char *grn; int dir=caddr(e1); @@ -4425,18 +4413,18 @@ } else { g_expr(e2); if (!is_int_reg(creg)) error(-1); - crn=register_name(ireg); + crn=register_name(reg0=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); + 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); + code_ldf(fstore(d),grn,0,reg0,""); } free_register(g); } @@ -4646,11 +4634,11 @@ use_longlong(creg); r = get_ptr_cache((NMTBL*)caddr(e2)); #if ENDIAN==0 - code_ldf(cstore(0),lregister_name_low(creg),cadr(e2),r); - code_ldf(cstore(0),lregister_name_high(creg),cadr(e2)+SIZE_OF_INT,r); + code_ldf(cstore(0),lregister_name_low(creg),cadr(e2),r,""); + code_ldf(cstore(0),lregister_name_high(creg),cadr(e2)+SIZE_OF_INT,r,""); #else code_ldf(cstore(0),lregister_name_high(creg),cadr(e2),r); - code_ldf(cstore(0),lregister_name_low(creg),cadr(e2)+SIZE_OF_INT,r); + code_ldf(cstore(0),lregister_name_low(creg),cadr(e2)+SIZE_OF_INT,r,""); #endif } @@ -4714,8 +4702,8 @@ void code_lneg(int creg) { - int dreg; - char *rh,*rl,*dh,*dl; + + char *rh,*rl; use_longlong(creg); rl=lregister_name_low(creg); rh=lregister_name_high(creg); @@ -4734,11 +4722,11 @@ crn_l = lregister_name_low(creg); r = get_ptr_cache((NMTBL*)caddr(e1)); #if ENDIAN==0 - code_ldf("ldr",crn_l,cadr(e1),r); - code_ldf("ldr",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("ldr",crn_h,cadr(e1),r); - code_ldf("ldr",crn_l,cadr(e1)+SIZE_OF_INT,r); + code_ldf("ldr",crn_l,cadr(e1)+SIZE_OF_INT,r,""); #endif } @@ -4772,9 +4760,9 @@ { int dx = -1; int ox = -1; - char *orn_h,*crn_h,*drn_h; - char *orn_l,*crn_l,*drn_l; - char *drn; + char *orn_h,*crn_h; + char *orn_l,*crn_l; + // reg = reg op oreg use_longlong(reg); @@ -4790,17 +4778,17 @@ switch(op) { case LLSHIFT: case LULSHIFT: - code_longlong_lib("__ashldi3",reg,oreg) + code_longlong_lib("__ashldi3",reg,oreg); check_lreg(reg); if(ox!=-1) free_register(ox); return; case LRSHIFT: - code_longlong_lib("__ashrdi3",reg,oreg) + code_longlong_lib("__ashrdi3",reg,oreg); check_lreg(reg); if(ox!=-1) free_register(ox); return; case LURSHIFT: - code_longlong_lib("__lshrdi3",reg,oreg) + code_longlong_lib("__lshrdi3",reg,oreg); check_lreg(reg); if(ox!=-1) free_register(ox); return; @@ -4835,23 +4823,23 @@ break; case LMUL: case LUMUL: - code_longlong_lib("__muldi3",reg,oreg) + code_longlong_lib("__muldi3",reg,oreg); check_lreg(reg); break; case LDIV: - code_longlong_lib("____divdi3",reg,oreg) + code_longlong_lib("____divdi3",reg,oreg); check_lreg(reg); break; case LUDIV: - code_longlong_lib("___udivdi3",reg,oreg) + code_longlong_lib("___udivdi3",reg,oreg); check_lreg(reg); break; case LMOD: - code_longlong_lib("___moddi3",reg,oreg) + code_longlong_lib("___moddi3",reg,oreg); check_lreg(reg); break; case LUMOD: - code_longlong_lib("___umoddi3",reg,oreg) + code_longlong_lib("___umoddi3",reg,oreg); check_lreg(reg); break; default: @@ -4879,8 +4867,8 @@ case LADD: case LSUB: case LBOR: - case LEOR: case LBOR: case LBAND: - return is_stage1_const(v,0); + case LEOR: case LBAND: + return is_stage1_const(v,0) && is_stage1_const(v>>32,0); default: return 0; @@ -4892,7 +4880,7 @@ { char *crn_h; char *crn_l; - char *grn,*drn; + char *grn; int v; int vh; int greg,dx=-1; @@ -5062,7 +5050,7 @@ set_dreg(DREGISTER_OPERAND,1); extern_conv("__fixdfdi"); set_lreg(RET_LREGISTER,0); - if (reg!=USE_CREG&®!=RET_LREGISTER) + if (reg!=USE_CREG&®!=RET_LREGISTER) { use_longlong(reg); } } @@ -5135,16 +5123,17 @@ static void ladd(int dreg,int rreg,int v) // rreg = dreg + v { + // v should be 8bit const with 2's shift if (v>0) { printf("\tadds\t%s, %s, #%d\n", - lregister_name_low(creg),lregister_name_low(reg), v); + lregister_name_low(rreg),lregister_name_low(dreg), v); printf("\tadc\t%s %s, #0\n", - lregister_name_high(creg),lregister_name_high(reg)); + lregister_name_high(rreg),lregister_name_high(dreg)); } else { printf("\tsubs\t%s, %s, #%d\n", - lregister_name_low(creg),lregister_name_low(reg), -v); + lregister_name_low(rreg),lregister_name_low(dreg), -v); printf("\tsbc\t%s %s, #0\n", - lregister_name_high(creg),lregister_name_high(reg)); + lregister_name_high(rreg),lregister_name_high(dreg)); } } @@ -5305,25 +5294,23 @@ void code_table_jump(int l,int csvalue,int delta,int max,int min,int dlabel) { - int t,s; - char *crn = register_name(csvalue); // can be t or s + int t; + char *trn = register_name(t=get_register()); - char *srn = register_name(s=get_register()); - - code_add(t,s,-min); - code_cmpidimm(max-min+1,t,dlabel,GT); + + code_add(t,csvalue,-min); + code_cmpdimm(max-min+1,t,dlabel,GT); switch(delta) { case 1: printf("\tldrls\tpc, [pc, %s, asl #2]\n",trn); break; case 2: - printf("\tand\t%s, %s, #1\n",srn,trn,srn); - printf("\tcmp\t%s, #0\n",srn); - printf("\tbne\t% .L%d\n",dlabel); + printf("\ttst\t%s, #1\n",trn); + printf("\tbne\t.L%d\n",dlabel); printf("\tldrls\tpc, [pc, %s, asl #1]\n",trn); break; break; case 4: - printf("\tand\t%s, %s, #3\n",srn,trn,srn); - printf("\tcmp\t%s, #0\n",srn); - printf("\tbne\t% .L%d\n",dlabel); + printf("\ttst\t%s, #3\n",trn); + printf("\tbne\t.L%d\n",dlabel); + printf("\tbne\t.L%d\n",dlabel); printf("\tldrls\tpc, [pc, %s]\n",trn); break; break; default: @@ -5331,7 +5318,6 @@ } printf("\tb\t.L%d\n",dlabel); - free_register(s); free_register(t); }