Mercurial > hg > CbC > old > device
changeset 421:ab58eea5e032
Non aligned bit field (not yet complete)
author | kono |
---|---|
date | Fri, 29 Oct 2004 04:18:39 +0900 |
parents | efbd420386c5 |
children | 83a7f9426a55 |
files | mc-code-arm.c mc-codegen.c |
diffstat | 2 files changed, 128 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-code-arm.c Thu Oct 28 21:20:52 2004 +0900 +++ b/mc-code-arm.c Fri Oct 29 04:18:39 2004 +0900 @@ -647,6 +647,14 @@ regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */ return i; /* その場所を表す番号を返す */ } + for(i=0;i<REG_VAR_MAX-REG_VAR_MIN;i++) { + reg =REG_VAR_BASE+i; + if (! regs[reg]) { /* 使われていないなら */ + regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ + if (i+1>max_reg_var) max_reg_var=i+1; + return reg; /* その場所を表す番号を返す */ + } + } /* search register stack */ for(i=0;i<reg_sp;i++) { if ((reg=reg_stack[i])>0) { @@ -668,14 +676,6 @@ } } #endif - for(i=0;i<REG_VAR_MAX-REG_VAR_MIN;i++) { - reg =REG_VAR_BASE+i; - if (! regs[reg]) { /* 使われていないなら */ - regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */ - if (i+1>max_reg_var) max_reg_var=i+1; - return reg; /* その場所を表す番号を返す */ - } - } /* PTR_CACHE をつぶす */ for(i=MAX_TMP_REG;i>=MIN_TMP_REG;i--) { if (regs[i]==PTRC_REG) { @@ -5870,7 +5870,7 @@ } if (car(caddr(type))>0) { /* store type */ if (car(car(caddr(type)))==STRUCT) { - bitsz=64+32; align=4;l=1; + bitsz=64+32; l=2; } else error(-1); } else { switch(car(caddr(type))) { @@ -5880,8 +5880,8 @@ case UCHAR: bitsz= 8; break; case SHORT: bitsz=16; break; case USHORT: bitsz=16; break; - case LONGLONG: bitsz=64; break; - case ULONGLONG: bitsz=64; break; + case LONGLONG: bitsz=64; l=1; break; + case ULONGLONG: bitsz=64; l=1; break; default: error(-1); } } @@ -5904,7 +5904,6 @@ int bitpos = *bfd; int offset = *poffset; int l; - int stype; int bitsize = caddr(caddr(type)); set_bitsz(type,&sign,&bitsz,&align,&l); @@ -5914,7 +5913,10 @@ if (bitpos) { /* previous field is bit field and spaces may remain */ /* calc previsous offset */ - if (bitpos+bitsize > bitsz) { +#if 1 + int stype; + /* code for non-aligned non-hole bit-field */ + if (bitpos!=bitsz && bitpos+bitsize > bitsz) { switch(car(caddr(type))) { case INT: stype=ULONGLONG; break; case UNSIGNED: stype=ULONGLONG; break; @@ -5926,9 +5928,10 @@ case ULONGLONG: stype=list4(STRUCT,12,0,0); break; default: error(-1); } - bitsz = size(stype); - cadr(caddr(type)) = stype; + bitsz = size(stype)*8; + car(caddr(type)) = stype; } +#endif i= offset-(bitpos+7)/8; for(l = bitpos;l>0;l -= 8,i++) { @@ -5936,8 +5939,12 @@ /* alignment is correct and space remains */ *poffset=offset=i; i = l+bitsize; - *bfd = i; - *sz = (i+7)/8; + if (i==bitsz) { + *bfd = 0; + } else { + *bfd = i; + } + *sz = (i+7)/8; printf("# bitpos=%d bitsize=%d bitsz=%d offset=%d\n",l,bitsize,bitsz,*poffset); return l; } @@ -5977,6 +5984,45 @@ /* shift right */ if ((i=bitsz-bitsize)) loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i)); + } else if (l==2) { + use_int(reg); + lreg = get_lregister(); +#if LENDIAN_L==0 + code_ld(cload(0,0),regv_l(lreg),0,reg,cext_at(0,0)); + code_ld(cload(0,0),regv_h(lreg),SIZE_OF_INT,reg,cext_at(0,0)); +#else + code_ld(cload(0,0),regv_l(lreg),0,reg,cext_at(0,0)); + code_ld(cload(0,0),regv_h(lreg),SIZE_OF_INT,reg,cext_at(0,0)); +#endif + code_ld(cload(0,0),reg,SIZE_OF_INT*2,reg,cext_at(0,0)); + /* + 111111 222222222222 0000000000 + |------||------------||----------| + |-------||-------| + 1111111 0000000 + <------bitsize---------------><a-> a = bitsz-bitsize + <---b--> b = 64+32-bitsize-bitbpos + + (r0:r1) <<= bitsz-bitsize-bitbos + rest >> = b; + rest << = a; (b>a) ==> rest >> (b-a) + (64+32-bitsize -bitpos - (bitsz-bitsize)) + = 64+32 -bitsz -bitbpos + */ + /* shift left */ + if ((i=bitsz-SIZE_OF_LONGLONG*8-bitpos)) + oprtc(LSHIFT,reg,list2(CONST,i)); + if ((i=SIZE_OF_LONGLONG*8-bitsize-bitpos)) + loprtc(LLSHIFT,lreg,list2(CONST,i)); + inc_inst(1); + printf("\tadd\t%s,%s,%s\n", + register_name(regv_l(lreg)), + register_name(regv_l(lreg)), + register_name(reg)); + set_lreg(lreg,1); + /* shift right */ + if ((i=SIZE_OF_LONGLONG*8-bitsize)) + loprtc(sign?LRSHIFT:LURSHIFT,lreg,list2(CONST,i)); } else { use_int(reg); /* shift left */ @@ -6013,10 +6059,11 @@ int bitsize = caddr(caddr(type)); int mask = 0; int tmp = -1; + int tmpvar = -1; char *crn,*lrn,*trn; set_bitsz(type,&sign,&bitsz,&align,&l); // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); - if (l) { + if (l==1) { use_longlong(value); crn = lregister_name_high(value); lrn = lregister_name_high(lvalue); @@ -6036,6 +6083,35 @@ mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); make_mask_and_or(mask,tmp,trn,crn,lrn); } + } else if (l==2) { + use_longlong(value); + tmpvar=new_lvar(SIZE_OF_LONGLONG); + code_lassign_lvar(tmpvar,value); + use_int(lvalue); + lrn = register_name(tmp = get_register()); + + if (bitsz-bitpos-bitsize) + oprtc(RSHIFT,regv_l(value),list2(CONST,bitsz-bitpos-bitsize)); + crn = lregister_name_low(value); + code_ld(cload(0,0),regv_l(value),0,lvalue,cext_at(0,0)); + trn = lregister_name_high(value); + mask = make_mask(bitsz-bitpos-bitsize,31); + make_mask_and_or(mask,regv_h(value),trn,crn,lrn); + inc_inst(1); + printf("\t%s\t%s, [%s, #0]\n",cstore(0),crn,register_name(lvalue)); + + code_lrlvar(list2(LVAR,tmpvar),value); + loprtc(LLSHIFT,value,list2(CONST,64-(bitsize-bitpos))); + inc_inst(1); + printf("\t%s\t%s, [%s, #4]\n",cstore(0),crn,register_name(lvalue)); + + code_ld(cload(0,0),regv_h(value),SIZE_OF_INT*2,lvalue,cext_at(0,0)); + mask = make_mask(0,31-(bitsz-bitpos-bitsize)); + make_mask_and_or(mask,regv_h(value),trn,crn,lrn); + inc_inst(1); + printf("\t%s\t%s, [%s, #8]\n",cstore(0),crn,register_name(lvalue)); + free_lvar(tmpvar); + set_ireg(lvalue,0); } else { use_int(value); crn = register_name(value); @@ -6096,11 +6172,12 @@ int c; #if LONGLONG_CODE long long lc; + int tmp; #endif - char *crn; + char *crn,*trn; set_bitsz(type,&sign,&bitsz,&align,&l); // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); - if (l) { + if (l==1) { #if LONGLONG_CODE use_longlong(lvalue); crn = lregister_name_high(lvalue); @@ -6118,6 +6195,31 @@ mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); make_mask_and_or_const(mask,crn,(int)lc); } + } else if (l==2) { + use_int(lvalue); + crn = register_name(lvalue); + trn = register_name(tmp = get_register()); + /* shift right */ + lc = lcadr(value); + lc >>= 32-bitpos; + /* make and-mask upper */ + code_ld(cload(0,0),tmp,0,value,cext_at(0,0)); + mask = make_mask(bitsz-bitpos-bitsize,bitsz-bitpos); + make_mask_and_or_const(mask,trn,(int)(lc>>32)); + inc_inst(1); + printf("\t%s\t%s, [%s, #0]\n",cstore(0),trn,crn); + /* store middle */ + code_const((int)lc,tmp); + inc_inst(1); + printf("\t%s\t%s, [%s, #4]\n",cstore(0),trn,crn); + /* make and-mask lower */ + lc = lcadr(value); + lc <<= bitpos; + code_ld(cload(0,0),tmp,SIZE_OF_INT*2,value,cext_at(0,0)); + mask = make_mask(0,31-bitpos); + make_mask_and_or_const(mask,trn,(int)lc); + inc_inst(1); + printf("\t%s\t%s, [%s, #8]\n",cstore(0),trn,crn); #endif } else { use_int(lvalue);
--- a/mc-codegen.c Thu Oct 28 21:20:52 2004 +0900 +++ b/mc-codegen.c Fri Oct 29 04:18:39 2004 +0900 @@ -1875,8 +1875,7 @@ case BIT_FIELD: // type = list4(BIT_FIELD,type, // list3(type /*store type*/,0 /*bit offset*/,symval)); - e2 = correct_type(e2,car(caddr(t))); /* store type */ - type = cadr(t); /* value type */ + e2 = correct_type(e2,cadr(t)); /* value type */ return(list4(BASS,e1,e2,list2(BASS,t))); case STRUCT:case UNION: if (size(t)!=size(type)) error(TYERR); @@ -3494,20 +3493,21 @@ bit_field_repl(int e1,int e2,int t) { /* e1 = e2 */ - int lo = is_long_type(car(caddr(t))); /* store type */ + int stype = car(caddr(t)); /* store type */ + int lo = is_long_type(stype); if ((car(e2)==CONST||car(e2)==LCONST)) { g_expr(e1); code_bit_replace_const(e2,USE_CREG, t /* type */,cadr(caddr(t)) /* bit offset */); - return cadr(t); + return stype; } g_expr(e1); if (lo) emit_lpush(); else emit_push(); g_expr(e2); - code_bit_replace(USE_CREG,(e2=lo?emit_lpop():pop_register()), + code_bit_replace(USE_CREG,(e2=lo?emit_lpop():emit_pop(0)), t /* type */,cadr(caddr(t)) /* bit offset */); if (lo) emit_lpop_free(e2); else emit_pop_free(e2); - return cadr(t); + return stype; } static int