commit 2feb742b6911b385fc80177f8df77315fef9cd37
parent 4756643e58965eb21e0bf2ddb45ddb24b9f8bf03
Author: Michael Forney <mforney@mforney.org>
Date: Mon, 1 Mar 2021 17:41:35 -0800
arm64: handle stack offsets >=4096 in Oaddr
The immediate in the add instruction is only 12 bits. If the offset
does not fit, we must move it into a register first.
Diffstat:
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/arm64/emit.c b/arm64/emit.c
@@ -271,6 +271,8 @@ static void
emitins(Ins *i, E *e)
{
int o;
+ char *rn;
+ uint64_t s;
switch (i->op) {
default:
@@ -302,9 +304,17 @@ emitins(Ins *i, E *e)
break;
case Oaddr:
assert(rtype(i->arg[0]) == RSlot);
- fprintf(e->f, "\tadd\t%s, x29, #%"PRIu64"\n",
- rname(i->to.val, Kl), slot(i->arg[0].val, e)
- );
+ rn = rname(i->to.val, Kl);
+ s = slot(i->arg[0].val, e);
+ if (s <= 4095) {
+ fprintf(e->f, "\tadd\t%s, x29, #%"PRIu64"\n", rn, s);
+ } else {
+ fprintf(e->f,
+ "\tmov\t%s, #%"PRIu64"\n"
+ "\tadd\t%s, x29, %s\n",
+ rn, s, rn, rn
+ );
+ }
break;
}
}