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,