changeset 365:5ac17fa9d7e0

bit-field constant assignment
author kono
date Wed, 07 Jul 2004 14:34:25 +0900
parents c29eebf3eaf4
children 2d510935c37d
files .gdbinit Changes Makefile mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-code.h mc-codegen.c test/bitfield.c
diffstat 9 files changed, 418 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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 になっちゃってるな。
+
+あ、いけない、なんか壊しちゃったよ。。。
--- 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)
--- 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]<MAX_DATA_REG && ((a& ~0xffff)==~0xffff)) {
+	    if ((a& ~0xff)==~0xff)
+		printf("\tandb $%d,%s\n",a&0xff,register_name(reg,1));
+	    else
+		printf("\tandw $%d,%s\n",a&0xffff,register_name(reg,2));
+	} else
+	    printf("\tandl $%d,%s\n",a,register_name(reg,0));
+    }
+    /* make or-mask  */
+    c = mask&c;
+    if (c!=0) {
+	/* do disjunction  */
+	if (rname[reg]<MAX_DATA_REG && (!(c& ~0xffff))) {
+	    if (!(c& ~0xff))
+		printf("\torb $%d,%s\n",c&0xff,register_name(reg,1));
+	    else
+		printf("\torw $%d,%s\n",c&0xffff,register_name(reg,2));
+	} else
+	    printf("\torl $%d,%s\n",c,register_name(reg,0));
+    }
+}
+
+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
+    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);
+	/* 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,
+		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 */
--- 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 */
--- 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 */
--- 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
 
--- 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);
--- 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 */