aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Graham <[email protected]>2026-01-08 12:32:59 -0800
committerQuentin Carbonneaux <[email protected]>2026-01-13 18:47:58 +0100
commitb3b6d8ba0b33693f406a314d2dd10c68400cd8a4 (patch)
treec9d69aa8c23a020cef330d1c8e1e403c77078269
parentb6545e90d85176235e179a7f74caefded4b15c42 (diff)
winabi: fix allocation of parameters to regs with hidden argwinabi
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.)
-rwxr-xr-xamd64/winabi.c3
-rw-r--r--test/abi9.ssa20
2 files changed, 22 insertions, 1 deletions
diff --git a/amd64/winabi.c b/amd64/winabi.c
index 82829bc..a7d0a1a 100755
--- a/amd64/winabi.c
+++ b/amd64/winabi.c
@@ -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) {
diff --git a/test/abi9.ssa b/test/abi9.ssa
new file mode 100644
index 0000000..cb70028
--- /dev/null
+++ b/test/abi9.ssa
@@ -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
+# <<<