diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2016-03-18 10:42:16 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2016-03-18 10:47:57 -0400 |
commit | 73371a0f906916f18e2b9a085f8b49bdbfbbda06 (patch) | |
tree | 4b55d04ed9121e47df2298a9c5cdc3d330ee4f6e /lisc/isel.c | |
parent | 5e388fffbc87d05d53e10517d5ba1c6350e2c01a (diff) | |
download | roux-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/isel.c')
-rw-r--r-- | lisc/isel.c | 30 |
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 |