aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/t_aarch64_emit.c4
-rw-r--r--src/t_aarch64_isel.c20
2 files changed, 21 insertions, 3 deletions
diff --git a/src/t_aarch64_emit.c b/src/t_aarch64_emit.c
index 799b388..ca251f0 100644
--- a/src/t_aarch64_emit.c
+++ b/src/t_aarch64_emit.c
@@ -636,6 +636,10 @@ gencopy(uchar **pcode, enum irclass cls, Block *blk, int curi, Oper dst, Ref val
} else {
Xadr(pcode, KPTR, dst, src);
}
+ } else if (src.t == OMEM) {
+ assert(dst.t == OREG);
+ assert(src.m.mode == AIMMIDX);
+ Xadd(pcode, cls, dst, reg2oper(src.m.base), mkoper(OIMM, .imm = src.m.disp));
} else assert(0);
}
diff --git a/src/t_aarch64_isel.c b/src/t_aarch64_isel.c
index 58d9377..178fa23 100644
--- a/src/t_aarch64_isel.c
+++ b/src/t_aarch64_isel.c
@@ -232,7 +232,7 @@ selcall(Function *fn, Instr *ins, Block *blk, int *curi)
}
static bool
-aimm(IRAddr *addr, int disp)
+aimm(IRAddr *addr, s64int disp)
{
if (addr->index.bits) return 0;
s64int a = addr->disp;
@@ -297,7 +297,7 @@ aadd(IRAddr *addr, Block *blk, int *curi, Ref r, uint siz/*1,2,4,8*/)
r = insertinstr(blk, (*curi)++, mkinstr1(Ocopy, KPTR, r));
}
if (!addr->base.bits) addr->base = r;
- else if (!addr->index.bits) addr->index = r;
+ else if (!addr->index.bits && addr->base.t != RSTACK) addr->index = r;
else return 0;
} else return 0;
return 1;
@@ -434,8 +434,22 @@ sel(Function *fn, Instr *ins, Block *blk, int *curi)
op = ins->op ^= 1;
ins->r.i = -ins->r.i;
}
- if (!(isaddrcon(ins->l,0) && (contab.p[ins->l.i].flag & SLOCAL)))
+ if (isaddrcon(ins->l,0)) {
+ if (!(contab.p[ins->l.i].flag & SLOCAL) || !isintcon(ins->r) || ins->cls != KPTR) CopyFirst: {
+ regarg(&ins->l, ins->cls, blk, curi);
+ } else TryAdr: {
+ IRAddr adr = {.base = ins->l};
+ s64int disp = intconval(ins->r);
+ if (!aimm(&adr, ins->op == Osub ? -(u64int)disp : disp)) goto CopyFirst;
+ ins->op = Ocopy;
+ ins->l = mkaddr(adr);
+ ins->r = NOREF;
+ break;
+ }
+ } else if (ins->l.t == RSTACK) {
+ if (isintcon(ins->r)) goto TryAdr;
regarg(&ins->l, ins->cls, blk, curi);
+ }
fixarg(&ins->r, ins, blk, curi);
break;
case Oand: case Oior: case Oxor: