diff mc-code-powerpc.c @ 530:58aceee8e4b4

get_lregister messed up
author kono
date Fri, 30 Dec 2005 12:21:27 +0900
parents ad874ef77dde
children 19f5882997f5
line wrap: on
line diff
--- a/mc-code-powerpc.c	Thu Dec 29 11:05:21 2005 +0900
+++ b/mc-code-powerpc.c	Fri Dec 30 12:21:27 2005 +0900
@@ -167,7 +167,7 @@
 int use_int0() { 
     int i = creg;
     if (!i||!ireg||!is_int_reg(i)) {
-	if (lreg) { if (regs[lreg]) free_register(lreg); lreg = 0; }
+	if (lreg) { free_register(lreg); lreg = 0; }
 	if (!ireg) ireg = get_register();
 	// else if (ireg!=i) free_register(i);
 	i = ireg;
@@ -643,19 +643,53 @@
 }
 #endif
 
+
 int
 get_lregister0()
 {
     int i;
     for(i=LREG_OFFSET+1;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) {
 	if (regs[i]==0) {
-// printf("## get_lregister %d\n",i);
 	    return i;
 	}
     }
     return -1;
 }
 
+static int
+get_lregister1(int n,int m)
+{
+    int i;
+#if 1
+    for(i=LREG_OFFSET;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) {
+	if (regv_l(i)==n && regv_h(i)==m) {
+	    return i;
+	}
+    }
+#endif
+    return get_lregister0();
+}
+
+
+static void
+cleanup_lregister0()
+{
+    int i;
+#if 1
+    for(i=LREG_OFFSET+1;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) {
+	if (regs[i]) {
+	    if(!regv_l(i) && !regv_h(i)) {
+		regs[i]=0;
+		// printf("## cleanup lreg 0 %d\n",i);
+	    } else if(!regs[regv_l(i)] && !regs[regv_h(i)]) {
+		free_register(i);
+		// printf("## cleanup lreg 1 %d\n",i);
+	    }
+	}
+    }
+#endif
+}
+
 int
 get_lregister()
 {
@@ -666,9 +700,10 @@
     if (h==-1) return -1;
     regv_h(i) = h;
     l = get_register(); 
-    if (l==-1) { free_register(h); return -1; }
+    if (l==-1) { free_register(h); free_register(i); return -1; }
     regv_l(i) = l;
     regs[i]=USING_REG;
+// printf("## get_lregister %d %s %s\n",i, lregister_name_high(i), lregister_name_low(i));
     return i;
 }
 
@@ -720,13 +755,13 @@
 
 free_register(int i) {    /* いらなくなったレジスタを開放 */
 // printf("## free_register %d\n",i);
-    regs[i]=0;
     if (is_longlong_reg(i)) {
 	regs[regv_l(i)]=0;
 	regs[regv_h(i)]=0;
-	//regv_l(i)=0;
+	//regv_l(i)=0;  will erase input register...
 	//regv_h(i)=0;
     }
+    regs[i]=0;
 }
 
 extern void
@@ -752,7 +787,6 @@
 get_input_lregister_var(int i,NMTBL *n,int is_code)
 {
     int ll;
-    ll = get_lregister0();
     if (i!=-1) {
 	if (is_code) {
 	    if(!(i<REG_VAR_BASE-REG_VAR_MIN)) return 0;
@@ -761,6 +795,7 @@
 	    if (i<0||i>=MAX_INPUT_REGISTER_VAR) return 0;
 	    i = i+MIN_TMP_REG;
 	}
+	ll = get_lregister1(i,i+1);
 #if ENDIAN_L==0
 	regv_l(ll)=i;
 	regv_h(ll)=i+1;
@@ -898,6 +933,8 @@
     return 0;
 }
 
+int lreg_count;
+
 void
 register_usage(char *s)
 {
@@ -914,7 +951,7 @@
 #if 1
     for(j=0,i=0;i<MAX_REGISTER;i++) if (regs[i]) j++;
     if (j>USAGE_MAX) {
-	printf("\n## regs:");
+	printf("\n## regs(%d):",j);
 	for(i=0;i<MAX_REGISTER;i++) {  printf("%d",regs[i]); }
     }
     if (reg_sp>0) {
@@ -928,7 +965,7 @@
     }
     for(j=0,i=0;i<MAX_FREGISTER;i++) if (regs[i+FREG_OFFSET]) j++;
     if (j>USAGE_MAX) {
-	printf("\n## freg:");
+	printf("\n## freg(%d):",j);
 	for(i=0;i<MAX_FREGISTER;i++) {  printf("%d",regs[i+FREG_OFFSET]); }
     }
     if (freg_sp>0) {
@@ -942,9 +979,18 @@
     }
 
     for(j=0,i=0;i<REAL_MAX_LREGISTER;i++) if (regs[i+LREG_OFFSET]) j++;
+    lreg_count = j;
     if (j>USAGE_MAX) {
-	printf("\n## lreg:");
+	printf("\n## lreg(%d):",j);
 	for(i=0;i<REAL_MAX_LREGISTER;i++) {  printf("%d",regs[i+LREG_OFFSET]); }
+#if 0
+	for(i=0;i<REAL_MAX_LREGISTER;i++) {  
+	    if (regs[i+LREG_OFFSET] && regv_l(i+LREG_OFFSET))
+		printf(" %s-%s", lregister_name_high(i+LREG_OFFSET),lregister_name_low(i+LREG_OFFSET));
+	    else if (regv_l(i+LREG_OFFSET))
+		printf(" *%s-%s", lregister_name_high(i+LREG_OFFSET),lregister_name_low(i+LREG_OFFSET));
+	}
+#endif
     }
     if (lreg_sp>0) {
 	printf(" lstack ");
@@ -1649,23 +1695,26 @@
     }
     if (!is_longlong_reg(reg)) error(-1);
     if (reg!=creg) {
-	if (lreg && reg!=lreg) {
-	    if (mode) {
-		printf("\tmr %s,%s\n",
-		    lregister_name_low(reg),lregister_name_low(lreg));
-		printf("\tmr %s,%s\n",
-		    lregister_name_high(reg),lregister_name_high(lreg));
+	if (lreg) {
+	    if (reg!=lreg) {
+		if (mode) {
+		    printf("\tmr %s,%s\n",
+			lregister_name_low(reg),lregister_name_low(lreg));
+		    printf("\tmr %s,%s\n",
+			lregister_name_high(reg),lregister_name_high(lreg));
+		}
+		free_register(lreg);
 	    }
-	    free_register(lreg);
+	    if (lreg==creg) creg=0;
 	}
-	free_register(creg);
+	if (creg) free_register(creg);
 	regs[reg]=USING_REG;
 	clear_ptr_cache_reg(regv_l(reg));
 	regs[regv_l(reg)]=USING_REG;
 	clear_ptr_cache_reg(regv_h(reg));
 	regs[regv_h(reg)]=USING_REG;
+	creg = lreg = reg;
     }
-    creg = lreg = reg;
 }
 
 void
@@ -2083,9 +2132,11 @@
 			arg,INT,INT),
 		    arg_assign);
 		use_input_reg(cadr(r0),1);
+		reg_arg_list = list2(r0,reg_arg_list);
 	    } else {
-		if (car(arg)==LREGISTER)
+		if (car(arg)==LREGISTER) {
 		    use_input_reg(cadr(arg),1);
+		}
 	    }
 	    reg_arg_list = list2(arg,reg_arg_list);
 	    g_expr_u(assign_expr0(arg,e4,t,t));
@@ -2154,9 +2205,11 @@
     for(;reg_arg_list;reg_arg_list=cadr(reg_arg_list)) {
 	arg = car(reg_arg_list);
 	if (car(arg)==REGISTER||car(arg)==DREGISTER||car(arg)==FREGISTER
-		||car(arg)==LREGISTER) 
+		||car(arg)==LREGISTER)  {
+// if (car(arg)==LREGISTER)
+// printf("## lreg freeing %d %s %s\n",cadr(arg), lregister_name_high(cadr(arg)), lregister_name_low(cadr(arg)));
 	    free_register(cadr(arg));
-	else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg));
+	} else if (car(arg)==LVAR&&cadr(arg)<0) free_lvar(cadr(arg));
     }
     if (ret_type==DOUBLE||ret_type==FLOAT) {
 	set_freg(RET_FREGISTER,0);
@@ -2167,6 +2220,7 @@
     } else {
 	set_ireg(RET_REGISTER,0);
     }
