Mercurial > hg > CbC > old > device
changeset 424:485bf7dde96a non-aligned-bit-field
ARM non-aligned bitfield
author | kono |
---|---|
date | Fri, 29 Oct 2004 20:34:08 +0900 |
parents | 8b9136a06f56 |
children | 7851023f5af1 |
files | .gdbinit Changes mc-code-arm.c mc-codegen.c test/bitfield.c |
diffstat | 5 files changed, 116 insertions(+), 75 deletions(-) [+] |
line wrap: on
line diff
--- a/.gdbinit Fri Oct 29 14:20:19 2004 +0900 +++ b/.gdbinit Fri Oct 29 20:34:08 2004 +0900 @@ -1,5 +1,5 @@ tb main -run -s test/bitfield1.c +run -s test/bitfield.c # run -s mc-parse.c # run -s mc-codegen.c # run -s nkf203/nkf.c
--- a/Changes Fri Oct 29 14:20:19 2004 +0900 +++ b/Changes Fri Oct 29 20:34:08 2004 +0900 @@ -6355,4 +6355,17 @@ この手のbit-field って、本来なら、inline で *C* で記述されるべき ものだよね。 - +Fri Oct 29 20:30:41 JST 2004 + +できたけど.... bassign の中のsassignでアドレスが狂うバグが +あるらしい。本来は、余計なコピーがあっても、害はないはず +なんだが、 +diff test/bitfield.gcc.out test/bitfield.mc-arm.out +1058c1058 +< 2:00000000 00000000 00000000 def00000 56789abc 00000234 00000000 00000000 +--- +> 2:00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +と言う形で、上書きしてしまう。 + +dum()をはさむと直ったしするのでレジスタのメンテナンスの +問題らしいが...
--- a/mc-code-arm.c Fri Oct 29 14:20:19 2004 +0900 +++ b/mc-code-arm.c Fri Oct 29 20:34:08 2004 +0900 @@ -5994,43 +5994,41 @@ } 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 - + + <-----bitsize---------------> + hhhhhh mmmmmmmmmmmm lllllll + lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh + |-----||-----------||------------||-------||-------| + <-bitpos---> + <----------------bitsz-----------------------------> + <-----32----------> <---32------> <----32----------> (r0:r1) <<= bitsz-bitsize-bitbos rest >> = b; rest << = a; (b>a) ==> rest >> (b-a) (64+32-bitsize -bitpos - (bitsz-bitsize)) = 64+32 -bitsz -bitbpos */ - if ((i=bitpos)) - loprtc(LLSHIFT,lreg,list2(CONST,i)); + /* load hhhhh */ + code_ld(cload(0,0),regv_h(lreg),SIZE_OF_INT*2,reg,cext_at(0,0)); + /* load mmmmmm */ + code_ld(cload(0,0),regv_l(lreg),SIZE_OF_INT,reg,cext_at(0,0)); + i = 64-(bitsize-(32-bitpos)); + loprtc(LLSHIFT,lreg,list2(CONST,i)); if (i<0||64<=i) error(-1); - /* shift right */ - if ((i=SIZE_OF_LONGLONG*8-bitsize)) - loprtc(sign?LRSHIFT:LURSHIFT,lreg,list2(CONST,i)); - if (i<0||64<=i) error(-1); - if ((i=bitsz-bitsize-bitpos)) - oprtc(RSHIFT,reg,list2(CONST,i)); + /* load lllll */ + code_ld(cload(0,0),reg,0,reg,cext_at(0,0)); + i = (bitsize-(32-bitpos))-32; + oprtc(URSHIFT,reg,list2(CONST,i)); if (i<0||32<=i) error(-1); inc_inst(1); printf("\tadd\t%s,%s,%s\n", - register_name(regv_h(lreg)), - register_name(regv_h(lreg)), + register_name(regv_l(lreg)), + register_name(regv_l(lreg)), register_name(reg)); + i = 64-bitsize; + loprtc(sign?LRSHIFT:LURSHIFT,lreg,list2(CONST,i)); + if (i<0||64<=i) error(-1); set_lreg(lreg,1); } else { use_int(reg); @@ -6097,37 +6095,45 @@ tmpvar=new_lvar(SIZE_OF_LONGLONG); code_lassign_lvar(tmpvar,value); use_int(lvalue); - lrn = register_name(tmp = get_register()); - - i=bitsz-bitpos-bitsize; + trn = register_name(tmp = get_register()); + + /* make and-mask upper */ + i=bitpos; if (i) - oprtc(RSHIFT,regv_l(value),list2(CONST,i)); + 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),tmp,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); + code_ld(cload(0,0),regv_h(value),0,lvalue,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)); /* - 111111 222222222222 1111111 - 0000000000 111111 222222222222 1111111 0000000 - |----------||------||------------||-------||-------| + <-----bitsize---------------> + hhhhhh mmmmmmmmmmmm lllllll + lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh + |-----||-----------||------------||-------||-------| + <-bitpos---> + <----------------bitsz-----------------------------> + <-----32----------> <---32------> <----32----------> */ + /* store middle */ code_lrlvar(tmpvar,value); - i=bitsz-bitsize-bitpos; + i=32-bitpos; if (i) - loprtc(LLSHIFT,value,list2(CONST,i)); + 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),trn,register_name(lvalue)); - - code_ld(cload(0,0),tmp,SIZE_OF_INT*2,lvalue,cext_at(0,0)); - mask = make_mask(0,31-i); - make_mask_and_or(mask,regv_h(value),trn,crn,lrn); + printf("\t%s\t%s, [%s, #4]\n",cstore(0),crn,register_name(lvalue)); + + /* make and-mask lower */ + code_ld(cload(0,0),regv_l(value),SIZE_OF_INT*2,lvalue,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),crn,register_name(lvalue)); + printf("\t%s\t%s, [%s, #8]\n",cstore(0),lrn,register_name(lvalue)); free_lvar(tmpvar); set_ireg(lvalue,0); } else { @@ -6214,28 +6220,30 @@ make_mask_and_or_const(mask,crn,(int)lc); } } else if (l==2) { +/* + hhhhhh mmmmmmmmmmmm lllllll + lllll 00000000000 mmmmmmmmmmmm 0000000 hhhhhhh + |-----||-----------||------------||-------||-------| + */ 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,lvalue,cext_at(0,0)); - mask = make_mask(bitsz-bitpos-bitsize,bitsz-bitpos); - make_mask_and_or_const(mask,trn,(int)(lc>>32)); + mask = make_mask(0,31-bitpos); + make_mask_and_or_const(mask,trn,(int)(lc<<bitpos)); inc_inst(1); printf("\t%s\t%s, [%s, #0]\n",cstore(0),trn,crn); /* store middle */ - code_const((int)lc,tmp); + code_const((int)(lc>>(32-bitpos)),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,lvalue,cext_at(0,0)); - mask = make_mask(0,31-bitpos); - make_mask_and_or_const(mask,trn,(int)lc); + 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); #endif
--- a/mc-codegen.c Fri Oct 29 14:20:19 2004 +0900 +++ b/mc-codegen.c Fri Oct 29 20:34:08 2004 +0900 @@ -1309,9 +1309,11 @@ if (car(e4)==RSTRUCT) { e4 = cadr(e4); } - if (is_same_type(e2,e4)&&cadr(e2)==cadr(e4)) { - if (use) g_expr(e4); - return; + if (is_same_type(e2,e4)) { + if (cadr(e2)==cadr(e4)) { + if (use) g_expr(e4); + return; + } } g_expr(e4); emit_push(); @@ -3522,21 +3524,29 @@ } if (car(e2)==LREGISTER||car(e2)==REGISTER||car(e2)==LVAR||car(e2)==GVAR) { e4 = rvalue_t(e2,stype); - g_expr(assign_expr0(e2, list4(BFD_REPL,e4,e3,t), stype,stype)); + if (stype>0 && car(stype)==STRUCT) + g_expr(list4(BFD_REPL,e4,e3,t)); + else + g_expr(assign_expr0(e2, list4(BFD_REPL,e4,e3,t), stype,stype)); if (use) code_bit_field(t, cadr(caddr(t)) /* bit offset */, USE_CREG); return type; } /* new = &e2 */ /* *new = *new bit_repl e3 */ - 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)),stype); - g_expr(assign_expr0(list2(INDIRECT,rvalue_t(n,INT)), - list4(BFD_REPL,e4,e3,t), - stype,stype)); - free_lvar(cadr(n)); + if (stype>0 && car(stype)==STRUCT) { + e4 = rvalue_t(list2(INDIRECT,rvalue_t(n,INT)),stype); + g_expr(list4(BFD_REPL,list2(ADDRESS,cadr(e2)),e3,t)); + } else { + n = list2(LVAR,new_lvar(size_of_int)); + g_expr_u(assign_expr0(n,list2(ADDRESS,cadr(e2)),INT,INT)); + 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), + stype,stype)); + free_lvar(cadr(n)); + } if (use) code_bit_field(t, cadr(caddr(t)) /* bit offset */, USE_CREG); return type;
--- a/test/bitfield.c Fri Oct 29 14:20:19 2004 +0900 +++ b/test/bitfield.c Fri Oct 29 20:34:08 2004 +0900 @@ -534,7 +534,7 @@ } b; } ii; -int m1 = -1; +long long m1 = 0x123456789abcdefLL; int p1 = 1; int zero = 0; @@ -543,60 +543,68 @@ ii.b.a = -1; printf("m5c-00:%d\n",ii.b.a); - ll1.b.v = -1; + ll1.b.v = 0x123456789abcdefLL; printf("m5c-01:%llx\n",ll1.b.v); printf("m5c-02:%08x %08x %08x %08x %08x %08x %08x %08x\n", ll1.a[0],ll1.a[1],ll1.a[2],ll1.a[3], ll1.a[4],ll1.a[5],ll1.a[6],ll1.a[7] ); ll1.b.v = 0; - ll1.b.w = -1; + printf("m5c-01:%llx\n", + ll1.b.w = 0x123456789abcdefLL); printf("m5c-02:%08x %08x %08x %08x %08x %08x %08x %08x\n", ll1.a[0],ll1.a[1],ll1.a[2],ll1.a[3], ll1.a[4],ll1.a[5],ll1.a[6],ll1.a[7] ); ll1.b.w = 0; - ll1.b.x = -1; + printf("m5c-01:%llx\n", + ll1.b.x = 0x123456789abcdefLL); printf("m5c-02:%08x %08x %08x %08x %08x %08x %08x %08x\n", ll1.a[0],ll1.a[1],ll1.a[2],ll1.a[3], ll1.a[4],ll1.a[5],ll1.a[6],ll1.a[7] ); ll1.b.x = 0; - ll0.b.v = -1; + printf("m5c-01:%llx\n", + ll0.b.v = 0x123456789abcdefLL); printf("m5c-01:%llx\n",ll0.b.v); printf("m5c-02:%08x %08x %08x %08x %08x %08x %08x %08x\n", ll0.a[0],ll0.a[1],ll0.a[2],ll0.a[3], ll0.a[4],ll0.a[5],ll0.a[6],ll0.a[7] ); ll0.b.v = 0; - ll0.b.w = -1; + printf("m5c-01:%llx\n", + ll0.b.w = 0x123456789abcdefLL); printf("m5c-02:%08x %08x %08x %08x %08x %08x %08x %08x\n", ll0.a[0],ll0.a[1],ll0.a[2],ll0.a[3], ll0.a[4],ll0.a[5],ll0.a[6],ll0.a[7] ); ll0.b.w = 0; - ll0.b.x = -1; + printf("m5c-01:%llx\n", + ll0.b.x = 0x123456789abcdefLL); printf("m5c-02:%08x %08x %08x %08x %08x %08x %08x %08x\n", ll0.a[0],ll0.a[1],ll0.a[2],ll0.a[3], ll0.a[4],ll0.a[5],ll0.a[6],ll0.a[7] ); ll0.b.x = 0; - ll.b.v = -1; + printf("m5c-01:%llx\n", + ll.b.v = 0x123456789abcdefLL); printf("m5c-1:%llx\n",ll.b.v); printf("m5c-2:%08x %08x %08x %08x %08x %08x %08x %08x\n", ll.a[0],ll.a[1],ll.a[2],ll.a[3], ll.a[4],ll.a[5],ll.a[6],ll.a[7] ); ll.b.v = 0; - ll.b.w = -1; + printf("m5c-01:%llx\n", + ll.b.w = 0x123456789abcdefLL); printf("m5c-2:%08x %08x %08x %08x %08x %08x %08x %08x\n", ll.a[0],ll.a[1],ll.a[2],ll.a[3], ll.a[4],ll.a[5],ll.a[6],ll.a[7] ); ll.b.w = 0; - ll.b.x = -1; + printf("m5c-01:%llx\n", + ll.b.x = 0x123456789abcdefLL); printf("m5c-2:%08x %08x %08x %08x %08x %08x %08x %08x\n", ll.a[0],ll.a[1],ll.a[2],ll.a[3], ll.a[4],ll.a[5],ll.a[6],ll.a[7] @@ -604,6 +612,7 @@ ll.b.x = 0; printf("m5c-char a:1; char b:4; char c:7; char d:4; char e:4; char f:4;\n"); + cc.a = 0; cc.b.a = -1; printf("m5c-a:%08x\n",cc.a); cc.b.b = -1; @@ -735,6 +744,7 @@ ); ll.b.x = zero; + cc.a = zero; printf("char a:1; char b:4; char c:7; char d:4; char e:4; char f:4;\n"); cc.b.a = m1; printf("a:%08x\n",cc.a);