changeset 530:58aceee8e4b4

get_lregister messed up
author kono
date Fri, 30 Dec 2005 12:21:27 +0900
parents ad874ef77dde
children 19f5882997f5
files Changes mc-code-powerpc.c mc-inline.c
diffstat 3 files changed, 100 insertions(+), 174 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Thu Dec 29 11:05:21 2005 +0900
+++ b/Changes	Fri Dec 30 12:21:27 2005 +0900
@@ -7526,146 +7526,4 @@
 あぁ、確かに goto のラベルは、inline の中ではlocal なscope
 にしないといけないのであった。で、どうすれば良いわけ? 
 
-うまく直せない。scope 関係を見直せば良いんだけど.... enter_top_scope とか。
-マルチレベルscopeになるわけね。
-
-ではなくて、parse してしまえば、single level scpe になるので、
-enter_scope して、st_label では、make_local_scope すれば良いらしい。
-
-## 65:     } while ( k < j);
-        la r11,lo16(-20)(r30)
-        la r10,lo16(-24)(r30)
-        cmpw cr2,r10,r11
-
-なので、rvalue が取れてないみたいね。そう言われてみると、
-IVAR のravalue とかは無視してましたが、RVALUEみたいなのが
-いるってこと? 
-
-RINDIRECT で逃げようと思ったが、
-
-## 40:    if (i>j) return j;
-        li r11,-3
-        lwz r11,lo16(0)(r11)
-        li r10,5
-        lwz r10,lo16(0)(r10)
-        cmpw cr1,r10,r11
-        ble cr1,L_37
-        li r10,-3
-        lwz r10,lo16(0)(r10)
-## 41:    else return i;
-
-const でreplaceする時がまずいな。RIVARみたいなのを作ると、
-ちょっとcaseが増えすぎるが... pindirect でいんちきするか。
-
-(で、あとで、やっぱりだめで、const replace を諦めてるし)
-
-const で置換したIVARのアドレスを取られると気まずいなぁ。
-
-このあたりはマルチパスでないとできない。まぁ、parse tree を
-持っているので可能ではあるけど。
-
-Sun Dec 25 20:24:02 JST 2005
-
-さて、return を作らないとだめか。
-
-なに、結局、
-
-    return value がないときは jump 
-    return value がある時には、g_expr でjump
-
-にする? とりあえず。
-
-pfdecl で struct_return は、なんとかしてるの?
-
-やっぱ、ret() で、 code_set_return_register(1);
-は、だめじゃん。if 文の分岐で値を同じレジスタ
-に置くためには.... ?: と同じ方法か。
-
-code_get_fixed_creg ねぇ。
-        t = code_get_fixed_creg(USE_CREG,d);
-        gen_jmp(e3=fwdlabel());
-        fwddef(e2);
-        t1=g_expr0(cadddr(e1));
-        code_set_fixed_creg(t,1,d);
-ですか。
-
-Mon Dec 26 10:54:29 JST 2005
-
-  .cstring とかのデータモードとglobalラベルが変。
-
-これねぇ。string をconstに置くかどうかは arch によるわけだから、
-mc-code-*.c で解決するのが正しいわけだけど、emit_data に分散して
-しまっているね。
-
-Mon Dec 26 22:57:49 JST 2005
-
-引数中の関数型の定義があまり正確でないらしい。型宣言のない
-code segment の呼び出しで、間違った値を送ってしまう。
-
-大きな構造体二種類を含む parallel assignment が 無限ループ
-する。分割を小さくすると通る。
-
-register のtargetがoverrapしている場合に、registerを free
-してからsave_targetしているので同じregisterが再利用されて
-しまって無限ループしているらしい。save_target で register
-overlap を見るようにしたけど、ad-hoc じゃない? (ま、
-もともと今の実装が ad-hoc だし)
-
-ASSIGN_STRUCT_DIVDE ってDIVDEする大きさのlimitなのか。
-大きいのは逆にdivdeしないのか。
-
-Mon Dec 26 23:18:06 JST 2005
-
-そもそも、仮引数のユーザに名前と大きさを決めさせているんだ
-から、順序はこっちで決めれば良い。その代わり、異なる名前で
-仮引数を受けるのは許さないってのがいいかもね。とすると、code
-segment の引数のdefault とかを考えるとかなり、不思議な感じ。
-なんか整合性の良い interface ってあるんだろうか? stack を含
-めて? 
-
-   goto hoge(i=1,j=3,...)
-
-みたいな?
-
-Tue Dec 27 18:17:55 JST 2005
-
-inline をstaticとして扱うoptionがあった方がいいかもね。
-
-あ、そうか。inline で new_lvar したら、あとでfreeしないと。
-ということは、keep track しないとまずいのね。
-
-## 94:  i += k;
-        la r3,lo16(-32)(r30)
-        lwz r3,lo16(0)(r3)
-        li r11,3
-
-当然、const arg でないとconstantに置き換えてはいけないわけね。
-address を取られた場合も同様。ということは、has_address みたいな
-attribute も必要なわけだ。
-
-ま、それはあとで。
-
-Wed Dec 28 17:29:59 JST 2005
-
-skipspc() で、inmode の時に、cheap に書かれてしまうので、
-cheap 上の string  をterminate しないうちに、skipspc()
-してはいけないわけね。
-
-なんだが、"hoge" "ahoge" のcaseに、inmode の ST_COMMENT
-が干渉してしまうわけね。それは、まずいか。
-
-やっぱり、STRING は、"" で一つにして、複数つながる
-っていう構文にした方が良いね。
-
-    list(STRING,value,continue)
-
-みたいな感じ。でも、それだと変更が多い(何故か nptr にいれてた...)
-ので、やっぱり、append しました。
-
-Thu Dec 29 09:59:38 JST 2005
-
-PowerPC の get_lregister が失敗するのが、まだ、微妙に残ってる。
-足りないはずないんだけどね。input register も探させちゃうか。
-そういえば、最初は input register は使わない方針だったけど、
-今は使ってもいいんじゃないの?
-
+うまく直せない。scope 関係を見直せば良
\ No newline at end of file
--- 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);
 }
 
