changeset 91:9b1aeb62e0b9

powerpc continue... (floating point)
author kono
date Fri, 07 Mar 2003 05:22:01 +0900
parents 07e3113c3c13
children e7f8515ba882
files mc-code-powerpc.c mc-codegen.c mc.h test/float.c
diffstat 4 files changed, 225 insertions(+), 97 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-powerpc.c	Fri Mar 07 03:09:02 2003 +0900
+++ b/mc-code-powerpc.c	Fri Mar 07 05:22:01 2003 +0900
@@ -1563,161 +1563,276 @@
     regs[creg]=1;
 }
 
+static int i2d_lib_used=0;
+static char *i2d_lib[] = {
+".data",
+".literal8",
+"        .align 3",
+"__i2dLC0:",
+"        .long   1127219200",
+"        .long   -2147483648",
+".text",
+"        .align 2",
+"i2d:",
+"        mflr r0",
+"        bcl 20,31,__i2dL1$pb",
+"__i2dL1$pb:",
+"        mflr r10",
+"        mtlr r0",
+"        xoris r3,r3,0x8000",
+"        stw r3,-28(r1)",
+"        lis r0,0x4330",
+"        stw r0,-32(r1)",
+"        lfd f0,-32(r1)",
+"        addis r9,r10,ha16(__i2dLC0-__i2dL1$pb)",
+"        lfd f1,lo16(__i2dLC0-__i2dL1$pb)(r9)",
+"        fsub f1,f0,f1",
+"        blr",
+0
+};
+
 void code_i2d()
 { 
+    d2u_lib_used=1;
     char *frn = register_name(freg);
     char *crn = register_name(creg);
-    int  dreg = get_register();
-    char *drn = register_name(dreg);
-    disp-=size_of_double;
-
-    printf("\tlis %s,0x4330\n",drn);
-    printf("\txoris %s,%s,0x8000\n",crn,crn);
-    printf("\tstw %s,%d(r1)\n",crn,disp+size_of_int);
-    printf("\tstw %s,%d(r1)\n",drn,disp);
-    printf("\tlfd %s,%d(r1)\n",frn,disp);
-    free_register(dreg);
+    printf("\tmr r3,%s\n",crn);
+    printf("\tbl i2d_\n");
+    printf("\tfmr %s,f1\n",frn);
     fregs[freg]=1;
     regs[creg]=0;
 }
 
+static int d2u_lib_used=0;
+static char *d2u_lib[] = {
+".literal8",
+"        .align 3",
+"__d2uLC0:",
+"        .long   1105199104",
+"        .long   0",
+".text",
+"        .align 2",
+"d2u:",
+"        mflr r0",
+"        bcl 20,31,__d2uL1$pb",
+"__d2uL1$pb:",
+"        mflr r10",
+"        mtlr r0",
+"        addis r9,r10,ha16(__d2uLC0-__d2uL1$pb)",
+"        lfd f0,lo16(__d2uLC0-__d2uL1$pb)(r9)",
+"        fcmpu cr0,f1,f0",
+"        cror 2,1,2",
+"        beq- cr0,__d2uL2",
+"        fctiwz f0,f1",
+"        stfd f0,-32(r1)",
+"        lwz r3,-28(r1)",
+"        blr",
+"__d2uL2:",
+"        addis r9,r10,ha16(__d2uLC0-__d2uL1$pb)",
+"        lfd f0,lo16(__d2uLC0-__d2uL1$pb)(r9)",
+"        fsub f0,f1,f0",
+"        fctiwz f0,f0",
+"        stfd f0,-24(r1)",
+"        lwz r3,-20(r1)",
+"        xoris r3,r3,0x8000",
+"        blr",
+0
+};
+
 void code_d2u()
 { 
-        bl _u2w
-        addis r9,r31,ha16(_d-L1$pb)
-        la r9,lo16(_d-L1$pb)(r9)
-        lfd f13,0(r9)
-        addis r11,r31,ha16(LC1-L1$pb)
-        lfd f0,lo16(LC1-L1$pb)(r11)
-        fcmpu cr0,f13,f0
-        cror 2,1,2
-        beq- cr0,L2
-        fctiwz f0,f13
-        stfd f0,72(r1)
-        lwz r0,76(r1)
-        b L3
-L2:
-        lfd f0,0(r9)
-        addis r9,r31,ha16(LC1-L1$pb)
-        lfd f13,lo16(LC1-L1$pb)(r9)
-        fsub f0,f0,f13
-        fctiwz f0,f0
-        stfd f0,80(r1)
-        lwz r0,84(r1)
-        xoris r0,r0,0x8000
-L3:
-        stw r0,0(r29)
+    d2u_lib_used=1;
+    char *frn = register_name(freg);
+    char *crn = register_name(creg);
+    printf("\tfmr f1,%s\n",frn);
+    printf("\tbl d2u\n");
+    printf("\tmr %s,r3\n",crn);
+    fregs[freg]=1;
+    regs[creg]=0;
+}
 
