diff options
Diffstat (limited to 'isel.c')
-rw-r--r-- | isel.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/isel.c b/isel.c index 52ba599..0c92dcd 100644 --- 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; |