1
0
Fork 0
mirror of https://gitlab.alpinelinux.org/alpine/aports.git synced 2025-07-15 04:05:15 +03:00
aports/community/qbe/fix-various-codegen-bugs-on-arm64.patch

89 lines
2 KiB
Diff

From 90050202f57b22243f5d3dd434a81df2f89de9ed Mon Sep 17 00:00:00 2001
From: Quentin Carbonneaux
Date: Tue, 1 Oct 2024 19:38:15 +0200
Subject: 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
+# <<<
--
cgit v1.2.3