authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-08-24 19:12:07-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-08-26 03:11:07+02:00
loge955d137e7d23eacd6aeb0eeb406d9fd9cfa9526
tree4ec9b4756f32b7dddef3243d2239b64e699fe6cd
parent18e38104ce60a02f27b565097cff66c3429aa8d4

x86_64: add soft float abi support

Closes #36582

2 files changed, 17 insertions(+), 15 deletions(-)

src/Type.zig+1-1
...@@ -3163,7 +3163,7 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool...@@ -3163,7 +3163,7 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool
3163 },3163 },
3164 .float => switch (ty.floatBits(zcu.getTarget())) {3164 .float => switch (ty.floatBits(zcu.getTarget())) {
3165 else => true,3165 else => true,
3166 80 => zcu.getTarget().cTypeBitSize(.longdouble) == 80,3166 80 => |bits| std.zig.target.compilerRtFloatAbi(zcu.getTarget(), bits) == .hard,
3167 },3167 },
3168 .@"fn" => {3168 .@"fn" => {
3169 if (position != .other) return false;3169 if (position != .other) return false;
src/codegen/x86_64/abi.zig+16-14
...@@ -122,19 +122,17 @@ pub fn classifyWindows(init_ty: Type, zcu: *Zcu, target: *const std.Target, ctx:...@@ -122,19 +122,17 @@ pub fn classifyWindows(init_ty: Type, zcu: *Zcu, target: *const std.Target, ctx:
122 1, 2, 4, 8 => .integer,122 1, 2, 4, 8 => .integer,
123 else => switch (ty.zigTypeTag(zcu)) {123 else => switch (ty.zigTypeTag(zcu)) {
124 .int => .win_i128,124 .int => .win_i128,
125 .@"struct", .@"union" => if (ty.containerLayout(zcu) == .@"packed")125 .@"struct", .@"union" => if (ty.containerLayout(zcu) != .@"packed" or
126 .win_i128126 target.cpu.has(.x86, .soft_float)) .memory else .win_i128,
127 else
128 .memory,
129 else => .memory,127 else => .memory,
130 },128 },
131 },129 },
132 .noreturn => unreachable,130 .noreturn => unreachable,
133 .float => switch (ty.floatBits(target)) {131 .float => switch (ty.floatBits(target)) {
134 16, 32, 64 => .sse,
135 80 => .memory,
136 128 => .win_i128,
137 else => unreachable,132 else => unreachable,
133 16, 32, 64 => if (target.cpu.has(.x86, .soft_float)) .integer else .sse,
134 80 => .memory,
135 128 => if (target.cpu.has(.x86, .soft_float)) .memory else .win_i128,
138 },136 },
139 .vector => {137 .vector => {
140 const len = ty.vectorLen(zcu);138 const len = ty.vectorLen(zcu);
...@@ -183,6 +181,7 @@ pub fn classifyWindows(init_ty: Type, zcu: *Zcu, target: *const std.Target, ctx:...@@ -183,6 +181,7 @@ pub fn classifyWindows(init_ty: Type, zcu: *Zcu, target: *const std.Target, ctx:
183/// the beginning of the array; unused slots are filled with .none.181/// the beginning of the array; unused slots are filled with .none.
184pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Context) [8]Class {182pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Context) [8]Class {
185 switch (ty.zigTypeTag(zcu)) {183 switch (ty.zigTypeTag(zcu)) {
184 else => unreachable,
186 .void => return Class.zero_bit,185 .void => return Class.zero_bit,
187 .bool => return Class.one_integer,186 .bool => return Class.one_integer,
188 .noreturn => unreachable,187 .noreturn => unreachable,
...@@ -195,7 +194,12 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont...@@ -195,7 +194,12 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont
195 if (bits <= 64 * 4) return Class.four_integers;194 if (bits <= 64 * 4) return Class.four_integers;
196 return Class.stack;195 return Class.stack;
197 },196 },
198 .float => switch (ty.floatBits(target)) {197 .float => if (target.cpu.has(.x86, .soft_float)) switch (ty.floatBits(target)) {
198 else => unreachable,
199 16, 32, 64 => return Class.one_integer,
200 80, 128 => return Class.two_integers,
201 } else switch (ty.floatBits(target)) {
202 else => unreachable,
199 16 => {203 16 => {
200 if (ctx == .other) return Class.stack;204 if (ctx == .other) return Class.stack;
201 // TODO clang doesn't allow __fp16 as .ret or .arg205 // TODO clang doesn't allow __fp16 as .ret or .arg
...@@ -203,15 +207,14 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont...@@ -203,15 +207,14 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont
203 },207 },
204 32 => return Class.f32,208 32 => return Class.f32,
205 64 => return Class.f64,209 64 => return Class.f64,
206 // "Arguments of types __float128, _Decimal128 and __m128 are
207 // split into two halves. The least significant ones belong
208 // to class SSE, the most significant one to class SSEUP."
209 128 => return Class.f128,
210 // "The 64-bit mantissa of arguments of type long double210 // "The 64-bit mantissa of arguments of type long double
211 // belongs to class X87, the 16-bit exponent plus 6 bytes211 // belongs to class X87, the 16-bit exponent plus 6 bytes
212 // of padding belongs to class X87UP."212 // of padding belongs to class X87UP."
213 80 => return Class.f80,213 80 => return Class.f80,
214 else => unreachable,214 // "Arguments of types __float128, _Decimal128 and __m128 are
215 // split into two halves. The least significant ones belong
216 // to class SSE, the most significant one to class SSEUP."
217 128 => return Class.f128,
215 },218 },
216 .pointer => switch (ty.ptrSize(zcu)) {219 .pointer => switch (ty.ptrSize(zcu)) {
217 .slice => return Class.two_integers,220 .slice => return Class.two_integers,
...@@ -341,7 +344,6 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont...@@ -341,7 +344,6 @@ pub fn classifySystemV(ty: Type, zcu: *Zcu, target: *const std.Target, ctx: Cont
341 if (ty_size <= 16) return Class.two_integers;344 if (ty_size <= 16) return Class.two_integers;
342 return Class.stack;345 return Class.stack;
343 },346 },
344 else => unreachable,
345 }347 }
346}348}
347349