Mercurial > hg > CbC > old > device
changeset 429:7733da111bd6
arm register usage
author | kono |
---|---|
date | Sat, 30 Oct 2004 22:25:27 +0900 |
parents | 61c77ff18023 |
children | ba5faa547607 |
files | mc-code-arm.c |
diffstat | 1 files changed, 89 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-code-arm.c Sat Oct 30 20:53:18 2004 +0900 +++ b/mc-code-arm.c Sat Oct 30 22:25:27 2004 +0900 @@ -129,6 +129,7 @@ #define LREG_V 3 /* mark for virtual long long/double register */ #define REGS_MAX (REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_LREGISTER+LREG_V) static int arm_regs[REGS_MAX]; +static int regs_use[REGS_MAX]; static int regv_h0[REAL_MAX_LREGISTER+LREG_V]; static int regv_l0[REAL_MAX_LREGISTER+LREG_V]; #define regv_h(i) regv_h0[(i)-LREG_OFFSET] @@ -563,7 +564,7 @@ void code_gexpr(int e){ if (is_int_reg(creg) && creg!=ireg) error(-1); -// register_usage("code_gexpr"); + register_usage("code_gexpr"); } @@ -1166,16 +1167,16 @@ return list2(LVAR,new_lvar(d?SIZE_OF_DOUBLE:SIZE_OF_FLOAT)); } -void - +int emit_push() { - int new_reg; + int new_reg,old; if (!is_int_reg(creg)) error(-1); if (reg_sp>MAX_MAX) error(-1); new_reg = get_register(); /* 絶対に取れる */ reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ ireg = creg = new_reg; + return old; } int @@ -2228,6 +2229,7 @@ case DPOSTINC : case DPREINC : case DASSOP : case DOP+LT : case DOP+LE : case DOP+GT : case DOP+GE : case DOP+EQ : case DOP+NEQ: + case RBIT_FIELD: case BASS: case BASSOP: return 1; } return 0; @@ -2468,7 +2470,7 @@ int jmp = 0; int complex_; int pnargs,preg_arg,pfreg_arg; - int stargs; + int stargs,i; int half_register = 0; special_lvar = -1; @@ -2655,6 +2657,9 @@ free_register(cadr(arg)); else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg)); } + for(i=1;i<MAX_INPUT_REGISTER_VAR;i++) { + free_register(i); + } if (ret_type==DOUBLE) { set_dreg(RET_DREGISTER,0); use_reg(RET_DREGISTER); @@ -5857,10 +5862,13 @@ /* bit field alignment calcuration */ static void -set_bitsz(int type,int *psign,int *pbitsz,int *palign,int *pl) +set_bitsz(int type,int *pbitpos, int *pbitsize, + int *psign,int *pbitsz,int *palign,int *pl) { int sign=0,bitsz; int align,l=0; + *pbitpos = cadr(caddr(type)); + *pbitsize = caddr(caddr(type)); switch(cadr(type)) { /* value type */ case INT: sign=1; break; case UNSIGNED: break; @@ -5908,8 +5916,8 @@ int bitpos = *bfd; int offset = *poffset; int l; - int bitsize = caddr(caddr(type)); - set_bitsz(type,&sign,&bitsz,&align,&l); + int bitsize,bitpos0; + set_bitsz(type,&bitpos0,&bitsize,&sign,&bitsz,&align,&l); if (bitsize>bitsz) { error(BTERR); bitsize = i; } @@ -5956,7 +5964,7 @@ i = l+bitsize; *bfd = (i==bitsz)?0:i; *sz = (i+7)/8; - printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset); +// printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset); return l; } } @@ -5971,7 +5979,7 @@ *bfd = (bitsize==bitsz)?0:bitsize; *sz = (bitsize+7)/8; - printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset); +// printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset); return bitpos; } @@ -5979,16 +5987,19 @@ /* reg contains container value, result should be in reg */ extern void -code_bit_field(int type,int bitpos,int reg) +code_bit_field(int type,int adr,int reg) { int sign,bitsz,l,align; - int bitsize = caddr(caddr(type)); - int i; - set_bitsz(type,&sign,&bitsz,&align,&l); + int bitsize,bitpos; + int i,size,adhoc=-1; + set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); + size = bitsz/8; // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); /* this implementation returns -1 for int i:1; */ if (l==1) { + use_int(adr); use_longlong(reg); + lload(adr,reg,0); /* shift left */ if ((i=bitsz-bitsize-bitpos)) loprtc(LLSHIFT,reg,list2(CONST,i)); @@ -5996,8 +6007,8 @@ if ((i=bitsz-bitsize)) loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i)); } else if (l==2) { - use_int(reg); - lreg = get_lregister(); + use_int(adr); + use_longlong(reg); /* <-----bitsize---------------> @@ -6013,29 +6024,35 @@ (64+32-bitsize -bitpos - (bitsz-bitsize)) = 64+32 -bitsz -bitbpos */ + if (adr==regv_h(reg)||adr==regv_l(reg)) { +// adhoc = get_register(); adhoc=1; +// code_register(adr,adhoc); + } /* load hhhhh */ - code_ld(cload(0,0),regv_h(lreg),SIZE_OF_INT*2,reg,cext_at(0,0)); + code_ld(cload(0,0),regv_h(reg),SIZE_OF_INT*2,adr,cext_at(0,0)); /* load mmmmmm */ - code_ld(cload(0,0),regv_l(lreg),SIZE_OF_INT,reg,cext_at(0,0)); + code_ld(cload(0,0),regv_l(reg),SIZE_OF_INT,adr,cext_at(0,0)); i = 64-(bitsize-(32-bitpos)); - loprtc(LLSHIFT,lreg,list2(CONST,i)); + loprtc(LLSHIFT,reg,list2(CONST,i)); if (i<0||64<=i) error(-1); /* load lllll */ - code_ld(cload(0,0),reg,0,reg,cext_at(0,0)); + code_ld(cload(0,0),adr,0,adr,cext_at(0,0)); i = (bitsize-(32-bitpos))-32; - oprtc(URSHIFT,reg,list2(CONST,i)); + oprtc(URSHIFT,adr,list2(CONST,i)); if (i<0||32<=i) error(-1); inc_inst(1); printf("\tadd\t%s,%s,%s\n", - register_name(regv_l(lreg)), - register_name(regv_l(lreg)), - register_name(reg)); + register_name(regv_l(reg)), + register_name(regv_l(reg)), + register_name(adr)); i = 64-bitsize; - loprtc(sign?LRSHIFT:LURSHIFT,lreg,list2(CONST,i)); + loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i)); if (i<0||64<=i) error(-1); - set_lreg(lreg,1); + if (adhoc>0) free_register(adhoc); } else { + use_int(adr); use_int(reg); + code_ld(cload(0,0),reg,SIZE_OF_INT,adr,cext_at(0,0)); /* shift left */ if ((i=32-bitsize-bitpos)) oprtc(LSHIFT,reg,list2(CONST,i)); @@ -6064,17 +6081,21 @@ } extern void -code_bit_replace(int value,int lvalue,int type,int bitpos) +code_bit_replace(int adr,int value,int type) { int sign,bitsz,l,align,i; - int bitsize = caddr(caddr(type)); + int bitsize,bitpos; int mask = 0; - int tmp = -1; + int tmp = -1,lvalue,size; int tmpvar = -1; char *crn,*lrn,*trn; - set_bitsz(type,&sign,&bitsz,&align,&l); + set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); + size = bitsz/8; // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); if (l==1) { + use_int(adr); + lvalue = get_lregister(); + lload(adr,lvalue,0); use_longlong(value); crn = lregister_name_high(value); lrn = lregister_name_high(lvalue); @@ -6094,11 +6115,13 @@ mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); make_mask_and_or(mask,tmp,trn,crn,lrn); } + code_lassign(adr,value); + free_register(lvalue); } else if (l==2) { + use_int(adr); use_longlong(value); tmpvar=new_lvar(SIZE_OF_LONGLONG); code_lassign_lvar(tmpvar,value); - use_int(lvalue); trn = register_name(tmp = get_register()); /* make and-mask upper */ @@ -6107,12 +6130,12 @@ oprtc(LSHIFT,regv_l(value),list2(CONST,i)); if (i<0||32<=i) error(-1); crn = lregister_name_low(value); - code_ld(cload(0,0),regv_h(value),0,lvalue,cext_at(0,0)); + code_ld(cload(0,0),regv_h(value),0,adr,cext_at(0,0)); lrn = lregister_name_high(value); mask = make_mask(0,31-bitpos); make_mask_and_or(mask,tmp,trn,crn,lrn); inc_inst(1); - printf("\t%s\t%s, [%s, #0]\n",cstore(0),crn,register_name(lvalue)); + printf("\t%s\t%s, [%s, #0]\n",cstore(0),crn,register_name(adr)); /* <-----bitsize---------------> hhhhhh mmmmmmmmmmmm lllllll @@ -6129,19 +6152,21 @@ loprtc(LRSHIFT,value,list2(CONST,i)); if (i<0||64<=i) error(-1); inc_inst(1); - printf("\t%s\t%s, [%s, #4]\n",cstore(0),crn,register_name(lvalue)); + printf("\t%s\t%s, [%s, #4]\n",cstore(0),crn,register_name(adr)); /* make and-mask lower */ - code_ld(cload(0,0),regv_l(value),SIZE_OF_INT*2,lvalue,cext_at(0,0)); + code_ld(cload(0,0),regv_l(value),SIZE_OF_INT*2,adr,cext_at(0,0)); if (i<0||64<=i) error(-1); mask = make_mask(bitsz-bitpos-bitsize,31); make_mask_and_or(mask,tmp,trn,lrn,crn); inc_inst(1); - printf("\t%s\t%s, [%s, #8]\n",cstore(0),lrn,register_name(lvalue)); + printf("\t%s\t%s, [%s, #8]\n",cstore(0),lrn,register_name(adr)); free_lvar(tmpvar); - set_ireg(lvalue,0); } else { + use_int(adr); use_int(value); + lvalue = get_register(); + code_ld(cload(size,sign),lvalue,0,adr,cext_at(0,0)); crn = register_name(value); lrn = register_name(lvalue); /* shift left */ @@ -6151,8 +6176,13 @@ /* make and-mask */ mask = make_mask(32-bitpos-bitsize,31-bitpos); make_mask_and_or(mask,tmp,trn,crn,lrn); + code_assign(adr,size,value); + free_register(lvalue); } if (tmp!=-1) free_register(tmp); + if (use) { + code_bit_field(type,adr,USE_CREG); + } } @@ -6192,22 +6222,26 @@ } extern void -code_bit_replace_const(int value,int lvalue,int type,int bitpos) +code_bit_replace_const(int value,int adr,int type) { int sign,bitsz,l,align; - int bitsize = caddr(caddr(type)); + int bitsize,bitpos,size; int mask = 0; int c; + int lvalue; #if LONGLONG_CODE long long lc; int tmp; #endif char *crn,*trn; - set_bitsz(type,&sign,&bitsz,&align,&l); + set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); + size = bitsz/8; // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); if (l==1) { #if LONGLONG_CODE - use_longlong(lvalue); + use_int(adr); + lvalue = get_lregister(); + lload(adr,lvalue,0); crn = lregister_name_high(lvalue); /* shift left */ lc = lcadr(value); @@ -6223,19 +6257,20 @@ mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); make_mask_and_or_const(mask,crn,(int)lc); } + free_register(lvalue); } else if (l==2) { /* hhhhhh mmmmmmmmmmmm lllllll lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh |-----||-----------||------------||-------||-------| */ - use_int(lvalue); - crn = register_name(lvalue); + use_int(adr); + crn = register_name(adr); trn = register_name(tmp = get_register()); /* shift right */ lc = lcadr(value); /* make and-mask upper */ - code_ld(cload(0,0),tmp,0,lvalue,cext_at(0,0)); + code_ld(cload(0,0),tmp,0,adr,cext_at(0,0)); mask = make_mask(0,31-bitpos); make_mask_and_or_const(mask,trn,(int)(lc<<bitpos)); inc_inst(1); @@ -6245,14 +6280,17 @@ inc_inst(1); printf("\t%s\t%s, [%s, #4]\n",cstore(0),trn,crn); /* make and-mask lower */ - code_ld(cload(0,0),tmp,SIZE_OF_INT*2,lvalue,cext_at(0,0)); + code_ld(cload(0,0),tmp,SIZE_OF_INT*2,adr,cext_at(0,0)); mask = make_mask(bitsz-bitpos-bitsize,31); make_mask_and_or_const(mask,trn,(int)(lc>>(64-bitpos))); inc_inst(1); printf("\t%s\t%s, [%s, #8]\n",cstore(0),trn,crn); + free_register(tmp); #endif } else { - use_int(lvalue); + use_int(adr); + lvalue = get_register(); + code_ld(cload(size,sign),lvalue,SIZE_OF_INT*2,adr,cext_at(0,0)); crn = register_name(lvalue); /* shift left */ c = cadr(value); @@ -6260,6 +6298,11 @@ /* make and-mask */ mask = make_mask(32-bitpos-bitsize,31-bitpos); make_mask_and_or_const(mask,crn,c); + code_assign(adr,size,lvalue); + free_register(lvalue); + } + if (use) { + code_bit_field(type,adr,USE_CREG); } }