shithub: mc

Download patch

ref: 399b644b26513d89f12bd1a52c6a6e2f30390338
parent: d563b951f40542b355fc4acfc60c2f1f420935d0
author: Ori Bernstein <[email protected]>
date: Wed Sep 25 10:13:48 EDT 2013

Closer to floating point support.

--- a/6/asm.h
+++ b/6/asm.h
@@ -220,6 +220,7 @@
 size_t tysize(Type *t);
 size_t size(Node *n);
 int stacktype(Type *t);
+int floattype(Type *t);
 int stacknode(Node *n);
 void breakhere();
 void dumpasm(Isel *s, FILE *fd);
--- a/6/insns.def
+++ b/6/insns.def
@@ -57,6 +57,10 @@
 Insn(Isetg,     "\tsetg %v\n",                  Use(),  Def(.l={1}))
 Insn(Isetge,    "\tsetge %v\n",                 Use(),  Def(.l={1}))
 
+/* fp specific instructions */
+Insn(Icvttsd2si, "\tcvttsd2si%2t %x,%r\n",         Use(.l={1}),    Def(.l={2}))
+Insn(Icvttsi2sd, "\tcvttsd2si%2t %x,%r\n",         Use(.l={1}),    Def(.l={2}))
+
 /* branch instructions */
 Insn(Icall,     "\tcall %v\n",                  Use(.l={1}), Def(.r={Rrax}))
 Insn(Icallind,  "\tcall *%v\n",                 Use(.l={1}), Def(.r={Rrax}))
--- a/6/isel.c
+++ b/6/isel.c
@@ -380,7 +380,7 @@
 static Loc *gencall(Isel *s, Node *n)
 {
     Loc *src, *dst, *arg, *fn;  /* values we reduced */
-    Loc *rax, *rsp, *ret;       /* hard-coded registers */
+    Loc *retloc, *rsp, *ret;       /* hard-coded registers */
     Loc *stkbump;        /* calculated stack offset */
     int argsz, argoff;
     size_t i;
@@ -387,13 +387,16 @@
 
     rsp = locphysreg(Rrsp);
     if (tybase(exprtype(n))->type == Tyvoid) {
-        rax = NULL;
+        retloc = NULL;
         ret = NULL;
     } else if (stacktype(exprtype(n))) {
-        rax = locphysreg(Rrax);
+        retloc = locphysreg(Rrax);
         ret = locreg(ModeQ);
+    } else if (floattype(exprtype(n))) {
+        retloc = coreg(Rxmm0d, mode(n));
+        ret = locreg(mode(n));
     } else {
-        rax = coreg(Rrax, mode(n));
+        retloc = coreg(Rrax, mode(n));
         ret = locreg(mode(n));
     }
     argsz = 0;
@@ -434,8 +437,8 @@
         g(s, Icallind, fn, NULL);
     if (argsz)
         g(s, Iadd, stkbump, rsp, NULL);
-    if (rax)
-        g(s, Imov, rax, ret, NULL);
+    if (retloc)
+        g(s, Imov, retloc, ret, NULL);
     return ret;
 }
 
@@ -581,9 +584,8 @@
             break;
         case Oblit:
             a = selexpr(s, args[0]);
-            b = selexpr(s, args[1]);
-            blit(s, a, b, 0, 0, args[2]->expr.args[0]->lit.intval);
-            r = b;
+            r = selexpr(s, args[1]);
+            blit(s, a, r, 0, 0, args[2]->expr.args[0]->lit.intval);
             break;
         case Otrunc:
             a = selexpr(s, args[0]);
@@ -594,17 +596,25 @@
         case Ozwiden:
             a = selexpr(s, args[0]);
             a = inr(s, a);
-            b = locreg(mode(n));
-            movz(s, a, b);
-            r = b;
+            r = locreg(mode(n));
+            movz(s, a, r);
             break;
         case Oswiden:
             a = selexpr(s, args[0]);
             a = inr(s, a);
-            b = locreg(mode(n));
-            g(s, Imovs, a, b, NULL);
-            r = b;
+            r = locreg(mode(n));
+            g(s, Imovs, a, r, NULL);
             break;
