changeset 277:d5467cf30f58

Prallel Register Assignment
author kono
date Fri, 21 May 2004 21:29:40 +0900
parents ebaec1ae566e
children 5b50813d0c45
files Changes mc-code-mips.c mc-codegen.c mc-codegen.h
diffstat 4 files changed, 82 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Fri May 21 18:59:56 2004 +0900
+++ b/Changes	Fri May 21 21:29:40 2004 +0900
@@ -4383,3 +4383,5 @@
 えーと、double register がconflict しまくるなぁ。
 さすがに function では起きないらしいが...
 ということは、set_[dl]operand の問題か。
+
+やっぱり register parallel assign を書くのが簡単だよね。
--- a/mc-code-mips.c	Fri May 21 18:59:56 2004 +0900
+++ b/mc-code-mips.c	Fri May 21 21:29:40 2004 +0900
@@ -1673,6 +1673,7 @@
     }
 }
 
+/*
 static void
 set_lreg_operand1(int reg,int mode)
 {
@@ -1682,6 +1683,7 @@
 	lmove(LREGISTER_OPERAND_1,reg);
     }
 }
+ */
 
 static void
 set_dreg_operand(int reg,int mode)
@@ -1689,11 +1691,13 @@
      set_lreg_operand(reg,mode);
 }
 
+/*
 static void
 set_dreg_operand1(int reg,int mode)
 {
      set_lreg_operand1(reg,mode);
 }
+ */
 
 void
 use_reg(int arg)
@@ -2282,30 +2286,27 @@
 #endif
 }
 
+
 static void
 lmove(int to,int from)
 {
-    int tmp;
-    if (regv_h(to)==regv_h(from)&&(regv_l(to)==regv_l(from))) {
-	return;
-    } else if (regv_h(to)!=regv_l(from)) {
-	if (regv_h(to)!=regv_h(from)) 
-	    printf("\tmove %s,%s\n",lregister_name_high(to),lregister_name_high(from));
-	if (regv_l(to)!=regv_l(from)) 
-	    printf("\tmove %s,%s\n",lregister_name_low(to),lregister_name_low(from));
-    } else if (regv_l(to)!=regv_h(from)) {
-	if (regv_l(to)!=regv_l(from)) 
-	    printf("\tmove %s,%s\n",lregister_name_low(to),lregister_name_low(from));
-	if (regv_h(to)!=regv_h(from)) 
-	    printf("\tmove %s,%s\n",lregister_name_high(to),lregister_name_high(from));
-    } else {
-	tmp = get_register();
-	printf("\tmove %s,%s\n",register_name(tmp),lregister_name_low(from));
-	printf("\tmove %s,%s\n",lregister_name_high(to),lregister_name_high(from));
-	printf("\tmove %s,%s\n",lregister_name_low(to),register_name(tmp));
-	free_register(tmp);
-    }
-}
+    int l;
+    l = list3(regv_l(to),0,regv_l(from));
+    l = list3(regv_h(to),l,regv_h(from));
+    parallel_rassign(l);
+}
+
+static void
+set_operands(int r0,int r1,int r2,int r3)
+{
+    int l;
+    l = list3(DREGISTER_OPERAND_L,0,r0);
+    l = list3(DREGISTER_OPERAND_H,l,r1);
+    l = list3(DREGISTER_OPERAND_1_L,l,r2);
+    l = list3(DREGISTER_OPERAND_1_H,l,r3);
+    parallel_rassign(l);
+}
+
 
 static void
 lstore(int e2,int creg)