--- a/mc-inline.c	Thu Dec 29 11:05:21 2005 +0900
+++ b/mc-inline.c	Fri Dec 30 12:21:27 2005 +0900
@@ -451,14 +451,19 @@
 prindirect(int e)
 {
     int lvar;
-    if (car(lvar=cadr(e))==IVAR)
+    if (car(lvar=cadr(e))==IVAR) {
 	lvar=p_lvar(cadr(e)); // can be anything....
-    switch(car(lvar)) {
-    case LVAR:
-	return rvalue_t(lvar,cadddr(e));
-    default:
-	return list3(car(e),pexpr(cadr(e)),caddr(e));
+	switch(car(lvar)) {
+	case LVAR:
+	    return rvalue_t(lvar,cadddr(e));
+	case REGISTER: case DREGISTER:
+	case FREGISTER: case LREGISTER:
+	case CONST: case FCONST: case DCONST: case LCONST:
+	    // should do type check
+	    return lvar;
+	}
     }
+    return list3(car(e),pexpr(cadr(e)),caddr(e));
 }
 
 static int
@@ -1005,6 +1010,8 @@
 
 #define round4(i)   ((i+(SIZE_OF_INT-1))&~(SIZE_OF_INT-1))
 
+extern int lreg_count;
+
 extern int
 gen_inline(int e)
 {
@@ -1019,6 +1026,7 @@
     int sret_reg_mode = ret_reg_mode;
     int sinline_lvars = inline_lvars;
     int slfree=lfree;
+    int slreg_count=lreg_count;
 
     int narg,arg;
     NMTBL *n = (NMTBL*)cadr(cadr(e));
@@ -1107,6 +1115,10 @@
     inline_lvars = sinline_lvars;
     lfree=slfree;
 
+    if (slreg_count!=lreg_count && lreg_count>0) {
+	printf("## lreg_count %d != %d\n", slreg_count,lreg_count);
+    }
+
     return ret_type;
 }