# HG changeset patch # User kono # Date 1089178465 -32400 # Node ID 5ac17fa9d7e0c5152354cb955fd0f92e4713d164 # Parent c29eebf3eaf44f3718172f19d58368d62d1323ca bit-field constant assignment diff -r c29eebf3eaf4 -r 5ac17fa9d7e0 .gdbinit --- a/.gdbinit Tue Jul 06 17:55:40 2004 +0900 +++ b/.gdbinit Wed Jul 07 14:34:25 2004 +0900 @@ -4,7 +4,7 @@ # run -s nkf203/nkf.c # run -s -ob01.s mc-switch.c # run -s l.c -run -s test/scope.c +run -s test/bitfield.c # run -s test/code-gen-all.c define regs printf "pc =%08x lr =%08x r0 =%08x r1 =%08x r3= %08x r4= %08x\n",$pc,$lr,$r0,$r1,$r3,$r4 diff -r c29eebf3eaf4 -r 5ac17fa9d7e0 Changes --- a/Changes Tue Jul 06 17:55:40 2004 +0900 +++ b/Changes Wed Jul 07 14:34:25 2004 +0900 @@ -5523,3 +5523,5 @@ type は、LTDECL のみで局所っていうようにするべきだよね。 static が global になっちゃってるな。 + +あ、いけない、なんか壊しちゃったよ。。。 diff -r c29eebf3eaf4 -r 5ac17fa9d7e0 Makefile --- a/Makefile Tue Jul 06 17:55:40 2004 +0900 +++ b/Makefile Wed Jul 07 14:34:25 2004 +0900 @@ -80,6 +80,7 @@ make check TARGET=test/bitfield make check TARGET=test/bitfield1 make check TARGET=test/cext + make check TARGET=test/scope STDFLAG="-std=gnu99" #MK =-make MK= check-all-code: @@ -104,7 +105,7 @@ # -./$(MC) -Itest/ -s $(TARGET).c check: $(MC) $(TARGET).c - -gcc -std=gnu99 $(TARGET).c -o b.out $(MLIB) + -gcc $(STDFLAG) $(TARGET).c -o b.out $(MLIB) -./b.out > $(TARGET).gcc.out -./$(MC) -s $(TARGET).c -gcc $(TARGET).s $(MLIB) diff -r c29eebf3eaf4 -r 5ac17fa9d7e0 mc-code-ia32.c --- a/mc-code-ia32.c Tue Jul 06 17:55:40 2004 +0900 +++ b/mc-code-ia32.c Wed Jul 07 14:34:25 2004 +0900 @@ -1286,6 +1286,9 @@ } else if (ret_type==VOID) { regv[freg]=0; regv[creg]=0; } else { + if (!is_int_reg(creg)) { + lreg=0; creg=virtual(REG_EAX); + } use_register(creg,REG_EAX,0); fregv[freg]=0; regv[creg]=1; } @@ -3460,6 +3463,80 @@ } } + +static void +make_mask_and_or_const(int mask,int reg,int c) +{ + int a; +// printf("# mask 0x%08x ~0x%08x\n",mask,~mask); + a = ~mask|c; + if (a!=-1) { + /* do conjunction */ + if (rname[reg]=32) { + /* make and-mask upper */ + mask = make_mask(64-bitpos-bitsize,bitpos>=32?63-bitpos:31); + make_mask_and_or_const(mask, + virtual(lvalue==REG_L?REG_EDI:REG_EDX),(int)(lc>>32)); + } + if (bitpos<32) { + /* make and-mask lower */ + mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); + make_mask_and_or_const(mask, + virtual(lvalue==REG_L?REG_ESI:REG_EAX),(int)(lc)); + } +#endif + } else { + use_int(lvalue); + /* shift left */ + c = cadr(value); + c <<= bitpos; + /* make and-mask */ + mask = make_mask(32-bitpos-bitsize,31-bitpos); + make_mask_and_or_const(mask,lvalue,c); + } +} + + #endif /* end */ diff -r c29eebf3eaf4 -r 5ac17fa9d7e0 mc-code-mips.c --- a/mc-code-mips.c Tue Jul 06 17:55:40 2004 +0900 +++ b/mc-code-mips.c Wed Jul 07 14:34:25 2004 +0900 @@ -5565,6 +5565,79 @@ if (tmp!=-1) free_register(tmp); } + +static void +make_mask_and_or_const(int mask,char *crn,int c) +{ + char *trn; + int tmp = -1; +// printf("# mask 0x%08x ~0x%08x\n",mask,~mask); + if ((~mask|c)!=-1) { + trn = register_name(tmp=get_register()); + code_const((~mask|c),tmp); + /* do conjunction */ + printf("\tand %s,%s,%s\n",crn,trn,crn); + } + /* make or-mask */ + c = mask&c; + if (c!=0) { + /* do disjunction */ + if (!((mask&c)&0xffff0000)) { + printf("\tori %s,%s,%d\n",crn,crn,c); + } else { + trn = register_name(tmp=get_register()); + code_const(c,tmp); + printf("\tor %s,%s,%s\n",crn,trn,crn); + } + } + if (tmp!=-1) free_register(tmp); +} + +extern void +code_bit_replace_const(int value,int lvalue,int type,int bitpos) +{ + int sign,bitsz,l,align; + int bitsize = cadddr(type); + int mask = 0; + int c; +#if LONGLONG_CODE + long long lc; +#endif + char *crn; + set_bitsz(type,&sign,&bitsz,&align,&l); +// printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); + if (l) { +#if LONGLONG_CODE + use_longlong(lvalue); + crn = lregister_name_high(lvalue); + /* shift left */ + lc = lcadr(value); + lc <<= bitpos; + if (bitpos+bitsize>=32) { + /* make and-mask upper */ + mask = make_mask(64-bitpos-bitsize,bitpos>=32?63-bitpos:31); + make_mask_and_or_const(mask,crn,(int)(lc>>32)); + } + crn = lregister_name_low(lvalue); + if (bitpos<32) { + /* make and-mask lower */ + mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); + make_mask_and_or_const(mask,crn,(int)lc); + } +#endif + } else { + use_int(lvalue); + crn = register_name(lvalue); + /* shift left */ + c = cadr(value); + c <<= bitpos; + /* make and-mask */ + mask = make_mask(32-bitpos-bitsize,31-bitpos); + make_mask_and_or_const(mask,crn,c); + } +} + + #endif /* end */ diff -r c29eebf3eaf4 -r 5ac17fa9d7e0 mc-code-powerpc.c --- a/mc-code-powerpc.c Tue Jul 06 17:55:40 2004 +0900 +++ b/mc-code-powerpc.c Wed Jul 07 14:34:25 2004 +0900 @@ -5235,6 +5235,80 @@ if (tmp!=-1) free_register(tmp); } +static void +make_mask_and_or_const(int mask,char *crn,int c) +{ + char *trn; + int tmp = -1; +// printf("# mask 0x%08x ~0x%08x\n",mask,~mask); + if ((~mask|c)!=-1) { + trn = register_name(tmp=get_register()); + code_const((~mask|c),tmp); + /* do conjunction */ + printf("\tand %s,%s,%s\n",crn,trn,crn); + } + /* make or-mask */ + c = mask&c; + if (c!=0) { + /* do disjunction */ + if (!((mask&c)&0xffff0000)) { + printf("\tori %s,%s,lo16(%d)\n",crn,crn,c); + } else { + trn = register_name(tmp=get_register()); + code_const(c,tmp); + printf("\tor %s,%s,%s\n",crn,trn,crn); + } + } + if (tmp!=-1) free_register(tmp); +} + +extern void +code_bit_replace_const(int value,int lvalue,int type,int bitpos) +{ + int sign,bitsz,l,align; + int bitsize = cadddr(type); + int mask = 0; + int i; + int c; +#if LONGLONG_CODE + long long lc; +#endif + char *crn; + set_bitsz(type,&sign,&bitsz,&align,&l); +// printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); + if (l) { +#if LONGLONG_CODE + use_longlong(lvalue); + crn = lregister_name_low(lvalue); + /* shift left */ + lc = lcadr(value); + if ((i=bitsz-bitsize-bitpos)) + lc <<= i; + if (bitpos+bitsize>=32) { + /* make and-mask lower */ + mask = make_mask(bitpos>=32?bitpos-32:0,bitpos+bitsize-32-1); + make_mask_and_or_const(mask,crn,(int)lc); + } + crn = lregister_name_high(lvalue); + if (bitpos<32) { + /* make and-mask upper */ + mask = make_mask(bitpos,bitpos+bitsize>=32?31:bitpos+bitsize-1); + make_mask_and_or_const(mask,crn,(int)(lc>>32)); + } +#endif + } else { + use_int(lvalue); + crn = register_name(lvalue); + /* shift left */ + c = cadr(value); + if ((i=bitsz-bitsize-bitpos)) + c <<= i; + /* make and-mask */ + mask = make_mask(bitpos+(32-bitsz),bitpos+bitsize-1+(32-bitsz)); + make_mask_and_or_const(mask,crn,c); + } +} + #endif /* end */ diff -r c29eebf3eaf4 -r 5ac17fa9d7e0 mc-code.h --- a/mc-code.h Tue Jul 06 17:55:40 2004 +0900 +++ b/mc-code.h Wed Jul 07 14:34:25 2004 +0900 @@ -282,6 +282,8 @@ extern void code_bit_replace(int value,int lvalue,int type,int bit_offset); /* register, register */ +extern void code_bit_replace_const(int value,int lvalue,int type,int bit_offset); + /* exp, register */ #endif diff -r c29eebf3eaf4 -r 5ac17fa9d7e0 mc-codegen.c --- a/mc-codegen.c Tue Jul 06 17:55:40 2004 +0900 +++ b/mc-codegen.c Wed Jul 07 14:34:25 2004 +0900 @@ -2446,7 +2446,7 @@ break; case LLDECL: nsc = FLABEL; - n->dsp = fwdlabel(); + ndsp = fwdlabel(); break; case ADECL: if(!integral(type)&&(car(type)==FUNCTION||car(type)==CODE)) { @@ -3440,8 +3440,14 @@ static int bit_field_repl(int e1,int e2,int t) { - /* e2 = e1 */ + /* e1 = e2 */ int lo = is_long_type(cadr(t)); + if ((car(e2)==CONST||car(e2)==LCONST)) { + g_expr(e1); + code_bit_replace_const(e2,USE_CREG, + t /* type */,caddr(t) /* bit offset */); + return cadr(t); + } g_expr(e1); if (lo) emit_lpush(); else emit_push(); g_expr(e2); diff -r c29eebf3eaf4 -r 5ac17fa9d7e0 test/bitfield.c --- a/test/bitfield.c Tue Jul 06 17:55:40 2004 +0900 +++ b/test/bitfield.c Wed Jul 07 14:34:25 2004 +0900 @@ -20,7 +20,7 @@ long long lpn:40; } pte; struct { - unsigned char v:1; + char v:1; signed long vsid:24; unsigned long h:1; signed char api:6; @@ -191,6 +191,8 @@ main5(); main3(); main4(); + main6(); + main7(); return 0; } @@ -737,3 +739,179 @@ return --b; } + +main6() +{ + int i =0; + g.pte.api = 0; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 1; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 2; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 3; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 4; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 5; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 6; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 7; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 8; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 9; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 10; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 11; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 12; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 13; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 14; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 15; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 16; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 17; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 18; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 19; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 20; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 21; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 22; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 23; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 24; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 25; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 26; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 27; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 28; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 29; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 30; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 31; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 32; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 33; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 34; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 35; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 36; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 37; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 38; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 39; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 40; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 41; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 42; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 43; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 44; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 45; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 46; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 47; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 48; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 49; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 50; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 51; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 52; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 53; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 54; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 55; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 56; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 57; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 58; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 59; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 60; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 61; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 62; + printf("main5: %d %d\n",i++,g.pte.api); + g.pte.api = 63; + printf("main5: %d %d\n",i++,g.pte.api); +} + +main7() +{ + int i; + for (i=-2;i<2;i++) { + g.pte.api = i; + if (g.pte.api) { + printf("main 7:1 %d yes\n",i); + } else { + printf("main 7:1 %d no\n",i); + } + if (g.pte.api==1) { + printf("main 7:2 %d yes\n",i); + } else { + printf("main 7:2 %d no\n",i); + } + if (g.pte.api==-1) { + printf("main 7:3 %d yes\n",i); + } else { + printf("main 7:3 %d no\n",i); + } + } + for (i=-2;i<2;i++) { + g.sg.v = i; + if (g.sg.v) { + printf("main 7:4 %d yes\n",i); + } else { + printf("main 7:4 %d no\n",i); + } + if (g.sg.v==1) { + printf("main 7:5 %d yes\n",i); + } else { + printf("main 7:5 %d no\n",i); + } + if (g.sg.v==-1) { + printf("main 7:6 %d yes\n",i); + } else { + printf("main 7:6 %d no\n",i); + } + } +} + +/* end */