changeset 345:2b3946ee4fc9 nametbl-before

*** empty log message ***
author kono
date Sun, 27 Jun 2004 20:31:46 +0900
parents b7f07df0c0f8
children 969089695850
files Changes mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-code.h mc-codegen.c
diffstat 6 files changed, 174 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Sun Jun 27 14:56:21 2004 +0900
+++ b/Changes	Sun Jun 27 20:31:46 2004 +0900
@@ -5229,3 +5229,46 @@
 
 そういえば、double register pair のparallel assignmentって
 やってる?
+
+うーん、やっぱり、codegen が register pair を知ることが出来
+るように、list2(LREGISTER,high,low) みたいな形にしたいよね。
+なんで、だめなんだったっけ? 
+	list2(DREGISTER,list2(REGISTER2,high,low))
+	list2(LREGISTER,list2(REGISTER2,high,low))
+	list2(FREGISTER,list2(REGISTER,high))
+とか?
+	list3(REGISTER,1,reg);
+	list3(DREGISTER,2,reg,reg);
+	list3(FREGISTER,1,reg);
+かな。
+
+いいんだけど、変更多くない? でも、use_reg とかの複雑さを考えると、
+そうした方がいいんじゃないかなぁ。
+
+でも、変更多いよね。利点としては、regs[] を lregster 分取らなくて
+すむことかな。でも、本当に簡単になるのかな?
+
+code_*() でレジスタを使っている部分を修正する必要があるから、
+かなり大きな変更になるのか。でも、code_*() に引き渡す変数と
+構文木中の要素が同じになるのは重要だよね。
+
+構文木でのレジスタ変数のユニークさを維持しないと、
+    if(r!=reg)
+        printf("\tmr %s,%s\n",register_name(reg),register_name(r));
+    return;
+みたいなのが困るね。ということは reverse poiner がいるってこ
+とか。
+
+overlap を見るときに、自分自身が overlap していても問題ない。
+ただし、重ならないようにコピーしないとだめ。そうしないと、
+巨大な構造体を二回コピーするはめになる。
+
+      |---||--------------|
+
+           |--------------||---|
+
+      |--------------|     |---|
+
+      |--------------||---|
+
+みたいな感じだね。
--- a/mc-code-ia32.c	Sun Jun 27 14:56:21 2004 +0900
+++ b/mc-code-ia32.c	Sun Jun 27 20:31:46 2004 +0900
@@ -373,6 +373,21 @@
 }
 
 int 
+get_input_lregister_var(int i,NMTBL *nptr,int is_code)
+{
+    int h,l;
+    if (is_code) {
+	if (i+1>=MAX_CODE_INPUT_REGISTER_VAR) return 0;
+	h = virtual(REG_ESI);
+	l = virtual(REG_EDI);
+	regs[h]=regs[l]=INPUT_REG;
+	regv[h]=regv[l]=INPUT_REG;
+	return list2(LREGISTER,REG_L);
+    }
+    return 0;
+}
+
+int 
 get_dregister(int d)
 {
     return -1;
@@ -437,6 +452,20 @@
     return;
 }
 
+extern int
+code_register_overlap(int s,int t)
+{
+    if (car(s)==REGISTER) {
+	if (car(t)==REGISTER) return cadr(s)==cadr(t);
+	if (car(t)==LREGISTER)
+	    return cadr(s)==virtual(REG_ESI)|| cadr(s)==virtual(REG_EDI);
+    } else if (car(s)==LREGISTER) {
+	if (car(t)==LREGISTER) return 1;
+	if (car(t)==REGISTER)
+	    return cadr(t)==virtual(REG_ESI)|| cadr(t)==virtual(REG_EDI);
+    }
+    return 0;
+}
 
 void
 register_usage(char *s)
--- a/mc-code-mips.c	Sun Jun 27 14:56:21 2004 +0900
+++ b/mc-code-mips.c	Sun Jun 27 20:31:46 2004 +0900
@@ -917,6 +917,52 @@
     return;
 }
 
