changeset 330:fa4c7b15d7ed

bit field all code written
author kono
date Wed, 23 Jun 2004 17:12:33 +0900
parents 4c8f8ef8c0cf
children f25aa4f03198
files mc-code-powerpc.c
diffstat 1 files changed, 59 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-powerpc.c	Wed Jun 23 16:10:03 2004 +0900
+++ b/mc-code-powerpc.c	Wed Jun 23 17:12:33 2004 +0900
@@ -5178,29 +5178,76 @@
 
 /* bit field replacement */
 
+static int
+make_mask(int from,int to)
+{
+    int mask = 0;
+    int bit = 1;
+    int i;
+    if (from<0||from>32) error(-1);
+    for (i=31;from<=i;i--,bit<<1) {
+	if (i<=to) {
+	    mask |= bit;
+	} 
+    }
+}
+
+static void
+make_mask_and_or(int mask,int tmp,char *trn,*crn,*lrn)
+{
+	code_const(~mask,tmp);
+	printf("\tor %s,%s,%s\n",trn,crn,trn);
+	/* do conjunction  */
+	printf("\tand %s,%s,%s\n",lrn,trn,lrn);
+	/* make or-mask  */
+	code_const(mask,tmp);
+	printf("\tand %s,%s,%s\n",trn,crn,trn);
+	/* do disjunction  */
+	printf("\tor %s,%s,%s\n",lrn,trn,lrn);
+}
+
 extern void
 code_bit_replace(int value,int lvalue,int type,int bit_offset)
 {
     int sign,bitsz,l;
     int bitsize = cadddr(type);
+    int mask = 0;
+    int tmp = -1;
+    char *crn,*lrn,*trn;
     set_bitsz(type,&sign,&bitsz,&l);
     if (l) {
-	use_longlong(reg);
-	/* make and-mask lower */
-	/* make and-mask upper */
-	/* make or-mask  lower */
-	/* make or-mask  upper */
+	use_longlong(value);
+	crn = lregister_name_low(value);
+	lrn = lregister_name_low(lvalue);
 	/* shift left */
-	/* do conjunction  */
-	/* do disjunction  */
+	if ((i=bitsz-bitsize-bitpos)) 
+	    loprtc(LLSHIFT,reg,i);
+	trn = register_name(tmp = get_register());
+	if (bitpos+bitsize>32) {
+	    /* make and-mask lower */
+	    mask = make_mask(bitpos>32?bitpos-32:0,bitpos+bitsize-32);
+	    make_mask_and_or(mask,tmp,trn,crn,lrn);
+	}
+	crn = lregister_name_high(value);
+	lrn = lregister_name_high(lvalue);
+	if (bitpos<32) {
+	    /* make and-mask upper */
+	    mask = make_mask(bitpos,bitpos+bitsize>32?31:bitpos+bitsize);
+	    make_mask_and_or(mask,tmp,trn,crn,lrn);
+	}
     } else {
-	use_int(reg);
+	use_int(value);
+	crn = register_name(value);
+	lrn = register_name(lvalue);
+	/* shift left */
+	if ((i=bitsz-bitsize-bitpos)) 
+	    oprtc(LSHIFT,reg,i);
+	trn = register_name(tmp = get_register());
 	/* make and-mask */
-	/* make or-mask  */
-	/* shift left */
-	/* do conjunction  */
-	/* do disjunction  */
+	mask = make_mask(bitpos+(32-bitsz),bitpos+bitsize);
+	make_mask_and_or(mask,tmp,trn,crn,lrn);
     }
+    if (tmp!=-1) free_register(tmp);
 }
 
 #endif