-    code_d2i();
-}
+static int u2d_lib_used=0;
+static char *u2d_lib[] = {
+".data",
+".literal8",
+"        .align 3",
+"__u2dLC1:",
+"        .long   1127219200",
+"        .long   0",
+".text",
+"        .align 2",
+"u2d:",
+"        mflr r0",
+"        bcl 20,31,__u2dL2$pb",
+"__u2dL2$pb:",
+"        mflr r10",
+"        mtlr r0",
+"        stw r3,-28(r1)",
+"        lis r0,0x4330",
+"        stw r0,-32(r1)",
+"        lfd f0,-32(r1)",
+"        addis r9,r10,ha16(__u2dLC1-__u2dL2$pb)",
+"        lfd f1,lo16(__u2dLC1-__u2dL2$pb)(r9)",
+"        fsub f1,f0,f1",
+"        blr",
+0
+};
 
 void code_u2d()
 { 
-    code_i2d();
-    lwz r0,0(r29)
-        stw r0,68(r1)
-        lis r0,0x4330
-        stw r0,64(r1)
-        lfd f13,64(r1)
-        addis r9,r31,ha16(LC0-L1$pb)
-        lfd f0,lo16(LC0-L1$pb)(r9)
-        fsub f13,f13,f0
-        addis r9,r31,ha16(_d1-L1$pb)
-        stfd f13,lo16(_d1-L1$pb)(r9)
+    u2d_lib_used=1;
+    char *frn = register_name(freg);
+    char *crn = register_name(creg);
+    printf("\tmr r3,%s\n",crn);
+    printf("\tbl u2d\n");
+    printf("\tfmr %s,f1\n",frn);
+    fregs[freg]=1;
+    regs[creg]=0;
 }
 
 void code_drgvar(int e2,int d)
 { 
-    printf("\t%s %s\n",fload(d),(char *)caddr(e2)) ;
+    int r;
+    r = get_ptr_cache((char*)caddr(e1));
+    printf("\t%s %s,(%s)\n",fload(d),register_name(freg),register_name(r));
 }
 
 
 void code_drlvar(int e2,int d)
 { 
-    printf("\t%s %d(%%ebp)\n",fload(d),e2);
+    printf("\t%s %s,%d(r1)\n",fload(d),register_name(freg),e2);
 }
 
 void code_cmp_drgvar(int e2)
 { 
-    printf("\tfcomp %s\n",(char *)caddr(e2)) ;
+    int r;
+    char *frn=register_name(freg);
+    int g=get_fregister();
+    char *grn=register_name(g);
+    r = get_ptr_cache((char*)caddr(e1));
+    printf("\t%s,(%s)\n",fload(d),grn,register_name(r));
+    printf("\tfcmpu cr0,%s,%s\n",frn,grn);
+    free_fregister(g);
 }
 
 void code_cmp_drlvar(int e2)
 { 
-    printf("\tfcomp %d(%%ebp)\n",e2);
+    printf("\tfcmpu %d(%%ebp)\n",e2);
+    char *frn=register_name(freg);
+    int g=get_fregister();
+    char *grn=register_name(g);
+    printf("\t%s,%d(r1)\n",fload(d),grn,e2);
+    printf("\tfcmpu cr0,%s,%s\n",frn,grn);
+    free_fregister(g);
 }
 
 void dtosop(int op,int e1)
 { 
+    char *opn;
+    char *frn=register_name(freg);
+    char *grn=register_name(e1);
     switch(op) {
-    case DADD: printf("\tfaddp %%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"); */
-	printf("\tfucompp\n");
-	printf("\tfnstsw\t%%ax\n");
+    case DADD: opn="fadd"; break;
+    case DSUB: opn="fadd"; break;
+    case DDIV: opn="fadd"; break;
+    case DMUL: opn="fadd"; break;
+    case DCMP: 
+	printf("\tfcompu cr0,%s,%s\n",opn,frn,grn);
+	fgree_register(e1);
+	break;
+    case DCMPGE: 
+	printf("\tfcompu cr7,%s,%s\n",opn,frn,grn);
+	fgree_register(e1);
 	break;
     }
+    printf("\t%s %s,%s,%s\n",opn,frn,frn,grn);
+    fgree_register(e1);
 }
 
 void
 code_dassop(int op,int d) {
-    /* we have lvalue in creg, applied floating value is in %st(0) */
-    printf("\t%s (%s)\n",fload(d),register_name(creg));
-    dtosop(op,0);
-    printf("\t%s (%s)\n",fstore(d),register_name(creg));
+    /* we have lvalue in creg, applied floating value is in freg */
+    char *frn=register_name(freg);
+    int  e1=get_fregister();
+    char *grn=register_name(e1);
+    char *crn=register_name(creg);
+
+    printf("\t%s %s,(%s)\n",fload(d),grn,crn);
+    dtosop(op,e1);
+    printf("\t%s %s,(%s)\n",fstore(d),frn,crn);
 }
 
