ref: e8e64a97011517107df79b4fa2905a58d1eb2280
parent: 2788f5eea5708ab8554bac41411543bef360389e
author: Ori Bernstein <[email protected]>
date: Sun Dec 29 08:13:43 EST 2013
More principled FP support started.
--- a/6/insns.def
+++ b/6/insns.def
@@ -2,12 +2,13 @@
is defined by the following macro:
Insn(enumval, fmt, attr)
The format string 'fmt' has the following expansions:
- %r - reg
+ %r - int reg
+ %f - xmm reg
%m - mem
%i - imm
%v - reg/mem
%u - reg/imm
- %x - reg/mem/imm
+ %x - reg/freg/mem/imm
%[1-9]*t - Mode of an operand. The optional number
preceeding it is the operand desired for
the mode.
@@ -20,9 +21,10 @@
Insn(Inone, "BAD_INSN", Use(), Def())
/* Note, the mov instruction is specified in an overly general manner. */
-Insn(Imov, "\tmov%t %x,%x\n", Use(.l={1}), Def(.l={2}))
-Insn(Imovz, "\tmovz%1t%2t %x,%x\n", Use(.l={1}), Def(.l={2}))
-Insn(Imovs, "\tmovs%1t%2t %x,%x\n", Use(.l={1}), Def(.l={2}))
+Insn(Imov, "\tmov%t %x,%x\n", Use(.l={1}), Def(.l={2}))
+Insn(Imovt, "PSEUDO: TRUNCATE\n", Use(.l={1}), Def(.l={2}))
+Insn(Imovzx, "\tmovz%1t%2t %x,%x\n", Use(.l={1}), Def(.l={2}))
+Insn(Imovsx, "\tmovs%1t%2t %x,%x\n", Use(.l={1}), Def(.l={2}))
Insn(Irepmovsb, "\trep movsb\n", Use(.r={Rrcx,Rrsi,Rrdi}), Def())
Insn(Irepmovsw, "\trep movsw\n", Use(.r={Rrcx,Rrsi,Rrdi}), Def())
Insn(Irepmovsl, "\trep movsl\n", Use(.r={Rrcx,Rrsi,Rrdi}), Def())
@@ -59,12 +61,15 @@
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(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}))
-Insn(Ifdiv, "\tdiv%t %x,%r\n", Use(.l={1},.r={Reax,Redx}), Def(.r={Reax,Redx}))
-Insn(Ifmul, "\tmul%t %x,%r\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Ifmov, "\tmov%t %x,%x\n", Use(.l={1,2}), Def(.l={2}))
-Insn(Icomi, "\tcomi%t %x,%r\n", Use(.l={1,2}), Def())
+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(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(Ixorp, "\tmuls%t %x,%f\n", Use(.l={1,2}), Def(.l={2}))
/* branch instructions */
Insn(Icall, "\tcall %v\n", Use(.l={1}), Def(.r={Rrax}))
--- a/6/isel.c
+++ b/6/isel.c
@@ -28,8 +28,8 @@
[ModeW] = "w",
[ModeL] = "l",
[ModeQ] = "q",
- [ModeF] = "ss",
- [ModeD] = "sd"
+ [ModeF] = "s",
+ [ModeD] = "d"
};
/* forward decls */
@@ -78,6 +78,16 @@
return ModeQ;
}
+static int isintmode(Mode m)
+{
+ return m == ModeB || m == ModeW || m == ModeL || m == ModeQ;
+}
+
+static int isfloatmode(Mode m)
+{
+ return m == ModeF || m == ModeD;
+}
+
static Loc *loc(Isel *s, Node *n)
{
ssize_t stkoff;
@@ -161,7 +171,7 @@
if (src->mode == dst->mode)
g(s, Imov, src, dst, NULL);
else
- g(s, Imovz, src, dst, NULL);
+ g(s, Imovzx, src, dst, NULL);
}
static void load(Isel *s, Loc *a, Loc *b)
@@ -173,7 +183,10 @@
l = locmem(0, b, Rnone, a->mode);
else
l = a;
- g(s, Imov, l, b, NULL);
+ if (isfloatmode(b->mode))
+ g(s, Imovs, l, b, NULL);
+ else
+ g(s, Imov, l, b, NULL);
}
static void stor(Isel *s, Loc *a, Loc *b)
@@ -467,7 +480,6 @@
Loc *a, *b, *c, *d, *r;
Loc *eax, *edx, *cl; /* x86 wants some hard-coded regs */
Node **args;
- int sz;
args = n->expr.args;
eax = locphysreg(Reax);
@@ -480,10 +492,8 @@
case Obor: r = binop(s, Ior, args[0], args[1]); break;
case Oband: r = binop(s, Iand, args[0], args[1]); break;
case Obxor: r = binop(s, Ixor, args[0], args[1]); break;
- case Omul:
- if (floattype(exprtype(n)))
- r = binop(s, Ifmul, args[0], args[1]);
- else if (size(args[0]) == 1) {
+ case Omul:
+ if (size(args[0]) == 1) {
a = selexpr(s, args[0]);
b = selexpr(s, args[1]);
@@ -498,53 +508,52 @@
break;
case Odiv:
case Omod:
- if (floattype(exprtype(n))) {
- r = binop(s, Ifdiv, args[0], args[1]);
- } else {
- /* these get clobbered by the div insn */
- a = selexpr(s, args[0]);
- b = selexpr(s, args[1]);
- b = inr(s, b);
- c = coreg(Reax, mode(n));
- r = locreg(a->mode);
- if (r->mode == ModeB)
- g(s, Ixor, eax, eax, NULL);
- else
- g(s, Ixor, edx, edx, NULL);
- g(s, Imov, a, c, NULL);
- g(s, Idiv, b, NULL);
- if (exprop(n) == Odiv)
- d = coreg(Reax, mode(n));
- else if (r->mode != ModeB)
- d = coreg(Redx, mode(n));
- else
- d = locphysreg(Rah);
- g(s, Imov, d, r, NULL);
- }
+ /* these get clobbered by the div insn */
+ a = selexpr(s, args[0]);
+ b = selexpr(s, args[1]);
+ b = inr(s, b);
+ c = coreg(Reax, mode(n));
+ r = locreg(a->mode);
+ if (r->mode == ModeB)
+ g(s, Ixor, eax, eax, NULL);
+ else
+ g(s, Ixor, edx, edx, NULL);
+ g(s, Imov, a, c, NULL);
+ g(s, Idiv, b, NULL);
+ if (exprop(n) == Odiv)
+ d = coreg(Reax, mode(n));
+ else if (r->mode != ModeB)
+ d = coreg(Redx, mode(n));
+ else
+ d = locphysreg(Rah);
+ g(s, Imov, d, r, NULL);
break;
case Oneg:
r = selexpr(s, args[0]);
r = inr(s, r);
- if (floatnode(args[0])) {
- sz = size(args[0]);
- a = NULL;
- b = NULL;
- if (sz == 4) {
- a = locreg(ModeD);
- b = loclit(1 << (8*sz-1), ModeD);
- g(s, Imov, r, a);
- } else if (size(args[0]) == 8) {
- a = locreg(ModeQ);
- b = loclit(1 << (8*sz-1), ModeQ);
- g(s, Imov, r, a, NULL);
- }
- g(s, Ixor, b, a, NULL);
- g(s, Imov, a, r, NULL);
- } else {
- g(s, Ineg, r, NULL);
- }
+ g(s, Ineg, r, NULL);
break;
+ /* fp expressions */
+ case Ofadd: r = binop(s, Iadds, args[0], args[1]); break;
+ case Ofsub: r = binop(s, Isubs, args[0], args[1]); break;
+ case Ofmul: r = binop(s, Imuls, args[0], args[1]); break;
+ case Ofdiv: r = binop(s, Idivs, args[0], args[1]); break;
+ case Ofneg:
+ a = NULL;
+ b = NULL;
+ if (mode(args[0]) == ModeF) {
+ a = locreg(ModeF);
+ b = loclit(1LL << (31), ModeF);
+ g(s, Imovs, r, a);
+ } else if (mode(args[0]) == ModeD) {
+ a = locreg(ModeQ);
+ b = loclit(1LL << 63, ModeQ);
+ g(s, Imov, r, a, NULL);
+ }
+ g(s, Ixor, b, a, NULL);
+ g(s, Imov, a, r, NULL);
+ break;
case Obsl:
case Obsr:
a = inr(s, selexpr(s, args[0]));
@@ -670,17 +679,21 @@
a = selexpr(s, args[0]);
a = inr(s, a);
r = locreg(mode(n));
- g(s, Imovs, a, r, NULL);
+ g(s, Imovsx, a, r, NULL);
break;
case Oint2flt:
a = selexpr(s, args[0]);
+ b = locreg(ModeQ);
r = locreg(mode(n));
- g(s, Icvttsi2sd, a, r, NULL);
+ g(s, Imovs, a, b, NULL);
+ g(s, Icvttsi2sd, b, r, NULL);
break;
case Oflt2int:
a = selexpr(s, args[0]);
+ b = locreg(ModeQ);
r = locreg(mode(n));
- g(s, Icvttsi2sd, a, r, NULL);
+ g(s, Icvttsd2si, a, b, NULL);
+ g(s, Imov, b, r, NULL);
break;
/* These operators should never show up in the reduced trees,
@@ -713,7 +726,11 @@
fprintf(fd, "%s", l->lbl);
break;
case Locreg:
- assert(spec == 'r' || spec == 'v' || spec == 'x' || spec == 'u');
+ assert((spec == 'r' && isintmode(l->mode)) ||
+ (spec == 'f' && isfloatmode(l->mode)) ||
+ spec == 'v' ||
+ spec == 'x' ||
+ spec == 'u');
if (l->reg.colour == Rnone)
fprintf(fd, "%%P.%zd", l->reg.id);
else
@@ -770,7 +787,7 @@
* we don't know the name of the reg to use, we need to sub it in when
* writing... */
switch (insn->op) {
- case Imovz:
+ case Imovzx:
if (insn->args[0]->mode == ModeL && insn->args[1]->mode == ModeQ) {
if (insn->args[1]->reg.colour) {
insn->op = Imov;
@@ -808,7 +825,8 @@
switch (*p) {
case '\0':
goto done; /* skip the final p++ */
- case 'r': /* register */
+ case 'r': /* int register */
+ case 'f': /* float register */
case 'm': /* memory */
case 'i': /* imm */
case 'v': /* reg/mem */
--- a/6/simp.c
+++ b/6/simp.c
@@ -1388,6 +1388,16 @@
r = t->expr.args[0];
break;
default:
+ if (istyfloat(exprtype(n))) {
+ switch (exprop(n)) {
+ case Oadd: n->expr.op = Ofadd; break;
+ 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;
+ }
+ }
r = visit(s, n);
}
return r;
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1201,6 +1201,7 @@
case Oblit: case Numops:
case Otrunc: case Oswiden: case Ozwiden:
case Oint2flt: case Oflt2int:
+ case Ofadd: case Ofsub: case Ofmul: case Ofdiv: case Ofneg:
case Ouget:
die("Should not see %s in fe", opstr(exprop(n)));
break;
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -65,3 +65,8 @@
O(Oswiden, 1) /* sign-extending widening cast */
O(Oflt2int, 1) /* float to int conversion */
O(Oint2flt, 1) /* int to float conversion */
+O(Ofadd, 1)
+O(Ofsub, 1)
+O(Ofmul, 1)
+O(Ofdiv, 1)
+O(Ofneg, 1)
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -384,6 +384,7 @@
Cstr *mkcstr(int line, char *name, Node **memb, size_t nmemb, Node **funcs, size_t nfuncs);
Type *mktylike(int line, Ty ty); /* constrains tyvar t like it was builtin ty */
int istysigned(Type *t);
+int istyfloat(Type *t);
int isgeneric(Type *t);
int hasparams(Type *t);
--- a/parse/type.c
+++ b/parse/type.c
@@ -258,9 +258,19 @@
int istysigned(Type *t)
{
- switch (t->type) {
+ switch (tybase(t)->type) {
case Tyint8: case Tyint16: case Tyint:
case Tyint32: case Tyint64: case Tylong:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+int istyfloat(Type *t)
+{
+ switch (tybase(t)->type) {
+ case Tyfloat32: case Tyfloat64:
return 1;
default:
return 0;