Commit 2b7678bc42

Veikka Tuominen <git@vexu.eu>
2023-01-19 15:13:52
llvm: implement Stdcall return types
1 parent 5949851
Changed files (3)
src
codegen
test
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;
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) {
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,