diff mc-code-mips.c @ 276:ebaec1ae566e

MIPS double/longlong lib operand register conflict
author kono
date Fri, 21 May 2004 18:59:56 +0900
parents 8f09f8bbc494
children d5467cf30f58
line wrap: on
line diff
--- a/mc-code-mips.c	Fri May 21 14:00:02 2004 +0900
+++ b/mc-code-mips.c	Fri May 21 18:59:56 2004 +0900
@@ -258,6 +258,9 @@
 
 static int code_d1(double d);
 static int code_d2(double d);
+static void code_double_lib(char *lib,int to,int reg,int oreg);
+static void code_double_lib_c(char *lib,int from,int to,double value);
+
 #endif
 #if LONGLONG_CODE
 static int code_l1(long long ll);
@@ -1666,14 +1669,7 @@
     // save_stack,clear_ptr_cache is assumed    
     if (!is_longlong_reg(reg)) { error(-1); return; }
     if (mode) {
-	if (regv_h(reg)!=DREGISTER_OPERAND_H) {
-	    printf("\tmove %s,%s\n", 
-	    lregister_name_high(DREGISTER_OPERAND),lregister_name_high(reg));
-	}
-	if (regv_l(reg)!=DREGISTER_OPERAND_L) {
-	    printf("\tmove %s,%s\n", 
-	    lregister_name_low(DREGISTER_OPERAND),lregister_name_low(reg));
-	}
+	lmove(LREGISTER_OPERAND,reg);
     }
 }
 
@@ -1683,14 +1679,7 @@
     // save_stack,clear_ptr_cache is assumed    
     if (!is_longlong_reg(reg)) { error(-1); return; }
     if (mode) {
-	if (regv_h(reg)!=DREGISTER_OPERAND_1_H) {
-	    printf("\tmove %s,%s\n", 
-	    lregister_name_high(DREGISTER_OPERAND_1),lregister_name_high(reg));
-	}
-	if (regv_l(reg)!=DREGISTER_OPERAND_1_L) {
-	    printf("\tmove %s,%s\n", 
-	    lregister_name_low(DREGISTER_OPERAND_1),lregister_name_low(reg));
-	}
+	lmove(LREGISTER_OPERAND_1,reg);
     }
 }
 
@@ -1749,7 +1738,6 @@
 	    n->dsp = offset;
 	    offset+=SIZE_OF_INT;
 	    t = INT;
-	    reg += reg_offset; /* for duplicated floating point argument */
 	} else if (tag==FREGISTER) {
 	    /* regs[reg]==INPUT_REG case should be considered */
 	    n->dsp = offset;
@@ -1760,7 +1748,7 @@
 		    tag = REGISTER; t = INT;
 		}
 	    }
-	    else if(t==DOUBLE) { offset+=SIZE_OF_DOUBLE; reg_offset+=2; }
+	    // else if(t==DOUBLE) { offset+=SIZE_OF_DOUBLE; reg_offset+=2; }
 	    else error(-1);
 	} else if (tag==DREGISTER) {
 	    /* regs[reg]==INPUT_REG case should be considered */
@@ -2298,20 +2286,24 @@
 lmove(int to,int from)
 {
     int tmp;
-    if (regv_h(to)==regv_h(from)&&(regv_l(to)==regv_l(from))) 
+    if (regv_h(to)==regv_h(from)&&(regv_l(to)==regv_l(from))) {
 	return;
-    if (regv_h(to)==regv_l(from)&&(regv_l(to)==regv_h(from))) {
+    } 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);
-    } else if (regv_h(to)==regv_l(from)) {
-	printf("\tmove %s,%s\n",lregister_name_low(to),lregister_name_low(from));
-	printf("\tmove %s,%s\n",lregister_name_high(to),lregister_name_high(from));
-    } else {
-	printf("\tmove %s,%s\n",lregister_name_low(to),lregister_name_low(from));
-	printf("\tmove %s,%s\n",lregister_name_high(to),lregister_name_high(from));
     }
 }
 
@@ -3201,7 +3193,7 @@
         code_save_stacks();
 	clear_ptr_cache();
 	set_dreg(RET_DREGISTER,1);
-	printf("\tli.d $6,%g\n",0.0);
+	printf("\tli.d $6,%10.10g\n",0.0);
         extern_conv("dpcmp");
 	cmpreg = 2;
 	return;
