From 90050202f57b22243f5d3dd434a81df2f89de9ed Mon Sep 17 00:00:00 2001 From: Quentin Carbonneaux Date: Tue, 1 Oct 2024 19:38:15 +0200 Subject: [PATCH] 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. --- arm64/emit.c | 19 ++++++++++++++----- test/isel5.ssa | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 test/isel5.ssa 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 +# <<<