+        case Oint2flt:
+            a = selexpr(s, args[0]);
+            r = locreg(mode(n));
+            g(s, Icvttsi2sd, a, r, NULL);
+            break;
+        case Oflt2int:
+            a = selexpr(s, args[0]);
+            r = locreg(mode(n));
+            g(s, Icvttsi2sd, a, r, NULL);
+            break;
 
         /* These operators should never show up in the reduced trees,
          * since they should have been replaced with more primitive
@@ -768,19 +778,11 @@
 }
 
 Reg savedregs[] = {
-    Rrcx,
-    Rrdx,
-    Rrbx,
-    Rrsi,
-    Rrdi,
-    Rr8,
-    Rr9,
-    Rr10,
-    Rr11,
-    Rr12,
-    Rr13,
-    Rr14,
-    Rr15
+    Rrcx, Rrdx, Rrbx, Rrsi, Rrdi, Rr8, Rr9, Rr10, Rr11, Rr12, Rr13, Rr14, Rr15,
+    /*
+    Rxmm0d, Rxmm1d, Rxmm2d, Rxmm3d, Rxmm4d, Rxmm5d, Rxmm6d, Rxmm7d,
+    Rxmm8d, Rxmm9d, Rxmm10d, Rxmm11d, Rxmm12d, Rxmm13d, Rxmm14d, Rxmm15d,
+    */
 };
 
 static void prologue(Isel *s, size_t sz)
@@ -815,7 +817,10 @@
     rbp = locphysreg(Rrbp);
     if (s->ret) {
         ret = loc(s, s->ret);
-        g(s, Imov, ret, coreg(Rax, ret->mode), NULL);
+        if (floattype(exprtype(s->ret)))
+            g(s, Imov, ret, coreg(Rxmm0d, ret->mode), NULL);
+        else
+            g(s, Imov, ret, coreg(Rax, ret->mode), NULL);
     }
     /* restore registers */
     for (i = 0; i < Nsaved; i++)
--- a/6/locs.c
+++ b/6/locs.c
@@ -262,6 +262,40 @@
         [Rr13]  = {Rnone, Rr13b, Rr13w, Rr13d, Rr13},
         [Rr14]  = {Rnone, Rr14b, Rr14w, Rr14d, Rr14},
         [Rr15]  = {Rnone, Rr15b, Rr15w, Rr15d, Rr15},
+
+        [Rxmm0f] = {[ModeF] = Rxmm0f, [ModeD] = Rxmm0d},
+        [Rxmm1f] = {[ModeF] = Rxmm1f, [ModeD] = Rxmm1d},
+        [Rxmm2f] = {[ModeF] = Rxmm2f, [ModeD] = Rxmm2d},
+        [Rxmm3f] = {[ModeF] = Rxmm3f, [ModeD] = Rxmm3d},
+        [Rxmm4f] = {[ModeF] = Rxmm4f, [ModeD] = Rxmm4d},
+        [Rxmm5f] = {[ModeF] = Rxmm5f, [ModeD] = Rxmm5d},
+        [Rxmm6f] = {[ModeF] = Rxmm6f, [ModeD] = Rxmm6d},
+        [Rxmm7f] = {[ModeF] = Rxmm7f, [ModeD] = Rxmm7d},
+        [Rxmm8f] = {[ModeF] = Rxmm8f, [ModeD] = Rxmm8d},
+        [Rxmm9f] = {[ModeF] = Rxmm9f, [ModeD] = Rxmm9d},
+        [Rxmm10f] = {[ModeF] = Rxmm0f, [ModeD] = Rxmm0d},
+        [Rxmm11f] = {[ModeF] = Rxmm1f, [ModeD] = Rxmm1d},
+        [Rxmm12f] = {[ModeF] = Rxmm2f, [ModeD] = Rxmm2d},
+        [Rxmm13f] = {[ModeF] = Rxmm3f, [ModeD] = Rxmm3d},
+        [Rxmm14f] = {[ModeF] = Rxmm4f, [ModeD] = Rxmm4d},
+        [Rxmm15f] = {[ModeF] = Rxmm5f, [ModeD] = Rxmm5d},
+
+        [Rxmm0d] = {[ModeF] = Rxmm0f, [ModeD] = Rxmm0d},
+        [Rxmm1d] = {[ModeF] = Rxmm1f, [ModeD] = Rxmm1d},
+        [Rxmm2d] = {[ModeF] = Rxmm2f, [ModeD] = Rxmm2d},
+        [Rxmm3d] = {[ModeF] = Rxmm3f, [ModeD] = Rxmm3d},
+        [Rxmm4d] = {[ModeF] = Rxmm4f, [ModeD] = Rxmm4d},
+        [Rxmm5d] = {[ModeF] = Rxmm5f, [ModeD] = Rxmm5d},
+        [Rxmm6d] = {[ModeF] = Rxmm6f, [ModeD] = Rxmm6d},
+        [Rxmm7d] = {[ModeF] = Rxmm7f, [ModeD] = Rxmm7d},
+        [Rxmm8d] = {[ModeF] = Rxmm8f, [ModeD] = Rxmm8d},
+        [Rxmm9d] = {[ModeF] = Rxmm9f, [ModeD] = Rxmm9d},
+        [Rxmm10d] = {[ModeF] = Rxmm0f, [ModeD] = Rxmm0d},
+        [Rxmm11d] = {[ModeF] = Rxmm1f, [ModeD] = Rxmm1d},
+        [Rxmm12d] = {[ModeF] = Rxmm2f, [ModeD] = Rxmm2d},
+        [Rxmm13d] = {[ModeF] = Rxmm3f, [ModeD] = Rxmm3d},
+        [Rxmm14d] = {[ModeF] = Rxmm4f, [ModeD] = Rxmm4d},
+        [Rxmm15d] = {[ModeF] = Rxmm5f, [ModeD] = Rxmm5d},
     };
 
     assert(crtab[r][m] != Rnone);
