shithub: mc

Download patch

ref: 8cd117e55ac16cda7d40738cbd48fc8f92066da4
parent: e8e64a97011517107df79b4fa2905a58d1eb2280
author: Ori Bernstein <[email protected]>
date: Sun Dec 29 13:11:27 EST 2013

Fix instruction generation bugs for float

    We tended to generate 'mov' instead of 'movs'

--- a/6/insns.def
+++ b/6/insns.def
@@ -61,14 +61,14 @@
 Insn(Isetge,    "\tsetge %v\n",                 Use(),  Def(.l={1}))
 
 /* fp specific instructions */
-Insn(Imovs,      "\tmovs%1t %x,%f\n",                 Use(.l={1}),                    Def(.l={2}))
+Insn(Imovs,      "\tmovs%1t %x,%x\n",           Use(.l={1}),                    Def(.l={2}))
 Insn(Icvttsd2si, "\tcvttsd2si%2t %x,%r\n",      Use(.l={1}),                    Def(.l={2}))
 Insn(Icvttsi2sd, "\tcvttsi2sd%2t %x,%f\n",      Use(.l={1}),                    Def(.l={2}))
-Insn(Iadds,      "\tadds%t %x,%f\n",             Use(.l={1},.r={Reax,Redx}),     Def(.r={Reax,Redx}))
-Insn(Isubs,      "\tsubs%t %x,%f\n",             Use(.l={1},.r={Reax,Redx}),     Def(.r={Reax,Redx}))
+Insn(Iadds,      "\tadds%t %x,%f\n",            Use(.l={1},.r={Reax,Redx}),     Def(.r={Reax,Redx}))
+Insn(Isubs,      "\tsubs%t %x,%f\n",            Use(.l={1},.r={Reax,Redx}),     Def(.r={Reax,Redx}))
 Insn(Imuls,      "\tmuls%t %x,%f\n",            Use(.l={1,2}),                  Def(.l={2}))
-Insn(Idivs,      "\tdiv%t %x,%f\n",             Use(.l={1},.r={Reax,Redx}),     Def(.r={Reax,Redx}))
-Insn(Icomi,      "\tcomi%t %x,%f\n",            Use(.l={1,2}),                  Def())
+Insn(Idivs,      "\tdivs%t %x,%f\n",            Use(.l={1},.r={Reax,Redx}),     Def(.r={Reax,Redx}))
+Insn(Icomis,     "\tcomis%t %x,%f\n",           Use(.l={1,2}),                  Def())
 Insn(Ixorp,      "\tmuls%t %x,%f\n",            Use(.l={1,2}),                  Def(.l={2}))
 
 /* branch instructions */
--- a/6/isel.c
+++ b/6/isel.c
@@ -45,12 +45,12 @@
     AsmOp getflag;
 } reloptab[Numops] = {
     [Olnot] = {Itest, 0, Ijz, Isetz}, /* lnot invalid for floats */
-    [Oeq] = {Icmp, Icomi, Ijz, Isetz},
-    [One] = {Icmp, Icomi, Ijnz, Isetnz},
-    [Ogt] = {Icmp, Icomi, Ijg, Isetg},
-    [Oge] = {Icmp, Icomi, Ijge, Isetge},
-    [Olt] = {Icmp, Icomi, Ijl, Isetl},
-    [Ole] = {Icmp, Icomi, Ijle, Isetle}
+    [Oeq] = {Icmp, Icomis, Ijz,  Isetz},
+    [One] = {Icmp, Icomis, Ijnz, Isetnz},
+    [Ogt] = {Icmp, Icomis, Ijg,  Isetg},
+    [Oge] = {Icmp, Icomis, Ijge, Isetge},
+    [Olt] = {Icmp, Icomis, Ijl,  Isetl},
+    [Ole] = {Icmp, Icomis, Ijle, Isetle}
 };
 
 static Mode mode(Node *n)
@@ -198,7 +198,10 @@
         l = locmem(0, b, Rnone, b->mode);
     else
         l = b;
-    g(s, Imov, a, l, NULL);
+    if (isfloatmode(b->mode))
+        g(s, Imovs, a, l, NULL);
+    else
+        g(s, Imov, a, l, NULL);
 }
 
 /* ensures that a location is within a reg */
