From 6986d2aca900bdda30f541baf9b06fb29688fe97 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 1 May 2024 14:39:24 -0700 Subject: [PATCH] x86_64 sysv C ABI: fix f128 param and return types Clang 17 passed struct{f128} parameters using rdi and rax, while Clang 18 matches GCC 13.2 behavior, passing them using xmm0. This commit makes Zig's LLVM backend match Clang 18 and GCC 13.2. The commit deletes a hack in x86_64/abi.zig which miscategorized f128 as "memory" which obviously disagreed with the spec. --- src/arch/x86_64/CodeGen.zig | 2 +- src/arch/x86_64/abi.zig | 4 ---- src/codegen/llvm.zig | 20 ++++++++++++++++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 7faf3d6d50c2ac5a0a3ffe0d6d7a5ab4f63c62ff..cc6e01408072fb8d3d61a65a091af30f3cdd5593 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -14318,7 +14318,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo else => { const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, self.target.*, .other), .none); assert(std.mem.indexOfNone(abi.Class, classes, &.{ - .integer, .sse, .memory, .float, .float_combine, + .integer, .sse, .sseup, .memory, .float, .float_combine, }) == null); const abi_size = ty.abiSize(mod); if (abi_size < 4 or diff --git a/src/arch/x86_64/abi.zig b/src/arch/x86_64/abi.zig index 8c81ad9ed2e24616b49d67e91956712a999c3b07..0ae69eb09c78d45dff34c240fc21be53328c522a 100644 --- a/src/arch/x86_64/abi.zig +++ b/src/arch/x86_64/abi.zig @@ -170,10 +170,6 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8 // "Arguments of types __float128, _Decimal128 and __m128 are // split into two halves. The least significant ones belong // to class SSE, the most significant one to class SSEUP." - if (ctx == .field) { - result[0] = .memory; - return result; - } result[0] = .sse; result[1] = .sseup; return result; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 877b2365c88eff39356f5d58bcc4759d4ffa0228..2d3c7de2e22eb794b0c86f5a2a0ad71d3ebade9a 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -11167,10 +11167,18 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.E types_buffer[types_index] = .i64; types_index += 1; }, - .sse, .sseup => { + .sse => { types_buffer[types_index] = .double; types_index += 1; }, + .sseup => { + if (types_buffer[types_index - 1] == .double) { + types_buffer[types_index - 1] = .fp128; + } else { + types_buffer[types_index] = .double; + types_index += 1; + } + }, .float => { types_buffer[types_index] = .float; types_index += 1; @@ -11454,10 +11462,18 @@ const ParamTypeIterator = struct { types_buffer[types_index] = .i64; types_index += 1; }, - .sse, .sseup => { + .sse => { types_buffer[types_index] = .double; types_index += 1; }, + .sseup => { + if (types_buffer[types_index - 1] == .double) { + types_buffer[types_index - 1] = .fp128; + } else { + types_buffer[types_index] = .double; + types_index += 1; + } + }, .float => { types_buffer[types_index] = .float; types_index += 1; -- 2.54.0