Mercurial > hg > CbC > old > device
changeset 428:61c77ff18023
MIPS bitfield fix
author | kono |
---|---|
date | Sat, 30 Oct 2004 20:53:18 +0900 |
parents | 0c256ea2a97e |
children | 7733da111bd6 |
files | Changes mc-code-mips.c test/bitfield1.c |
diffstat | 3 files changed, 61 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Sat Oct 30 18:49:25 2004 +0900 +++ b/Changes Sat Oct 30 20:53:18 2004 +0900 @@ -6390,3 +6390,9 @@ で、a は定数代入にはならないのね? 通常はいいんだけど、bitfield とかでは余り良くないね。 + +Sat Oct 30 20:39:34 JST 2004 + +MIPS の$4,$5,$6,$7 は引数渡しに使われるわけだけど、 +6,7にlong long が入るときには、$5 には、$6 と同じ値が入る? +いや、bitfield1.c の printf の %lld が %d になっていただけでした。
--- a/mc-code-mips.c Sat Oct 30 18:49:25 2004 +0900 +++ b/mc-code-mips.c Sat Oct 30 20:53:18 2004 +0900 @@ -1112,16 +1112,16 @@ return list2(LVAR,new_lvar(SIZE_OF_DOUBLE)); } -void - +int emit_push() { - int new_reg; + int new_reg,old=creg; if (!is_int_reg(creg)) error(-1); if (reg_sp>MAX_MAX) error(-1); new_reg = get_register(); /* 絶対に取れる */ reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ ireg = creg = new_reg; + return old; } int @@ -5452,10 +5452,13 @@ /* bit field alignment calcuration */ static void -set_bitsz(int type,int *psign,int *pbitsz,int *palign,int *pl) +set_bitsz(int type,int *pbitpos, int *pbitsize, + int *psign,int *pbitsz,int *palign,int *pl) { int sign=0,bitsz; int align,l=0; + *pbitpos = cadr(caddr(type)); + *pbitsize = caddr(caddr(type)); switch(cadr(type)) { /* value type */ case INT: sign=1; bitsz=32; align=4;break; case UNSIGNED: bitsz=32; align=4;break; @@ -5486,8 +5489,8 @@ int bitpos = *bfd; int offset = *poffset; int l; - int bitsize = caddr(caddr(type)); - set_bitsz(type,&sign,&bitsz,&align,&l); + int bitsize,bitpos0; + set_bitsz(type,&bitpos0,&bitsize,&sign,&bitsz,&align,&l); if (bitsize>bitsz) { error(BTERR); bitsize = i; } @@ -5517,7 +5520,7 @@ *poffset = (offset += (align-i)); } bitpos = 0; - *bfd = bitsize; + *bfd = (bitsize==bitsz)?0:bitsize; *sz = (bitsize+7)/8; // printf("# bitpos=%d bitsize=%d bitsz=%d offset=%d\n",bitpos,bitsize,bitsz,*poffset); @@ -5526,18 +5529,20 @@ /* bit field value */ -/* reg contains container value, result should be in reg */ extern void -code_bit_field(int type,int bitpos,int reg) +code_bit_field(int type,int adr,int reg) { int sign,bitsz,l,align; - int bitsize = caddr(caddr(type)); - int i; - set_bitsz(type,&sign,&bitsz,&align,&l); + int bitsize,bitpos; + int i,size; + set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); + size = bitsz/8; // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); /* this implementation returns -1 for int i:1; */ if (l==1) { + use_int(adr); use_longlong(reg); + lload(adr,reg,0); /* shift left */ if ((i=bitsz-bitsize-bitpos)) loprtc(LLSHIFT,reg,list2(CONST,i)); @@ -5545,7 +5550,9 @@ if ((i=bitsz-bitsize)) loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i)); } else { + use_int(adr); use_int(reg); + ld_indexx(size, 0, adr, reg, sign); /* shift left */ if ((i=32-bitsize-bitpos)) oprtc(LSHIFT,reg,list2(CONST,i)); @@ -5573,16 +5580,20 @@ } extern void -code_bit_replace(int value,int lvalue,int type,int bitpos) +code_bit_replace(int adr,int value,int type) { int sign,bitsz,l,align; - int bitsize = caddr(caddr(type)); + int bitsize,bitpos; int mask = 0; - int tmp = -1; + int tmp = -1,lvalue,size; char *crn,*lrn,*trn; - set_bitsz(type,&sign,&bitsz,&align,&l); + set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); + size = bitsz/8; // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); if (l) { + use_int(adr); + lvalue = get_lregister(); + lload(adr,lvalue,0); use_longlong(value); crn = lregister_name_high(value); lrn = lregister_name_high(lvalue); @@ -5602,8 +5613,12 @@ mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); make_mask_and_or(mask,tmp,trn,crn,lrn); } + code_lassign(adr,value); } else { + use_int(adr); use_int(value); + lvalue = get_register(); + ld_indexx(size, 0, adr, lvalue, sign); crn = register_name(value); lrn = register_name(lvalue); /* shift left */ @@ -5613,8 +5628,13 @@ /* make and-mask */ mask = make_mask(32-bitpos-bitsize,31-bitpos); make_mask_and_or(mask,tmp,trn,crn,lrn); + code_assign(adr,size,value); } + free_register(lvalue); if (tmp!=-1) free_register(tmp); + if (use) { + code_bit_field(type,adr,USE_CREG); + } } @@ -5647,21 +5667,25 @@ } extern void -code_bit_replace_const(int value,int lvalue,int type,int bitpos) +code_bit_replace_const(int value,int adr,int type) { int sign,bitsz,l,align; - int bitsize = caddr(caddr(type)); + int bitsize,bitpos,size; int mask = 0; int c; + int lvalue; #if LONGLONG_CODE long long lc; #endif char *crn; - set_bitsz(type,&sign,&bitsz,&align,&l); + set_bitsz(type,&bitpos,&bitsize,&sign,&bitsz,&align,&l); + size = bitsz/8; // printf("# %d: bitpos=%d bitsize=%d bitsz=%d\n",lineno,bitpos,bitsize,bitsz); if (l) { #if LONGLONG_CODE - use_longlong(lvalue); + use_int(adr); + lvalue = get_lregister(); + lload(adr,lvalue,0); crn = lregister_name_high(lvalue); /* shift left */ lc = lcadr(value); @@ -5677,17 +5701,25 @@ mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos); make_mask_and_or_const(mask,crn,(int)lc); } + code_lassign(adr,lvalue); #endif } else { - use_int(lvalue); + use_int(adr); + lvalue = get_register(); crn = register_name(lvalue); + ld_indexx(size, 0, adr, lvalue, sign); /* 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); - } + code_assign(adr,size,lvalue); + } + free_register(lvalue); + if (use) { + code_bit_field(type,adr,USE_CREG); + } }
--- a/test/bitfield1.c Sat Oct 30 18:49:25 2004 +0900 +++ b/test/bitfield1.c Sat Oct 30 20:53:18 2004 +0900 @@ -202,7 +202,7 @@ ll.a[0],ll.a[1],ll.a[2],ll.a[3], ll.a[4],ll.a[5],ll.a[6],ll.a[7] ); - printf("#0204: ll.b.v=%d ll.b.w=%d ll.b.x=%d\n",ll.b.v,ll.b.w,ll.b.x); + printf("#0204: ll.b.v=%lld ll.b.w=%lld ll.b.x=%lld\n",ll.b.v,ll.b.w,ll.b.x); } ll.a[i]=0; }