diff options
| author | Quentin Carbonneaux <[email protected]> | 2024-10-01 19:38:15 +0200 |
|---|---|---|
| committer | Quentin Carbonneaux <[email protected]> | 2024-10-01 19:42:50 +0200 |
| commit | 90050202f57b22243f5d3dd434a81df2f89de9ed (patch) | |
| tree | d72a890222adcf345e6cbfa1b1d7ac2639cc9a0d /arm64 | |
| parent | 626f0b278137ff6f8b7d910d9b3fc3cbdfbb39fc (diff) | |
fix various codegen bugs on arm64
- dynamic allocations could generate
bad 'and' instructions (for the
and with -16 in salloc()).
- symbols used in w context would
generate adrp and add instructions
on wN registers while they seem to
only work on xN registers.
Thanks to Rosie for reporting them.
Diffstat (limited to 'arm64')
| -rw-r--r-- | arm64/emit.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/arm64/emit.c b/arm64/emit.c index ffdc178..28cd6a5 100644 --- a/arm64/emit.c +++ b/arm64/emit.c @@ -160,7 +160,8 @@ emitf(char *s, Ins *i, E *e) Ref r; int k, c; Con *pc; - uint n, sp; + uint64_t n; + uint sp; fputc('\t', e->f); @@ -217,10 +218,17 @@ emitf(char *s, Ins *i, E *e) pc = &e->fn->con[r.val]; n = pc->bits.i; assert(pc->type == CBits); - if (n & 0xfff000) - fprintf(e->f, "#%u, lsl #12", n>>12); - else - fprintf(e->f, "#%u", n); + if (n >> 24) { + assert(arm64_logimm(n, k)); + fprintf(e->f, "#%"PRIu64, n); + } else if (n & 0xfff000) { + assert(!(n & ~0xfff000ull)); + fprintf(e->f, "#%"PRIu64", lsl #12", + n>>12); + } else { + assert(!(n & ~0xfffull)); + fprintf(e->f, "#%"PRIu64, n); + } break; } break; @@ -304,6 +312,7 @@ loadcon(Con *c, int r, int k, E *e) rn = rname(r, k); n = c->bits.i; if (c->type == CAddr) { + rn = rname(r, Kl); loadaddr(c, rn, e); return; } |