--- a/6/simp.c
+++ b/6/simp.c
@@ -234,6 +234,12 @@
     return t->type >= Tyslice;
 }
 
+int floattype(Type *t)
+{
+    t = tybase(t);
+    return t->type == Tyfloat32 || t->type == Tyfloat64;
+}
+
 int stacknode(Node *n)
 {
     if (n->type == Nexpr)
@@ -790,9 +796,32 @@
                 case Typtr:
                     r = intconvert(s, val, to, 0);
                     break;
+                case Tyfloat32: case Tyfloat64:
+                    if (tybase(to)->type == Typtr)
+                        fatal(val->line, "Bad cast from %s to %s",
+                              tystr(exprtype(val)), tystr(to));
+                    r = mkexpr(val->line, Oflt2int, rval(s, val, NULL), NULL);
+                    r->expr.type = to;
+                    break;
                 default:
                     fatal(val->line, "Bad cast from %s to %s",
                           tystr(exprtype(val)), tystr(to));
+            }
+            break;
+        case Tyfloat32: case Tyfloat64:
+            t = tybase(exprtype(val));
+            switch (t->type) {
+                case Tyint8: case Tyint16: case Tyint32: case Tyint64:
+                case Tyuint8: case Tyuint16: case Tyuint32: case Tyuint64:
+                case Tyint: case Tyuint: case Tylong: case Tyulong:
+                case Tychar: case Tybyte:
+                    r = mkexpr(val->line, Oflt2int, rval(s, val, NULL), NULL);
+                    r->expr.type = to;
+                    break;
+                default:
+                    fatal(val->line, "Bad cast from %s to %s",
+                          tystr(exprtype(val)), tystr(to));
+                    break;
             }
             break;
         /* no other destination types are handled as things stand */
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1128,6 +1128,7 @@
         case Oslbase: case Osllen:
         case Oblit: case Numops:
         case Otrunc: case Oswiden: case Ozwiden:
+        case Oint2flt: case Oflt2int:
         case Ouget:
             die("Should not see %s in fe", opstr(exprop(n)));
             break;
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -63,3 +63,5 @@
 O(Otrunc, 1)       /* truncating cast */
 O(Ozwiden, 1)      /* zero-extending widening cast */
 O(Oswiden, 1)      /* sign-extending widening cast */
+O(Oflt2int, 1)     /* float to int conversion */
+O(Oint2flt, 1)     /* int to float conversion */