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.
This commit is contained in:
parent
626f0b2781
commit
90050202f5
2 changed files with 30 additions and 5 deletions
19
arm64/emit.c
19
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;
|
||||
}
|
||||
|
|
16
test/isel5.ssa
Normal file
16
test/isel5.ssa
Normal file
|
@ -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
|
||||
# <<<
|
Loading…
Add table
Reference in a new issue