commit e38da51c14d9eaf8c53b58b3d2e33d7b37768f29
parent 0602ad48f0e21ad604d938cd77c652adeb5eed87
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Tue, 10 Jan 2017 17:23:56 -0500
isel fixes for lame apple assembler
Diffstat:
M | isel.c | | | 31 | +++++++++++++++++++++++++++---- |
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/isel.c b/isel.c
@@ -114,7 +114,7 @@ argcls(Ins *i, int n)
static void
fixarg(Ref *r, int k, int phi, Fn *fn)
{
- Addr a;
+ Addr a, *m;
Ref r0, r1;
int s, n;
@@ -149,6 +149,18 @@ fixarg(Ref *r, int k, int phi, Fn *fn)
*/
r1 = newtmp("isel", Kl, fn);
emit(Oaddr, Kl, r1, SLOT(s), R);
+ } else if (rtype(r0) == RMem) {
+ /* apple asm fix */
+ m = &fn->mem[r0.val];
+ if (req(m->base, R)) {
+ n = fn->ncon;
+ vgrow(&fn->con, ++fn->ncon);
+ fn->con[n] = m->offset;
+ m->offset.type = CUndef;
+ r0 = newtmp("isel", Kl, fn);
+ emit(Oaddr, Kl, r0, CON(n), R);
+ m->base = r0;
+ }
}
*r = r1;
}
@@ -162,8 +174,19 @@ seladdr(Ref *r, ANum *an, Fn *fn)
r0 = *r;
if (rtype(r0) == RTmp) {
amatch(&a, r0, an, fn, 1);
- if (req(a.base, R) || req(a.base, r0))
+ if (req(a.base, r0))
return;
+ if (a.offset.type == CAddr)
+ if (!req(a.base, R)) {
+ /* apple asm fix */
+ if (!req(a.index, R))
+ return;
+ else {
+ a.index = a.base;
+ a.scale = 1;
+ a.base = R;
+ }
+ }
chuse(r0, -1, fn);
vgrow(&fn->mem, ++fn->nmem);
fn->mem[fn->nmem-1] = a;
@@ -185,7 +208,7 @@ selcmp(Ref arg[2], int k, Fn *fn)
}
assert(rtype(arg[0]) != RCon);
emit(Oxcmp, k, R, arg[1], arg[0]);
- iarg = curi->arg;
+ iarg = curi->arg; /* fixarg() can change curi */
fixarg(&iarg[0], k, 0, fn);
fixarg(&iarg[1], k, 0, fn);
}
@@ -290,7 +313,7 @@ sel(Ins i, ANum *an, Fn *fn)
case_OExt:
Emit:
emiti(i);
- iarg = curi->arg;
+ iarg = curi->arg; /* fixarg() can change curi */
fixarg(&iarg[0], argcls(&i, 0), 0, fn);
fixarg(&iarg[1], argcls(&i, 1), 0, fn);
break;