authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-19 16:13:52+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-19 16:13:52+02:00
log2b7678bc421e2efbdbce60d0f25ac68ffa20e100
treeec68858f064a42ce790db3dd787434564fde876c
parent5949851074597dbc315476237f42fa67a0b6770a

llvm: implement Stdcall return types


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
1041210412 .riscv32, .riscv64 => return riscv_c_abi.classifyType(fn_info.return_type, target) == .memory,
1041310413 else => return false, // TODO investigate C ABI for other architectures
1041410414 },
10415 .Stdcall => return !isScalar(fn_info.return_type),
1041510416 else => return false,
1041610417 }
1041710418}
......@@ -10567,6 +10568,13 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type {
1056710568 else => return dg.lowerType(fn_info.return_type),
1056810569 }
1056910570 },
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 },
1057010578 else => return dg.lowerType(fn_info.return_type),
1057110579 }
1057210580}
......@@ -10802,12 +10810,7 @@ const ParamTypeIterator = struct {
1080210810 it.zig_index += 1;
1080310811 it.llvm_index += 1;
1080410812
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) {
10813 if (isScalar(ty)) {
1081110814 return .byval;
1081210815 } else {
1081310816 it.byval_attr = true;
test/c_abi/cfuncs.c+2-1
......@@ -999,13 +999,14 @@ typedef struct {
999999 short y;
10001000} Coord2;
10011001
1002void __attribute__((stdcall)) stdcall_coord2(Coord2 a, Coord2 b, Coord2 c) {
1002Coord2 __attribute__((stdcall)) stdcall_coord2(Coord2 a, Coord2 b, Coord2 c) {
10031003 assert_or_panic(a.x == 0x1111);
10041004 assert_or_panic(a.y == 0x2222);
10051005 assert_or_panic(b.x == 0x3333);
10061006 assert_or_panic(b.y == 0x4444);
10071007 assert_or_panic(c.x == 0x5555);
10081008 assert_or_panic(c.y == 0x6666);
1009 return (Coord2){123, 456};
10091010}
10101011
10111012void __attribute__((stdcall)) stdcall_big_union(union BigUnion x) {
test/c_abi/main.zig+10-2
......@@ -1161,17 +1161,25 @@ const Coord2 = extern struct {
11611161 y: i16,
11621162};
11631163
1164extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) void;
1164extern fn stdcall_coord2(Coord2, Coord2, Coord2) callconv(stdcall_callconv) Coord2;
11651165test "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(
11671171 .{ .x = 0x1111, .y = 0x2222 },
11681172 .{ .x = 0x3333, .y = 0x4444 },
11691173 .{ .x = 0x5555, .y = 0x6666 },
11701174 );
1175 try expect(res.x == 123);
1176 try expect(res.y == 456);
11711177}
11721178
11731179extern fn stdcall_big_union(BigUnion) callconv(stdcall_callconv) void;
11741180test "Stdcall ABI big union" {
1181 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
1182
11751183 var x = BigUnion{
11761184 .a = BigStruct{
11771185 .a = 1,