mirror of
git://c9x.me/qbe.git
synced 2026-04-05 09:59:47 +00:00
winabi: fix allocation of parameters to regs with hidden arg
In the presence of the hidden arg for return-by-value, the registers used for natural arguments were incorrect. (This should be applied on the 'winabi' branch.)
This commit is contained in:
parent
d166a61141
commit
d5f02dc67c
@ -630,6 +630,7 @@ static RegisterUsage lower_func_parameters(Fn* func) {
|
|||||||
// when adding to it.
|
// when adding to it.
|
||||||
curi = &insb[NIns];
|
curi = &insb[NIns];
|
||||||
|
|
||||||
|
int reg_counter = 0;
|
||||||
RegisterUsage reg_usage = {0};
|
RegisterUsage reg_usage = {0};
|
||||||
if (func->retty >= 0) {
|
if (func->retty >= 0) {
|
||||||
bool by_copy = type_is_by_copy(&typ[func->retty]);
|
bool by_copy = type_is_by_copy(&typ[func->retty]);
|
||||||
@ -639,6 +640,7 @@ static RegisterUsage lower_func_parameters(Fn* func) {
|
|||||||
Ref ret_ref = newtmp("abi.ret", Kl, func);
|
Ref ret_ref = newtmp("abi.ret", Kl, func);
|
||||||
emit(Ocopy, Kl, ret_ref, TMP(RCX), R);
|
emit(Ocopy, Kl, ret_ref, TMP(RCX), R);
|
||||||
func->retr = ret_ref;
|
func->retr = ret_ref;
|
||||||
|
++reg_counter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ref env = R;
|
Ref env = R;
|
||||||
@ -650,7 +652,6 @@ static RegisterUsage lower_func_parameters(Fn* func) {
|
|||||||
// Copy from the registers or stack slots into the named parameters. Depending
|
// Copy from the registers or stack slots into the named parameters. Depending
|
||||||
// on how they're passed, they either need to be copied or loaded.
|
// on how they're passed, they either need to be copied or loaded.
|
||||||
ArgClass* arg = arg_classes;
|
ArgClass* arg = arg_classes;
|
||||||
int reg_counter = 0;
|
|
||||||
uint slot_offset = SHADOW_SPACE_SIZE / 4 + 4;
|
uint slot_offset = SHADOW_SPACE_SIZE / 4 + 4;
|
||||||
for (Ins* instr = start_of_params; instr < end_of_params; ++instr, ++arg) {
|
for (Ins* instr = start_of_params; instr < end_of_params; ++instr, ++arg) {
|
||||||
switch (arg->style) {
|
switch (arg->style) {
|
||||||
|
|||||||
20
test/abi9.ssa
Normal file
20
test/abi9.ssa
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
type :obj = { l, l, l, l }
|
||||||
|
|
||||||
|
export
|
||||||
|
function :obj $f(l %self) {
|
||||||
|
@_0
|
||||||
|
%_1 =l alloc8 16
|
||||||
|
storel 77, %_1
|
||||||
|
ret %_1
|
||||||
|
}
|
||||||
|
|
||||||
|
# >>> driver
|
||||||
|
# #include <stdio.h>
|
||||||
|
# typedef struct { long long a, b, c, d; } obj;
|
||||||
|
# extern obj f();
|
||||||
|
# int main() { obj ret = f(); printf("%lld\n", ret.a); return 0; }
|
||||||
|
# <<<
|
||||||
|
|
||||||
|
# >>> output
|
||||||
|
# 77
|
||||||
|
# <<<
|
||||||
Loading…
Reference in New Issue
Block a user