diff options
| author | 2026-04-09 09:31:25 +0200 | |
|---|---|---|
| committer | 2026-04-09 09:31:25 +0200 | |
| commit | 2c777a84d54fec374f95034d2b823d92be6e8658 (patch) | |
| tree | 414ad24bbd315696e3cf37edae00fda3096c2a08 /src/t_aarch64_isel.c | |
| parent | 015d408ca05f8663850fb284a4de15924c6e5acb (diff) | |
aarch64 handle more cases of stack relative addressing
Diffstat (limited to 'src/t_aarch64_isel.c')
| -rw-r--r-- | src/t_aarch64_isel.c | 20 |
1 files changed, 17 insertions, 3 deletions
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: |