changeset 85:3789aef7331d

minor fix
author kono
date Wed, 05 Mar 2003 13:43:52 +0900
parents 1a723130a2c7
children 4d1275f8a5b5
files Changes mc-code-ia32.c mc-code.h mc-codegen.c mc-parse.c mc.h test/float.c
diffstat 7 files changed, 260 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Wed Mar 05 10:54:33 2003 +0900
+++ b/Changes	Wed Mar 05 13:43:52 2003 +0900
@@ -1877,9 +1877,25 @@
 fmulp とかでは、fpp のstackのつじつまはあう。fstl とかだと、
 合わない。fstpl すればいいんだが、そうすると連続代入でまずくなる。
 値を使うかどうかを代入時に知ることができれば良いんだが。
+(use flag で判断することにした)
 
 結局、freg は、使わなかったね。0が、入っているので直さないとまずいか。
 fregを見て、stack を直すってのは、やっぱり、まずいよな...
 
 でも、浮動小数点レジスタを持つCPUの場合はいるんじゃないの?
 
+Wed Mar  5 11:25:11 JST 2003
+
+printf では 引数はdoubleで統一する必要がある。goto() では、
+それをするのはまずい。局所変数と同等だから。ってことは、
+
+関数の引数はdoubleにしないとだめなのね。プロトタイプが
+ある時は、その限りでない。(うーむ...)
+
+あと、fpp のスタックに頼っているので、overflowした時に
+困らないか? ほとんどの場合でだいじょうぶだが、だめだった
+時にerrorぐらい出せば? でも実行時にしかわからないか...
+
+I2D でさ、singned/unsigned の区別がいるね。
+
+やっぱり FCONST いるんじゃないの?
--- a/mc-code-ia32.c	Wed Mar 05 10:54:33 2003 +0900
+++ b/mc-code-ia32.c	Wed Mar 05 13:43:52 2003 +0900
@@ -717,14 +717,19 @@
 	} else if (t==DOUBLE) {
 	    g_expr(e4);
 	    printf("\tleal\t-8(%%esp),%%esp\n\tfstpl\t(%%esp)\n");
+	    nargs += size_of_double/size_of_int;
 	    fregv[freg]=0;
-	    nargs += size_of_double/size_of_int;
 	    continue;
 	} else if (t==FLOAT) {
 	    g_expr(e4);
+#if 0
 	    printf("\tleal\t-4(%%esp),%%esp\n\tfstps\t(%%esp)\n");
+	    nargs += size_of_float/size_of_int;
+#else
+	    printf("\tleal\t-8(%%esp),%%esp\n\tfstpl\t(%%esp)\n");
+	    nargs += size_of_double/size_of_int;
+#endif
 	    fregv[freg]=0;
-	    nargs += size_of_float/size_of_int;
 	    continue;
 	} else if (car(t)==STRUCT||car(t)==UNION) {
 	    nargs += struct_push(e4,t);
@@ -1407,8 +1412,8 @@
     printf("\tmovb    $12, 1(%%esp)\n");
     printf("\tfldcw   (%%esp)\n");
     printf("\tmovl    %s, (%%ebp)\n",register_name(creg,0));
-    printf("\tfistpl  %d(%%ebp)\n",size_of_int);
-    printf("\tfldcw   (%%ebp)\n");
+    printf("\tfistpl  %d(%%esp)\n",size_of_int);
+    printf("\tfldcw   (%%esp)\n");
     printf("\tpopl    %s\n",register_name(creg,0));
     printf("\tpopl    %s\n",register_name(creg,0));
 }
@@ -1420,6 +1425,28 @@
     printf("\tlea %d(%%esp),%%esp\n",size_of_int);
 }
 
