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 */