+
+extern int
+code_register_overlap(int s,int t)
+{
+    switch(car(s)) {
+    case REGISTER:
+	switch(car(t)) {
+	case FREGISTER: break;
+	case REGISTER:
+	    return cadr(s)==cadr(t);
+	    break;
+	case LREGISTER: case DREGISTER: 
+	    if(cadr(s)==regv_l(cadr(t))) return 1;
+	    if(cadr(s)==regv_h(cadr(t))) return 1;
+	    break;
+	}   
+	break;
+    case FREGISTER:
+	switch(car(t)) {
+	case REGISTER: case LREGISTER: case DREGISTER: break;
+	case FREGISTER:
+	    return cadr(s)==cadr(t);
+	    break;
+	}   
+	break;
+    case DREGISTER:
+    case LREGISTER:
+	switch(car(t)) {
+	case FREGISTER: break;
+	case REGISTER:
+	    if(cadr(t)==regv_l(cadr(s))) return 1;
+	    if(cadr(t)==regv_h(cadr(s))) return 1;
+	    break;
+	case LREGISTER: case DREGISTER: 
+	    if(regv_l(cadr(t))==regv_l(cadr(s))) return 1;
+	    if(regv_l(cadr(t))==regv_h(cadr(s))) return 1;
+	    if(regv_h(cadr(t))==regv_l(cadr(s))) return 1;
+	    if(regv_h(cadr(t))==regv_h(cadr(s))) return 1;
+	    break;
+	}   
+	break;
+    }   
+    return 0;
+}
+
+
 void
 register_usage(char *s)
 {
@@ -1794,7 +1840,7 @@
 	    } else if (regv_h(lreg)==reg) {
 		regs[lreg]=0;
 		if (regv_h(lreg)>reg && (
-		    (regs[regv_l(lreg)]==USING_DREG) ||
+		    (regs[regv_l(lreg)]==USING_REG) ||
 		    (regs[regv_l(lreg)]==USING_DREG) ))
 		  {
 		    free_register(regv_l(lreg));
--- a/mc-code-powerpc.c	Sun Jun 27 14:56:21 2004 +0900
+++ b/mc-code-powerpc.c	Sun Jun 27 20:31:46 2004 +0900
@@ -817,6 +817,50 @@
     return;
 }
 
+extern int
+code_register_overlap(int s,int t)
+{
+    switch(car(s)) {
+    case REGISTER:
+	switch(car(t)) {
+	case DREGISTER: case FREGISTER: break;
+	case REGISTER:
+	    if(cadr(s)==cadr(t)) return 1;
+	    break;
+	case LREGISTER:
+	    if(cadr(s)==regv_l(cadr(t))) return 1;
+	    if(cadr(s)==regv_h(cadr(t))) return 1;
+	    break;
+	}   
+	break;
+    case DREGISTER:
+    case FREGISTER:
+	switch(car(t)) {
+	case REGISTER: case LREGISTER: break;
+	case DREGISTER: case FREGISTER:
+	    if(cadr(s)==cadr(t)) return 1;
+	    break;
+	}   
+	break;
+    case LREGISTER:
+	switch(car(t)) {
+	case DREGISTER: case FREGISTER: break;
+	case REGISTER:
+	    if(cadr(t)==regv_l(cadr(s))) return 1;
+	    if(cadr(t)==regv_h(cadr(s))) return 1;
+	    break;
+	case LREGISTER:
+	    if(regv_l(cadr(t))==regv_l(cadr(s))) return 1;
+	    if(regv_l(cadr(t))==regv_h(cadr(s))) return 1;
+	    if(regv_h(cadr(t))==regv_l(cadr(s))) return 1;
+	    if(regv_h(cadr(t))==regv_h(cadr(s))) return 1;
+	    break;
+	}   
+	break;
+    }   
+    return 0;
+}
+
 void
 register_usage(char *s)
 {
--- a/mc-code.h	Sun Jun 27 14:56:21 2004 +0900
+++ b/mc-code.h	Sun Jun 27 20:31:46 2004 +0900
@@ -54,6 +54,7 @@
 extern int get_input_lregister_var(int,NMTBL *,int);
 extern void code_ptr_cache_def(int r,NMTBL *nptr);
 extern void use_ptr_cache(int r);
+extern int code_register_overlap(int s,int t);
 
 extern void emit_push();
 extern int emit_pop(int type);
--- a/mc-codegen.c	Sun Jun 27 14:56:21 2004 +0900
+++ b/mc-codegen.c	Sun Jun 27 20:31:46 2004 +0900
@@ -844,15 +844,8 @@
     for(;source;source=cadr(source)) {
 	s=car(source); s0=cadr(s); 
 	switch(car(s)) {
-	// double register pair?
-	case REGISTER:
-	    if(car(t)==REGISTER && s0==t0) return s;
-	case DREGISTER:
-	    if(car(t)==DREGISTER && s0==t0) return s;
-	case FREGISTER:
-	    if(car(t)==FREGISTER && s0==t0) return s;
-	case LREGISTER:
-	    if(car(t)==LREGISTER && s0==t0) return s;
+	case REGISTER: case DREGISTER: case FREGISTER: case LREGISTER:
+	    if (code_register_overlap(s,t)) return s;
 	}
 	if (is_same_type(s,t)) {
 	    s1=s0+caddr(source);
@@ -875,7 +868,7 @@
     while(use0) {
 	if (car(use0)==t) {
 	    reg = car(caddr(use0));
-	    if (reg==REGISTER||reg==FREGISTER||reg==DREGISTER)
+	    if (reg==REGISTER||reg==FREGISTER||reg==DREGISTER||reg==LREGISTER)
 		free_register(cadr(caddr(use0)));
 	    break;
 	}
@@ -889,25 +882,25 @@
 {
     int e1;
     /*新しいレジスタ(or スタック)を取得する*/
-    if (sz==size_of_int && (e1=get_register())!=-1) {
+    if (scalar(ty) && sz==size_of_int && (e1=get_register())!=-1) {
 	e1=list3(REGISTER,e1,0);
 	*use=list3(t,*use,e1);
 	g_expr_u(assign_expr0(e1,s,ty,ty));
 	*target = append4(*target,t,ty,e1);
 #if FLOAT_CODE
-    } else if (sz==size_of_double && (e1=get_dregister(1))!=-1) {
+    } else if (ty==DOUBLE && sz==size_of_double && (e1=get_dregister(1))!=-1) {
 	e1=list3(DREGISTER,e1,0);
 	*use=list3(t,*use,e1);
 	g_expr_u(assign_expr0(e1,s,ty,ty));
 	*target = append4(*target,t,ty,e1);
-    } else if (sz==size_of_float && (e1=get_dregister(0))!=-1) {
+    } else if (ty==FLOAT && sz==size_of_float && (e1=get_dregister(0))!=-1) {
 	e1=list3(FREGISTER,e1,0);
 	*use=list3(t,*use,e1);
 	g_expr_u(assign_expr0(e1,s,ty,ty));
 	*target = append4(*target,t,ty,e1);
 #endif
 #if LONGLONG_CODE
-    } else if (sz==size_of_longlong && (e1=get_lregister())!=-1) {
+    } else if ((ty==LONGLONG||ty==ULONGLONG)&&(e1=get_lregister())!=-1) {
 	e1=list3(LREGISTER,e1,0);
 	*use=list3(t,*use,e1);
 	g_expr_u(assign_expr0(e1,s,ty,ty));
@@ -1097,6 +1090,8 @@
 	    target=list4(r, target,ty,e2); fregs++;
 	} else if (ty==DOUBLE && (r = get_input_dregister_var(fregs,0,1,1))) {
 	    target=list4(r, target,ty,e2); fregs++;
+	} else if ((ty==LONGLONG||ty==ULONGLONG) && (r = get_input_lregister_var(fregs,0,1))) {
+	    target=list4(r, target,ty,e2); regs+=2;
 	} else {
 	    target=list4(list2(LVAR,0), target,ty,e2);
 	}
@@ -1138,7 +1133,7 @@
 #endif
                 /* we should check size also (but currently useless) */
                 remove0(&target,t0);
-                /* still we have source to avoid overwrite */
+                /* still we keep source to avoid overwrite */
 	    }
         }
 	if(is_memory(s0)) {