Mercurial > hg > CbC > old > device
changeset 329:4c8f8ef8c0cf
bit field continue...
author | kono |
---|---|
date | Wed, 23 Jun 2004 16:10:03 +0900 |
parents | 7ecb023d29b8 |
children | fa4c7b15d7ed |
files | Changes mc-code-powerpc.c mc-code.h mc-codegen.c mc-parse.c mc-parse.h mc.h |
diffstat | 7 files changed, 392 insertions(+), 90 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Tue Jun 22 01:24:00 2004 +0900 +++ b/Changes Wed Jun 23 16:10:03 2004 +0900 @@ -5070,3 +5070,67 @@ ようやっとリカバリできたよ。 +local scope { int hoge; ... { int hoge;... }} for(int i=0; hoge...) +は、やらざるを得ないだろうね。 + +Tue Jun 22 06:49:55 JST 2004 + +bit-field の alignment は、アーキテクチャによって任意って +感じだな。 + +MIPS + +01:ffffffffffffffff +02:fffffff0 0000001f 00000000 00000000 00000000 00000000 00000000 00000000 +02:00000000 00000000 ffffffff 00000001 00000000 00000000 00000000 00000000 +02:00000000 00000000 00000000 00000000 ffffffff 00000001 00000000 00000000 +01:ffffffffffffffff +02:fffffff0 000fffff 00000000 00000000 00000000 00000000 00000000 00000000 +02:00000000 00000000 ffffffff 0000ffff 00000000 00000000 00000000 00000000 +02:00000000 00000000 00000000 00000000 ffffffff 0000ffff 00000000 00000000 +1:ffffffffffffffff +2:fffffff0 0fffffff 00000000 00000000 00000000 00000000 00000000 00000000 +2:00000000 00000000 ffffffff 00ffffff 00000000 00000000 00000000 00000000 +2:00000000 00000000 00000000 00000000 ffffffff 00ffffff 00000000 00000000 + +PowerPC + +01:ffffffffffffffff +02:0fffffff f8000000 00000000 00000000 00000000 00000000 00000000 00000000 +02:00000000 07ffffff fc000000 00000000 00000000 00000000 00000000 00000000 +02:00000000 00000000 03ffffff fe000000 00000000 00000000 00000000 00000000 +01:ffffffffffffffff +02:0fffffff fffff000 00000000 00000000 00000000 00000000 00000000 00000000 +02:00000000 00000000 ffffffff ffff0000 00000000 00000000 00000000 00000000 +02:00000000 00000000 00000000 0000ffff ffffffff 00000000 00000000 00000000 +1:ffffffffffffffff +2:0fffffff fffffff0 00000000 00000000 00000000 00000000 00000000 00000000 +2:00000000 00000000 ffffffff ffffff00 00000000 00000000 00000000 00000000 +2:00000000 00000000 00000000 00000000 ffffffff ffffff00 00000000 00000000 + +実装は、mc-parse.c では決められないのか。 + +まず、 + boundary を含めて読み込み (必ず指定された型のサイズに収まる) +次に、 + 読み込んだ部分の指定されたbitを置き換え + まず 0 にして、置き換えと or を取る(?) +そして、 + 書込 +って感じですかね。64bit はめんどくさいな〜 + +ってことは、 + and mask をつくって、or mask をつくって、 + 逐次実行 +って感じですか。はぁ〜。 + +BIT_FIELD のsizeをやらないと、初期化ができない。 + +Wed Jun 23 14:06:10 JST 2004 + +(昨日は飲みすぎ...) + +emit_data は、mc-codegen にあるべきだよね。 + +bit_field の大域変数の初期化ができない。いったん、どっかに +貯めないとだめ。assign_data level?
--- a/mc-code-powerpc.c Tue Jun 22 01:24:00 2004 +0900 +++ b/mc-code-powerpc.c Wed Jun 23 16:10:03 2004 +0900 @@ -5072,4 +5072,137 @@ #endif +#if BIT_FIELD_CODE + +/* bit field alignment calcuration */ + +static void +set_bitsz(int type,int *psign,int *pbitsz,int *palign,int *pl) +{ + int sign=0,bitsz; + switch(cadr(type)) { + case INT: sign=1; bitsz=32; align=4;break; + case UNSIGNED: bitsz=32; align=4;break; + case CHAR: sign=1; bitsz=24; align=1;break; + case UCHAR: bitsz=24; 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; + default: error(-1); + } + *psign = sign; + *pbitsz = bitsz; + *palign = align; + *pl = l; +} + +/* + bit field alignment calcuration + this is architecture depenedent + */ + +extern int +code_bit_field_disp(int type,int *poffset,int *bfd,int *sz) +{ + int sign,bitsz; + int i; + int bitpos = *bfd; + int offset = *poffset; + int l; + int bitsize = cadddr(type); + set_bitsz(type,&sign,&bitsz,&l); + + if (bitsize>bitsz) { error(BTERR); bitsize = i; } + + /* bfd means previous bit field bit offset */ + if (bitpos) { + /* previous field is bit field and spaces may remain */ + /* calc previsous offset */ + + i= offset-(bitpos+7)/8; + + if ((i & (align-1)) && bitpos+bitsize < bitsz) { + + /* alignment is correct and space remains */ + + *poffset=offset=i; + i = bitpos+bitsize; + *bfd = i; + *sz = (i+7)/8; + return bitpos; + } + } + + /* first bit-field */ + + if ((i=(offset & (align-1)))) { + *poffset = (offset += i); + } + bitpos = 0; + *bfd = bitsize; + *sz = (bitsize+7)/8; + + return bitpos; +} + +/* bit field value */ + +/* reg contains container value, result should be in reg */ +extern void +code_bit_field(int type,int bit_offset,int bit_size,int reg) +{ + int sign,bitsz,l; + int bitsize = cadddr(type); + int i; + set_bitsz(type,&sign,&bitsz,&l); + /* this implementation returns -1 for int i:1; */ + if (l==1) { + use_longlong(reg); + /* shift left */ + if (bit_offset) + loprtc(LLSHIFT,reg,bit_offset); + /* shift right */ + if ((i=bitsz-bitsize)) + loprtc(sign?LRSHIFT:LRUSHIFT,reg,i); + } else { + use_int(reg); + /* shift left */ + if (bit_offset) + oprtc(LSHIFT,reg,bit_offset); + /* shift right */ + if ((i=bitsz-bitsize)) + oprtc(sign?RSHIFT:RUSHIFT,reg,i); + } +} + +/* bit field replacement */ + +extern void +code_bit_replace(int value,int lvalue,int type,int bit_offset) +{ + int sign,bitsz,l; + int bitsize = cadddr(type); + set_bitsz(type,&sign,&bitsz,&l); + if (l) { + use_longlong(reg); + /* make and-mask lower */ + /* make and-mask upper */ + /* make or-mask lower */ + /* make or-mask upper */ + /* shift left */ + /* do conjunction */ + /* do disjunction */ + } else { + use_int(reg); + /* make and-mask */ + /* make or-mask */ + /* shift left */ + /* do conjunction */ + /* do disjunction */ + } +} + +#endif + /* end */
--- a/mc-code.h Tue Jun 22 01:24:00 2004 +0900 +++ b/mc-code.h Wed Jun 23 16:10:03 2004 +0900 @@ -246,4 +246,22 @@ extern void gen_comment(char *s); +#if BIT_FIELD_CODE + +/* bit field alignment calcuration */ + +extern int code_bit_field_disp(int type,int *offset,int *bfd,int *sz,int mode); + +/* bit field value */ + +/* reg contains address of bit_field, result should goto reg */ +extern void code_bit_field(int type,int bit_offset,int reg); + +/* bit field replacement */ + +extern void code_bit_replace(int value,int lvalue,int type,int bit_offset); + /* register, register */ + +#endif + /* end */
--- a/mc-codegen.c Tue Jun 22 01:24:00 2004 +0900 +++ b/mc-codegen.c Wed Jun 23 16:10:03 2004 +0900 @@ -46,6 +46,12 @@ static void lassign(int e1); #endif +#if BIT_FIELD_CODE +static int bit_field(int e1,int t); +static int bassign(int e1,int e2,int t); +static int bassop(int e1,int e2,int op,int t); +#endif + extern void codegen_init() @@ -457,6 +463,17 @@ case ENVIRONMENT: code_environment(USE_CREG); return ADDRESS; +#if BIT_FIELD_CODE + case RBIT_FIELD: + return bit_field(e2,caddr(e1) /* type */); + case BASS: + return bassign(e2,caddr(e1),cadr(cadddr(e1))/* type */); + case BASSOP: + return bassop(e2,caddr(e1),car(cadddr(e1)),/* op */ + cadr(cadddr(e1))/* type */); + case BFD_REPL: + return bit_field_repl(e2,caddr(e1),cadddr(e1) /* type */); +#endif #if ASM_CODE case ASM: gen_asm(car(e2),cadr(e2),caddr(e2),cadddr(e2),caddr(e1)); @@ -1269,21 +1286,21 @@ case CURGVAR: code_crgvar(e4,reg,e5==CRGVAR,1); return; case SRGVAR: case SURGVAR: code_crgvar(e4,reg,e5==SRGVAR,size_of_short); return; - case RGVAR: code_rgvar(e4,reg); return; + case RGVAR: code_rgvar(e4,reg); return; case CRLVAR: case CURLVAR: code_crlvar(cadr(e4),reg,e5==CRLVAR,1); return; case SRLVAR: case SURLVAR: code_crlvar(cadr(e4),reg,e5==SRLVAR,size_of_short); return; - case RLVAR: code_rlvar(cadr(e4),reg); return; - case GVAR: code_gvar(e4,reg); return; - case LVAR: code_lvar(cadr(e4),reg); return; - case CONST: code_const(cadr(e4),reg); return; + case RLVAR: code_rlvar(cadr(e4),reg); return; + case GVAR: code_gvar(e4,reg); return; + case LVAR: code_lvar(cadr(e4),reg); return; + case CONST: code_const(cadr(e4),reg); return; case ADDRESS: if (car(cadr(e4))==STRING) code_string(cadr(e4),reg); else code_gvar(cadr(e4),reg); return; - case FNAME: code_fname((NMTBL*)cadr(e4),reg); return; - case STRING: code_string(e4,reg); return; + case FNAME: code_fname((NMTBL*)cadr(e4),reg); return; + case STRING: code_string(e4,reg); return; default: error(-1); } } @@ -1681,7 +1698,7 @@ return(list3(ASS,e1,e2)); } else if (car(t)==BIT_FIELD) { e2 = correct_type(e2,cadr(t)); - return(list3(BASS,e1,e2)); + return(list4(BASS,e1,e2,list2(BASS,t))); } else if((car(t)==STRUCT||car(t)==UNION)) { if (size(t)!=size(type)) error(TYERR); type=t; @@ -1790,8 +1807,6 @@ type=t; if(integral(t)) return(list4(ASSOP,e1,e2,op)); /* pointer += ... */ - if(integral(t)) return(list4(ASSOP,e1,e2,op)); - /* pointer += ... */ if((op!=ADD&&op!=SUB)||car(t)!=POINTER) error(TYERR); e2=binop(MUL,e2,list2(CONST,size(cadr(t))),INT,UNSIGNED); type=t; @@ -2221,10 +2236,9 @@ if (car(n->ty)==BIT_FIELD) { bit_field_disp=sbit_f; // default is 0, recover only here. // n->ty = list4(BIT_FIELD,type,bit_offset,bit_width); - caddr(n->ty) = bit_field_disp; // bitwise offset - bit_field_disp += cadddr(n->ty); - sz = bit_field_disp/bit_of_byte; - bit_field_disp %= bit_of_byte; + caddr(n->ty) = code_bit_field_disp( + cadr(n->ty),cadddr(n->ty),&disp,&bit_field_disp,&sz); + /* bit_field_disp is next bit posision */ } else { sz = size(type); } @@ -2361,14 +2375,17 @@ extern int assign_data(int e, int t, NMTBL *n,int offset) { - int ass; + int ass,sz,bfd; if(mode==GDECL) { emit_data(e,t,n); } else if(mode==STADECL) { emit_data(e,t,n); } else if(mode==LDECL) { - if (t==EMPTY) return offset+cadr(e); + if (t==EMPTY) { + /* empty space in partial initialization */ + return offset+cadr(e); + } ass = assign_expr0( (n->sc==REGISTER||n->sc==DREGISTER||n->sc==FREGISTER||n->sc==LREGISTER)? list3(n->sc,n->dsp,(int)n): @@ -2382,6 +2399,12 @@ error(DCERR); return offset; } + if (t>0&&car(t)==BIT_FIELD) { + sz = 0; + bfd = caddr(t); /* bit_field_disp */ + code_bit_field_disp(cadr(t),cadddr(t),&offset,&bfd,&sz); + return offset+sz; + } return offset+((t==EMPTY)?cadr(e):size(t)); } @@ -2607,8 +2630,8 @@ case POINTER: break; case BIT_FIELD: - return list4(BIT_FIELD,caddr(type),cadddr(type),rvalue(cadddr(e))); - /* bit offset, bit size, rvalue */ + return list3(RBIT_FIELD,rvalue(cadddr(e)),type); + /* byte rvalue, type */ type = cadr(e); break; default: @@ -2727,7 +2750,7 @@ } if (type>0&&car(type)==BIT_FIELD) { // n->ty = list4(BIT_FIELD,type,bit_offset, bit_size); - e=list4(BIT_FIELD, caddr(type),cadddr(type), e); + e=list3(BIT_FIELD,e,type); } return e; } @@ -3134,6 +3157,64 @@ return (cadr(e)); } +#define is_long_type(type) (type==LONGLONG||type==ULONGLONG) + +#if BIT_FIELD_CODE +static int +bit_field(int e1,int t) +{ + g_expr(e1); + code_bit_field(cadr(t) /* type */, + caddr(t) /* bit offset */, + USE_CREG); + return cadr(t); +} + +static int +bit_field_repl(int e1,int e2,int t) +{ + /* e1 = e2 */ + int lo = is_long_type(cadr(t)); + g_expr(e2); + if (lo) emit_lpush(); else emit_push(); + g_expr(e1); + code_bit_replace(USE_CREG,(e2=lo?emit_lpop():pop_register()), + t /* type */,caddr(t) /* bit offset */); + if (lo) emit_lpop_free(e2) else emit_pop_free(e2); + return cadr(t); +} + +static int +bassop(int e2,int e3,int op,int t) +{ + int type = cadr(t); + /* if op==NULL e2 = e3 */ + /* e2 = e2 op e3; */ + if (car(e2)==LREGISTER||car(e2)==REGISTER||car(e2)==LVAR||car(e2)==GVAR) { + g_expr(assign_expr0(e2, + list4(BFD_REPL,e2,op?list3(op,rvalue_t(e2,t),e3):e3,t), + type,type)); + return type; + } + /* new = &e2 */ + /* *new = *new op e3 */ + n = list2(LVAR,new_lvar(size_of_int)); + g_expr_u(assign_expr0(n,list2(ADDRESS,e2),INT,INT)); + g_expr(assign_expr0(list2(INDIRECT,n), + list4(BFD_REPL,n,op?list3(op,n,e3):e3,t), + type,type)); + free_lvar(cadr(n)); + return type; +} + +static int +bassign(int e2,int e3,int t) +{ + return bassop(e2,e3,0,t); +} + +#endif + /* temporal local variable free list */ static int lvar_list,lvar_free_list;
--- a/mc-parse.c Tue Jun 22 01:24:00 2004 +0900 +++ b/mc-parse.c Wed Jun 23 16:10:03 2004 +0900 @@ -1116,7 +1116,11 @@ return offset; /* not reached */ } } else if (t1==BIT_FIELD) { - error(DCERR); // not supported now + e=expr1(); + mode = mode_save; + offset = assign_data(e,t,n,offset); + type=t; + return offset; } else if (t1==STRUCT) { if (sym==LC) { conv->lc_(); conv->decl_data_begin_();
--- a/mc-parse.h Tue Jun 22 01:24:00 2004 +0900 +++ b/mc-parse.h Wed Jun 23 16:10:03 2004 +0900 @@ -9,7 +9,7 @@ extern int gtypedefed; extern int retlabel,retpending,retcont; extern int chk; -#if BITFIELD_CODE +#if BIT_FIELD_CODE extern int bit_field_disp; #endif extern int fields;
--- a/mc.h Tue Jun 22 01:24:00 2004 +0900 +++ b/mc.h Wed Jun 23 16:10:03 2004 +0900 @@ -4,7 +4,7 @@ #define LONGLONG_CODE 1 #define CASE_CODE 1 #define ASM_CODE 1 -#define BITFIELD_CODE 1 +#define BIT_FIELD_CODE 1 /* reserved word start */ @@ -69,7 +69,6 @@ #define VOLATILE (-57) #define TYPEOF (-58) #define ASM (-59) -#define BIT_FIELD (-60) /* reserved word end */ @@ -199,52 +198,54 @@ #define LURINDIRECT (LOP+URINDIRECT) #define RSTRUCT 27 #define ALLOCA 28 -#define CONV 29 +#define BIT_FIELD 29 +#define RBIT_FIELD 30 +#define CONV 31 #define UNARY_ARGS(i) (ADDRESS<=(i%SOP)&&(i%SOP)<=CONV) /* binary argments */ -#define MUL 30 -#define UMUL 31 -#define DIV 32 -#define UDIV 33 -#define MOD 34 -#define UMOD 35 -#define ADD 36 -#define SUB 37 -#define CMP 38 -#define RSHIFT 39 -#define URSHIFT 40 -#define LSHIFT 41 -#define ULSHIFT 42 -#define GT 43 -#define UGT 44 -#define GE 45 -#define UGE 46 -#define LT 47 -#define ULT 48 -#define LE 49 -#define ULE 50 -#define EQ 51 -#define NEQ 52 -#define BAND 53 -#define EOR 54 -#define BOR 55 -#define LAND 56 -#define LOR 57 -#define ASS 58 -#define UCMP 59 -#define UCMPGE 60 -#define CMPGE 61 -#define CMPEQ 62 -#define CMPNEQ 63 -#define ASSOP 64 -#define COMMA 65 +#define MUL 32 +#define UMUL 33 +#define DIV 34 +#define UDIV 35 +#define MOD 36 +#define UMOD 37 +#define ADD 38 +#define SUB 39 +#define CMP 40 +#define RSHIFT 41 +#define URSHIFT 42 +#define LSHIFT 43 +#define ULSHIFT 44 +#define GT 45 +#define UGT 46 +#define GE 47 +#define UGE 48 +#define LT 49 +#define ULT 50 +#define LE 51 +#define ULE 52 +#define EQ 53 +#define NEQ 54 +#define BAND 55 +#define EOR 56 +#define BOR 57 +#define LAND 58 +#define LOR 59 +#define ASS 60 +#define UCMP 61 +#define UCMPGE 62 +#define CMPGE 63 +#define CMPEQ 64 +#define CMPNEQ 65 +#define ASSOP 66 +#define COMMA 67 -#define CASS 66 -#define CASSOP 67 -#define CUASSOP 68 +#define CASS 68 +#define CASSOP 69 +#define CUASSOP 70 #define SASS (SOP+CASS) #define SASSOP (SOP+CASSOP) @@ -300,17 +301,18 @@ #define LEOR (LOP+EOR) #define LBOR (LOP+BOR) -#define BASS 69 -#define BASSOP 70 +#define BASS 71 +#define BASSOP 72 +#define BFD_REPL 73 -#define STASS 71 +#define STASS 74 #define BINARY_ARGS(i) (MUL<=(i%SOP)&&(i%SOP)<=STASS) /* tarnary argments */ -#define COND 72 +#define COND 75 #define SCOND (SOP+COND) #define DCOND (DOP+COND) #define FCOND (FOP+COND) @@ -320,19 +322,19 @@ /* not appeared as tags */ -#define I2I 73 -#define I2U 74 -#define I2D 75 -#define I2F 76 -#define I2LL 77 -#define I2ULL 78 +#define I2I 76 +#define I2U 77 +#define I2D 78 +#define I2F 79 +#define I2LL 80 +#define I2ULL 81 -#define U2I 79 -#define U2U 80 -#define U2D 81 -#define U2F 82 -#define U2LL 83 -#define U2ULL 84 +#define U2I 82 +#define U2U 83 +#define U2D 84 +#define U2F 85 +#define U2LL 86 +#define U2ULL 87 #define D2I (DOP+I2I) #define D2U (DOP+I2U) @@ -362,17 +364,17 @@ #define ULL2LL (LOP+U2LL) #define ULL2ULL (LOP+U2ULL) -#define LPAR 85 -#define RPAR 86 -#define LBRA 87 -#define RBRA 88 -#define LC 89 -#define RC 90 -#define COLON 91 -#define SM 92 -#define PERIOD 93 -#define ARROW 94 -#define CNAME 95 +#define LPAR 88 +#define RPAR 89 +#define LBRA 90 +#define RBRA 91 +#define LC 92 +#define RC 93 +#define COLON 94 +#define SM 95 +#define PERIOD 96 +#define ARROW 97 +#define CNAME 98 /* tree node tags end */