ref: 8cd117e55ac16cda7d40738cbd48fc8f92066da4
parent: e8e64a97011517107df79b4fa2905a58d1eb2280
	author: Ori Bernstein <ori@eigenstate.org>
	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;
}
}
--
⑨