+void code_d2u()
+{ 
+    /* fuck you! */
+    printf("\tlea -%d(%%esp),%%esp\n",size_of_int*2);
+    printf("\tfnstcw  (%%esp)\n");
+    printf("\tmovl    (%%esp), %s\n",register_name(creg,0));
+    printf("\tmovb    $12, 1(%%esp)\n");
+    printf("\tfldcw   (%%esp)\n");
+    printf("\tmovl    %s, (%%ebp)\n",register_name(creg,0));
+    printf("\tfistpl  %d(%%esp)\n",size_of_int);
+    printf("\tfldcw   (%%esp)\n");
+    printf("\tpopl    %s\n",register_name(creg,0));
+    printf("\tpopl    %s\n",register_name(creg,0));
+}
+
+void code_u2d()
+{ 
+    printf("\tpushl %s\n",register_name(creg,0));
+    printf("\tfildl (%%esp)\n");
+    printf("\tlea %d(%%esp),%%esp\n",size_of_int);
+}
+
 void code_drgvar(int e2,int d)
 { 
     printf("\t%s %s\n",fload(d),(char *)caddr(e2)) ;
@@ -1445,8 +1472,8 @@
 { 
     switch(op) {
     case DADD: printf("\tfaddp %%st,%%st(1)\n"); break;
-    case DSUB: printf("\tfsubrp %%st,%%st(1)\n"); break;
-    case DDIV: printf("\tfdivrp %%st,%%st(1)\n"); break;
+    case DSUB: printf("\tfsubp %%st,%%st(1)\n"); break;
+    case DDIV: printf("\tfdivp %%st,%%st(1)\n"); break;
     case DMUL: printf("\tfmulp %%st,%%st(1)\n"); break;
     case DCOMP: 
 	/* printf("\tfxch\t%%st(1)\n"); */
--- a/mc-code.h	Wed Mar 05 10:54:33 2003 +0900
+++ b/mc-code.h	Wed Mar 05 13:43:52 2003 +0900
@@ -95,6 +95,8 @@
 extern void emit_dpush();
 extern void code_i2d();
 extern void code_d2i();
+extern void code_u2d();
+extern void code_d2u();
 
 extern void code_dpreinc(int e1,int e2,int d);
 extern void code_dpostinc(int e1,int e2,int d);
--- a/mc-codegen.c	Wed Mar 05 10:54:33 2003 +0900
+++ b/mc-codegen.c	Wed Mar 05 13:43:52 2003 +0900
@@ -346,28 +346,28 @@
 	g_expr0(e2);
 	return;
     case MINUS:  /* レジスタに対し、neglを実行すれば実現可能 */
-	g_expr0(e2);
-	code_neg();
+	g_expr0(e2); code_neg();
 	return;
     case DMINUS: 
-	g_expr0(e2);
-	code_dneg();
+	g_expr0(e2); code_dneg();
 	return;
     case I2D: 
-	g_expr0(e2);
-	code_i2d();
+	g_expr0(e2); code_i2d();
 	return;
     case D2I: 
-	g_expr0(e2);
-	code_d2i();
+	g_expr0(e2); code_d2i();
+	return;
+    case U2D: 
+	g_expr0(e2); code_u2d();
+	return;
+    case D2U: 
+	g_expr0(e2); code_d2u();
 	return;
     case BNOT:   /* ~ */
-	g_expr0(e2);
-	code_not();
+	g_expr0(e2); code_not();
 	return;
     case LNOT:   /* !  */
-	g_expr0(e2);
-	code_lnot();
+	g_expr0(e2); code_lnot();
 	return;
     case PREINC:
 	code_preinc(e1,e2);
--- a/mc-parse.c	Wed Mar 05 10:54:33 2003 +0900
+++ b/mc-parse.c	Wed Mar 05 13:43:52 2003 +0900
@@ -1642,6 +1642,34 @@
 }
 
 int
+float_value(int e2,int type)
+{
+    if (car(e2)==CONST)  return dlist2(DCONST,(double)cadr(e2));
+    if(type==FLOAT||type==DOUBLE) return e2;
+    if(type==UNSIGNED) return list2(U2D,e2);
+    if(integral(type)) return list2(I2D,e2);
+    error(TYERR); return dlist2(DCONST,1.0);
+}
+
+int
+int_value(int e2,int type)
+{
+    if (car(e2)==DCONST||car(e2)==FCONST)  return list2(CONST,(int)dcadr(e2));
+    if(scalar(type)) return e2;
+    if(type==FLOAT||type==DOUBLE) return list2(D2I,e2);
+    error(TYERR); return list2(CONST,1);
+}
+
+int
+unsigned_value(int e2,int type)
+{
+    if(scalar(type)) return e2;
+    if(type==FLOAT||type==DOUBLE) list2(D2U,e2);
+    error(TYERR); return e2;
+}
+
+
+int
 assign_expr0(int e1,int e2,int t,int type) {
     int stype;
     stype=type;
@@ -1655,19 +1683,17 @@
     if(t==VOID)
 	error(TYERR);
     if(t==CHAR) {
-	if (type==FLOAT||type==DOUBLE) e2=list2(D2I,e2);
-	else if (!integral(type)) error(TYERR);
+	e2=int_value(e2,type);
+	if (!integral(type)) error(TYERR);
 	type= INT;return(list3(CASS,e1,e2));
     } else if(t==DOUBLE) {
-	if(integral(type)) e2=list2(I2D,e2);
-	else if (type!=FLOAT&&type!=DOUBLE) error(TYERR);
+	e2=float_value(e2,type);
 	type= t;return(list3(DASS,e1,e2));
     } else if(t==FLOAT) {
-	if(integral(type)) e2=list2(I2D,e2);
-	else if (type!=FLOAT&&type!=DOUBLE) error(TYERR);
+	e2=float_value(e2,type);
 	type= t;return(list3(FASS,e1,e2));
     } else if(scalar(t)) {
-	if (type==FLOAT||type==DOUBLE) e2=list2(D2I,e2);
+	e2=int_value(e2,type);
 	type=t;
 	return(list3(ASS,e1,e2));
     } else if((car(t)==STRUCT||car(t)==UNION)) {
@@ -1728,6 +1754,15 @@
 	getsym();
 	e2=rvalue(expr1());
 
+	if(!(integral(type)||type==FLOAT||type==DOUBLE)) error(TYERR);
+	if (t==FLOAT) {
+	    e2=float_value(e2,type); type=t;
+	    return(list4(FASSOP,e1,e2,op));
+	}
+	if (t==DOUBLE) {
+	    e2=float_value(e2,type); type=t;
+	    return(list4(DASSOP,e1,e2,op));
+	}
 	if(!integral(type)) error(TYERR);
 	if((t==UNSIGNED||type==UNSIGNED)&&
 	    (op==MUL||op==DIV||op==MOD||op==RSHIFT||op==LSHIFT))
@@ -1737,12 +1772,6 @@
 	    return(list4(CASSOP,e1,e2,op));
 	}
 	type=t;
-	if (t==FLOAT) {
-	    return(list4(FASSOP,e1,e2,op));
-	}
-	if (t==DOUBLE) {
-	    return(list4(DASSOP,e1,e2,op));
-	}
 	if(integral(t)) return(list4(ASSOP,e1,e2,op));
 	if((op!=ADD&&op!=SUB)||car(t)!=POINTER) error(TYERR);
 	e2=binop(MUL,e2,list2(CONST,size(cadr(t))),INT,UNSIGNED);
@@ -2178,10 +2207,11 @@
 	    conv->rpar_();
 	    checksym(RPAR);
 	    e1=expr13();
-	    if (integral(type)) {
-		if(t==FLOAT||t==DOUBLE) e1=list2(I2D,e1);
-	    } else if(type==FLOAT||type==DOUBLE) {
-		if(integral(t)) e1=list2(D2I,e1);
+	    if (integral(t)) {
+		if(t==UNSIGNED) e1=unsigned_value(e1,type);
+		else e1=int_value(e1,type);
+	    } else if(t==FLOAT||t==DOUBLE) {
+		if(integral(type)) e1=float_value(e1,type);
 	    }
 	    type=t;
 	    return e1;
@@ -2375,13 +2405,11 @@
     double d1,d2,d;
 
     type= DOUBLE;
+    if (integral(t1)) { e1=float_value(e1,t1); t1=DOUBLE; }
+    if (integral(t2)) { e2=float_value(e2,t2); t2=DOUBLE; }
     if(car(e1)==DCONST&&car(e2)==DCONST) {
-	if (integral(t1)) { d1=cadr(e1);
-	} else if(t1==DOUBLE) d1=dcadr(e1);
-	else error(-1);
-	if (integral(t2)) { d2=cadr(e2);
-	} else if(t2==DOUBLE) d2=dcadr(e2);
-	else error(-1);
+	d1=dcadr(e1);
+	d2=dcadr(e2);
 	switch(op) {
 	case ADD: d=d1+d2; break;
 	case SUB: d=d1-d2; break;
@@ -2403,8 +2431,6 @@
 	}
 	return dlist2(DCONST,d);
     }
-    if (integral(t1)) e1=list2(I2D,e1);
-    if (integral(t2)) e2=list2(I2D,e2);
     if(op==GT||op==GE||op==LT||op==LE||op==EQ||op==NEQ||
 	    ADD||SUB||MUL||DIV)
 	return(list3(op+DOP,e1,e2));
--- a/mc.h	Wed Mar 05 10:54:33 2003 +0900
+++ b/mc.h	Wed Mar 05 13:43:52 2003 +0900
@@ -170,18 +170,21 @@
 #define LRLVAR	89
 #define LRINDIRECT	90
 #define DCONST	91
-#define LCONST	92
-#define DASS	93
-#define FASS	94
-#define LASS	95
-#define SHASS	96
+#define FCONST	92
+#define LCONST	93
+#define DASS	94
+#define FASS	95
+#define LASS	96
+#define SHASS	97
 
-#define I2D	97
-#define D2I	98
-#define FPOSTINC	99
-#define DPOSTINC	100
-#define FPREINC	101
-#define DPREINC	102
+#define I2D	98
+#define D2I	99
+#define U2D	100
+#define D2U	101
+#define FPOSTINC	102
+#define DPOSTINC	103
+#define FPREINC	104
+#define DPREINC	105
 
 #define US	1
 #define AS	200
--- a/test/float.c	Wed Mar 05 10:54:33 2003 +0900
+++ b/test/float.c	Wed Mar 05 13:43:52 2003 +0900
@@ -17,6 +17,7 @@
 main(int ac,char *av[]) {
    double g;
    int i;
+   unsigned u;
 
    g = 1.0;
    g = -g;
@@ -36,6 +37,7 @@
    if(d<d2) printf("-8 ");
    if(d<=d1) printf("9 ");
    if(d<=d2) printf("-9 ");
+   d = 123.4234; f=-234.333;
    i = d;
    d = i;
    i = f;
@@ -44,6 +46,13 @@
    f = g = d = g = d = f;
    printf(" %d %g %f %g\n",i,d,f,g);
 
+   d = 4294967295.4234; f=4294967295.4234;
+   u = d;
+   d = u;
+   u = f;
+   f = u;
+   printf("%u %g %f\n",u,d,f);
+
    print(1.0);
    print(0.1234);
    print(1.234e10);
@@ -89,29 +98,151 @@
     float f1;
     double g;
     double g1;
+    float *pf;
+    float *pf1;
+    double *pg;
+    double *pg1;
+    int n = 1;
 
     f = 1.3;
 
     g = 1.0;
     g = g+g;
+    printf("%d:%g\t",n++,g);
     g1 = g*g;
+    printf("%d:%g\t",n++,g1);
     g = g/g1;
+    printf("%d:%g\t",n++,g);
     g = g-g1;
+    printf("%d:%g\t",n++,g);
     g = sin(g1);
+    printf("%d:%g\t",n++,g);
     g = testd(g,g1);
+    printf("%d:%g\t",n++,g);
+    printf("\n");
 
     f = f+f;
+    printf("%d:%g\t",n++,f);
     f1 = f*f;
+    printf("%d:%g\t",n++,f1);
     f = f/f1;
+    printf("%d:%g\t",n++,f);
     f = f-f1;
+    printf("%d:%g\t",n++,f);
     f = sin(f1);
+    printf("%d:%g\t",n++,f);
+    printf("\n");
+
+    g = g1++ - ++g1;
+    printf("%d:%g\t",n++,g);
+
+    g = f1++ - ++f1;
+    printf("%d:%g\t",n++,g);
 
     g = f+f;
+    printf("%d:%g\t",n++,g);
     f = g*g;
+    printf("%d:%g\t",n++,f);
     f = testf(f,f1);
+    printf("%d:%g\t",n++,f);
 
     g = g*g+f*f-g1*g1;
+    printf("%d:%g\t",n++,g);
+    printf("\n");
 
-    printf("%g %g %g %g\n",g,f,g1,f1);
+    n=1;
+    f = 1.3; pf=&f; pf1=&f1;
+
+    g = 1.0; pg=&g; pg1=&g1;
+    *pg = *pg+ *pg;
+    printf("%d:%g\t",n++,*pg);
+    *pg1 = *pg**pg;
+    printf("%d:%g\t",n++,*pg1);
+    *pg = *pg/ *pg1;
+    printf("%d:%g\t",n++,*pg);
+    *pg = *pg-*pg1;
+    printf("%d:%g\t",n++,*pg);
+    *pg = sin(*pg1);
+    printf("%d:%g\t",n++,*pg);
+    *pg = testd(*pg,*pg1);
+    printf("%d:%g\t",n++,*pg);
+    printf("\n");
+
+    *pf = *pf+*pf;
+    printf("%d:%g\t",n++,*pf);
+    *pf1 = *pf**pf;
+    printf("%d:%g\t",n++,*pf1);
+    *pf = *pf/ *pf1;
+    printf("%d:%g\t",n++,*pf);
+    *pf = *pf-*pf1;
+    printf("%d:%g\t",n++,*pf);
+    *pf = sin(*pf1);
+    printf("%d:%g\t",n++,*pf);
+    printf("\n");
+
+    *pg = (*pg1)++ - ++(*pg1);
+    printf("%d:%g\t",n++,*pg);
+
+    *pg = (*pf1)++ - ++(*pf1);
+    printf("%d:%g\t",n++,*pg);
+
+    *pg = *pf+*pf;
+    printf("%d:%g\t",n++,*pg);
+    *pf = *pg**pg;
+    printf("%d:%g\t",n++,*pf);
+    *pf = testf(*pf,*pf1);
+    printf("%d:%g\t",n++,*pf);
+
+    *pg = *pg**pg+*pf**pf-*pg1**pg1;
+    printf("%d:%g\t",n++,*pg);
+    printf("\n");
+
+    n=1;
+    f = 1.3;
+    g = 1.0;
+
+    g *= 2*g;
+    printf("%d:%g\t",n++,g);
+    g /= 2*g;
+    printf("%d:%g\t",n++,g);
+    g -= 2*g;
+    printf("%d:%g\t",n++,g);
+    g += 2*g;
+    printf("%d:%g\t",n++,g);
+
+    f *= 2*g;
+    printf("%d:%g\t",n++,f);
+    f /= 2*g;
+    printf("%d:%g\t",n++,f);
+    f -= 2*g;
+    printf("%d:%g\t",n++,f);
+    f += 2*g;
+    printf("%d:%g\t",n++,f);
+    printf("\n");
+
+    n=1;
+    f = 1.3;
+    g = 1.0;
+
+    *pg *= 2**pg;
+    printf("%d:%g\t",n++,*pg);
+    *pg /= 2**pg;
+    printf("%d:%g\t",n++,*pg);
+    *pg -= 2**pg;
+    printf("%d:%g\t",n++,*pg);
+    *pg += 2**pg;
+    printf("%d:%g\t",n++,*pg);
+
+    *pf *= 2**pg;
+    printf("%d:%g\t",n++,*pf);
+    *pf /= 2**pg;
+    printf("%d:%g\t",n++,*pf);
+    *pf -= 2**pg;
+    printf("%d:%g\t",n++,*pf);
+    *pf += 2**pg;
+    printf("%d:%g\t",n++,*pf);
+    printf("\n");
+
+
     return;
 }