Mercurial > hg > CbC > old > device
changeset 384:5fc059f1947d
ARM continue...
author | kono |
---|---|
date | Wed, 21 Jul 2004 13:52:13 +0900 |
parents | 9a3d897d58fd |
children | 875582d14b26 |
files | Changes mc-code-arm.c |
diffstat | 2 files changed, 185 insertions(+), 195 deletions(-) [+] |
line wrap: on
line diff
--- 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 を、どうやっていれるか....
--- 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;count<length;count+=SIZE_OF_INT) { - printf("\tldr %s, [%s, #%d]\n",srn,crn,count); - printf("\tstr %s, [%s, #%d]\n",srn,crn,count); + printf("\tldr\t%s, [%s, #%d]\n",srn,crn,count); + printf("\tstr\t%s, [%s, #%d]\n",srn,crn,count); } free_register(sreg); free_register(dreg); @@ -1848,7 +1853,7 @@ if (ireg && reg!=ireg ) { free_register(ireg); if (mode) { - printf("\tmov %s,%s\n",register_name(reg),register_name(ireg)); + printf("\tmov\t%s,%s\n",register_name(reg),register_name(ireg)); } } free_register(creg); @@ -1866,7 +1871,7 @@ free_register(freg); if (mode) { printf("\t%s %s,%s\n", - arch_mode&UseFPP?"mvfd":"mov", + (arch_mode&UseFPP)?"mvfs":"mov", fregister_name(reg),fregister_name(freg)); } } @@ -1937,32 +1942,12 @@ } } -/* -static void -set_lreg_operand1(int reg,int mode) -{ - // save_stack,clear_ptr_cache is assumed - if (!is_longlong_reg(reg)) { error(-1); return; } - if (mode) { - lmove(LREGISTER_OPERAND_1,reg); - } -} - */ - static void set_dreg_operand(int reg,int mode) { set_lreg_operand(reg,mode); } -/* -static void -set_dreg_operand1(int reg,int mode) -{ - set_lreg_operand1(reg,mode); -} - */ - void use_reg(int arg) { @@ -2124,37 +2109,6 @@ if (mode) use_reg(reg); } -#define FASS_INPUT (FOP+199) - -static void -code_assign_input_float_int(int e0) { - int e1 = cadr(e0); - int e2 = caddr(e0); - int r; - double value; - char *frn; - // e2 = e3; - if (car(e1)!=REGISTER) { error(-1); return; } - frn = register_name(cadr(e1)); - switch(car(e2)) { - case FCONST: - value = dcadr(e2); - printf("\tli.s %s,%12.12g\n",frn,value); - break; - case FRGVAR: - r = get_ptr_cache((NMTBL*)caddr(e2)); - printf("\tlw %s,%d(%s)\n",frn,cadr(e2),register_name(r)); - break; - case FRLVAR: - lvar_intro(cadr(e2)); - printf("\tlw %s,",frn); lvar(cadr(e2),""); - default: - g_expr(e2); - case FREGISTER: - printf("\tmfc1 %s,%s\n",frn,fregister_name(freg)); - } -} - static int compute_complex_arg(int e3,int reg_arg_list,int arg) { int t=caddr(e3); @@ -2409,9 +2363,9 @@ if (car(arg)==FREGISTER) { use_input_reg(cadr(arg),1);/* protect from input register free */ g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ - } else if (car(arg)==REGISTER) { - use_input_reg(cadr(arg),1);/* protect from input register free */ - code_assign_input_float_int(list3(FASS_INPUT, arg, e4)); + + + } else { g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ } @@ -3011,8 +2965,8 @@ code_register_restore(int reg_save,int freg_save,int disp) { int i; - if (freg_save>0) { - 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=(op<FOP); use_float(d,reg); @@ -4055,11 +4043,11 @@ dtosop_f(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); @@ -4102,8 +4090,8 @@ /* 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; @@ -4143,7 +4131,7 @@ dtosop(op,USE_CREG,xreg); use_reg(freg); edx = emit_pop(0); - code_assign(edx,RET_FREGISTER); + code_assign(edx,0,RET_FREGISTER); if (edx0!=-1) free_register(edx0); emit_pop_free(edx); @@ -4161,17 +4149,17 @@ 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); + code_ldf(fload(d),fregister_name(freg),0,ireg,""); dtosop(op,reg,xreg); - code_ldf(fstore(d),fregister_name(freg),0,ireg); + code_ldf(fstore(d),fregister_name(freg),0,ireg,""); emit_dpop_free(xreg,d); } @@ -4218,10 +4206,10 @@ void code_dpreinc_d(int e1,int e2,int d,int reg) { - char *frn; - char *crn; - int g,xreg; - char *grn; + + + int xreg; + int dir=caddr(e1); if (!d) { @@ -4240,7 +4228,7 @@ 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); + code_assign_register(xreg,0,RET_DREGISTER); if (use) { if (reg==USE_CREG) set_freg(RET_FREGISTER,0); @@ -4277,10 +4265,10 @@ void code_dpostinc_d(int e1,int e2,int d,int reg) { - char *frn; - char *crn; + + int g,xreg; - char *grn; + int dir=caddr(e1); if (!d) { @@ -4293,7 +4281,7 @@ if (reg==USE_CREG) { use_float(d,reg); if (reg==RET_FREGISTER) { - reg = get_register(d); + reg = get_dregister(d); } set_freg(reg,0); } @@ -4317,7 +4305,7 @@ code_rindirect(xreg,reg,0,0,0); } reg = emit_lpop(); - code_register_assign(xreg,reg); + code_assign_register(xreg,0,reg); emit_pop_free(reg); emit_pop_free(xreg); } else { @@ -4366,7 +4354,7 @@ code_dpreinc_f(int e1,int e2,int d,int reg) { char *frn; char *crn; - int g,xreg,reg0; + int g,reg0; char *grn; int dir=caddr(e1); @@ -4393,11 +4381,11 @@ } grn = fregister_name(g = code_dload_1(d)); frn=fregister_name(reg); - 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), 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); }