| author | |
| committer | |
| log | 2b7678bc421e2efbdbce60d0f25ac68ffa20e100 |
| tree | ec68858f064a42ce790db3dd787434564fde876c |
| parent | 5949851074597dbc315476237f42fa67a0b6770a |
3 files changed, 21 insertions(+), 9 deletions(-)
src/codegen/llvm.zig+9-6| ... | @@ -10412,6 +10412,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool | ... | @@ -10412,6 +10412,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool |
| 10412 | .riscv32, .riscv64 => return riscv_c_abi.classifyType(fn_info.return_type, target) == .memory, | 10412 | .riscv32, .riscv64 => return riscv_c_abi.classifyType(fn_info.return_type, target) == .memory, |
| 10413 | else => return false, // TODO investigate C ABI for other architectures | 10413 | else => return false, // TODO investigate C ABI for other architectures |
| 10414 | }, | 10414 | }, |
| 10415 | .Stdcall => return !isScalar(fn_info.return_type), | ||
| 10415 | else => return false, | 10416 | else => return false, |
| 10416 | } | 10417 | } |
| 10417 | } | 10418 | } |
| ... | @@ -10567,6 +10568,13 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type { | ... | @@ -10567,6 +10568,13 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type { |
| 10567 | else => return dg.lowerType(fn_info.return_type), | 10568 | else => return dg.lowerType(fn_info.return_type), |
| 10568 | } | 10569 | } |
| 10569 | }, | 10570 | }, |
| 10571 | .Stdcall => { | ||
| 10572 | if (isScalar(fn_info.return_type)) { | ||
| 10573 | return dg.lowerType(fn_info.return_type); | ||
| 10574 | } else { | ||
| 10575 | return dg.context.voidType(); | ||
| 10576 | } | ||
| 10577 | }, | ||
| 10570 | else => return dg.lowerType(fn_info.return_type), | 10578 | else => return dg.lowerType(fn_info.return_type), |
| 10571 | } | 10579 | } |
| 10572 | } | 10580 | } |
| ... | @@ -10802,12 +10810,7 @@ const ParamTypeIterator = struct { | ... | @@ -10802,12 +10810,7 @@ const ParamTypeIterator = struct { |
| 10802 | it.zig_index += 1; | 10810 | it.zig_index += 1; |
| 10803 | it.llvm_index += 1; | 10811 | it.llvm_index += 1; |
| 10804 | 10812 | ||
| 10805 | if (it.target.cpu.arch != .x86 or it.target.os.tag != .windows) { | 10813 | if (isScalar(ty)) { |
| 10806 | return .byval; | ||
| 10807 | } | ||
| 10808 | |||
| 10809 | const is_scalar = isScalar(ty); | ||
| 10810 | if (is_scalar) { | ||
| 10811 | return .byval; | 10814 | return .byval; |
| 10812 | } else { | 10815 | } else { |
| 10813 | it.byval_attr = true; | 10816 | it.byval_attr = true; |
test/c_abi/cfuncs.c+2-1| ... | @@ -999,13 +999,14 @@ typedef struct { | ... | @@ -999,13 +999,14 @@ typedef struct { |
| 999 | short y; | 999 | short y; |
| 1000 | } Coord2; | 1000 | } Coord2; |
| 1001 | 1001 | ||
| 1002 | void __attribute__((stdcall)) stdcall_coord2(Coord2 a, Coord2 b, Coord2 c) { | 1002 | Coord2 __attribute__((stdcall)) stdcall_coord2(Coord2 a, Coord2 b, Coord2 c) { |
| 1003 | assert_or_panic(a.x == 0x1111); | 1003 | assert_or_panic(a.x == 0x1111); |
| 1004 | assert_or_panic(a.y == 0x2222); | 1004 | assert_or_panic(a.y == 0x2222); |
| 1005 | assert_or_panic(b.x == 0x3333); | 1005 | assert_or_panic(b.x == 0x3333); |
| 1006 | assert_or_panic(b.y == 0x4444); | 1006 | assert_or_panic(b.y == 0x4444); |
| 1007 | assert_or_panic(c.x == 0x5555); | 1007 | assert_or_panic(c.x == 0x5555); |
| 1008 | assert_or_panic(c.y == 0x6666); | 1008 | assert_or_panic(c.y == 0x6666); |
| 1009 | return (Coord2){123, 456}; | ||
| 1009 | } | 1010 | } |
| 1010 | 1011 | ||
| 1011 | void __attribute__((stdcall)) stdcall_big_union(union BigUnion x) { | 1012 | void __attribute__((stdcall)) stdcall_big_union(union BigUnion x) { |
test/c_abi/main.zig+10-2| ... | @@ -1161,17 +1161,25 @@ const Coord2 = extern struct { | ... | @@ -1161,17 +1161,25 @@ const Coord2 = extern struct { |
| 1161 | y: i16, | 1161 | y: i16, |
| 1162 | }; | 1162 | }; |
| 1163 | 1163 | ||
| 1164 | extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) void; | 1164 | extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) Coord2; |
| 1165 | test "Stdcall ABI structs" { | 1165 | test "Stdcall ABI structs" { |
| 1166 | stdcall_coord2( | 1166 | if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 1167 | if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; | ||
| 1168 | if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; | ||
| 1169 | |||
| 1170 | const res = stdcall_coord2( | ||
| 1167 | .{ .x = 0x1111, .y = 0x2222 }, | 1171 | .{ .x = 0x1111, .y = 0x2222 }, |
| 1168 | .{ .x = 0x3333, .y = 0x4444 }, | 1172 | .{ .x = 0x3333, .y = 0x4444 }, |
| 1169 | .{ .x = 0x5555, .y = 0x6666 }, | 1173 | .{ .x = 0x5555, .y = 0x6666 }, |
| 1170 | ); | 1174 | ); |
| 1175 | try expect(res.x == 123); | ||
| 1176 | try expect(res.y == 456); | ||
| 1171 | } | 1177 | } |
| 1172 | 1178 | ||
| 1173 | extern fn stdcall_big_union(BigUnion) callconv(stdcall_callconv) void; | 1179 | extern fn stdcall_big_union(BigUnion) callconv(stdcall_callconv) void; |
| 1174 | test "Stdcall ABI big union" { | 1180 | test "Stdcall ABI big union" { |
| 1181 | if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; | ||
| 1182 | |||
| 1175 | var x = BigUnion{ | 1183 | var x = BigUnion{ |
| 1176 | .a = BigStruct{ | 1184 | .a = BigStruct{ |
| 1177 | .a = 1, | 1185 | .a = 1, |