ref: 2b00b4a0fc8f56bd47fa9e8fab3a9e47add497fc
parent: f60dbb91eeb4bd2c39242669a5f35252aab21fce
author: Ori Bernstein <[email protected]>
date: Wed Jun 6 19:49:52 EDT 2012
Add missing test files.
--- a/8/asm.h
+++ b/8/asm.h
@@ -54,6 +54,7 @@
/* only one of lbldisp and constdisp may be used */
char *lbldisp;
long constdisp;
+ int scale;
Reg base;
Reg idx;
} mem;
@@ -85,8 +86,11 @@
Loc *locreg(Loc *l, Reg r);
Loc *locmem(Loc *l, long disp, Reg base, Reg idx, Mode mode);
Loc *locmeml(Loc *l, char *disp, Reg base, Reg idx, Mode mode);
+Loc *locmems(Loc *l, long disp, Reg base, Reg idx, int scale, Mode mode);
+Loc *locmemls(Loc *l, char *disp, Reg base, Reg idx, int scale, Mode mode);
Loc *loclit(Loc *l, long val);
/* useful functions */
size_t size(Node *n);
void breakhere();
+
--- a/8/isel.c
+++ b/8/isel.c
@@ -121,9 +121,17 @@
l->mem.constdisp = disp;
l->mem.base = base;
l->mem.idx = idx;
+ l->mem.scale = 0;
return l;
}
+Loc *locmems(Loc *l, long disp, Reg base, Reg idx, int scale, Mode mode)
+{
+ locmem(l, disp, base, idx, mode);
+ l->mem.scale = scale;
+ return l;
+}
+
Loc *locmeml(Loc *l, char *disp, Reg base, Reg idx, Mode mode)
{
l->type = Locmem;
@@ -131,9 +139,18 @@
l->mem.lbldisp = strdup(disp);
l->mem.base = base;
l->mem.idx = idx;
+ l->mem.scale = 0;
return l;
}
+Loc *locmemls(Loc *l, char *disp, Reg base, Reg idx, int scale, Mode mode)
+{
+ locmeml(l, disp, base, idx, mode);
+ l->mem.scale = scale;
+ return l;
+}
+
+
Loc *loclit(Loc *l, long val)
{
l->type = Loclit;
@@ -394,11 +411,29 @@
return a;
}
+static int ismergablemul(Node *n, int *r)
+{
+ int v;
+
+ if (exprop(n) != Omul)
+ return 0;
+ if (exprop(n->expr.args[1]) != Olit)
+ return 0;
+ if (n->expr.args[1]->expr.args[0]->type != Nlit)
+ return 0;
+ if (n->expr.args[1]->expr.args[0]->lit.littype != Lint)
+ return 0;
+ v = n->expr.args[1]->expr.args[0]->lit.intval;
+ if (v != 2 && v != 4 && v != 8)
+ return 0;
+ *r = v;
+ return 1;
+}
/* We have a few common cases to optimize here:
* Oadd(
* reg,
* reg||const))
- * TODO:
+ * or:
* Oadd(
* reg,
* Omul(reg,
@@ -408,11 +443,16 @@
{
Node **args;
Loc l, b, o; /* location, base, offset */
+ int scale;
+ scale = 0;
if (exprop(e) == Oadd) {
args = e->expr.args;
b = selexpr(s, args[0]);
- o = selexpr(s, args[1]);
+ if (ismergablemul(args[1], &scale))
+ o = selexpr(s, args[1]->expr.args[0]);
+ else
+ o = selexpr(s, args[1]);
if (b.type != Locreg)
b = inr(s, b);
if (o.type == Loclit) {
@@ -419,7 +459,7 @@
locmem(&l, o.lit, b.reg, Rnone, m);
} else if (o.type == Locreg) {
b = inr(s, b);
- locmem(&l, 0, b.reg, o.reg, m);
+ locmems(&l, 0, b.reg, o.reg, scale, m);
}
} else {
l = selexpr(s, e);
@@ -472,6 +512,7 @@
Loc selexpr(Isel *s, Node *n)
{
Loc a, b, c, r;
+ Loc eax;
Node **args;
args = n->expr.args;
@@ -480,7 +521,14 @@
case Oadd: r = binop(s, Iadd, args[0], args[1]); break;
case Osub: r = binop(s, Isub, args[0], args[1]); break;
- case Omul: die("Unimplemented op %s", opstr(exprop(n))); break;
+ case Omul:
+ /* these get clobbered by the mul insn */
+ claimreg(s, Reax);
+ claimreg(s, Redx);
+ a = selexpr(s, args[0]);
+ b = selexpr(s, args[1]);
+ r =
+ break;
case Odiv: die("Unimplemented op %s", opstr(exprop(n))); break;
case Omod: die("Unimplemented op %s", opstr(exprop(n))); break;
case Oneg: die("Unimplemented op %s", opstr(exprop(n))); break;
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -295,8 +295,10 @@
static Node *idxaddr(Simp *s, Node *n)
{
- Node *t, *u, *r;
+ Node *t, *u, *v; /* temps */
+ Node *r; /* result */
Node **args;
+ size_t sz;
assert(exprop(n) == Oidx);
args = n->expr.args;
@@ -307,23 +309,28 @@
else
die("Can't index type %s\n", tystr(n->expr.type));
u = rval(s, args[1]);
- r = mkexpr(-1, Oadd, t, u, NULL);
+ sz = size(n);
+ v = mkexpr(-1, Omul, u, mkexpr(-1, Olit, mkint(-1, sz), NULL));
+ r = mkexpr(-1, Oadd, t, v, NULL);
return r;
}
static Node *slicebase(Simp *s, Node *n, Node *off)
{
- Node *t, *u;
+ Node *t, *u, *v;
+ int sz;
t = rval(s, n);
u = NULL;
switch (n->expr.type->type) {
case Typtr: u = n;
- case Tyarray: u = mkexpr(-1, Oaddr, n, NULL); break;
- case Tyslice: u = mkexpr(-1, Oslbase, n, NULL); break;
+ case Tyarray: u = mkexpr(-1, Oaddr, t, NULL); break;
+ case Tyslice: u = mkexpr(-1, Oslbase, t, NULL); break;
default: die("Unslicable type %s", tystr(n->expr.type));
}
- return mkexpr(-1, Oadd, u, off, NULL);
+ sz = tysize(n->expr.args[0]->expr.type->sub[0]);
+ v = mkexpr(-1, Omul, u, mkexpr(-1, Olit, mkint(-1, sz), NULL));
+ return mkexpr(-1, Oadd, u, v, NULL);
}
Node *lval(Simp *s, Node *n)
--- /dev/null
+++ b/test/call.myr
@@ -1,0 +1,7 @@
+const f = {
+ -> 21
+}
+
+const main = {
+ -> f() + f()
+}
--- /dev/null
+++ b/test/loop.myr
@@ -1,0 +1,14 @@
+const f = {a
+}
+
+const main = {
+ var i
+ var n
+ i = f
+
+ n = 0
+ for i = 0; i < 10; ++i
+ n += i
+ ;;
+ -> n
+}