changeset 429:7733da111bd6

arm register usage
author kono
date Sat, 30 Oct 2004 22:25:27 +0900
parents 61c77ff18023
children ba5faa547607
files mc-code-arm.c
diffstat 1 files changed, 89 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-arm.c	Sat Oct 30 20:53:18 2004 +0900
+++ b/mc-code-arm.c	Sat Oct 30 22:25:27 2004 +0900
@@ -129,6 +129,7 @@
 #define LREG_V 3    /* mark for virtual long long/double register */
 #define REGS_MAX (REAL_MAX_REGISTER+REAL_MAX_FREGISTER+REAL_MAX_LREGISTER+LREG_V)
 static int arm_regs[REGS_MAX];
+static int regs_use[REGS_MAX];
 static int regv_h0[REAL_MAX_LREGISTER+LREG_V];
 static int regv_l0[REAL_MAX_LREGISTER+LREG_V];
 #define regv_h(i)  regv_h0[(i)-LREG_OFFSET]
@@ -563,7 +564,7 @@
 void
 code_gexpr(int e){
      if (is_int_reg(creg) && creg!=ireg) error(-1);
-//  register_usage("code_gexpr");
+  register_usage("code_gexpr");
 }
 
 
@@ -1166,16 +1167,16 @@
     return list2(LVAR,new_lvar(d?SIZE_OF_DOUBLE:SIZE_OF_FLOAT));
 }
 
-void
-
+int
 emit_push()
 {
-    int new_reg;
+    int new_reg,old;
     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
@@ -2228,6 +2229,7 @@
 	case DPOSTINC : case DPREINC : case DASSOP :
 	case DOP+LT : case DOP+LE : case DOP+GT : case DOP+GE :
 	case DOP+EQ : case DOP+NEQ:
+	case RBIT_FIELD: case BASS: case BASSOP:
 	return 1;
     }
     return 0;
@@ -2468,7 +2470,7 @@
     int jmp = 0;
     int complex_;
     int pnargs,preg_arg,pfreg_arg;
-    int stargs;
+    int stargs,i;
     int half_register = 0;
 
     special_lvar = -1;
@@ -2655,6 +2657,9 @@
 	    free_register(cadr(arg));
 	else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg));
     }
+    for(i=1;i<MAX_INPUT_REGISTER_VAR;i++) {
+	free_register(i);
+    }
     if (ret_type==DOUBLE) {
         set_dreg(RET_DREGISTER,0);
         use_reg(RET_DREGISTER);
@@ -5857,10 +5862,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; break; 
     case UNSIGNED:	break; 
@@ -5908,8 +5916,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; }
 
@@ -5956,7 +5964,7 @@
 		i = l+bitsize;
 		*bfd = (i==bitsz)?0:i;
 	        *sz = (i+7)/8;
- printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset);
+// printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset);
 		return l;
 	    } 
 	}
@@ -5971,7 +5979,7 @@
     *bfd = (bitsize==bitsz)?0:bitsize;
     *sz = (bitsize+7)/8;
 
- printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset);
+// printf("# %d: bitpos=%d bitsize=%d bitsz=%d offset=%d\n",lineno,bitpos,bitsize,bitsz,*poffset);
     return bitpos;
 }
 
@@ -5979,16 +5987,19 @@
 
 /* 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,adhoc=-1;
+    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));
@@ -5996,8 +6007,8 @@
 	if ((i=bitsz-bitsize)) 
 	    loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i));
     } else if (l==2) {
-	use_int(reg);
-	lreg = get_lregister();
+	use_int(adr);
+	use_longlong(reg);
    /*
 
                         <-----bitsize--------------->
@@ -6013,29 +6024,35 @@
                   (64+32-bitsize -bitpos - (bitsz-bitsize))
                  = 64+32 -bitsz -bitbpos
    */
+	if (adr==regv_h(reg)||adr==regv_l(reg)) {
+//	    adhoc = get_register(); adhoc=1;
+//	    code_register(adr,adhoc);
+	}
 	/* load hhhhh */