@@ -470,8 +473,12 @@
     call(s, n->expr.args[0]);
     if (argsz)
         g(s, Iadd, stkbump, rsp, NULL);
-    if (retloc)
-        g(s, Imov, retloc, ret, NULL);
+    if (retloc) {
+        if (isfloatmode(retloc->mode))
+            g(s, Imovs, retloc, ret, NULL);
+        else
+            g(s, Imov, retloc, ret, NULL);
+    }
     return ret;
 }
 
@@ -540,6 +547,8 @@
         case Ofmul:      r = binop(s, Imuls, args[0], args[1]); break;
         case Ofdiv:      r = binop(s, Idivs, args[0], args[1]); break;
         case Ofneg:
+            r = selexpr(s, args[0]);
+            r = inr(s, r);
             a = NULL;
             b = NULL;
             if (mode(args[0]) == ModeF) {
@@ -630,7 +639,10 @@
             else
                 a = selexpr(s, args[0]);
             b = inri(s, b);
-            g(s, Imov, b, a, NULL);
+            if (isfloatmode(b->mode))
+                g(s, Imovs, b, a, NULL);
+            else
+                g(s, Imov, b, a, NULL);
             r = b;
             break;
         case Ocall:
@@ -796,6 +808,7 @@
             }
             break;
         case Imov:
+            assert(!isfloatmode(insn->args[1]->mode));
             if (insn->args[0]->type != Locreg || insn->args[1]->type != Locreg)
                 break;
             if (insn->args[0]->reg.colour == Rnone || insn->args[1]->reg.colour == Rnone)
@@ -908,7 +921,7 @@
     if (s->ret) {
         ret = loc(s, s->ret);
         if (floattype(exprtype(s->ret)))
-            g(s, Imov, ret, coreg(Rxmm0d, ret->mode), NULL);
+            g(s, Imovs, ret, coreg(Rxmm0d, ret->mode), NULL);
         else
             g(s, Imov, ret, coreg(Rax, ret->mode), NULL);
     }
@@ -978,6 +991,12 @@
         [4] = ".long",
         [8] = ".quad"
     };
+    union {
+        float fv;
+        double dv;
+        uint64_t qv;
+        uint32_t lv;
+    } u;
 
     assert(v->type == Nlit);
     switch (v->lit.littype) {
@@ -984,7 +1003,15 @@
         case Lint:      fprintf(fd, "\t%s %lld\n", intsz[sz], v->lit.intval);    break;
         case Lbool:     fprintf(fd, "\t.byte %d\n", v->lit.boolval);     break;
         case Lchr:      fprintf(fd, "\t.long %d\n",  v->lit.chrval);     break;
-        case Lflt:      fprintf(fd, "\t.double %f\n", v->lit.fltval);    break;
+        case Lflt:
+                if (tybase(v->lit.type)->type == Tyfloat32) {
+                    u.fv = v->lit.fltval;
+                    fprintf(fd, "\t.long 0x%x\n", u.lv);
+                } else if (tybase(v->lit.type)->type == Tyfloat64) {
+                    u.dv = v->lit.fltval;
+                    fprintf(fd, "\t.quad 0x%lx\n", u.qv);
+                }
+                break;
         case Lstr:
            if (hthas(strtab, v->lit.strval)) {
                lbl = htget(strtab, v->lit.strval);
--- a/6/simp.c
+++ b/6/simp.c
@@ -1387,6 +1387,17 @@
             else
                 r = t->expr.args[0];
             break;
+        case Oneg:
+            if (istyfloat(exprtype(n))) {
+                t = mkexpr(n->line, Olit, mkfloat(n->line, -1.0), NULL);
+                t->expr.type = n->expr.type;
+                u = simplit(s, t, &s->blobs, &s->nblobs);
+                r = mkexpr(n->line, Ofmul, u, args[0], NULL);
+                r->expr.type = n->expr.type;
+            } else {
+                r = visit(s, n);
+            }
+            break;
         default:
             if (istyfloat(exprtype(n))) {
                 switch (exprop(n)) {
@@ -1394,7 +1405,6 @@
                     case Osub: n->expr.op = Ofsub; break;
                     case Omul: n->expr.op = Ofmul; break;
                     case Odiv: n->expr.op = Ofdiv; break;
-                    case Oneg: n->expr.op = Ofneg; break;
                     default: break;
                 }
             }