+static int use_float_one=0;
+
 void
 code_dpreinc(int e1,int e2,int d) {
+    char *frn;
+    char *crn;
+    int  g;
+    char *grn,*drn;
+    int r;
+    r = get_ptr_cache("float_one");
+    use_float_one=1;
+
     g_expr(e2);
-    printf("\t%s (%s)\n",fload(d),register_name(creg));
-    printf("\tfld1\n");
+
+    crn=register_name(creg);
+    frn=register_name(freg);
+    drn=register_name(r);
+    grn=register_name(g);
+
+    printf("\t%s %s,(%s)\n",fload(d),frn,crn);
+    printf("\tfls %s,(%s)\n",grn,drn);
     if (caddr(e1)>0)
-	printf("\tfaddp %%st,%%st(1)\n");
+	printf("\tfadd %s,%s,%s\n",frn,frn,grn);
     else
-	printf("\tfsubrp %%st,%%st(1)\n");
-    printf("\t%s (%s)\n",fstore(d),register_name(creg));
+	printf("\tfsub %s,%s,%s\n",frn,frn,grn);
+    printf("\t%s %s,(%s)\n",fstore(d),frn,crn);
 }
 
 void
 code_dpostinc(int e1,int e2,int d) {
+    char *frn;
+    char *crn;
+    int  g;
+    char *grn,*drn;
+    int r;
+    r = get_ptr_cache("float_one");
+    use_float_one=1;
+
     g_expr(e2);
-    printf("\t%s (%s)\n",fload(d),register_name(creg));
-    if (use)
-	printf("\t%s (%s)\n",fload(d),register_name(creg));
-    printf("\tfld1\n");
+
+    crn=register_name(creg);
+    frn=register_name(freg);
+    drn=register_name(r);
+    grn=register_name(g);
+
+    printf("\t%s %s,(%s)\n",fload(d),frn,crn);
+    printf("\tfls %s,(%s)\n",grn,drn);
     if (caddr(e1)>0)
-	printf("\tfaddp %%st,%%st(1)\n");
+	printf("\tfadd %s,%s,%s\n",grn,frn,grn);
     else
-	printf("\tfsubrp %%st,%%st(1)\n");
-    printf("\t%s (%s)\n",(use?fstore_u(d):fstore(d)),register_name(creg));
+	printf("\tfsub %s,%s,%s\n",grn,frn,grn);
+    printf("\t%s %s,(%s)\n",fstore(d),grn,crn);
 }
 
 void
 drexpr(int e1, int e2,int l1, int op)
 {       
-    g_expr(list3(DCOMP,e1,e2));
+    g_expr(list3(((op==DOP+GE)?DCMPGE:DCMP),e1,e2));
     switch(op) {
 	case DOP+GE:
-	    printf("\ttestb\t$5,%%ah\n");
-	    printf("\tjne\t_%d\n",l1);
+	    printf("\tcror 2,29,30\n");
+	    printf("\tbeq\tcr0,_%d\n",l1);
 	    break;
 	case DOP+GT:
-	    printf("\ttestb\t$69,%%ah\n");
-	    printf("\tjne\t_%d\n",l1);
+	    printf("\tbgt\tcr0,_%d\n",l1);
 	    break;
 	case DOP+EQ:
-	    printf("\tandb\t$69,%%ah\n");
-	    printf("\txorb\t$64,%%ah\n");
-	    printf("\tjne\t_%d\n",l1);
+	    printf("\tbeq\tcr0,_%d\n",l1);
 	    break;
 	case DOP+NEQ:
-	    printf("\tandb\t$69,%%ah\n");
-	    printf("\txorb\t$64,%%ah\n");
-	    printf("\tje\t_%d\n",l1);
+	    printf("\tbne\tcr0,_%d\n",l1);
 	    break;
     }
 }