-	code_ld(cload(0,0),regv_h(lreg),SIZE_OF_INT*2,reg,cext_at(0,0));
+	code_ld(cload(0,0),regv_h(reg),SIZE_OF_INT*2,adr,cext_at(0,0));
 	/* load mmmmmm */
-	code_ld(cload(0,0),regv_l(lreg),SIZE_OF_INT,reg,cext_at(0,0));
+	code_ld(cload(0,0),regv_l(reg),SIZE_OF_INT,adr,cext_at(0,0));
 	i = 64-(bitsize-(32-bitpos));
-	loprtc(LLSHIFT,lreg,list2(CONST,i));
+	loprtc(LLSHIFT,reg,list2(CONST,i));
 	if (i<0||64<=i) error(-1);
 	/* load lllll */
-	code_ld(cload(0,0),reg,0,reg,cext_at(0,0));
+	code_ld(cload(0,0),adr,0,adr,cext_at(0,0));
 	i = (bitsize-(32-bitpos))-32;
-	oprtc(URSHIFT,reg,list2(CONST,i));
+	oprtc(URSHIFT,adr,list2(CONST,i));
 	if (i<0||32<=i) error(-1);
 	inc_inst(1);
 	printf("\tadd\t%s,%s,%s\n",
-			    register_name(regv_l(lreg)),
-			    register_name(regv_l(lreg)),
-			    register_name(reg));
+			    register_name(regv_l(reg)),
+			    register_name(regv_l(reg)),
+			    register_name(adr));
 	i = 64-bitsize;
-	loprtc(sign?LRSHIFT:LURSHIFT,lreg,list2(CONST,i));
+	loprtc(sign?LRSHIFT:LURSHIFT,reg,list2(CONST,i));
 	if (i<0||64<=i) error(-1);
-	set_lreg(lreg,1);
+	if (adhoc>0) free_register(adhoc);
     } else {
+	use_int(adr);
 	use_int(reg);
+	code_ld(cload(0,0),reg,SIZE_OF_INT,adr,cext_at(0,0));
 	/* shift left */
 	if ((i=32-bitsize-bitpos)) 
 	    oprtc(LSHIFT,reg,list2(CONST,i));
@@ -6064,17 +6081,21 @@
 }
 
 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,i;
-    int bitsize = caddr(caddr(type));
+    int bitsize,bitpos;
     int mask = 0;
-    int tmp = -1;
+    int tmp = -1,lvalue,size;
     int tmpvar = -1;
     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==1) {
+        use_int(adr);
+        lvalue = get_lregister();
+        lload(adr,lvalue,0);
 	use_longlong(value);
 	crn = lregister_name_high(value);
 	lrn = lregister_name_high(lvalue);
@@ -6094,11 +6115,13 @@
 	    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);
