From c8d2f5f30eaaf56c7caabff4a3a287e9db285a58 Mon Sep 17 00:00:00 2001 From: Cody Tapscott Date: Sun, 10 Jul 2022 09:53:24 -0700 Subject: [PATCH] compiler_rt: Update Windows ABI for float<->int conversion routines Starting with LLVM 14, the Libcalls to these functions are now lowered using a Vec(2, u64) instead of the standard ABI for i128 integers, so our compiler-rt implementation needs to be updated to expose the same ABI on Windows. --- lib/compiler_rt/fixdfti.zig | 16 +++++++++++++++- lib/compiler_rt/fixhfti.zig | 18 ++++++++++++++++-- lib/compiler_rt/fixsfti.zig | 16 +++++++++++++++- lib/compiler_rt/fixtfti.zig | 16 +++++++++++++++- lib/compiler_rt/fixunsdfti.zig | 16 +++++++++++++++- lib/compiler_rt/fixunshfti.zig | 16 +++++++++++++++- lib/compiler_rt/fixunssfti.zig | 16 +++++++++++++++- lib/compiler_rt/fixunstfti.zig | 16 +++++++++++++++- lib/compiler_rt/fixunsxfti.zig | 16 +++++++++++++++- lib/compiler_rt/fixxfti.zig | 18 ++++++++++++++++-- lib/compiler_rt/floattidf.zig | 16 +++++++++++++++- lib/compiler_rt/floattihf.zig | 18 ++++++++++++++++-- lib/compiler_rt/floattisf.zig | 16 +++++++++++++++- lib/compiler_rt/floattitf.zig | 16 +++++++++++++++- lib/compiler_rt/floattixf.zig | 18 ++++++++++++++++-- lib/compiler_rt/floatuntidf.zig | 16 +++++++++++++++- lib/compiler_rt/floatuntihf.zig | 18 ++++++++++++++++-- lib/compiler_rt/floatuntisf.zig | 16 +++++++++++++++- lib/compiler_rt/floatuntitf.zig | 22 +++++++++++++++------- lib/compiler_rt/floatuntixf.zig | 16 +++++++++++++++- lib/std/fmt.zig | 8 -------- 21 files changed, 305 insertions(+), 39 deletions(-) diff --git a/lib/compiler_rt/fixdfti.zig b/lib/compiler_rt/fixdfti.zig index b2476ce2f3f1..8eb38ab7f360 100644 --- a/lib/compiler_rt/fixdfti.zig +++ b/lib/compiler_rt/fixdfti.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const floatToInt = @import("./float_to_int.zig").floatToInt; pub const panic = common.panic; comptime { - @export(__fixdfti, .{ .name = "__fixdfti", .linkage = common.linkage }); + const fixdfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __fixdfti_windows_x86_64; + } else __fixdfti; + + @export(fixdfti_fn, .{ .name = "__fixdfti", .linkage = common.linkage }); } pub fn __fixdfti(a: f64) callconv(.C) i128 { return floatToInt(i128, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __fixdfti_windows_x86_64(a: f64) callconv(.C) v128 { + return @bitCast(v128, floatToInt(i128, a)); +} diff --git a/lib/compiler_rt/fixhfti.zig b/lib/compiler_rt/fixhfti.zig index 36fc1bf60758..b9d3d2e767e5 100644 --- a/lib/compiler_rt/fixhfti.zig +++ b/lib/compiler_rt/fixhfti.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const floatToInt = @import("./float_to_int.zig").floatToInt; pub const panic = common.panic; comptime { - @export(__fixhfti, .{ .name = "__fixhfti", .linkage = common.linkage }); + const fixhfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __fixhfti_windows_x86_64; + } else __fixhfti; + + @export(fixhfti_fn, .{ .name = "__fixhfti", .linkage = common.linkage }); } -fn __fixhfti(a: f16) callconv(.C) i128 { +pub fn __fixhfti(a: f16) callconv(.C) i128 { return floatToInt(i128, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __fixhfti_windows_x86_64(a: f16) callconv(.C) v128 { + return @bitCast(v128, floatToInt(i128, a)); +} diff --git a/lib/compiler_rt/fixsfti.zig b/lib/compiler_rt/fixsfti.zig index 4bf68ec8b0c9..ab280701f981 100644 --- a/lib/compiler_rt/fixsfti.zig +++ b/lib/compiler_rt/fixsfti.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const floatToInt = @import("./float_to_int.zig").floatToInt; pub const panic = common.panic; comptime { - @export(__fixsfti, .{ .name = "__fixsfti", .linkage = common.linkage }); + const fixsfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __fixsfti_windows_x86_64; + } else __fixsfti; + + @export(fixsfti_fn, .{ .name = "__fixsfti", .linkage = common.linkage }); } pub fn __fixsfti(a: f32) callconv(.C) i128 { return floatToInt(i128, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __fixsfti_windows_x86_64(a: f32) callconv(.C) v128 { + return @bitCast(v128, floatToInt(i128, a)); +} diff --git a/lib/compiler_rt/fixtfti.zig b/lib/compiler_rt/fixtfti.zig index 9ba761729e58..117b2f91b40e 100644 --- a/lib/compiler_rt/fixtfti.zig +++ b/lib/compiler_rt/fixtfti.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const floatToInt = @import("./float_to_int.zig").floatToInt; pub const panic = common.panic; comptime { - @export(__fixtfti, .{ .name = "__fixtfti", .linkage = common.linkage }); + const fixtfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __fixtfti_windows_x86_64; + } else __fixtfti; + + @export(fixtfti_fn, .{ .name = "__fixtfti", .linkage = common.linkage }); } pub fn __fixtfti(a: f128) callconv(.C) i128 { return floatToInt(i128, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __fixtfti_windows_x86_64(a: f128) callconv(.C) v128 { + return @bitCast(v128, floatToInt(i128, a)); +} diff --git a/lib/compiler_rt/fixunsdfti.zig b/lib/compiler_rt/fixunsdfti.zig index ce3c4aabddd2..e426ea61b971 100644 --- a/lib/compiler_rt/fixunsdfti.zig +++ b/lib/compiler_rt/fixunsdfti.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const floatToInt = @import("./float_to_int.zig").floatToInt; pub const panic = common.panic; comptime { - @export(__fixunsdfti, .{ .name = "__fixunsdfti", .linkage = common.linkage }); + const fixunsdfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __fixunsdfti_windows_x86_64; + } else __fixunsdfti; + + @export(fixunsdfti_fn, .{ .name = "__fixunsdfti", .linkage = common.linkage }); } pub fn __fixunsdfti(a: f64) callconv(.C) u128 { return floatToInt(u128, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __fixunsdfti_windows_x86_64(a: f64) callconv(.C) v128 { + return @bitCast(v128, floatToInt(u128, a)); +} diff --git a/lib/compiler_rt/fixunshfti.zig b/lib/compiler_rt/fixunshfti.zig index b804c52f9613..837710ec5d2c 100644 --- a/lib/compiler_rt/fixunshfti.zig +++ b/lib/compiler_rt/fixunshfti.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const floatToInt = @import("./float_to_int.zig").floatToInt; pub const panic = common.panic; comptime { - @export(__fixunshfti, .{ .name = "__fixunshfti", .linkage = common.linkage }); + const fixunshfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __fixunshfti_windows_x86_64; + } else __fixunshfti; + + @export(fixunshfti_fn, .{ .name = "__fixunshfti", .linkage = common.linkage }); } pub fn __fixunshfti(a: f16) callconv(.C) u128 { return floatToInt(u128, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __fixunshfti_windows_x86_64(a: f16) callconv(.C) v128 { + return @bitCast(v128, floatToInt(u128, a)); +} diff --git a/lib/compiler_rt/fixunssfti.zig b/lib/compiler_rt/fixunssfti.zig index 7b1965b5abf6..8d60796e4992 100644 --- a/lib/compiler_rt/fixunssfti.zig +++ b/lib/compiler_rt/fixunssfti.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const floatToInt = @import("./float_to_int.zig").floatToInt; pub const panic = common.panic; comptime { - @export(__fixunssfti, .{ .name = "__fixunssfti", .linkage = common.linkage }); + const fixunssfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __fixunssfti_windows_x86_64; + } else __fixunssfti; + + @export(fixunssfti_fn, .{ .name = "__fixunssfti", .linkage = common.linkage }); } pub fn __fixunssfti(a: f32) callconv(.C) u128 { return floatToInt(u128, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __fixunssfti_windows_x86_64(a: f32) callconv(.C) v128 { + return @bitCast(v128, floatToInt(u128, a)); +} diff --git a/lib/compiler_rt/fixunstfti.zig b/lib/compiler_rt/fixunstfti.zig index 5e39db106527..dca837b16b78 100644 --- a/lib/compiler_rt/fixunstfti.zig +++ b/lib/compiler_rt/fixunstfti.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const floatToInt = @import("./float_to_int.zig").floatToInt; pub const panic = common.panic; comptime { - @export(__fixunstfti, .{ .name = "__fixunstfti", .linkage = common.linkage }); + const fixunstfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __fixunstfti_windows_x86_64; + } else __fixunstfti; + + @export(fixunstfti_fn, .{ .name = "__fixunstfti", .linkage = common.linkage }); } pub fn __fixunstfti(a: f128) callconv(.C) u128 { return floatToInt(u128, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __fixunstfti_windows_x86_64(a: f128) callconv(.C) v128 { + return @bitCast(v128, floatToInt(u128, a)); +} diff --git a/lib/compiler_rt/fixunsxfti.zig b/lib/compiler_rt/fixunsxfti.zig index acd41469be13..05c11ed6568e 100644 --- a/lib/compiler_rt/fixunsxfti.zig +++ b/lib/compiler_rt/fixunsxfti.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const floatToInt = @import("./float_to_int.zig").floatToInt; pub const panic = common.panic; comptime { - @export(__fixunsxfti, .{ .name = "__fixunsxfti", .linkage = common.linkage }); + const fixunsxfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __fixunsxfti_windows_x86_64; + } else __fixunsxfti; + + @export(fixunsxfti_fn, .{ .name = "__fixunsxfti", .linkage = common.linkage }); } pub fn __fixunsxfti(a: f80) callconv(.C) u128 { return floatToInt(u128, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __fixunsxfti_windows_x86_64(a: f80) callconv(.C) v128 { + return @bitCast(v128, floatToInt(u128, a)); +} diff --git a/lib/compiler_rt/fixxfti.zig b/lib/compiler_rt/fixxfti.zig index fb547f411566..bfde1d0950a1 100644 --- a/lib/compiler_rt/fixxfti.zig +++ b/lib/compiler_rt/fixxfti.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const floatToInt = @import("./float_to_int.zig").floatToInt; pub const panic = common.panic; comptime { - @export(__fixxfti, .{ .name = "__fixxfti", .linkage = common.linkage }); + const fixxfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __fixxfti_windows_x86_64; + } else __fixxfti; + + @export(fixxfti_fn, .{ .name = "__fixxfti", .linkage = common.linkage }); } -fn __fixxfti(a: f80) callconv(.C) i128 { +pub fn __fixxfti(a: f80) callconv(.C) i128 { return floatToInt(i128, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __fixxfti_windows_x86_64(a: f80) callconv(.C) v128 { + return @bitCast(v128, floatToInt(i128, a)); +} diff --git a/lib/compiler_rt/floattidf.zig b/lib/compiler_rt/floattidf.zig index 1f1ac2f2effe..4fee83fa9336 100644 --- a/lib/compiler_rt/floattidf.zig +++ b/lib/compiler_rt/floattidf.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const intToFloat = @import("./int_to_float.zig").intToFloat; pub const panic = common.panic; comptime { - @export(__floattidf, .{ .name = "__floattidf", .linkage = common.linkage }); + const floattidf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __floattidf_windows_x86_64; + } else __floattidf; + + @export(floattidf_fn, .{ .name = "__floattidf", .linkage = common.linkage }); } pub fn __floattidf(a: i128) callconv(.C) f64 { return intToFloat(f64, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __floattidf_windows_x86_64(a: v128) callconv(.C) f64 { + return intToFloat(f64, @bitCast(i128, a)); +} diff --git a/lib/compiler_rt/floattihf.zig b/lib/compiler_rt/floattihf.zig index c7e45c7d5371..0da48a7a5784 100644 --- a/lib/compiler_rt/floattihf.zig +++ b/lib/compiler_rt/floattihf.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const intToFloat = @import("./int_to_float.zig").intToFloat; pub const panic = common.panic; comptime { - @export(__floattihf, .{ .name = "__floattihf", .linkage = common.linkage }); + const floattihf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __floattihf_windows_x86_64; + } else __floattihf; + + @export(floattihf_fn, .{ .name = "__floattihf", .linkage = common.linkage }); } -fn __floattihf(a: i128) callconv(.C) f16 { +pub fn __floattihf(a: i128) callconv(.C) f16 { return intToFloat(f16, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __floattihf_windows_x86_64(a: v128) callconv(.C) f16 { + return intToFloat(f16, @bitCast(i128, a)); +} diff --git a/lib/compiler_rt/floattisf.zig b/lib/compiler_rt/floattisf.zig index 5eb493d09b02..e619d671cea2 100644 --- a/lib/compiler_rt/floattisf.zig +++ b/lib/compiler_rt/floattisf.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const intToFloat = @import("./int_to_float.zig").intToFloat; pub const panic = common.panic; comptime { - @export(__floattisf, .{ .name = "__floattisf", .linkage = common.linkage }); + const floattisf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __floattisf_windows_x86_64; + } else __floattisf; + + @export(floattisf_fn, .{ .name = "__floattisf", .linkage = common.linkage }); } pub fn __floattisf(a: i128) callconv(.C) f32 { return intToFloat(f32, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __floattisf_windows_x86_64(a: v128) callconv(.C) f32 { + return intToFloat(f32, @bitCast(i128, a)); +} diff --git a/lib/compiler_rt/floattitf.zig b/lib/compiler_rt/floattitf.zig index 0764c2d2c2b2..2496d39df6bb 100644 --- a/lib/compiler_rt/floattitf.zig +++ b/lib/compiler_rt/floattitf.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const intToFloat = @import("./int_to_float.zig").intToFloat; pub const panic = common.panic; comptime { - @export(__floattitf, .{ .name = "__floattitf", .linkage = common.linkage }); + const floattitf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __floattitf_windows_x86_64; + } else __floattitf; + + @export(floattitf_fn, .{ .name = "__floattitf", .linkage = common.linkage }); } pub fn __floattitf(a: i128) callconv(.C) f128 { return intToFloat(f128, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __floattitf_windows_x86_64(a: v128) callconv(.C) f128 { + return intToFloat(f128, @bitCast(i128, a)); +} diff --git a/lib/compiler_rt/floattixf.zig b/lib/compiler_rt/floattixf.zig index def9bef4d5e0..afcb59582f2f 100644 --- a/lib/compiler_rt/floattixf.zig +++ b/lib/compiler_rt/floattixf.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const intToFloat = @import("./int_to_float.zig").intToFloat; pub const panic = common.panic; comptime { - @export(__floattixf, .{ .name = "__floattixf", .linkage = common.linkage }); + const floattixf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __floattixf_windows_x86_64; + } else __floattixf; + + @export(floattixf_fn, .{ .name = "__floattixf", .linkage = common.linkage }); } -fn __floattixf(a: i128) callconv(.C) f80 { +pub fn __floattixf(a: i128) callconv(.C) f80 { return intToFloat(f80, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __floattixf_windows_x86_64(a: v128) callconv(.C) f80 { + return intToFloat(f80, @bitCast(i128, a)); +} diff --git a/lib/compiler_rt/floatuntidf.zig b/lib/compiler_rt/floatuntidf.zig index a77a952fe914..75bad71386fe 100644 --- a/lib/compiler_rt/floatuntidf.zig +++ b/lib/compiler_rt/floatuntidf.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const intToFloat = @import("./int_to_float.zig").intToFloat; pub const panic = common.panic; comptime { - @export(__floatuntidf, .{ .name = "__floatuntidf", .linkage = common.linkage }); + const floatuntidf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __floatuntidf_windows_x86_64; + } else __floatuntidf; + + @export(floatuntidf_fn, .{ .name = "__floatuntidf", .linkage = common.linkage }); } pub fn __floatuntidf(a: u128) callconv(.C) f64 { return intToFloat(f64, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __floatuntidf_windows_x86_64(a: v128) callconv(.C) f64 { + return intToFloat(f64, @bitCast(u128, a)); +} diff --git a/lib/compiler_rt/floatuntihf.zig b/lib/compiler_rt/floatuntihf.zig index 0263b1da98bc..ae952212259c 100644 --- a/lib/compiler_rt/floatuntihf.zig +++ b/lib/compiler_rt/floatuntihf.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const intToFloat = @import("./int_to_float.zig").intToFloat; pub const panic = common.panic; comptime { - @export(__floatuntihf, .{ .name = "__floatuntihf", .linkage = common.linkage }); + const floatuntihf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __floatuntihf_windows_x86_64; + } else __floatuntihf; + + @export(floatuntihf_fn, .{ .name = "__floatuntihf", .linkage = common.linkage }); } -fn __floatuntihf(a: u128) callconv(.C) f16 { +pub fn __floatuntihf(a: u128) callconv(.C) f16 { return intToFloat(f16, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __floatuntihf_windows_x86_64(a: v128) callconv(.C) f16 { + return intToFloat(f16, @bitCast(u128, a)); +} diff --git a/lib/compiler_rt/floatuntisf.zig b/lib/compiler_rt/floatuntisf.zig index 3edf63698748..5b41ea30983b 100644 --- a/lib/compiler_rt/floatuntisf.zig +++ b/lib/compiler_rt/floatuntisf.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const intToFloat = @import("./int_to_float.zig").intToFloat; pub const panic = common.panic; comptime { - @export(__floatuntisf, .{ .name = "__floatuntisf", .linkage = common.linkage }); + const floatuntisf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __floatuntisf_windows_x86_64; + } else __floatuntisf; + + @export(floatuntisf_fn, .{ .name = "__floatuntisf", .linkage = common.linkage }); } pub fn __floatuntisf(a: u128) callconv(.C) f32 { return intToFloat(f32, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __floatuntisf_windows_x86_64(a: v128) callconv(.C) f32 { + return intToFloat(f32, @bitCast(u128, a)); +} diff --git a/lib/compiler_rt/floatuntitf.zig b/lib/compiler_rt/floatuntitf.zig index 1a755cccdb3b..1e73831f2d8c 100644 --- a/lib/compiler_rt/floatuntitf.zig +++ b/lib/compiler_rt/floatuntitf.zig @@ -1,20 +1,28 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const intToFloat = @import("./int_to_float.zig").intToFloat; pub const panic = common.panic; comptime { - if (common.want_ppc_abi) { - @export(__floatuntikf, .{ .name = "__floatuntikf", .linkage = common.linkage }); - } else { - @export(__floatuntitf, .{ .name = "__floatuntitf", .linkage = common.linkage }); - } + const symbol_name = if (common.want_ppc_abi) "__floatuntikf" else "__floatuntitf"; + + const floatuntitf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __floatuntitf_windows_x86_64; + } else __floatuntitf; + + @export(floatuntitf_fn, .{ .name = symbol_name, .linkage = common.linkage }); } pub fn __floatuntitf(a: u128) callconv(.C) f128 { return intToFloat(f128, a); } -fn __floatuntikf(a: u128) callconv(.C) f128 { - return intToFloat(f128, a); +const v128 = @import("std").meta.Vector(2, u64); + +fn __floatuntitf_windows_x86_64(a: v128) callconv(.C) f128 { + return intToFloat(f128, @bitCast(u128, a)); } diff --git a/lib/compiler_rt/floatuntixf.zig b/lib/compiler_rt/floatuntixf.zig index 07017d1f5738..26fd257c5c23 100644 --- a/lib/compiler_rt/floatuntixf.zig +++ b/lib/compiler_rt/floatuntixf.zig @@ -1,12 +1,26 @@ +const builtin = @import("builtin"); +const arch = builtin.cpu.arch; const common = @import("./common.zig"); const intToFloat = @import("./int_to_float.zig").intToFloat; pub const panic = common.panic; comptime { - @export(__floatuntixf, .{ .name = "__floatuntixf", .linkage = common.linkage }); + const floatuntixf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: { + // The "ti" functions must use Vector(2, u64) return types to adhere to the ABI + // that LLVM expects compiler-rt to have. + break :b __floatuntixf_windows_x86_64; + } else __floatuntixf; + + @export(floatuntixf_fn, .{ .name = "__floatuntixf", .linkage = common.linkage }); } pub fn __floatuntixf(a: u128) callconv(.C) f80 { return intToFloat(f80, a); } + +const v128 = @import("std").meta.Vector(2, u64); + +fn __floatuntixf_windows_x86_64(a: v128) callconv(.C) f80 { + return intToFloat(f80, @bitCast(u128, a)); +} diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index 90e70a7c4163..f6b98be44dbc 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -2284,10 +2284,6 @@ test "float.hexadecimal.precision" { } test "float.decimal" { - if (builtin.zig_backend == .stage1 and builtin.os.tag == .windows) { - // https://github.com/ziglang/zig/issues/12063 - return error.SkipZigTest; - } try expectFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)}); try expectFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)}); try expectFmt("f32: 0", "f32: {d:.0}", .{@as(f32, 0.0)}); @@ -2311,10 +2307,6 @@ test "float.decimal" { } test "float.libc.sanity" { - if (builtin.zig_backend == .stage1 and builtin.os.tag == .windows) { - // https://github.com/ziglang/zig/issues/12063 - return error.SkipZigTest; - } try expectFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 916964781)))}); try expectFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 925353389)))}); try expectFmt("f64: 0.10000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1036831278)))});