authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-01 14:39:24-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-08 19:37:29-07:00
log6986d2aca900bdda30f541baf9b06fb29688fe97
treec5011736f5b9383478cabcbae8205c10258a6b77
parentbc69cb9b106cbb0748b960c10b7cf66d0c5fd28e

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.

3 files changed, 19 insertions(+), 7 deletions(-)

src/arch/x86_64/CodeGen.zig+1-1
......@@ -14318,7 +14318,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo
1431814318 else => {
1431914319 const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, self.target.*, .other), .none);
1432014320 assert(std.mem.indexOfNone(abi.Class, classes, &.{
14321 .integer, .sse, .memory, .float, .float_combine,
14321 .integer, .sse, .sseup, .memory, .float, .float_combine,
1432214322 }) == null);
1432314323 const abi_size = ty.abiSize(mod);
1432414324 if (abi_size < 4 or
src/arch/x86_64/abi.zig-4
......@@ -170,10 +170,6 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8
170170 // "Arguments of types __float128, _Decimal128 and __m128 are
171171 // split into two halves. The least significant ones belong
172172 // to class SSE, the most significant one to class SSEUP."
173 if (ctx == .field) {
174 result[0] = .memory;
175 return result;
176 }
177173 result[0] = .sse;
178174 result[1] = .sseup;
179175 return result;
src/codegen/llvm.zig+18-2
......@@ -11167,10 +11167,18 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.E
1116711167 types_buffer[types_index] = .i64;
1116811168 types_index += 1;
1116911169 },
11170 .sse, .sseup => {
11170 .sse => {
1117111171 types_buffer[types_index] = .double;
1117211172 types_index += 1;
1117311173 },
11174 .sseup => {
11175 if (types_buffer[types_index - 1] == .double) {
11176 types_buffer[types_index - 1] = .fp128;
11177 } else {
11178 types_buffer[types_index] = .double;
11179 types_index += 1;
11180 }
11181 },
1117411182 .float => {
1117511183 types_buffer[types_index] = .float;
1117611184 types_index += 1;
......@@ -11454,10 +11462,18 @@ const ParamTypeIterator = struct {
1145411462 types_buffer[types_index] = .i64;
1145511463 types_index += 1;
1145611464 },
11457 .sse, .sseup => {
11465 .sse => {
1145811466 types_buffer[types_index] = .double;
1145911467 types_index += 1;
1146011468 },
11469 .sseup => {
11470 if (types_buffer[types_index - 1] == .double) {
11471 types_buffer[types_index - 1] = .fp128;
11472 } else {
11473 types_buffer[types_index] = .double;
11474 types_index += 1;
11475 }
11476 },
1146111477 .float => {
1146211478 types_buffer[types_index] = .float;
1146311479 types_index += 1;