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 | |
| 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.
| -rw-r--r-- | arm64/emit.c | 19 | ||||
| -rw-r--r-- | test/isel5.ssa | 16 |
2 files changed, 30 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; } diff --git a/test/isel5.ssa b/test/isel5.ssa new file mode 100644 index 0000000..9c546d7 --- /dev/null +++ b/test/isel5.ssa @@ -0,0 +1,16 @@ +# make sure the local symbols used for +# fp constants do not get a _ prefix +# on apple arm hardware + +export function w $main() { +@start + %r =d copy d_1.2 + %x =w call $printf(l $fmt, ..., d %r) + ret 0 +} + +data $fmt = { b "%.06f\n", b 0 } + +# >>> output +# 1.200000 +# <<< |