@@ -3595,24 +3596,9 @@
 static void
 code_double_lib(char *lib,int to,int reg,int oreg)
 {
-    int tmp;
     code_save_stacks();
     clear_ptr_cache();
-    if (regs[DREGISTER_OPERAND_L]||regs[DREGISTER_OPERAND_H]) {
-        if (regs[DREGISTER_OPERAND_1_L]||regs[DREGISTER_OPERAND_1_H]) {
-	    tmp = new_lvar(SIZE_OF_DOUBLE);
-	    code_lassign_lvar(tmp,reg); 
-	    set_dreg_operand1(oreg,1);
-	    code_lrlvar(tmp,DREGISTER_OPERAND);
-	    free_lvar(tmp);
-        } else {
-	    set_dreg_operand1(oreg,1);
-	    set_dreg_operand(reg,1);
-	}
-    } else {
-	set_dreg_operand(reg,1);
-	set_dreg_operand1(oreg,1);
-    }
+    set_operands(regv_l(reg),regv_h(reg),regv_l(oreg),regv_h(oreg));
     extern_conv(lib);
     set_dreg(RET_DREGISTER,0);
     if (to!=RET_DREGISTER) {
@@ -3857,23 +3843,21 @@
 	if (car(e2)==DREGISTER) {
 	    xreg = cadr(e2);
 	    code_double_lib_c("dpadd",xreg,RET_DREGISTER,dir);
+	    //    xreg は increment する
+            //    USE_CREG だと increment する前の値を creg にセット
+	    //    reg が指定されていれば、それに前の値をセット
 	    if (reg==USE_CREG) {
 		use_float(d,reg);
 		if (reg==RET_DREGISTER) {
 		    reg = get_dregister(d);
-		    set_dreg(reg,0);
 		}
+		set_dreg(reg,0);
 	    }
-	    if (reg==RET_DREGISTER) {
-		g = get_dregister(d);
-		lmove(g,xreg);
-		lmove(xreg,reg);
-		lmove(reg,g);
-		free_register(g);
-		return;
-	    }
-	    if (reg!=xreg) lmove(reg,xreg);
-	    lmove(xreg,RET_DREGISTER);
+	    g = list3(regv_l(reg),0,regv_l(xreg));
+	    g = list3(regv_h(reg),g,regv_h(xreg));
+	    g = list3(regv_l(xreg),g,regv_l(RET_DREGISTER));
+	    g = list3(regv_h(xreg),g,regv_h(RET_DREGISTER));
+	    parallel_rassign(g);
 	    return;
 	} 
 	g_expr(e2);
@@ -4400,24 +4384,9 @@
 static void
 code_longlong_lib(char *lib,int reg,int oreg)
 {
-    int tmp;
     code_save_stacks();
     clear_ptr_cache();
-    if (regs[LREGISTER_OPERAND_L]||regs[LREGISTER_OPERAND_H]) {
-        if (regs[LREGISTER_OPERAND_1_L]||regs[LREGISTER_OPERAND_1_H]) {
-	    tmp = new_lvar(SIZE_OF_LONGLONG);
-	    code_lassign_lvar(tmp,reg); 
-	    set_lreg_operand1(oreg,1);
-	    code_lrlvar(tmp,LREGISTER_OPERAND);
-	    free_lvar(tmp);
-        } else {
-	    set_lreg_operand1(oreg,1);
-	    set_lreg_operand(reg,1);
-	}
-    } else {
-	set_lreg_operand(reg,1);
-	set_lreg_operand1(oreg,1);
-    }
+    set_operands(regv_l(reg),regv_h(reg),regv_l(oreg),regv_h(oreg));
     extern_conv(lib);
     set_lreg(RET_LREGISTER,0);
 }
--- a/mc-codegen.c	Fri May 21 18:59:56 2004 +0900
+++ b/mc-codegen.c	Fri May 21 21:29:40 2004 +0900
@@ -717,6 +717,52 @@
 #endif
 }
 
+// parallel assignment of registers.
+//
+//  target = list3(target_regnum,next,source_regnum);
+
+void
+parallel_rassign(int assigns)
+{
+    int free,tmp,tmp_target,remains,t0,t2,src;
+    tmp = 0;
+    for(;;) {
+	remains = 0;
+	// find free target
+	for(free=assigns;free;free=cadr(free)) {
+	    if (!caddr(free)) continue;       // already done
+	    remains++;
+	    t0 = car(free);                   // target register
+	    // check target is free
+	    for(src=assigns;src;src=cadr(src)) {
+		if ((t2=caddr(src)) && t0==t2) break;  // target is in source
+	    }
+	    if (src==0) {
+		break;                      // free is a free target
+	    } 
+	}
+	if (remains==0) {
+	    if (tmp) {
+		code_rlvar(tmp,tmp_target);
+	    }
+	    return;
+	}
+	if (free) {  // free target
+	    if (t0!=caddr(free))
+		code_assign_register(t0,0,caddr(free));
+	} else {  // no free target
+	    for(free=assigns;free;free=cadr(free)) {
+		if (caddr(free)) break; // not yet done
+	    }
+	    if (!free) error(-1);
+	    tmp = new_lvar(size_of_int);
+	    tmp_target = car(free);
+	    code_assign_lvar(tmp,caddr(free),0);
+	}
+	caddr(free)=0;       // mark it done
+    }
+}
+
 /* goto arguments list                                      */
 /* target         list4(list2(tag,disp),cdr,ty,source_expr) */
 /*     source         expr=listn(tag,...)                   */
--- a/mc-codegen.h	Fri May 21 18:59:56 2004 +0900
+++ b/mc-codegen.h	Fri May 21 21:29:40 2004 +0900
@@ -27,6 +27,7 @@
 
 extern int is_code(NMTBL *fnptr);
 extern int is_function(NMTBL *fnptr);
+extern void parallel_rassign(int list);
 
 extern int csvalue();
 extern void cmpdimm(int e, int csreg);