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.
|
||||
curi = &insb[NIns];
|
||||
|
||||
int reg_counter = 0;
|
||||
RegisterUsage reg_usage = {0};
|
||||
if (func->retty >= 0) {
|
||||
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);
|
||||
emit(Ocopy, Kl, ret_ref, TMP(RCX), R);
|
||||
func->retr = ret_ref;
|
||||
++reg_counter;
|
||||
}
|
||||
}
|
||||
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
|
||||
// on how they're passed, they either need to be copied or loaded.
|
||||
ArgClass* arg = arg_classes;
|
||||
int reg_counter = 0;
|
||||
uint slot_offset = SHADOW_SPACE_SIZE / 4 + 4;
|
||||
for (Ins* instr = start_of_params; instr < end_of_params; ++instr, ++arg) {
|
||||
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