--- a/mc-codegen.c	Fri Mar 07 03:09:02 2003 +0900
+++ b/mc-codegen.c	Fri Mar 07 05:22:01 2003 +0900
@@ -243,7 +243,7 @@
 	return;
     case DMUL: case DDIV:
     case DADD: case DSUB:
-    case DCMP:
+    case DCMP: case DCMPGE:
 	dmachinop(e1);
 	return;
     case COND:
--- a/mc.h	Fri Mar 07 03:09:02 2003 +0900
+++ b/mc.h	Fri Mar 07 05:22:01 2003 +0900
@@ -156,10 +156,11 @@
 #define DDIV	(DOP+DIV)
 #define DADD	(DOP+ADD)
 #define DSUB	(DOP+SUB)
-#define LMUL	72
-#define LDIV	73
-#define LADD	74
-#define LSUB	75
+#define DCMPGE	72
+#define LMUL	73
+#define LDIV	74
+#define LADD	75
+#define LSUB	76
 
 #define FRGVAR	82
 #define FRLVAR	83
--- a/test/float.c	Fri Mar 07 03:09:02 2003 +0900
+++ b/test/float.c	Fri Mar 07 05:22:01 2003 +0900
@@ -13,13 +13,25 @@
 double d1 = 0.3;
 double d2 = -0.2;
 
-unsigned u;
+int
+d2i(double d) {
+   return (int)d;
+}
+
+double
+i2d(int u) {
+   return (double)u;
+}
 
-int
-u2w() {
-   d1=u;
-   u2w();
-   u=d;
+unsigned u;
+unsigned
+d2u(double d) {
+   return (unsigned)d;
+}
+
+double
+u2d(unsigned u) {
+   return (double)u;
 }
 
 int