authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2023-01-19 00:37:20-05:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2023-01-19 00:37:56-05:00
log5949851074597dbc315476237f42fa67a0b6770a
tree28002d1b10b993ac93cf25865a570715e0927659
parentd389dba04f66deb3dd1831ed96b6843a9eee1309

llvm: pass non-scalars as byref in .Stdcall

- add c_abi tests for .Stdcall - enable (x86|x86_64)-windows-gnu in the c_abi tests

4 files changed, 96 insertions(+), 0 deletions(-)

src/codegen/llvm.zig+16
......@@ -10798,6 +10798,22 @@ const ParamTypeIterator = struct {
1079810798 },
1079910799 }
1080010800 },
10801 .Stdcall => {
10802 it.zig_index += 1;
10803 it.llvm_index += 1;
10804
10805 if (it.target.cpu.arch != .x86 or it.target.os.tag != .windows) {
10806 return .byval;
10807 }
10808
10809 const is_scalar = isScalar(ty);
10810 if (is_scalar) {
10811 return .byval;
10812 } else {
10813 it.byval_attr = true;
10814 return .byref;
10815 }
10816 },
1080110817 else => {
1080210818 it.zig_index += 1;
1080310819 it.llvm_index += 1;
test/c_abi/cfuncs.c+29
......@@ -985,3 +985,32 @@ f128_struct c_f128_struct(f128_struct a) {
985985 return (f128_struct){56.78};
986986}
987987#endif
988
989void __attribute__((stdcall)) stdcall_scalars(char a, short b, int c, float d, double e) {
990 assert_or_panic(a == 1);
991 assert_or_panic(b == 2);
992 assert_or_panic(c == 3);
993 assert_or_panic(d == 4.0);
994 assert_or_panic(e == 5.0);
995}
996
997typedef struct {
998 short x;
999 short y;
1000} Coord2;
1001
1002void __attribute__((stdcall)) stdcall_coord2(Coord2 a, Coord2 b, Coord2 c) {
1003 assert_or_panic(a.x == 0x1111);
1004 assert_or_panic(a.y == 0x2222);
1005 assert_or_panic(b.x == 0x3333);
1006 assert_or_panic(b.y == 0x4444);
1007 assert_or_panic(c.x == 0x5555);
1008 assert_or_panic(c.y == 0x6666);
1009}
1010
1011void __attribute__((stdcall)) stdcall_big_union(union BigUnion x) {
1012 assert_or_panic(x.a.a == 1);
1013 assert_or_panic(x.a.b == 2);
1014 assert_or_panic(x.a.c == 3);
1015 assert_or_panic(x.a.d == 4);
1016}
test/c_abi/main.zig+36
......@@ -1147,3 +1147,39 @@ test "f128 struct" {
11471147 const a = c_f128_struct(.{ .a = 12.34 });
11481148 try expect(@floatCast(f64, a.a) == 56.78);
11491149}
1150
1151// The stdcall attribute on C functions is ignored when compiled on non-x86
1152const stdcall_callconv: std.builtin.CallingConvention = if (builtin.cpu.arch == .x86) .Stdcall else .C;
1153
1154extern fn stdcall_scalars(i8, i16, i32, f32, f64) callconv(stdcall_callconv) void;
1155test "Stdcall ABI scalars" {
1156 stdcall_scalars(1, 2, 3, 4.0, 5.0);
1157}
1158
1159const Coord2 = extern struct {
1160 x: i16,
1161 y: i16,
1162};
1163
1164extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) void;
1165test "Stdcall ABI structs" {
1166 stdcall_coord2(
1167 .{ .x = 0x1111, .y = 0x2222 },
1168 .{ .x = 0x3333, .y = 0x4444 },
1169 .{ .x = 0x5555, .y = 0x6666 },
1170 );
1171}
1172
1173extern fn stdcall_big_union(BigUnion) callconv(stdcall_callconv) void;
1174test "Stdcall ABI big union" {
1175 var x = BigUnion{
1176 .a = BigStruct{
1177 .a = 1,
1178 .b = 2,
1179 .c = 3,
1180 .d = 4,
1181 .e = 5,
1182 },
1183 };
1184 stdcall_big_union(x);
1185}
test/tests.zig+15
......@@ -1321,6 +1321,16 @@ const c_abi_targets = [_]CrossTarget{
13211321 .os_tag = .linux,
13221322 .abi = .musl,
13231323 },
1324 .{
1325 .cpu_arch = .x86,
1326 .os_tag = .windows,
1327 .abi = .gnu,
1328 },
1329 .{
1330 .cpu_arch = .x86_64,
1331 .os_tag = .windows,
1332 .abi = .gnu,
1333 },
13241334};
13251335
13261336pub fn addCAbiTests(b: *build.Builder, skip_non_native: bool, skip_release: bool) *build.Step {
......@@ -1343,6 +1353,11 @@ pub fn addCAbiTests(b: *build.Builder, skip_non_native: bool, skip_release: bool
13431353 test_step.addCSourceFile("test/c_abi/cfuncs.c", &.{"-std=c99"});
13441354 test_step.setBuildMode(mode);
13451355
1356 if (c_abi_target.isWindows() and c_abi_target.getCpuArch() == .x86) {
1357 // LTO currently incorrectly strips stdcall name-mangled functions
1358 test_step.want_lto = false;
1359 }
1360
13461361 const triple_prefix = c_abi_target.zigTriple(b.allocator) catch unreachable;
13471362 test_step.setNamePrefix(b.fmt("{s}-{s}-{s} ", .{
13481363 "test-c-abi",