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;
}
}