changeset 276:ebaec1ae566e

MIPS double/longlong lib operand register conflict
author kono
date Fri, 21 May 2004 18:59:56 +0900
parents 8f09f8bbc494
children d5467cf30f58
files .gdbinit Changes mc-code-mips.c mc-parse.c test/code-gen.c test/float.c
diffstat 6 files changed, 161 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Fri May 21 14:00:02 2004 +0900
+++ b/.gdbinit	Fri May 21 18:59:56 2004 +0900
@@ -1,5 +1,5 @@
 tb main
-run  -s test/basic.c
+run  -s test/float.c
 # run  -s -ob00.s mc-parse.c
 # run -s test/code-gen-all.c
 define regs 
--- a/Changes	Fri May 21 14:00:02 2004 +0900
+++ b/Changes	Fri May 21 18:59:56 2004 +0900
@@ -4372,3 +4372,14 @@
 
 switch なんだけど、long long を通すと落ちるね。
 
+なかなかself compileが通らないな。今度は、getsym か。やっぱり、$gp
+関連?
+
+代入文の型が右辺値の型になっていた。こんなバグが、まだ、
+残っていたとは。
+
+double register の順序を決めないとdead lock するな。
+
+えーと、double register がconflict しまくるなぁ。
+さすがに function では起きないらしいが...
+ということは、set_[dl]operand の問題か。
--- 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);
 }
--- a/mc-parse.c	Fri May 21 14:00:02 2004 +0900
+++ b/mc-parse.c	Fri May 21 18:59:56 2004 +0900
@@ -2121,7 +2121,8 @@
     if(scalar(type)) return e2;
 #if FLOAT_CODE
     if (car(e2)==DCONST||car(e2)==FCONST)  return list2(CONST,(int)dcadr(e2));
-    if(type==FLOAT||type==DOUBLE) return list3(CONV,rvalue_t(e2,type),D2I);
+    if(type==FLOAT) return list3(CONV,rvalue_t(e2,type),F2I);
+    if(type==DOUBLE) return list3(CONV,rvalue_t(e2,type),D2I);
 #endif
 #if LONGLONG_CODE
     if (car(e2)==LCONST)  return list2(CONST,(int)lcadr(e2));
@@ -2138,7 +2139,8 @@
     if(scalar(type)) return e2;
 #if FLOAT_CODE
     if (car(e2)==DCONST||car(e2)==FCONST)  return list2(CONST,(unsigned)dcadr(e2));
-    if(type==FLOAT||type==DOUBLE) return list3(CONV,rvalue_t(e2,type),D2U);
+    if(type==FLOAT) return list3(CONV,rvalue_t(e2,type),F2U);
+    if(type==DOUBLE) return list3(CONV,rvalue_t(e2,type),D2U);
 #endif
 #if LONGLONG_CODE
     if(type==LONGLONG) return list3(CONV,rvalue_t(e2,type),LL2U);
@@ -2247,7 +2249,9 @@
 	t=type;
 	getsym(0);
 	e2=rvalue(expr1());
-	return assign_expr(e1,e2,t,type);
+	e1 =  assign_expr(e1,e2,t,type);
+	type = t;
+	return e1;
     case RSHIFT+AS: case LSHIFT+AS: case BAND+AS: 
     case EOR+AS: case BOR+AS: case MOD+AS:
 	no_float = 1;
--- a/test/code-gen.c	Fri May 21 14:00:02 2004 +0900
+++ b/test/code-gen.c	Fri May 21 18:59:56 2004 +0900
@@ -352,10 +352,21 @@
 void
 code_bool()
 {
+    int i1l,i2l;
+    unsigned int ui1l,ui2l;
+
     printf("code_bool > gvar %d %d %d %d %d %d\n",
 	i1>i2,ui1>ui2,i1>=i2,ui1>=ui2,ui1==ui2,i1!=i2);
     printf("code_bool < gvar %d %d %d %d %d %d\n",
 	i1<i2,ui1<ui2,i1<=i2,ui1<=ui2,ui1==ui2,i1!=i2);
+
+    i1l=i2l=i1;
+    ui1l=ui2l=ui1;
+
+    printf("code_bool eq > lvar %d %d %d %d %d %d\n",
+	i1l>i2l,ui1l>ui2l,i1l>=i2l,ui1l>=ui2l,ui1l==ui2l,i1l!=i2l);
+    printf("code_bool eq < lvar %d %d %d %d %d %d\n",
+	i1l<i2l,ui1l<ui2l,i1l<=i2l,ui1l<=ui2l,ui1l==ui2l,i1l!=i2l);
 }
 
 void
@@ -1082,9 +1093,10 @@
 void
 code_d2i()
 {
-    double d;
+    double d,z;
     int i;
     d = 0.1;
+    z = 555;
     i = d;
     printf("code_d2i %d\n",i);
 }