+    cleanup_lregister0();
     return ret_type;
 }
 
@@ -3891,7 +3945,7 @@
 
 /* 64bit int part */
 static void
-lmove(int to,int from)   //   to = from
+lmove(int to,int from)   //   to <= from
 {
     int tmp;
     if (regv_h(to)==regv_l(from)&&(regv_l(to)==regv_h(from))) {
@@ -4431,7 +4485,9 @@
     extern_conv("__umoddi3");
 }
 
-#define check_lreg(reg) if (reg!=lreg) { lmove(reg,lreg); }
+#define check_lreg(reg) if (reg!=lreg) { lmove(reg,lreg); /* reg<=lreg */ }
+
+//   reg = reg op oreg
 
 void
 ltosop(int op,int reg,int oreg)
@@ -4502,7 +4558,7 @@
     case LUMUL:
 	// code_save_stacks();
 	// clear_ptr_cache();
-	dx=get_lregister();
+	dx=get_lregister(); if (dx<0) error(-1);
 	use_reg(dx);
 	drn_l = lregister_name_low(dx);
 	drn_h = lregister_name_high(dx);
@@ -4542,7 +4598,7 @@
     default:
 	error(-1);
     }
-    if(ox!=-1) free_register(dx);
+    if(ox!=-1) free_register(ox);
     if(dx!=-1) free_register(dx);
 }