diff mc-code-ia32.c @ 365:5ac17fa9d7e0

bit-field constant assignment
author kono
date Wed, 07 Jul 2004 14:34:25 +0900
parents c29eebf3eaf4
children 2d510935c37d
line wrap: on
line diff
--- 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 */