Commit 0f61d1f0df

Veikka Tuominen <git@vexu.eu>
2022-09-03 00:05:46
stage2 llvm: improve handling of i128 on Windows C ABI
1 parent b83c037
Changed files (2)
src
arch
x86_64
codegen
src/arch/x86_64/abi.zig
@@ -5,7 +5,7 @@ const assert = std.debug.assert;
 const Register = @import("bits.zig").Register;
 const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
 
-pub const Class = enum { integer, sse, sseup, x87, x87up, complex_x87, memory, none };
+pub const Class = enum { integer, sse, sseup, x87, x87up, complex_x87, memory, none, win_i128 };
 
 pub fn classifyWindows(ty: Type, target: Target) Class {
     // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
@@ -34,7 +34,15 @@ pub fn classifyWindows(ty: Type, target: Target) Class {
         => switch (ty.abiSize(target)) {
             0 => unreachable,
             1, 2, 4, 8 => return .integer,
-            else => return .memory,
+            else => switch (ty.zigTypeTag()) {
+                .Int => return .win_i128,
+                .Struct, .Union => if (ty.containerLayout() == .Packed) {
+                    return .win_i128;
+                } else {
+                    return .memory;
+                },
+                else => return .memory,
+            },
         },
 
         .Float, .Vector => return .sse,
src/codegen/llvm.zig
@@ -9687,6 +9687,7 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*const llvm.
                                 return dg.context.intType(@intCast(c_uint, abi_size * 8));
                             }
                         },
+                        .win_i128 => return dg.context.intType(64).vectorType(2),
                         .memory => return dg.context.voidType(),
                         .sse => return dg.lowerType(fn_info.return_type),
                         else => unreachable,
@@ -9727,6 +9728,7 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*const llvm.
                                     @panic("TODO");
                                 },
                                 .memory => unreachable, // handled above
+                                .win_i128 => unreachable, // windows only
                                 .none => break,
                             }
                         }
@@ -9851,6 +9853,11 @@ const ParamTypeIterator = struct {
                                     return .abi_sized_int;
                                 }
                             },
+                            .win_i128 => {
+                                it.zig_index += 1;
+                                it.llvm_index += 1;
+                                return .byref;
+                            },
                             .memory => {
                                 it.zig_index += 1;
                                 it.llvm_index += 1;
@@ -9905,6 +9912,7 @@ const ParamTypeIterator = struct {
                                         @panic("TODO");
                                     },
                                     .memory => unreachable, // handled above
+                                    .win_i128 => unreachable, // windows only
                                     .none => break,
                                 }
                             }