@@ -1093,8 +1105,9 @@
 code_i2d()
 {
     double d;
-    int i;
+    int i,z;
     i = 242342342;
+    z = -1;
     d = i;
     printf("code_i2d %g\n",d);
 }
@@ -1102,9 +1115,10 @@
 void
 code_d2u()
 {
-    double d;
+    double d,z;
     unsigned int i;
     d = 0.1;
+    z = 555;
     i = d;
     printf("code_d2u %ud\n",i);
 }
@@ -1113,8 +1127,9 @@
 code_u2d()
 {
     double d;
-    unsigned int i;
+    unsigned int i,z;
     i = 242342342;
+    z = 3;
     d = i;
     printf("code_u2d %g\n",d);
 }
@@ -1122,9 +1137,10 @@
 void
 code_f2i()
 {
-    float d;
+    float d,z;
     int i;
     d = 0.1;
+    z = 555;
     i = d;
     printf("code_d2i %d\n",i);
 }
@@ -1133,8 +1149,9 @@
 code_i2f()
 {
     float d;
-    int i;
+    int i,z;
     i = 24234342;
+    z = 555;
     d = i;
     printf("code_i2f %g\n",d);
 }
@@ -1142,9 +1159,10 @@
 void
 code_f2u()
 {
-    float d;
+    float d,z;
     unsigned int i;
     d = 0.1;
+    z = 555;
     i = d;
     printf("code_f2u %ud\n",i);
 }
@@ -1153,8 +1171,9 @@
 code_u2f()
 {
     float d;
-    unsigned int i;
+    unsigned int i,z;
     i = 242342342;
+    z = 555;
     d = i;
     printf("code_u2f %g\n",d);
 }
@@ -1454,6 +1473,9 @@
 void
 code_dbool()
 {
+    float lf0,lf1;
+    double ld0,ld1;
+
     printf("code_bool > float %d %d %d %d\n",
 	f0>f1,f0>=f1,f0==f1,f0!=f1);
     printf("code_bool > double %d %d %d %d\n",
@@ -1462,6 +1484,19 @@
 	f0<f1,f0<=f1,f0==f1,f0!=f1);
     printf("code_bool < double %d %d %d %d\n",
 	d0<d1,d0<=d1,d0==d1,d0!=d1);
+
+   lf0=lf1=f0;
+   ld0=ld1=d0;
+
+    printf("code_bool eq > float %d %d %d %d\n",
+	lf0>lf1,lf0>=lf1,lf0==lf1,lf0!=lf1);
+    printf("code_bool eq > double %d %d %d %d\n",
+	ld0>ld1,ld0>=ld1,ld0==ld1,ld0!=ld1);
+    printf("code_bool eq < float %d %d %d %d\n",
+	lf0<lf1,lf0<=lf1,lf0==lf1,lf0!=lf1);
+    printf("code_bool eq < double %d %d %d %d\n",
+	ld0<ld1,ld0<=ld1,ld0==ld1,ld0!=ld1);
+
 }
 #endif
 
@@ -1471,10 +1506,22 @@
 void
 code_lbool()
 {
+    long long l0l,l1l;
+    unsigned long long ul0l,ul1l;
+
     printf("code_bool > long long %d %d %d %d %d %d\n",
 	l1>l0,ul1>ul0,l1>=l0,ul1>=ul0,ul1==ul0,l1!=l0);
     printf("code_bool < long long %d %d %d %d %d %d\n",
 	l1<l0,ul1<ul0,l1<=l0,ul1<=ul0,ul1==ul0,l1!=l0);
+
+    l0l=l1l=l0;
+    ul0l=ul1l=ul0;
+
+    printf("code_bool eq > long long %d %d %d %d %d %d\n",
+	l1l>l0l,ul1l>ul0l,l1l>=l0l,ul1l>=ul0l,ul1l==ul0l,l1l!=l0l);
+    printf("code_bool eq < long long %d %d %d %d %d %d\n",
+	l1l<l0l,ul1l<ul0l,l1l<=l0l,ul1l<=ul0l,ul1l==ul0l,l1l!=l0l);
+
 }
 
 // int lpop_register()
--- a/test/float.c	Fri May 21 14:00:02 2004 +0900
+++ b/test/float.c	Fri May 21 18:59:56 2004 +0900
@@ -82,16 +82,16 @@
    d = i;
    i = f;
    f = i;
-   printf("\n%d %g %f",i,d,f);
+   printf("\ni=%d d=%g f=%f",i,d,f);
    f = g = d = d1 = d2 = f;
-   printf(" %d %g %f %g\n",i,d,f,g);
+   printf(" i=%d d=%g f=%f g=%g\n",i,d,f,g);
 
    d = 4204967294.4234; f=4204967294.4234;
    u = d;
    d = u;
    u = f;
    f = u;
-   printf("%u %g %f\n",u,d,f);
+   printf("u=%u d=%g f=%f\n",u,d,f);
 
    print(1.0);
    print(0.1234);