mirror of
git://c9x.me/qbe.git
synced 2026-04-05 09:59:47 +00:00
winabi: fix isel of large consts
ABI lowering for winabi was incorrectly using a Kl cls when emitting Ostorel, which in turn was causing isel to fail to lower large constants in to temporaries ( https://c9x.me/git/qbe.git/tree/amd64/isel.c#n107 ) when necessary. (This should be applied on the 'winabi' branch.)
This commit is contained in:
parent
d5f02dc67c
commit
01102ad63b
@ -346,7 +346,7 @@ static Ins* lower_call(Fn* func,
|
||||
return_copy->link = (*pextra_alloc);
|
||||
*pextra_alloc = return_copy;
|
||||
Ref copy = newtmp("abi.copy", Kl, func);
|
||||
emit(Ostorel, Kl, R, copy, call_instr->to);
|
||||
emit(Ostorel, 0, R, copy, call_instr->to);
|
||||
emit(Ocopy, Kl, copy, TMP(RAX), R);
|
||||
reg_usage.rax_returned = true;
|
||||
} else if (is_integer_type(call_instr->cls)) {
|
||||
@ -421,11 +421,11 @@ static Ins* lower_call(Fn* func,
|
||||
// slot. (And, remember that these are emitted backwards, so store,
|
||||
// then load.)
|
||||
Ref smalltmp = newtmp("abi.smalltmp", arg->cls, func);
|
||||
emit(Ostorel, Kl, R, smalltmp, slot);
|
||||
emit(Ostorel, 0, R, smalltmp, slot);
|
||||
emit(Oload, arg->cls, smalltmp, instr->arg[1], R);
|
||||
} else {
|
||||
// Stash the value into the stack slot.
|
||||
emit(Ostorel, Kl, R, instr->arg[0], slot);
|
||||
emit(Ostorel, 0, R, instr->arg[0], slot);
|
||||
}
|
||||
emit(Oadd, Kl, slot, arg_stack_slots, getcon(slot_offset, func));
|
||||
slot_offset += arg->size;
|
||||
@ -451,7 +451,7 @@ static Ins* lower_call(Fn* func,
|
||||
} else {
|
||||
assert(arg->style == APS_CopyAndPointerOnStack);
|
||||
Ref slot = newtmp("abi.off", Kl, func);
|
||||
emit(Ostorel, Kl, R, copy_ref, slot);
|
||||
emit(Ostorel, 0, R, copy_ref, slot);
|
||||
emit(Oadd, Kl, slot, arg_stack_slots, getcon(slot_offset, func));
|
||||
slot_offset += 8;
|
||||
}
|
||||
@ -533,7 +533,7 @@ static void lower_vastart(Fn* func,
|
||||
// that were actually passed.
|
||||
|
||||
Ref offset = newtmp("abi.vastart", Kl, func);
|
||||
emit(Ostorel, Kl, R, offset, valist);
|
||||
emit(Ostorel, 0, R, offset, valist);
|
||||
|
||||
// *8 for sizeof(u64), +16 because the return address and rbp have been pushed
|
||||
// by the time we get to the body of the function.
|
||||
@ -547,7 +547,7 @@ static void lower_vaarg(Fn* func, Ins* vaarg_instr) {
|
||||
// (All emitted backwards as usual.)
|
||||
Ref inc = newtmp("abi.vaarg.inc", Kl, func);
|
||||
Ref ptr = newtmp("abi.vaarg.ptr", Kl, func);
|
||||
emit(Ostorel, Kl, R, inc, vaarg_instr->arg[0]);
|
||||
emit(Ostorel, 0, R, inc, vaarg_instr->arg[0]);
|
||||
emit(Oadd, Kl, inc, ptr, getcon(8, func));
|
||||
emit(Oload, vaarg_instr->cls, vaarg_instr->to, ptr, R);
|
||||
emit(Oload, Kl, ptr, vaarg_instr->arg[0], R);
|
||||
@ -661,7 +661,7 @@ static RegisterUsage lower_func_parameters(Fn* func) {
|
||||
// an alloca so we have something to point at (same for InlineOnStack).
|
||||
if (instr->op == Oparc) {
|
||||
arg->ref = newtmp("abi", Kl, func);
|
||||
emit(Ostorel, Kl, R, arg->ref, instr->to);
|
||||
emit(Ostorel, 0, R, arg->ref, instr->to);
|
||||
emit(Ocopy, instr->cls, arg->ref, from, R);
|
||||
emit(Oalloc8, Kl, instr->to, getcon(arg->size, func), R);
|
||||
} else {
|
||||
@ -672,7 +672,7 @@ static RegisterUsage lower_func_parameters(Fn* func) {
|
||||
case APS_InlineOnStack:
|
||||
if (instr->op == Oparc) {
|
||||
arg->ref = newtmp("abi", Kl, func);
|
||||
emit(Ostorel, Kl, R, arg->ref, instr->to);
|
||||
emit(Ostorel, 0, R, arg->ref, instr->to);
|
||||
emit(Ocopy, instr->cls, arg->ref, SLOT(-slot_offset), R);
|
||||
emit(Oalloc8, Kl, instr->to, getcon(arg->size, func), R);
|
||||
} else {
|
||||
|
||||
38
test/isel6.ssa
Normal file
38
test/isel6.ssa
Normal file
@ -0,0 +1,38 @@
|
||||
# make sure large consts are lowered
|
||||
# without an offset
|
||||
# i.e. not movq $9223372036854775807, 64(%rax)
|
||||
|
||||
export function w $main() {
|
||||
@_0
|
||||
%_1 =w call $myfunc(l 1, l 2, l 3, l 4, l 5, l 6, l 7, l 8, l 9223372036854775807)
|
||||
ret 0
|
||||
}
|
||||
|
||||
# >>> driver
|
||||
# #include <stdio.h>
|
||||
# #include <stdint.h>
|
||||
# #include <inttypes.h>
|
||||
# void myfunc(int64_t a, int64_t b, int64_t c, int64_t d, int64_t e, int64_t f, int64_t g, int64_t h, int64_t i) {
|
||||
# printf("%" PRId64 "\n", a);
|
||||
# printf("%" PRId64 "\n", b);
|
||||
# printf("%" PRId64 "\n", c);
|
||||
# printf("%" PRId64 "\n", d);
|
||||
# printf("%" PRId64 "\n", e);
|
||||
# printf("%" PRId64 "\n", f);
|
||||
# printf("%" PRId64 "\n", g);
|
||||
# printf("%" PRId64 "\n", h);
|
||||
# printf("%" PRId64 "\n", i);
|
||||
# }
|
||||
# <<<
|
||||
|
||||
# >>> output
|
||||
# 1
|
||||
# 2
|
||||
# 3
|
||||
# 4
|
||||
# 5
|
||||
# 6
|
||||
# 7
|
||||
# 8
|
||||
# 9223372036854775807
|
||||
# <<<
|
||||
Loading…
Reference in New Issue
Block a user