@@ -3328,7 +3320,7 @@
     if (d) {
         code_save_stacks();
 	clear_ptr_cache();
-	set_lreg(LREGISTER_OPERAND_1,1);
+	set_dreg(DREGISTER_OPERAND_1,1);
         printf("\tmove $4,$0\n"); 
         printf("\tmove $5,$0\n"); 
 	/// set_dreg_operand(oreg,1);
@@ -3346,7 +3338,7 @@
     use_float(1,reg);
     code_save_stacks();
     clear_ptr_cache();
-    set_dreg(RET_DREGISTER,1);
+    set_dreg(DREGISTER_OPERAND,1);
     extern_conv("dptoli");
     set_ireg(RET_REGISTER,0);
     return;
@@ -3370,7 +3362,7 @@
     use_float(1,reg);
     code_save_stacks();
     clear_ptr_cache();
-    set_dreg(RET_DREGISTER,1);
+    set_dreg(DREGISTER_OPERAND,1);
     extern_conv("dptoul");
     set_ireg(RET_REGISTER,0);
     return;
@@ -3379,18 +3371,30 @@
 void
 code_u2d(int reg)
 { 
+    int tmp=new_lvar(SIZE_OF_INT);
     set_ireg(REGISTER_OPERAND,1);
+    code_assign_lvar(tmp,REGISTER_OPERAND,0);
     code_save_stacks();
     clear_ptr_cache();
     extern_conv("litodp");
+    code_rlvar(tmp,REGISTER_OPERAND);
+    printf("\tbgez\t%s,1f\n",register_name(REGISTER_OPERAND));
+    code_double_lib_c("dpadd",RET_DREGISTER,RET_DREGISTER,4.294967296e9);
+    printf("1:\n");
     set_dreg(RET_DREGISTER,0);
-    use_float(1,reg);
+    if (reg!=USE_CREG) {
+	use_float(1,reg);
+	if (reg!=RET_DREGISTER) {
+	    lmove(reg,RET_DREGISTER);
+	}
+    }
+    free_lvar(tmp);
     return;
 }
 
 void
 code_d2f(int reg) { 
-    set_dreg(RET_DREGISTER,1);
+    set_dreg(DREGISTER_OPERAND,1);
     code_save_stacks();
     clear_ptr_cache();
     extern_conv("dptofp");
@@ -3412,9 +3416,20 @@
 
 void
 code_f2i(int reg) {
+#if 0
+    int tmp=new_lvar(SIZE_OF_INT);
     use_int(reg);
     printf("\ttrunc.w.s %s,%s,%s\n",register_name(freg),
 	register_name(freg),register_name(ireg));
+    code_dassign_lvar(tmp,freg,1);
+    code_rlvar(tmp,reg);
+    free_lvar(tmp);
+#else
+    use_int(reg);
+    printf("\ttrunc.w.s %s,%s,%s\n",fregister_name(freg),
+	fregister_name(freg),register_name(ireg));
+    printf("\tmfc1    %s,%s\n",register_name(reg),fregister_name(freg));
+#endif
 }
 
 void
@@ -3461,6 +3476,7 @@
      use_float(0,reg);
      code_drlvar(n,0,reg);
      printf("\tcvt.s.w %s,%s\n",register_name(freg),register_name(freg));
+     free_lvar(n);
 }
 
 void
@@ -3579,10 +3595,24 @@
 static void
 code_double_lib(char *lib,int to,int reg,int oreg)
 {
+    int tmp;
     code_save_stacks();
     clear_ptr_cache();
-    set_dreg_operand(reg,1);
-    set_dreg_operand1(oreg,1);
+    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);
+    }
     extern_conv(lib);
     set_dreg(RET_DREGISTER,0);
     if (to!=RET_DREGISTER) {
@@ -3596,7 +3626,7 @@
     code_save_stacks();
     clear_ptr_cache();
     set_dreg_operand(from,1);
-    printf("\tli.d $6,%g\n",value);
+    printf("\tli.d $6,%10.10g\n",value);
     extern_conv(lib);
     set_dreg(RET_DREGISTER,0);
     if (to!=RET_DREGISTER) {
@@ -3764,6 +3794,7 @@
     } else {
 	if (car(e2)==DREGISTER) {
 	    use_float(d,reg);
+	    code_save_stacks();
 	    code_double_lib_c("dpadd",cadr(e2),cadr(e2),dir);
 	    if (reg!=cadr(e2)) lmove(reg,cadr(e2));
 	    return;
@@ -3903,8 +3934,8 @@
     }
     g_expr(list3(op1,e2,e1));
     switch(op) {
-	case DOP+GT:	printf("\tblez\t$2,$L_%d\n",l1);break;
-	case DOP+GE:	printf("\tbltz\t$2,$L_%d\n",l1);break;
+	case DOP+GT:	printf("\tbltz\t$2,$L_%d\n",l1);break;
+	case DOP+GE:	printf("\tblez\t$2,$L_%d\n",l1);break;
 	case DOP+EQ:	printf("\tbeq\t$2,$0,$L_%d\n",l1);break;
 	case DOP+NEQ:	printf("\tbne\t$2,$0,$L_%d\n",l1);break;
 	case FOP+GT:	printf("\tbc1t\t$L_%d\n",l1);break;
@@ -4369,10 +4400,24 @@
 static void
 code_longlong_lib(char *lib,int reg,int oreg)
 {
+    int tmp;
     code_save_stacks();
     clear_ptr_cache();
-    set_lreg_operand(reg,1);
-    set_lreg_operand1(oreg,1);
+    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);
+    }
     extern_conv(lib);
     set_lreg(RET_LREGISTER,0);
 }