| author | |
| committer | |
| log | 76c89a3de9661264395d111fa3db8d4cfa633f83 |
| tree | 62d4c9456e5caae29dc59c792371f3e1d4e04a3f |
| parent | f3333a56e8452c16ad30da99f8e4a62a16e58a03 |
| parent | 2b5215436c47e7546cbe5000345cd81fc45019b8 |
| signature |
compiler_rt: Update Windows ABI for float<->int conversion routines30 files changed, 334 insertions(+), 207 deletions(-)
lib/compiler_rt/common.zig+4| ... | @@ -17,6 +17,10 @@ pub const want_aeabi = switch (builtin.abi) { | ... | @@ -17,6 +17,10 @@ pub const want_aeabi = switch (builtin.abi) { |
| 17 | }; | 17 | }; |
| 18 | pub const want_ppc_abi = builtin.cpu.arch.isPPC() or builtin.cpu.arch.isPPC64(); | 18 | pub const want_ppc_abi = builtin.cpu.arch.isPPC() or builtin.cpu.arch.isPPC64(); |
| 19 | 19 | ||
| 20 | // Libcalls that involve u128 on Windows x86-64 are expected by LLVM to use the | ||
| 21 | // calling convention of @Vector(2, u64), rather than what's standard. | ||
| 22 | pub const want_windows_v2u64_abi = builtin.os.tag == .windows and builtin.cpu.arch == .x86_64; | ||
| 23 | |||
| 20 | /// This governs whether to use these symbol names for f16/f32 conversions | 24 | /// This governs whether to use these symbol names for f16/f32 conversions |
| 21 | /// rather than the standard names: | 25 | /// rather than the standard names: |
| 22 | /// * __gnu_f2h_ieee | 26 | /// * __gnu_f2h_ieee |
lib/compiler_rt/fixdfti.zig+12-1| ... | @@ -1,12 +1,23 @@ | ... | @@ -1,12 +1,23 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const floatToInt = @import("./float_to_int.zig").floatToInt; | 3 | const floatToInt = @import("./float_to_int.zig").floatToInt; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__fixdfti, .{ .name = "__fixdfti", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__fixdfti_windows_x86_64, .{ .name = "__fixdfti", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__fixdfti, .{ .name = "__fixdfti", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __fixdfti(a: f64) callconv(.C) i128 { | 15 | pub fn __fixdfti(a: f64) callconv(.C) i128 { |
| 11 | return floatToInt(i128, a); | 16 | return floatToInt(i128, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | const v2u64 = @Vector(2, u64); | ||
| 20 | |||
| 21 | fn __fixdfti_windows_x86_64(a: f64) callconv(.C) v2u64 { | ||
| 22 | return @bitCast(v2u64, floatToInt(i128, a)); | ||
| 23 | } |
lib/compiler_rt/fixhfti.zig+13-2| ... | @@ -1,12 +1,23 @@ | ... | @@ -1,12 +1,23 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const floatToInt = @import("./float_to_int.zig").floatToInt; | 3 | const floatToInt = @import("./float_to_int.zig").floatToInt; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__fixhfti, .{ .name = "__fixhfti", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__fixhfti_windows_x86_64, .{ .name = "__fixhfti", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__fixhfti, .{ .name = "__fixhfti", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | fn __fixhfti(a: f16) callconv(.C) i128 { | 15 | pub fn __fixhfti(a: f16) callconv(.C) i128 { |
| 11 | return floatToInt(i128, a); | 16 | return floatToInt(i128, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | const v2u64 = @Vector(2, u64); | ||
| 20 | |||
| 21 | fn __fixhfti_windows_x86_64(a: f16) callconv(.C) v2u64 { | ||
| 22 | return @bitCast(v2u64, floatToInt(i128, a)); | ||
| 23 | } |
lib/compiler_rt/fixsfti.zig+12-1| ... | @@ -1,12 +1,23 @@ | ... | @@ -1,12 +1,23 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const floatToInt = @import("./float_to_int.zig").floatToInt; | 3 | const floatToInt = @import("./float_to_int.zig").floatToInt; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__fixsfti, .{ .name = "__fixsfti", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__fixsfti_windows_x86_64, .{ .name = "__fixsfti", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__fixsfti, .{ .name = "__fixsfti", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __fixsfti(a: f32) callconv(.C) i128 { | 15 | pub fn __fixsfti(a: f32) callconv(.C) i128 { |
| 11 | return floatToInt(i128, a); | 16 | return floatToInt(i128, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | const v2u64 = @Vector(2, u64); | ||
| 20 | |||
| 21 | fn __fixsfti_windows_x86_64(a: f32) callconv(.C) v2u64 { | ||
| 22 | return @bitCast(v2u64, floatToInt(i128, a)); | ||
| 23 | } |
lib/compiler_rt/fixtfti.zig+12-1| ... | @@ -1,12 +1,23 @@ | ... | @@ -1,12 +1,23 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const floatToInt = @import("./float_to_int.zig").floatToInt; | 3 | const floatToInt = @import("./float_to_int.zig").floatToInt; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__fixtfti, .{ .name = "__fixtfti", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__fixtfti_windows_x86_64, .{ .name = "__fixtfti", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__fixtfti, .{ .name = "__fixtfti", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __fixtfti(a: f128) callconv(.C) i128 { | 15 | pub fn __fixtfti(a: f128) callconv(.C) i128 { |
| 11 | return floatToInt(i128, a); | 16 | return floatToInt(i128, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | const v2u64 = @Vector(2, u64); | ||
| 20 | |||
| 21 | fn __fixtfti_windows_x86_64(a: f128) callconv(.C) v2u64 { | ||
| 22 | return @bitCast(v2u64, floatToInt(i128, a)); | ||
| 23 | } |
lib/compiler_rt/fixunsdfti.zig+12-1| ... | @@ -1,12 +1,23 @@ | ... | @@ -1,12 +1,23 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const floatToInt = @import("./float_to_int.zig").floatToInt; | 3 | const floatToInt = @import("./float_to_int.zig").floatToInt; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__fixunsdfti, .{ .name = "__fixunsdfti", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__fixunsdfti_windows_x86_64, .{ .name = "__fixunsdfti", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__fixunsdfti, .{ .name = "__fixunsdfti", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __fixunsdfti(a: f64) callconv(.C) u128 { | 15 | pub fn __fixunsdfti(a: f64) callconv(.C) u128 { |
| 11 | return floatToInt(u128, a); | 16 | return floatToInt(u128, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | const v2u64 = @Vector(2, u64); | ||
| 20 | |||
| 21 | fn __fixunsdfti_windows_x86_64(a: f64) callconv(.C) v2u64 { | ||
| 22 | return @bitCast(v2u64, floatToInt(u128, a)); | ||
| 23 | } |
lib/compiler_rt/fixunshfti.zig+12-1| ... | @@ -1,12 +1,23 @@ | ... | @@ -1,12 +1,23 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const floatToInt = @import("./float_to_int.zig").floatToInt; | 3 | const floatToInt = @import("./float_to_int.zig").floatToInt; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__fixunshfti, .{ .name = "__fixunshfti", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__fixunshfti_windows_x86_64, .{ .name = "__fixunshfti", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__fixunshfti, .{ .name = "__fixunshfti", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __fixunshfti(a: f16) callconv(.C) u128 { | 15 | pub fn __fixunshfti(a: f16) callconv(.C) u128 { |
| 11 | return floatToInt(u128, a); | 16 | return floatToInt(u128, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | const v2u64 = @import("std").meta.Vector(2, u64); | ||
| 20 | |||
| 21 | fn __fixunshfti_windows_x86_64(a: f16) callconv(.C) v2u64 { | ||
| 22 | return @bitCast(v2u64, floatToInt(u128, a)); | ||
| 23 | } |
lib/compiler_rt/fixunssfti.zig+12-1| ... | @@ -1,12 +1,23 @@ | ... | @@ -1,12 +1,23 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const floatToInt = @import("./float_to_int.zig").floatToInt; | 3 | const floatToInt = @import("./float_to_int.zig").floatToInt; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__fixunssfti, .{ .name = "__fixunssfti", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__fixunssfti_windows_x86_64, .{ .name = "__fixunssfti", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__fixunssfti, .{ .name = "__fixunssfti", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __fixunssfti(a: f32) callconv(.C) u128 { | 15 | pub fn __fixunssfti(a: f32) callconv(.C) u128 { |
| 11 | return floatToInt(u128, a); | 16 | return floatToInt(u128, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | const v2u64 = @Vector(2, u64); | ||
| 20 | |||
| 21 | fn __fixunssfti_windows_x86_64(a: f32) callconv(.C) v2u64 { | ||
| 22 | return @bitCast(v2u64, floatToInt(u128, a)); | ||
| 23 | } |
lib/compiler_rt/fixunstfti.zig+12-1| ... | @@ -1,12 +1,23 @@ | ... | @@ -1,12 +1,23 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const floatToInt = @import("./float_to_int.zig").floatToInt; | 3 | const floatToInt = @import("./float_to_int.zig").floatToInt; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__fixunstfti, .{ .name = "__fixunstfti", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__fixunstfti_windows_x86_64, .{ .name = "__fixunstfti", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__fixunstfti, .{ .name = "__fixunstfti", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __fixunstfti(a: f128) callconv(.C) u128 { | 15 | pub fn __fixunstfti(a: f128) callconv(.C) u128 { |
| 11 | return floatToInt(u128, a); | 16 | return floatToInt(u128, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | const v2u64 = @Vector(2, u64); | ||
| 20 | |||
| 21 | fn __fixunstfti_windows_x86_64(a: f128) callconv(.C) v2u64 { | ||
| 22 | return @bitCast(v2u64, floatToInt(u128, a)); | ||
| 23 | } |
lib/compiler_rt/fixunsxfti.zig+12-1| ... | @@ -1,12 +1,23 @@ | ... | @@ -1,12 +1,23 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const floatToInt = @import("./float_to_int.zig").floatToInt; | 3 | const floatToInt = @import("./float_to_int.zig").floatToInt; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__fixunsxfti, .{ .name = "__fixunsxfti", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__fixunsxfti_windows_x86_64, .{ .name = "__fixunsxfti", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__fixunsxfti, .{ .name = "__fixunsxfti", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __fixunsxfti(a: f80) callconv(.C) u128 { | 15 | pub fn __fixunsxfti(a: f80) callconv(.C) u128 { |
| 11 | return floatToInt(u128, a); | 16 | return floatToInt(u128, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | const v2u64 = @Vector(2, u64); | ||
| 20 | |||
| 21 | fn __fixunsxfti_windows_x86_64(a: f80) callconv(.C) v2u64 { | ||
| 22 | return @bitCast(v2u64, floatToInt(u128, a)); | ||
| 23 | } |
lib/compiler_rt/fixxfti.zig+13-2| ... | @@ -1,12 +1,23 @@ | ... | @@ -1,12 +1,23 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const floatToInt = @import("./float_to_int.zig").floatToInt; | 3 | const floatToInt = @import("./float_to_int.zig").floatToInt; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__fixxfti, .{ .name = "__fixxfti", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__fixxfti_windows_x86_64, .{ .name = "__fixxfti", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__fixxfti, .{ .name = "__fixxfti", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | fn __fixxfti(a: f80) callconv(.C) i128 { | 15 | pub fn __fixxfti(a: f80) callconv(.C) i128 { |
| 11 | return floatToInt(i128, a); | 16 | return floatToInt(i128, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | const v2u64 = @Vector(2, u64); | ||
| 20 | |||
| 21 | fn __fixxfti_windows_x86_64(a: f80) callconv(.C) v2u64 { | ||
| 22 | return @bitCast(v2u64, floatToInt(i128, a)); | ||
| 23 | } |
lib/compiler_rt/floattidf.zig+10-1| ... | @@ -1,12 +1,21 @@ | ... | @@ -1,12 +1,21 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const intToFloat = @import("./int_to_float.zig").intToFloat; | 3 | const intToFloat = @import("./int_to_float.zig").intToFloat; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__floattidf, .{ .name = "__floattidf", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__floattidf_windows_x86_64, .{ .name = "__floattidf", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__floattidf, .{ .name = "__floattidf", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __floattidf(a: i128) callconv(.C) f64 { | 15 | pub fn __floattidf(a: i128) callconv(.C) f64 { |
| 11 | return intToFloat(f64, a); | 16 | return intToFloat(f64, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | fn __floattidf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f64 { | ||
| 20 | return intToFloat(f64, @bitCast(i128, a)); | ||
| 21 | } |
lib/compiler_rt/floattihf.zig+11-2| ... | @@ -1,12 +1,21 @@ | ... | @@ -1,12 +1,21 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const intToFloat = @import("./int_to_float.zig").intToFloat; | 3 | const intToFloat = @import("./int_to_float.zig").intToFloat; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__floattihf, .{ .name = "__floattihf", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__floattihf_windows_x86_64, .{ .name = "__floattihf", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__floattihf, .{ .name = "__floattihf", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | fn __floattihf(a: i128) callconv(.C) f16 { | 15 | pub fn __floattihf(a: i128) callconv(.C) f16 { |
| 11 | return intToFloat(f16, a); | 16 | return intToFloat(f16, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | fn __floattihf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f16 { | ||
| 20 | return intToFloat(f16, @bitCast(i128, a)); | ||
| 21 | } |
lib/compiler_rt/floattisf.zig+10-1| ... | @@ -1,12 +1,21 @@ | ... | @@ -1,12 +1,21 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const intToFloat = @import("./int_to_float.zig").intToFloat; | 3 | const intToFloat = @import("./int_to_float.zig").intToFloat; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__floattisf, .{ .name = "__floattisf", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__floattisf_windows_x86_64, .{ .name = "__floattisf", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__floattisf, .{ .name = "__floattisf", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __floattisf(a: i128) callconv(.C) f32 { | 15 | pub fn __floattisf(a: i128) callconv(.C) f32 { |
| 11 | return intToFloat(f32, a); | 16 | return intToFloat(f32, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | fn __floattisf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f32 { | ||
| 20 | return intToFloat(f32, @bitCast(i128, a)); | ||
| 21 | } |
lib/compiler_rt/floattitf.zig+10-1| ... | @@ -1,12 +1,21 @@ | ... | @@ -1,12 +1,21 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const intToFloat = @import("./int_to_float.zig").intToFloat; | 3 | const intToFloat = @import("./int_to_float.zig").intToFloat; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__floattitf, .{ .name = "__floattitf", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__floattitf_windows_x86_64, .{ .name = "__floattitf", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__floattitf, .{ .name = "__floattitf", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __floattitf(a: i128) callconv(.C) f128 { | 15 | pub fn __floattitf(a: i128) callconv(.C) f128 { |
| 11 | return intToFloat(f128, a); | 16 | return intToFloat(f128, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | fn __floattitf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f128 { | ||
| 20 | return intToFloat(f128, @bitCast(i128, a)); | ||
| 21 | } |
lib/compiler_rt/floattixf.zig+11-2| ... | @@ -1,12 +1,21 @@ | ... | @@ -1,12 +1,21 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const intToFloat = @import("./int_to_float.zig").intToFloat; | 3 | const intToFloat = @import("./int_to_float.zig").intToFloat; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__floattixf, .{ .name = "__floattixf", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__floattixf_windows_x86_64, .{ .name = "__floattixf", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__floattixf, .{ .name = "__floattixf", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | fn __floattixf(a: i128) callconv(.C) f80 { | 15 | pub fn __floattixf(a: i128) callconv(.C) f80 { |
| 11 | return intToFloat(f80, a); | 16 | return intToFloat(f80, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | fn __floattixf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f80 { | ||
| 20 | return intToFloat(f80, @bitCast(i128, a)); | ||
| 21 | } |
lib/compiler_rt/floatuntidf.zig+10-1| ... | @@ -1,12 +1,21 @@ | ... | @@ -1,12 +1,21 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const intToFloat = @import("./int_to_float.zig").intToFloat; | 3 | const intToFloat = @import("./int_to_float.zig").intToFloat; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__floatuntidf, .{ .name = "__floatuntidf", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__floatuntidf_windows_x86_64, .{ .name = "__floatuntidf", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__floatuntidf, .{ .name = "__floatuntidf", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __floatuntidf(a: u128) callconv(.C) f64 { | 15 | pub fn __floatuntidf(a: u128) callconv(.C) f64 { |
| 11 | return intToFloat(f64, a); | 16 | return intToFloat(f64, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | fn __floatuntidf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f64 { | ||
| 20 | return intToFloat(f64, @bitCast(u128, a)); | ||
| 21 | } |
lib/compiler_rt/floatuntihf.zig+11-2| ... | @@ -1,12 +1,21 @@ | ... | @@ -1,12 +1,21 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const intToFloat = @import("./int_to_float.zig").intToFloat; | 3 | const intToFloat = @import("./int_to_float.zig").intToFloat; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__floatuntihf, .{ .name = "__floatuntihf", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__floatuntihf_windows_x86_64, .{ .name = "__floatuntihf", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__floatuntihf, .{ .name = "__floatuntihf", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | fn __floatuntihf(a: u128) callconv(.C) f16 { | 15 | pub fn __floatuntihf(a: u128) callconv(.C) f16 { |
| 11 | return intToFloat(f16, a); | 16 | return intToFloat(f16, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | fn __floatuntihf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f16 { | ||
| 20 | return intToFloat(f16, @bitCast(u128, a)); | ||
| 21 | } |
lib/compiler_rt/floatuntisf.zig+10-1| ... | @@ -1,12 +1,21 @@ | ... | @@ -1,12 +1,21 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const intToFloat = @import("./int_to_float.zig").intToFloat; | 3 | const intToFloat = @import("./int_to_float.zig").intToFloat; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__floatuntisf, .{ .name = "__floatuntisf", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__floatuntisf_windows_x86_64, .{ .name = "__floatuntisf", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__floatuntisf, .{ .name = "__floatuntisf", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __floatuntisf(a: u128) callconv(.C) f32 { | 15 | pub fn __floatuntisf(a: u128) callconv(.C) f32 { |
| 11 | return intToFloat(f32, a); | 16 | return intToFloat(f32, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | fn __floatuntisf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f32 { | ||
| 20 | return intToFloat(f32, @bitCast(u128, a)); | ||
| 21 | } |
lib/compiler_rt/floatuntitf.zig+8-5| ... | @@ -1,13 +1,16 @@ | ... | @@ -1,13 +1,16 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const intToFloat = @import("./int_to_float.zig").intToFloat; | 3 | const intToFloat = @import("./int_to_float.zig").intToFloat; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | if (common.want_ppc_abi) { | 8 | const symbol_name = if (common.want_ppc_abi) "__floatuntikf" else "__floatuntitf"; |
| 8 | @export(__floatuntikf, .{ .name = "__floatuntikf", .linkage = common.linkage }); | 9 | |
| 10 | if (common.want_windows_v2u64_abi) { | ||
| 11 | @export(__floatuntitf_windows_x86_64, .{ .name = symbol_name, .linkage = common.linkage }); | ||
| 9 | } else { | 12 | } else { |
| 10 | @export(__floatuntitf, .{ .name = "__floatuntitf", .linkage = common.linkage }); | 13 | @export(__floatuntitf, .{ .name = symbol_name, .linkage = common.linkage }); |
| 11 | } | 14 | } |
| 12 | } | 15 | } |
| 13 | 16 | ||
| ... | @@ -15,6 +18,6 @@ pub fn __floatuntitf(a: u128) callconv(.C) f128 { | ... | @@ -15,6 +18,6 @@ pub fn __floatuntitf(a: u128) callconv(.C) f128 { |
| 15 | return intToFloat(f128, a); | 18 | return intToFloat(f128, a); |
| 16 | } | 19 | } |
| 17 | 20 | ||
| 18 | fn __floatuntikf(a: u128) callconv(.C) f128 { | 21 | fn __floatuntitf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f128 { |
| 19 | return intToFloat(f128, a); | 22 | return intToFloat(f128, @bitCast(u128, a)); |
| 20 | } | 23 | } |
lib/compiler_rt/floatuntixf.zig+10-1| ... | @@ -1,12 +1,21 @@ | ... | @@ -1,12 +1,21 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 1 | const common = @import("./common.zig"); | 2 | const common = @import("./common.zig"); |
| 2 | const intToFloat = @import("./int_to_float.zig").intToFloat; | 3 | const intToFloat = @import("./int_to_float.zig").intToFloat; |
| 3 | 4 | ||
| 4 | pub const panic = common.panic; | 5 | pub const panic = common.panic; |
| 5 | 6 | ||
| 6 | comptime { | 7 | comptime { |
| 7 | @export(__floatuntixf, .{ .name = "__floatuntixf", .linkage = common.linkage }); | 8 | if (common.want_windows_v2u64_abi) { |
| 9 | @export(__floatuntixf_windows_x86_64, .{ .name = "__floatuntixf", .linkage = common.linkage }); | ||
| 10 | } else { | ||
| 11 | @export(__floatuntixf, .{ .name = "__floatuntixf", .linkage = common.linkage }); | ||
| 12 | } | ||
| 8 | } | 13 | } |
| 9 | 14 | ||
| 10 | pub fn __floatuntixf(a: u128) callconv(.C) f80 { | 15 | pub fn __floatuntixf(a: u128) callconv(.C) f80 { |
| 11 | return intToFloat(f80, a); | 16 | return intToFloat(f80, a); |
| 12 | } | 17 | } |
| 18 | |||
| 19 | fn __floatuntixf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f80 { | ||
| 20 | return intToFloat(f80, @bitCast(u128, a)); | ||
| 21 | } |
lib/compiler_rt/modti3.zig+5-19| ... | @@ -5,27 +5,13 @@ | ... | @@ -5,27 +5,13 @@ |
| 5 | const std = @import("std"); | 5 | const std = @import("std"); |
| 6 | const builtin = @import("builtin"); | 6 | const builtin = @import("builtin"); |
| 7 | const udivmod = @import("udivmod.zig").udivmod; | 7 | const udivmod = @import("udivmod.zig").udivmod; |
| 8 | const arch = builtin.cpu.arch; | ||
| 9 | const common = @import("common.zig"); | 8 | const common = @import("common.zig"); |
| 10 | 9 | ||
| 11 | pub const panic = common.panic; | 10 | pub const panic = common.panic; |
| 12 | 11 | ||
| 13 | comptime { | 12 | comptime { |
| 14 | if (builtin.os.tag == .windows) { | 13 | if (common.want_windows_v2u64_abi) { |
| 15 | switch (arch) { | 14 | @export(__modti3_windows_x86_64, .{ .name = "__modti3", .linkage = common.linkage }); |
| 16 | .i386 => { | ||
| 17 | @export(__modti3, .{ .name = "__modti3", .linkage = common.linkage }); | ||
| 18 | }, | ||
| 19 | .x86_64 => { | ||
| 20 | // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI | ||
| 21 | // that LLVM expects compiler-rt to have. | ||
| 22 | @export(__modti3_windows_x86_64, .{ .name = "__modti3", .linkage = common.linkage }); | ||
| 23 | }, | ||
| 24 | else => {}, | ||
| 25 | } | ||
| 26 | if (arch.isAARCH64()) { | ||
| 27 | @export(__modti3, .{ .name = "__modti3", .linkage = common.linkage }); | ||
| 28 | } | ||
| 29 | } else { | 15 | } else { |
| 30 | @export(__modti3, .{ .name = "__modti3", .linkage = common.linkage }); | 16 | @export(__modti3, .{ .name = "__modti3", .linkage = common.linkage }); |
| 31 | } | 17 | } |
| ... | @@ -35,10 +21,10 @@ pub fn __modti3(a: i128, b: i128) callconv(.C) i128 { | ... | @@ -35,10 +21,10 @@ pub fn __modti3(a: i128, b: i128) callconv(.C) i128 { |
| 35 | return mod(a, b); | 21 | return mod(a, b); |
| 36 | } | 22 | } |
| 37 | 23 | ||
| 38 | const v128 = @import("std").meta.Vector(2, u64); | 24 | const v2u64 = @Vector(2, u64); |
| 39 | 25 | ||
| 40 | fn __modti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 { | 26 | fn __modti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 { |
| 41 | return @bitCast(v128, mod(@bitCast(i128, a), @bitCast(i128, b))); | 27 | return @bitCast(v2u64, mod(@bitCast(i128, a), @bitCast(i128, b))); |
| 42 | } | 28 | } |
| 43 | 29 | ||
| 44 | inline fn mod(a: i128, b: i128) i128 { | 30 | inline fn mod(a: i128, b: i128) i128 { |
lib/compiler_rt/multi3.zig+5-16| ... | @@ -4,25 +4,14 @@ | ... | @@ -4,25 +4,14 @@ |
| 4 | 4 | ||
| 5 | const std = @import("std"); | 5 | const std = @import("std"); |
| 6 | const builtin = @import("builtin"); | 6 | const builtin = @import("builtin"); |
| 7 | const arch = builtin.cpu.arch; | ||
| 8 | const native_endian = builtin.cpu.arch.endian(); | 7 | const native_endian = builtin.cpu.arch.endian(); |
| 9 | const common = @import("common.zig"); | 8 | const common = @import("common.zig"); |
| 10 | 9 | ||
| 11 | pub const panic = common.panic; | 10 | pub const panic = common.panic; |
| 12 | 11 | ||
| 13 | comptime { | 12 | comptime { |
| 14 | if (builtin.os.tag == .windows) { | 13 | if (common.want_windows_v2u64_abi) { |
| 15 | switch (arch) { | 14 | @export(__multi3_windows_x86_64, .{ .name = "__multi3", .linkage = common.linkage }); |
| 16 | .i386 => { | ||
| 17 | @export(__multi3, .{ .name = "__multi3", .linkage = common.linkage }); | ||
| 18 | }, | ||
| 19 | .x86_64 => { | ||
| 20 | // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI | ||
| 21 | // that LLVM expects compiler-rt to have. | ||
| 22 | @export(__multi3_windows_x86_64, .{ .name = "__multi3", .linkage = common.linkage }); | ||
| 23 | }, | ||
| 24 | else => {}, | ||
| 25 | } | ||
| 26 | } else { | 15 | } else { |
| 27 | @export(__multi3, .{ .name = "__multi3", .linkage = common.linkage }); | 16 | @export(__multi3, .{ .name = "__multi3", .linkage = common.linkage }); |
| 28 | } | 17 | } |
| ... | @@ -32,10 +21,10 @@ pub fn __multi3(a: i128, b: i128) callconv(.C) i128 { | ... | @@ -32,10 +21,10 @@ pub fn __multi3(a: i128, b: i128) callconv(.C) i128 { |
| 32 | return mul(a, b); | 21 | return mul(a, b); |
| 33 | } | 22 | } |
| 34 | 23 | ||
| 35 | const v128 = @Vector(2, u64); | 24 | const v2u64 = @Vector(2, u64); |
| 36 | 25 | ||
| 37 | fn __multi3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 { | 26 | fn __multi3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 { |
| 38 | return @bitCast(v128, mul(@bitCast(i128, a), @bitCast(i128, b))); | 27 | return @bitCast(v2u64, mul(@bitCast(i128, a), @bitCast(i128, b))); |
| 39 | } | 28 | } |
| 40 | 29 | ||
| 41 | inline fn mul(a: i128, b: i128) i128 { | 30 | inline fn mul(a: i128, b: i128) i128 { |
lib/compiler_rt/udivmodti4.zig+5-16| ... | @@ -1,24 +1,13 @@ | ... | @@ -1,24 +1,13 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const udivmod = @import("udivmod.zig").udivmod; | 3 | const udivmod = @import("udivmod.zig").udivmod; |
| 4 | const arch = builtin.cpu.arch; | ||
| 5 | const common = @import("common.zig"); | 4 | const common = @import("common.zig"); |
| 6 | 5 | ||
| 7 | pub const panic = common.panic; | 6 | pub const panic = common.panic; |
| 8 | 7 | ||
| 9 | comptime { | 8 | comptime { |
| 10 | if (builtin.os.tag == .windows) { | 9 | if (common.want_windows_v2u64_abi) { |
| 11 | switch (arch) { | 10 | @export(__udivmodti4_windows_x86_64, .{ .name = "__udivmodti4", .linkage = common.linkage }); |
| 12 | .i386 => { | ||
| 13 | @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = common.linkage }); | ||
| 14 | }, | ||
| 15 | .x86_64 => { | ||
| 16 | // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI | ||
| 17 | // that LLVM expects compiler-rt to have. | ||
| 18 | @export(__udivmodti4_windows_x86_64, .{ .name = "__udivmodti4", .linkage = common.linkage }); | ||
| 19 | }, | ||
| 20 | else => {}, | ||
| 21 | } | ||
| 22 | } else { | 11 | } else { |
| 23 | @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = common.linkage }); | 12 | @export(__udivmodti4, .{ .name = "__udivmodti4", .linkage = common.linkage }); |
| 24 | } | 13 | } |
| ... | @@ -28,10 +17,10 @@ pub fn __udivmodti4(a: u128, b: u128, maybe_rem: ?*u128) callconv(.C) u128 { | ... | @@ -28,10 +17,10 @@ pub fn __udivmodti4(a: u128, b: u128, maybe_rem: ?*u128) callconv(.C) u128 { |
| 28 | return udivmod(u128, a, b, maybe_rem); | 17 | return udivmod(u128, a, b, maybe_rem); |
| 29 | } | 18 | } |
| 30 | 19 | ||
| 31 | const v128 = std.meta.Vector(2, u64); | 20 | const v2u64 = @Vector(2, u64); |
| 32 | 21 | ||
| 33 | fn __udivmodti4_windows_x86_64(a: v128, b: v128, maybe_rem: ?*u128) callconv(.C) v128 { | 22 | fn __udivmodti4_windows_x86_64(a: v2u64, b: v2u64, maybe_rem: ?*u128) callconv(.C) v2u64 { |
| 34 | return @bitCast(v128, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), maybe_rem)); | 23 | return @bitCast(v2u64, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), maybe_rem)); |
| 35 | } | 24 | } |
| 36 | 25 | ||
| 37 | test { | 26 | test { |
lib/compiler_rt/udivti3.zig+5-19| ... | @@ -1,27 +1,13 @@ | ... | @@ -1,27 +1,13 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const udivmod = @import("udivmod.zig").udivmod; | 3 | const udivmod = @import("udivmod.zig").udivmod; |
| 4 | const arch = builtin.cpu.arch; | ||
| 5 | const common = @import("common.zig"); | 4 | const common = @import("common.zig"); |
| 6 | 5 | ||
| 7 | pub const panic = common.panic; | 6 | pub const panic = common.panic; |
| 8 | 7 | ||
| 9 | comptime { | 8 | comptime { |
| 10 | if (builtin.os.tag == .windows) { | 9 | if (common.want_windows_v2u64_abi) { |
| 11 | switch (arch) { | 10 | @export(__udivti3_windows_x86_64, .{ .name = "__udivti3", .linkage = common.linkage }); |
| 12 | .i386 => { | ||
| 13 | @export(__udivti3, .{ .name = "__udivti3", .linkage = common.linkage }); | ||
| 14 | }, | ||
| 15 | .x86_64 => { | ||
| 16 | // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI | ||
| 17 | // that LLVM expects compiler-rt to have. | ||
| 18 | @export(__udivti3_windows_x86_64, .{ .name = "__udivti3", .linkage = common.linkage }); | ||
| 19 | }, | ||
| 20 | else => {}, | ||
| 21 | } | ||
| 22 | if (arch.isAARCH64()) { | ||
| 23 | @export(__udivti3, .{ .name = "__udivti3", .linkage = common.linkage }); | ||
| 24 | } | ||
| 25 | } else { | 11 | } else { |
| 26 | @export(__udivti3, .{ .name = "__udivti3", .linkage = common.linkage }); | 12 | @export(__udivti3, .{ .name = "__udivti3", .linkage = common.linkage }); |
| 27 | } | 13 | } |
| ... | @@ -31,8 +17,8 @@ pub fn __udivti3(a: u128, b: u128) callconv(.C) u128 { | ... | @@ -31,8 +17,8 @@ pub fn __udivti3(a: u128, b: u128) callconv(.C) u128 { |
| 31 | return udivmod(u128, a, b, null); | 17 | return udivmod(u128, a, b, null); |
| 32 | } | 18 | } |
| 33 | 19 | ||
| 34 | const v128 = std.meta.Vector(2, u64); | 20 | const v2u64 = @Vector(2, u64); |
| 35 | 21 | ||
| 36 | fn __udivti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 { | 22 | fn __udivti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 { |
| 37 | return @bitCast(v128, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), null)); | 23 | return @bitCast(v2u64, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), null)); |
| 38 | } | 24 | } |
lib/compiler_rt/umodti3.zig+5-19| ... | @@ -1,27 +1,13 @@ | ... | @@ -1,27 +1,13 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const udivmod = @import("udivmod.zig").udivmod; | 3 | const udivmod = @import("udivmod.zig").udivmod; |
| 4 | const arch = builtin.cpu.arch; | ||
| 5 | const common = @import("common.zig"); | 4 | const common = @import("common.zig"); |
| 6 | 5 | ||
| 7 | pub const panic = common.panic; | 6 | pub const panic = common.panic; |
| 8 | 7 | ||
| 9 | comptime { | 8 | comptime { |
| 10 | if (builtin.os.tag == .windows) { | 9 | if (common.want_windows_v2u64_abi) { |
| 11 | switch (arch) { | 10 | @export(__umodti3_windows_x86_64, .{ .name = "__umodti3", .linkage = common.linkage }); |
| 12 | .i386 => { | ||
| 13 | @export(__umodti3, .{ .name = "__umodti3", .linkage = common.linkage }); | ||
| 14 | }, | ||
| 15 | .x86_64 => { | ||
| 16 | // The "ti" functions must use Vector(2, u64) parameter types to adhere to the ABI | ||
| 17 | // that LLVM expects compiler-rt to have. | ||
| 18 | @export(__umodti3_windows_x86_64, .{ .name = "__umodti3", .linkage = common.linkage }); | ||
| 19 | }, | ||
| 20 | else => {}, | ||
| 21 | } | ||
| 22 | if (arch.isAARCH64()) { | ||
| 23 | @export(__umodti3, .{ .name = "__umodti3", .linkage = common.linkage }); | ||
| 24 | } | ||
| 25 | } else { | 11 | } else { |
| 26 | @export(__umodti3, .{ .name = "__umodti3", .linkage = common.linkage }); | 12 | @export(__umodti3, .{ .name = "__umodti3", .linkage = common.linkage }); |
| 27 | } | 13 | } |
| ... | @@ -33,10 +19,10 @@ pub fn __umodti3(a: u128, b: u128) callconv(.C) u128 { | ... | @@ -33,10 +19,10 @@ pub fn __umodti3(a: u128, b: u128) callconv(.C) u128 { |
| 33 | return r; | 19 | return r; |
| 34 | } | 20 | } |
| 35 | 21 | ||
| 36 | const v128 = std.meta.Vector(2, u64); | 22 | const v2u64 = @Vector(2, u64); |
| 37 | 23 | ||
| 38 | fn __umodti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 { | 24 | fn __umodti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 { |
| 39 | var r: u128 = undefined; | 25 | var r: u128 = undefined; |
| 40 | _ = udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), &r); | 26 | _ = udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), &r); |
| 41 | return @bitCast(v128, r); | 27 | return @bitCast(v2u64, r); |
| 42 | } | 28 | } |
lib/std/fmt.zig-8| ... | @@ -2284,10 +2284,6 @@ test "float.hexadecimal.precision" { | ... | @@ -2284,10 +2284,6 @@ test "float.hexadecimal.precision" { |
| 2284 | } | 2284 | } |
| 2285 | 2285 | ||
| 2286 | test "float.decimal" { | 2286 | test "float.decimal" { |
| 2287 | if (builtin.zig_backend == .stage1 and builtin.os.tag == .windows) { | ||
| 2288 | // https://github.com/ziglang/zig/issues/12063 | ||
| 2289 | return error.SkipZigTest; | ||
| 2290 | } | ||
| 2291 | try expectFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)}); | 2287 | try expectFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)}); |
| 2292 | try expectFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)}); | 2288 | try expectFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)}); |
| 2293 | try expectFmt("f32: 0", "f32: {d:.0}", .{@as(f32, 0.0)}); | 2289 | try expectFmt("f32: 0", "f32: {d:.0}", .{@as(f32, 0.0)}); |
| ... | @@ -2311,10 +2307,6 @@ test "float.decimal" { | ... | @@ -2311,10 +2307,6 @@ test "float.decimal" { |
| 2311 | } | 2307 | } |
| 2312 | 2308 | ||
| 2313 | test "float.libc.sanity" { | 2309 | test "float.libc.sanity" { |
| 2314 | if (builtin.zig_backend == .stage1 and builtin.os.tag == .windows) { | ||
| 2315 | // https://github.com/ziglang/zig/issues/12063 | ||
| 2316 | return error.SkipZigTest; | ||
| 2317 | } | ||
| 2318 | try expectFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 916964781)))}); | 2310 | try expectFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 916964781)))}); |
| 2319 | try expectFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 925353389)))}); | 2311 | try expectFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 925353389)))}); |
| 2320 | try expectFmt("f64: 0.10000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1036831278)))}); | 2312 | try expectFmt("f64: 0.10000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1036831278)))}); |
src/codegen/llvm.zig+30-11| ... | @@ -4802,7 +4802,7 @@ pub const FuncGen = struct { | ... | @@ -4802,7 +4802,7 @@ pub const FuncGen = struct { |
| 4802 | const operand_bits = @intCast(u16, operand_scalar_ty.bitSize(target)); | 4802 | const operand_bits = @intCast(u16, operand_scalar_ty.bitSize(target)); |
| 4803 | const rt_int_bits = compilerRtIntBits(operand_bits); | 4803 | const rt_int_bits = compilerRtIntBits(operand_bits); |
| 4804 | const rt_int_ty = self.context.intType(rt_int_bits); | 4804 | const rt_int_ty = self.context.intType(rt_int_bits); |
| 4805 | const extended = e: { | 4805 | var extended = e: { |
| 4806 | if (operand_scalar_ty.isSignedInt()) { | 4806 | if (operand_scalar_ty.isSignedInt()) { |
| 4807 | break :e self.builder.buildSExtOrBitCast(operand, rt_int_ty, ""); | 4807 | break :e self.builder.buildSExtOrBitCast(operand, rt_int_ty, ""); |
| 4808 | } else { | 4808 | } else { |
| ... | @@ -4819,7 +4819,16 @@ pub const FuncGen = struct { | ... | @@ -4819,7 +4819,16 @@ pub const FuncGen = struct { |
| 4819 | compiler_rt_operand_abbrev, | 4819 | compiler_rt_operand_abbrev, |
| 4820 | compiler_rt_dest_abbrev, | 4820 | compiler_rt_dest_abbrev, |
| 4821 | }) catch unreachable; | 4821 | }) catch unreachable; |
| 4822 | const param_types = [1]*const llvm.Type{rt_int_ty}; | 4822 | |
| 4823 | var param_types = [1]*const llvm.Type{rt_int_ty}; | ||
| 4824 | if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) { | ||
| 4825 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard | ||
| 4826 | // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have. | ||
| 4827 | const v2i64 = self.context.intType(64).vectorType(2); | ||
| 4828 | extended = self.builder.buildBitCast(extended, v2i64, ""); | ||
| 4829 | param_types = [1]*const llvm.Type{v2i64}; | ||
| 4830 | } | ||
| 4831 | |||
| 4823 | const libc_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty); | 4832 | const libc_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty); |
| 4824 | const params = [1]*const llvm.Value{extended}; | 4833 | const params = [1]*const llvm.Value{extended}; |
| 4825 | 4834 | ||
| ... | @@ -4851,7 +4860,12 @@ pub const FuncGen = struct { | ... | @@ -4851,7 +4860,12 @@ pub const FuncGen = struct { |
| 4851 | } | 4860 | } |
| 4852 | 4861 | ||
| 4853 | const rt_int_bits = compilerRtIntBits(@intCast(u16, dest_scalar_ty.bitSize(target))); | 4862 | const rt_int_bits = compilerRtIntBits(@intCast(u16, dest_scalar_ty.bitSize(target))); |
| 4854 | const libc_ret_ty = self.context.intType(rt_int_bits); | 4863 | const ret_ty = self.context.intType(rt_int_bits); |
| 4864 | const libc_ret_ty = if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) b: { | ||
| 4865 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard | ||
| 4866 | // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have. | ||
| 4867 | break :b self.context.intType(64).vectorType(2); | ||
| 4868 | } else ret_ty; | ||
| 4855 | 4869 | ||
| 4856 | const operand_bits = operand_scalar_ty.floatBits(target); | 4870 | const operand_bits = operand_scalar_ty.floatBits(target); |
| 4857 | const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits); | 4871 | const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits); |
| ... | @@ -4871,13 +4885,11 @@ pub const FuncGen = struct { | ... | @@ -4871,13 +4885,11 @@ pub const FuncGen = struct { |
| 4871 | const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty); | 4885 | const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty); |
| 4872 | const params = [1]*const llvm.Value{operand}; | 4886 | const params = [1]*const llvm.Value{operand}; |
| 4873 | 4887 | ||
| 4874 | const result = self.builder.buildCall(libc_fn, &params, params.len, .C, .Auto, ""); | 4888 | var result = self.builder.buildCall(libc_fn, &params, params.len, .C, .Auto, ""); |
| 4875 | |||
| 4876 | if (libc_ret_ty == dest_llvm_ty) { | ||
| 4877 | return result; | ||
| 4878 | } | ||
| 4879 | 4889 | ||
| 4880 | return self.builder.buildTrunc(result, dest_llvm_ty, ""); | 4890 | if (libc_ret_ty != ret_ty) result = self.builder.buildBitCast(result, ret_ty, ""); |
| 4891 | if (ret_ty != dest_llvm_ty) result = self.builder.buildTrunc(result, dest_llvm_ty, ""); | ||
| 4892 | return result; | ||
| 4881 | } | 4893 | } |
| 4882 | 4894 | ||
| 4883 | fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*const llvm.Value { | 4895 | fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*const llvm.Value { |
| ... | @@ -6490,8 +6502,15 @@ pub const FuncGen = struct { | ... | @@ -6490,8 +6502,15 @@ pub const FuncGen = struct { |
| 6490 | const one = int_llvm_ty.constInt(1, .False); | 6502 | const one = int_llvm_ty.constInt(1, .False); |
| 6491 | const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False); | 6503 | const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False); |
| 6492 | const sign_mask = one.constShl(shift_amt); | 6504 | const sign_mask = one.constShl(shift_amt); |
| 6493 | const bitcasted_operand = self.builder.buildBitCast(params[0], int_llvm_ty, ""); | 6505 | const result = if (ty.zigTypeTag() == .Vector) blk: { |
| 6494 | const result = self.builder.buildXor(bitcasted_operand, sign_mask, ""); | 6506 | const splat_sign_mask = self.builder.buildVectorSplat(ty.vectorLen(), sign_mask, ""); |
| 6507 | const cast_ty = int_llvm_ty.vectorType(ty.vectorLen()); | ||
| 6508 | const bitcasted_operand = self.builder.buildBitCast(params[0], cast_ty, ""); | ||
| 6509 | break :blk self.builder.buildXor(bitcasted_operand, splat_sign_mask, ""); | ||
| 6510 | } else blk: { | ||
| 6511 | const bitcasted_operand = self.builder.buildBitCast(params[0], int_llvm_ty, ""); | ||
| 6512 | break :blk self.builder.buildXor(bitcasted_operand, sign_mask, ""); | ||
| 6513 | }; | ||
| 6495 | return self.builder.buildBitCast(result, llvm_ty, ""); | 6514 | return self.builder.buildBitCast(result, llvm_ty, ""); |
| 6496 | }, | 6515 | }, |
| 6497 | .add, .sub, .div, .mul => FloatOpStrat{ | 6516 | .add, .sub, .div, .mul => FloatOpStrat{ |
src/stage1/codegen.cpp+38-58| ... | @@ -3371,14 +3371,12 @@ static LLVMValueRef add_icmp(CodeGen *g, LLVMValueRef val, Icmp kind) { | ... | @@ -3371,14 +3371,12 @@ static LLVMValueRef add_icmp(CodeGen *g, LLVMValueRef val, Icmp kind) { |
| 3371 | } | 3371 | } |
| 3372 | 3372 | ||
| 3373 | static LLVMValueRef gen_soft_int_to_float_op(CodeGen *g, LLVMValueRef value_ref, ZigType *operand_type, ZigType *result_type) { | 3373 | static LLVMValueRef gen_soft_int_to_float_op(CodeGen *g, LLVMValueRef value_ref, ZigType *operand_type, ZigType *result_type) { |
| 3374 | uint32_t vector_len = operand_type->id == ZigTypeIdVector ? operand_type->data.vector.len : 0; | ||
| 3375 | |||
| 3376 | // Handle integers of non-pot bitsize by widening them. | 3374 | // Handle integers of non-pot bitsize by widening them. |
| 3377 | const size_t bitsize = operand_type->data.integral.bit_count; | 3375 | const size_t bitsize = operand_type->data.integral.bit_count; |
| 3378 | const bool is_signed = operand_type->data.integral.is_signed; | 3376 | const bool is_signed = operand_type->data.integral.is_signed; |
| 3379 | if (bitsize < 32 || !is_power_of_2(bitsize)) { | 3377 | if (bitsize < 32 || !is_power_of_2(bitsize)) { |
| 3380 | const size_t wider_bitsize = bitsize < 32 ? 32 : round_to_next_power_of_2(bitsize); | 3378 | const size_t wider_bitsize = bitsize < 32 ? 32 : round_to_next_power_of_2(bitsize); |
| 3381 | ZigType *const wider_type = get_int_type(g, is_signed, wider_bitsize); | 3379 | ZigType *wider_type = get_int_type(g, is_signed, wider_bitsize); |
| 3382 | value_ref = gen_widen_or_shorten(g, false, operand_type, wider_type, value_ref); | 3380 | value_ref = gen_widen_or_shorten(g, false, operand_type, wider_type, value_ref); |
| 3383 | operand_type = wider_type; | 3381 | operand_type = wider_type; |
| 3384 | } | 3382 | } |
| ... | @@ -3395,35 +3393,22 @@ static LLVMValueRef gen_soft_int_to_float_op(CodeGen *g, LLVMValueRef value_ref, | ... | @@ -3395,35 +3393,22 @@ static LLVMValueRef gen_soft_int_to_float_op(CodeGen *g, LLVMValueRef value_ref, |
| 3395 | } | 3393 | } |
| 3396 | 3394 | ||
| 3397 | int param_count = 1; | 3395 | int param_count = 1; |
| 3398 | LLVMValueRef func_ref = get_soft_float_fn(g, fn_name, param_count, operand_type->llvm_type, result_type->llvm_type); | 3396 | LLVMValueRef func_ref; |
| 3399 | 3397 | if ((operand_type->data.integral.bit_count == 128) && (g->zig_target->os == OsWindows) && (g->zig_target->arch == ZigLLVM_x86_64)) { | |
| 3400 | LLVMValueRef result; | 3398 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard i128 calling |
| 3401 | if (vector_len == 0) { | 3399 | // convention to adhere to the ABI that LLVM expects compiler-rt to have. |
| 3402 | LLVMValueRef params[1] = {value_ref}; | 3400 | LLVMTypeRef v2i64 = LLVMVectorType(LLVMInt64Type(), 2); |
| 3403 | result = LLVMBuildCall(g->builder, func_ref, params, param_count, ""); | 3401 | value_ref = LLVMBuildBitCast(g->builder, value_ref, v2i64, ""); |
| 3402 | func_ref = get_soft_float_fn(g, fn_name, param_count, v2i64, result_type->llvm_type); | ||
| 3404 | } else { | 3403 | } else { |
| 3405 | ZigType *alloca_ty = operand_type; | 3404 | func_ref = get_soft_float_fn(g, fn_name, param_count, operand_type->llvm_type, result_type->llvm_type); |
| 3406 | result = build_alloca(g, alloca_ty, "", 0); | ||
| 3407 | |||
| 3408 | LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type; | ||
| 3409 | for (uint32_t i = 0; i < vector_len; i++) { | ||
| 3410 | LLVMValueRef index_value = LLVMConstInt(usize_ref, i, false); | ||
| 3411 | LLVMValueRef params[1] = { | ||
| 3412 | LLVMBuildExtractElement(g->builder, value_ref, index_value, ""), | ||
| 3413 | }; | ||
| 3414 | LLVMValueRef call_result = LLVMBuildCall(g->builder, func_ref, params, param_count, ""); | ||
| 3415 | LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""), | ||
| 3416 | call_result, index_value, ""); | ||
| 3417 | } | ||
| 3418 | |||
| 3419 | result = LLVMBuildLoad(g->builder, result, ""); | ||
| 3420 | } | 3405 | } |
| 3421 | return result; | 3406 | |
| 3407 | LLVMValueRef params[1] = {value_ref}; | ||
| 3408 | return LLVMBuildCall(g->builder, func_ref, params, param_count, ""); | ||
| 3422 | } | 3409 | } |
| 3423 | 3410 | ||
| 3424 | static LLVMValueRef gen_soft_float_to_int_op(CodeGen *g, LLVMValueRef value_ref, ZigType *operand_type, ZigType *result_type) { | 3411 | static LLVMValueRef gen_soft_float_to_int_op(CodeGen *g, LLVMValueRef value_ref, ZigType *operand_type, ZigType *result_type) { |
| 3425 | uint32_t vector_len = operand_type->id == ZigTypeIdVector ? operand_type->data.vector.len : 0; | ||
| 3426 | |||
| 3427 | // Handle integers of non-pot bitsize by truncating a sufficiently wide pot integer | 3412 | // Handle integers of non-pot bitsize by truncating a sufficiently wide pot integer |
| 3428 | const size_t bitsize = result_type->data.integral.bit_count; | 3413 | const size_t bitsize = result_type->data.integral.bit_count; |
| 3429 | const bool is_signed = result_type->data.integral.is_signed; | 3414 | const bool is_signed = result_type->data.integral.is_signed; |
| ... | @@ -3445,46 +3430,41 @@ static LLVMValueRef gen_soft_float_to_int_op(CodeGen *g, LLVMValueRef value_ref, | ... | @@ -3445,46 +3430,41 @@ static LLVMValueRef gen_soft_float_to_int_op(CodeGen *g, LLVMValueRef value_ref, |
| 3445 | } | 3430 | } |
| 3446 | 3431 | ||
| 3447 | int param_count = 1; | 3432 | int param_count = 1; |
| 3448 | LLVMValueRef func_ref = get_soft_float_fn(g, fn_name, param_count, operand_type->llvm_type, wider_type->llvm_type); | 3433 | LLVMValueRef func_ref; |
| 3449 | 3434 | if ((wider_type->data.integral.bit_count == 128) && (g->zig_target->os == OsWindows) && (g->zig_target->arch == ZigLLVM_x86_64)) { | |
| 3450 | LLVMValueRef result; | 3435 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard i128 calling |
| 3451 | if (vector_len == 0) { | 3436 | // convention to adhere to the ABI that LLVM expects compiler-rt to have. |
| 3452 | LLVMValueRef params[1] = {value_ref}; | 3437 | LLVMTypeRef v2i64 = LLVMVectorType(LLVMInt64Type(), 2); |
| 3453 | result = LLVMBuildCall(g->builder, func_ref, params, param_count, ""); | 3438 | func_ref = get_soft_float_fn(g, fn_name, param_count, operand_type->llvm_type, v2i64); |
| 3454 | } else { | 3439 | } else { |
| 3455 | ZigType *alloca_ty = operand_type; | 3440 | func_ref = get_soft_float_fn(g, fn_name, param_count, operand_type->llvm_type, wider_type->llvm_type); |
| 3456 | result = build_alloca(g, alloca_ty, "", 0); | 3441 | } |
| 3457 | 3442 | ||
| 3458 | LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type; | 3443 | LLVMValueRef params[1] = {value_ref}; |
| 3459 | for (uint32_t i = 0; i < vector_len; i++) { | 3444 | LLVMValueRef result = LLVMBuildCall(g->builder, func_ref, params, param_count, ""); |
| 3460 | LLVMValueRef index_value = LLVMConstInt(usize_ref, i, false); | ||
| 3461 | LLVMValueRef params[1] = { | ||
| 3462 | LLVMBuildExtractElement(g->builder, value_ref, index_value, ""), | ||
| 3463 | }; | ||
| 3464 | LLVMValueRef call_result = LLVMBuildCall(g->builder, func_ref, params, param_count, ""); | ||
| 3465 | LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""), | ||
| 3466 | call_result, index_value, ""); | ||
| 3467 | } | ||
| 3468 | 3445 | ||
| 3469 | result = LLVMBuildLoad(g->builder, result, ""); | 3446 | if ((wider_type->data.integral.bit_count == 128) && (g->zig_target->os == OsWindows) && (g->zig_target->arch == ZigLLVM_x86_64)) { |
| 3447 | result = LLVMBuildBitCast(g->builder, result, wider_type->llvm_type, ""); | ||
| 3470 | } | 3448 | } |
| 3471 | 3449 | ||
| 3472 | // Handle integers of non-pot bitsize by shortening them on the output | 3450 | // Handle integers of non-pot bitsize by shortening them on the output |
| 3473 | if (result_type != wider_type) { | 3451 | if (result_type != wider_type) { |
| 3474 | return gen_widen_or_shorten(g, false, wider_type, result_type, result); | 3452 | result = gen_widen_or_shorten(g, false, wider_type, result_type, result); |
| 3475 | } | 3453 | } |
| 3454 | |||
| 3476 | return result; | 3455 | return result; |
| 3477 | } | 3456 | } |
| 3478 | 3457 | ||
| 3479 | static LLVMValueRef gen_soft_float_bin_op(CodeGen *g, LLVMValueRef op1_value, LLVMValueRef op2_value, ZigType *operand_type, IrBinOp op_id) { | 3458 | static LLVMValueRef gen_soft_float_bin_op(CodeGen *g, LLVMValueRef op1_value, LLVMValueRef op2_value, ZigType *operand_type, IrBinOp op_id) { |
| 3480 | uint32_t vector_len = operand_type->id == ZigTypeIdVector ? operand_type->data.vector.len : 0; | 3459 | uint32_t vector_len = operand_type->id == ZigTypeIdVector ? operand_type->data.vector.len : 0; |
| 3481 | 3460 | ||
| 3482 | LLVMTypeRef return_type = operand_type->llvm_type; | ||
| 3483 | int param_count = 2; | 3461 | int param_count = 2; |
| 3484 | 3462 | ||
| 3485 | const char *compiler_rt_type_abbrev = get_compiler_rt_type_abbrev(operand_type); | 3463 | ZigType *operand_scalar_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type; |
| 3486 | const char *math_float_prefix = libc_float_prefix(g, operand_type); | 3464 | LLVMTypeRef return_scalar_type = operand_scalar_type->llvm_type; |
| 3487 | const char *math_float_suffix = libc_float_suffix(g, operand_type); | 3465 | const char *compiler_rt_type_abbrev = get_compiler_rt_type_abbrev(operand_scalar_type); |
| 3466 | const char *math_float_prefix = libc_float_prefix(g, operand_scalar_type); | ||
| 3467 | const char *math_float_suffix = libc_float_suffix(g, operand_scalar_type); | ||
| 3488 | 3468 | ||
| 3489 | char fn_name[64]; | 3469 | char fn_name[64]; |
| 3490 | Icmp res_icmp = NONE; | 3470 | Icmp res_icmp = NONE; |
| ... | @@ -3511,32 +3491,32 @@ static LLVMValueRef gen_soft_float_bin_op(CodeGen *g, LLVMValueRef op1_value, LL | ... | @@ -3511,32 +3491,32 @@ static LLVMValueRef gen_soft_float_bin_op(CodeGen *g, LLVMValueRef op1_value, LL |
| 3511 | case IrBinOpShlSat: | 3491 | case IrBinOpShlSat: |
| 3512 | zig_unreachable(); | 3492 | zig_unreachable(); |
| 3513 | case IrBinOpCmpEq: | 3493 | case IrBinOpCmpEq: |
| 3514 | return_type = g->builtin_types.entry_i32->llvm_type; | 3494 | return_scalar_type = g->builtin_types.entry_i32->llvm_type; |
| 3515 | snprintf(fn_name, sizeof(fn_name), "__eq%sf2", compiler_rt_type_abbrev); | 3495 | snprintf(fn_name, sizeof(fn_name), "__eq%sf2", compiler_rt_type_abbrev); |
| 3516 | res_icmp = EQ_ZERO; | 3496 | res_icmp = EQ_ZERO; |
| 3517 | break; | 3497 | break; |
| 3518 | case IrBinOpCmpNotEq: | 3498 | case IrBinOpCmpNotEq: |
| 3519 | return_type = g->builtin_types.entry_i32->llvm_type; | 3499 | return_scalar_type = g->builtin_types.entry_i32->llvm_type; |
| 3520 | snprintf(fn_name, sizeof(fn_name), "__ne%sf2", compiler_rt_type_abbrev); | 3500 | snprintf(fn_name, sizeof(fn_name), "__ne%sf2", compiler_rt_type_abbrev); |
| 3521 | res_icmp = NE_ZERO; | 3501 | res_icmp = NE_ZERO; |
| 3522 | break; | 3502 | break; |
| 3523 | case IrBinOpCmpLessOrEq: | 3503 | case IrBinOpCmpLessOrEq: |
| 3524 | return_type = g->builtin_types.entry_i32->llvm_type; | 3504 | return_scalar_type = g->builtin_types.entry_i32->llvm_type; |
| 3525 | snprintf(fn_name, sizeof(fn_name), "__le%sf2", compiler_rt_type_abbrev); | 3505 | snprintf(fn_name, sizeof(fn_name), "__le%sf2", compiler_rt_type_abbrev); |
| 3526 | res_icmp = LE_ZERO; | 3506 | res_icmp = LE_ZERO; |
| 3527 | break; | 3507 | break; |
| 3528 | case IrBinOpCmpLessThan: | 3508 | case IrBinOpCmpLessThan: |
| 3529 | return_type = g->builtin_types.entry_i32->llvm_type; | 3509 | return_scalar_type = g->builtin_types.entry_i32->llvm_type; |
| 3530 | snprintf(fn_name, sizeof(fn_name), "__le%sf2", compiler_rt_type_abbrev); | 3510 | snprintf(fn_name, sizeof(fn_name), "__le%sf2", compiler_rt_type_abbrev); |
| 3531 | res_icmp = EQ_NEG; | 3511 | res_icmp = EQ_NEG; |
| 3532 | break; | 3512 | break; |
| 3533 | case IrBinOpCmpGreaterOrEq: | 3513 | case IrBinOpCmpGreaterOrEq: |
| 3534 | return_type = g->builtin_types.entry_i32->llvm_type; | 3514 | return_scalar_type = g->builtin_types.entry_i32->llvm_type; |
| 3535 | snprintf(fn_name, sizeof(fn_name), "__ge%sf2", compiler_rt_type_abbrev); | 3515 | snprintf(fn_name, sizeof(fn_name), "__ge%sf2", compiler_rt_type_abbrev); |
| 3536 | res_icmp = GE_ZERO; | 3516 | res_icmp = GE_ZERO; |
| 3537 | break; | 3517 | break; |
| 3538 | case IrBinOpCmpGreaterThan: | 3518 | case IrBinOpCmpGreaterThan: |
| 3539 | return_type = g->builtin_types.entry_i32->llvm_type; | 3519 | return_scalar_type = g->builtin_types.entry_i32->llvm_type; |
| 3540 | snprintf(fn_name, sizeof(fn_name), "__ge%sf2", compiler_rt_type_abbrev); | 3520 | snprintf(fn_name, sizeof(fn_name), "__ge%sf2", compiler_rt_type_abbrev); |
| 3541 | res_icmp = EQ_ONE; | 3521 | res_icmp = EQ_ONE; |
| 3542 | break; | 3522 | break; |
| ... | @@ -3569,7 +3549,7 @@ static LLVMValueRef gen_soft_float_bin_op(CodeGen *g, LLVMValueRef op1_value, LL | ... | @@ -3569,7 +3549,7 @@ static LLVMValueRef gen_soft_float_bin_op(CodeGen *g, LLVMValueRef op1_value, LL |
| 3569 | zig_unreachable(); | 3549 | zig_unreachable(); |
| 3570 | } | 3550 | } |
| 3571 | 3551 | ||
| 3572 | LLVMValueRef func_ref = get_soft_float_fn(g, fn_name, param_count, operand_type->llvm_type, return_type); | 3552 | LLVMValueRef func_ref = get_soft_float_fn(g, fn_name, param_count, operand_scalar_type->llvm_type, return_scalar_type); |
| 3573 | 3553 | ||
| 3574 | LLVMValueRef result; | 3554 | LLVMValueRef result; |
| 3575 | if (vector_len == 0) { | 3555 | if (vector_len == 0) { |
test/behavior/vector.zig+14-12| ... | @@ -101,18 +101,20 @@ test "vector float operators" { | ... | @@ -101,18 +101,20 @@ test "vector float operators" { |
| 101 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 101 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 102 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 102 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 103 | 103 | ||
| 104 | const S = struct { | 104 | inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| { |
| 105 | fn doTheTest() !void { | 105 | const S = struct { |
| 106 | var v: @Vector(4, f32) = [4]f32{ 10, 20, 30, 40 }; | 106 | fn doTheTest() !void { |
| 107 | var x: @Vector(4, f32) = [4]f32{ 1, 2, 3, 4 }; | 107 | var v: @Vector(4, T) = [4]T{ 10, 20, 30, 40 }; |
| 108 | try expect(mem.eql(f32, &@as([4]f32, v + x), &[4]f32{ 11, 22, 33, 44 })); | 108 | var x: @Vector(4, T) = [4]T{ 1, 2, 3, 4 }; |
| 109 | try expect(mem.eql(f32, &@as([4]f32, v - x), &[4]f32{ 9, 18, 27, 36 })); | 109 | try expect(mem.eql(T, &@as([4]T, v + x), &[4]T{ 11, 22, 33, 44 })); |
| 110 | try expect(mem.eql(f32, &@as([4]f32, v * x), &[4]f32{ 10, 40, 90, 160 })); | 110 | try expect(mem.eql(T, &@as([4]T, v - x), &[4]T{ 9, 18, 27, 36 })); |
| 111 | try expect(mem.eql(f32, &@as([4]f32, -x), &[4]f32{ -1, -2, -3, -4 })); | 111 | try expect(mem.eql(T, &@as([4]T, v * x), &[4]T{ 10, 40, 90, 160 })); |
| 112 | } | 112 | try expect(mem.eql(T, &@as([4]T, -x), &[4]T{ -1, -2, -3, -4 })); |
| 113 | }; | 113 | } |
| 114 | try S.doTheTest(); | 114 | }; |
| 115 | comptime try S.doTheTest(); | 115 | try S.doTheTest(); |
| 116 | comptime try S.doTheTest(); | ||
| 117 | } | ||
| 116 | } | 118 | } |
| 117 | 119 | ||
| 118 | test "vector bit operators" { | 120 | test "vector bit operators" { |