summaryrefslogtreecommitdiff
path: root/lisc
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-03-18 10:42:16 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-03-18 10:47:57 -0400
commit73371a0f906916f18e2b9a085f8b49bdbfbbda06 (patch)
tree4b55d04ed9121e47df2298a9c5cdc3d330ee4f6e /lisc
parent5e388fffbc87d05d53e10517d5ba1c6350e2c01a (diff)
downloadroux-73371a0f906916f18e2b9a085f8b49bdbfbbda06.tar.gz
small fixes in selcall()
* Floating point return values are now handled correctly (I thought they were...). * Use counts of the "stack pointer" used for memory arguments are tracked correctly. * Use counts of struct argument pointers are tracked correctly.
Diffstat (limited to 'lisc')
-rw-r--r--lisc/isel.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/lisc/isel.c b/lisc/isel.c
index 51a0aa0..53f98be 100644
--- a/lisc/isel.c
+++ b/lisc/isel.c
@@ -659,17 +659,26 @@ selcall(Fn *fn, Ins *i0, Ins *i1)
stk += stk & 15;
}
stk += stk & 15;
-
- if (!req(i1->arg[1], R))
- diag("struct-returning function not implemented");
if (stk) {
r = getcon(-(int64_t)stk, fn);
emit(OSAlloc, Kl, R, r, R);
}
- emit(OCopy, i1->cls, i1->to, TMP(RAX), R);
- emit(OCall, i1->cls, R, i1->arg[0], CALL(1 | ca));
- for (i=i0, a=ac, ni=ns=0; i<i1; i++, a++) {
+ if (!req(i1->arg[1], R)) {
+ diag("struct-returning function not implemented");
+ } else {
+ if (KBASE(i1->cls) == 0) {
+ emit(OCopy, i1->cls, i1->to, TMP(RAX), R);
+ ca += 1;
+ } else {
+ emit(OCopy, i1->cls, i1->to, TMP(XMM0), R);
+ ca += 1 << 2;
+ }
+ }
+ emit(OCall, i1->cls, R, i1->arg[0], CALL(ca));
+
+ ni = ns = 0;
+ for (i=i0, a=ac; i<i1; i++, a++) {
if (a->inmem)
continue;
r1 = rarg(a->cls[0], &ni, &ns);
@@ -679,13 +688,18 @@ selcall(Fn *fn, Ins *i0, Ins *i1)
r = newtmp("abi", Kl, fn);
emit(OLoad, a->cls[1], r2, r, R);
emit(OAdd, Kl, r, i->arg[1], getcon(8, fn));
+ chuse(i->arg[1], +1, fn);
}
emit(OLoad, a->cls[0], r1, i->arg[1], R);
} else
emit(OCopy, i->cls, r1, i->arg[0], R);
}
+ if (!stk)
+ return;
+
r = newtmp("abi", Kl, fn);
+ chuse(r, -1, fn);
for (i=i0, a=ac, off=0; i<i1; i++, a++) {
if (!a->inmem)
continue;
@@ -697,11 +711,11 @@ selcall(Fn *fn, Ins *i0, Ins *i1)
r1 = newtmp("abi", Kl, fn);
emit(OStorel, 0, R, i->arg[0], r1);
emit(OAdd, Kl, r1, r, getcon(off, fn));
+ chuse(r, +1, fn);
}
off += a->size;
}
- if (stk)
- emit(OSAlloc, Kl, r, getcon(stk, fn), R);
+ emit(OSAlloc, Kl, r, getcon(stk, fn), R);
}
static void