Mercurial > hg > CbC > old > device
changeset 420:efbd420386c5
non aligned bitfield (not yet finished)
author | kono |
---|---|
date | Thu, 28 Oct 2004 21:20:52 +0900 |
parents | 5fafb50df9d4 |
children | ab58eea5e032 |
files | .gdbinit Changes Makefile mc-code-arm.c mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-codegen.c mc-parse.c |
diffstat | 9 files changed, 174 insertions(+), 64 deletions(-) [+] |
line wrap: on
line diff
--- a/.gdbinit Wed Oct 27 09:04:07 2004 +0900 +++ b/.gdbinit Thu Oct 28 21:20:52 2004 +0900 @@ -1,5 +1,5 @@ tb main -run -s test/arg.c +run -s test/bitfield.c # run -s mc-parse.c # run -s mc-codegen.c # run -s nkf203/nkf.c
--- a/Changes Wed Oct 27 09:04:07 2004 +0900 +++ b/Changes Thu Oct 28 21:20:52 2004 +0900 @@ -6286,4 +6286,62 @@ が出る。だから、alloca で$gpを移動する必要はない。しかし、code_segment で alloca は使えない。$gp をswしなおせば? - +input interface 構造体の alignment を64にすれば、マッチする可能性が +ちょっと高くなる。 + +const がレジスタに既にあるかどうかをチェックする? ま、いらないか。 + +ARM の bitield + |---====|=====|====----| + |--===|===--| +は、mc-codegen 側で対処しない? char/short/int は -> short/int/long +にすれば良いわけだよね。 + +問題は、long だけ。はみだすのはintだってわかっている。 + +bit_filed + bit_field(upper) << offset + bit_filed(lower) + +bassign + bit_filed(upper) = value >> offset; + bit_filed(lower) = value << (32-offset-size); + +bassop .... + +やっぱだめだめ。 + +bit_filed の前に、読み込みの段階で + upper2 << offset + (lower&mask >> 32-offset-size) +するか。 + +bit_field_repl,bit_filed_repl_const はそのままで、 +代入するときに、二回 replace する。 + +おんなじことか。 + +** そうではなくて、 + +long でintが余ったときの確保する場所(int)(bitfield_opt)をstack上に用意する。 +(new_lvarでしょうね) get_register_var でもいいけど... ARM では意味ない +だろうな。 + + mc-codegen:bit_field では、load する時に、bitfield_opt にもload + code_bit_field では、必要ならば、bitfield_opt から値を読む + + mc-codegen:bassign では、load する時に、bitfield_opt にもload + mc-codegen:bit_field_repl では、必要ならば、bitfield_opt も置換する + 代入時には、忘れずにbit_field_opt も書き込む + + mc-codegen:bassop では、tmp1 を読むときにbitfield_opt にもいれる + +でいいんじゃない? 虚しいが... + +Thu Oct 28 17:40:35 JST 2004 + +それだと変更点が多すぎる。long long でバウンダリがまたがる時 +には、格納type を struct { int [3]; } として、一時領域に格納 +する。実際には、アドレスが帰って来ることになる。で、code_bit_ +replace_const などでは、アドレスに対して処理すれば良い。そう +すれば、codegen 側の変更はなくなる。 + +でも、そうすると格納型と値型を区別しないとまずいね。
--- a/Makefile Wed Oct 27 09:04:07 2004 +0900 +++ b/Makefile Thu Oct 28 21:20:52 2004 +0900 @@ -15,6 +15,8 @@ COMPLIB = mc-parse.o mc-codegen.o mc-switch.o mc-macro.o mc-tree.o # CODE=mc-code-ia32.c CODE=mc-code-$(ARCH).c +# +TARGET=test/simp all: mc mc-ia32 mc-powerpc mc-mips mc-arm
--- a/mc-code-arm.c Wed Oct 27 09:04:07 2004 +0900 +++ b/mc-code-arm.c Thu Oct 28 21:20:52 2004 +0900 @@ -5857,17 +5857,34 @@ { int sign=0,bitsz; int align,l=0; - switch(cadr(type)) { - case INT: sign=1; bitsz=32; align=4;break; - case UNSIGNED: bitsz=32; align=4;break; - case CHAR: sign=1; bitsz= 8; align=1;break; - case UCHAR: bitsz= 8; align=1;break; - case SHORT: sign=1; bitsz=16; align=2;break; - case USHORT: sign=1; bitsz=16; align=2;break; - case LONGLONG: sign=1; bitsz=64; align=4;l=1; break; - case ULONGLONG: bitsz=64; align=4;l=1; break; + switch(cadr(type)) { /* value type */ + case INT: sign=1; align=4;break; + case UNSIGNED: align=4;break; + case CHAR: sign=1; align=1;break; + case UCHAR: align=1;break; + case SHORT: sign=1; align=2;break; + case USHORT: sign=1; align=2;break; + case LONGLONG: sign=1; align=4;l=1; break; + case ULONGLONG: align=4;l=1; break; default: error(-1); } + if (car(caddr(type))>0) { /* store type */ + if (car(car(caddr(type)))==STRUCT) { + bitsz=64+32; align=4;l=1; + } else error(-1); + } else { + switch(car(caddr(type))) { + case INT: bitsz=32; break; + case UNSIGNED: bitsz=32; break; + case CHAR: bitsz= 8; break; + 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; + default: error(-1); + } + } *psign = sign; *pbitsz = bitsz; *palign = align; @@ -5887,7 +5904,8 @@ int bitpos = *bfd; int offset = *poffset; int l; - int bitsize = cadddr(type); + int stype; + int bitsize = caddr(caddr(type)); set_bitsz(type,&sign,&bitsz,&align,&l); if (bitsize>bitsz) { error(BTERR); bitsize = i; } @@ -5896,9 +5914,23 @@ if (bitpos) { /* previous field is bit field and spaces may remain */ /* calc previsous offset */ + if (bitpos+bitsize > bitsz) { + switch(car(caddr(type))) { + case INT: stype=ULONGLONG; break; + case UNSIGNED: stype=ULONGLONG; break; + case CHAR: stype=USHORT; break; + case UCHAR: stype=USHORT; break; + case SHORT: stype=UNSIGNED; break; + case USHORT: stype=UNSIGNED; break; + case LONGLONG: stype=list4(STRUCT,12,0,0); break; + case ULONGLONG: stype=list4(STRUCT,12,0,0); break; + default: error(-1); + } + bitsz = size(stype); + cadr(caddr(type)) = stype; + } i= offset-(bitpos+7)/8; - for(l = bitpos;l>0;l -= 8,i++) { if ((i & (align-1))==0 && l+bitsize <= bitsz) { /* alignment is correct and space remains */ @@ -5932,7 +5964,7 @@ code_bit_field(int type,int bitpos,int reg) { int sign,bitsz,l,align; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); int i; set_bitsz(type,&sign,&bitsz,&align,&l); // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); @@ -5978,7 +6010,7 @@ code_bit_replace(int value,int lvalue,int type,int bitpos) { int sign,bitsz,l,align; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); int mask = 0; int tmp = -1; char *crn,*lrn,*trn; @@ -6059,7 +6091,7 @@ code_bit_replace_const(int value,int lvalue,int type,int bitpos) { int sign,bitsz,l,align; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); int mask = 0; int c; #if LONGLONG_CODE
--- a/mc-code-ia32.c Wed Oct 27 09:04:07 2004 +0900 +++ b/mc-code-ia32.c Thu Oct 28 21:20:52 2004 +0900 @@ -3414,7 +3414,7 @@ int bitpos = *bfd; int offset = *poffset; int l; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); set_bitsz(type,&sign,&bitsz,&align,&l); if (bitsize>bitsz) { error(BTERR); bitsize = i; } @@ -3459,7 +3459,7 @@ code_bit_field(int type,int bitpos,int reg) { int sign,bitsz,l,align; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); int i; set_bitsz(type,&sign,&bitsz,&align,&l); // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); @@ -3518,7 +3518,7 @@ code_bit_replace(int value,int lvalue,int type,int bitpos) { int sign,bitsz,l,align; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); int mask = 0; set_bitsz(type,&sign,&bitsz,&align,&l); // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); @@ -3585,7 +3585,7 @@ code_bit_replace_const(int value,int lvalue,int type,int bitpos) { int sign,bitsz,l,align; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); int mask = 0; int c; #if LONGLONG_CODE
--- a/mc-code-mips.c Wed Oct 27 09:04:07 2004 +0900 +++ b/mc-code-mips.c Thu Oct 28 21:20:52 2004 +0900 @@ -2277,11 +2277,11 @@ { char *crn; - g_expr(list3(BAND,list3(ADD,e1,list2(CONST,15)),list2(CONST,~15))); + g_expr(list3(BAND,list3(ADD,e1,list2(CONST,15+4)),list2(CONST,~15))); use_int(reg); crn = register_name(reg); printf("\tsubu $sp,$sp,%s\n",crn); - printf("\taddu %s,$sp,$L_%d\n",crn,cprestore_label); + printf("\taddu %s,$sp,$L_%d+4\n",crn,cprestore_label); if (fnptr->sc==CODE) { printf("\tsw\t$gp,$L_%d($sp)\n",cprestore_label); } @@ -5456,7 +5456,7 @@ { int sign=0,bitsz; int align,l=0; - switch(cadr(type)) { + switch(cadr(type)) { /* value type */ case INT: sign=1; bitsz=32; align=4;break; case UNSIGNED: bitsz=32; align=4;break; case CHAR: sign=1; bitsz= 8; align=1;break; @@ -5486,7 +5486,7 @@ int bitpos = *bfd; int offset = *poffset; int l; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); set_bitsz(type,&sign,&bitsz,&align,&l); if (bitsize>bitsz) { error(BTERR); bitsize = i; } @@ -5531,7 +5531,7 @@ code_bit_field(int type,int bitpos,int reg) { int sign,bitsz,l,align; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); int i; set_bitsz(type,&sign,&bitsz,&align,&l); // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); @@ -5576,7 +5576,7 @@ code_bit_replace(int value,int lvalue,int type,int bitpos) { int sign,bitsz,l,align; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); int mask = 0; int tmp = -1; char *crn,*lrn,*trn; @@ -5650,7 +5650,7 @@ code_bit_replace_const(int value,int lvalue,int type,int bitpos) { int sign,bitsz,l,align; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); int mask = 0; int c; #if LONGLONG_CODE
--- a/mc-code-powerpc.c Wed Oct 27 09:04:07 2004 +0900 +++ b/mc-code-powerpc.c Thu Oct 28 21:20:52 2004 +0900 @@ -5218,7 +5218,7 @@ { int sign=0,bitsz; int align,l=0; - switch(cadr(type)) { + switch(cadr(type)) { /* value type */ case INT: sign=1; bitsz=32; align=4;break; case UNSIGNED: bitsz=32; align=4;break; case CHAR: sign=1; bitsz= 8; align=1;break; @@ -5248,7 +5248,7 @@ int bitpos = *bfd; int offset = *poffset; int l; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); set_bitsz(type,&sign,&bitsz,&align,&l); if (bitsize>bitsz) { error(BTERR); bitsize = i; } @@ -5293,7 +5293,7 @@ code_bit_field(int type,int bitpos,int reg) { int sign,bitsz,l,align; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); int i; set_bitsz(type,&sign,&bitsz,&align,&l); // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); @@ -5338,7 +5338,7 @@ code_bit_replace(int value,int lvalue,int type,int bitpos) { int sign,bitsz,l,align; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); int mask = 0; int tmp = -1; int i; @@ -5411,7 +5411,7 @@ code_bit_replace_const(int value,int lvalue,int type,int bitpos) { int sign,bitsz,l,align; - int bitsize = cadddr(type); + int bitsize = caddr(caddr(type)); int mask = 0; int i; int c;
--- a/mc-codegen.c Wed Oct 27 09:04:07 2004 +0900 +++ b/mc-codegen.c Thu Oct 28 21:20:52 2004 +0900 @@ -1873,7 +1873,10 @@ } switch(car(t)) { case BIT_FIELD: - e2 = correct_type(e2,cadr(t)); + // 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 */ return(list4(BASS,e1,e2,list2(BASS,t))); case STRUCT:case UNION: if (size(t)!=size(type)) error(TYERR); @@ -1971,7 +1974,10 @@ type= UNSIGNED; ass = ASSOP; u=1; break; default: if (t>0 && car(t)==BIT_FIELD) { - e2 = correct_type(e2,cadr(t)); + // 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 */ return(list4(BASSOP,e1,e2,list2(op,t))); } } @@ -2412,8 +2418,9 @@ /* Only name in the table is used. Do not set n->ty! */ if (car(type)==BIT_FIELD) { bit_field_disp=sbit_f; // default is 0, recover only here. - // n->ty = list4(BIT_FIELD,type,bit_offset,bit_width); - caddr(type) = code_bit_field_disp( + // type = list4(BIT_FIELD,value type, + // list3(store type,bit offset,bit_width)); + cadr(caddr(type)) = code_bit_field_disp( type,&disp,&bit_field_disp,&sz); /* bit_field_disp is next bit posision */ } else { @@ -2423,7 +2430,7 @@ fields = list4(type,fields,(int)(n->nm),disp); } else if (mode==GUDECL||mode==LUDECL) { if (car(type)==BIT_FIELD) { - caddr(type) = 0; sz = size(cadr(type)); + cadr(caddr(type)) = 0; sz = size(cadr(type)); } else { sz = size(type); } @@ -2677,7 +2684,7 @@ } if (t>0&&car(t)==BIT_FIELD) { sz = 0; - bfd = caddr(t); /* bit_field_disp */ + bfd = cadr(caddr(t)); /* bit_field_disp */ code_bit_field_disp(t,&offset,&bfd,&sz); return offset+sz; } @@ -2918,9 +2925,9 @@ case POINTER: break; case BIT_FIELD: - e = list3(RBIT_FIELD,rvalue_t(cadr(e),cadr(type)),type); - /* byte rvalue, type */ - type = cadr(type); + e = list3(RBIT_FIELD,rvalue_t(cadr(e),car(caddr(type))),type); + /* byte rvalue, store type */ + type = cadr(type); /* value type */ return e; break; default: @@ -3043,7 +3050,7 @@ } if (type>0&&car(type)==BIT_FIELD) { // n->ty = list4(BIT_FIELD,type,bit_offset, bit_size); - e=list3(BIT_FIELD,e,type); + e=list3(BIT_FIELD,e,type); // ??? } return e; } @@ -3479,7 +3486,7 @@ e1 = cadr(e1); } g_expr(e1); - code_bit_field(t, caddr(t) /* bit offset */, USE_CREG); + code_bit_field(t, cadr(caddr(t)) /* bit offset */, USE_CREG); return cadr(t); } @@ -3487,18 +3494,18 @@ bit_field_repl(int e1,int e2,int t) { /* e1 = e2 */ - int lo = is_long_type(cadr(t)); + int lo = is_long_type(car(caddr(t))); /* store type */ if ((car(e2)==CONST||car(e2)==LCONST)) { g_expr(e1); code_bit_replace_const(e2,USE_CREG, - t /* type */,caddr(t) /* bit offset */); + t /* type */,cadr(caddr(t)) /* bit offset */); return cadr(t); } g_expr(e1); if (lo) emit_lpush(); else emit_push(); g_expr(e2); code_bit_replace(USE_CREG,(e2=lo?emit_lpop():pop_register()), - t /* type */,caddr(t) /* bit offset */); + t /* type */,cadr(caddr(t)) /* bit offset */); if (lo) emit_lpop_free(e2); else emit_pop_free(e2); return cadr(t); } @@ -3508,15 +3515,16 @@ { int n,e4; int type = cadr(t); + int stype = car(caddr(t)); /* e2 = e3 */ if (car(e2)==BIT_FIELD) { e2 = cadr(e2); } if (car(e2)==LREGISTER||car(e2)==REGISTER||car(e2)==LVAR||car(e2)==GVAR) { - e4 = rvalue_t(e2,type); - g_expr(assign_expr0(e2, list4(BFD_REPL,e4,e3,t), type,type)); + e4 = rvalue_t(e2,stype); + g_expr(assign_expr0(e2, list4(BFD_REPL,e4,e3,t), stype,stype)); if (use) - code_bit_field(t, caddr(t) /* bit offset */, USE_CREG); + code_bit_field(t, cadr(caddr(t)) /* bit offset */, USE_CREG); return type; } /* new = &e2 */ @@ -3524,13 +3532,13 @@ n = list2(LVAR,new_lvar(size_of_int)); // n = get_register_var(0); g_expr_u(assign_expr0(n,list2(ADDRESS,cadr(e2)),INT,INT)); - e4 = rvalue_t(list2(INDIRECT,rvalue_t(n,INT)),type); + e4 = rvalue_t(list2(INDIRECT,rvalue_t(n,INT)),stype); g_expr(assign_expr0(list2(INDIRECT,rvalue_t(n,INT)), list4(BFD_REPL,e4,e3,t), - type,type)); + stype,stype)); free_lvar(cadr(n)); if (use) - code_bit_field(t, caddr(t) /* bit offset */, USE_CREG); + code_bit_field(t, cadr(caddr(t)) /* bit offset */, USE_CREG); return type; } @@ -3557,7 +3565,9 @@ int n=-1,n1=-1,n2=-1,adr=-1,e4; int type = cadr(t); + int stype = car(caddr(t)); int byte; + int bit_offset = cadr(caddr(t)); byte = size(type); if (byte==4) byte = 0; n = list2(LVAR,new_lvar(size(type))); @@ -3568,22 +3578,28 @@ e2 = cadr(e2); } if (!(car(e2)==LREGISTER||car(e2)==REGISTER||car(e2)==LVAR||car(e2)==GVAR)) { - adr = list2(LVAR,new_lvar(size(type))); + adr = list2(LVAR,new_lvar(size(stype))); g_expr_u(assign_expr0(adr,list2(ADDRESS,cadr(e2)),INT,INT)); - e4 = rvalue_t(list2(INDIRECT,rvalue_t(adr,INT)),type); + e4 = rvalue_t(list2(INDIRECT,rvalue_t(adr,INT)),stype); e2 = list2(INDIRECT,rvalue_t(adr,INT)); } else { - e4 = rvalue_t(e2,type); + e4 = rvalue_t(e2,stype); } - g_expr(e4); - if (type==ULONGLONG||type==LONGLONG) { + if (stype==ULONGLONG||stype==LONGLONG) { + g_expr(e4); code_lassign_lvar(cadr(n1),USE_CREG); - code_bit_field(t, caddr(t) /* bit offset */, USE_CREG); + code_bit_field(t, bit_offset, USE_CREG); + code_lassign_lvar(cadr(n),USE_CREG); + if (post) code_lassign_lvar(cadr(n2),USE_CREG); + } else if (stype==STRUCT) { + g_expr0(assign_expr0(n1,e4,stype,stype)); + code_bit_field(t, bit_offset, USE_CREG); code_lassign_lvar(cadr(n),USE_CREG); if (post) code_lassign_lvar(cadr(n2),USE_CREG); } else { + g_expr(e4); code_assign_lvar(cadr(n1),USE_CREG,byte); - code_bit_field(t, caddr(t) /* bit offset */, USE_CREG); + code_bit_field(t, bit_offset, USE_CREG); code_assign_lvar(cadr(n),USE_CREG,byte); if (post) code_assign_lvar(cadr(n2),USE_CREG,byte); } @@ -3601,11 +3617,11 @@ } g_expr(assign_expr0(e2, - list4(BFD_REPL,rvalue_t(n1,type),rvalue_t(n,type),t),type,type)); + list4(BFD_REPL,rvalue_t(n1,type),rvalue_t(n,type),t),stype,stype)); if (post) { g_expr(rvalue_t(n2,type)); free_lvar(cadr(n2)); } else if (use) { - code_bit_field(t, caddr(t) /* bit offset */, USE_CREG); + code_bit_field(t, bit_offset, USE_CREG); } if (adr!=-1) free_lvar(cadr(adr)); free_lvar(cadr(n));
--- a/mc-parse.c Wed Oct 27 09:04:07 2004 +0900 +++ b/mc-parse.c Thu Oct 28 21:20:52 2004 +0900 @@ -640,6 +640,7 @@ n=decl0(); reverse(t); if(n == &null_nptr) { + /* only bitfield allow null field name */ if (!(type>0&&car(type)==BIT_FIELD)) error(DCERR); } @@ -877,7 +878,8 @@ if (mode==GSDECL||mode==GUDECL||mode==LSDECL||mode==LUDECL) { if (scalar(type) || type==LONGLONG || type==ULONGLONG) { getsym(0); - type = list4(BIT_FIELD,type,0 /* bit offset */,symval); + type = list3(BIT_FIELD,type, + list3(type /*store type*/,0 /*bit offset*/,symval)); getsym(0); } } else @@ -2397,7 +2399,7 @@ return(list4(PREINC,e,dir,size_of_int)); if(type>0 && car(type)==BIT_FIELD) { e = list4(BPREINC,e,dir,type); - type = cadr(type); + type = cadr(type); /* value type */ return e; } if(car(type)!=POINTER) @@ -2561,7 +2563,7 @@ return(list4(POSTINC,e,dir,size_of_int)); if(type>0 && car(type)==BIT_FIELD) { e = list4(BPOSTINC,e,dir,type); - type = cadr(type); + type = cadr(type); /* value type */ return e; } if(car(type)!=POINTER)