x86_64: fix windows calling convention abi

This commit is contained in:
Jacob Young 2025-09-28 07:23:08 -04:00
parent bc4da9a907
commit d5f09f56e0
4 changed files with 5540 additions and 9763 deletions

View File

@ -12103,7 +12103,7 @@ fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: *const st
return switch (fn_info.cc) { return switch (fn_info.cc) {
.auto => returnTypeByRef(zcu, target, return_type), .auto => returnTypeByRef(zcu, target, return_type),
.x86_64_sysv => firstParamSRetSystemV(return_type, zcu, target), .x86_64_sysv => firstParamSRetSystemV(return_type, zcu, target),
.x86_64_win => x86_64_abi.classifyWindows(return_type, zcu, target) == .memory, .x86_64_win => x86_64_abi.classifyWindows(return_type, zcu, target, .ret) == .memory,
.x86_sysv, .x86_win => isByRef(return_type, zcu), .x86_sysv, .x86_win => isByRef(return_type, zcu),
.x86_stdcall => !isScalar(zcu, return_type), .x86_stdcall => !isScalar(zcu, return_type),
.wasm_mvp => wasm_c_abi.classifyType(return_type, zcu) == .indirect, .wasm_mvp => wasm_c_abi.classifyType(return_type, zcu) == .indirect,
@ -12205,7 +12205,7 @@ fn lowerFnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType)
fn lowerWin64FnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type { fn lowerWin64FnRetTy(o: *Object, pt: Zcu.PerThread, fn_info: InternPool.Key.FuncType) Allocator.Error!Builder.Type {
const zcu = pt.zcu; const zcu = pt.zcu;
const return_type = Type.fromInterned(fn_info.return_type); const return_type = Type.fromInterned(fn_info.return_type);
switch (x86_64_abi.classifyWindows(return_type, zcu, zcu.getTarget())) { switch (x86_64_abi.classifyWindows(return_type, zcu, zcu.getTarget(), .ret)) {
.integer => { .integer => {
if (isScalar(zcu, return_type)) { if (isScalar(zcu, return_type)) {
return o.lowerType(pt, return_type); return o.lowerType(pt, return_type);
@ -12476,7 +12476,7 @@ const ParamTypeIterator = struct {
fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering { fn nextWin64(it: *ParamTypeIterator, ty: Type) ?Lowering {
const zcu = it.pt.zcu; const zcu = it.pt.zcu;
switch (x86_64_abi.classifyWindows(ty, zcu, zcu.getTarget())) { switch (x86_64_abi.classifyWindows(ty, zcu, zcu.getTarget(), .arg)) {
.integer => { .integer => {
if (isScalar(zcu, ty)) { if (isScalar(zcu, ty)) {
it.zig_index += 1; it.zig_index += 1;

File diff suppressed because it is too large Load Diff

View File

@ -110,7 +110,9 @@ pub const Class = enum {
} }
}; };
pub fn classifyWindows(ty: Type, zcu: *Zcu, target: *const std.Target) Class { pub const Context = enum { ret, arg, other };
pub fn classifyWindows(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Context) Class {
// https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017 // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017
// "There's a strict one-to-one correspondence between a function call's arguments // "There's a strict one-to-one correspondence between a function call's arguments
// and the registers used for those arguments. Any argument that doesn't fit in 8 // and the registers used for those arguments. Any argument that doesn't fit in 8
@ -148,8 +150,9 @@ pub fn classifyWindows(ty: Type, zcu: *Zcu, target: *const std.Target) Class {
}, },
.float => switch (ty.floatBits(target)) { .float => switch (ty.floatBits(target)) {
16, 32, 64, 128 => .sse, 16, 32, 64 => .sse,
80 => .memory, 80 => .memory,
128 => if (ctx == .arg) .memory else .sse,
else => unreachable, else => unreachable,
}, },
.vector => .sse, .vector => .sse,
@ -166,8 +169,6 @@ pub fn classifyWindows(ty: Type, zcu: *Zcu, target: *const std.Target) Class {
}; };
} }
pub const Context = enum { ret, arg, other };
/// There are a maximum of 8 possible return slots. Returned values are in /// There are a maximum of 8 possible return slots. Returned values are in
/// the beginning of the array; unused slots are filled with .none. /// the beginning of the array; unused slots are filled with .none.
pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Context) [8]Class { pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Context) [8]Class {

View File

@ -5172,15 +5172,6 @@ test mulSaturate {
try test_mul_saturate.testIntVectors(); try test_mul_saturate.testIntVectors();
} }
inline fn multiply(comptime Type: type, lhs: Type, rhs: Type) Type {
return lhs * rhs;
}
test multiply {
const test_multiply = binary(multiply, .{});
try test_multiply.testFloats();
try test_multiply.testFloatVectors();
}
inline fn divide(comptime Type: type, lhs: Type, rhs: Type) Type { inline fn divide(comptime Type: type, lhs: Type, rhs: Type) Type {
return lhs / rhs; return lhs / rhs;
} }
@ -5264,7 +5255,7 @@ inline fn mod(comptime Type: type, lhs: Type, rhs: Type) Type {
return @mod(lhs, rhs); return @mod(lhs, rhs);
} }
test mod { test mod {
if (@import("builtin").object_format == .coff) return error.SkipZigTest; if (@import("builtin").object_format == .coff and @import("builtin").target.abi != .gnu) return error.SkipZigTest;
const test_mod = binary(mod, .{}); const test_mod = binary(mod, .{});
try test_mod.testInts(); try test_mod.testInts();
try test_mod.testIntVectors(); try test_mod.testIntVectors();