aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/llvm.zig15
-rw-r--r--test/c_abi/cfuncs.c3
-rw-r--r--test/c_abi/main.zig12
3 files changed, 21 insertions, 9 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 178c0aaf0a..6da4e0d9af 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -10412,6 +10412,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool
.riscv32, .riscv64 => return riscv_c_abi.classifyType(fn_info.return_type, target) == .memory,
else => return false, // TODO investigate C ABI for other architectures
},
+ .Stdcall => return !isScalar(fn_info.return_type),
else => return false,
}
}
@@ -10567,6 +10568,13 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
else => return dg.lowerType(fn_info.return_type),
}
},
+ .Stdcall => {
+ if (isScalar(fn_info.return_type)) {
+ return dg.lowerType(fn_info.return_type);
+ } else {
+ return dg.context.voidType();
+ }
+ },
else => return dg.lowerType(fn_info.return_type),
}
}
@@ -10802,12 +10810,7 @@ const ParamTypeIterator = struct {
it.zig_index += 1;
it.llvm_index += 1;
- if (it.target.cpu.arch != .x86 or it.target.os.tag != .windows) {
- return .byval;
- }
-
- const is_scalar = isScalar(ty);
- if (is_scalar) {
+ if (isScalar(ty)) {
return .byval;
} else {
it.byval_attr = true;
diff --git a/test/c_abi/cfuncs.c b/test/c_abi/cfuncs.c
index 50e58c508e..bd249335c5 100644
--- a/test/c_abi/cfuncs.c
+++ b/test/c_abi/cfuncs.c
@@ -999,13 +999,14 @@ typedef struct {
short y;
} Coord2;
-void __attribute__((stdcall)) stdcall_coord2(Coord2 a, Coord2 b, Coord2 c) {
+Coord2 __attribute__((stdcall)) stdcall_coord2(Coord2 a, Coord2 b, Coord2 c) {
assert_or_panic(a.x == 0x1111);
assert_or_panic(a.y == 0x2222);
assert_or_panic(b.x == 0x3333);
assert_or_panic(b.y == 0x4444);
assert_or_panic(c.x == 0x5555);
assert_or_panic(c.y == 0x6666);
+ return (Coord2){123, 456};
}
void __attribute__((stdcall)) stdcall_big_union(union BigUnion x) {
diff --git a/test/c_abi/main.zig b/test/c_abi/main.zig
index 5511094487..e9543c4e7e 100644
--- a/test/c_abi/main.zig
+++ b/test/c_abi/main.zig
@@ -1161,17 +1161,25 @@ const Coord2 = extern struct {
y: i16,
};
-extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) void;
+extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) Coord2;
test "Stdcall ABI structs" {
- stdcall_coord2(
+ if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
+ if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
+ if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
+
+ const res = stdcall_coord2(
.{ .x = 0x1111, .y = 0x2222 },
.{ .x = 0x3333, .y = 0x4444 },
.{ .x = 0x5555, .y = 0x6666 },
);
+ try expect(res.x == 123);
+ try expect(res.y == 456);
}
extern fn stdcall_big_union(BigUnion) callconv(stdcall_callconv) void;
test "Stdcall ABI big union" {
+ if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
+
var x = BigUnion{
.a = BigStruct{
.a = 1,