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;
     }