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...@@ -14318,7 +14318,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo
14318 else => {14318 else => {
14319 const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, self.target.*, .other), .none);14319 const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, self.target.*, .other), .none);
14320 assert(std.mem.indexOfNone(abi.Class, classes, &.{14320 assert(std.mem.indexOfNone(abi.Class, classes, &.{
14321 .integer, .sse, .memory, .float, .float_combine,14321 .integer, .sse, .sseup, .memory, .float, .float_combine,
14322 }) == null);14322 }) == null);
14323 const abi_size = ty.abiSize(mod);14323 const abi_size = ty.abiSize(mod);
14324 if (abi_size < 4 or14324 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...@@ -170,10 +170,6 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: std.Target, ctx: Context) [8
170 // "Arguments of types __float128, _Decimal128 and __m128 are170 // "Arguments of types __float128, _Decimal128 and __m128 are
171 // split into two halves. The least significant ones belong171 // split into two halves. The least significant ones belong
172 // to class SSE, the most significant one to class SSEUP."172 // to class SSE, the most significant one to class SSEUP."
173 if (ctx == .field) {
174 result[0] = .memory;
175 return result;
176 }
177 result[0] = .sse;173 result[0] = .sse;
178 result[1] = .sseup;174 result[1] = .sseup;
179 return result;175 return result;
src/codegen/llvm.zig+18-2
...@@ -11167,10 +11167,18 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.E...@@ -11167,10 +11167,18 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.E
11167 types_buffer[types_index] = .i64;11167 types_buffer[types_index] = .i64;
11168 types_index += 1;11168 types_index += 1;
11169 },11169 },
11170 .sse, .sseup => {11170 .sse => {
11171 types_buffer[types_index] = .double;11171 types_buffer[types_index] = .double;
11172 types_index += 1;11172 types_index += 1;
11173 },11173 },
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 },
11174 .float => {11182 .float => {
11175 types_buffer[types_index] = .float;11183 types_buffer[types_index] = .float;
11176 types_index += 1;11184 types_index += 1;
...@@ -11454,10 +11462,18 @@ const ParamTypeIterator = struct {...@@ -11454,10 +11462,18 @@ const ParamTypeIterator = struct {
11454 types_buffer[types_index] = .i64;11462 types_buffer[types_index] = .i64;
11455 types_index += 1;11463 types_index += 1;
11456 },11464 },
11457 .sse, .sseup => {11465 .sse => {
11458 types_buffer[types_index] = .double;11466 types_buffer[types_index] = .double;
11459 types_index += 1;11467 types_index += 1;
11460 },11468 },
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 },
11461 .float => {11477 .float => {
11462 types_buffer[types_index] = .float;11478 types_buffer[types_index] = .float;
11463 types_index += 1;11479 types_index += 1;