+	free_register(lvalue);
     } else if (l==2) {
+        use_int(adr);
 	use_longlong(value);
         tmpvar=new_lvar(SIZE_OF_LONGLONG);
 	code_lassign_lvar(tmpvar,value);
-	use_int(lvalue);
 	trn = register_name(tmp = get_register());
 
         /* make and-mask upper */
@@ -6107,12 +6130,12 @@
 	    oprtc(LSHIFT,regv_l(value),list2(CONST,i));
 	if (i<0||32<=i) error(-1);
 	crn = lregister_name_low(value);
-	code_ld(cload(0,0),regv_h(value),0,lvalue,cext_at(0,0));
+	code_ld(cload(0,0),regv_h(value),0,adr,cext_at(0,0));
 	lrn = lregister_name_high(value);
         mask = make_mask(0,31-bitpos);
 	make_mask_and_or(mask,tmp,trn,crn,lrn);
 	inc_inst(1);
-	printf("\t%s\t%s, [%s, #0]\n",cstore(0),crn,register_name(lvalue));
+	printf("\t%s\t%s, [%s, #0]\n",cstore(0),crn,register_name(adr));
 /*
                         <-----bitsize--------------->
                         hhhhhh  mmmmmmmmmmmm  lllllll
@@ -6129,19 +6152,21 @@
 	    loprtc(LRSHIFT,value,list2(CONST,i));
 	if (i<0||64<=i) error(-1);
 	inc_inst(1);
-	printf("\t%s\t%s, [%s, #4]\n",cstore(0),crn,register_name(lvalue));
+	printf("\t%s\t%s, [%s, #4]\n",cstore(0),crn,register_name(adr));
 
         /* make and-mask lower */
-	code_ld(cload(0,0),regv_l(value),SIZE_OF_INT*2,lvalue,cext_at(0,0));
+	code_ld(cload(0,0),regv_l(value),SIZE_OF_INT*2,adr,cext_at(0,0));
 	if (i<0||64<=i) error(-1);
 	mask = make_mask(bitsz-bitpos-bitsize,31);
 	make_mask_and_or(mask,tmp,trn,lrn,crn);
 	inc_inst(1);
-	printf("\t%s\t%s, [%s, #8]\n",cstore(0),lrn,register_name(lvalue));
+	printf("\t%s\t%s, [%s, #8]\n",cstore(0),lrn,register_name(adr));
 	free_lvar(tmpvar);
-	set_ireg(lvalue,0);
     } else {
+	use_int(adr);
 	use_int(value);
+        lvalue = get_register();
+	code_ld(cload(size,sign),lvalue,0,adr,cext_at(0,0));
 	crn = register_name(value);
 	lrn = register_name(lvalue);
 	/* shift left */
@@ -6151,8 +6176,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);
+    }
 }
 
 
@@ -6192,22 +6222,26 @@
 }
 
 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;
     int tmp;
 #endif
     char *crn,*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==1) {
 #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);
@@ -6223,19 +6257,20 @@
 	    mask = make_mask(bitpos+bitsize>=32?0:32-bitpos-bitsize,31-bitpos);
 	    make_mask_and_or_const(mask,crn,(int)lc);
 	}
+        free_register(lvalue);
     } else if (l==2) {
 /*
                         hhhhhh  mmmmmmmmmmmm  lllllll
    lllll  00000000000  mmmmmmmmmmmm  0000000  hhhhhhh 
   |-----||-----------||------------||-------||-------|
  */
-	use_int(lvalue);
-	crn = register_name(lvalue);
+	use_int(adr);
+	crn = register_name(adr);
 	trn = register_name(tmp = get_register());
 	/* shift right */
 	lc = lcadr(value);
 	/* make and-mask upper */
-	code_ld(cload(0,0),tmp,0,lvalue,cext_at(0,0));
+	code_ld(cload(0,0),tmp,0,adr,cext_at(0,0));
 	mask = make_mask(0,31-bitpos);
 	make_mask_and_or_const(mask,trn,(int)(lc<<bitpos));
 	inc_inst(1);
@@ -6245,14 +6280,17 @@
 	inc_inst(1);
 	printf("\t%s\t%s, [%s, #4]\n",cstore(0),trn,crn);
 	/* make and-mask lower */
-	code_ld(cload(0,0),tmp,SIZE_OF_INT*2,lvalue,cext_at(0,0));
+	code_ld(cload(0,0),tmp,SIZE_OF_INT*2,adr,cext_at(0,0));
 	mask = make_mask(bitsz-bitpos-bitsize,31);
 	make_mask_and_or_const(mask,trn,(int)(lc>>(64-bitpos)));
 	inc_inst(1);
 	printf("\t%s\t%s, [%s, #8]\n",cstore(0),trn,crn);
+	free_register(tmp);
 #endif
     } else {
-	use_int(lvalue);
+	use_int(adr);
+	lvalue = get_register();
+	code_ld(cload(size,sign),lvalue,SIZE_OF_INT*2,adr,cext_at(0,0));
 	crn = register_name(lvalue);
 	/* shift left */
 	c = cadr(value);
@@ -6260,6 +6298,11 @@
 	/* 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);
     }
 }