diff --git a/lib/compiler/resinator/parse.zig b/lib/compiler/resinator/parse.zig index 445424429ea2249991661e99840331e2b936bd96..1f3b2f156ae15fb7fb548ffe37bce6f036079e19 100644 --- a/lib/compiler/resinator/parse.zig +++ b/lib/compiler/resinator/parse.zig @@ -1277,7 +1277,7 @@ pub const Parser = struct { }, else => unreachable, } - @compileError("unreachable"); + comptime unreachable; } pub const OptionalParamParser = struct { diff --git a/lib/compiler_rt.zig b/lib/compiler_rt.zig index f042d0076e62740c50d61b4e28b8b3ddb07012f3..5ff6e659d56f0797225b7661aa076cb41f715a42 100644 --- a/lib/compiler_rt.zig +++ b/lib/compiler_rt.zig @@ -1,4 +1,5 @@ const builtin = @import("builtin"); +const compiler_rt = @This(); const ofmt_c = builtin.object_format == .c; const native_endian = builtin.cpu.arch.endian(); @@ -84,144 +85,17 @@ comptime { // Float routines // conversion _ = @import("compiler_rt/extendf.zig"); - _ = @import("compiler_rt/extendhfsf2.zig"); - _ = @import("compiler_rt/extendhfdf2.zig"); - _ = @import("compiler_rt/extendhftf2.zig"); - _ = @import("compiler_rt/extendhfxf2.zig"); - _ = @import("compiler_rt/extendsfdf2.zig"); - _ = @import("compiler_rt/extendsftf2.zig"); - _ = @import("compiler_rt/extendsfxf2.zig"); - _ = @import("compiler_rt/extenddftf2.zig"); - _ = @import("compiler_rt/extenddfxf2.zig"); - _ = @import("compiler_rt/extendxftf2.zig"); - _ = @import("compiler_rt/truncf.zig"); - _ = @import("compiler_rt/truncsfhf2.zig"); - _ = @import("compiler_rt/truncdfhf2.zig"); - _ = @import("compiler_rt/truncdfsf2.zig"); - _ = @import("compiler_rt/truncxfhf2.zig"); - _ = @import("compiler_rt/truncxfsf2.zig"); - _ = @import("compiler_rt/truncxfdf2.zig"); - _ = @import("compiler_rt/trunctfhf2.zig"); - _ = @import("compiler_rt/trunctfsf2.zig"); - _ = @import("compiler_rt/trunctfdf2.zig"); - _ = @import("compiler_rt/trunctfxf2.zig"); - _ = @import("compiler_rt/int_from_float.zig"); - _ = @import("compiler_rt/fixhfei.zig"); - _ = @import("compiler_rt/fixsfsi.zig"); - _ = @import("compiler_rt/fixsfdi.zig"); - _ = @import("compiler_rt/fixsfti.zig"); - _ = @import("compiler_rt/fixsfei.zig"); - _ = @import("compiler_rt/fixdfsi.zig"); - _ = @import("compiler_rt/fixdfdi.zig"); - _ = @import("compiler_rt/fixdfti.zig"); - _ = @import("compiler_rt/fixdfei.zig"); - _ = @import("compiler_rt/fixtfsi.zig"); - _ = @import("compiler_rt/fixtfdi.zig"); - _ = @import("compiler_rt/fixtfti.zig"); - _ = @import("compiler_rt/fixtfei.zig"); - _ = @import("compiler_rt/fixxfsi.zig"); - _ = @import("compiler_rt/fixxfdi.zig"); - _ = @import("compiler_rt/fixxfei.zig"); - - _ = @import("compiler_rt/fixunshfsi.zig"); - _ = @import("compiler_rt/fixunshfdi.zig"); - _ = @import("compiler_rt/fixunshfti.zig"); - _ = @import("compiler_rt/fixunshfei.zig"); - _ = @import("compiler_rt/fixunssfsi.zig"); - _ = @import("compiler_rt/fixunssfdi.zig"); - _ = @import("compiler_rt/fixunssfti.zig"); - _ = @import("compiler_rt/fixunssfei.zig"); - _ = @import("compiler_rt/fixunsdfsi.zig"); - _ = @import("compiler_rt/fixunsdfdi.zig"); - _ = @import("compiler_rt/fixunsdfti.zig"); - _ = @import("compiler_rt/fixunsdfei.zig"); - _ = @import("compiler_rt/fixunstfsi.zig"); - _ = @import("compiler_rt/fixunstfdi.zig"); - _ = @import("compiler_rt/fixunstfti.zig"); - _ = @import("compiler_rt/fixunstfei.zig"); - _ = @import("compiler_rt/fixunsxfsi.zig"); - _ = @import("compiler_rt/fixunsxfdi.zig"); - _ = @import("compiler_rt/fixunsxfti.zig"); - _ = @import("compiler_rt/fixunsxfei.zig"); - _ = @import("compiler_rt/float_from_int.zig"); - _ = @import("compiler_rt/floatsihf.zig"); - _ = @import("compiler_rt/floatsisf.zig"); - _ = @import("compiler_rt/floatsidf.zig"); - _ = @import("compiler_rt/floatsitf.zig"); - _ = @import("compiler_rt/floatsixf.zig"); - _ = @import("compiler_rt/floatdihf.zig"); - _ = @import("compiler_rt/floatdisf.zig"); - _ = @import("compiler_rt/floatdidf.zig"); - _ = @import("compiler_rt/floatditf.zig"); - _ = @import("compiler_rt/floatdixf.zig"); - _ = @import("compiler_rt/floattihf.zig"); - _ = @import("compiler_rt/floattisf.zig"); - _ = @import("compiler_rt/floattidf.zig"); - _ = @import("compiler_rt/floattitf.zig"); - _ = @import("compiler_rt/floattixf.zig"); - _ = @import("compiler_rt/floateihf.zig"); - _ = @import("compiler_rt/floateisf.zig"); - _ = @import("compiler_rt/floateidf.zig"); - _ = @import("compiler_rt/floateitf.zig"); - _ = @import("compiler_rt/floateixf.zig"); - _ = @import("compiler_rt/floatunsihf.zig"); - _ = @import("compiler_rt/floatunsisf.zig"); - _ = @import("compiler_rt/floatunsidf.zig"); - _ = @import("compiler_rt/floatunsitf.zig"); - _ = @import("compiler_rt/floatunsixf.zig"); - _ = @import("compiler_rt/floatundihf.zig"); - _ = @import("compiler_rt/floatundisf.zig"); - _ = @import("compiler_rt/floatundidf.zig"); - _ = @import("compiler_rt/floatunditf.zig"); - _ = @import("compiler_rt/floatundixf.zig"); - _ = @import("compiler_rt/floatuntihf.zig"); - _ = @import("compiler_rt/floatuntisf.zig"); - _ = @import("compiler_rt/floatuntidf.zig"); - _ = @import("compiler_rt/floatuntitf.zig"); - _ = @import("compiler_rt/floatuntixf.zig"); - _ = @import("compiler_rt/floatuneihf.zig"); - _ = @import("compiler_rt/floatuneisf.zig"); - _ = @import("compiler_rt/floatuneidf.zig"); - _ = @import("compiler_rt/floatuneitf.zig"); - _ = @import("compiler_rt/floatuneixf.zig"); // comparison _ = @import("compiler_rt/comparef.zig"); - _ = @import("compiler_rt/cmpdf2.zig"); - _ = @import("compiler_rt/cmptf2.zig"); - _ = @import("compiler_rt/cmpxf2.zig"); - _ = @import("compiler_rt/unorddf2.zig"); - _ = @import("compiler_rt/gehf2.zig"); - _ = @import("compiler_rt/gesf2.zig"); - _ = @import("compiler_rt/gedf2.zig"); - _ = @import("compiler_rt/gexf2.zig"); - _ = @import("compiler_rt/getf2.zig"); // arithmetic _ = @import("compiler_rt/addf3.zig"); - _ = @import("compiler_rt/addhf3.zig"); - _ = @import("compiler_rt/addsf3.zig"); - _ = @import("compiler_rt/adddf3.zig"); - _ = @import("compiler_rt/addtf3.zig"); - _ = @import("compiler_rt/addxf3.zig"); - - _ = @import("compiler_rt/subhf3.zig"); - _ = @import("compiler_rt/subsf3.zig"); - _ = @import("compiler_rt/subdf3.zig"); - _ = @import("compiler_rt/subtf3.zig"); - _ = @import("compiler_rt/subxf3.zig"); - _ = @import("compiler_rt/mulf3.zig"); - _ = @import("compiler_rt/mulhf3.zig"); - _ = @import("compiler_rt/mulsf3.zig"); - _ = @import("compiler_rt/muldf3.zig"); - _ = @import("compiler_rt/multf3.zig"); - _ = @import("compiler_rt/mulxf3.zig"); - _ = @import("compiler_rt/divhf3.zig"); _ = @import("compiler_rt/divsf3.zig"); _ = @import("compiler_rt/divdf3.zig"); _ = @import("compiler_rt/divxf3.zig"); @@ -235,25 +109,17 @@ comptime { symbol(&__negsf2, "__negsf2"); symbol(&__negdf2, "__negdf2"); } - if (want_ppc_abi) symbol(&__negtf2, "__negkf2"); - symbol(&__negtf2, "__negtf2"); + if (want_ppc_abi) { + symbol(&__negtf2, "__negkf2"); + } else { + symbol(&__negtf2, "__negtf2"); + } symbol(&__negxf2, "__negxf2"); // other _ = @import("compiler_rt/powiXf2.zig"); _ = @import("compiler_rt/mulc3.zig"); - _ = @import("compiler_rt/mulhc3.zig"); - _ = @import("compiler_rt/mulsc3.zig"); - _ = @import("compiler_rt/muldc3.zig"); - _ = @import("compiler_rt/mulxc3.zig"); - _ = @import("compiler_rt/multc3.zig"); - _ = @import("compiler_rt/divc3.zig"); - _ = @import("compiler_rt/divhc3.zig"); - _ = @import("compiler_rt/divsc3.zig"); - _ = @import("compiler_rt/divdc3.zig"); - _ = @import("compiler_rt/divxc3.zig"); - _ = @import("compiler_rt/divtc3.zig"); // Math routines. Alphabetically sorted. _ = @import("compiler_rt/cos.zig"); @@ -279,7 +145,7 @@ comptime { _ = @import("compiler_rt/divmodei4.zig"); _ = @import("compiler_rt/udivmodei4.zig"); - _ = @import("compiler_rt/limb64.zig"); + if (builtin.cpu.arch.isWasm()) _ = @import("compiler_rt/limb64.zig"); // extra _ = @import("compiler_rt/os_version_check.zig"); @@ -290,7 +156,7 @@ comptime { _ = @import("compiler_rt/clear_cache.zig"); _ = @import("compiler_rt/hexagon.zig"); - if (@import("builtin").object_format != .c) { + if (builtin.object_format != .c) { if (builtin.zig_backend != .stage2_aarch64) _ = @import("compiler_rt/atomics.zig"); _ = @import("compiler_rt/stack_probe.zig"); @@ -366,10 +232,7 @@ pub const want_aeabi = switch (builtin.abi) { .gnueabihf, .android, .androideabi, - => switch (builtin.cpu.arch) { - .arm, .armeb, .thumb, .thumbeb => true, - else => false, - }, + => builtin.cpu.arch.isArm(), else => false, }; @@ -443,17 +306,106 @@ pub const gnu_f16_abi = switch (builtin.cpu.arch) { pub const want_sparc64_abi = builtin.cpu.arch == .sparc64; pub const want_sparc32_abi = builtin.cpu.arch == .sparc; -pub fn F16T(comptime OtherType: type) type { - return switch (builtin.cpu.arch) { - .x86, .x86_64 => if (builtin.target.os.tag.isDarwin()) switch (OtherType) { - // Starting with LLVM 16, Darwin uses different abi for f16 - // depending on the type of the other return/argument..??? - f32, f64 => u16, - f80, f128 => f16, - else => unreachable, - } else f16, - else => f16, +/// For operations converting between `f16` and another floating point type. +pub fn f16Conv(comptime OtherType: type) type { + switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 16)) { + .hard => {}, + .soft => return softFloatAbi(f16), + } + if (builtin.cpu.arch.isX86() and builtin.os.tag.isDarwin()) switch (OtherType) { + else => unreachable, + // Starting with LLVM 16, Darwin uses different abi for f16 + // depending on the type of the other return/argument..??? + f32, f64 => return softFloatAbi(f16), + f80, f128 => {}, }; + return hardFloatAbi(f16); +} +pub const @"f16" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 16)) { + .hard => hardFloatAbi(f16), + .soft => softFloatAbi(f16), +}; +pub const @"f32" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 32)) { + .hard => hardFloatAbi(f32), + .soft => softFloatAbi(f32), +}; +pub const @"f64" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 64)) { + .hard => hardFloatAbi(f64), + .soft => softFloatAbi(f64), +}; +pub const @"f80" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 80)) { + .hard => hardFloatAbi(f80), + .soft => struct { + pub const Abi = extern struct { mantissa: u64, exponent: u16 }; + const Repr = packed struct { mantissa: u64, exponent: u16 }; + pub inline fn toAbi(raw: f80) Abi { + const repr: Repr = @bitCast(raw); + return .{ .mantissa = repr.mantissa, .exponent = repr.exponent }; + } + pub inline fn fromAbi(abi: Abi) f80 { + const repr: Repr = .{ .mantissa = abi.mantissa, .exponent = abi.exponent }; + return @bitCast(repr); + } + pub const complex = complexAbi(f80, @This()); + }, +}; +pub const @"f128" = switch (std.zig.target.compilerRtFloatAbi(&builtin.target, 128)) { + .hard => hardFloatAbi(f128), + .soft => struct { + pub const Abi = switch (builtin.cpu.arch.endian()) { + .big => extern struct { hi: u64, lo: u64 }, + .little => extern struct { lo: u64, hi: u64 }, + }; + const Repr = packed struct { lo: u64, hi: u64 }; + pub inline fn toAbi(raw: f128) Abi { + const repr: Repr = @bitCast(raw); + return .{ .lo = repr.lo, .hi = repr.hi }; + } + pub inline fn fromAbi(abi: Abi) f128 { + const repr: Repr = .{ .lo = abi.lo, .hi = abi.hi }; + return @bitCast(repr); + } + pub const complex = complexAbi(f128, @This()); + }, +}; +fn hardFloatAbi(comptime Float: type) type { + return struct { + pub const Abi = Float; + pub inline fn toAbi(raw: Float) Abi { + return raw; + } + pub inline fn fromAbi(abi: Abi) Float { + return abi; + } + pub const complex = complexAbi(Float, @This()); + }; +} +fn softFloatAbi(comptime Float: type) type { + return struct { + pub const Abi = @Int(.unsigned, @bitSizeOf(Float)); + pub inline fn toAbi(raw: Float) Abi { + return @bitCast(raw); + } + pub inline fn fromAbi(abi: Abi) Float { + return @bitCast(abi); + } + pub const complex = complexAbi(Float, @This()); + }; +} +fn complexAbi(comptime Float: type, comptime float: type) type { + return struct { + pub const Abi = extern struct { real: float.Abi, imag: float.Abi }; + pub inline fn toAbi(raw: Complex(Float)) Abi { + return .{ .real = float.toAbi(raw.real), .imag = float.toAbi(raw.imag) }; + } + pub inline fn fromAbi(abi: Abi) Complex(Float) { + return .{ .real = float.fromAbi(abi.real), .imag = float.fromAbi(abi.imag) }; + } + }; +} + +pub fn Complex(comptime Float: type) type { + return struct { real: Float, imag: Float }; } pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void { @@ -588,34 +540,34 @@ pub inline fn fneg(a: anytype) @TypeOf(a) { return @bitCast(negated); } -fn __negxf2(a: f80) callconv(.c) f80 { - return fneg(a); +fn __neghf2(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(fneg(compiler_rt.f16.fromAbi(a))); } -fn __neghf2(a: f16) callconv(.c) f16 { - return fneg(a); +fn __negsf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(fneg(compiler_rt.f32.fromAbi(a))); } -fn __negdf2(a: f64) callconv(.c) f64 { - return fneg(a); +fn __negdf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(fneg(compiler_rt.f64.fromAbi(a))); } -fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 { - return fneg(a); +fn __negxf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(fneg(compiler_rt.f80.fromAbi(a))); } -fn __negtf2(a: f128) callconv(.c) f128 { - return fneg(a); -} - -fn __negsf2(a: f32) callconv(.c) f32 { - return fneg(a); +fn __negtf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(fneg(compiler_rt.f128.fromAbi(a))); } fn __aeabi_fneg(a: f32) callconv(.{ .arm_aapcs = .{} }) f32 { return fneg(a); } +fn __aeabi_dneg(a: f64) callconv(.{ .arm_aapcs = .{} }) f64 { + return fneg(a); +} + /// Allows to access underlying bits as two equally sized lower and higher /// signed or unsigned integers. pub fn HalveInt(comptime T: type, comptime signed_half: bool) type { diff --git a/lib/compiler_rt/absv.zig b/lib/compiler_rt/absv.zig index 8910a4a6b9417bd099065db02f1535ace9968ee0..4621835dd6f6abd9cdb37a53231e88139556eb9a 100644 --- a/lib/compiler_rt/absv.zig +++ b/lib/compiler_rt/absv.zig @@ -14,8 +14,7 @@ pub inline fn absv(comptime ST: type, a: ST) ST { const sign: ST = a >> N - 1; x +%= sign; x ^= sign; - if (x < 0) - @panic("compiler_rt absv: overflow"); + if (x < 0) @panic("integer overflow"); return x; } diff --git a/lib/compiler_rt/absvdi2.zig b/lib/compiler_rt/absvdi2.zig index 408d70ad167d29c7895e6145e7635da95ec62a82..598629ebfc689258a055110aa976cf0d3b56226a 100644 --- a/lib/compiler_rt/absvdi2.zig +++ b/lib/compiler_rt/absvdi2.zig @@ -1,5 +1,6 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const absv = @import("./absv.zig").absv; +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; +const absv = @import("absv.zig").absv; comptime { symbol(&__absvdi2, "__absvdi2"); diff --git a/lib/compiler_rt/absvsi2.zig b/lib/compiler_rt/absvsi2.zig index 538d7f7f0155f98cf997b711514145ae77da5c2a..e01627090082800cd53ee4b614f3a68d9480c214 100644 --- a/lib/compiler_rt/absvsi2.zig +++ b/lib/compiler_rt/absvsi2.zig @@ -1,6 +1,6 @@ const compiler_rt = @import("../compiler_rt.zig"); const symbol = compiler_rt.symbol; -const absv = @import("./absv.zig").absv; +const absv = @import("absv.zig").absv; comptime { symbol(&__absvsi2, "__absvsi2"); diff --git a/lib/compiler_rt/absvti2.zig b/lib/compiler_rt/absvti2.zig index ab367d2b78ae2f0a813d011ec74dc532d103303f..008060504e318f7d9979a43d4d53ac34a8d38c76 100644 --- a/lib/compiler_rt/absvti2.zig +++ b/lib/compiler_rt/absvti2.zig @@ -1,5 +1,6 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const absv = @import("./absv.zig").absv; +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; +const absv = @import("absv.zig").absv; comptime { symbol(&__absvti2, "__absvti2"); diff --git a/lib/compiler_rt/adddf3.zig b/lib/compiler_rt/adddf3.zig deleted file mode 100644 index 7b6f252da2c7f697b23b8e9e9fd13d34cc99bc80..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/adddf3.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const addf3 = @import("./addf3.zig").addf3; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_dadd, "__aeabi_dadd"); - } else { - symbol(&__adddf3, "__adddf3"); - } -} - -fn __adddf3(a: f64, b: f64) callconv(.c) f64 { - return addf3(f64, a, b); -} - -fn __aeabi_dadd(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { - return addf3(f64, a, b); -} diff --git a/lib/compiler_rt/addf3.zig b/lib/compiler_rt/addf3.zig index 1e68c82f0fbcf3a4a28d4d9c0d877b997496d7a2..189f7afd6d02c78bdb63de8e38ca7731c96684d4 100644 --- a/lib/compiler_rt/addf3.zig +++ b/lib/compiler_rt/addf3.zig @@ -1,12 +1,143 @@ const std = @import("std"); const math = std.math; const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; const normalize = compiler_rt.normalize; +comptime { + symbol(&__addhf3, "__addhf3"); + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_fadd, "__aeabi_fadd"); + symbol(&__aeabi_dadd, "__aeabi_dadd"); + } else { + symbol(&__addsf3, "__addsf3"); + symbol(&__adddf3, "__adddf3"); + } + symbol(&__addxf3, "__addxf3"); + if (compiler_rt.want_ppc_abi) { + symbol(&__addtf3, "__addkf3"); + } else if (compiler_rt.want_sparc64_abi) { + symbol(&_Qp_add, "_Qp_add"); + } else if (compiler_rt.want_sparc32_abi) { + symbol(&__addtf3, "_Q_add"); + } else { + symbol(&__addtf3, "__addtf3"); + } +} + +fn __addhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(add_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); +} +pub fn add_f16(a: f16, b: f16) f16 { + return addf3(f16, a, b); +} + +fn __addsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(add_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); +} +fn __aeabi_fadd(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { + return add_f32(a, b); +} +pub fn add_f32(a: f32, b: f32) f32 { + return addf3(f32, a, b); +} + +fn __adddf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(add_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); +} +fn __aeabi_dadd(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { + return add_f64(a, b); +} +pub fn add_f64(a: f64, b: f64) f64 { + return addf3(f64, a, b); +} + +fn __addxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(add_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); +} +pub fn add_f80(a: f80, b: f80) f80 { + return addf3(f80, a, b); +} + +fn __addtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(add_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); +} +fn _Qp_add(c: *f128, a: *f128, b: *f128) callconv(.c) void { + c.* = add_f128(a.*, b.*); +} +pub fn add_f128(a: f128, b: f128) f128 { + return addf3(f128, a, b); +} + +comptime { + symbol(&__subhf3, "__subhf3"); + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_fsub, "__aeabi_fsub"); + symbol(&__aeabi_dsub, "__aeabi_dsub"); + } else { + symbol(&__subsf3, "__subsf3"); + symbol(&__subdf3, "__subdf3"); + } + symbol(&__subxf3, "__subxf3"); + if (compiler_rt.want_ppc_abi) { + symbol(&__subtf3, "__subkf3"); + } else if (compiler_rt.want_sparc64_abi) { + symbol(&_Qp_sub, "_Qp_sub"); + } else if (compiler_rt.want_sparc32_abi) { + symbol(&__subtf3, "_Q_sub"); + } else { + symbol(&__subtf3, "__subtf3"); + } +} + +fn __subhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(sub_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); +} +pub fn sub_f16(a: f16, b: f16) f16 { + return add_f16(a, compiler_rt.fneg(b)); +} + +fn __subsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(sub_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); +} +fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { + return sub_f32(a, b); +} +pub fn sub_f32(a: f32, b: f32) f32 { + return add_f32(a, compiler_rt.fneg(b)); +} + +fn __subdf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(sub_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); +} +fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { + return sub_f64(a, b); +} +pub fn sub_f64(a: f64, b: f64) f64 { + return add_f64(a, compiler_rt.fneg(b)); +} + +fn __subxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(sub_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); +} +pub fn sub_f80(a: f80, b: f80) f80 { + return add_f80(a, compiler_rt.fneg(b)); +} + +fn __subtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(sub_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); +} +fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { + c.* = sub_f128(a.*, b.*); +} +pub fn sub_f128(a: f128, b: f128) f128 { + return add_f128(a, compiler_rt.fneg(b)); +} + /// Ported from: /// /// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc -pub inline fn addf3(comptime T: type, a: T, b: T) T { +inline fn addf3(comptime T: type, a: T, b: T) T { const bits = @typeInfo(T).float.bits; const Z = @Int(.unsigned, bits); diff --git a/lib/compiler_rt/addf3_test.zig b/lib/compiler_rt/addf3_test.zig index 1e9bfa1bbf5403cee4cb6fc839478782714eca5b..ffa3a48086a47e9617145c0d33e049b221303ec5 100644 --- a/lib/compiler_rt/addf3_test.zig +++ b/lib/compiler_rt/addf3_test.zig @@ -8,12 +8,13 @@ const builtin = @import("builtin"); const math = std.math; const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64); -const __addtf3 = @import("addtf3.zig").__addtf3; -const __addxf3 = @import("addxf3.zig").__addxf3; -const __subtf3 = @import("subtf3.zig").__subtf3; +const impl = @import("addf3.zig"); +const add_f128 = impl.add_f128; +const add_f80 = impl.add_f80; +const sub_f128 = impl.sub_f128; fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { - const x = __addtf3(a, b); + const x = add_f128(a, b); const rep: u128 = @bitCast(x); const hi: u64 = @intCast(rep >> 64); @@ -52,7 +53,7 @@ test "addtf3" { } fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { - const x = __subtf3(a, b); + const x = sub_f128(a, b); const rep: u128 = @bitCast(x); const hi: u64 = @intCast(rep >> 64); @@ -91,7 +92,7 @@ test "subtf3" { const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))); fn test__addxf3(a: f80, b: f80, expected: u80) !void { - const x = __addxf3(a, b); + const x = add_f80(a, b); const rep: u80 = @bitCast(x); if (rep == expected) diff --git a/lib/compiler_rt/addhf3.zig b/lib/compiler_rt/addhf3.zig deleted file mode 100644 index bd13f48cac5f1ebeda2f019b1252d6a6967aa964..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/addhf3.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const addf3 = @import("./addf3.zig").addf3; - -comptime { - symbol(&__addhf3, "__addhf3"); -} - -fn __addhf3(a: f16, b: f16) callconv(.c) f16 { - return addf3(f16, a, b); -} diff --git a/lib/compiler_rt/addsf3.zig b/lib/compiler_rt/addsf3.zig deleted file mode 100644 index 4878fb704d1769469fb0a9155c930f0e24e0cabc..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/addsf3.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const addf3 = @import("./addf3.zig").addf3; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_fadd, "__aeabi_fadd"); - } else { - symbol(&__addsf3, "__addsf3"); - } -} - -fn __addsf3(a: f32, b: f32) callconv(.c) f32 { - return addf3(f32, a, b); -} - -fn __aeabi_fadd(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { - return addf3(f32, a, b); -} diff --git a/lib/compiler_rt/addtf3.zig b/lib/compiler_rt/addtf3.zig deleted file mode 100644 index 3097027f482ed73deee604acfcd7be877192d1fc..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/addtf3.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const addf3 = @import("./addf3.zig").addf3; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__addtf3, "__addkf3"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_add, "_Qp_add"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__addtf3, "_Q_add"); - } - symbol(&__addtf3, "__addtf3"); -} - -pub fn __addtf3(a: f128, b: f128) callconv(.c) f128 { - return addf3(f128, a, b); -} - -fn _Qp_add(c: *f128, a: *f128, b: *f128) callconv(.c) void { - c.* = addf3(f128, a.*, b.*); -} diff --git a/lib/compiler_rt/addvdi3.zig b/lib/compiler_rt/addvdi3.zig index a5cde2494acba14282409395aa47ce9660faa0ff..063c2bcd44f16ea3dcd14fb427b24835830190bd 100644 --- a/lib/compiler_rt/addvdi3.zig +++ b/lib/compiler_rt/addvdi3.zig @@ -1,4 +1,5 @@ -const symbol = @import("../compiler_rt.zig").symbol; +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; const testing = @import("std").testing; comptime { @@ -9,7 +10,7 @@ pub fn __addvdi3(a: i64, b: i64) callconv(.c) i64 { const sum = a +% b; // Overflow occurred iff both operands have the same sign, and the sign of the sum does // not match it. In other words, iff the sum sign is not the sign of either operand. - if (((sum ^ a) & (sum ^ b)) < 0) @panic("compiler-rt: integer overflow"); + if (((sum ^ a) & (sum ^ b)) < 0) @panic("integer overflow"); return sum; } diff --git a/lib/compiler_rt/addvsi3.zig b/lib/compiler_rt/addvsi3.zig index c35b22e8dfd73703480c89f4a5d305fa5b8ec9fd..f180f680c52e8ddc4a991838714eff4647cb57ba 100644 --- a/lib/compiler_rt/addvsi3.zig +++ b/lib/compiler_rt/addvsi3.zig @@ -10,7 +10,7 @@ pub fn __addvsi3(a: i32, b: i32) callconv(.c) i32 { const sum = a +% b; // Overflow occurred iff both operands have the same sign, and the sign of the sum does // not match it. In other words, iff the sum sign is not the sign of either operand. - if (((sum ^ a) & (sum ^ b)) < 0) @panic("compiler-rt: integer overflow"); + if (((sum ^ a) & (sum ^ b)) < 0) @panic("integer overflow"); return sum; } diff --git a/lib/compiler_rt/addxf3.zig b/lib/compiler_rt/addxf3.zig deleted file mode 100644 index f57708c98553874b47b62591b339e49b22ecedbd..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/addxf3.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const addf3 = @import("./addf3.zig").addf3; - -comptime { - symbol(&__addxf3, "__addxf3"); -} - -pub fn __addxf3(a: f80, b: f80) callconv(.c) f80 { - return addf3(f80, a, b); -} diff --git a/lib/compiler_rt/atomics.zig b/lib/compiler_rt/atomics.zig index f2c744c730b8c20501af60bf51fa78d57cb7cbc3..83b978a11ca2fad3dc2e4f8483556751c2f6e3d1 100644 --- a/lib/compiler_rt/atomics.zig +++ b/lib/compiler_rt/atomics.zig @@ -5,7 +5,7 @@ const arch = cpu.arch; const std = @import("std"); const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; +const symbol = compiler_rt.symbol; // This parameter is true iff the target architecture supports the bare minimum // to implement the atomic load/store intrinsics. diff --git a/lib/compiler_rt/aulldiv.zig b/lib/compiler_rt/aulldiv.zig index 4ed92f39eefde1b941634b5b72eac8d1e41ba0d2..3e002379220fa5e957f2d2a728435a2a11972415 100644 --- a/lib/compiler_rt/aulldiv.zig +++ b/lib/compiler_rt/aulldiv.zig @@ -1,7 +1,7 @@ const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; +const symbol = compiler_rt.symbol; comptime { if (compiler_rt.want_windows_x86_msvc_abi) { diff --git a/lib/compiler_rt/cmpdf2.zig b/lib/compiler_rt/cmpdf2.zig deleted file mode 100644 index e55972efbd00da3c3b215e722ba2277557a37525..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/cmpdf2.zig +++ /dev/null @@ -1,67 +0,0 @@ -///! The quoted behavior definitions are from -///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines -const compiler_rt = @import("../compiler_rt.zig"); -const comparef = @import("./comparef.zig"); -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_dcmpeq, "__aeabi_dcmpeq"); - symbol(&__aeabi_dcmplt, "__aeabi_dcmplt"); - symbol(&__aeabi_dcmple, "__aeabi_dcmple"); - } else { - symbol(&__eqdf2, "__eqdf2"); - symbol(&__nedf2, "__nedf2"); - symbol(&__ledf2, "__ledf2"); - symbol(&__cmpdf2, "__cmpdf2"); - symbol(&__ltdf2, "__ltdf2"); - } -} - -/// "These functions calculate a <=> b. That is, if a is less than b, they return -1; -/// if a is greater than b, they return 1; and if a and b are equal they return 0. -/// If either argument is NaN they return 1..." -/// -/// Note that this matches the definition of `__ledf2`, `__eqdf2`, `__nedf2`, `__cmpdf2`, -/// and `__ltdf2`. -fn __cmpdf2(a: f64, b: f64) callconv(.c) i32 { - return @backingInt(comparef.cmpf2(f64, comparef.LE, a, b)); -} - -/// "These functions return a value less than or equal to zero if neither argument is NaN, -/// and a is less than or equal to b." -pub fn __ledf2(a: f64, b: f64) callconv(.c) i32 { - return __cmpdf2(a, b); -} - -/// "These functions return zero if neither argument is NaN, and a and b are equal." -/// Note that due to some kind of historical accident, __eqdf2 and __nedf2 are defined -/// to have the same return value. -pub fn __eqdf2(a: f64, b: f64) callconv(.c) i32 { - return __cmpdf2(a, b); -} - -/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." -/// Note that due to some kind of historical accident, __eqdf2 and __nedf2 are defined -/// to have the same return value. -pub fn __nedf2(a: f64, b: f64) callconv(.c) i32 { - return __cmpdf2(a, b); -} - -/// "These functions return a value less than zero if neither argument is NaN, and a -/// is strictly less than b." -pub fn __ltdf2(a: f64, b: f64) callconv(.c) i32 { - return __cmpdf2(a, b); -} - -fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { - return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Equal); -} - -fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { - return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) == .Less); -} - -fn __aeabi_dcmple(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { - return @intFromBool(comparef.cmpf2(f64, comparef.LE, a, b) != .Greater); -} diff --git a/lib/compiler_rt/cmptf2.zig b/lib/compiler_rt/cmptf2.zig deleted file mode 100644 index 89418fb320b5b8ea3d2f972cf05dde162eccc7c0..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/cmptf2.zig +++ /dev/null @@ -1,146 +0,0 @@ -///! The quoted behavior definitions are from -///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines -const compiler_rt = @import("../compiler_rt.zig"); -const comparef = @import("./comparef.zig"); -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__eqtf2, "__eqkf2"); - symbol(&__netf2, "__nekf2"); - symbol(&__lttf2, "__ltkf2"); - symbol(&__letf2, "__lekf2"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_cmp, "_Qp_cmp"); - symbol(&_Qp_feq, "_Qp_feq"); - symbol(&_Qp_fne, "_Qp_fne"); - symbol(&_Qp_flt, "_Qp_flt"); - symbol(&_Qp_fle, "_Qp_fle"); - symbol(&_Qp_fgt, "_Qp_fgt"); - symbol(&_Qp_fge, "_Qp_fge"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&_Q_cmp, "_Q_cmp"); - symbol(&_Q_feq, "_Q_feq"); - symbol(&_Q_fne, "_Q_fne"); - symbol(&_Q_flt, "_Q_flt"); - symbol(&_Q_fle, "_Q_fle"); - symbol(&_Q_fgt, "_Q_fgt"); - symbol(&_Q_fge, "_Q_fge"); - } - symbol(&__eqtf2, "__eqtf2"); - symbol(&__netf2, "__netf2"); - symbol(&__letf2, "__letf2"); - symbol(&__cmptf2, "__cmptf2"); - symbol(&__lttf2, "__lttf2"); -} - -/// "These functions calculate a <=> b. That is, if a is less than b, they return -1; -/// if a is greater than b, they return 1; and if a and b are equal they return 0. -/// If either argument is NaN they return 1..." -/// -/// Note that this matches the definition of `__letf2`, `__eqtf2`, `__netf2`, `__cmptf2`, -/// and `__lttf2`. -fn __cmptf2(a: f128, b: f128) callconv(.c) i32 { - return @backingInt(comparef.cmpf2(f128, comparef.LE, a, b)); -} - -/// "These functions return a value less than or equal to zero if neither argument is NaN, -/// and a is less than or equal to b." -fn __letf2(a: f128, b: f128) callconv(.c) i32 { - return __cmptf2(a, b); -} - -/// "These functions return zero if neither argument is NaN, and a and b are equal." -/// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined -/// to have the same return value. -fn __eqtf2(a: f128, b: f128) callconv(.c) i32 { - return __cmptf2(a, b); -} - -/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." -/// Note that due to some kind of historical accident, __eqtf2 and __netf2 are defined -/// to have the same return value. -fn __netf2(a: f128, b: f128) callconv(.c) i32 { - return __cmptf2(a, b); -} - -/// "These functions return a value less than zero if neither argument is NaN, and a -/// is strictly less than b." -fn __lttf2(a: f128, b: f128) callconv(.c) i32 { - return __cmptf2(a, b); -} - -const SparcFCMP = enum(i32) { - Equal = 0, - Less = 1, - Greater = 2, - Unordered = 3, -}; - -fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.c) i32 { - return @backingInt(comparef.cmpf2(f128, SparcFCMP, a.*, b.*)); -} - -fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) bool { - return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Equal; -} - -fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) bool { - return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) != .Equal; -} - -fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) bool { - return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Less; -} - -fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) bool { - return @as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b)))) == .Greater; -} - -fn _Qp_fge(a: *const f128, b: *const f128) callconv(.c) bool { - return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b))))) { - .Equal, .Greater => true, - .Less, .Unordered => false, - }; -} - -fn _Qp_fle(a: *const f128, b: *const f128) callconv(.c) bool { - return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Qp_cmp(a, b))))) { - .Equal, .Less => true, - .Greater, .Unordered => false, - }; -} - -fn _Q_cmp(a: f128, b: f128) callconv(.c) i32 { - return @backingInt(comparef.cmpf2(f128, SparcFCMP, a, b)); -} - -fn _Q_feq(a: f128, b: f128) callconv(.c) bool { - return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Equal; -} - -fn _Q_fne(a: f128, b: f128) callconv(.c) bool { - return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) != .Equal; -} - -fn _Q_flt(a: f128, b: f128) callconv(.c) bool { - return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Less; -} - -fn _Q_fgt(a: f128, b: f128) callconv(.c) bool { - return @as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b)))) == .Greater; -} - -fn _Q_fge(a: f128, b: f128) callconv(.c) bool { - return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b))))) { - .Equal, .Greater => true, - .Less, .Unordered => false, - }; -} - -fn _Q_fle(a: f128, b: f128) callconv(.c) bool { - return switch (@as(SparcFCMP, @fromBackingInt(@intCast(_Q_cmp(a, b))))) { - .Equal, .Less => true, - .Greater, .Unordered => false, - }; -} diff --git a/lib/compiler_rt/cmpxf2.zig b/lib/compiler_rt/cmpxf2.zig deleted file mode 100644 index 8146cd83c2f05bff98a3a122de2431820d897a08..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/cmpxf2.zig +++ /dev/null @@ -1,49 +0,0 @@ -///! The quoted behavior definitions are from -///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const comparef = @import("./comparef.zig"); - -comptime { - symbol(&__eqxf2, "__eqxf2"); - symbol(&__nexf2, "__nexf2"); - symbol(&__lexf2, "__lexf2"); - symbol(&__cmpxf2, "__cmpxf2"); - symbol(&__ltxf2, "__ltxf2"); -} - -/// "These functions calculate a <=> b. That is, if a is less than b, they return -1; -/// if a is greater than b, they return 1; and if a and b are equal they return 0. -/// If either argument is NaN they return 1..." -/// -/// Note that this matches the definition of `__lexf2`, `__eqxf2`, `__nexf2`, `__cmpxf2`, -/// and `__ltxf2`. -fn __cmpxf2(a: f80, b: f80) callconv(.c) i32 { - return @backingInt(comparef.cmp_f80(comparef.LE, a, b)); -} - -/// "These functions return a value less than or equal to zero if neither argument is NaN, -/// and a is less than or equal to b." -fn __lexf2(a: f80, b: f80) callconv(.c) i32 { - return __cmpxf2(a, b); -} - -/// "These functions return zero if neither argument is NaN, and a and b are equal." -/// Note that due to some kind of historical accident, __eqxf2 and __nexf2 are defined -/// to have the same return value. -fn __eqxf2(a: f80, b: f80) callconv(.c) i32 { - return __cmpxf2(a, b); -} - -/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." -/// Note that due to some kind of historical accident, __eqxf2 and __nexf2 are defined -/// to have the same return value. -fn __nexf2(a: f80, b: f80) callconv(.c) i32 { - return __cmpxf2(a, b); -} - -/// "These functions return a value less than zero if neither argument is NaN, and a -/// is strictly less than b." -fn __ltxf2(a: f80, b: f80) callconv(.c) i32 { - return __cmpxf2(a, b); -} diff --git a/lib/compiler_rt/comparedf2_test.zig b/lib/compiler_rt/comparedf2_test.zig index dbae6bbeeca09ef401a17334d57f3f3be824c781..cb8a7b727f993f5b57d46e55cfffdafa1343cc78 100644 --- a/lib/compiler_rt/comparedf2_test.zig +++ b/lib/compiler_rt/comparedf2_test.zig @@ -5,52 +5,12 @@ const std = @import("std"); const builtin = @import("builtin"); -const __eqdf2 = @import("./cmpdf2.zig").__eqdf2; -const __ledf2 = @import("./cmpdf2.zig").__ledf2; -const __ltdf2 = @import("./cmpdf2.zig").__ltdf2; -const __nedf2 = @import("./cmpdf2.zig").__nedf2; +const compiler_rt = @import("../compiler_rt.zig"); -const __gedf2 = @import("./gedf2.zig").__gedf2; -const __gtdf2 = @import("./gedf2.zig").__gtdf2; - -const __unorddf2 = @import("./unorddf2.zig").__unorddf2; - -const TestVector = struct { - a: f64, - b: f64, - eqReference: c_int, - geReference: c_int, - gtReference: c_int, - leReference: c_int, - ltReference: c_int, - neReference: c_int, - unReference: c_int, -}; - -fn test__cmpdf2(vector: TestVector) bool { - if (__eqdf2(vector.a, vector.b) != vector.eqReference) { - return false; - } - if (__gedf2(vector.a, vector.b) != vector.geReference) { - return false; - } - if (__gtdf2(vector.a, vector.b) != vector.gtReference) { - return false; - } - if (__ledf2(vector.a, vector.b) != vector.leReference) { - return false; - } - if (__ltdf2(vector.a, vector.b) != vector.ltReference) { - return false; - } - if (__nedf2(vector.a, vector.b) != vector.neReference) { - return false; - } - if (__unorddf2(vector.a, vector.b) != vector.unReference) { - return false; - } - return true; -} +const impl = @import("comparef.zig"); +const Order = impl.Order; +const cmp_f64 = impl.cmp_f64; +const unord_f64 = impl.unord_f64; const arguments = [_]f64{ std.math.nan(f64), @@ -73,36 +33,20 @@ const arguments = [_]f64{ std.math.inf(f64), }; -fn generateVector(comptime a: f64, comptime b: f64) TestVector { - const leResult = if (a < b) -1 else if (a == b) 0 else 1; - const geResult = if (a > b) 1 else if (a == b) 0 else -1; - const unResult = if (a != a or b != b) 1 else 0; - return TestVector{ - .a = a, - .b = b, - .eqReference = leResult, - .geReference = geResult, - .gtReference = geResult, - .leReference = leResult, - .ltReference = leResult, - .neReference = leResult, - .unReference = unResult, - }; -} - -const test_vectors = init: { - @setEvalBranchQuota(10000); - var vectors: [arguments.len * arguments.len]TestVector = undefined; +test "compare f64" { for (arguments[0..], 0..) |arg_i, i| { for (arguments[0..], 0..) |arg_j, j| { - vectors[(i * arguments.len) + j] = generateVector(arg_i, arg_j); + const expected_unord = i == 0 or j == 0; + const expected_order: ?Order = if (expected_unord) null else switch (std.math.order( + if (i >= 9) i - 1 else i, + if (j >= 9) j - 1 else j, + )) { + .lt => .lt, + .eq => .eq, + .gt => .gt, + }; + try std.testing.expect(expected_order == cmp_f64(arg_i, arg_j)); + try std.testing.expect(expected_unord == unord_f64(arg_i, arg_j)); } } - break :init vectors; -}; - -test "compare f64" { - for (test_vectors) |vector| { - try std.testing.expect(test__cmpdf2(vector)); - } } diff --git a/lib/compiler_rt/comparef.zig b/lib/compiler_rt/comparef.zig index a0f7551c74c9068909ef9e10c0ea71fa93140eef..7b397ba02f9aca5a534f015726bcb143a456eb63 100644 --- a/lib/compiler_rt/comparef.zig +++ b/lib/compiler_rt/comparef.zig @@ -1,163 +1,309 @@ +const builtin = @import("builtin"); const std = @import("std"); const compiler_rt = @import("../compiler_rt.zig"); const symbol = compiler_rt.symbol; +const Unordered = if (builtin.cpu.arch == .avr) + i8 +else if (builtin.cpu.arch.isAARCH64()) + i32 +else if (builtin.target.cTypeBitSize(.long) >= builtin.target.ptrBitWidth()) + c_long +else + c_longlong; +pub const Order = enum(Unordered) { lt = -1, eq = 0, gt = 1 }; +const SparcOrder = enum(i32) { eq = 0, lt = 1, gt = 2, un = 3 }; + comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_fcmpun, "__aeabi_fcmpun"); - } else { - symbol(&__unordsf2, "__unordsf2"); - } - - symbol(&__unordxf2, "__unordxf2"); - - symbol(&__eqhf2, "__eqhf2"); - symbol(&__nehf2, "__nehf2"); - symbol(&__lehf2, "__lehf2"); symbol(&__cmphf2, "__cmphf2"); - symbol(&__lthf2, "__lthf2"); + symbol(&__cmphf2, "__eqhf2"); + symbol(&__cmphf2, "__nehf2"); + symbol(&__cmphf2, "__lthf2"); + symbol(&__cmphf2, "__lehf2"); + symbol(&__gehf2, "__gthf2"); + symbol(&__gehf2, "__gehf2"); + symbol(&__unordhf2, "__unordhf2"); if (compiler_rt.want_aeabi) { symbol(&__aeabi_fcmpeq, "__aeabi_fcmpeq"); symbol(&__aeabi_fcmplt, "__aeabi_fcmplt"); symbol(&__aeabi_fcmple, "__aeabi_fcmple"); + symbol(&__aeabi_fcmpgt, "__aeabi_fcmpgt"); + symbol(&__aeabi_fcmpge, "__aeabi_fcmpge"); + symbol(&__aeabi_fcmpun, "__aeabi_fcmpun"); + + symbol(&__aeabi_dcmpeq, "__aeabi_dcmpeq"); + symbol(&__aeabi_dcmplt, "__aeabi_dcmplt"); + symbol(&__aeabi_dcmple, "__aeabi_dcmple"); + symbol(&__aeabi_dcmpgt, "__aeabi_dcmpgt"); + symbol(&__aeabi_dcmpge, "__aeabi_dcmpge"); + symbol(&__aeabi_dcmpun, "__aeabi_dcmpun"); } else { - symbol(&__eqsf2, "__eqsf2"); - symbol(&__nesf2, "__nesf2"); - symbol(&__lesf2, "__lesf2"); symbol(&__cmpsf2, "__cmpsf2"); - symbol(&__ltsf2, "__ltsf2"); + symbol(&__cmpsf2, "__eqsf2"); + symbol(&__cmpsf2, "__nesf2"); + symbol(&__cmpsf2, "__ltsf2"); + symbol(&__cmpsf2, "__lesf2"); + symbol(&__gesf2, "__gtsf2"); + symbol(&__gesf2, "__gesf2"); + symbol(&__unordsf2, "__unordsf2"); + + symbol(&__cmpdf2, "__cmpdf2"); + symbol(&__cmpdf2, "__eqdf2"); + symbol(&__cmpdf2, "__nedf2"); + symbol(&__cmpdf2, "__ltdf2"); + symbol(&__cmpdf2, "__ledf2"); + symbol(&__gedf2, "__gtdf2"); + symbol(&__gedf2, "__gedf2"); + symbol(&__unorddf2, "__unorddf2"); } + symbol(&__cmpxf2, "__cmpxf2"); + symbol(&__cmpxf2, "__eqxf2"); + symbol(&__cmpxf2, "__nexf2"); + symbol(&__cmpxf2, "__ltxf2"); + symbol(&__cmpxf2, "__lexf2"); + symbol(&__gexf2, "__gtxf2"); + symbol(&__gexf2, "__gexf2"); + symbol(&__unordxf2, "__unordxf2"); + if (compiler_rt.want_ppc_abi) { + symbol(&__cmptf2, "__eqkf2"); + symbol(&__cmptf2, "__nekf2"); + symbol(&__cmptf2, "__ltkf2"); + symbol(&__cmptf2, "__lekf2"); + symbol(&__getf2, "__gtkf2"); + symbol(&__getf2, "__gekf2"); symbol(&__unordtf2, "__unordkf2"); + } else if (compiler_rt.want_sparc64_abi) { + symbol(&_Qp_cmp, "_Qp_cmp"); + symbol(&_Qp_feq, "_Qp_feq"); + symbol(&_Qp_fne, "_Qp_fne"); + symbol(&_Qp_flt, "_Qp_flt"); + symbol(&_Qp_fle, "_Qp_fle"); + symbol(&_Qp_fgt, "_Qp_fgt"); + symbol(&_Qp_fge, "_Qp_fge"); + } else if (compiler_rt.want_sparc32_abi) { + symbol(&_Q_cmp, "_Q_cmp"); + symbol(&_Q_feq, "_Q_feq"); + symbol(&_Q_fne, "_Q_fne"); + symbol(&_Q_flt, "_Q_flt"); + symbol(&_Q_fle, "_Q_fle"); + symbol(&_Q_fgt, "_Q_fgt"); + symbol(&_Q_fge, "_Q_fge"); + } else { + symbol(&__cmptf2, "__cmptf2"); + symbol(&__cmptf2, "__eqtf2"); + symbol(&__cmptf2, "__netf2"); + symbol(&__cmptf2, "__lttf2"); + symbol(&__cmptf2, "__letf2"); + symbol(&__getf2, "__gttf2"); + symbol(&__getf2, "__getf2"); + symbol(&__unordtf2, "__unordtf2"); } - symbol(&__unordtf2, "__unordtf2"); - symbol(&__unordhf2, "__unordhf2"); } -pub fn __unordhf2(a: f16, b: f16) callconv(.c) i32 { - return unordcmp(f16, a, b); +fn __cmphf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Order { + return cmp_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)) orelse .gt; } - -pub fn __unordtf2(a: f128, b: f128) callconv(.c) i32 { - return unordcmp(f128, a, b); +fn __gehf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Order { + return cmp_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b)) orelse .lt; } - -/// "These functions calculate a <=> b. That is, if a is less than b, they return -1; -/// if a is greater than b, they return 1; and if a and b are equal they return 0. -/// If either argument is NaN they return 1..." -/// -/// Note that this matches the definition of `__lesf2`, `__eqsf2`, `__nesf2`, `__cmpsf2`, -/// and `__ltsf2`. -fn __cmpsf2(a: f32, b: f32) callconv(.c) i32 { - return @backingInt(cmpf2(f32, LE, a, b)); +fn __unordhf2(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) Unordered { + return @intFromBool(unord_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); } - -/// "These functions return a value less than or equal to zero if neither argument is NaN, -/// and a is less than or equal to b." -pub fn __lesf2(a: f32, b: f32) callconv(.c) i32 { - return __cmpsf2(a, b); +pub fn cmp_f16(a: f16, b: f16) ?Order { + return cmpf2(f16, a, b); } - -/// "These functions return zero if neither argument is NaN, and a and b are equal." -/// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined -/// to have the same return value. -pub fn __eqsf2(a: f32, b: f32) callconv(.c) i32 { - return __cmpsf2(a, b); +pub fn unord_f16(a: f16, b: f16) bool { + return unord(f16, a, b); } -/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." -/// Note that due to some kind of historical accident, __eqsf2 and __nesf2 are defined -/// to have the same return value. -pub fn __nesf2(a: f32, b: f32) callconv(.c) i32 { - return __cmpsf2(a, b); +fn __cmpsf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Order { + return cmp_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)) orelse .gt; } - -/// "These functions return a value less than zero if neither argument is NaN, and a -/// is strictly less than b." -pub fn __ltsf2(a: f32, b: f32) callconv(.c) i32 { - return __cmpsf2(a, b); -} - fn __aeabi_fcmpeq(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { - return @intFromBool(cmpf2(f32, LE, a, b) == .Equal); + return @intFromBool(cmp_f32(a, b) == .eq); } - fn __aeabi_fcmplt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { - return @intFromBool(cmpf2(f32, LE, a, b) == .Less); + return @intFromBool(cmp_f32(a, b) == .lt); } - fn __aeabi_fcmple(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { - return @intFromBool(cmpf2(f32, LE, a, b) != .Greater); + return @intFromBool(cmp_f32(a, b) orelse .gt != .gt); } - -/// "These functions calculate a <=> b. That is, if a is less than b, they return -1; -/// if a is greater than b, they return 1; and if a and b are equal they return 0. -/// If either argument is NaN they return 1..." -/// -/// Note that this matches the definition of `__lehf2`, `__eqhf2`, `__nehf2`, `__cmphf2`, -/// and `__lthf2`. -fn __cmphf2(a: f16, b: f16) callconv(.c) i32 { - return @backingInt(cmpf2(f16, LE, a, b)); +fn __gesf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Order { + return cmp_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b)) orelse .lt; } - -/// "These functions return a value less than or equal to zero if neither argument is NaN, -/// and a is less than or equal to b." -fn __lehf2(a: f16, b: f16) callconv(.c) i32 { - return __cmphf2(a, b); +fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(cmp_f32(a, b) orelse .lt != .lt); } - -/// "These functions return zero if neither argument is NaN, and a and b are equal." -/// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined -/// to have the same return value. -fn __eqhf2(a: f16, b: f16) callconv(.c) i32 { - return __cmphf2(a, b); +fn __aeabi_fcmpgt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(cmp_f32(a, b) == .gt); } - -/// "These functions return a nonzero value if either argument is NaN, or if a and b are unequal." -/// Note that due to some kind of historical accident, __eqhf2 and __nehf2 are defined -/// to have the same return value. -fn __nehf2(a: f16, b: f16) callconv(.c) i32 { - return __cmphf2(a, b); +fn __unordsf2(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) Unordered { + return @intFromBool(unord_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); } - -/// "These functions return a value less than zero if neither argument is NaN, and a -/// is strictly less than b." -fn __lthf2(a: f16, b: f16) callconv(.c) i32 { - return __cmphf2(a, b); -} - -fn __unordxf2(a: f80, b: f80) callconv(.c) i32 { - return unordcmp(f80, a, b); -} - -pub fn __unordsf2(a: f32, b: f32) callconv(.c) i32 { - return unordcmp(f32, a, b); -} - fn __aeabi_fcmpun(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { - return unordcmp(f32, a, b); + return @intFromBool(unord_f32(a, b)); } +pub fn cmp_f32(a: f32, b: f32) ?Order { + return cmpf2(f32, a, b); +} +pub fn unord_f32(a: f32, b: f32) bool { + return unord(f32, a, b); +} + +fn __cmpdf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Order { + return cmp_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)) orelse .gt; +} +fn __aeabi_dcmpeq(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(cmp_f64(a, b) == .eq); +} +fn __aeabi_dcmplt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(cmp_f64(a, b) == .lt); +} +fn __aeabi_dcmple(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(cmp_f64(a, b) orelse .gt != .gt); +} +fn __gedf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Order { + return cmp_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b)) orelse .lt; +} +fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(cmp_f64(a, b) orelse .lt != .lt); +} +fn __aeabi_dcmpgt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(cmp_f64(a, b) == .gt); +} +fn __unorddf2(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) Unordered { + return @intFromBool(unord_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); +} +fn __aeabi_dcmpun(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return @intFromBool(unord_f64(a, b)); +} +pub fn cmp_f64(a: f64, b: f64) ?Order { + return cmpf2(f64, a, b); +} +pub fn unord_f64(a: f64, b: f64) bool { + return unord(f64, a, b); +} + +fn __cmpxf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Order { + return cmp_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)) orelse .gt; +} +fn __gexf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Order { + return cmp_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b)) orelse .lt; +} +fn __unordxf2(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) Unordered { + return @intFromBool(unord_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); +} +pub fn cmp_f80(a: f80, b: f80) ?Order { + const a_rep = std.math.F80.fromFloat(a); + const b_rep = std.math.F80.fromFloat(b); + const sig_bits = std.math.floatMantissaBits(f80); + const int_bit = 0x8000000000000000; + const sign_bit = 0x8000; + const special_exp = 0x7FFF; -pub const LE = enum(i32) { - Less = -1, - Equal = 0, - Greater = 1, + // If either a or b is NaN, they are unordered. + if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or + (b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0)) + return null; - const Unordered: LE = .Greater; -}; + // If a and b are both zeros, they are equal. + if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0) + return .eq; -pub const GE = enum(i32) { - Less = -1, - Equal = 0, - Greater = 1, + if (@intFromBool(a_rep.exp == b_rep.exp) & @intFromBool(a_rep.fraction == b_rep.fraction) != 0) { + return .eq; + } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) { + // signs are different + if (@as(i16, @bitCast(a_rep.exp)) < @as(i16, @bitCast(b_rep.exp))) { + return .lt; + } else { + return .gt; + } + } else { + const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits); + const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits); + if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) { + return .lt; + } else { + return .gt; + } + } +} +pub fn unord_f80(a: f80, b: f80) bool { + return unord(f80, a, b); +} - const Unordered: GE = .Less; -}; +fn __cmptf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Order { + return cmp_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)) orelse .gt; +} +fn __getf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Order { + return cmp_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b)) orelse .lt; +} +fn __unordtf2(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) Unordered { + return @intFromBool(unord_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); +} +fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.c) SparcOrder { + return switch (cmp_f128(a.*, b.*) orelse return .un) { + .lt => .lt, + .eq => .eq, + .gt => .gt, + }; +} +fn _Qp_feq(a: *const f128, b: *const f128) callconv(.c) i32 { + return @intFromBool(cmp_f128(a.*, b.*) == .eq); +} +fn _Qp_fne(a: *const f128, b: *const f128) callconv(.c) i32 { + return @intFromBool(cmp_f128(a.*, b.*) != .eq); +} +fn _Qp_flt(a: *const f128, b: *const f128) callconv(.c) i32 { + return @intFromBool(cmp_f128(a.*, b.*) == .lt); +} +fn _Qp_fle(a: *const f128, b: *const f128) callconv(.c) i32 { + return @intFromBool((cmp_f128(a.*, b.*) orelse .gt) != .gt); +} +fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.c) i32 { + return @intFromBool(cmp_f128(a.*, b.*) == .gt); +} +fn _Qp_fge(a: *const f128, b: *const f128) callconv(.c) i32 { + return @intFromBool((cmp_f128(a.*, b.*) orelse .lt) != .lt); +} +fn _Q_cmp(a: f128, b: f128) callconv(.c) SparcOrder { + return switch (cmp_f128(a, b) orelse return .un) { + .lt => .lt, + .eq => .eq, + .gt => .gt, + }; +} +fn _Q_feq(a: f128, b: f128) callconv(.c) i32 { + return @intFromBool(cmp_f128(a, b) == .eq); +} +fn _Q_fne(a: f128, b: f128) callconv(.c) i32 { + return @intFromBool(cmp_f128(a, b) != .eq); +} +fn _Q_flt(a: f128, b: f128) callconv(.c) i32 { + return @intFromBool(cmp_f128(a, b) == .lt); +} +fn _Q_fle(a: f128, b: f128) callconv(.c) i32 { + return @intFromBool((cmp_f128(a, b) orelse .gt) != .gt); +} +fn _Q_fgt(a: f128, b: f128) callconv(.c) i32 { + return @intFromBool(cmp_f128(a, b) == .gt); +} +fn _Q_fge(a: f128, b: f128) callconv(.c) i32 { + return @intFromBool((cmp_f128(a, b) orelse .lt) != .lt); +} +pub fn cmp_f128(a: f128, b: f128) ?Order { + return cmpf2(f128, a, b); +} +pub fn unord_f128(a: f128, b: f128) bool { + return unord(f128, a, b); +} -pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT { +inline fn cmpf2(comptime T: type, a: T, b: T) ?Order { const bits = @typeInfo(T).float.bits; const srep_t = @Int(.signed, bits); const rep_t = @Int(.unsigned, bits); @@ -175,81 +321,42 @@ pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT { const bAbs = @as(rep_t, @bitCast(bInt)) & absMask; // If either a or b is NaN, they are unordered. - if (aAbs > infRep or bAbs > infRep) return RT.Unordered; + if (aAbs > infRep or bAbs > infRep) return null; // If a and b are both zeros, they are equal. - if ((aAbs | bAbs) == 0) return .Equal; + if ((aAbs | bAbs) == 0) return .eq; // If at least one of a and b is positive, we get the same result comparing // a and b as signed integers as we would with a floating-point compare. if ((aInt & bInt) >= 0) { if (aInt < bInt) { - return .Less; + return .lt; } else if (aInt == bInt) { - return .Equal; - } else return .Greater; + return .eq; + } else return .gt; } else { // Otherwise, both are negative, so we need to flip the sense of the // comparison to get the correct result. (This assumes a twos- or ones- // complement integer representation; if integers are represented in a // sign-magnitude representation, then this flip is incorrect). if (aInt > bInt) { - return .Less; + return .lt; } else if (aInt == bInt) { - return .Equal; - } else return .Greater; + return .eq; + } else return .gt; } } -pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT { - const a_rep = std.math.F80.fromFloat(a); - const b_rep = std.math.F80.fromFloat(b); - const sig_bits = std.math.floatMantissaBits(f80); - const int_bit = 0x8000000000000000; - const sign_bit = 0x8000; - const special_exp = 0x7FFF; - - // If either a or b is NaN, they are unordered. - if ((a_rep.exp & special_exp == special_exp and a_rep.fraction ^ int_bit != 0) or - (b_rep.exp & special_exp == special_exp and b_rep.fraction ^ int_bit != 0)) - return RT.Unordered; - - // If a and b are both zeros, they are equal. - if ((a_rep.fraction | b_rep.fraction) | ((a_rep.exp | b_rep.exp) & special_exp) == 0) - return .Equal; - - if (@intFromBool(a_rep.exp == b_rep.exp) & @intFromBool(a_rep.fraction == b_rep.fraction) != 0) { - return .Equal; - } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) { - // signs are different - if (@as(i16, @bitCast(a_rep.exp)) < @as(i16, @bitCast(b_rep.exp))) { - return .Less; - } else { - return .Greater; - } - } else { - const a_fraction = a_rep.fraction | (@as(u80, a_rep.exp) << sig_bits); - const b_fraction = b_rep.fraction | (@as(u80, b_rep.exp) << sig_bits); - if ((a_fraction < b_fraction) == (a_rep.exp & sign_bit == 0)) { - return .Less; - } else { - return .Greater; - } - } -} - -test "cmp_f80" { - inline for (.{ LE, GE }) |RT| { - try std.testing.expect(cmp_f80(RT, 1.0, 1.0) == RT.Equal); - try std.testing.expect(cmp_f80(RT, 0.0, -0.0) == RT.Equal); - try std.testing.expect(cmp_f80(RT, 2.0, 4.0) == RT.Less); - try std.testing.expect(cmp_f80(RT, 2.0, -4.0) == RT.Greater); - try std.testing.expect(cmp_f80(RT, -2.0, -4.0) == RT.Greater); - try std.testing.expect(cmp_f80(RT, -2.0, 4.0) == RT.Less); - } +test cmp_f80 { + try std.testing.expect(cmp_f80(1.0, 1.0) == .eq); + try std.testing.expect(cmp_f80(0.0, -0.0) == .eq); + try std.testing.expect(cmp_f80(2.0, 4.0) == .lt); + try std.testing.expect(cmp_f80(2.0, -4.0) == .gt); + try std.testing.expect(cmp_f80(-2.0, -4.0) == .gt); + try std.testing.expect(cmp_f80(-2.0, 4.0) == .lt); } -pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 { +inline fn unord(comptime T: type, a: T, b: T) bool { const rep_t = @Int(.unsigned, @typeInfo(T).float.bits); const significandBits = std.math.floatMantissaBits(T); @@ -261,7 +368,7 @@ pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 { const aAbs: rep_t = @as(rep_t, @bitCast(a)) & absMask; const bAbs: rep_t = @as(rep_t, @bitCast(b)) & absMask; - return @intFromBool(aAbs > infRep or bAbs > infRep); + return aAbs > infRep or bAbs > infRep; } test { diff --git a/lib/compiler_rt/comparesf2_test.zig b/lib/compiler_rt/comparesf2_test.zig index d42e1ca6db124de615f2eb3a74eadfeb119992eb..5e34b00604b8f7d608cb6d21e51d8118d26d013b 100644 --- a/lib/compiler_rt/comparesf2_test.zig +++ b/lib/compiler_rt/comparesf2_test.zig @@ -5,52 +5,12 @@ const std = @import("std"); const builtin = @import("builtin"); -const __eqsf2 = @import("./comparef.zig").__eqsf2; -const __lesf2 = @import("./comparef.zig").__lesf2; -const __ltsf2 = @import("./comparef.zig").__ltsf2; -const __nesf2 = @import("./comparef.zig").__nesf2; +const compiler_rt = @import("../compiler_rt.zig"); -const __gesf2 = @import("./gesf2.zig").__gesf2; -const __gtsf2 = @import("./gesf2.zig").__gtsf2; - -const __unordsf2 = @import("./comparef.zig").__unordsf2; - -const TestVector = struct { - a: f32, - b: f32, - eqReference: c_int, - geReference: c_int, - gtReference: c_int, - leReference: c_int, - ltReference: c_int, - neReference: c_int, - unReference: c_int, -}; - -fn test__cmpsf2(vector: TestVector) bool { - if (__eqsf2(vector.a, vector.b) != vector.eqReference) { - return false; - } - if (__gesf2(vector.a, vector.b) != vector.geReference) { - return false; - } - if (__gtsf2(vector.a, vector.b) != vector.gtReference) { - return false; - } - if (__lesf2(vector.a, vector.b) != vector.leReference) { - return false; - } - if (__ltsf2(vector.a, vector.b) != vector.ltReference) { - return false; - } - if (__nesf2(vector.a, vector.b) != vector.neReference) { - return false; - } - if (__unordsf2(vector.a, vector.b) != vector.unReference) { - return false; - } - return true; -} +const impl = @import("comparef.zig"); +const Order = impl.Order; +const cmp_f32 = impl.cmp_f32; +const unord_f32 = impl.unord_f32; const arguments = [_]f32{ std.math.nan(f32), @@ -73,36 +33,20 @@ const arguments = [_]f32{ std.math.inf(f32), }; -fn generateVector(comptime a: f32, comptime b: f32) TestVector { - const leResult = if (a < b) -1 else if (a == b) 0 else 1; - const geResult = if (a > b) 1 else if (a == b) 0 else -1; - const unResult = if (a != a or b != b) 1 else 0; - return TestVector{ - .a = a, - .b = b, - .eqReference = leResult, - .geReference = geResult, - .gtReference = geResult, - .leReference = leResult, - .ltReference = leResult, - .neReference = leResult, - .unReference = unResult, - }; -} - -const test_vectors = init: { - @setEvalBranchQuota(10000); - var vectors: [arguments.len * arguments.len]TestVector = undefined; +test "compare f32" { for (arguments[0..], 0..) |arg_i, i| { for (arguments[0..], 0..) |arg_j, j| { - vectors[(i * arguments.len) + j] = generateVector(arg_i, arg_j); + const expected_unord = i == 0 or j == 0; + const expected_order: ?Order = if (expected_unord) null else switch (std.math.order( + i - @intFromBool(i >= 9), + j - @intFromBool(j >= 9), + )) { + .lt => .lt, + .eq => .eq, + .gt => .gt, + }; + try std.testing.expect(expected_order == cmp_f32(arg_i, arg_j)); + try std.testing.expect(expected_unord == unord_f32(arg_i, arg_j)); } } - break :init vectors; -}; - -test "compare f32" { - for (test_vectors) |vector| { - try std.testing.expect(test__cmpsf2(vector)); - } } diff --git a/lib/compiler_rt/cos.zig b/lib/compiler_rt/cos.zig index a207f0244f941c3e6730f9e6f5891201840120cc..612698b1e9efb080804656c50e68cd6e0a2e8680 100644 --- a/lib/compiler_rt/cos.zig +++ b/lib/compiler_rt/cos.zig @@ -13,31 +13,35 @@ const expect = std.testing.expect; const expectApproxEqAbs = std.testing.expectApproxEqAbs; const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; +const symbol = compiler_rt.symbol; const trig = @import("trig.zig"); const rem_pio2 = @import("rem_pio2.zig").rem_pio2; const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; comptime { - symbol(&cosh, "__cosh"); - symbol(&cosl, "__cosl"); + symbol(&__cosh, "__cosh"); symbol(&cosf, "cosf"); symbol(&cos, "cos"); - symbol(&cosx, "__cosx"); - if (compiler_rt.want_ppc_abi) { - symbol(&cosq, "cosf128"); - } + symbol(&__cosx, "__cosx"); + if (compiler_rt.want_ppc_abi) symbol(&cosq, "cosf128"); symbol(&cosq, "cosq"); symbol(&cosl, "cosl"); + symbol(&cosl, "__cosl"); // required by musl } -pub fn cosh(a: f16) callconv(.c) f16 { +fn __cosh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(cos_f16(compiler_rt.f16.fromAbi(x))); +} +pub fn cos_f16(x: f16) f16 { // TODO: more efficient implementation - return @floatCast(cosf(a)); + return @floatCast(cos_f32(x)); } -pub fn cosf(x: f32) callconv(.c) f32 { +fn cosf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(cos_f32(compiler_rt.f32.fromAbi(x))); +} +pub fn cos_f32(x: f32) f32 { // Small multiples of pi/2 rounded to double precision. const c1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 const c2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 @@ -94,7 +98,10 @@ pub fn cosf(x: f32) callconv(.c) f32 { }; } -pub fn cos(x: f64) callconv(.c) f64 { +fn cos(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(cos_f64(compiler_rt.f64.fromAbi(x))); +} +pub fn cos_f64(x: f64) f64 { var ix = @as(u64, @bitCast(x)) >> 32; ix &= 0x7fffffff; @@ -123,7 +130,10 @@ pub fn cos(x: f64) callconv(.c) f64 { }; } -pub fn cosx(x: f80) callconv(.c) f80 { +fn __cosx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(cos_f80(compiler_rt.f80.fromAbi(x))); +} +pub fn cos_f80(x: f80) f80 { const se = ld.signExponent(x) & 0x7fff; if (se == 0x7fff) { return x - x; @@ -147,7 +157,10 @@ pub fn cosx(x: f80) callconv(.c) f80 { }; } -pub fn cosq(x: f128) callconv(.c) f128 { +fn cosq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(cos_f128(compiler_rt.f128.fromAbi(x))); +} +pub fn cos_f128(x: f128) f128 { const se = ld.signExponent(x) & 0x7fff; if (se == 0x7fff) { return x - x; @@ -173,20 +186,21 @@ pub fn cosq(x: f128) callconv(.c) f128 { pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return cos(x), - 80 => return cosx(x), - 128 => return cosq(x), - else => @compileError("unreachable"), + 64 => return cos_f64(x), + 80 => return cos_f80(x), + 128 => return cos_f128(x), + else => comptime unreachable, } } fn testCosSpecial(comptime T: type) !void { const f = switch (T) { - f32 => cosf, - f64 => cos, - f80 => cosx, - f128 => cosq, - else => @compileError("unimplemented"), + f16 => cos_f16, + f32 => cos_f32, + f64 => cos_f64, + f80 => cos_f80, + f128 => cos_f128, + else => comptime unreachable, }; try expect(f(0.0) == 1.0); @@ -198,13 +212,13 @@ fn testCosSpecial(comptime T: type) !void { test "cos32.normal" { const epsilon = math.floatEps(f32); - try expectApproxEqAbs(@as(f32, 1.0), cosf(0.0), epsilon); - try expectApproxEqAbs(@as(f32, 0.9800666), cosf(0.2), epsilon); - try expectApproxEqAbs(@as(f32, 0.6276231), cosf(0.8923), epsilon); - try expectApproxEqAbs(@as(f32, 0.0707372), cosf(1.5), epsilon); - try expectApproxEqAbs(@as(f32, 0.0707372), cosf(-1.5), epsilon); - try expectApproxEqAbs(@as(f32, 0.96913195), cosf(37.45), epsilon); - try expectApproxEqAbs(@as(f32, 0.40079966), cosf(89.123), epsilon); + try expectApproxEqAbs(@as(f32, 1.0), cos_f32(0.0), epsilon); + try expectApproxEqAbs(@as(f32, 0.9800666), cos_f32(0.2), epsilon); + try expectApproxEqAbs(@as(f32, 0.6276231), cos_f32(0.8923), epsilon); + try expectApproxEqAbs(@as(f32, 0.0707372), cos_f32(1.5), epsilon); + try expectApproxEqAbs(@as(f32, 0.0707372), cos_f32(-1.5), epsilon); + try expectApproxEqAbs(@as(f32, 0.96913195), cos_f32(37.45), epsilon); + try expectApproxEqAbs(@as(f32, 0.40079966), cos_f32(89.123), epsilon); } test "cos32.special" { @@ -213,13 +227,13 @@ test "cos32.special" { test "cos64.normal" { const epsilon = math.floatEps(f64); - try expectApproxEqAbs(@as(f64, 1.0), cos(0.0), epsilon); - try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos(0.2), epsilon); - try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos(0.8923), epsilon); - try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(1.5), epsilon); - try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(-1.5), epsilon); - try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos(37.45), epsilon); - try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos(89.123), epsilon); + try expectApproxEqAbs(@as(f64, 1.0), cos_f64(0.0), epsilon); + try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos_f64(0.2), epsilon); + try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos_f64(0.8923), epsilon); + try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos_f64(1.5), epsilon); + try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos_f64(-1.5), epsilon); + try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos_f64(37.45), epsilon); + try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos_f64(89.123), epsilon); } test "cos64.special" { @@ -228,13 +242,13 @@ test "cos64.special" { test "cos80.normal" { const epsilon = math.floatEps(f80); - try expectApproxEqAbs(@as(f80, 1.0), cosx(0.0), epsilon); - try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cosx(0.2), epsilon); - try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cosx(0.8923), epsilon); - try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(1.5), epsilon); - try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(-1.5), epsilon); - try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cosx(37.45), epsilon); - try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cosx(89.123), epsilon); + try expectApproxEqAbs(@as(f80, 1.0), cos_f80(0.0), epsilon); + try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cos_f80(0.2), epsilon); + try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cos_f80(0.8923), epsilon); + try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cos_f80(1.5), epsilon); + try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cos_f80(-1.5), epsilon); + try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cos_f80(37.45), epsilon); + try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cos_f80(89.123), epsilon); } test "cos80.special" { @@ -243,13 +257,13 @@ test "cos80.special" { test "cos128.normal" { const epsilon = math.floatEps(f128); - try expectApproxEqAbs(@as(f128, 1.0), cosq(0.0), epsilon); - try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cosq(0.2), epsilon); - try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cosq(0.8923), epsilon); - try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(1.5), epsilon); - try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(-1.5), epsilon); - try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cosq(37.45), epsilon); - try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cosq(89.123), epsilon); + try expectApproxEqAbs(@as(f128, 1.0), cos_f128(0.0), epsilon); + try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cos_f128(0.2), epsilon); + try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cos_f128(0.8923), epsilon); + try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cos_f128(1.5), epsilon); + try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cos_f128(-1.5), epsilon); + try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cos_f128(37.45), epsilon); + try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cos_f128(89.123), epsilon); } test "cos128.special" { diff --git a/lib/compiler_rt/count0bits.zig b/lib/compiler_rt/count0bits.zig index a8d0445dc69276e4639211818eb42707a8782c6c..fca372b33b98865ec041ee3ca764a5d8207ae330 100644 --- a/lib/compiler_rt/count0bits.zig +++ b/lib/compiler_rt/count0bits.zig @@ -1,6 +1,7 @@ const builtin = @import("builtin"); const std = @import("std"); -const symbol = @import("../compiler_rt.zig").symbol; +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; comptime { symbol(&__clzsi2, "__clzsi2"); diff --git a/lib/compiler_rt/divc3.zig b/lib/compiler_rt/divc3.zig index 92d2b39f663d272bdb83042f69abcd6a91c2ba09..a76a63c7e0f9059a112dc5c3b4406349766351f6 100644 --- a/lib/compiler_rt/divc3.zig +++ b/lib/compiler_rt/divc3.zig @@ -7,12 +7,81 @@ const maxInt = std.math.maxInt; const minInt = std.math.minInt; const isFinite = std.math.isFinite; const copysign = std.math.copysign; -const Complex = @import("mulc3.zig").Complex; + +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; +const Complex = compiler_rt.Complex; + +comptime { + if (@import("builtin").zig_backend != .stage2_c) { + symbol(&__divhc3, "__divhc3"); + symbol(&__divsc3, "__divsc3"); + symbol(&__divdc3, "__divdc3"); + symbol(&__divxc3, "__divxc3"); + if (compiler_rt.want_ppc_abi) { + symbol(&__divtc3, "__divkc3"); + } else { + symbol(&__divtc3, "__divtc3"); + } + } +} + +fn __divhc3(lhs_real: compiler_rt.f16.Abi, lhs_imag: compiler_rt.f16.Abi, rhs_real: compiler_rt.f16.Abi, rhs_imag: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.complex.Abi { + return compiler_rt.f16.complex.toAbi(div_cf16( + compiler_rt.f16.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), + compiler_rt.f16.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), + )); +} +pub fn div_cf16(a: Complex(f16), b: Complex(f16)) Complex(f16) { + return divc3(f16, a, b); +} + +fn __divsc3(lhs_real: compiler_rt.f32.Abi, lhs_imag: compiler_rt.f32.Abi, rhs_real: compiler_rt.f32.Abi, rhs_imag: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.complex.Abi { + return compiler_rt.f32.complex.toAbi(div_cf32( + compiler_rt.f32.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), + compiler_rt.f32.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), + )); +} +pub fn div_cf32(a: Complex(f32), b: Complex(f32)) Complex(f32) { + return divc3(f32, a, b); +} + +fn __divdc3(lhs_real: compiler_rt.f64.Abi, lhs_imag: compiler_rt.f64.Abi, rhs_real: compiler_rt.f64.Abi, rhs_imag: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.complex.Abi { + return compiler_rt.f64.complex.toAbi(div_cf64( + compiler_rt.f64.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), + compiler_rt.f64.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), + )); +} +pub fn div_cf64(a: Complex(f64), b: Complex(f64)) Complex(f64) { + return divc3(f64, a, b); +} + +fn __divxc3(lhs_real: compiler_rt.f80.Abi, lhs_imag: compiler_rt.f80.Abi, rhs_real: compiler_rt.f80.Abi, rhs_imag: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.complex.Abi { + return compiler_rt.f80.complex.toAbi(div_cf80( + compiler_rt.f80.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), + compiler_rt.f80.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), + )); +} +pub fn div_cf80(a: Complex(f80), b: Complex(f80)) Complex(f80) { + return divc3(f80, a, b); +} + +fn __divtc3(lhs_real: compiler_rt.f128.Abi, lhs_imag: compiler_rt.f128.Abi, rhs_real: compiler_rt.f128.Abi, rhs_imag: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.complex.Abi { + return compiler_rt.f128.complex.toAbi(div_cf128( + compiler_rt.f128.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), + compiler_rt.f128.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), + )); +} +pub fn div_cf128(a: Complex(f128), b: Complex(f128)) Complex(f128) { + return divc3(f128, a, b); +} /// Implementation based on Annex G of C17 Standard (N2176) -pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { - var c = c_in; - var d = d_in; +inline fn divc3(comptime T: type, lhs: Complex(T), rhs: Complex(T)) Complex(T) { + const a = lhs.real; + const b = lhs.imag; + var c = rhs.real; + var d = rhs.imag; // logbw used to prevent under/over-flow const logbw = ilogb(@max(@abs(c), @abs(d))); @@ -23,7 +92,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { break :b logbw; } else 0; const denom = c * c + d * d; - const result = Complex(T){ + const result: Complex(T) = .{ .real = scalbn((a * c + b * d) / denom, -ilogbw), .imag = scalbn((b * c - a * d) / denom, -ilogbw), }; @@ -58,3 +127,7 @@ pub inline fn divc3(comptime T: type, a: T, b: T, c_in: T, d_in: T) Complex(T) { return result; } + +test { + _ = @import("divc3_test.zig"); +} diff --git a/lib/compiler_rt/divc3_test.zig b/lib/compiler_rt/divc3_test.zig index d3c400d46cacb1f12ec677d0f5dd0fb661bace4d..277a879253eed991a5e2cfa8453e8d28ab589f21 100644 --- a/lib/compiler_rt/divc3_test.zig +++ b/lib/compiler_rt/divc3_test.zig @@ -2,76 +2,53 @@ const std = @import("std"); const math = std.math; const expect = std.testing.expect; -const Complex = @import("./mulc3.zig").Complex; -const __divhc3 = @import("./divhc3.zig").__divhc3; -const __divsc3 = @import("./divsc3.zig").__divsc3; -const __divdc3 = @import("./divdc3.zig").__divdc3; -const __divxc3 = @import("./divxc3.zig").__divxc3; -const __divtc3 = @import("./divtc3.zig").__divtc3; +const Complex = @import("../compiler_rt.zig").Complex; + +const impl = @import("divc3.zig"); +const div_cf16 = impl.div_cf16; +const div_cf32 = impl.div_cf32; +const div_cf64 = impl.div_cf64; +const div_cf80 = impl.div_cf80; +const div_cf128 = impl.div_cf128; test "divc3" { - try testDiv(f16, __divhc3); - try testDiv(f32, __divsc3); - try testDiv(f64, __divdc3); - try testDiv(f80, __divxc3); - try testDiv(f128, __divtc3); + try testDiv(f16, div_cf16); + try testDiv(f32, div_cf32); + try testDiv(f64, div_cf64); + try testDiv(f80, div_cf80); + try testDiv(f128, div_cf128); } -fn testDiv(comptime T: type, comptime f: fn (T, T, T, T) callconv(.c) Complex(T)) !void { +fn testDiv(comptime T: type, comptime f: fn (Complex(T), Complex(T)) Complex(T)) !void { { - const a: T = 1.0; - const b: T = 0.0; - const c: T = -1.0; - const d: T = 0.0; - - const result = f(a, b, c, d); + const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -1.0, .imag = 0.0 }); try expect(result.real == -1.0); - try expect(result.imag == 0.0); + try expect(math.isNegativeZero(result.imag)); } { - const a: T = 1.0; - const b: T = 0.0; - const c: T = -4.0; - const d: T = 0.0; - - const result = f(a, b, c, d); + const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -4.0, .imag = 0.0 }); try expect(result.real == -0.25); - try expect(result.imag == 0.0); + try expect(math.isNegativeZero(result.imag)); } { // if the first operand is an infinity and the second operand is a finite number, then the - // result of the / operator is an infinity; - const a: T = -math.inf(T); - const b: T = 0.0; - const c: T = -4.0; - const d: T = 1.0; - - const result = f(a, b, c, d); - try expect(result.real == math.inf(T)); - try expect(result.imag == math.inf(T)); + // resultult of the / operator is an infinity; + const result = f(.{ .real = -math.inf(T), .imag = 0.0 }, .{ .real = -4.0, .imag = 1.0 }); + try expect(math.isPositiveInf(result.real)); + try expect(math.isPositiveInf(result.imag)); } { // if the first operand is a finite number and the second operand is an infinity, then the // result of the / operator is a zero; - const a: T = 17.2; - const b: T = 0.0; - const c: T = -math.inf(T); - const d: T = 0.0; - - const result = f(a, b, c, d); - try expect(result.real == -0.0); - try expect(result.imag == 0.0); + const result = f(.{ .real = 17.2, .imag = 0.0 }, .{ .real = -math.inf(T), .imag = 0.0 }); + try expect(math.isNegativeZero(result.real)); + try expect(math.isNegativeZero(result.imag)); } { // if the first operand is a nonzero finite number or an infinity and the second operand is // a zero, then the result of the / operator is an infinity - const a: T = 1.1; - const b: T = 0.1; - const c: T = 0.0; - const d: T = 0.0; - - const result = f(a, b, c, d); - try expect(result.real == math.inf(T)); - try expect(result.imag == math.inf(T)); + const result = f(.{ .real = 1.1, .imag = 0.1 }, .{ .real = 0.0, .imag = 0.0 }); + try expect(math.isPositiveInf(result.real)); + try expect(math.isPositiveInf(result.imag)); } } diff --git a/lib/compiler_rt/divdc3.zig b/lib/compiler_rt/divdc3.zig deleted file mode 100644 index e26dd26d61552832bcd1d19c022e8b0455551a40..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/divdc3.zig +++ /dev/null @@ -1,13 +0,0 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const divc3 = @import("./divc3.zig"); -const Complex = @import("./mulc3.zig").Complex; - -comptime { - if (@import("builtin").zig_backend != .stage2_c) { - symbol(&__divdc3, "__divdc3"); - } -} - -pub fn __divdc3(a: f64, b: f64, c: f64, d: f64) callconv(.c) Complex(f64) { - return divc3.divc3(f64, a, b, c, d); -} diff --git a/lib/compiler_rt/divdf3.zig b/lib/compiler_rt/divdf3.zig index 3ad767dbf2292d403aa0e2aafbdaf20f80ff9571..90953e0d0616d6a211872eef0b0c18ba1ff0cdb4 100644 --- a/lib/compiler_rt/divdf3.zig +++ b/lib/compiler_rt/divdf3.zig @@ -17,15 +17,15 @@ comptime { } } -pub fn __divdf3(a: f64, b: f64) callconv(.c) f64 { - return div(a, b); +fn __divdf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(div_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); } fn __aeabi_ddiv(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { - return div(a, b); + return div_f64(a, b); } -inline fn div(a: f64, b: f64) f64 { +pub fn div_f64(a: f64, b: f64) f64 { const Z = @Int(.unsigned, 64); const SignedZ = @Int(.signed, 64); diff --git a/lib/compiler_rt/divdf3_test.zig b/lib/compiler_rt/divdf3_test.zig index 45de9b27ef794706fc6e0e297f4289be3ae549fc..cd927bafc4d28921e9fb0bf191537b43cb953986 100644 --- a/lib/compiler_rt/divdf3_test.zig +++ b/lib/compiler_rt/divdf3_test.zig @@ -6,7 +6,7 @@ const std = @import("std"); const math = std.math; const testing = std.testing; -const __divdf3 = @import("divdf3.zig").__divdf3; +const div_f64 = @import("divdf3.zig").div_f64; const nanRep: u64 = @as(u64, @bitCast(math.nan(f64))); const infRep: u64 = @as(u64, @bitCast(math.inf(f64))); @@ -30,7 +30,7 @@ fn compareResultD(result: f64, expected: u64) bool { } fn test__divdf3(a: f64, b: f64, expected: u64) !void { - const x = __divdf3(a, b); + const x = div_f64(a, b); const ret = compareResultD(x, expected); try testing.expect(ret == true); } diff --git a/lib/compiler_rt/divhc3.zig b/lib/compiler_rt/divhc3.zig deleted file mode 100644 index c9668f4ca8ae84840ab3ee65446b682b6223832b..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/divhc3.zig +++ /dev/null @@ -1,14 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const divc3 = @import("./divc3.zig"); -const Complex = @import("./mulc3.zig").Complex; - -comptime { - if (@import("builtin").zig_backend != .stage2_c) { - symbol(&__divhc3, "__divhc3"); - } -} - -pub fn __divhc3(a: f16, b: f16, c: f16, d: f16) callconv(.c) Complex(f16) { - return divc3.divc3(f16, a, b, c, d); -} diff --git a/lib/compiler_rt/divhf3.zig b/lib/compiler_rt/divhf3.zig deleted file mode 100644 index fc2710ff2761fce7e8822583b86aefc562f98486..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/divhf3.zig +++ /dev/null @@ -1,11 +0,0 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const divsf3 = @import("./divsf3.zig"); - -comptime { - symbol(&__divhf3, "__divhf3"); -} - -pub fn __divhf3(a: f16, b: f16) callconv(.c) f16 { - // TODO: more efficient implementation - return @floatCast(divsf3.__divsf3(a, b)); -} diff --git a/lib/compiler_rt/divmodei4.zig b/lib/compiler_rt/divmodei4.zig index 55c7ec5792549933d22e8962f58b8cb6e23a5d54..9198951fe554a89cd2f65c69ce3fea087952db0a 100644 --- a/lib/compiler_rt/divmodei4.zig +++ b/lib/compiler_rt/divmodei4.zig @@ -5,7 +5,7 @@ const std = @import("std"); const compiler_rt = @import("../compiler_rt.zig"); const udivmod = @import("udivmodei4.zig").divmod; -const symbol = @import("../compiler_rt.zig").symbol; +const symbol = compiler_rt.symbol; comptime { symbol(&__divei4, "__divei4"); diff --git a/lib/compiler_rt/divsc3.zig b/lib/compiler_rt/divsc3.zig deleted file mode 100644 index 9378bfab8ce80584b3b5b1b6d1fbd70200ef6648..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/divsc3.zig +++ /dev/null @@ -1,13 +0,0 @@ -const divc3 = @import("./divc3.zig"); -const Complex = @import("./mulc3.zig").Complex; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (@import("builtin").zig_backend != .stage2_c) { - symbol(&__divsc3, "__divsc3"); - } -} - -pub fn __divsc3(a: f32, b: f32, c: f32, d: f32) callconv(.c) Complex(f32) { - return divc3.divc3(f32, a, b, c, d); -} diff --git a/lib/compiler_rt/divsf3.zig b/lib/compiler_rt/divsf3.zig index c0fbcb92b743fff4e12db533d7694210e7ebb0a2..c86c860948d315b260498c959e4678f5f64b9e94 100644 --- a/lib/compiler_rt/divsf3.zig +++ b/lib/compiler_rt/divsf3.zig @@ -9,6 +9,7 @@ const symbol = compiler_rt.symbol; const normalize = compiler_rt.normalize; comptime { + symbol(&__divhf3, "__divhf3"); if (compiler_rt.want_aeabi) { symbol(&__aeabi_fdiv, "__aeabi_fdiv"); } else { @@ -16,15 +17,23 @@ comptime { } } -pub fn __divsf3(a: f32, b: f32) callconv(.c) f32 { - return div(a, b); +fn __divhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(div_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); +} +pub fn div_f16(a: f16, b: f16) f16 { + // TODO: more efficient implementation + return @floatCast(div_f32(a, b)); +} + +fn __divsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(div_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); } fn __aeabi_fdiv(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { - return div(a, b); + return div_f32(a, b); } -inline fn div(a: f32, b: f32) f32 { +pub fn div_f32(a: f32, b: f32) f32 { const Z = @Int(.unsigned, 32); const significandBits = std.math.floatMantissaBits(f32); diff --git a/lib/compiler_rt/divsf3_test.zig b/lib/compiler_rt/divsf3_test.zig index c457915e49cd41986f1470b2f868398cfad855e9..f12e152b31b41b1fd85d1f1493838dd68a43f983 100644 --- a/lib/compiler_rt/divsf3_test.zig +++ b/lib/compiler_rt/divsf3_test.zig @@ -6,7 +6,7 @@ const std = @import("std"); const math = std.math; const testing = std.testing; -const __divsf3 = @import("divsf3.zig").__divsf3; +const div_f32 = @import("divsf3.zig").div_f32; const nanRep: u32 = @as(u32, @bitCast(math.nan(f32))); const infRep: u32 = @as(u32, @bitCast(math.inf(f32))); @@ -30,7 +30,7 @@ fn compareResultF(result: f32, expected: u32) bool { } fn test__divsf3(a: f32, b: f32, expected: u32) !void { - const x = __divsf3(a, b); + const x = div_f32(a, b); const ret = compareResultF(x, expected); try testing.expect(ret == true); } diff --git a/lib/compiler_rt/divtc3.zig b/lib/compiler_rt/divtc3.zig deleted file mode 100644 index b0e0f35f5447488f4d15ba76ede68bab2425f96b..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/divtc3.zig +++ /dev/null @@ -1,16 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const divc3 = @import("./divc3.zig"); -const Complex = @import("./mulc3.zig").Complex; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (@import("builtin").zig_backend != .stage2_c) { - if (compiler_rt.want_ppc_abi) - symbol(&__divtc3, "__divkc3"); - symbol(&__divtc3, "__divtc3"); - } -} - -pub fn __divtc3(a: f128, b: f128, c: f128, d: f128) callconv(.c) Complex(f128) { - return divc3.divc3(f128, a, b, c, d); -} diff --git a/lib/compiler_rt/divtf3.zig b/lib/compiler_rt/divtf3.zig index 3b6f648e3ac33e2fb3183bdd7fcb892ea239500c..9995a9bfd796070d9573ac050bf233c9646a5d98 100644 --- a/lib/compiler_rt/divtf3.zig +++ b/lib/compiler_rt/divtf3.zig @@ -13,19 +13,20 @@ comptime { symbol(&_Qp_div, "_Qp_div"); } else if (compiler_rt.want_sparc32_abi) { symbol(&__divtf3, "_Q_div"); + } else { + symbol(&__divtf3, "__divtf3"); } - symbol(&__divtf3, "__divtf3"); } -pub fn __divtf3(a: f128, b: f128) callconv(.c) f128 { - return div(a, b); +fn __divtf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(div_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); } fn _Qp_div(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { - c.* = div(a.*, b.*); + c.* = div_f128(a.*, b.*); } -inline fn div(a: f128, b: f128) f128 { +pub fn div_f128(a: f128, b: f128) f128 { const Z = @Int(.unsigned, 128); const significandBits = std.math.floatMantissaBits(f128); diff --git a/lib/compiler_rt/divtf3_test.zig b/lib/compiler_rt/divtf3_test.zig index 4d10e5c39d7dc61b1c317364750757148635543d..dfc7e1e954ea96eb6927f4c56179efc15fe4a2ee 100644 --- a/lib/compiler_rt/divtf3_test.zig +++ b/lib/compiler_rt/divtf3_test.zig @@ -2,7 +2,7 @@ const std = @import("std"); const math = std.math; const testing = std.testing; -const __divtf3 = @import("divtf3.zig").__divtf3; +const div_f128 = @import("divtf3.zig").div_f128; fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { const rep: u128 = @bitCast(result); @@ -24,7 +24,7 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { } fn test__divtf3(a: f128, b: f128, expectedHi: u64, expectedLo: u64) !void { - const x = __divtf3(a, b); + const x = div_f128(a, b); const ret = compareResultLD(x, expectedHi, expectedLo); try testing.expect(ret == true); } diff --git a/lib/compiler_rt/divxc3.zig b/lib/compiler_rt/divxc3.zig deleted file mode 100644 index 86c737a83931c6c34f73303eeaba00536d8e1bd4..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/divxc3.zig +++ /dev/null @@ -1,13 +0,0 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const divc3 = @import("./divc3.zig"); -const Complex = @import("./mulc3.zig").Complex; - -comptime { - if (@import("builtin").zig_backend != .stage2_c) { - symbol(&__divxc3, "__divxc3"); - } -} - -pub fn __divxc3(a: f80, b: f80, c: f80, d: f80) callconv(.c) Complex(f80) { - return divc3.divc3(f80, a, b, c, d); -} diff --git a/lib/compiler_rt/divxf3.zig b/lib/compiler_rt/divxf3.zig index fdf43dc83bce6adbb53995826c516aecd7310fe2..eb3fde6862ab3937e8828d729287a35ea9d3ead9 100644 --- a/lib/compiler_rt/divxf3.zig +++ b/lib/compiler_rt/divxf3.zig @@ -11,7 +11,10 @@ comptime { symbol(&__divxf3, "__divxf3"); } -pub fn __divxf3(a: f80, b: f80) callconv(.c) f80 { +fn __divxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(div_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); +} +pub fn div_f80(a: f80, b: f80) f80 { const T = f80; const Z = @Int(.unsigned, @bitSizeOf(T)); diff --git a/lib/compiler_rt/divxf3_test.zig b/lib/compiler_rt/divxf3_test.zig index cb897a1014022d50e8cb93043749b033b56af55d..88d7cada4606920997b5b0030134aaab476da576 100644 --- a/lib/compiler_rt/divxf3_test.zig +++ b/lib/compiler_rt/divxf3_test.zig @@ -2,7 +2,7 @@ const std = @import("std"); const math = std.math; const testing = std.testing; -const __divxf3 = @import("divxf3.zig").__divxf3; +const div_f80 = @import("divxf3.zig").div_f80; const nanRep: u80 = @as(u80, @bitCast(math.nan(f80))); const infRep: u80 = @as(u80, @bitCast(math.inf(f80))); @@ -19,14 +19,14 @@ fn compareResult(result: f80, expected: u80) bool { } fn expect__divxf3_result(a: f80, b: f80, expected: u80) !void { - const x = __divxf3(a, b); + const x = div_f80(a, b); const ret = compareResult(x, expected); try testing.expect(ret == true); } fn test__divxf3(a: f80, b: f80) !void { const integerBit = 1 << math.floatFractionalBits(f80); - const x = __divxf3(a, b); + const x = div_f80(a, b); // Next float (assuming normal, non-zero result) const x_plus_eps: f80 = @bitCast((@as(u80, @bitCast(x)) + 1) | integerBit); diff --git a/lib/compiler_rt/exp.zig b/lib/compiler_rt/exp.zig index ce2eadb7f1edfe49ca51562a8b3ec4432f2017eb..ddec21869f166538e3497bb84050e55eba3ff33c 100644 --- a/lib/compiler_rt/exp.zig +++ b/lib/compiler_rt/exp.zig @@ -14,7 +14,7 @@ const expect = std.testing.expect; const expectEqual = std.testing.expectEqual; const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; +const symbol = compiler_rt.symbol; comptime { symbol(&__exph, "__exph"); @@ -28,12 +28,18 @@ comptime { symbol(&expl, "expl"); } -pub fn __exph(a: f16) callconv(.c) f16 { +fn __exph(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(exp_f16(compiler_rt.f16.fromAbi(x))); +} +pub fn exp_f16(x: f16) f16 { // TODO: more efficient implementation - return @floatCast(expf(a)); + return @floatCast(exp_f32(x)); } -pub fn expf(x_: f32) callconv(.c) f32 { +fn expf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(exp_f32(compiler_rt.f32.fromAbi(x))); +} +pub fn exp_f32(x_: f32) f32 { const half = [_]f32{ 0.5, -0.5 }; const ln2hi = 6.9314575195e-1; const ln2lo = 1.4286067653e-6; @@ -108,7 +114,10 @@ pub fn expf(x_: f32) callconv(.c) f32 { } } -pub fn exp(x_: f64) callconv(.c) f64 { +fn exp(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(exp_f64(compiler_rt.f64.fromAbi(x))); +} +pub fn exp_f64(x_: f64) f64 { const half = [_]f64{ 0.5, -0.5 }; const ln2hi: f64 = 6.93147180369123816490e-01; const ln2lo: f64 = 1.90821492927058770002e-10; @@ -189,116 +198,121 @@ pub fn exp(x_: f64) callconv(.c) f64 { } } -pub fn __expx(a: f80) callconv(.c) f80 { +fn __expx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(exp_f80(compiler_rt.f80.fromAbi(x))); +} +pub fn exp_f80(x: f80) f80 { // TODO: more efficient implementation - return @floatCast(expq(a)); + return @floatCast(exp_f128(x)); } -const expq = @import("exp_f128.zig").exp; +fn expq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(exp_f128(compiler_rt.f128.fromAbi(x))); +} +pub const exp_f128 = @import("exp_f128.zig").exp; pub fn expl(x: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return exp(x), - 80 => return __expx(x), - 128 => return expq(x), - else => @compileError("unreachable"), + 64 => return exp_f64(x), + 80 => return exp_f80(x), + 128 => return exp_f128(x), + else => comptime unreachable, } } test "expf() special" { - try expectEqual(expf(0.0), 1.0); - try expectEqual(expf(-0.0), 1.0); - try expectEqual(expf(1.0), math.e); - try expectEqual(expf(math.ln2), 2.0); - try expectEqual(expf(math.inf(f32)), math.inf(f32)); - try expect(math.isPositiveZero(expf(-math.inf(f32)))); - try expect(math.isNan(expf(math.nan(f32)))); - try expect(math.isNan(expf(math.snan(f32)))); + try expectEqual(exp_f32(0.0), 1.0); + try expectEqual(exp_f32(-0.0), 1.0); + try expectEqual(exp_f32(1.0), math.e); + try expectEqual(exp_f32(math.ln2), 2.0); + try expectEqual(exp_f32(math.inf(f32)), math.inf(f32)); + try expect(math.isPositiveZero(exp_f32(-math.inf(f32)))); + try expect(math.isNan(exp_f32(math.nan(f32)))); + try expect(math.isNan(exp_f32(math.snan(f32)))); } test "expf() sanity" { - try expectEqual(expf(-0x1.0223a0p+3), 0x1.490320p-12); - try expectEqual(expf(0x1.161868p+2), 0x1.34712ap+6); - try expectEqual(expf(-0x1.0c34b4p+3), 0x1.e06b1ap-13); - try expectEqual(expf(-0x1.a206f0p+2), 0x1.7dd484p-10); - try expectEqual(expf(0x1.288bbcp+3), 0x1.4abc80p+13); - try expectEqual(expf(0x1.52efd0p-1), 0x1.f04a9cp+0); - try expectEqual(expf(-0x1.a05cc8p-2), 0x1.54f1e0p-1); - try expectEqual(expf(0x1.1f9efap-1), 0x1.c0f628p+0); - try expectEqual(expf(0x1.8c5db0p-1), 0x1.1599b2p+1); - try expectEqual(expf(-0x1.5b86eap-1), 0x1.03b572p-1); - try expectEqual(expf(-0x1.57f25cp+2), 0x1.2fbea2p-8); - try expectEqual(expf(0x1.c7d310p+3), 0x1.76eefp+20); - try expectEqual(expf(0x1.19be70p+4), 0x1.52d3dep+25); - try expectEqual(expf(-0x1.ab6d70p+3), 0x1.a88adep-20); - try expectEqual(expf(-0x1.5ac18ep+2), 0x1.22b328p-8); - try expectEqual(expf(-0x1.925982p-1), 0x1.d2acc0p-2); - try expectEqual(expf(0x1.7221cep+3), 0x1.9c2ceap+16); - try expectEqual(expf(0x1.11a0d4p+4), 0x1.980ee6p+24); - try expectEqual(expf(-0x1.ae41a2p+1), 0x1.1c28d0p-5); - try expectEqual(expf(-0x1.329154p+4), 0x1.47ef94p-28); + try expectEqual(exp_f32(-0x1.0223a0p+3), 0x1.490320p-12); + try expectEqual(exp_f32(0x1.161868p+2), 0x1.34712ap+6); + try expectEqual(exp_f32(-0x1.0c34b4p+3), 0x1.e06b1ap-13); + try expectEqual(exp_f32(-0x1.a206f0p+2), 0x1.7dd484p-10); + try expectEqual(exp_f32(0x1.288bbcp+3), 0x1.4abc80p+13); + try expectEqual(exp_f32(0x1.52efd0p-1), 0x1.f04a9cp+0); + try expectEqual(exp_f32(-0x1.a05cc8p-2), 0x1.54f1e0p-1); + try expectEqual(exp_f32(0x1.1f9efap-1), 0x1.c0f628p+0); + try expectEqual(exp_f32(0x1.8c5db0p-1), 0x1.1599b2p+1); + try expectEqual(exp_f32(-0x1.5b86eap-1), 0x1.03b572p-1); + try expectEqual(exp_f32(-0x1.57f25cp+2), 0x1.2fbea2p-8); + try expectEqual(exp_f32(0x1.c7d310p+3), 0x1.76eefp+20); + try expectEqual(exp_f32(0x1.19be70p+4), 0x1.52d3dep+25); + try expectEqual(exp_f32(-0x1.ab6d70p+3), 0x1.a88adep-20); + try expectEqual(exp_f32(-0x1.5ac18ep+2), 0x1.22b328p-8); + try expectEqual(exp_f32(-0x1.925982p-1), 0x1.d2acc0p-2); + try expectEqual(exp_f32(0x1.7221cep+3), 0x1.9c2ceap+16); + try expectEqual(exp_f32(0x1.11a0d4p+4), 0x1.980ee6p+24); + try expectEqual(exp_f32(-0x1.ae41a2p+1), 0x1.1c28d0p-5); + try expectEqual(exp_f32(-0x1.329154p+4), 0x1.47ef94p-28); } test "expf() boundary" { - try expectEqual(expf(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite - try expectEqual(expf(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf - try expectEqual(expf(0x1.fffffep+127), math.inf(f32)); // Max input value - try expectEqual(expf(0x1p-149), 1.0); // Min positive input value - try expectEqual(expf(-0x1p-149), 1.0); // Min negative input value - try expectEqual(expf(0x1p-126), 1.0); // First positive subnormal input - try expectEqual(expf(-0x1p-126), 1.0); // First negative subnormal input - try expectEqual(expf(-0x1.9fe368p+6), 0x1p-149); // The last value before the result flushes to zero - try expectEqual(expf(-0x1.9fe36ap+6), 0.0); // The first value at which the result flushes to zero - try expectEqual(expf(-0x1.5d589ep+6), 0x1.00004cp-126); // The last value before the result flushes to subnormal - try expectEqual(expf(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal - + try expectEqual(exp_f32(0x1.62e42ep+6), 0x1.ffff08p+127); // The last value before the result gets infinite + try expectEqual(exp_f32(0x1.62e430p+6), math.inf(f32)); // The first value that gives inf + try expectEqual(exp_f32(0x1.fffffep+127), math.inf(f32)); // Max input value + try expectEqual(exp_f32(0x1p-149), 1.0); // Min positive input value + try expectEqual(exp_f32(-0x1p-149), 1.0); // Min negative input value + try expectEqual(exp_f32(0x1p-126), 1.0); // First positive subnormal input + try expectEqual(exp_f32(-0x1p-126), 1.0); // First negative subnormal input + try expectEqual(exp_f32(-0x1.9fe368p+6), 0x1p-149); // The last value before the result flushes to zero + try expectEqual(exp_f32(-0x1.9fe36ap+6), 0.0); // The first value at which the result flushes to zero + try expectEqual(exp_f32(-0x1.5d589ep+6), 0x1.00004cp-126); // The last value before the result flushes to subnormal + try expectEqual(exp_f32(-0x1.5d58a0p+6), 0x1.ffff98p-127); // The first value for which the result flushes to subnormal } test "exp() special" { - try expectEqual(exp(0.0), 1.0); - try expectEqual(exp(-0.0), 1.0); + try expectEqual(exp_f64(0.0), 1.0); + try expectEqual(exp_f64(-0.0), 1.0); // TODO: Accuracy error - off in the last bit in 64-bit, disagreeing with GCC // try expectEqual(exp(1.0), math.e); - try expectEqual(exp(math.ln2), 2.0); - try expectEqual(exp(math.inf(f64)), math.inf(f64)); - try expect(math.isPositiveZero(exp(-math.inf(f64)))); - try expect(math.isNan(exp(math.nan(f64)))); - try expect(math.isNan(exp(math.snan(f64)))); + try expectEqual(exp_f64(math.ln2), 2.0); + try expectEqual(exp_f64(math.inf(f64)), math.inf(f64)); + try expect(math.isPositiveZero(exp_f64(-math.inf(f64)))); + try expect(math.isNan(exp_f64(math.nan(f64)))); + try expect(math.isNan(exp_f64(math.snan(f64)))); } test "exp() sanity" { - try expectEqual(exp(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12); - try expectEqual(exp(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6); - try expectEqual(exp(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13); - try expectEqual(exp(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10); - try expectEqual(exp(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13); - try expectEqual(exp(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0); - try expectEqual(exp(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1); - try expectEqual(exp(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0); - try expectEqual(exp(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1); - try expectEqual(exp(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1); - try expectEqual(exp(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8); - try expectEqual(exp(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20); - try expectEqual(exp(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25); - try expectEqual(exp(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20); - try expectEqual(exp(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8); - try expectEqual(exp(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2); - try expectEqual(exp(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16); - try expectEqual(exp(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24); - try expectEqual(exp(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5); - try expectEqual(exp(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28); + try expectEqual(exp_f64(-0x1.02239f3c6a8f1p+3), 0x1.490327ea61235p-12); + try expectEqual(exp_f64(0x1.161868e18bc67p+2), 0x1.34712ed238c04p+6); + try expectEqual(exp_f64(-0x1.0c34b3e01e6e7p+3), 0x1.e06b1b6c18e64p-13); + try expectEqual(exp_f64(-0x1.a206f0a19dcc4p+2), 0x1.7dd47f810e68cp-10); + try expectEqual(exp_f64(0x1.288bbb0d6a1e6p+3), 0x1.4abc77496e07ep+13); + try expectEqual(exp_f64(0x1.52efd0cd80497p-1), 0x1.f04a9c1080500p+0); + try expectEqual(exp_f64(-0x1.a05cc754481d1p-2), 0x1.54f1e0fd3ea0dp-1); + try expectEqual(exp_f64(0x1.1f9ef934745cbp-1), 0x1.c0f6266a6a547p+0); + try expectEqual(exp_f64(0x1.8c5db097f7442p-1), 0x1.1599b1d4a25fbp+1); + try expectEqual(exp_f64(-0x1.5b86ea8118a0ep-1), 0x1.03b5728a00229p-1); + try expectEqual(exp_f64(-0x1.57f25b2b5006dp+2), 0x1.2fbea6a01cab9p-8); + try expectEqual(exp_f64(0x1.c7d30fb825911p+3), 0x1.76eeed45a0634p+20); + try expectEqual(exp_f64(0x1.19be709de7505p+4), 0x1.52d3eb7be6844p+25); + try expectEqual(exp_f64(-0x1.ab6d6fba96889p+3), 0x1.a88ae12f985d6p-20); + try expectEqual(exp_f64(-0x1.5ac18e27084ddp+2), 0x1.22b327da9cca6p-8); + try expectEqual(exp_f64(-0x1.925981b093c41p-1), 0x1.d2acc046b55f7p-2); + try expectEqual(exp_f64(0x1.7221cd18455f5p+3), 0x1.9c2cde8699cfbp+16); + try expectEqual(exp_f64(0x1.11a0d4a51b239p+4), 0x1.980ef612ff182p+24); + try expectEqual(exp_f64(-0x1.ae41a1079de4dp+1), 0x1.1c28d16bb3222p-5); + try expectEqual(exp_f64(-0x1.329153103b871p+4), 0x1.47efa6ddd0d22p-28); } test "exp() boundary" { - try expectEqual(exp(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite - try expectEqual(exp(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf - try expectEqual(exp(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value - try expectEqual(exp(0x1p-1074), 1.0); // Min positive input value - try expectEqual(exp(-0x1p-1074), 1.0); // Min negative input value - try expectEqual(exp(0x1p-1022), 1.0); // First positive subnormal input - try expectEqual(exp(-0x1p-1022), 1.0); // First negative subnormal input - try expectEqual(exp(-0x1.74910d52d3051p+9), 0x1p-1074); // The last value before the result flushes to zero - try expectEqual(exp(-0x1.74910d52d3052p+9), 0.0); // The first value at which the result flushes to zero - try expectEqual(exp(-0x1.6232bdd7abcd2p+9), 0x1.000000000007cp-1022); // The last value before the result flushes to subnormal - try expectEqual(exp(-0x1.6232bdd7abcd3p+9), 0x1.ffffffffffcf8p-1023); // The first value for which the result flushes to subnormal + try expectEqual(exp_f64(0x1.62e42fefa39efp+9), 0x1.fffffffffff2ap+1023); // The last value before the result gets infinite + try expectEqual(exp_f64(0x1.62e42fefa39f0p+9), math.inf(f64)); // The first value that gives inf + try expectEqual(exp_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value + try expectEqual(exp_f64(0x1p-1074), 1.0); // Min positive input value + try expectEqual(exp_f64(-0x1p-1074), 1.0); // Min negative input value + try expectEqual(exp_f64(0x1p-1022), 1.0); // First positive subnormal input + try expectEqual(exp_f64(-0x1p-1022), 1.0); // First negative subnormal input + try expectEqual(exp_f64(-0x1.74910d52d3051p+9), 0x1p-1074); // The last value before the result flushes to zero + try expectEqual(exp_f64(-0x1.74910d52d3052p+9), 0.0); // The first value at which the result flushes to zero + try expectEqual(exp_f64(-0x1.6232bdd7abcd2p+9), 0x1.000000000007cp-1022); // The last value before the result flushes to subnormal + try expectEqual(exp_f64(-0x1.6232bdd7abcd3p+9), 0x1.ffffffffffcf8p-1023); // The first value for which the result flushes to subnormal } diff --git a/lib/compiler_rt/exp2.zig b/lib/compiler_rt/exp2.zig index abcef881073619a860997766283c950cc702a3e6..36ee7c14c90be2c13dd0e09ca91d656a19a539a7 100644 --- a/lib/compiler_rt/exp2.zig +++ b/lib/compiler_rt/exp2.zig @@ -26,12 +26,18 @@ comptime { symbol(&exp2l, "exp2l"); } -pub fn __exp2h(x: f16) callconv(.c) f16 { +fn __exp2h(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(exp2_f16(compiler_rt.f16.fromAbi(x))); +} +pub fn exp2_f16(x: f16) f16 { // TODO: more efficient implementation - return @floatCast(exp2f(x)); + return @floatCast(exp2_f32(x)); } -pub fn exp2f(x: f32) callconv(.c) f32 { +fn exp2f(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(exp2_f32(compiler_rt.f32.fromAbi(x))); +} +pub fn exp2_f32(x: f32) f32 { const tblsiz: u32 = @intCast(exp2ft.len); const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz)); const P1: f32 = 0x1.62e430p-1; @@ -88,7 +94,10 @@ pub fn exp2f(x: f32) callconv(.c) f32 { return @floatCast(r * uk); } -pub fn exp2(x: f64) callconv(.c) f64 { +fn exp2(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(exp2_f64(compiler_rt.f64.fromAbi(x))); +} +pub fn exp2_f64(x: f64) f64 { const tblsiz: u32 = @intCast(exp2dt.len / 2); const redux: f64 = 0x1.8p52 / @as(f64, @floatFromInt(tblsiz)); const P1: f64 = 0x1.62e42fefa39efp-1; @@ -156,19 +165,25 @@ pub fn exp2(x: f64) callconv(.c) f64 { return math.scalbn(r, ik); } -pub fn __exp2x(x: f80) callconv(.c) f80 { +fn __exp2x(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(exp2_f80(compiler_rt.f80.fromAbi(x))); +} +pub fn exp2_f80(x: f80) f80 { // TODO: more efficient implementation - return @floatCast(exp2q(x)); + return @floatCast(exp2_f128(x)); } -pub const exp2q = @import("exp_f128.zig").exp2; +fn exp2q(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(exp2_f128(compiler_rt.f128.fromAbi(x))); +} +pub const exp2_f128 = @import("exp_f128.zig").exp2; pub fn exp2l(x: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return exp2(x), - 80 => return __exp2x(x), - 128 => return exp2q(x), - else => @compileError("unreachable"), + 64 => return exp2_f64(x), + 80 => return exp2_f80(x), + 128 => return exp2_f128(x), + else => comptime unreachable, } } @@ -452,77 +467,77 @@ const exp2dt = [_]f64{ }; test "exp2f() special" { - try expectEqual(exp2f(0.0), 1.0); - try expectEqual(exp2f(-0.0), 1.0); - try expectEqual(exp2f(1.0), 2.0); - try expectEqual(exp2f(-1.0), 0.5); - try expectEqual(exp2f(math.inf(f32)), math.inf(f32)); - try expect(math.isPositiveZero(exp2f(-math.inf(f32)))); - try expect(math.isNan(exp2f(math.nan(f32)))); - try expect(math.isNan(exp2f(math.snan(f32)))); + try expectEqual(exp2_f32(0.0), 1.0); + try expectEqual(exp2_f32(-0.0), 1.0); + try expectEqual(exp2_f32(1.0), 2.0); + try expectEqual(exp2_f32(-1.0), 0.5); + try expectEqual(exp2_f32(math.inf(f32)), math.inf(f32)); + try expect(math.isPositiveZero(exp2_f32(-math.inf(f32)))); + try expect(math.isNan(exp2_f32(math.nan(f32)))); + try expect(math.isNan(exp2_f32(math.snan(f32)))); } test "exp2f() sanity" { - try expectEqual(exp2f(-0x1.0223a0p+3), 0x1.e8d134p-9); - try expectEqual(exp2f(0x1.161868p+2), 0x1.453672p+4); - try expectEqual(exp2f(-0x1.0c34b4p+3), 0x1.890ca0p-9); - try expectEqual(exp2f(-0x1.a206f0p+2), 0x1.622d4ep-7); - try expectEqual(exp2f(0x1.288bbcp+3), 0x1.340ecep+9); - try expectEqual(exp2f(0x1.52efd0p-1), 0x1.950eeep+0); - try expectEqual(exp2f(-0x1.a05cc8p-2), 0x1.824056p-1); - try expectEqual(exp2f(0x1.1f9efap-1), 0x1.79dfa2p+0); - try expectEqual(exp2f(0x1.8c5db0p-1), 0x1.b5ceacp+0); - try expectEqual(exp2f(-0x1.5b86eap-1), 0x1.3fd8bap-1); + try expectEqual(exp2_f32(-0x1.0223a0p+3), 0x1.e8d134p-9); + try expectEqual(exp2_f32(0x1.161868p+2), 0x1.453672p+4); + try expectEqual(exp2_f32(-0x1.0c34b4p+3), 0x1.890ca0p-9); + try expectEqual(exp2_f32(-0x1.a206f0p+2), 0x1.622d4ep-7); + try expectEqual(exp2_f32(0x1.288bbcp+3), 0x1.340ecep+9); + try expectEqual(exp2_f32(0x1.52efd0p-1), 0x1.950eeep+0); + try expectEqual(exp2_f32(-0x1.a05cc8p-2), 0x1.824056p-1); + try expectEqual(exp2_f32(0x1.1f9efap-1), 0x1.79dfa2p+0); + try expectEqual(exp2_f32(0x1.8c5db0p-1), 0x1.b5ceacp+0); + try expectEqual(exp2_f32(-0x1.5b86eap-1), 0x1.3fd8bap-1); } test "exp2f() boundary" { - try expectEqual(exp2f(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite - try expectEqual(exp2f(0x1p+7), math.inf(f32)); // The first value that gives infinite result - try expectEqual(exp2f(-0x1.2bccccp+7), 0x1p-149); // The last value before the result flushes to zero - try expectEqual(exp2f(-0x1.2cp+7), 0); // The first value at which the result flushes to zero - try expectEqual(exp2f(-0x1.f8p+6), 0x1p-126); // The last value before the result flushes to subnormal - try expectEqual(exp2f(-0x1.f80002p+6), 0x1.ffff50p-127); // The first value for which the result flushes to subnormal - try expectEqual(exp2f(0x1.fffffep+127), math.inf(f32)); // Max input value - try expectEqual(exp2f(0x1p-149), 1); // Min positive input value - try expectEqual(exp2f(-0x1p-149), 1); // Min negative input value - try expectEqual(exp2f(0x1p-126), 1); // First positive subnormal input - try expectEqual(exp2f(-0x1p-126), 1); // First negative subnormal input + try expectEqual(exp2_f32(0x1.fffffep+6), 0x1.ffff4ep+127); // The last value before the result gets infinite + try expectEqual(exp2_f32(0x1p+7), math.inf(f32)); // The first value that gives infinite result + try expectEqual(exp2_f32(-0x1.2bccccp+7), 0x1p-149); // The last value before the result flushes to zero + try expectEqual(exp2_f32(-0x1.2cp+7), 0); // The first value at which the result flushes to zero + try expectEqual(exp2_f32(-0x1.f8p+6), 0x1p-126); // The last value before the result flushes to subnormal + try expectEqual(exp2_f32(-0x1.f80002p+6), 0x1.ffff50p-127); // The first value for which the result flushes to subnormal + try expectEqual(exp2_f32(0x1.fffffep+127), math.inf(f32)); // Max input value + try expectEqual(exp2_f32(0x1p-149), 1); // Min positive input value + try expectEqual(exp2_f32(-0x1p-149), 1); // Min negative input value + try expectEqual(exp2_f32(0x1p-126), 1); // First positive subnormal input + try expectEqual(exp2_f32(-0x1p-126), 1); // First negative subnormal input } test "exp2() special" { - try expectEqual(exp2(0.0), 1.0); - try expectEqual(exp2(-0.0), 1.0); - try expectEqual(exp2(1.0), 2.0); - try expectEqual(exp2(-1.0), 0.5); - try expectEqual(exp2(math.inf(f64)), math.inf(f64)); - try expect(math.isPositiveZero(exp2(-math.inf(f64)))); - try expect(math.isNan(exp2(math.nan(f64)))); - try expect(math.isNan(exp2(math.snan(f64)))); + try expectEqual(exp2_f64(0.0), 1.0); + try expectEqual(exp2_f64(-0.0), 1.0); + try expectEqual(exp2_f64(1.0), 2.0); + try expectEqual(exp2_f64(-1.0), 0.5); + try expectEqual(exp2_f64(math.inf(f64)), math.inf(f64)); + try expect(math.isPositiveZero(exp2_f64(-math.inf(f64)))); + try expect(math.isNan(exp2_f64(math.nan(f64)))); + try expect(math.isNan(exp2_f64(math.snan(f64)))); } test "exp2() sanity" { - try expectEqual(exp2(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9); - try expectEqual(exp2(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4); - try expectEqual(exp2(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9); - try expectEqual(exp2(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7); - try expectEqual(exp2(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9); - try expectEqual(exp2(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0); - try expectEqual(exp2(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1); - try expectEqual(exp2(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0); - try expectEqual(exp2(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0); - try expectEqual(exp2(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1); + try expectEqual(exp2_f64(-0x1.02239f3c6a8f1p+3), 0x1.e8d13c396f452p-9); + try expectEqual(exp2_f64(0x1.161868e18bc67p+2), 0x1.4536746bb6f12p+4); + try expectEqual(exp2_f64(-0x1.0c34b3e01e6e7p+3), 0x1.890ca0c00b9a2p-9); + try expectEqual(exp2_f64(-0x1.a206f0a19dcc4p+2), 0x1.622d4b0ebc6c1p-7); + try expectEqual(exp2_f64(0x1.288bbb0d6a1e6p+3), 0x1.340ec7f3e607ep+9); + try expectEqual(exp2_f64(0x1.52efd0cd80497p-1), 0x1.950eef4bc5451p+0); + try expectEqual(exp2_f64(-0x1.a05cc754481d1p-2), 0x1.824056efc687cp-1); + try expectEqual(exp2_f64(0x1.1f9ef934745cbp-1), 0x1.79dfa14ab121ep+0); + try expectEqual(exp2_f64(0x1.8c5db097f7442p-1), 0x1.b5cead2247372p+0); + try expectEqual(exp2_f64(-0x1.5b86ea8118a0ep-1), 0x1.3fd8ba33216b9p-1); } test "exp2() boundary" { - try expectEqual(exp2(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite - try expectEqual(exp2(0x1p+10), math.inf(f64)); // The first value that gives infinite result - try expectEqual(exp2(-0x1.0cbffffffffffp+10), 0x1p-1074); // The last value before the result flushes to zero - try expectEqual(exp2(-0x1.0ccp+10), 0); // The first value at which the result flushes to zero - try expectEqual(exp2(-0x1.ffp+9), 0x1p-1022); // The last value before the result flushes to subnormal - try expectEqual(exp2(-0x1.ff00000000001p+9), 0x1.ffffffffffd3ap-1023); // The first value for which the result flushes to subnormal - try expectEqual(exp2(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value - try expectEqual(exp2(0x1p-1074), 1); // Min positive input value - try expectEqual(exp2(-0x1p-1074), 1); // Min negative input value - try expectEqual(exp2(0x1p-1022), 1); // First positive subnormal input - try expectEqual(exp2(-0x1p-1022), 1); // First negative subnormal input + try expectEqual(exp2_f64(0x1.fffffffffffffp+9), 0x1.ffffffffffd3ap+1023); // The last value before the result gets infinite + try expectEqual(exp2_f64(0x1p+10), math.inf(f64)); // The first value that gives infinite result + try expectEqual(exp2_f64(-0x1.0cbffffffffffp+10), 0x1p-1074); // The last value before the result flushes to zero + try expectEqual(exp2_f64(-0x1.0ccp+10), 0); // The first value at which the result flushes to zero + try expectEqual(exp2_f64(-0x1.ffp+9), 0x1p-1022); // The last value before the result flushes to subnormal + try expectEqual(exp2_f64(-0x1.ff00000000001p+9), 0x1.ffffffffffd3ap-1023); // The first value for which the result flushes to subnormal + try expectEqual(exp2_f64(0x1.fffffffffffffp+1023), math.inf(f64)); // Max input value + try expectEqual(exp2_f64(0x1p-1074), 1); // Min positive input value + try expectEqual(exp2_f64(-0x1p-1074), 1); // Min negative input value + try expectEqual(exp2_f64(0x1p-1022), 1); // First positive subnormal input + try expectEqual(exp2_f64(-0x1p-1022), 1); // First negative subnormal input } diff --git a/lib/compiler_rt/exp_f128.zig b/lib/compiler_rt/exp_f128.zig index ac09308ff30ee94c46403e4e7cd9f6afd0bea60c..c7a042c2b11edb228cd597eebdefcadbd3b689bd 100644 --- a/lib/compiler_rt/exp_f128.zig +++ b/lib/compiler_rt/exp_f128.zig @@ -26,7 +26,7 @@ const exp_f128 = @This(); const std = @import("std"); const math = std.math; -pub fn exp(x: f128) callconv(.c) f128 { +pub fn exp(x: f128) f128 { if (!math.isFinite(x)) { if (math.isNan(x)) { if (math.isSignalNan(x)) math.raiseInvalid(); @@ -91,7 +91,7 @@ fn expPoly(r_hi: f128, r_lo: f128) f128 { } /// Computes 2^x -pub fn exp2(x: f128) callconv(.c) f128 { +pub fn exp2(x: f128) f128 { if (!math.isFinite(x)) { if (math.isNan(x)) { if (math.isSignalNan(x)) math.raiseInvalid(); diff --git a/lib/compiler_rt/extenddftf2.zig b/lib/compiler_rt/extenddftf2.zig deleted file mode 100644 index d6267d7d8a93acd5a56d528d803f789a013dced5..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/extenddftf2.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const extendf = @import("./extendf.zig").extendf; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__extenddftf2, "__extenddfkf2"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_dtoq, "_Qp_dtoq"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__extenddftf2, "_Q_dtoq"); - } - symbol(&__extenddftf2, "__extenddftf2"); -} - -pub fn __extenddftf2(a: f64) callconv(.c) f128 { - return extendf(f128, f64, @as(u64, @bitCast(a))); -} - -fn _Qp_dtoq(c: *f128, a: f64) callconv(.c) void { - c.* = extendf(f128, f64, @as(u64, @bitCast(a))); -} diff --git a/lib/compiler_rt/extenddfxf2.zig b/lib/compiler_rt/extenddfxf2.zig deleted file mode 100644 index d18195aea357d8fdd8fc26a0d34db798bc06f187..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/extenddfxf2.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const extend_f80 = @import("./extendf.zig").extend_f80; - -comptime { - symbol(&__extenddfxf2, "__extenddfxf2"); -} - -pub fn __extenddfxf2(a: f64) callconv(.c) f80 { - return extend_f80(f64, @as(u64, @bitCast(a))); -} diff --git a/lib/compiler_rt/extendf.zig b/lib/compiler_rt/extendf.zig index b923e9d25b7fe41a733b0aeb10db9d51b24176df..a0c637b352680a3b1bf1728c662bce3bdb6db91c 100644 --- a/lib/compiler_rt/extendf.zig +++ b/lib/compiler_rt/extendf.zig @@ -1,10 +1,175 @@ const std = @import("std"); -pub inline fn extendf( - comptime dst_t: type, - comptime src_t: type, - a: @Int(.unsigned, @typeInfo(src_t).float.bits), -) dst_t { +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; + +comptime { + if (compiler_rt.want_aeabi) { + if (compiler_rt.gnu_f16_abi) { + symbol(&__aeabi_h2f, "__gnu_h2f_ieee"); + } else { + symbol(&__aeabi_h2f, "__aeabi_h2f"); + } + } else if (compiler_rt.gnu_f16_abi) { + symbol(&__extendhfsf2, "__gnu_h2f_ieee"); + } + symbol(&__extendhfsf2, "__extendhfsf2"); + symbol(&__extendhfdf2, "__extendhfdf2"); + symbol(&__extendhfxf2, "__extendhfxf2"); + if (compiler_rt.want_ppc_abi) { + symbol(&__extendhftf2, "__extendhfkf2"); + } else { + symbol(&__extendhftf2, "__extendhftf2"); + } + + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_f2d, "__aeabi_f2d"); + } else { + symbol(&__extendsfdf2, "__extendsfdf2"); + } + symbol(&__extendsfxf2, "__extendsfxf2"); + if (compiler_rt.want_ppc_abi) { + symbol(&__extendsftf2, "__extendsfkf2"); + } else if (compiler_rt.want_sparc64_abi) { + symbol(&_Qp_stoq, "_Qp_stoq"); + } else if (compiler_rt.want_sparc32_abi) { + symbol(&__extendsftf2, "_Q_stoq"); + } else { + symbol(&__extendsftf2, "__extendsftf2"); + } + + symbol(&__extenddfxf2, "__extenddfxf2"); + if (compiler_rt.want_ppc_abi) { + symbol(&__extenddftf2, "__extenddfkf2"); + } else if (compiler_rt.want_sparc64_abi) { + symbol(&_Qp_dtoq, "_Qp_dtoq"); + } else if (compiler_rt.want_sparc32_abi) { + symbol(&__extenddftf2, "_Q_dtoq"); + } else { + symbol(&__extenddftf2, "__extenddftf2"); + } + + if (compiler_rt.want_ppc_abi) { + symbol(&__extendxftf2, "__extendxfkf2"); + } else { + symbol(&__extendxftf2, "__extendxftf2"); + } +} + +fn __extendhfsf2(a: compiler_rt.f16Conv(f32).Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(f32_floatCast_f16(compiler_rt.f16Conv(f32).fromAbi(a))); +} +fn __aeabi_h2f(a: u16) callconv(.{ .arm_aapcs = .{} }) u32 { + return @bitCast(f32_floatCast_f16(@bitCast(a))); +} +pub fn f32_floatCast_f16(a: f16) f32 { + return extendf(f32, f16, a); +} + +fn __extendhfdf2(a: compiler_rt.f16Conv(f64).Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(f64_floatCast_f16(compiler_rt.f16Conv(f64).fromAbi(a))); +} +pub fn f64_floatCast_f16(a: f16) f64 { + return extendf(f64, f16, a); +} + +fn __extendhfxf2(a: compiler_rt.f16Conv(f80).Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(f80_floatCast_f16(compiler_rt.f16Conv(f80).fromAbi(a))); +} +pub fn f80_floatCast_f16(a: f16) f80 { + return extend_f80(f16, a); +} + +fn __extendhftf2(a: compiler_rt.f16Conv(f128).Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatCast_f16(compiler_rt.f16Conv(f128).fromAbi(a))); +} +pub fn f128_floatCast_f16(a: f16) f128 { + return extendf(f128, f16, a); +} + +fn __extendsfdf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(f64_floatCast_f32(compiler_rt.f32.fromAbi(a))); +} +fn __aeabi_f2d(a: f32) callconv(.{ .arm_aapcs = .{} }) f64 { + return f64_floatCast_f32(a); +} +pub fn f64_floatCast_f32(a: f32) f64 { + return extendf(f64, f32, a); +} + +fn __extendsfxf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(f80_floatCast_f32(compiler_rt.f32.fromAbi(a))); +} +pub fn f80_floatCast_f32(a: f32) f80 { + return extend_f80(f32, a); +} + +pub fn __extendsftf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatCast_f32(compiler_rt.f32.fromAbi(a))); +} +fn _Qp_stoq(c: *f128, a: f32) callconv(.c) void { + c.* = f128_floatCast_f32(a); +} +pub fn f128_floatCast_f32(a: f32) f128 { + return extendf(f128, f32, a); +} + +fn __extenddfxf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(f80_floatCast_f64(compiler_rt.f64.fromAbi(a))); +} +pub fn f80_floatCast_f64(a: f64) f80 { + return extend_f80(f64, a); +} + +fn __extenddftf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatCast_f64(compiler_rt.f64.fromAbi(a))); +} +fn _Qp_dtoq(c: *f128, a: f64) callconv(.c) void { + c.* = f128_floatCast_f64(a); +} +pub fn f128_floatCast_f64(a: f64) f128 { + return extendf(f128, f64, a); +} + +fn __extendxftf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatCast_f80(compiler_rt.f80.fromAbi(a))); +} +pub fn f128_floatCast_f80(a: f80) f128 { + const src_int_bit: u64 = 0x8000000000000000; + const src_sig_mask = ~src_int_bit; + const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit + const dst_sig_bits = std.math.floatMantissaBits(f128); + + const dst_bits = @bitSizeOf(f128); + + // Break a into a sign and representation of the absolute value + var a_rep: std.math.F80 = .fromFloat(a); + const sign = a_rep.exp & 0x8000; + a_rep.exp &= 0x7FFF; + var abs_result: u128 = undefined; + + if (a_rep.exp == 0 and a_rep.fraction == 0) { + // zero + abs_result = 0; + } else if (a_rep.exp == 0x7FFF) { + // a is nan or infinite + abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); + abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; + } else if (a_rep.fraction & src_int_bit != 0) { + // a is a normal value + abs_result = @as(u128, a_rep.fraction & src_sig_mask) << (dst_sig_bits - src_sig_bits); + abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; + } else { + // a is denormal + abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); + } + + // Apply the signbit to (dst_t)abs(a). + const result: u128 = abs_result | @as(u128, sign) << (dst_bits - 16); + return @bitCast(result); +} + +inline fn extendf(comptime dst_t: type, comptime src_t: type, f: src_t) dst_t { const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits); const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits); const srcSigBits = std.math.floatMantissaBits(src_t); @@ -31,6 +196,7 @@ pub inline fn extendf( const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits; + const a: src_rep_t = @bitCast(f); // Break a into a sign and representation of the absolute value const aRep: src_rep_t = @bitCast(a); const aAbs: src_rep_t = aRep & srcAbsMask; @@ -66,11 +232,11 @@ pub inline fn extendf( } // Apply the signbit to (dst_t)abs(a). - const result: dst_rep_t align(@alignOf(dst_t)) = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits); + const result: dst_rep_t = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits); return @bitCast(result); } -pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_t).float.bits)) f80 { +inline fn extend_f80(comptime src_t: type, f: src_t) f80 { const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits); const src_sig_bits = std.math.floatMantissaBits(src_t); const dst_int_bit = 0x8000000000000000; @@ -92,6 +258,7 @@ pub inline fn extend_f80(comptime src_t: type, a: @Int(.unsigned, @typeInfo(src_ var dst: std.math.F80 = undefined; + const a: src_rep_t = @bitCast(f); // Break a into a sign and representation of the absolute value const a_abs = a & src_abs_mask; const sign: u16 = if (a & src_sign_mask != 0) 0x8000 else 0; diff --git a/lib/compiler_rt/extendf_test.zig b/lib/compiler_rt/extendf_test.zig index f572495b6634f8096fa5dd41dd9d2fd1b362a0a1..4cba105a6dc88b24230e9624d250b05da947edf2 100644 --- a/lib/compiler_rt/extendf_test.zig +++ b/lib/compiler_rt/extendf_test.zig @@ -1,31 +1,37 @@ const builtin = @import("builtin"); - const std = @import("std"); -const math = std.math; +const testing = std.testing; -const __extendhfsf2 = @import("extendhfsf2.zig").__extendhfsf2; -const __extendhftf2 = @import("extendhftf2.zig").__extendhftf2; -const __extendsftf2 = @import("extendsftf2.zig").__extendsftf2; -const __extenddftf2 = @import("extenddftf2.zig").__extenddftf2; -const __extenddfxf2 = @import("extenddfxf2.zig").__extenddfxf2; -const F16T = @import("../compiler_rt.zig").F16T; +const impl = @import("extendf.zig"); -fn test__extenddfxf2(a: f64, expected: u80) !void { - const x = __extenddfxf2(a); +const f32_floatCast_f16 = impl.f32_floatCast_f16; +const f64_floatCast_f16 = impl.f64_floatCast_f16; +const f80_floatCast_f16 = impl.f80_floatCast_f16; +const f128_floatCast_f16 = impl.f128_floatCast_f16; + +const f64_floatCast_f32 = impl.f64_floatCast_f32; +const f80_floatCast_f32 = impl.f80_floatCast_f32; +const f128_floatCast_f32 = impl.f128_floatCast_f32; + +const f80_floatCast_f64 = impl.f80_floatCast_f64; +const f128_floatCast_f64 = impl.f128_floatCast_f64; + +const f128_floatCast_f80 = impl.f128_floatCast_f80; + +fn test_f80_floatCast_f64(a: f64, expected: u80) !void { + const x = f80_floatCast_f64(a); const rep: u80 = @bitCast(x); if (rep == expected) return; - // test other possible NaN representation(signal NaN) - if (math.isNan(@as(f80, @bitCast(expected))) and math.isNan(x)) + if (std.math.isNan(@as(f80, @bitCast(expected))) and std.math.isNan(x)) return; - - @panic("__extenddfxf2 test failure"); + return error.TestFailure; } -fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { - const x = __extenddftf2(a); +fn test_f128_floatCast_f64(a: f64, expected_hi: u64, expected_lo: u64) !void { + const x = f128_floatCast_f64(a); const rep: u128 = @bitCast(x); const hi: u64 = @intCast(rep >> 64); @@ -33,7 +39,6 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { if (hi == expected_hi and lo == expected_lo) return; - // test other possible NaN representation(signal NaN) if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) { if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and @@ -42,12 +47,11 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { return; } } - - @panic("__extenddftf2 test failure"); + return error.TestFailure; } -fn test__extendhfsf2(a: u16, expected: u32) !void { - const x = __extendhfsf2(@as(F16T(f32), @bitCast(a))); +fn test_f32_floatCast_f16(a: u16, expected: u32) !void { + const x = f32_floatCast_f16(@bitCast(a)); const rep: u32 = @bitCast(x); if (rep == expected) { @@ -58,12 +62,11 @@ fn test__extendhfsf2(a: u16, expected: u32) !void { return; } } - return error.TestFailure; } -fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { - const x = __extendsftf2(a); +fn test_f128_floatCast_f32(a: f32, expected_hi: u64, expected_lo: u64) !void { + const x = f128_floatCast_f32(a); const rep: u128 = @bitCast(x); const hi: u64 = @intCast(rep >> 64); @@ -71,7 +74,6 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { if (hi == expected_hi and lo == expected_lo) return; - // test other possible NaN representation(signal NaN) if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) { if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and @@ -80,111 +82,108 @@ fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { return; } } - return error.TestFailure; } -test "extenddfxf2" { +test f80_floatCast_f64 { // qNaN - try test__extenddfxf2(makeQNaN64(), 0x7fffc000000000000000); + try test_f80_floatCast_f64(makeQNaN64(), 0x7fffc000000000000000); // NaN - try test__extenddfxf2(makeNaN64(0x7100000000000), 0x7fffe080000000000000); + try test_f80_floatCast_f64(makeNaN64(0x7100000000000), 0x7fffe080000000000000); // This is bad? // inf - try test__extenddfxf2(makeInf64(), 0x7fff8000000000000000); + try test_f80_floatCast_f64(makeInf64(), 0x7fff8000000000000000); // zero - try test__extenddfxf2(0.0, 0x0); + try test_f80_floatCast_f64(0.0, 0x0); - try test__extenddfxf2(0x0.a3456789abcdefp+6, 0x4004a3456789abcdf000); + try test_f80_floatCast_f64(0x0.a3456789abcdefp+6, 0x4004a3456789abcdf000); - try test__extenddfxf2(0x0.edcba987654321fp-8, 0x3ff6edcba98765432000); + try test_f80_floatCast_f64(0x0.edcba987654321fp-8, 0x3ff6edcba98765432000); - try test__extenddfxf2(0x0.a3456789abcdefp+46, 0x402ca3456789abcdf000); + try test_f80_floatCast_f64(0x0.a3456789abcdefp+46, 0x402ca3456789abcdf000); - try test__extenddfxf2(0x0.edcba987654321fp-44, 0x3fd2edcba98765432000); + try test_f80_floatCast_f64(0x0.edcba987654321fp-44, 0x3fd2edcba98765432000); // subnormal - try test__extenddfxf2(0x1.8000000000001p-1022, 0x3c01c000000000000800); - try test__extenddfxf2(0x1.8000000000002p-1023, 0x3c00c000000000001000); + try test_f80_floatCast_f64(0x1.8000000000001p-1022, 0x3c01c000000000000800); + try test_f80_floatCast_f64(0x1.8000000000002p-1023, 0x3c00c000000000001000); } -test "extenddftf2" { - if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isPowerPC()) return error.SkipZigTest; - +test f128_floatCast_f64 { // qNaN - try test__extenddftf2(makeQNaN64(), 0x7fff800000000000, 0x0); + try test_f128_floatCast_f64(makeQNaN64(), 0x7fff800000000000, 0x0); // NaN - try test__extenddftf2(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0); + try test_f128_floatCast_f64(makeNaN64(0x7100000000000), 0x7fff710000000000, 0x0); // inf - try test__extenddftf2(makeInf64(), 0x7fff000000000000, 0x0); + try test_f128_floatCast_f64(makeInf64(), 0x7fff000000000000, 0x0); // zero - try test__extenddftf2(0.0, 0x0, 0x0); + try test_f128_floatCast_f64(0.0, 0x0, 0x0); - try test__extenddftf2(0x1.23456789abcdefp+5, 0x400423456789abcd, 0xf000000000000000); + try test_f128_floatCast_f64(0x1.23456789abcdefp+5, 0x400423456789abcd, 0xf000000000000000); - try test__extenddftf2(0x1.edcba987654321fp-9, 0x3ff6edcba9876543, 0x2000000000000000); + try test_f128_floatCast_f64(0x1.edcba987654321fp-9, 0x3ff6edcba9876543, 0x2000000000000000); - try test__extenddftf2(0x1.23456789abcdefp+45, 0x402c23456789abcd, 0xf000000000000000); + try test_f128_floatCast_f64(0x1.23456789abcdefp+45, 0x402c23456789abcd, 0xf000000000000000); - try test__extenddftf2(0x1.edcba987654321fp-45, 0x3fd2edcba9876543, 0x2000000000000000); + try test_f128_floatCast_f64(0x1.edcba987654321fp-45, 0x3fd2edcba9876543, 0x2000000000000000); // subnormal - try test__extenddftf2(0x1.8p-1022, 0x3c01800000000000, 0x0); - try test__extenddftf2(0x1.8p-1023, 0x3c00800000000000, 0x0); + try test_f128_floatCast_f64(0x1.8p-1022, 0x3c01800000000000, 0x0); + try test_f128_floatCast_f64(0x1.8p-1023, 0x3c00800000000000, 0x0); } -test "extendhfsf2" { - try test__extendhfsf2(0x7e00, 0x7fc00000); // qNaN - try test__extendhfsf2(0x7f00, 0x7fe00000); // sNaN +test f32_floatCast_f16 { + try test_f32_floatCast_f16(0x7e00, 0x7fc00000); // qNaN + try test_f32_floatCast_f16(0x7f00, 0x7fe00000); // sNaN // On x86 the NaN becomes quiet because the return is pushed on the x87 // stack due to ABI requirements if (builtin.target.cpu.arch != .x86 and builtin.target.os.tag == .windows) - try test__extendhfsf2(0x7c01, 0x7f802000); // sNaN + try test_f32_floatCast_f16(0x7c01, 0x7f802000); // sNaN - try test__extendhfsf2(0, 0); // 0 - try test__extendhfsf2(0x8000, 0x80000000); // -0 + try test_f32_floatCast_f16(0, 0); // 0 + try test_f32_floatCast_f16(0x8000, 0x80000000); // -0 - try test__extendhfsf2(0x7c00, 0x7f800000); // inf - try test__extendhfsf2(0xfc00, 0xff800000); // -inf + try test_f32_floatCast_f16(0x7c00, 0x7f800000); // inf + try test_f32_floatCast_f16(0xfc00, 0xff800000); // -inf - try test__extendhfsf2(0x0001, 0x33800000); // denormal (min), 2**-24 - try test__extendhfsf2(0x8001, 0xb3800000); // denormal (min), -2**-24 + try test_f32_floatCast_f16(0x0001, 0x33800000); // denormal (min), 2**-24 + try test_f32_floatCast_f16(0x8001, 0xb3800000); // denormal (min), -2**-24 - try test__extendhfsf2(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24 - try test__extendhfsf2(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24 + try test_f32_floatCast_f16(0x03ff, 0x387fc000); // denormal (max), 2**-14 - 2**-24 + try test_f32_floatCast_f16(0x83ff, 0xb87fc000); // denormal (max), -2**-14 + 2**-24 - try test__extendhfsf2(0x0400, 0x38800000); // normal (min), 2**-14 - try test__extendhfsf2(0x8400, 0xb8800000); // normal (min), -2**-14 + try test_f32_floatCast_f16(0x0400, 0x38800000); // normal (min), 2**-14 + try test_f32_floatCast_f16(0x8400, 0xb8800000); // normal (min), -2**-14 - try test__extendhfsf2(0x7bff, 0x477fe000); // normal (max), 65504 - try test__extendhfsf2(0xfbff, 0xc77fe000); // normal (max), -65504 + try test_f32_floatCast_f16(0x7bff, 0x477fe000); // normal (max), 65504 + try test_f32_floatCast_f16(0xfbff, 0xc77fe000); // normal (max), -65504 - try test__extendhfsf2(0x3c01, 0x3f802000); // normal, 1 + 2**-10 - try test__extendhfsf2(0xbc01, 0xbf802000); // normal, -1 - 2**-10 + try test_f32_floatCast_f16(0x3c01, 0x3f802000); // normal, 1 + 2**-10 + try test_f32_floatCast_f16(0xbc01, 0xbf802000); // normal, -1 - 2**-10 - try test__extendhfsf2(0x3555, 0x3eaaa000); // normal, approx. 1/3 - try test__extendhfsf2(0xb555, 0xbeaaa000); // normal, approx. -1/3 + try test_f32_floatCast_f16(0x3555, 0x3eaaa000); // normal, approx. 1/3 + try test_f32_floatCast_f16(0xb555, 0xbeaaa000); // normal, approx. -1/3 } -test "extendsftf2" { +test f128_floatCast_f32 { // qNaN - try test__extendsftf2(makeQNaN32(), 0x7fff800000000000, 0x0); + try test_f128_floatCast_f32(makeQNaN32(), 0x7fff800000000000, 0x0); // NaN - try test__extendsftf2(makeNaN32(0x410000), 0x7fff820000000000, 0x0); + try test_f128_floatCast_f32(makeNaN32(0x410000), 0x7fff820000000000, 0x0); // inf - try test__extendsftf2(makeInf32(), 0x7fff000000000000, 0x0); + try test_f128_floatCast_f32(makeInf32(), 0x7fff000000000000, 0x0); // zero - try test__extendsftf2(0.0, 0x0, 0x0); - try test__extendsftf2(0x1.23456p+5, 0x4004234560000000, 0x0); - try test__extendsftf2(0x1.edcbap-9, 0x3ff6edcba0000000, 0x0); - try test__extendsftf2(0x1.23456p+45, 0x402c234560000000, 0x0); - try test__extendsftf2(0x1.edcbap-45, 0x3fd2edcba0000000, 0x0); + try test_f128_floatCast_f32(0.0, 0x0, 0x0); + try test_f128_floatCast_f32(0x1.23456p+5, 0x4004234560000000, 0x0); + try test_f128_floatCast_f32(0x1.edcbap-9, 0x3ff6edcba0000000, 0x0); + try test_f128_floatCast_f32(0x1.23456p+45, 0x402c234560000000, 0x0); + try test_f128_floatCast_f32(0x1.edcbap-45, 0x3fd2edcba0000000, 0x0); } fn makeQNaN64() f64 { @@ -211,8 +210,8 @@ fn makeInf32() f32 { return @bitCast(@as(u32, 0x7f800000)); } -fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void { - const x = __extendhftf2(@as(F16T(f128), @bitCast(a))); +fn test_f128_floatCast_f16(a: u16, expected_hi: u64, expected_lo: u64) !void { + const x = f128_floatCast_f16(@bitCast(a)); const rep: u128 = @bitCast(x); const hi: u64 = @intCast(rep >> 64); @@ -233,26 +232,26 @@ fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void { return error.TestFailure; } -test "extendhftf2" { +test f128_floatCast_f16 { // qNaN - try test__extendhftf2(0x7e00, 0x7fff800000000000, 0x0); + try test_f128_floatCast_f16(0x7e00, 0x7fff800000000000, 0x0); // NaN - try test__extendhftf2(0x7d00, 0x7fff400000000000, 0x0); + try test_f128_floatCast_f16(0x7d00, 0x7fff400000000000, 0x0); // inf - try test__extendhftf2(0x7c00, 0x7fff000000000000, 0x0); - try test__extendhftf2(0xfc00, 0xffff000000000000, 0x0); + try test_f128_floatCast_f16(0x7c00, 0x7fff000000000000, 0x0); + try test_f128_floatCast_f16(0xfc00, 0xffff000000000000, 0x0); // zero - try test__extendhftf2(0x0000, 0x0000000000000000, 0x0); - try test__extendhftf2(0x8000, 0x8000000000000000, 0x0); + try test_f128_floatCast_f16(0x0000, 0x0000000000000000, 0x0); + try test_f128_floatCast_f16(0x8000, 0x8000000000000000, 0x0); // denormal - try test__extendhftf2(0x0010, 0x3feb000000000000, 0x0); - try test__extendhftf2(0x0001, 0x3fe7000000000000, 0x0); - try test__extendhftf2(0x8001, 0xbfe7000000000000, 0x0); + try test_f128_floatCast_f16(0x0010, 0x3feb000000000000, 0x0); + try test_f128_floatCast_f16(0x0001, 0x3fe7000000000000, 0x0); + try test_f128_floatCast_f16(0x8001, 0xbfe7000000000000, 0x0); // pi - try test__extendhftf2(0x4248, 0x4000920000000000, 0x0); - try test__extendhftf2(0xc248, 0xc000920000000000, 0x0); + try test_f128_floatCast_f16(0x4248, 0x4000920000000000, 0x0); + try test_f128_floatCast_f16(0xc248, 0xc000920000000000, 0x0); - try test__extendhftf2(0x508c, 0x4004230000000000, 0x0); - try test__extendhftf2(0x1bb7, 0x3ff6edc000000000, 0x0); + try test_f128_floatCast_f16(0x508c, 0x4004230000000000, 0x0); + try test_f128_floatCast_f16(0x1bb7, 0x3ff6edc000000000, 0x0); } diff --git a/lib/compiler_rt/extendhfdf2.zig b/lib/compiler_rt/extendhfdf2.zig deleted file mode 100644 index 8cadc7139eebbad29f39b5245a14971c5c187a0d..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/extendhfdf2.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; -const extendf = @import("./extendf.zig").extendf; - -comptime { - symbol(&__extendhfdf2, "__extendhfdf2"); -} - -pub fn __extendhfdf2(a: compiler_rt.F16T(f64)) callconv(.c) f64 { - return extendf(f64, f16, @as(u16, @bitCast(a))); -} diff --git a/lib/compiler_rt/extendhfsf2.zig b/lib/compiler_rt/extendhfsf2.zig deleted file mode 100644 index b638192c47502e6e698e86fcce8be3fbc0f7d2f9..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/extendhfsf2.zig +++ /dev/null @@ -1,24 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const extendf = @import("./extendf.zig").extendf; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.gnu_f16_abi) { - symbol(&__gnu_h2f_ieee, "__gnu_h2f_ieee"); - } else if (compiler_rt.want_aeabi) { - symbol(&__aeabi_h2f, "__aeabi_h2f"); - } - symbol(&__extendhfsf2, "__extendhfsf2"); -} - -pub fn __extendhfsf2(a: compiler_rt.F16T(f32)) callconv(.c) f32 { - return extendf(f32, f16, @as(u16, @bitCast(a))); -} - -fn __gnu_h2f_ieee(a: compiler_rt.F16T(f32)) callconv(.c) f32 { - return extendf(f32, f16, @as(u16, @bitCast(a))); -} - -fn __aeabi_h2f(a: u16) callconv(.{ .arm_aapcs = .{} }) f32 { - return extendf(f32, f16, @as(u16, @bitCast(a))); -} diff --git a/lib/compiler_rt/extendhftf2.zig b/lib/compiler_rt/extendhftf2.zig deleted file mode 100644 index 29e7866b663389aae7048a474e585916fec7cac1..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/extendhftf2.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const extendf = @import("./extendf.zig").extendf; - -comptime { - symbol(&__extendhftf2, "__extendhftf2"); -} - -pub fn __extendhftf2(a: compiler_rt.F16T(f128)) callconv(.c) f128 { - return extendf(f128, f16, @as(u16, @bitCast(a))); -} diff --git a/lib/compiler_rt/extendhfxf2.zig b/lib/compiler_rt/extendhfxf2.zig deleted file mode 100644 index e76daf4f55045262daa10cb4547688ed012a6bc0..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/extendhfxf2.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const extend_f80 = @import("./extendf.zig").extend_f80; - -comptime { - symbol(&__extendhfxf2, "__extendhfxf2"); -} - -fn __extendhfxf2(a: compiler_rt.F16T(f80)) callconv(.c) f80 { - return extend_f80(f16, @as(u16, @bitCast(a))); -} diff --git a/lib/compiler_rt/extendsfdf2.zig b/lib/compiler_rt/extendsfdf2.zig deleted file mode 100644 index 4f34b05242a5f57155c9bb83c3e978c6ec3ace42..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/extendsfdf2.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const extendf = @import("./extendf.zig").extendf; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_f2d, "__aeabi_f2d"); - } else { - symbol(&__extendsfdf2, "__extendsfdf2"); - } -} - -fn __extendsfdf2(a: f32) callconv(.c) f64 { - return extendf(f64, f32, @as(u32, @bitCast(a))); -} - -fn __aeabi_f2d(a: f32) callconv(.{ .arm_aapcs = .{} }) f64 { - return extendf(f64, f32, @as(u32, @bitCast(a))); -} diff --git a/lib/compiler_rt/extendsftf2.zig b/lib/compiler_rt/extendsftf2.zig deleted file mode 100644 index 6135065b14297e34c04e7cefec5b9387321089a7..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/extendsftf2.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const extendf = @import("./extendf.zig").extendf; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__extendsftf2, "__extendsfkf2"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_stoq, "_Qp_stoq"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__extendsftf2, "_Q_stoq"); - } - symbol(&__extendsftf2, "__extendsftf2"); -} - -pub fn __extendsftf2(a: f32) callconv(.c) f128 { - return extendf(f128, f32, @as(u32, @bitCast(a))); -} - -fn _Qp_stoq(c: *f128, a: f32) callconv(.c) void { - c.* = extendf(f128, f32, @as(u32, @bitCast(a))); -} diff --git a/lib/compiler_rt/extendsfxf2.zig b/lib/compiler_rt/extendsfxf2.zig deleted file mode 100644 index 9a6796bd668602b1d653a6581613fcb69edb7853..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/extendsfxf2.zig +++ /dev/null @@ -1,10 +0,0 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const extend_f80 = @import("./extendf.zig").extend_f80; - -comptime { - symbol(&__extendsfxf2, "__extendsfxf2"); -} - -fn __extendsfxf2(a: f32) callconv(.c) f80 { - return extend_f80(f32, @as(u32, @bitCast(a))); -} diff --git a/lib/compiler_rt/extendxftf2.zig b/lib/compiler_rt/extendxftf2.zig deleted file mode 100644 index 1c39e1e84c7a3beb0a9470a123c05dea456eed77..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/extendxftf2.zig +++ /dev/null @@ -1,42 +0,0 @@ -const std = @import("std"); - -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - symbol(&__extendxftf2, "__extendxftf2"); -} - -fn __extendxftf2(a: f80) callconv(.c) f128 { - const src_int_bit: u64 = 0x8000000000000000; - const src_sig_mask = ~src_int_bit; - const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit - const dst_sig_bits = std.math.floatMantissaBits(f128); - - const dst_bits = @bitSizeOf(f128); - - // Break a into a sign and representation of the absolute value - var a_rep = std.math.F80.fromFloat(a); - const sign = a_rep.exp & 0x8000; - a_rep.exp &= 0x7FFF; - var abs_result: u128 = undefined; - - if (a_rep.exp == 0 and a_rep.fraction == 0) { - // zero - abs_result = 0; - } else if (a_rep.exp == 0x7FFF) { - // a is nan or infinite - abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); - abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; - } else if (a_rep.fraction & src_int_bit != 0) { - // a is a normal value - abs_result = @as(u128, a_rep.fraction & src_sig_mask) << (dst_sig_bits - src_sig_bits); - abs_result |= @as(u128, a_rep.exp) << dst_sig_bits; - } else { - // a is denormal - abs_result = @as(u128, a_rep.fraction) << (dst_sig_bits - src_sig_bits); - } - - // Apply the signbit to (dst_t)abs(a). - const result: u128 align(@alignOf(f128)) = abs_result | @as(u128, sign) << (dst_bits - 16); - return @bitCast(result); -} diff --git a/lib/compiler_rt/fabs.zig b/lib/compiler_rt/fabs.zig index abdf21df8f33de1c080aba1452ae233287283540..50d2cc17d590a11615bdc471e6926af6c1f7bc6c 100644 --- a/lib/compiler_rt/fabs.zig +++ b/lib/compiler_rt/fabs.zig @@ -16,32 +16,47 @@ comptime { symbol(&fabsl, "fabsl"); } -pub fn __fabsh(a: f16) callconv(.c) f16 { +fn __fabsh(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(fabs_f16(compiler_rt.f16.fromAbi(a))); +} +pub fn fabs_f16(a: f16) f16 { return generic_fabs(a); } -pub fn fabsf(a: f32) callconv(.c) f32 { +fn fabsf(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(fabs_f32(compiler_rt.f32.fromAbi(a))); +} +pub fn fabs_f32(a: f32) f32 { return generic_fabs(a); } -pub fn fabs(a: f64) callconv(.c) f64 { +fn fabs(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(fabs_f64(compiler_rt.f64.fromAbi(a))); +} +pub fn fabs_f64(a: f64) f64 { return generic_fabs(a); } -pub fn __fabsx(a: f80) callconv(.c) f80 { +fn __fabsx(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(fabs_f80(compiler_rt.f80.fromAbi(a))); +} +pub fn fabs_f80(a: f80) f80 { return generic_fabs(a); } -pub fn fabsq(a: f128) callconv(.c) f128 { +fn fabsq(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(fabs_f128(compiler_rt.f128.fromAbi(a))); +} +pub fn fabs_f128(a: f128) f128 { return generic_fabs(a); } pub fn fabsl(x: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return fabs(x), - 80 => return __fabsx(x), - 128 => return fabsq(x), - else => @compileError("unreachable"), + 64 => return fabs_f64(x), + 80 => return fabs_f80(x), + 128 => return fabs_f128(x), + else => comptime unreachable, } } diff --git a/lib/compiler_rt/fixdfdi.zig b/lib/compiler_rt/fixdfdi.zig deleted file mode 100644 index 5a66cc124f0f4ec092f1c49715ae6c547a396b66..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixdfdi.zig +++ /dev/null @@ -1,23 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_d2lz, "__aeabi_d2lz"); - } else { - if (compiler_rt.want_windows_arm_abi) { - symbol(&__fixdfdi, "__dtoi64"); - } - symbol(&__fixdfdi, "__fixdfdi"); - } -} - -pub fn __fixdfdi(a: f64) callconv(.c) i64 { - return intFromFloat(i64, a); -} - -fn __aeabi_d2lz(a: f64) callconv(.{ .arm_aapcs = .{} }) i64 { - return intFromFloat(i64, a); -} diff --git a/lib/compiler_rt/fixdfei.zig b/lib/compiler_rt/fixdfei.zig deleted file mode 100644 index 170b4a160337fe5fc426fe2e715ab46426d76d7e..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixdfei.zig +++ /dev/null @@ -1,14 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; - -comptime { - symbol(&__fixdfei, "__fixdfei"); -} - -pub fn __fixdfei(r: [*]u8, bits: usize, a: f64) callconv(.c) void { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); -} diff --git a/lib/compiler_rt/fixdfsi.zig b/lib/compiler_rt/fixdfsi.zig deleted file mode 100644 index 1d42337ea54573e4c7423147323046b029f9af52..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixdfsi.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const intFromFloat = @import("./int_from_float.zig").intFromFloat; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_d2iz, "__aeabi_d2iz"); - } else { - symbol(&__fixdfsi, "__fixdfsi"); - } -} - -pub fn __fixdfsi(a: f64) callconv(.c) i32 { - return intFromFloat(i32, a); -} - -fn __aeabi_d2iz(a: f64) callconv(.{ .arm_aapcs = .{} }) i32 { - return intFromFloat(i32, a); -} diff --git a/lib/compiler_rt/fixdfti.zig b/lib/compiler_rt/fixdfti.zig deleted file mode 100644 index ff7434d63da148afc20b22bbfb54d6c1bdd17822..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixdfti.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const intFromFloat = @import("./int_from_float.zig").intFromFloat; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - symbol(&__fixdfti, "__fixdfti"); -} - -pub fn __fixdfti(a: f64) callconv(.c) i128 { - return intFromFloat(i128, a); -} diff --git a/lib/compiler_rt/fixhfei.zig b/lib/compiler_rt/fixhfei.zig deleted file mode 100644 index 5b759c3fc683d909ce7808242a59129c310bbb56..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixhfei.zig +++ /dev/null @@ -1,14 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; - -comptime { - symbol(&__fixhfei, "__fixhfei"); -} - -pub fn __fixhfei(r: [*]u8, bits: usize, a: f16) callconv(.c) void { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); -} diff --git a/lib/compiler_rt/fixint_test.zig b/lib/compiler_rt/fixint_test.zig deleted file mode 100644 index 198167ab867c22ed6160e83ed90920a6c5e97f28..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixint_test.zig +++ /dev/null @@ -1,149 +0,0 @@ -const std = @import("std"); -const math = std.math; -const testing = std.testing; - -const fixint = @import("fixint.zig").fixint; - -fn test__fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t, expected: fixint_t) !void { - const x = fixint(fp_t, fixint_t, a); - try testing.expect(x == expected); -} - -test "fixint.i1" { - try test__fixint(f32, i1, -math.inf(f32), -1); - try test__fixint(f32, i1, -math.floatMax(f32), -1); - try test__fixint(f32, i1, -2.0, -1); - try test__fixint(f32, i1, -1.1, -1); - try test__fixint(f32, i1, -1.0, -1); - try test__fixint(f32, i1, -0.9, 0); - try test__fixint(f32, i1, -0.1, 0); - try test__fixint(f32, i1, -math.floatMin(f32), 0); - try test__fixint(f32, i1, -0.0, 0); - try test__fixint(f32, i1, 0.0, 0); - try test__fixint(f32, i1, math.floatMin(f32), 0); - try test__fixint(f32, i1, 0.1, 0); - try test__fixint(f32, i1, 0.9, 0); - try test__fixint(f32, i1, 1.0, 0); - try test__fixint(f32, i1, 2.0, 0); - try test__fixint(f32, i1, math.floatMax(f32), 0); - try test__fixint(f32, i1, math.inf(f32), 0); -} - -test "fixint.i2" { - try test__fixint(f32, i2, -math.inf(f32), -2); - try test__fixint(f32, i2, -math.floatMax(f32), -2); - try test__fixint(f32, i2, -2.0, -2); - try test__fixint(f32, i2, -1.9, -1); - try test__fixint(f32, i2, -1.1, -1); - try test__fixint(f32, i2, -1.0, -1); - try test__fixint(f32, i2, -0.9, 0); - try test__fixint(f32, i2, -0.1, 0); - try test__fixint(f32, i2, -math.floatMin(f32), 0); - try test__fixint(f32, i2, -0.0, 0); - try test__fixint(f32, i2, 0.0, 0); - try test__fixint(f32, i2, math.floatMin(f32), 0); - try test__fixint(f32, i2, 0.1, 0); - try test__fixint(f32, i2, 0.9, 0); - try test__fixint(f32, i2, 1.0, 1); - try test__fixint(f32, i2, 2.0, 1); - try test__fixint(f32, i2, math.floatMax(f32), 1); - try test__fixint(f32, i2, math.inf(f32), 1); -} - -test "fixint.i3" { - try test__fixint(f32, i3, -math.inf(f32), -4); - try test__fixint(f32, i3, -math.floatMax(f32), -4); - try test__fixint(f32, i3, -4.0, -4); - try test__fixint(f32, i3, -3.0, -3); - try test__fixint(f32, i3, -2.0, -2); - try test__fixint(f32, i3, -1.9, -1); - try test__fixint(f32, i3, -1.1, -1); - try test__fixint(f32, i3, -1.0, -1); - try test__fixint(f32, i3, -0.9, 0); - try test__fixint(f32, i3, -0.1, 0); - try test__fixint(f32, i3, -math.floatMin(f32), 0); - try test__fixint(f32, i3, -0.0, 0); - try test__fixint(f32, i3, 0.0, 0); - try test__fixint(f32, i3, math.floatMin(f32), 0); - try test__fixint(f32, i3, 0.1, 0); - try test__fixint(f32, i3, 0.9, 0); - try test__fixint(f32, i3, 1.0, 1); - try test__fixint(f32, i3, 2.0, 2); - try test__fixint(f32, i3, 3.0, 3); - try test__fixint(f32, i3, 4.0, 3); - try test__fixint(f32, i3, math.floatMax(f32), 3); - try test__fixint(f32, i3, math.inf(f32), 3); -} - -test "fixint.i32" { - try test__fixint(f64, i32, -math.inf(f64), math.minInt(i32)); - try test__fixint(f64, i32, -math.floatMax(f64), math.minInt(i32)); - try test__fixint(f64, i32, @as(f64, math.minInt(i32)), math.minInt(i32)); - try test__fixint(f64, i32, @as(f64, math.minInt(i32)) + 1, math.minInt(i32) + 1); - try test__fixint(f64, i32, -2.0, -2); - try test__fixint(f64, i32, -1.9, -1); - try test__fixint(f64, i32, -1.1, -1); - try test__fixint(f64, i32, -1.0, -1); - try test__fixint(f64, i32, -0.9, 0); - try test__fixint(f64, i32, -0.1, 0); - try test__fixint(f64, i32, -@as(f64, math.floatMin(f32)), 0); - try test__fixint(f64, i32, -0.0, 0); - try test__fixint(f64, i32, 0.0, 0); - try test__fixint(f64, i32, @as(f64, math.floatMin(f32)), 0); - try test__fixint(f64, i32, 0.1, 0); - try test__fixint(f64, i32, 0.9, 0); - try test__fixint(f64, i32, 1.0, 1); - try test__fixint(f64, i32, @as(f64, math.maxInt(i32)) - 1, math.maxInt(i32) - 1); - try test__fixint(f64, i32, @as(f64, math.maxInt(i32)), math.maxInt(i32)); - try test__fixint(f64, i32, math.floatMax(f64), math.maxInt(i32)); - try test__fixint(f64, i32, math.inf(f64), math.maxInt(i32)); -} - -test "fixint.i64" { - try test__fixint(f64, i64, -math.inf(f64), math.minInt(i64)); - try test__fixint(f64, i64, -math.floatMax(f64), math.minInt(i64)); - try test__fixint(f64, i64, @as(f64, math.minInt(i64)), math.minInt(i64)); - try test__fixint(f64, i64, @as(f64, math.minInt(i64)) + 1, math.minInt(i64)); - try test__fixint(f64, i64, @as(f64, math.minInt(i64) / 2), math.minInt(i64) / 2); - try test__fixint(f64, i64, -2.0, -2); - try test__fixint(f64, i64, -1.9, -1); - try test__fixint(f64, i64, -1.1, -1); - try test__fixint(f64, i64, -1.0, -1); - try test__fixint(f64, i64, -0.9, 0); - try test__fixint(f64, i64, -0.1, 0); - try test__fixint(f64, i64, -@as(f64, math.floatMin(f32)), 0); - try test__fixint(f64, i64, -0.0, 0); - try test__fixint(f64, i64, 0.0, 0); - try test__fixint(f64, i64, @as(f64, math.floatMin(f32)), 0); - try test__fixint(f64, i64, 0.1, 0); - try test__fixint(f64, i64, 0.9, 0); - try test__fixint(f64, i64, 1.0, 1); - try test__fixint(f64, i64, @as(f64, math.maxInt(i64)) - 1, math.maxInt(i64)); - try test__fixint(f64, i64, @as(f64, math.maxInt(i64)), math.maxInt(i64)); - try test__fixint(f64, i64, math.floatMax(f64), math.maxInt(i64)); - try test__fixint(f64, i64, math.inf(f64), math.maxInt(i64)); -} - -test "fixint.i128" { - try test__fixint(f64, i128, -math.inf(f64), math.minInt(i128)); - try test__fixint(f64, i128, -math.floatMax(f64), math.minInt(i128)); - try test__fixint(f64, i128, @as(f64, math.minInt(i128)), math.minInt(i128)); - try test__fixint(f64, i128, @as(f64, math.minInt(i128)) + 1, math.minInt(i128)); - try test__fixint(f64, i128, -2.0, -2); - try test__fixint(f64, i128, -1.9, -1); - try test__fixint(f64, i128, -1.1, -1); - try test__fixint(f64, i128, -1.0, -1); - try test__fixint(f64, i128, -0.9, 0); - try test__fixint(f64, i128, -0.1, 0); - try test__fixint(f64, i128, -@as(f64, math.floatMin(f32)), 0); - try test__fixint(f64, i128, -0.0, 0); - try test__fixint(f64, i128, 0.0, 0); - try test__fixint(f64, i128, @as(f64, math.floatMin(f32)), 0); - try test__fixint(f64, i128, 0.1, 0); - try test__fixint(f64, i128, 0.9, 0); - try test__fixint(f64, i128, 1.0, 1); - try test__fixint(f64, i128, @as(f64, math.maxInt(i128)) - 1, math.maxInt(i128)); - try test__fixint(f64, i128, @as(f64, math.maxInt(i128)), math.maxInt(i128)); - try test__fixint(f64, i128, math.floatMax(f64), math.maxInt(i128)); - try test__fixint(f64, i128, math.inf(f64), math.maxInt(i128)); -} diff --git a/lib/compiler_rt/fixsfdi.zig b/lib/compiler_rt/fixsfdi.zig deleted file mode 100644 index 0a3731877e8bf7c7591391c8d76a6a5f953e74f1..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixsfdi.zig +++ /dev/null @@ -1,23 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const intFromFloat = @import("./int_from_float.zig").intFromFloat; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_f2lz, "__aeabi_f2lz"); - } else { - if (compiler_rt.want_windows_arm_abi) { - symbol(&__fixsfdi, "__stoi64"); - } - symbol(&__fixsfdi, "__fixsfdi"); - } -} - -pub fn __fixsfdi(a: f32) callconv(.c) i64 { - return intFromFloat(i64, a); -} - -fn __aeabi_f2lz(a: f32) callconv(.{ .arm_aapcs = .{} }) i64 { - return intFromFloat(i64, a); -} diff --git a/lib/compiler_rt/fixsfei.zig b/lib/compiler_rt/fixsfei.zig deleted file mode 100644 index 43243254059d78d0ba678bcf1ae9ab37b50c3f47..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixsfei.zig +++ /dev/null @@ -1,14 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; - -comptime { - symbol(&__fixsfei, "__fixsfei"); -} - -pub fn __fixsfei(r: [*]u8, bits: usize, a: f32) callconv(.c) void { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); -} diff --git a/lib/compiler_rt/fixsfsi.zig b/lib/compiler_rt/fixsfsi.zig deleted file mode 100644 index 9c07c5824a25aac5f83ae2e2f58ce4df66f53b38..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixsfsi.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_f2iz, "__aeabi_f2iz"); - } else { - symbol(&__fixsfsi, "__fixsfsi"); - } -} - -pub fn __fixsfsi(a: f32) callconv(.c) i32 { - return intFromFloat(i32, a); -} - -fn __aeabi_f2iz(a: f32) callconv(.{ .arm_aapcs = .{} }) i32 { - return intFromFloat(i32, a); -} diff --git a/lib/compiler_rt/fixsfti.zig b/lib/compiler_rt/fixsfti.zig deleted file mode 100644 index 121eff084d58a00726ed140a0d4f4cacafdce87b..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixsfti.zig +++ /dev/null @@ -1,12 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - symbol(&__fixsfti, "__fixsfti"); -} - -pub fn __fixsfti(a: f32) callconv(.c) i128 { - return intFromFloat(i128, a); -} diff --git a/lib/compiler_rt/fixtfdi.zig b/lib/compiler_rt/fixtfdi.zig deleted file mode 100644 index d64682db1c1153d982acba2636b39f2b17e63753..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixtfdi.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const intFromFloat = @import("./int_from_float.zig").intFromFloat; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__fixtfdi, "__fixkfdi"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_qtox, "_Qp_qtox"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__fixtfdi, "_Q_qtoll"); - } - symbol(&__fixtfdi, "__fixtfdi"); -} - -pub fn __fixtfdi(a: f128) callconv(.c) i64 { - return intFromFloat(i64, a); -} - -fn _Qp_qtox(a: *const f128) callconv(.c) i64 { - return intFromFloat(i64, a.*); -} diff --git a/lib/compiler_rt/fixtfei.zig b/lib/compiler_rt/fixtfei.zig deleted file mode 100644 index 6443a0cb3be226c25affb17567fa8c860868aaa1..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixtfei.zig +++ /dev/null @@ -1,14 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; - -comptime { - symbol(&__fixtfei, "__fixtfei"); -} - -pub fn __fixtfei(r: [*]u8, bits: usize, a: f128) callconv(.c) void { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); -} diff --git a/lib/compiler_rt/fixtfsi.zig b/lib/compiler_rt/fixtfsi.zig deleted file mode 100644 index 9acc5ec8eac8cb72a826c50d6d034e1ea48ef603..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixtfsi.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__fixtfsi, "__fixkfsi"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_qtoi, "_Qp_qtoi"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__fixtfsi, "_Q_qtoi"); - } - symbol(&__fixtfsi, "__fixtfsi"); -} - -pub fn __fixtfsi(a: f128) callconv(.c) i32 { - return intFromFloat(i32, a); -} - -fn _Qp_qtoi(a: *const f128) callconv(.c) i32 { - return intFromFloat(i32, a.*); -} diff --git a/lib/compiler_rt/fixtfti.zig b/lib/compiler_rt/fixtfti.zig deleted file mode 100644 index 0aac298ca2c4d0fa3f8d7fd02cf1290f98929c2b..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixtfti.zig +++ /dev/null @@ -1,13 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const intFromFloat = @import("./int_from_float.zig").intFromFloat; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_ppc_abi) - symbol(&__fixtfti, "__fixkfti"); - symbol(&__fixtfti, "__fixtfti"); -} - -pub fn __fixtfti(a: f128) callconv(.c) i128 { - return intFromFloat(i128, a); -} diff --git a/lib/compiler_rt/fixunsdfdi.zig b/lib/compiler_rt/fixunsdfdi.zig deleted file mode 100644 index 340bb8f6b11276fd9fff401b7f6a655e63d0a218..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunsdfdi.zig +++ /dev/null @@ -1,23 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_d2ulz, "__aeabi_d2ulz"); - } else { - if (compiler_rt.want_windows_arm_abi) { - symbol(&__fixunsdfdi, "__dtou64"); - } - symbol(&__fixunsdfdi, "__fixunsdfdi"); - } -} - -pub fn __fixunsdfdi(a: f64) callconv(.c) u64 { - return intFromFloat(u64, a); -} - -fn __aeabi_d2ulz(a: f64) callconv(.{ .arm_aapcs = .{} }) u64 { - return intFromFloat(u64, a); -} diff --git a/lib/compiler_rt/fixunsdfei.zig b/lib/compiler_rt/fixunsdfei.zig deleted file mode 100644 index f564f7f7a32869e7cdad92a2f264941a3eab7511..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunsdfei.zig +++ /dev/null @@ -1,15 +0,0 @@ -const builtin = @import("builtin"); - -const std = @import("std"); - -const symbol = @import("../compiler_rt.zig").symbol; -const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; - -comptime { - symbol(&__fixunsdfei, "__fixunsdfei"); -} - -pub fn __fixunsdfei(r: [*]u8, bits: usize, a: f64) callconv(.c) void { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); -} diff --git a/lib/compiler_rt/fixunsdfsi.zig b/lib/compiler_rt/fixunsdfsi.zig deleted file mode 100644 index e8b976d03d690d0de88d07e3fe4b97c0490e5901..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunsdfsi.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_d2uiz, "__aeabi_d2uiz"); - } else { - symbol(&__fixunsdfsi, "__fixunsdfsi"); - } -} - -pub fn __fixunsdfsi(a: f64) callconv(.c) u32 { - return intFromFloat(u32, a); -} - -fn __aeabi_d2uiz(a: f64) callconv(.{ .arm_aapcs = .{} }) u32 { - return intFromFloat(u32, a); -} diff --git a/lib/compiler_rt/fixunsdfti.zig b/lib/compiler_rt/fixunsdfti.zig deleted file mode 100644 index 1a634baaf5a6da399abaebb3e236ea5c02005ead..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunsdfti.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - symbol(&__fixunsdfti, "__fixunsdfti"); -} - -pub fn __fixunsdfti(a: f64) callconv(.c) u128 { - return intFromFloat(u128, a); -} diff --git a/lib/compiler_rt/fixunshfdi.zig b/lib/compiler_rt/fixunshfdi.zig deleted file mode 100644 index 741e482506d2df3ffbb1388a9848f9317f6f1808..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunshfdi.zig +++ /dev/null @@ -1,10 +0,0 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - symbol(&__fixunshfdi, "__fixunshfdi"); -} - -fn __fixunshfdi(a: f16) callconv(.c) u64 { - return intFromFloat(u64, a); -} diff --git a/lib/compiler_rt/fixunshfei.zig b/lib/compiler_rt/fixunshfei.zig deleted file mode 100644 index a61d94f3958f4cc8f5f01f57f317e5a44f32fc20..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunshfei.zig +++ /dev/null @@ -1,15 +0,0 @@ -const builtin = @import("builtin"); - -const std = @import("std"); - -const symbol = @import("../compiler_rt.zig").symbol; -const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; - -comptime { - symbol(&__fixunshfei, "__fixunshfei"); -} - -pub fn __fixunshfei(r: [*]u8, bits: usize, a: f16) callconv(.c) void { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); -} diff --git a/lib/compiler_rt/fixunshfsi.zig b/lib/compiler_rt/fixunshfsi.zig deleted file mode 100644 index 438767c7a89a57c22385a1b666a6f59875d1f7ba..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunshfsi.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - symbol(&__fixunshfsi, "__fixunshfsi"); -} - -fn __fixunshfsi(a: f16) callconv(.c) u32 { - return intFromFloat(u32, a); -} diff --git a/lib/compiler_rt/fixunshfti.zig b/lib/compiler_rt/fixunshfti.zig deleted file mode 100644 index 3dc7a5f99390d05606bb09298651e1d4482e3ab6..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunshfti.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const intFromFloat = @import("./int_from_float.zig").intFromFloat; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - symbol(&__fixunshfti, "__fixunshfti"); -} - -pub fn __fixunshfti(a: f16) callconv(.c) u128 { - return intFromFloat(u128, a); -} diff --git a/lib/compiler_rt/fixunssfdi.zig b/lib/compiler_rt/fixunssfdi.zig deleted file mode 100644 index ffc238a53fb9f12a64446371a3d3191331d6994c..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunssfdi.zig +++ /dev/null @@ -1,23 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_f2ulz, "__aeabi_f2ulz"); - } else { - if (compiler_rt.want_windows_arm_abi) { - symbol(&__fixunssfdi, "__stou64"); - } - symbol(&__fixunssfdi, "__fixunssfdi"); - } -} - -pub fn __fixunssfdi(a: f32) callconv(.c) u64 { - return intFromFloat(u64, a); -} - -fn __aeabi_f2ulz(a: f32) callconv(.{ .arm_aapcs = .{} }) u64 { - return intFromFloat(u64, a); -} diff --git a/lib/compiler_rt/fixunssfei.zig b/lib/compiler_rt/fixunssfei.zig deleted file mode 100644 index 2fd123bd1b4693f96b51604a794dc2879660dc87..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunssfei.zig +++ /dev/null @@ -1,15 +0,0 @@ -const builtin = @import("builtin"); - -const std = @import("std"); - -const symbol = @import("../compiler_rt.zig").symbol; -const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; - -comptime { - symbol(&__fixunssfei, "__fixunssfei"); -} - -pub fn __fixunssfei(r: [*]u8, bits: usize, a: f32) callconv(.c) void { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); -} diff --git a/lib/compiler_rt/fixunssfsi.zig b/lib/compiler_rt/fixunssfsi.zig deleted file mode 100644 index f9c09b3f3d881774c21117e3c32b3a0b0b0a9f82..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunssfsi.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_f2uiz, "__aeabi_f2uiz"); - } else { - symbol(&__fixunssfsi, "__fixunssfsi"); - } -} - -pub fn __fixunssfsi(a: f32) callconv(.c) u32 { - return intFromFloat(u32, a); -} - -fn __aeabi_f2uiz(a: f32) callconv(.{ .arm_aapcs = .{} }) u32 { - return intFromFloat(u32, a); -} diff --git a/lib/compiler_rt/fixunssfti.zig b/lib/compiler_rt/fixunssfti.zig deleted file mode 100644 index 6824afcde4b518642189696a47c0983047dd47c3..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunssfti.zig +++ /dev/null @@ -1,12 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const intFromFloat = @import("./int_from_float.zig").intFromFloat; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - symbol(&__fixunssfti, "__fixunssfti"); -} - -pub fn __fixunssfti(a: f32) callconv(.c) u128 { - return intFromFloat(u128, a); -} diff --git a/lib/compiler_rt/fixunstfdi.zig b/lib/compiler_rt/fixunstfdi.zig deleted file mode 100644 index c535bcc3583c93721f4fc07146f66edcc7611b01..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunstfdi.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__fixunstfdi, "__fixunskfdi"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_qtoux, "_Qp_qtoux"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__fixunstfdi, "_Q_qtoull"); - } - symbol(&__fixunstfdi, "__fixunstfdi"); -} - -pub fn __fixunstfdi(a: f128) callconv(.c) u64 { - return intFromFloat(u64, a); -} - -fn _Qp_qtoux(a: *const f128) callconv(.c) u64 { - return intFromFloat(u64, a.*); -} diff --git a/lib/compiler_rt/fixunstfei.zig b/lib/compiler_rt/fixunstfei.zig deleted file mode 100644 index 3d8986da90790a1a9cbf9a5fa2939e94c8009cc2..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunstfei.zig +++ /dev/null @@ -1,15 +0,0 @@ -const builtin = @import("builtin"); - -const std = @import("std"); - -const symbol = @import("../compiler_rt.zig").symbol; -const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; - -comptime { - symbol(&__fixunstfei, "__fixunstfei"); -} - -pub fn __fixunstfei(r: [*]u8, bits: usize, a: f128) callconv(.c) void { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); -} diff --git a/lib/compiler_rt/fixunstfsi.zig b/lib/compiler_rt/fixunstfsi.zig deleted file mode 100644 index d31cd759744d7616b30050335f70c50921a76ca9..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunstfsi.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__fixunstfsi, "__fixunskfsi"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_qtoui, "_Qp_qtoui"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__fixunstfsi, "_Q_qtou"); - } - symbol(&__fixunstfsi, "__fixunstfsi"); -} - -pub fn __fixunstfsi(a: f128) callconv(.c) u32 { - return intFromFloat(u32, a); -} - -fn _Qp_qtoui(a: *const f128) callconv(.c) u32 { - return intFromFloat(u32, a.*); -} diff --git a/lib/compiler_rt/fixunstfti.zig b/lib/compiler_rt/fixunstfti.zig deleted file mode 100644 index 78c6b1e8f7b90aa5d90a957920e949bb0aa2cbc0..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunstfti.zig +++ /dev/null @@ -1,14 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - if (compiler_rt.want_ppc_abi) - symbol(&__fixunstfti, "__fixunskfti"); - symbol(&__fixunstfti, "__fixunstfti"); -} - -pub fn __fixunstfti(a: f128) callconv(.c) u128 { - return intFromFloat(u128, a); -} diff --git a/lib/compiler_rt/fixunsxfdi.zig b/lib/compiler_rt/fixunsxfdi.zig deleted file mode 100644 index 8385961b6b2ea2cd7632776ffa46d41e9e6f8bf3..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunsxfdi.zig +++ /dev/null @@ -1,10 +0,0 @@ -const intFromFloat = @import("./int_from_float.zig").intFromFloat; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - symbol(&__fixunsxfdi, "__fixunsxfdi"); -} - -fn __fixunsxfdi(a: f80) callconv(.c) u64 { - return intFromFloat(u64, a); -} diff --git a/lib/compiler_rt/fixunsxfei.zig b/lib/compiler_rt/fixunsxfei.zig deleted file mode 100644 index d7902ddff54773d5240a57c8aaf6910ab6f9f02e..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunsxfei.zig +++ /dev/null @@ -1,13 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const symbol = @import("../compiler_rt.zig").symbol; -const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; - -comptime { - symbol(&__fixunsxfei, "__fixunsxfei"); -} - -pub fn __fixunsxfei(r: [*]u8, bits: usize, a: f80) callconv(.c) void { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return bigIntFromFloat(.unsigned, @ptrCast(@alignCast(r[0..byte_size])), a); -} diff --git a/lib/compiler_rt/fixunsxfsi.zig b/lib/compiler_rt/fixunsxfsi.zig deleted file mode 100644 index 7309fbf5a6cf72a7eb862773fbb121437243c2ee..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunsxfsi.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - symbol(&__fixunsxfsi, "__fixunsxfsi"); -} - -fn __fixunsxfsi(a: f80) callconv(.c) u32 { - return intFromFloat(u32, a); -} diff --git a/lib/compiler_rt/fixunsxfti.zig b/lib/compiler_rt/fixunsxfti.zig deleted file mode 100644 index 064c1352c9045870c1a984850f71c86fcf6e8e61..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixunsxfti.zig +++ /dev/null @@ -1,12 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - symbol(&__fixunsxfti, "__fixunsxfti"); -} - -pub fn __fixunsxfti(a: f80) callconv(.c) u128 { - return intFromFloat(u128, a); -} diff --git a/lib/compiler_rt/fixxfdi.zig b/lib/compiler_rt/fixxfdi.zig deleted file mode 100644 index e9e4b7528b07168dafdf4791a6cc13d795d5b78a..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixxfdi.zig +++ /dev/null @@ -1,10 +0,0 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - symbol(&__fixxfdi, "__fixxfdi"); -} - -fn __fixxfdi(a: f80) callconv(.c) i64 { - return intFromFloat(i64, a); -} diff --git a/lib/compiler_rt/fixxfei.zig b/lib/compiler_rt/fixxfei.zig deleted file mode 100644 index 82cd67648df13ac446de3a74ef796ba55ad45065..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixxfei.zig +++ /dev/null @@ -1,14 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const bigIntFromFloat = @import("int_from_float.zig").bigIntFromFloat; - -comptime { - symbol(&__fixxfei, "__fixxfei"); -} - -pub fn __fixxfei(r: [*]u8, bits: usize, a: f80) callconv(.c) void { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return bigIntFromFloat(.signed, @ptrCast(@alignCast(r[0..byte_size])), a); -} diff --git a/lib/compiler_rt/fixxfsi.zig b/lib/compiler_rt/fixxfsi.zig deleted file mode 100644 index 363492168c760bcd12432e7c757ec4b8f60a2cc1..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/fixxfsi.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const intFromFloat = @import("./int_from_float.zig").intFromFloat; - -comptime { - symbol(&__fixxfsi, "__fixxfsi"); -} - -fn __fixxfsi(a: f80) callconv(.c) i32 { - return intFromFloat(i32, a); -} diff --git a/lib/compiler_rt/float_from_int.zig b/lib/compiler_rt/float_from_int.zig index 548d027accbb674e1ecbaeb77ef01a5491e256bc..898f246579c2902f5267d7e54c87422292931891 100644 --- a/lib/compiler_rt/float_from_int.zig +++ b/lib/compiler_rt/float_from_int.zig @@ -1,7 +1,475 @@ +const builtin = @import("builtin"); const std = @import("std"); const math = std.math; -pub fn floatFromInt(comptime T: type, x: anytype) T { +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; + +comptime { + symbol(&__floatsihf, "__floatsihf"); + symbol(&__floatdihf, "__floatdihf"); + symbol(&__floattihf, "__floattihf"); + symbol(&__floateihf, "__floateihf"); + + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_i2f, "__aeabi_i2f"); + symbol(&__aeabi_l2f, "__aeabi_l2f"); + } else { + symbol(&__floatsisf, "__floatsisf"); + symbol(&__floatdisf, "__floatdisf"); + if (compiler_rt.want_windows_arm_abi) symbol(&__floatdisf, "__i64tos"); + } + symbol(&__floattisf, "__floattisf"); + symbol(&__floateisf, "__floateisf"); + + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_i2d, "__aeabi_i2d"); + symbol(&__aeabi_l2d, "__aeabi_l2d"); + } else { + symbol(&__floatsidf, "__floatsidf"); + symbol(&__floatdidf, "__floatdidf"); + if (compiler_rt.want_windows_arm_abi) symbol(&__floatdidf, "__i64tod"); + } + symbol(&__floattidf, "__floattidf"); + symbol(&__floateidf, "__floateidf"); + + symbol(&__floatsixf, "__floatsixf"); + symbol(&__floatdixf, "__floatdixf"); + symbol(&__floattixf, "__floattixf"); + symbol(&__floateixf, "__floateixf"); + + if (compiler_rt.want_ppc_abi) { + symbol(&__floatsitf, "__floatsikf"); + symbol(&__floatditf, "__floatdikf"); + } else if (compiler_rt.want_sparc64_abi) { + symbol(&_Qp_itoq, "_Qp_itoq"); + symbol(&_Qp_xtoq, "_Qp_xtoq"); + } else if (compiler_rt.want_sparc32_abi) { + symbol(&__floatsitf, "_Q_itoq"); + symbol(&__floatditf, "_Q_lltoq"); + } else { + symbol(&__floatsitf, "__floatsitf"); + symbol(&__floatditf, "__floatditf"); + } + if (compiler_rt.want_ppc_abi) { + symbol(&__floattitf, "__floattikf"); + symbol(&__floateitf, "__floateikf"); + } else { + if (builtin.cpu.arch == .x86) { + symbol(&__floattitf_x86, "__floattitf"); + } else { + symbol(&__floattitf, "__floattitf"); + } + symbol(&__floateitf, "__floateitf"); + } +} + +fn __floatsihf(a: i32) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(f16_floatFromInt_i32(a)); +} +pub fn f16_floatFromInt_i32(a: i32) f16 { + return floatFromInt(f16, a); +} + +fn __floatdihf(a: i64) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(f16_floatFromInt_i64(a)); +} +pub fn f16_floatFromInt_i64(a: i64) f16 { + return floatFromInt(f16, a); +} + +fn __floattihf(a: i128) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(f16_floatFromInt_i128(a)); +} +pub fn f16_floatFromInt_i128(a: i128) f16 { + return floatFromInt(f16, a); +} + +fn __floateihf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f16.Abi { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return compiler_rt.f16.toAbi(f16_floatFromInt_signed(a[0..byte_size])); +} +pub fn f16_floatFromInt_signed(a: []const u8) f16 { + return floatFromBigInt(f16, .signed, @ptrCast(@alignCast(a))); +} + +fn __floatsisf(a: i32) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(f32_floatFromInt_i32(a)); +} +fn __aeabi_i2f(a: i32) callconv(.{ .arm_aapcs = .{} }) f32 { + return f32_floatFromInt_i32(a); +} +pub fn f32_floatFromInt_i32(a: i32) f32 { + return floatFromInt(f32, a); +} + +fn __floatdisf(a: i64) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(f32_floatFromInt_i64(a)); +} +fn __aeabi_l2f(a: i64) callconv(.{ .arm_aapcs = .{} }) f32 { + return f32_floatFromInt_i64(a); +} +pub fn f32_floatFromInt_i64(a: i64) f32 { + return floatFromInt(f32, a); +} + +fn __floattisf(a: i128) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(f32_floatFromInt_i128(a)); +} +pub fn f32_floatFromInt_i128(a: i128) f32 { + return floatFromInt(f32, a); +} + +fn __floateisf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f32.Abi { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return compiler_rt.f32.toAbi(f32_floatFromInt_signed(a[0..byte_size])); +} +pub fn f32_floatFromInt_signed(a: []const u8) f32 { + return floatFromBigInt(f32, .signed, @ptrCast(@alignCast(a))); +} + +fn __floatsidf(a: i32) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(f64_floatFromInt_i32(a)); +} +fn __aeabi_i2d(a: i32) callconv(.{ .arm_aapcs = .{} }) f64 { + return f64_floatFromInt_i32(a); +} +pub fn f64_floatFromInt_i32(a: i32) f64 { + return floatFromInt(f64, a); +} + +fn __floatdidf(a: i64) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(f64_floatFromInt_i64(a)); +} +fn __aeabi_l2d(a: i64) callconv(.{ .arm_aapcs = .{} }) f64 { + return f64_floatFromInt_i64(a); +} +pub fn f64_floatFromInt_i64(a: i64) f64 { + return floatFromInt(f64, a); +} + +fn __floattidf(a: i128) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(f64_floatFromInt_i128(a)); +} +pub fn f64_floatFromInt_i128(a: i128) f64 { + return floatFromInt(f64, a); +} + +fn __floateidf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f64.Abi { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return compiler_rt.f64.toAbi(f64_floatFromInt_signed(a[0..byte_size])); +} +pub fn f64_floatFromInt_signed(a: []const u8) f64 { + return floatFromBigInt(f64, .signed, @ptrCast(@alignCast(a))); +} + +fn __floatsixf(a: i32) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(f80_floatFromInt_i32(a)); +} +pub fn f80_floatFromInt_i32(a: i32) f80 { + return floatFromInt(f80, a); +} + +fn __floatdixf(a: i64) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(f80_floatFromInt_i64(a)); +} +pub fn f80_floatFromInt_i64(a: i64) f80 { + return floatFromInt(f80, a); +} + +fn __floattixf(a: i128) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(f80_floatFromInt_i128(a)); +} +pub fn f80_floatFromInt_i128(a: i128) f80 { + return floatFromInt(f80, a); +} + +fn __floateixf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f80.Abi { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return compiler_rt.f80.toAbi(f80_floatFromInt_signed(a[0..byte_size])); +} +pub fn f80_floatFromInt_signed(a: []const u8) f80 { + return floatFromBigInt(f80, .signed, @ptrCast(@alignCast(a))); +} + +fn __floatsitf(a: i32) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatFromInt_i32(a)); +} +fn _Qp_itoq(c: *f128, a: i32) callconv(.c) void { + c.* = f128_floatFromInt_i32(a); +} +pub fn f128_floatFromInt_i32(a: i32) f128 { + return floatFromInt(f128, a); +} + +fn __floatditf(a: i64) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatFromInt_i64(a)); +} +fn _Qp_xtoq(c: *f128, a: i64) callconv(.c) void { + c.* = f128_floatFromInt_i64(a); +} +pub fn f128_floatFromInt_i64(a: i64) f128 { + return floatFromInt(f128, a); +} + +fn __floattitf(a: i128) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatFromInt_i128(a)); +} +fn __floattitf_x86(a: f128) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatFromInt_i128(@bitCast(a))); +} +pub fn f128_floatFromInt_i128(a: i128) f128 { + return floatFromInt(f128, a); +} + +fn __floateitf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f128.Abi { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return compiler_rt.f128.toAbi(f128_floatFromInt_signed(a[0..byte_size])); +} +pub fn f128_floatFromInt_signed(a: []const u8) f128 { + return floatFromBigInt(f128, .signed, @ptrCast(@alignCast(a))); +} + +comptime { + symbol(&__floatunsihf, "__floatunsihf"); + symbol(&__floatundihf, "__floatundihf"); + symbol(&__floatuntihf, "__floatuntihf"); + symbol(&__floatuneihf, "__floatuneihf"); + + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_ui2f, "__aeabi_ui2f"); + symbol(&__aeabi_ul2f, "__aeabi_ul2f"); + } else { + symbol(&__floatunsisf, "__floatunsisf"); + symbol(&__floatundisf, "__floatundisf"); + if (compiler_rt.want_windows_arm_abi) symbol(&__floatundisf, "__u64tos"); + } + symbol(&__floatuntisf, "__floatuntisf"); + symbol(&__floatuneisf, "__floatuneisf"); + + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_ui2d, "__aeabi_ui2d"); + } else { + symbol(&__floatunsidf, "__floatunsidf"); + } + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_ul2d, "__aeabi_ul2d"); + } else { + if (compiler_rt.want_windows_arm_abi) { + symbol(&__floatundidf, "__u64tod"); + } + symbol(&__floatundidf, "__floatundidf"); + } + symbol(&__floatuntidf, "__floatuntidf"); + symbol(&__floatuneidf, "__floatuneidf"); + + symbol(&__floatunsixf, "__floatunsixf"); + symbol(&__floatundixf, "__floatundixf"); + symbol(&__floatuntixf, "__floatuntixf"); + symbol(&__floatuneixf, "__floatuneixf"); + + if (compiler_rt.want_ppc_abi) { + symbol(&__floatunsitf, "__floatunsikf"); + symbol(&__floatunditf, "__floatundikf"); + } else if (compiler_rt.want_sparc64_abi) { + symbol(&_Qp_uitoq, "_Qp_uitoq"); + symbol(&_Qp_uxtoq, "_Qp_uxtoq"); + } else if (compiler_rt.want_sparc32_abi) { + symbol(&__floatunsitf, "_Q_utoq"); + symbol(&__floatunditf, "_Q_ulltoq"); + } else { + symbol(&__floatunsitf, "__floatunsitf"); + symbol(&__floatunditf, "__floatunditf"); + } + if (compiler_rt.want_ppc_abi) { + symbol(&__floatuntitf, "__floatuntikf"); + symbol(&__floatuneitf, "__floatuneikf"); + } else { + if (builtin.cpu.arch == .x86) { + symbol(&__floatuntitf_x86, "__floatuntitf"); + } else if (builtin.cpu.arch == .x86_64 and + (builtin.os.tag == .windows or builtin.os.tag == .uefi)) + { + symbol(&__floatuntitf_x86_64_windows, "__floatuntitf"); + } else { + symbol(&__floatuntitf, "__floatuntitf"); + } + symbol(&__floatuneitf, "__floatuneitf"); + } +} + +fn __floatunsihf(a: u32) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(f16_floatFromInt_u32(a)); +} +pub fn f16_floatFromInt_u32(a: u32) f16 { + return floatFromInt(f16, a); +} + +fn __floatundihf(a: u64) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(f16_floatFromInt_u64(a)); +} +pub fn f16_floatFromInt_u64(a: u64) f16 { + return floatFromInt(f16, a); +} + +fn __floatuntihf(a: u128) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(f16_floatFromInt_u128(a)); +} +pub fn f16_floatFromInt_u128(a: u128) f16 { + return floatFromInt(f16, a); +} + +fn __floatuneihf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f16.Abi { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return compiler_rt.f16.toAbi(f16_floatFromInt_unsigned(a[0..byte_size])); +} +pub fn f16_floatFromInt_unsigned(a: []const u8) f16 { + return floatFromBigInt(f16, .unsigned, @ptrCast(@alignCast(a))); +} + +fn __floatunsisf(a: u32) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(f32_floatFromInt_u32(a)); +} +fn __aeabi_ui2f(a: u32) callconv(.{ .arm_aapcs = .{} }) f32 { + return f32_floatFromInt_u32(a); +} +pub fn f32_floatFromInt_u32(a: u32) f32 { + return floatFromInt(f32, a); +} + +fn __floatundisf(a: u64) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(f32_floatFromInt_u64(a)); +} +fn __aeabi_ul2f(a: u64) callconv(.{ .arm_aapcs = .{} }) f32 { + return f32_floatFromInt_u64(a); +} +pub fn f32_floatFromInt_u64(a: u64) f32 { + return floatFromInt(f32, a); +} + +fn __floatuntisf(a: u128) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(f32_floatFromInt_u128(a)); +} +pub fn f32_floatFromInt_u128(a: u128) f32 { + return floatFromInt(f32, a); +} + +fn __floatuneisf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f32.Abi { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return compiler_rt.f32.toAbi(f32_floatFromInt_unsigned(a[0..byte_size])); +} +pub fn f32_floatFromInt_unsigned(a: []const u8) f32 { + return floatFromBigInt(f32, .unsigned, @ptrCast(@alignCast(a))); +} + +fn __floatunsidf(a: u32) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(f64_floatFromInt_u32(a)); +} +fn __aeabi_ui2d(a: u32) callconv(.{ .arm_aapcs = .{} }) f64 { + return f64_floatFromInt_u32(a); +} +pub fn f64_floatFromInt_u32(a: u32) f64 { + return floatFromInt(f64, a); +} + +fn __floatundidf(a: u64) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(f64_floatFromInt_u64(a)); +} +fn __aeabi_ul2d(a: u64) callconv(.{ .arm_aapcs = .{} }) f64 { + return f64_floatFromInt_u64(a); +} +pub fn f64_floatFromInt_u64(a: u64) f64 { + return floatFromInt(f64, a); +} + +fn __floatuntidf(a: u128) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(f64_floatFromInt_u128(a)); +} +pub fn f64_floatFromInt_u128(a: u128) f64 { + return floatFromInt(f64, a); +} + +fn __floatuneidf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f64.Abi { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return compiler_rt.f64.toAbi(f64_floatFromInt_unsigned(a[0..byte_size])); +} +pub fn f64_floatFromInt_unsigned(a: []const u8) f64 { + return floatFromBigInt(f64, .unsigned, @ptrCast(@alignCast(a))); +} + +fn __floatunsixf(a: u32) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(f80_floatFromInt_u32(a)); +} +pub fn f80_floatFromInt_u32(a: u32) f80 { + return floatFromInt(f80, a); +} + +fn __floatundixf(a: u64) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(f80_floatFromInt_u64(a)); +} +pub fn f80_floatFromInt_u64(a: u64) f80 { + return floatFromInt(f80, a); +} + +fn __floatuntixf(a: u128) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(f80_floatFromInt_u128(a)); +} +pub fn f80_floatFromInt_u128(a: u128) f80 { + return floatFromInt(f80, a); +} + +fn __floatuneixf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f80.Abi { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return compiler_rt.f80.toAbi(f80_floatFromInt_unsigned(a[0..byte_size])); +} +pub fn f80_floatFromInt_unsigned(a: []const u8) f80 { + return floatFromBigInt(f80, .unsigned, @ptrCast(@alignCast(a))); +} + +fn __floatunsitf(a: u32) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatFromInt_u32(a)); +} +fn _Qp_uitoq(c: *f128, a: u32) callconv(.c) void { + c.* = f128_floatFromInt_u32(a); +} +pub fn f128_floatFromInt_u32(a: u32) f128 { + return floatFromInt(f128, a); +} + +fn __floatunditf(a: u64) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatFromInt_u64(a)); +} +fn _Qp_uxtoq(c: *f128, a: u64) callconv(.c) void { + c.* = f128_floatFromInt_u64(a); +} +pub fn f128_floatFromInt_u64(a: u64) f128 { + return floatFromInt(f128, a); +} + +fn __floatuntitf(a: u128) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatFromInt_u128(a)); +} +fn __floatuntitf_x86(a: f128) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatFromInt_u128(@bitCast(a))); +} +fn __floatuntitf_x86_64_windows(a_lo: u64, a_hi: u64) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(f128_floatFromInt_u128(@bitCast( + packed struct { lo: u64, hi: u64 }{ .lo = a_lo, .hi = a_hi }, + ))); +} +pub fn f128_floatFromInt_u128(a: u128) f128 { + return floatFromInt(f128, a); +} + +fn __floatuneitf(a: [*]const u8, bits: usize) callconv(.c) compiler_rt.f128.Abi { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return compiler_rt.f128.toAbi(f128_floatFromInt_unsigned(a[0..byte_size])); +} +pub fn f128_floatFromInt_unsigned(a: []const u8) f128 { + return floatFromBigInt(f128, .unsigned, @ptrCast(@alignCast(a))); +} + +inline fn floatFromInt(comptime T: type, x: anytype) T { if (x == 0) return 0; // Various constants whose values follow from the type parameters. @@ -53,7 +521,7 @@ pub fn floatFromInt(comptime T: type, x: anytype) T { return @bitCast(sign_bit | result); } -const endian = @import("builtin").cpu.arch.endian(); +const endian = builtin.cpu.arch.endian(); inline fn limb(limbs: []const u32, index: usize) u32 { return switch (endian) { .little => limbs[index], @@ -61,11 +529,11 @@ inline fn limb(limbs: []const u32, index: usize) u32 { }; } -pub inline fn floatFromBigInt(comptime T: type, comptime signedness: std.builtin.Signedness, x: []const u32) T { +inline fn floatFromBigInt(comptime T: type, comptime signedness: std.lang.Signedness, x: []const u32) T { switch (x.len) { 0 => return 0, inline 1...4 => |limbs_len| { - const low_to_high: [limbs_len]u32 = switch (@import("builtin").cpu.arch.endian()) { + const low_to_high: [limbs_len]u32 = switch (endian) { .little => x[0..limbs_len].*, .big => switch (limbs_len) { 1 => .{x[0]}, diff --git a/lib/compiler_rt/float_from_int_test.zig b/lib/compiler_rt/float_from_int_test.zig index 8c908f420959b28fe107f290cb0bcb709c9ffd85..4ce3129f890f3f303d835733644afcf2fedbff4c 100644 --- a/lib/compiler_rt/float_from_int_test.zig +++ b/lib/compiler_rt/float_from_int_test.zig @@ -2,571 +2,593 @@ const std = @import("std"); const testing = std.testing; const math = std.math; -const __floatunsihf = @import("floatunsihf.zig").__floatunsihf; - -// Conversion to f32 -const __floatsisf = @import("floatsisf.zig").__floatsisf; -const __floatunsisf = @import("floatunsisf.zig").__floatunsisf; -const __floatdisf = @import("floatdisf.zig").__floatdisf; -const __floatundisf = @import("floatundisf.zig").__floatundisf; -const __floattisf = @import("floattisf.zig").__floattisf; -const __floatuntisf = @import("floatuntisf.zig").__floatuntisf; -const __floateisf = @import("floateisf.zig").__floateisf; -const __floatuneisf = @import("floatuneisf.zig").__floatuneisf; - -// Conversion to f64 -const __floatsidf = @import("floatsidf.zig").__floatsidf; -const __floatunsidf = @import("floatunsidf.zig").__floatunsidf; -const __floatdidf = @import("floatdidf.zig").__floatdidf; -const __floatundidf = @import("floatundidf.zig").__floatundidf; -const __floattidf = @import("floattidf.zig").__floattidf; -const __floatuntidf = @import("floatuntidf.zig").__floatuntidf; - -// Conversion to f128 -const __floatsitf = @import("floatsitf.zig").__floatsitf; -const __floatunsitf = @import("floatunsitf.zig").__floatunsitf; -const __floatditf = @import("floatditf.zig").__floatditf; -const __floatunditf = @import("floatunditf.zig").__floatunditf; -const __floattitf = @import("floattitf.zig").__floattitf; -const __floatuntitf = @import("floatuntitf.zig").__floatuntitf; - -fn test__floatsisf(a: i32, expected: u32) !void { - const r = __floatsisf(a); +const impl = @import("float_from_int.zig"); + +const f16_floatFromInt_i32 = impl.f16_floatFromInt_i32; +const f16_floatFromInt_u32 = impl.f16_floatFromInt_u32; +const f16_floatFromInt_i64 = impl.f16_floatFromInt_i64; +const f16_floatFromInt_u64 = impl.f16_floatFromInt_u64; +const f16_floatFromInt_i128 = impl.f16_floatFromInt_i128; +const f16_floatFromInt_u128 = impl.f16_floatFromInt_u128; +const f16_floatFromInt_signed = impl.f16_floatFromInt_signed; +const f16_floatFromInt_unsigned = impl.f16_floatFromInt_unsigned; + +const f32_floatFromInt_i32 = impl.f32_floatFromInt_i32; +const f32_floatFromInt_u32 = impl.f32_floatFromInt_u32; +const f32_floatFromInt_i64 = impl.f32_floatFromInt_i64; +const f32_floatFromInt_u64 = impl.f32_floatFromInt_u64; +const f32_floatFromInt_i128 = impl.f32_floatFromInt_i128; +const f32_floatFromInt_u128 = impl.f32_floatFromInt_u128; +const f32_floatFromInt_signed = impl.f32_floatFromInt_signed; +const f32_floatFromInt_unsigned = impl.f32_floatFromInt_unsigned; + +const f64_floatFromInt_i32 = impl.f64_floatFromInt_i32; +const f64_floatFromInt_u32 = impl.f64_floatFromInt_u32; +const f64_floatFromInt_i64 = impl.f64_floatFromInt_i64; +const f64_floatFromInt_u64 = impl.f64_floatFromInt_u64; +const f64_floatFromInt_i128 = impl.f64_floatFromInt_i128; +const f64_floatFromInt_u128 = impl.f64_floatFromInt_u128; +const f64_floatFromInt_signed = impl.f64_floatFromInt_signed; +const f64_floatFromInt_unsigned = impl.f64_floatFromInt_unsigned; + +const f80_floatFromInt_i32 = impl.f80_floatFromInt_i32; +const f80_floatFromInt_u32 = impl.f80_floatFromInt_u32; +const f80_floatFromInt_i64 = impl.f80_floatFromInt_i64; +const f80_floatFromInt_u64 = impl.f80_floatFromInt_u64; +const f80_floatFromInt_i128 = impl.f80_floatFromInt_i128; +const f80_floatFromInt_u128 = impl.f80_floatFromInt_u128; +const f80_floatFromInt_signed = impl.f80_floatFromInt_signed; +const f80_floatFromInt_unsigned = impl.f80_floatFromInt_unsigned; + +const f128_floatFromInt_i32 = impl.f128_floatFromInt_i32; +const f128_floatFromInt_u32 = impl.f128_floatFromInt_u32; +const f128_floatFromInt_i64 = impl.f128_floatFromInt_i64; +const f128_floatFromInt_u64 = impl.f128_floatFromInt_u64; +const f128_floatFromInt_i128 = impl.f128_floatFromInt_i128; +const f128_floatFromInt_u128 = impl.f128_floatFromInt_u128; +const f128_floatFromInt_signed = impl.f128_floatFromInt_signed; +const f128_floatFromInt_unsigned = impl.f128_floatFromInt_unsigned; + +fn test_f32_floatFromInt_i32(a: i32, expected: u32) !void { + const r = f32_floatFromInt_i32(a); try std.testing.expect(@as(u32, @bitCast(r)) == expected); } -fn test_one_floatunsisf(a: u32, expected: u32) !void { - const r = __floatunsisf(a); +fn test_f32_floatFromInt_u32(a: u32, expected: u32) !void { + const r = f32_floatFromInt_u32(a); try std.testing.expect(@as(u32, @bitCast(r)) == expected); } -test "floatsisf" { - try test__floatsisf(0, 0x00000000); - try test__floatsisf(1, 0x3f800000); - try test__floatsisf(-1, 0xbf800000); - try test__floatsisf(0x7FFFFFFF, 0x4f000000); - try test__floatsisf(@bitCast(@as(u32, @intCast(0x80000000))), 0xcf000000); +test f32_floatFromInt_i32 { + try test_f32_floatFromInt_i32(0, 0x00000000); + try test_f32_floatFromInt_i32(1, 0x3f800000); + try test_f32_floatFromInt_i32(-1, 0xbf800000); + try test_f32_floatFromInt_i32(0x7FFFFFFF, 0x4f000000); + try test_f32_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xcf000000); + + try testing.expect(f32_floatFromInt_i32(math.minInt(i32)) == math.minInt(i32)); } -test "floatunsisf" { +test f32_floatFromInt_u32 { // Test the produced bit pattern - try test_one_floatunsisf(0, 0); - try test_one_floatunsisf(1, 0x3f800000); - try test_one_floatunsisf(0x7FFFFFFF, 0x4f000000); - try test_one_floatunsisf(0x80000000, 0x4f000000); - try test_one_floatunsisf(0xFFFFFFFF, 0x4f800000); + try test_f32_floatFromInt_u32(0, 0); + try test_f32_floatFromInt_u32(1, 0x3f800000); + try test_f32_floatFromInt_u32(0x7FFFFFFF, 0x4f000000); + try test_f32_floatFromInt_u32(0x80000000, 0x4f000000); + try test_f32_floatFromInt_u32(0xFFFFFFFF, 0x4f800000); + + try testing.expect(f32_floatFromInt_u32(0) == 0.0); + try testing.expect(f32_floatFromInt_u32(math.maxInt(u24)) == math.maxInt(u24)); + try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 1) == math.maxInt(u24) + 1); // 0x100_0000 - Exact + try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 2) == math.maxInt(u24) + 1); // 0x100_0001 - Tie: Rounds down to even + try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 3) == math.maxInt(u24) + 3); // 0x100_0002 - Exact + try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 4) == math.maxInt(u24) + 5); // 0x100_0003 - Tie: Rounds up to even + try testing.expect(f32_floatFromInt_u32(math.maxInt(u24) + 5) == math.maxInt(u24) + 5); // 0x100_0004 - Exact + try testing.expect(f32_floatFromInt_u32(math.maxInt(u32)) == math.maxInt(u32) + 1); } -fn test__floatdisf(a: i64, expected: f32) !void { - const x = __floatdisf(a); +fn test_f32_floatFromInt_i64(a: i64, expected: f32) !void { + const x = f32_floatFromInt_i64(a); try testing.expect(x == expected); } -fn test__floatundisf(a: u64, expected: f32) !void { - try std.testing.expectEqual(expected, __floatundisf(a)); +fn test_f32_floatFromInt_u64(a: u64, expected: f32) !void { + const x = f32_floatFromInt_u64(a); + try testing.expect(x == expected); } -test "floatdisf" { - try test__floatdisf(0, 0.0); - try test__floatdisf(1, 1.0); - try test__floatdisf(2, 2.0); - try test__floatdisf(-1, -1.0); - try test__floatdisf(-2, -2.0); - try test__floatdisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); - try test__floatdisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); - try test__floatdisf(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62); - try test__floatdisf(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62); - try test__floatdisf(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63); - try test__floatdisf(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63); - try test__floatdisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); - try test__floatdisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); - try test__floatdisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); - try test__floatdisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); - try test__floatdisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); - try test__floatdisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); - try test__floatdisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); - try test__floatdisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); - try test__floatdisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); - try test__floatdisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); - try test__floatdisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); +test f32_floatFromInt_i64 { + try test_f32_floatFromInt_i64(0, 0.0); + try test_f32_floatFromInt_i64(1, 1.0); + try test_f32_floatFromInt_i64(2, 2.0); + try test_f32_floatFromInt_i64(-1, -1.0); + try test_f32_floatFromInt_i64(-2, -2.0); + try test_f32_floatFromInt_i64(0x7FFFFF8000000000, 0x1.FFFFFEp+62); + try test_f32_floatFromInt_i64(0x7FFFFF0000000000, 0x1.FFFFFCp+62); + try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62); + try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62); + try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000000)), -0x1.000000p+63); + try test_f32_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000001)), -0x1.000000p+63); + try test_f32_floatFromInt_i64(0x0007FB72E8000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i64(0x0007FB72EA000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i64(0x0007FB72EB000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i64(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i64(0x0007FB72EC000000, 0x1.FEDCBCp+50); + try test_f32_floatFromInt_i64(0x0007FB72E8000001, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i64(0x0007FB72E6000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i64(0x0007FB72E7000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i64(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i64(0x0007FB72E4000001, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i64(0x0007FB72E4000000, 0x1.FEDCB8p+50); } -test "floatundisf" { - try test__floatundisf(0, 0.0); - try test__floatundisf(1, 1.0); - try test__floatundisf(2, 2.0); - try test__floatundisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); - try test__floatundisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); - try test__floatundisf(0x8000008000000000, 0x1p+63); - try test__floatundisf(0x8000010000000000, 0x1.000002p+63); - try test__floatundisf(0x8000000000000000, 0x1p+63); - try test__floatundisf(0x8000000000000001, 0x1p+63); - try test__floatundisf(0xFFFFFFFFFFFFFFFE, 0x1p+64); - try test__floatundisf(0xFFFFFFFFFFFFFFFF, 0x1p+64); - try test__floatundisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); - try test__floatundisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); - try test__floatundisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); - try test__floatundisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); - try test__floatundisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); - try test__floatundisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); - try test__floatundisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); - try test__floatundisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); - try test__floatundisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); - try test__floatundisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); - try test__floatundisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); +test f32_floatFromInt_u64 { + try test_f32_floatFromInt_u64(0, 0.0); + try test_f32_floatFromInt_u64(1, 1.0); + try test_f32_floatFromInt_u64(2, 2.0); + try test_f32_floatFromInt_u64(0x7FFFFF8000000000, 0x1.FFFFFEp+62); + try test_f32_floatFromInt_u64(0x7FFFFF0000000000, 0x1.FFFFFCp+62); + try test_f32_floatFromInt_u64(0x8000008000000000, 0x1p+63); + try test_f32_floatFromInt_u64(0x8000010000000000, 0x1.000002p+63); + try test_f32_floatFromInt_u64(0x8000000000000000, 0x1p+63); + try test_f32_floatFromInt_u64(0x8000000000000001, 0x1p+63); + try test_f32_floatFromInt_u64(0xFFFFFFFFFFFFFFFE, 0x1p+64); + try test_f32_floatFromInt_u64(0xFFFFFFFFFFFFFFFF, 0x1p+64); + try test_f32_floatFromInt_u64(0x0007FB72E8000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u64(0x0007FB72EA000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u64(0x0007FB72EB000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u64(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u64(0x0007FB72EC000000, 0x1.FEDCBCp+50); + try test_f32_floatFromInt_u64(0x0007FB72E8000001, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u64(0x0007FB72E6000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u64(0x0007FB72E7000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u64(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u64(0x0007FB72E4000001, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u64(0x0007FB72E4000000, 0x1.FEDCB8p+50); } -fn test__floattisf(a: i128, expected: f32) !void { - const x = __floattisf(a); +fn test_f32_floatFromInt_i128(a: i128, expected: f32) !void { + const x = f32_floatFromInt_i128(a); try testing.expect(x == expected); } -fn test__floatuntisf(a: u128, expected: f32) !void { - const x = __floatuntisf(a); +fn test_f32_floatFromInt_u128(a: u128, expected: f32) !void { + const x = f32_floatFromInt_u128(a); try testing.expect(x == expected); } -test "floattisf" { - try test__floattisf(0, 0.0); +test f32_floatFromInt_i128 { + try test_f32_floatFromInt_i128(0, 0.0); - try test__floattisf(1, 1.0); - try test__floattisf(2, 2.0); - try test__floattisf(-1, -1.0); - try test__floattisf(-2, -2.0); + try test_f32_floatFromInt_i128(1, 1.0); + try test_f32_floatFromInt_i128(2, 2.0); + try test_f32_floatFromInt_i128(-1, -1.0); + try test_f32_floatFromInt_i128(-2, -2.0); - try test__floattisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); - try test__floattisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); + try test_f32_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); + try test_f32_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); - try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62); - try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62); + try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000008000000000), -0x1.FFFFFEp+62); + try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000010000000000), -0x1.FFFFFCp+62); - try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63); - try test__floattisf(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63); + try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000000), -0x1.000000p+63); + try test_f32_floatFromInt_i128(make_ti(0xFFFFFFFFFFFFFFFF, 0x8000000000000001), -0x1.000000p+63); - try test__floattisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50); - try test__floattisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); - try test__floattisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); - try test__floattisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); - try test__floattisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); - try test__floattisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBCp+50); + try test_f32_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBAp+50); - try test__floattisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); - try test__floattisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); - try test__floattisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); - try test__floattisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); - try test__floattisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); + try test_f32_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB8p+50); - try test__floattisf(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114); + try test_f32_floatFromInt_i128(make_ti(0x0007FB72E8000000, 0), 0x1.FEDCBAp+114); - try test__floattisf(make_ti(0x0007FB72EA000000, 0), 0x1.FEDCBAp+114); - try test__floattisf(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114); - try test__floattisf(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114); - try test__floattisf(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114); - try test__floattisf(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114); + try test_f32_floatFromInt_i128(make_ti(0x0007FB72EA000000, 0), 0x1.FEDCBAp+114); + try test_f32_floatFromInt_i128(make_ti(0x0007FB72EB000000, 0), 0x1.FEDCBAp+114); + try test_f32_floatFromInt_i128(make_ti(0x0007FB72EBFFFFFF, 0), 0x1.FEDCBAp+114); + try test_f32_floatFromInt_i128(make_ti(0x0007FB72EC000000, 0), 0x1.FEDCBCp+114); + try test_f32_floatFromInt_i128(make_ti(0x0007FB72E8000001, 0), 0x1.FEDCBAp+114); - try test__floattisf(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114); - try test__floattisf(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114); - try test__floattisf(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114); - try test__floattisf(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114); - try test__floattisf(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114); + try test_f32_floatFromInt_i128(make_ti(0x0007FB72E6000000, 0), 0x1.FEDCBAp+114); + try test_f32_floatFromInt_i128(make_ti(0x0007FB72E7000000, 0), 0x1.FEDCBAp+114); + try test_f32_floatFromInt_i128(make_ti(0x0007FB72E7FFFFFF, 0), 0x1.FEDCBAp+114); + try test_f32_floatFromInt_i128(make_ti(0x0007FB72E4000001, 0), 0x1.FEDCBAp+114); + try test_f32_floatFromInt_i128(make_ti(0x0007FB72E4000000, 0), 0x1.FEDCB8p+114); } -test "floatuntisf" { - try test__floatuntisf(0, 0.0); +test f32_floatFromInt_u128 { + try test_f32_floatFromInt_u128(0, 0.0); - try test__floatuntisf(1, 1.0); - try test__floatuntisf(2, 2.0); - try test__floatuntisf(20, 20.0); + try test_f32_floatFromInt_u128(1, 1.0); + try test_f32_floatFromInt_u128(2, 2.0); + try test_f32_floatFromInt_u128(20, 20.0); - try test__floatuntisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); - try test__floatuntisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); + try test_f32_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); + try test_f32_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); - try test__floatuntisf(make_uti(0x8000008000000000, 0), 0x1.000001p+127); - try test__floatuntisf(make_uti(0x8000000000000800, 0), 0x1.0p+127); - try test__floatuntisf(make_uti(0x8000010000000000, 0), 0x1.000002p+127); + try test_f32_floatFromInt_u128(make_uti(0x8000008000000000, 0), 0x1.000001p+127); + try test_f32_floatFromInt_u128(make_uti(0x8000000000000800, 0), 0x1.0p+127); + try test_f32_floatFromInt_u128(make_uti(0x8000010000000000, 0), 0x1.000002p+127); - try test__floatuntisf(make_uti(0x8000000000000000, 0), 0x1.000000p+127); + try test_f32_floatFromInt_u128(make_uti(0x8000000000000000, 0), 0x1.000000p+127); - try test__floatuntisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); - try test__floatuntisf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); - try test__floatuntisf(0x0007FB72EB000000, 0x1.FEDCBACp+50); + try test_f32_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); + try test_f32_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50); - try test__floatuntisf(0x0007FB72EC000000, 0x1.FEDCBBp+50); + try test_f32_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50); - try test__floatuntisf(0x0007FB72E6000000, 0x1.FEDCB98p+50); - try test__floatuntisf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); - try test__floatuntisf(0x0007FB72E4000000, 0x1.FEDCB9p+50); + try test_f32_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50); + try test_f32_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); + try test_f32_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50); - try test__floatuntisf(0xFFFFFFFFFFFFFFFE, 0x1p+64); - try test__floatuntisf(0xFFFFFFFFFFFFFFFF, 0x1p+64); + try test_f32_floatFromInt_u128(0xFFFFFFFFFFFFFFFE, 0x1p+64); + try test_f32_floatFromInt_u128(0xFFFFFFFFFFFFFFFF, 0x1p+64); - try test__floatuntisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); - try test__floatuntisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); - try test__floatuntisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); - try test__floatuntisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); - try test__floatuntisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); - try test__floatuntisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBCp+50); + try test_f32_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBAp+50); - try test__floatuntisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); - try test__floatuntisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); - try test__floatuntisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); - try test__floatuntisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); - try test__floatuntisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); + try test_f32_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCBAp+50); + try test_f32_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB8p+50); - try test__floatuntisf(make_uti(0x0000000000001FED, 0xCB90000000000001), 0x1.FEDCBAp+76); - try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBA0000000000000), 0x1.FEDCBAp+76); - try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBAFFFFFFFFFFFFF), 0x1.FEDCBAp+76); - try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBB0000000000000), 0x1.FEDCBCp+76); - try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBB0000000000001), 0x1.FEDCBCp+76); - try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBBFFFFFFFFFFFFF), 0x1.FEDCBCp+76); - try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBC0000000000000), 0x1.FEDCBCp+76); - try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBC0000000000001), 0x1.FEDCBCp+76); - try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBD0000000000000), 0x1.FEDCBCp+76); - try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBD0000000000001), 0x1.FEDCBEp+76); - try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBDFFFFFFFFFFFFF), 0x1.FEDCBEp+76); - try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76); + try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCB90000000000001), 0x1.FEDCBAp+76); + try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBA0000000000000), 0x1.FEDCBAp+76); + try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBAFFFFFFFFFFFFF), 0x1.FEDCBAp+76); + try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBB0000000000000), 0x1.FEDCBCp+76); + try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBB0000000000001), 0x1.FEDCBCp+76); + try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBBFFFFFFFFFFFFF), 0x1.FEDCBCp+76); + try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBC0000000000000), 0x1.FEDCBCp+76); + try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBC0000000000001), 0x1.FEDCBCp+76); + try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBD0000000000000), 0x1.FEDCBCp+76); + try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBD0000000000001), 0x1.FEDCBEp+76); + try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBDFFFFFFFFFFFFF), 0x1.FEDCBEp+76); + try test_f32_floatFromInt_u128(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76); // Test overflow to infinity - try test__floatuntisf(math.maxInt(u128), @bitCast(math.inf(f32))); + try test_f32_floatFromInt_u128(math.maxInt(u128), @bitCast(math.inf(f32))); } -fn test_floateisf(expected: u32, comptime T: type, a: T) !void { +fn test_f32_floatFromInt(expected: u32, comptime T: type, a: T) !void { const int = @typeInfo(T).int; const r = switch (int.signedness) { - .signed => __floateisf, - .unsigned => __floatuneisf, - }(@ptrCast(&a), int.bits); + .signed => f32_floatFromInt_signed, + .unsigned => f32_floatFromInt_unsigned, + }(@ptrCast(&a)); try testing.expect(expected == @as(u32, @bitCast(r))); } -test "floateisf" { - try test_floateisf(0xFF000000, i256, -1 << 127); - try test_floateisf(0xFF000000, i256, -math.maxInt(u127)); - try test_floateisf(0xDF012347, i256, -0x8123468100000000); - try test_floateisf(0xDF012347, i256, -0x8123468000000001); - try test_floateisf(0xDF012346, i256, -0x8123468000000000); - try test_floateisf(0xDF012346, i256, -0x8123458100000000); - try test_floateisf(0xDF012346, i256, -0x8123458000000001); - try test_floateisf(0xDF012346, i256, -0x8123458000000000); - try test_floateisf(0xDF012345, i256, -0x8123456789ABCDEF); - try test_floateisf(0xBF800000, i256, -1); - try test_floateisf(0x00000000, i256, 0); - try test_floateisf(0x5F012345, i256, 0x8123456789ABCDEF); - try test_floateisf(0x5F012346, i256, 0x8123458000000000); - try test_floateisf(0x5F012346, i256, 0x8123458000000001); - try test_floateisf(0x5F012346, i256, 0x8123458100000000); - try test_floateisf(0x5F012346, i256, 0x8123468000000000); - try test_floateisf(0x5F012347, i256, 0x8123468000000001); - try test_floateisf(0x5F012347, i256, 0x8123468100000000); - try test_floateisf(0x7F000000, i256, math.maxInt(u127)); - try test_floateisf(0x7F000000, i256, 1 << 127); +test f32_floatFromInt_signed { + try test_f32_floatFromInt(0xFF000000, i256, -1 << 127); + try test_f32_floatFromInt(0xFF000000, i256, -math.maxInt(u127)); + try test_f32_floatFromInt(0xDF012347, i256, -0x8123468100000000); + try test_f32_floatFromInt(0xDF012347, i256, -0x8123468000000001); + try test_f32_floatFromInt(0xDF012346, i256, -0x8123468000000000); + try test_f32_floatFromInt(0xDF012346, i256, -0x8123458100000000); + try test_f32_floatFromInt(0xDF012346, i256, -0x8123458000000001); + try test_f32_floatFromInt(0xDF012346, i256, -0x8123458000000000); + try test_f32_floatFromInt(0xDF012345, i256, -0x8123456789ABCDEF); + try test_f32_floatFromInt(0xBF800000, i256, -1); + try test_f32_floatFromInt(0x00000000, i256, 0); + try test_f32_floatFromInt(0x5F012345, i256, 0x8123456789ABCDEF); + try test_f32_floatFromInt(0x5F012346, i256, 0x8123458000000000); + try test_f32_floatFromInt(0x5F012346, i256, 0x8123458000000001); + try test_f32_floatFromInt(0x5F012346, i256, 0x8123458100000000); + try test_f32_floatFromInt(0x5F012346, i256, 0x8123468000000000); + try test_f32_floatFromInt(0x5F012347, i256, 0x8123468000000001); + try test_f32_floatFromInt(0x5F012347, i256, 0x8123468100000000); + try test_f32_floatFromInt(0x7F000000, i256, math.maxInt(u127)); + try test_f32_floatFromInt(0x7F000000, i256, 1 << 127); } -test "floatuneisf" { - try test_floateisf(0x00000000, u256, 0); - try test_floateisf(0x5F012345, u256, 0x8123456789ABCDEF); - try test_floateisf(0x5F012346, u256, 0x8123458000000000); - try test_floateisf(0x5F012346, u256, 0x8123458000000001); - try test_floateisf(0x5F012346, u256, 0x8123458080000000); - try test_floateisf(0x5F012346, u256, 0x8123468000000000); - try test_floateisf(0x5F012347, u256, 0x8123468000000001); - try test_floateisf(0x5F012347, u256, 0x8123468080000000); - try test_floateisf(0x7F000000, u256, math.maxInt(u127)); - try test_floateisf(0x7F000000, u256, 1 << 127); - try test_floateisf(0x7F800000, u256, math.maxInt(u256)); +test f32_floatFromInt_unsigned { + try test_f32_floatFromInt(0x00000000, u256, 0); + try test_f32_floatFromInt(0x5F012345, u256, 0x8123456789ABCDEF); + try test_f32_floatFromInt(0x5F012346, u256, 0x8123458000000000); + try test_f32_floatFromInt(0x5F012346, u256, 0x8123458000000001); + try test_f32_floatFromInt(0x5F012346, u256, 0x8123458080000000); + try test_f32_floatFromInt(0x5F012346, u256, 0x8123468000000000); + try test_f32_floatFromInt(0x5F012347, u256, 0x8123468000000001); + try test_f32_floatFromInt(0x5F012347, u256, 0x8123468080000000); + try test_f32_floatFromInt(0x7F000000, u256, math.maxInt(u127)); + try test_f32_floatFromInt(0x7F000000, u256, 1 << 127); + try test_f32_floatFromInt(0x7F800000, u256, math.maxInt(u256)); } -fn test_one_floatsidf(a: i32, expected: u64) !void { - const r = __floatsidf(a); +fn test_f64_floatFromInt_i32(a: i32, expected: u64) !void { + const r = f64_floatFromInt_i32(a); try std.testing.expect(@as(u64, @bitCast(r)) == expected); } -fn test_one_floatunsidf(a: u32, expected: u64) !void { - const r = __floatunsidf(a); +fn test_f64_floatFromInt_u32(a: u32, expected: u64) !void { + const r = f64_floatFromInt_u32(a); try std.testing.expect(@as(u64, @bitCast(r)) == expected); } -test "floatsidf" { - try test_one_floatsidf(0, 0x0000000000000000); - try test_one_floatsidf(1, 0x3ff0000000000000); - try test_one_floatsidf(-1, 0xbff0000000000000); - try test_one_floatsidf(0x7FFFFFFF, 0x41dfffffffc00000); - try test_one_floatsidf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000); +test f64_floatFromInt_i32 { + try test_f64_floatFromInt_i32(0, 0x0000000000000000); + try test_f64_floatFromInt_i32(1, 0x3ff0000000000000); + try test_f64_floatFromInt_i32(-1, 0xbff0000000000000); + try test_f64_floatFromInt_i32(0x7FFFFFFF, 0x41dfffffffc00000); + try test_f64_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xc1e0000000000000); } -test "floatunsidf" { - try test_one_floatunsidf(0, 0x0000000000000000); - try test_one_floatunsidf(1, 0x3ff0000000000000); - try test_one_floatunsidf(0x7FFFFFFF, 0x41dfffffffc00000); - try test_one_floatunsidf(@intCast(0x80000000), 0x41e0000000000000); - try test_one_floatunsidf(@intCast(0xFFFFFFFF), 0x41efffffffe00000); +test f64_floatFromInt_u32 { + try test_f64_floatFromInt_u32(0, 0x0000000000000000); + try test_f64_floatFromInt_u32(1, 0x3ff0000000000000); + try test_f64_floatFromInt_u32(0x7FFFFFFF, 0x41dfffffffc00000); + try test_f64_floatFromInt_u32(@intCast(0x80000000), 0x41e0000000000000); + try test_f64_floatFromInt_u32(@intCast(0xFFFFFFFF), 0x41efffffffe00000); } -fn test__floatdidf(a: i64, expected: f64) !void { - const r = __floatdidf(a); +fn test_f64_floatFromInt_i64(a: i64, expected: f64) !void { + const r = f64_floatFromInt_i64(a); try testing.expect(r == expected); } -fn test__floatundidf(a: u64, expected: f64) !void { - const r = __floatundidf(a); +fn test_f64_floatFromInt_u64(a: u64, expected: f64) !void { + const r = f64_floatFromInt_u64(a); try testing.expect(r == expected); } -test "floatdidf" { - try test__floatdidf(0, 0.0); - try test__floatdidf(1, 1.0); - try test__floatdidf(2, 2.0); - try test__floatdidf(20, 20.0); - try test__floatdidf(-1, -1.0); - try test__floatdidf(-2, -2.0); - try test__floatdidf(-20, -20.0); - try test__floatdidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); - try test__floatdidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); - try test__floatdidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); - try test__floatdidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); - try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62); - try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62); - try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62); - try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62); - try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63); - try test__floatdidf(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001 - try test__floatdidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); - try test__floatdidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); - try test__floatdidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); - try test__floatdidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); - try test__floatdidf(0x0007FB72EC000000, 0x1.FEDCBBp+50); - try test__floatdidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); - try test__floatdidf(0x0007FB72E6000000, 0x1.FEDCB98p+50); - try test__floatdidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); - try test__floatdidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); - try test__floatdidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); - try test__floatdidf(0x0007FB72E4000000, 0x1.FEDCB9p+50); - try test__floatdidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); - try test__floatdidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); - try test__floatdidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); - try test__floatdidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); - try test__floatdidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); - try test__floatdidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); - try test__floatdidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); - try test__floatdidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); - try test__floatdidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); - try test__floatdidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); - try test__floatdidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); - try test__floatdidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); - try test__floatdidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); - try test__floatdidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); - try test__floatdidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); +test f64_floatFromInt_i64 { + try test_f64_floatFromInt_i64(0, 0.0); + try test_f64_floatFromInt_i64(1, 1.0); + try test_f64_floatFromInt_i64(2, 2.0); + try test_f64_floatFromInt_i64(20, 20.0); + try test_f64_floatFromInt_i64(-1, -1.0); + try test_f64_floatFromInt_i64(-2, -2.0); + try test_f64_floatFromInt_i64(-20, -20.0); + try test_f64_floatFromInt_i64(0x7FFFFF8000000000, 0x1.FFFFFEp+62); + try test_f64_floatFromInt_i64(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); + try test_f64_floatFromInt_i64(0x7FFFFF0000000000, 0x1.FFFFFCp+62); + try test_f64_floatFromInt_i64(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); + try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000008000000000))), -0x1.FFFFFEp+62); + try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000800))), -0x1.FFFFFFFFFFFFEp+62); + try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000010000000000))), -0x1.FFFFFCp+62); + try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000001000))), -0x1.FFFFFFFFFFFFCp+62); + try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000000))), -0x1.000000p+63); + try test_f64_floatFromInt_i64(@bitCast(@as(u64, @intCast(0x8000000000000001))), -0x1.000000p+63); // 0x8000000000000001 + try test_f64_floatFromInt_i64(0x0007FB72E8000000, 0x1.FEDCBAp+50); + try test_f64_floatFromInt_i64(0x0007FB72EA000000, 0x1.FEDCBA8p+50); + try test_f64_floatFromInt_i64(0x0007FB72EB000000, 0x1.FEDCBACp+50); + try test_f64_floatFromInt_i64(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); + try test_f64_floatFromInt_i64(0x0007FB72EC000000, 0x1.FEDCBBp+50); + try test_f64_floatFromInt_i64(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); + try test_f64_floatFromInt_i64(0x0007FB72E6000000, 0x1.FEDCB98p+50); + try test_f64_floatFromInt_i64(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); + try test_f64_floatFromInt_i64(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); + try test_f64_floatFromInt_i64(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); + try test_f64_floatFromInt_i64(0x0007FB72E4000000, 0x1.FEDCB9p+50); + try test_f64_floatFromInt_i64(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); + try test_f64_floatFromInt_i64(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); } -test "floatundidf" { - try test__floatundidf(0, 0.0); - try test__floatundidf(1, 1.0); - try test__floatundidf(2, 2.0); - try test__floatundidf(20, 20.0); - try test__floatundidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); - try test__floatundidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); - try test__floatundidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); - try test__floatundidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); - try test__floatundidf(0x8000008000000000, 0x1.000001p+63); - try test__floatundidf(0x8000000000000800, 0x1.0000000000001p+63); - try test__floatundidf(0x8000010000000000, 0x1.000002p+63); - try test__floatundidf(0x8000000000001000, 0x1.0000000000002p+63); - try test__floatundidf(0x8000000000000000, 0x1p+63); - try test__floatundidf(0x8000000000000001, 0x1p+63); - try test__floatundidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); - try test__floatundidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); - try test__floatundidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); - try test__floatundidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); - try test__floatundidf(0x0007FB72EC000000, 0x1.FEDCBBp+50); - try test__floatundidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); - try test__floatundidf(0x0007FB72E6000000, 0x1.FEDCB98p+50); - try test__floatundidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); - try test__floatundidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); - try test__floatundidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); - try test__floatundidf(0x0007FB72E4000000, 0x1.FEDCB9p+50); - try test__floatundidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); - try test__floatundidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); - try test__floatundidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); - try test__floatundidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); - try test__floatundidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); - try test__floatundidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); - try test__floatundidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); - try test__floatundidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); - try test__floatundidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); - try test__floatundidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); - try test__floatundidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); - try test__floatundidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); - try test__floatundidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); - try test__floatundidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); - try test__floatundidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); +test f64_floatFromInt_u64 { + try test_f64_floatFromInt_u64(0, 0.0); + try test_f64_floatFromInt_u64(1, 1.0); + try test_f64_floatFromInt_u64(2, 2.0); + try test_f64_floatFromInt_u64(20, 20.0); + try test_f64_floatFromInt_u64(0x7FFFFF8000000000, 0x1.FFFFFEp+62); + try test_f64_floatFromInt_u64(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); + try test_f64_floatFromInt_u64(0x7FFFFF0000000000, 0x1.FFFFFCp+62); + try test_f64_floatFromInt_u64(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); + try test_f64_floatFromInt_u64(0x8000008000000000, 0x1.000001p+63); + try test_f64_floatFromInt_u64(0x8000000000000800, 0x1.0000000000001p+63); + try test_f64_floatFromInt_u64(0x8000010000000000, 0x1.000002p+63); + try test_f64_floatFromInt_u64(0x8000000000001000, 0x1.0000000000002p+63); + try test_f64_floatFromInt_u64(0x8000000000000000, 0x1p+63); + try test_f64_floatFromInt_u64(0x8000000000000001, 0x1p+63); + try test_f64_floatFromInt_u64(0x0007FB72E8000000, 0x1.FEDCBAp+50); + try test_f64_floatFromInt_u64(0x0007FB72EA000000, 0x1.FEDCBA8p+50); + try test_f64_floatFromInt_u64(0x0007FB72EB000000, 0x1.FEDCBACp+50); + try test_f64_floatFromInt_u64(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); + try test_f64_floatFromInt_u64(0x0007FB72EC000000, 0x1.FEDCBBp+50); + try test_f64_floatFromInt_u64(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); + try test_f64_floatFromInt_u64(0x0007FB72E6000000, 0x1.FEDCB98p+50); + try test_f64_floatFromInt_u64(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); + try test_f64_floatFromInt_u64(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); + try test_f64_floatFromInt_u64(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); + try test_f64_floatFromInt_u64(0x0007FB72E4000000, 0x1.FEDCB9p+50); + try test_f64_floatFromInt_u64(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); + try test_f64_floatFromInt_u64(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); } -fn test__floattidf(a: i128, expected: f64) !void { - const x = __floattidf(a); +fn test_f64_floatFromInt_i128(a: i128, expected: f64) !void { + const x = f64_floatFromInt_i128(a); try testing.expect(x == expected); } -fn test__floatuntidf(a: u128, expected: f64) !void { - const x = __floatuntidf(a); +fn test_f64_floatFromInt_u128(a: u128, expected: f64) !void { + const x = f64_floatFromInt_u128(a); try testing.expect(x == expected); } -test "floattidf" { - try test__floattidf(0, 0.0); - - try test__floattidf(1, 1.0); - try test__floattidf(2, 2.0); - try test__floattidf(20, 20.0); - try test__floattidf(-1, -1.0); - try test__floattidf(-2, -2.0); - try test__floattidf(-20, -20.0); - - try test__floattidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); - try test__floattidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); - try test__floattidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); - try test__floattidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); - - try test__floattidf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126); - try test__floattidf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126); - try test__floattidf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126); - try test__floattidf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126); - - try test__floattidf(make_ti(0x8000000000000000, 0), -0x1.000000p+127); - try test__floattidf(make_ti(0x8000000000000001, 0), -0x1.000000p+127); - - try test__floattidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); - - try test__floattidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); - try test__floattidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); - try test__floattidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); - try test__floattidf(0x0007FB72EC000000, 0x1.FEDCBBp+50); - try test__floattidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); - - try test__floattidf(0x0007FB72E6000000, 0x1.FEDCB98p+50); - try test__floattidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); - try test__floattidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); - try test__floattidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); - try test__floattidf(0x0007FB72E4000000, 0x1.FEDCB9p+50); - - try test__floattidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); - try test__floattidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); - try test__floattidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); - try test__floattidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); - try test__floattidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); - try test__floattidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); - try test__floattidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); - try test__floattidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); - try test__floattidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); - try test__floattidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); - try test__floattidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); - try test__floattidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); - try test__floattidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); - try test__floattidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); - try test__floattidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); - - try test__floattidf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); - try test__floattidf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121); - try test__floattidf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121); - try test__floattidf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121); - try test__floattidf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121); - try test__floattidf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121); - try test__floattidf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121); - try test__floattidf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121); - try test__floattidf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121); - try test__floattidf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121); - try test__floattidf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121); - try test__floattidf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121); - try test__floattidf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121); - try test__floattidf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121); - try test__floattidf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); +test f64_floatFromInt_i128 { + try test_f64_floatFromInt_i128(0, 0.0); + + try test_f64_floatFromInt_i128(1, 1.0); + try test_f64_floatFromInt_i128(2, 2.0); + try test_f64_floatFromInt_i128(20, 20.0); + try test_f64_floatFromInt_i128(-1, -1.0); + try test_f64_floatFromInt_i128(-2, -2.0); + try test_f64_floatFromInt_i128(-20, -20.0); + + try test_f64_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); + try test_f64_floatFromInt_i128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); + try test_f64_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); + try test_f64_floatFromInt_i128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); + + try test_f64_floatFromInt_i128(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126); + try test_f64_floatFromInt_i128(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126); + try test_f64_floatFromInt_i128(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126); + try test_f64_floatFromInt_i128(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126); + + try test_f64_floatFromInt_i128(make_ti(0x8000000000000000, 0), -0x1.000000p+127); + try test_f64_floatFromInt_i128(make_ti(0x8000000000000001, 0), -0x1.000000p+127); + + try test_f64_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50); + + try test_f64_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); + try test_f64_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBACp+50); + try test_f64_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); + try test_f64_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBBp+50); + try test_f64_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); + + try test_f64_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCB98p+50); + try test_f64_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); + try test_f64_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); + try test_f64_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); + try test_f64_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB9p+50); + + try test_f64_floatFromInt_i128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); + try test_f64_floatFromInt_i128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); + + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121); + try test_f64_floatFromInt_i128(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); } -test "floatuntidf" { - try test__floatuntidf(0, 0.0); - - try test__floatuntidf(1, 1.0); - try test__floatuntidf(2, 2.0); - try test__floatuntidf(20, 20.0); - - try test__floatuntidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); - try test__floatuntidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); - try test__floatuntidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); - try test__floatuntidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); - - try test__floatuntidf(make_uti(0x8000008000000000, 0), 0x1.000001p+127); - try test__floatuntidf(make_uti(0x8000000000000800, 0), 0x1.0000000000001p+127); - try test__floatuntidf(make_uti(0x8000010000000000, 0), 0x1.000002p+127); - try test__floatuntidf(make_uti(0x8000000000001000, 0), 0x1.0000000000002p+127); - - try test__floatuntidf(make_uti(0x8000000000000000, 0), 0x1.000000p+127); - try test__floatuntidf(make_uti(0x8000000000000001, 0), 0x1.0000000000000002p+127); - - try test__floatuntidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); - - try test__floatuntidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); - try test__floatuntidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); - try test__floatuntidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); - try test__floatuntidf(0x0007FB72EC000000, 0x1.FEDCBBp+50); - try test__floatuntidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); - - try test__floatuntidf(0x0007FB72E6000000, 0x1.FEDCB98p+50); - try test__floatuntidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); - try test__floatuntidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); - try test__floatuntidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); - try test__floatuntidf(0x0007FB72E4000000, 0x1.FEDCB9p+50); - - try test__floatuntidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); - try test__floatuntidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); - try test__floatuntidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); - try test__floatuntidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); - try test__floatuntidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); - try test__floatuntidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); - try test__floatuntidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); - try test__floatuntidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); - try test__floatuntidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); - try test__floatuntidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); - try test__floatuntidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); - try test__floatuntidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); - try test__floatuntidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); - try test__floatuntidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); - try test__floatuntidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); - - try test__floatuntidf(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); - try test__floatuntidf(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121); - try test__floatuntidf(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121); - try test__floatuntidf(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121); - try test__floatuntidf(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121); - try test__floatuntidf(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121); - try test__floatuntidf(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121); - try test__floatuntidf(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121); - try test__floatuntidf(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121); - try test__floatuntidf(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121); - try test__floatuntidf(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121); - try test__floatuntidf(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121); - try test__floatuntidf(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121); - try test__floatuntidf(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121); - try test__floatuntidf(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); +test f64_floatFromInt_u128 { + try test_f64_floatFromInt_u128(0, 0.0); + + try test_f64_floatFromInt_u128(1, 1.0); + try test_f64_floatFromInt_u128(2, 2.0); + try test_f64_floatFromInt_u128(20, 20.0); + + try test_f64_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); + try test_f64_floatFromInt_u128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); + try test_f64_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); + try test_f64_floatFromInt_u128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); + + try test_f64_floatFromInt_u128(make_uti(0x8000008000000000, 0), 0x1.000001p+127); + try test_f64_floatFromInt_u128(make_uti(0x8000000000000800, 0), 0x1.0000000000001p+127); + try test_f64_floatFromInt_u128(make_uti(0x8000010000000000, 0), 0x1.000002p+127); + try test_f64_floatFromInt_u128(make_uti(0x8000000000001000, 0), 0x1.0000000000002p+127); + + try test_f64_floatFromInt_u128(make_uti(0x8000000000000000, 0), 0x1.000000p+127); + try test_f64_floatFromInt_u128(make_uti(0x8000000000000001, 0), 0x1.0000000000000002p+127); + + try test_f64_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); + + try test_f64_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); + try test_f64_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50); + try test_f64_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); + try test_f64_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50); + try test_f64_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); + + try test_f64_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50); + try test_f64_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); + try test_f64_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); + try test_f64_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); + try test_f64_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50); + + try test_f64_floatFromInt_u128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57); + try test_f64_floatFromInt_u128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); + + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496Dp+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496Ep+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496Fp+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496Fp+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496Fp+121); + try test_f64_floatFromInt_u128(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); } -fn test__floatsitf(a: i32, expected: u128) !void { - const r = __floatsitf(a); +fn test_f128_floatFromInt_i32(a: i32, expected: u128) !void { + const r = f128_floatFromInt_i32(a); try std.testing.expect(@as(u128, @bitCast(r)) == expected); } -test "floatsitf" { - try test__floatsitf(0, 0); - try test__floatsitf(0x7FFFFFFF, 0x401dfffffffc00000000000000000000); - try test__floatsitf(0x12345678, 0x401b2345678000000000000000000000); - try test__floatsitf(-0x12345678, 0xc01b2345678000000000000000000000); - try test__floatsitf(@bitCast(@as(u32, @intCast(0xffffffff))), 0xbfff0000000000000000000000000000); - try test__floatsitf(@bitCast(@as(u32, @intCast(0x80000000))), 0xc01e0000000000000000000000000000); -} - -fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void { - const x = __floatunsitf(a); +fn test_f128_floatFromInt_u32(a: u32, expected_hi: u64, expected_lo: u64) !void { + const x = f128_floatFromInt_u32(a); const x_repr: u128 = @bitCast(x); const x_hi: u64 = @intCast(x_repr >> 64); @@ -581,24 +603,32 @@ fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void { return; } } + return error.TestFailure; +} - @panic("__floatunsitf test failure"); +test f128_floatFromInt_i32 { + try test_f128_floatFromInt_i32(0, 0); + try test_f128_floatFromInt_i32(0x7FFFFFFF, 0x401dfffffffc00000000000000000000); + try test_f128_floatFromInt_i32(0x12345678, 0x401b2345678000000000000000000000); + try test_f128_floatFromInt_i32(-0x12345678, 0xc01b2345678000000000000000000000); + try test_f128_floatFromInt_i32(@bitCast(@as(u32, @intCast(0xffffffff))), 0xbfff0000000000000000000000000000); + try test_f128_floatFromInt_i32(@bitCast(@as(u32, @intCast(0x80000000))), 0xc01e0000000000000000000000000000); } -test "floatunsitf" { - try test__floatunsitf(0x7fffffff, 0x401dfffffffc0000, 0x0); - try test__floatunsitf(0, 0x0, 0x0); - try test__floatunsitf(0xffffffff, 0x401efffffffe0000, 0x0); - try test__floatunsitf(0x12345678, 0x401b234567800000, 0x0); +test f128_floatFromInt_u32 { + try test_f128_floatFromInt_u32(0x7fffffff, 0x401dfffffffc0000, 0x0); + try test_f128_floatFromInt_u32(0, 0x0, 0x0); + try test_f128_floatFromInt_u32(0xffffffff, 0x401efffffffe0000, 0x0); + try test_f128_floatFromInt_u32(0x12345678, 0x401b234567800000, 0x0); } -fn test__floatditf(a: i64, expected: f128) !void { - const x = __floatditf(a); +fn test_f128_floatFromInt_i64(a: i64, expected: f128) !void { + const x = f128_floatFromInt_i64(a); try testing.expect(x == expected); } -fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void { - const x = __floatunditf(a); +fn test_f128_floatFromInt_u64(a: u64, expected_hi: u64, expected_lo: u64) !void { + const x = f128_floatFromInt_u64(a); const x_repr: u128 = @bitCast(x); const x_hi: u64 = @intCast(x_repr >> 64); @@ -613,208 +643,207 @@ fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void { return; } } - - @panic("__floatunditf test failure"); + return error.TestFailure; } -test "floatditf" { - try test__floatditf(0x7fffffffffffffff, make_tf(0x403dffffffffffff, 0xfffc000000000000)); - try test__floatditf(0x123456789abcdef1, make_tf(0x403b23456789abcd, 0xef10000000000000)); - try test__floatditf(0x2, make_tf(0x4000000000000000, 0x0)); - try test__floatditf(0x1, make_tf(0x3fff000000000000, 0x0)); - try test__floatditf(0x0, make_tf(0x0, 0x0)); - try test__floatditf(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0)); - try test__floatditf(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0)); - try test__floatditf(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000)); - try test__floatditf(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0)); +test f128_floatFromInt_i64 { + try test_f128_floatFromInt_i64(0x7fffffffffffffff, make_tf(0x403dffffffffffff, 0xfffc000000000000)); + try test_f128_floatFromInt_i64(0x123456789abcdef1, make_tf(0x403b23456789abcd, 0xef10000000000000)); + try test_f128_floatFromInt_i64(0x2, make_tf(0x4000000000000000, 0x0)); + try test_f128_floatFromInt_i64(0x1, make_tf(0x3fff000000000000, 0x0)); + try test_f128_floatFromInt_i64(0x0, make_tf(0x0, 0x0)); + try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0)); + try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0)); + try test_f128_floatFromInt_i64(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000)); + try test_f128_floatFromInt_i64(@bitCast(@as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0)); } -test "floatunditf" { - try test__floatunditf(0xffffffffffffffff, 0x403effffffffffff, 0xfffe000000000000); - try test__floatunditf(0xfffffffffffffffe, 0x403effffffffffff, 0xfffc000000000000); - try test__floatunditf(0x8000000000000000, 0x403e000000000000, 0x0); - try test__floatunditf(0x7fffffffffffffff, 0x403dffffffffffff, 0xfffc000000000000); - try test__floatunditf(0x123456789abcdef1, 0x403b23456789abcd, 0xef10000000000000); - try test__floatunditf(0x2, 0x4000000000000000, 0x0); - try test__floatunditf(0x1, 0x3fff000000000000, 0x0); - try test__floatunditf(0x0, 0x0, 0x0); +test f128_floatFromInt_u64 { + try test_f128_floatFromInt_u64(0xffffffffffffffff, 0x403effffffffffff, 0xfffe000000000000); + try test_f128_floatFromInt_u64(0xfffffffffffffffe, 0x403effffffffffff, 0xfffc000000000000); + try test_f128_floatFromInt_u64(0x8000000000000000, 0x403e000000000000, 0x0); + try test_f128_floatFromInt_u64(0x7fffffffffffffff, 0x403dffffffffffff, 0xfffc000000000000); + try test_f128_floatFromInt_u64(0x123456789abcdef1, 0x403b23456789abcd, 0xef10000000000000); + try test_f128_floatFromInt_u64(0x2, 0x4000000000000000, 0x0); + try test_f128_floatFromInt_u64(0x1, 0x3fff000000000000, 0x0); + try test_f128_floatFromInt_u64(0x0, 0x0, 0x0); } -fn test__floattitf(a: i128, expected: f128) !void { - const x = __floattitf(a); +fn test_f128_floatFromInt_i128(a: i128, expected: f128) !void { + const x = f128_floatFromInt_i128(a); try testing.expect(x == expected); } -fn test__floatuntitf(a: u128, expected: f128) !void { - const x = __floatuntitf(a); +fn test_f128_floatFromInt_u128(a: u128, expected: f128) !void { + const x = f128_floatFromInt_u128(a); try testing.expect(x == expected); } -test "floattitf" { - try test__floattitf(0, 0.0); - - try test__floattitf(1, 1.0); - try test__floattitf(2, 2.0); - try test__floattitf(20, 20.0); - try test__floattitf(-1, -1.0); - try test__floattitf(-2, -2.0); - try test__floattitf(-20, -20.0); - - try test__floattitf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); - try test__floattitf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); - try test__floattitf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); - try test__floattitf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); - - try test__floattitf(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126); - try test__floattitf(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126); - try test__floattitf(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126); - try test__floattitf(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126); - - try test__floattitf(make_ti(0x8000000000000000, 0), -0x1.000000p+127); - try test__floattitf(make_ti(0x8000000000000001, 0), -0x1.FFFFFFFFFFFFFFFCp+126); - - try test__floattitf(0x0007FB72E8000000, 0x1.FEDCBAp+50); - - try test__floattitf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); - try test__floattitf(0x0007FB72EB000000, 0x1.FEDCBACp+50); - try test__floattitf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); - try test__floattitf(0x0007FB72EC000000, 0x1.FEDCBBp+50); - try test__floattitf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); - - try test__floattitf(0x0007FB72E6000000, 0x1.FEDCB98p+50); - try test__floattitf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); - try test__floattitf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); - try test__floattitf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); - try test__floattitf(0x0007FB72E4000000, 0x1.FEDCB9p+50); - - try test__floattitf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); - try test__floattitf(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57); - try test__floattitf(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57); - try test__floattitf(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57); - try test__floattitf(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57); - try test__floattitf(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57); - try test__floattitf(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57); - try test__floattitf(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57); - try test__floattitf(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57); - try test__floattitf(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57); - try test__floattitf(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57); - try test__floattitf(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57); - try test__floattitf(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57); - try test__floattitf(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57); - try test__floattitf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); - - try test__floattitf(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); - try test__floattitf(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121); - try test__floattitf(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121); - try test__floattitf(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121); - try test__floattitf(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121); - try test__floattitf(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121); - try test__floattitf(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121); - try test__floattitf(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121); - try test__floattitf(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121); - try test__floattitf(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121); - try test__floattitf(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121); - try test__floattitf(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121); - try test__floattitf(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121); - try test__floattitf(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121); - try test__floattitf(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); - - try test__floattitf(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); - - try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124); - try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124); - try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124); - try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124); - try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124); - try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124); - try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124); - try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124); - try test__floattitf(make_ti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124); +test f128_floatFromInt_i128 { + try test_f128_floatFromInt_i128(0, 0.0); + + try test_f128_floatFromInt_i128(1, 1.0); + try test_f128_floatFromInt_i128(2, 2.0); + try test_f128_floatFromInt_i128(20, 20.0); + try test_f128_floatFromInt_i128(-1, -1.0); + try test_f128_floatFromInt_i128(-2, -2.0); + try test_f128_floatFromInt_i128(-20, -20.0); + + try test_f128_floatFromInt_i128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); + try test_f128_floatFromInt_i128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); + try test_f128_floatFromInt_i128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); + try test_f128_floatFromInt_i128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); + + try test_f128_floatFromInt_i128(make_ti(0x8000008000000000, 0), -0x1.FFFFFEp+126); + try test_f128_floatFromInt_i128(make_ti(0x8000000000000800, 0), -0x1.FFFFFFFFFFFFEp+126); + try test_f128_floatFromInt_i128(make_ti(0x8000010000000000, 0), -0x1.FFFFFCp+126); + try test_f128_floatFromInt_i128(make_ti(0x8000000000001000, 0), -0x1.FFFFFFFFFFFFCp+126); + + try test_f128_floatFromInt_i128(make_ti(0x8000000000000000, 0), -0x1.000000p+127); + try test_f128_floatFromInt_i128(make_ti(0x8000000000000001, 0), -0x1.FFFFFFFFFFFFFFFCp+126); + + try test_f128_floatFromInt_i128(0x0007FB72E8000000, 0x1.FEDCBAp+50); + + try test_f128_floatFromInt_i128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); + try test_f128_floatFromInt_i128(0x0007FB72EB000000, 0x1.FEDCBACp+50); + try test_f128_floatFromInt_i128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); + try test_f128_floatFromInt_i128(0x0007FB72EC000000, 0x1.FEDCBBp+50); + try test_f128_floatFromInt_i128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); + + try test_f128_floatFromInt_i128(0x0007FB72E6000000, 0x1.FEDCB98p+50); + try test_f128_floatFromInt_i128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); + try test_f128_floatFromInt_i128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); + try test_f128_floatFromInt_i128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); + try test_f128_floatFromInt_i128(0x0007FB72E4000000, 0x1.FEDCB9p+50); + + try test_f128_floatFromInt_i128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57); + try test_f128_floatFromInt_i128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); + + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121); + try test_f128_floatFromInt_i128(make_ti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); + + try test_f128_floatFromInt_i128(make_ti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); + + try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124); + try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124); + try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124); + try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124); + try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124); + try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124); + try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124); + try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124); + try test_f128_floatFromInt_i128(make_ti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124); } -test "floatuntitf" { - try test__floatuntitf(0, 0.0); - - try test__floatuntitf(1, 1.0); - try test__floatuntitf(2, 2.0); - try test__floatuntitf(20, 20.0); - - try test__floatuntitf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); - try test__floatuntitf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); - try test__floatuntitf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); - try test__floatuntitf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); - try test__floatuntitf(0x7FFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFEp+59); - try test__floatuntitf(0xFFFFFFFFFFFFFFFE, 0xF.FFFFFFFFFFFFFFEp+60); - try test__floatuntitf(0xFFFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFFp+60); - - try test__floatuntitf(0x8000008000000000, 0x8.000008p+60); - try test__floatuntitf(0x8000000000000800, 0x8.0000000000008p+60); - try test__floatuntitf(0x8000010000000000, 0x8.00001p+60); - try test__floatuntitf(0x8000000000001000, 0x8.000000000001p+60); - - try test__floatuntitf(0x8000000000000000, 0x8p+60); - try test__floatuntitf(0x8000000000000001, 0x8.000000000000001p+60); - - try test__floatuntitf(0x0007FB72E8000000, 0x1.FEDCBAp+50); - - try test__floatuntitf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); - try test__floatuntitf(0x0007FB72EB000000, 0x1.FEDCBACp+50); - try test__floatuntitf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); - try test__floatuntitf(0x0007FB72EC000000, 0x1.FEDCBBp+50); - try test__floatuntitf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); - - try test__floatuntitf(0x0007FB72E6000000, 0x1.FEDCB98p+50); - try test__floatuntitf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); - try test__floatuntitf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); - try test__floatuntitf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); - try test__floatuntitf(0x0007FB72E4000000, 0x1.FEDCB9p+50); - - try test__floatuntitf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); - try test__floatuntitf(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57); - try test__floatuntitf(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57); - try test__floatuntitf(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57); - try test__floatuntitf(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57); - try test__floatuntitf(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57); - try test__floatuntitf(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57); - try test__floatuntitf(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57); - try test__floatuntitf(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57); - try test__floatuntitf(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57); - try test__floatuntitf(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57); - try test__floatuntitf(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57); - try test__floatuntitf(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57); - try test__floatuntitf(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57); - try test__floatuntitf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); - - try test__floatuntitf(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); - try test__floatuntitf(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121); - try test__floatuntitf(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121); - try test__floatuntitf(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121); - try test__floatuntitf(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121); - try test__floatuntitf(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121); - try test__floatuntitf(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121); - try test__floatuntitf(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121); - try test__floatuntitf(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121); - try test__floatuntitf(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121); - try test__floatuntitf(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121); - try test__floatuntitf(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121); - try test__floatuntitf(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121); - try test__floatuntitf(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121); - try test__floatuntitf(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); - - try test__floatuntitf(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); - - try test__floatuntitf(make_uti(0xFFFFFFFFFFFFFFFF, 0x0000000000000000), 0x1.FFFFFFFFFFFFFFFEp+127); - try test__floatuntitf(make_uti(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x1.0000000000000000p+128); - - try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124); - try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124); - try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124); - try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124); - try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124); - try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124); - try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124); - try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124); - try test__floatuntitf(make_uti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124); +test f128_floatFromInt_u128 { + try test_f128_floatFromInt_u128(0, 0.0); + + try test_f128_floatFromInt_u128(1, 1.0); + try test_f128_floatFromInt_u128(2, 2.0); + try test_f128_floatFromInt_u128(20, 20.0); + + try test_f128_floatFromInt_u128(0x7FFFFF8000000000, 0x1.FFFFFEp+62); + try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); + try test_f128_floatFromInt_u128(0x7FFFFF0000000000, 0x1.FFFFFCp+62); + try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); + try test_f128_floatFromInt_u128(0x7FFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFEp+59); + try test_f128_floatFromInt_u128(0xFFFFFFFFFFFFFFFE, 0xF.FFFFFFFFFFFFFFEp+60); + try test_f128_floatFromInt_u128(0xFFFFFFFFFFFFFFFF, 0xF.FFFFFFFFFFFFFFFp+60); + + try test_f128_floatFromInt_u128(0x8000008000000000, 0x8.000008p+60); + try test_f128_floatFromInt_u128(0x8000000000000800, 0x8.0000000000008p+60); + try test_f128_floatFromInt_u128(0x8000010000000000, 0x8.00001p+60); + try test_f128_floatFromInt_u128(0x8000000000001000, 0x8.000000000001p+60); + + try test_f128_floatFromInt_u128(0x8000000000000000, 0x8p+60); + try test_f128_floatFromInt_u128(0x8000000000000001, 0x8.000000000000001p+60); + + try test_f128_floatFromInt_u128(0x0007FB72E8000000, 0x1.FEDCBAp+50); + + try test_f128_floatFromInt_u128(0x0007FB72EA000000, 0x1.FEDCBA8p+50); + try test_f128_floatFromInt_u128(0x0007FB72EB000000, 0x1.FEDCBACp+50); + try test_f128_floatFromInt_u128(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50); + try test_f128_floatFromInt_u128(0x0007FB72EC000000, 0x1.FEDCBBp+50); + try test_f128_floatFromInt_u128(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50); + + try test_f128_floatFromInt_u128(0x0007FB72E6000000, 0x1.FEDCB98p+50); + try test_f128_floatFromInt_u128(0x0007FB72E7000000, 0x1.FEDCB9Cp+50); + try test_f128_floatFromInt_u128(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50); + try test_f128_floatFromInt_u128(0x0007FB72E4000001, 0x1.FEDCB90000004p+50); + try test_f128_floatFromInt_u128(0x0007FB72E4000000, 0x1.FEDCB9p+50); + + try test_f128_floatFromInt_u128(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DA1, 0x1.1A3CFE870496D08p+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DB0, 0x1.1A3CFE870496D8p+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DB8, 0x1.1A3CFE870496DCp+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DB6, 0x1.1A3CFE870496DBp+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DBF, 0x1.1A3CFE870496DF8p+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DC1, 0x1.1A3CFE870496E08p+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DC7, 0x1.1A3CFE870496E38p+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DC8, 0x1.1A3CFE870496E4p+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DCF, 0x1.1A3CFE870496E78p+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DD0, 0x1.1A3CFE870496E8p+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DD1, 0x1.1A3CFE870496E88p+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DD8, 0x1.1A3CFE870496ECp+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DDF, 0x1.1A3CFE870496EF8p+57); + try test_f128_floatFromInt_u128(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57); + + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC0, 0), 0x1.1A3CFE870496Ep+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DA1, 1), 0x1.1A3CFE870496D08p+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB0, 2), 0x1.1A3CFE870496D8p+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB8, 3), 0x1.1A3CFE870496DCp+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DB6, 4), 0x1.1A3CFE870496DBp+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DBF, 5), 0x1.1A3CFE870496DF8p+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC1, 6), 0x1.1A3CFE870496E08p+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC7, 7), 0x1.1A3CFE870496E38p+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DC8, 8), 0x1.1A3CFE870496E4p+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DCF, 9), 0x1.1A3CFE870496E78p+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD0, 0), 0x1.1A3CFE870496E8p+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD1, 11), 0x1.1A3CFE870496E88p+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DD8, 12), 0x1.1A3CFE870496ECp+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DDF, 13), 0x1.1A3CFE870496EF8p+121); + try test_f128_floatFromInt_u128(make_uti(0x023479FD0E092DE0, 14), 0x1.1A3CFE870496Fp+121); + + try test_f128_floatFromInt_u128(make_uti(0, 0xFFFFFFFFFFFFFFFF), 0x1.FFFFFFFFFFFFFFFEp+63); + + try test_f128_floatFromInt_u128(make_uti(0xFFFFFFFFFFFFFFFF, 0x0000000000000000), 0x1.FFFFFFFFFFFFFFFEp+127); + try test_f128_floatFromInt_u128(make_uti(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0x1.0000000000000000p+128); + + try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC2801), 0x1.23456789ABCDEF0123456789ABC3p+124); + try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC3000), 0x1.23456789ABCDEF0123456789ABC3p+124); + try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC37FF), 0x1.23456789ABCDEF0123456789ABC3p+124); + try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC3800), 0x1.23456789ABCDEF0123456789ABC4p+124); + try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4000), 0x1.23456789ABCDEF0123456789ABC4p+124); + try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC47FF), 0x1.23456789ABCDEF0123456789ABC4p+124); + try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4800), 0x1.23456789ABCDEF0123456789ABC4p+124); + try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC4801), 0x1.23456789ABCDEF0123456789ABC5p+124); + try test_f128_floatFromInt_u128(make_uti(0x123456789ABCDEF0, 0x123456789ABC57FF), 0x1.23456789ABCDEF0123456789ABC5p+124); } fn make_ti(high: u64, low: u64) i128 { @@ -838,45 +867,40 @@ fn make_tf(high: u64, low: u64) f128 { return @bitCast(result); } -test "conversion to f16" { - try testing.expect(__floatunsihf(@as(u32, 0)) == 0.0); - try testing.expect(__floatunsihf(@as(u32, 1)) == 1.0); - try testing.expect(__floatunsihf(@as(u32, 65504)) == 65504); - try testing.expect(__floatunsihf(@as(u32, 65504 + (1 << 4))) == math.inf(f16)); +test f16_floatFromInt_u32 { + try testing.expect(f16_floatFromInt_u32(0) == 0.0); + try testing.expect(f16_floatFromInt_u32(1) == 1.0); + try testing.expect(f16_floatFromInt_u32(65504) == 65504); + try testing.expect(f16_floatFromInt_u32(65504 + (1 << 4)) == math.inf(f16)); } -test "conversion to f32" { - try testing.expect(__floatunsisf(@as(u32, 0)) == 0.0); - try testing.expect(__floatunsisf(@as(u32, math.maxInt(u32))) != 1.0); - try testing.expect(__floatsisf(@as(i32, math.minInt(i32))) != 1.0); - try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24))) == math.maxInt(u24)); - try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 1) == math.maxInt(u24) + 1); // 0x100_0000 - Exact - try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 2) == math.maxInt(u24) + 1); // 0x100_0001 - Tie: Rounds down to even - try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 3) == math.maxInt(u24) + 3); // 0x100_0002 - Exact - try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 4) == math.maxInt(u24) + 5); // 0x100_0003 - Tie: Rounds up to even - try testing.expect(__floatunsisf(@as(u32, math.maxInt(u24)) + 5) == math.maxInt(u24) + 5); // 0x100_0004 - Exact +test f80_floatFromInt_u32 { + try testing.expect(f80_floatFromInt_u32(0) == 0.0); + try testing.expect(f80_floatFromInt_u32(1) == 1.0); + try testing.expect(f80_floatFromInt_u32(math.maxInt(u24) + 0) == math.maxInt(u24)); } -test "conversion to f80" { - const floatFromInt = @import("./float_from_int.zig").floatFromInt; +test f80_floatFromInt_u64 { + try testing.expect(f80_floatFromInt_u64(math.maxInt(u64) + 0) == math.maxInt(u64) + 0); +} + +test f80_floatFromInt_i128 { + try testing.expect(f80_floatFromInt_i128(-12) == -12); +} - try testing.expect(floatFromInt(f80, @as(i80, -12)) == -12); - try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u64, math.maxInt(u64)) + 0))) == math.maxInt(u64) + 0); - try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1); +test f80_floatFromInt_u128 { + try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 1) == math.maxInt(u64) + 1); - try testing.expect(floatFromInt(f80, @as(u32, 0)) == 0.0); - try testing.expect(floatFromInt(f80, @as(u32, 1)) == 1.0); - try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u32, math.maxInt(u24)) + 0))) == math.maxInt(u24)); - try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 0))) == math.maxInt(u64)); - try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1); // Exact - try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 2))) == math.maxInt(u64) + 1); // Rounds down - try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 3))) == math.maxInt(u64) + 3); // Tie - Exact - try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 4))) == math.maxInt(u64) + 5); // Rounds up + try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 0) == math.maxInt(u64)); + try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 1) == math.maxInt(u64) + 1); // Exact + try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 2) == math.maxInt(u64) + 1); // Rounds down + try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 3) == math.maxInt(u64) + 3); // Tie - Exact + try testing.expect(f80_floatFromInt_u128(math.maxInt(u64) + 4) == math.maxInt(u64) + 5); // Rounds up - try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 0))) == math.maxInt(u65) + 1); // Rounds up - try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 1))) == math.maxInt(u65) + 1); // Exact - try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 2))) == math.maxInt(u65) + 1); // Rounds down - try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 3))) == math.maxInt(u65) + 1); // Tie - Rounds down - try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 4))) == math.maxInt(u65) + 5); // Rounds up - try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 5))) == math.maxInt(u65) + 5); // Exact + try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 0) == math.maxInt(u65) + 1); // Rounds up + try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 1) == math.maxInt(u65) + 1); // Exact + try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 2) == math.maxInt(u65) + 1); // Rounds down + try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 3) == math.maxInt(u65) + 1); // Tie - Rounds down + try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 4) == math.maxInt(u65) + 5); // Rounds up + try testing.expect(f80_floatFromInt_u128(math.maxInt(u65) + 5) == math.maxInt(u65) + 5); // Exact } diff --git a/lib/compiler_rt/floatdidf.zig b/lib/compiler_rt/floatdidf.zig deleted file mode 100644 index f8d5153d5b43896b3dd26a32e84f613151b84653..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatdidf.zig +++ /dev/null @@ -1,23 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_l2d, "__aeabi_l2d"); - } else { - if (compiler_rt.want_windows_arm_abi) { - symbol(&__floatdidf, "__i64tod"); - } - symbol(&__floatdidf, "__floatdidf"); - } -} - -pub fn __floatdidf(a: i64) callconv(.c) f64 { - return floatFromInt(f64, a); -} - -fn __aeabi_l2d(a: i64) callconv(.{ .arm_aapcs = .{} }) f64 { - return floatFromInt(f64, a); -} diff --git a/lib/compiler_rt/floatdihf.zig b/lib/compiler_rt/floatdihf.zig deleted file mode 100644 index c6865dff6b8025e49b8f1a0ffc36674c230247a4..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatdihf.zig +++ /dev/null @@ -1,10 +0,0 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floatdihf, "__floatdihf"); -} - -fn __floatdihf(a: i64) callconv(.c) f16 { - return floatFromInt(f16, a); -} diff --git a/lib/compiler_rt/floatdisf.zig b/lib/compiler_rt/floatdisf.zig deleted file mode 100644 index 3da1faba367a6a17b81f97c93db6ff2041765b84..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatdisf.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_l2f, "__aeabi_l2f"); - } else { - if (compiler_rt.want_windows_arm_abi) { - symbol(&__floatdisf, "__i64tos"); - } - symbol(&__floatdisf, "__floatdisf"); - } -} - -pub fn __floatdisf(a: i64) callconv(.c) f32 { - return floatFromInt(f32, a); -} - -fn __aeabi_l2f(a: i64) callconv(.{ .arm_aapcs = .{} }) f32 { - return floatFromInt(f32, a); -} diff --git a/lib/compiler_rt/floatditf.zig b/lib/compiler_rt/floatditf.zig deleted file mode 100644 index 033c35ffcbdd2137d84890c9176d7c77fe29541e..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatditf.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const floatFromInt = @import("./float_from_int.zig").floatFromInt; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__floatditf, "__floatdikf"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_xtoq, "_Qp_xtoq"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__floatditf, "_Q_lltoq"); - } - symbol(&__floatditf, "__floatditf"); -} - -pub fn __floatditf(a: i64) callconv(.c) f128 { - return floatFromInt(f128, a); -} - -fn _Qp_xtoq(c: *f128, a: i64) callconv(.c) void { - c.* = floatFromInt(f128, a); -} diff --git a/lib/compiler_rt/floatdixf.zig b/lib/compiler_rt/floatdixf.zig deleted file mode 100644 index 6bd06245d584402e7ed93b0d57d71f471bde05d4..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatdixf.zig +++ /dev/null @@ -1,10 +0,0 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floatdixf, "__floatdixf"); -} - -fn __floatdixf(a: i64) callconv(.c) f80 { - return floatFromInt(f80, a); -} diff --git a/lib/compiler_rt/floateidf.zig b/lib/compiler_rt/floateidf.zig deleted file mode 100644 index ac3972c28778600d342d0412741e9a3e41797546..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floateidf.zig +++ /dev/null @@ -1,15 +0,0 @@ -const builtin = @import("builtin"); - -const std = @import("std"); - -const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - symbol(&__floateidf, "__floateidf"); -} - -pub fn __floateidf(a: [*]const u8, bits: usize) callconv(.c) f64 { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return floatFromBigInt(f64, .signed, @ptrCast(@alignCast(a[0..byte_size]))); -} diff --git a/lib/compiler_rt/floateihf.zig b/lib/compiler_rt/floateihf.zig deleted file mode 100644 index c1ec290fb1084a05b6353ffde4968bce3c3cd3d8..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floateihf.zig +++ /dev/null @@ -1,14 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; - -comptime { - symbol(&__floateihf, "__floateihf"); -} - -pub fn __floateihf(a: [*]const u8, bits: usize) callconv(.c) f16 { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return floatFromBigInt(f16, .signed, @ptrCast(@alignCast(a[0..byte_size]))); -} diff --git a/lib/compiler_rt/floateisf.zig b/lib/compiler_rt/floateisf.zig deleted file mode 100644 index dd5933b7dff321ee90d0b13ee6d9a5e0d85a9f20..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floateisf.zig +++ /dev/null @@ -1,14 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; - -comptime { - symbol(&__floateisf, "__floateisf"); -} - -pub fn __floateisf(a: [*]const u8, bits: usize) callconv(.c) f32 { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return floatFromBigInt(f32, .signed, @ptrCast(@alignCast(a[0..byte_size]))); -} diff --git a/lib/compiler_rt/floateitf.zig b/lib/compiler_rt/floateitf.zig deleted file mode 100644 index 0df893bd18881c9ec382e718a7664bf4d0f7a8e4..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floateitf.zig +++ /dev/null @@ -1,14 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; - -comptime { - symbol(&__floateitf, "__floateitf"); -} - -pub fn __floateitf(a: [*]const u8, bits: usize) callconv(.c) f128 { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return floatFromBigInt(f128, .signed, @ptrCast(@alignCast(a[0..byte_size]))); -} diff --git a/lib/compiler_rt/floateixf.zig b/lib/compiler_rt/floateixf.zig deleted file mode 100644 index dafefa4e8f11b978f26b5e4d10cc8b0feeed480b..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floateixf.zig +++ /dev/null @@ -1,15 +0,0 @@ -const builtin = @import("builtin"); - -const std = @import("std"); - -const symbol = @import("../compiler_rt.zig").symbol; -const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; - -comptime { - symbol(&__floateixf, "__floateixf"); -} - -pub fn __floateixf(a: [*]const u8, bits: usize) callconv(.c) f80 { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return floatFromBigInt(f80, .signed, @ptrCast(@alignCast(a[0..byte_size]))); -} diff --git a/lib/compiler_rt/floatsidf.zig b/lib/compiler_rt/floatsidf.zig deleted file mode 100644 index dc5a261a08f1e86155d7af20b62b43b02c99bbe5..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatsidf.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_i2d, "__aeabi_i2d"); - } else { - symbol(&__floatsidf, "__floatsidf"); - } -} - -pub fn __floatsidf(a: i32) callconv(.c) f64 { - return floatFromInt(f64, a); -} - -fn __aeabi_i2d(a: i32) callconv(.{ .arm_aapcs = .{} }) f64 { - return floatFromInt(f64, a); -} diff --git a/lib/compiler_rt/floatsihf.zig b/lib/compiler_rt/floatsihf.zig deleted file mode 100644 index e1d588cfb0da1ed1007496f3d32db0fcdd8612ef..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatsihf.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floatsihf, "__floatsihf"); -} - -fn __floatsihf(a: i32) callconv(.c) f16 { - return floatFromInt(f16, a); -} diff --git a/lib/compiler_rt/floatsisf.zig b/lib/compiler_rt/floatsisf.zig deleted file mode 100644 index 0dac860ebfded913a3eacb1666cb34e246f87dde..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatsisf.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_i2f, "__aeabi_i2f"); - } else { - symbol(&__floatsisf, "__floatsisf"); - } -} - -pub fn __floatsisf(a: i32) callconv(.c) f32 { - return floatFromInt(f32, a); -} - -fn __aeabi_i2f(a: i32) callconv(.{ .arm_aapcs = .{} }) f32 { - return floatFromInt(f32, a); -} diff --git a/lib/compiler_rt/floatsitf.zig b/lib/compiler_rt/floatsitf.zig deleted file mode 100644 index 865ebce60fddaa5d8234cf76293b08e12be30000..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatsitf.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__floatsitf, "__floatsikf"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_itoq, "_Qp_itoq"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__floatsitf, "_Q_itoq"); - } - symbol(&__floatsitf, "__floatsitf"); -} - -pub fn __floatsitf(a: i32) callconv(.c) f128 { - return floatFromInt(f128, a); -} - -fn _Qp_itoq(c: *f128, a: i32) callconv(.c) void { - c.* = floatFromInt(f128, a); -} diff --git a/lib/compiler_rt/floatsixf.zig b/lib/compiler_rt/floatsixf.zig deleted file mode 100644 index bd28eaf1fa68f9580f63b918bfeea6cc78295699..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatsixf.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const floatFromInt = @import("./float_from_int.zig").floatFromInt; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - symbol(&__floatsixf, "__floatsixf"); -} - -fn __floatsixf(a: i32) callconv(.c) f80 { - return floatFromInt(f80, a); -} diff --git a/lib/compiler_rt/floattidf.zig b/lib/compiler_rt/floattidf.zig deleted file mode 100644 index 02298705324edcd49b36f69a64c0c78873ecb57b..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floattidf.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floattidf, "__floattidf"); -} - -pub fn __floattidf(a: i128) callconv(.c) f64 { - return floatFromInt(f64, a); -} diff --git a/lib/compiler_rt/floattihf.zig b/lib/compiler_rt/floattihf.zig deleted file mode 100644 index a751e3142c5b273819199105a6848c0280aee3c5..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floattihf.zig +++ /dev/null @@ -1,12 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floattihf, "__floattihf"); -} - -pub fn __floattihf(a: i128) callconv(.c) f16 { - return floatFromInt(f16, a); -} diff --git a/lib/compiler_rt/floattisf.zig b/lib/compiler_rt/floattisf.zig deleted file mode 100644 index 72af61c6b6805d9bd03e6d215dd300fe7589c21f..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floattisf.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const floatFromInt = @import("./float_from_int.zig").floatFromInt; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - symbol(&__floattisf, "__floattisf"); -} - -pub fn __floattisf(a: i128) callconv(.c) f32 { - return floatFromInt(f32, a); -} diff --git a/lib/compiler_rt/floattitf.zig b/lib/compiler_rt/floattitf.zig deleted file mode 100644 index 3e49a68fd56912ebe7573346b6b8aea6b98b91ba..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floattitf.zig +++ /dev/null @@ -1,13 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - if (compiler_rt.want_ppc_abi) - symbol(&__floattitf, "__floattikf"); - symbol(&__floattitf, "__floattitf"); -} - -pub fn __floattitf(a: i128) callconv(.c) f128 { - return floatFromInt(f128, a); -} diff --git a/lib/compiler_rt/floattixf.zig b/lib/compiler_rt/floattixf.zig deleted file mode 100644 index be05180795aef517800c15d01c928bab4f7f19a0..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floattixf.zig +++ /dev/null @@ -1,12 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floattixf, "__floattixf"); -} - -pub fn __floattixf(a: i128) callconv(.c) f80 { - return floatFromInt(f80, a); -} diff --git a/lib/compiler_rt/floatundidf.zig b/lib/compiler_rt/floatundidf.zig deleted file mode 100644 index 852675370503bab154245fd685ff2c2a5449aea0..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatundidf.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const floatFromInt = @import("./float_from_int.zig").floatFromInt; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_ul2d, "__aeabi_ul2d"); - } else { - if (compiler_rt.want_windows_arm_abi) { - symbol(&__floatundidf, "__u64tod"); - } - symbol(&__floatundidf, "__floatundidf"); - } -} - -pub fn __floatundidf(a: u64) callconv(.c) f64 { - return floatFromInt(f64, a); -} - -fn __aeabi_ul2d(a: u64) callconv(.{ .arm_aapcs = .{} }) f64 { - return floatFromInt(f64, a); -} diff --git a/lib/compiler_rt/floatundihf.zig b/lib/compiler_rt/floatundihf.zig deleted file mode 100644 index 064d565d2dc4ec4f118dee8400375de802400f2b..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatundihf.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floatundihf, "__floatundihf"); -} - -fn __floatundihf(a: u64) callconv(.c) f16 { - return floatFromInt(f16, a); -} diff --git a/lib/compiler_rt/floatundisf.zig b/lib/compiler_rt/floatundisf.zig deleted file mode 100644 index 827a419fd5315624866af773ea71a9098b2bcb3e..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatundisf.zig +++ /dev/null @@ -1,23 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_ul2f, "__aeabi_ul2f"); - } else { - if (compiler_rt.want_windows_arm_abi) { - symbol(&__floatundisf, "__u64tos"); - } - symbol(&__floatundisf, "__floatundisf"); - } -} - -pub fn __floatundisf(a: u64) callconv(.c) f32 { - return floatFromInt(f32, a); -} - -fn __aeabi_ul2f(a: u64) callconv(.{ .arm_aapcs = .{} }) f32 { - return floatFromInt(f32, a); -} diff --git a/lib/compiler_rt/floatunditf.zig b/lib/compiler_rt/floatunditf.zig deleted file mode 100644 index 79f9f54e176f5741bbc901b1790895feaadf1f98..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatunditf.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__floatunditf, "__floatundikf"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_uxtoq, "_Qp_uxtoq"); - } else if (compiler_rt.want_sparc32_abi) { - @export(&__floatunditf, "_Q_ulltoq"); - } - symbol(&__floatunditf, "__floatunditf"); -} - -pub fn __floatunditf(a: u64) callconv(.c) f128 { - return floatFromInt(f128, a); -} - -fn _Qp_uxtoq(c: *f128, a: u64) callconv(.c) void { - c.* = floatFromInt(f128, a); -} diff --git a/lib/compiler_rt/floatundixf.zig b/lib/compiler_rt/floatundixf.zig deleted file mode 100644 index ce36d47a4ef225c67e4e45f3695cdb14649cee4c..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatundixf.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floatundixf, "__floatundixf"); -} - -fn __floatundixf(a: u64) callconv(.c) f80 { - return floatFromInt(f80, a); -} diff --git a/lib/compiler_rt/floatuneidf.zig b/lib/compiler_rt/floatuneidf.zig deleted file mode 100644 index 6e391b7cf1c4baeacb55c731ca24c66750c6d346..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatuneidf.zig +++ /dev/null @@ -1,14 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; - -comptime { - symbol(&__floatuneidf, "__floatuneidf"); -} - -pub fn __floatuneidf(a: [*]const u8, bits: usize) callconv(.c) f64 { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return floatFromBigInt(f64, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); -} diff --git a/lib/compiler_rt/floatuneihf.zig b/lib/compiler_rt/floatuneihf.zig deleted file mode 100644 index 0df0cf155be8e7d39afb5012940fa85ec3211603..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatuneihf.zig +++ /dev/null @@ -1,14 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; - -comptime { - symbol(&__floatuneihf, "__floatuneihf"); -} - -pub fn __floatuneihf(a: [*]const u8, bits: usize) callconv(.c) f16 { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return floatFromBigInt(f16, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); -} diff --git a/lib/compiler_rt/floatuneisf.zig b/lib/compiler_rt/floatuneisf.zig deleted file mode 100644 index e2dadd9ffddc6efe13ffd53bb9f2cdeeffc3530d..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatuneisf.zig +++ /dev/null @@ -1,14 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; - -comptime { - symbol(&__floatuneisf, "__floatuneisf"); -} - -pub fn __floatuneisf(a: [*]const u8, bits: usize) callconv(.c) f32 { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return floatFromBigInt(f32, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); -} diff --git a/lib/compiler_rt/floatuneitf.zig b/lib/compiler_rt/floatuneitf.zig deleted file mode 100644 index ddee65dfb18b793bffe08d850384842fcff5747e..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatuneitf.zig +++ /dev/null @@ -1,15 +0,0 @@ -const builtin = @import("builtin"); - -const std = @import("std"); - -const symbol = @import("../compiler_rt.zig").symbol; -const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; - -comptime { - symbol(&__floatuneitf, "__floatuneitf"); -} - -pub fn __floatuneitf(a: [*]const u8, bits: usize) callconv(.c) f128 { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return floatFromBigInt(f128, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); -} diff --git a/lib/compiler_rt/floatuneixf.zig b/lib/compiler_rt/floatuneixf.zig deleted file mode 100644 index 75dd565daffe16ffb4e95230266fca2f5d288603..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatuneixf.zig +++ /dev/null @@ -1,14 +0,0 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromBigInt = @import("float_from_int.zig").floatFromBigInt; - -comptime { - symbol(&__floatuneixf, "__floatuneixf"); -} - -pub fn __floatuneixf(a: [*]const u8, bits: usize) callconv(.c) f80 { - const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); - return floatFromBigInt(f80, .unsigned, @ptrCast(@alignCast(a[0..byte_size]))); -} diff --git a/lib/compiler_rt/floatunsidf.zig b/lib/compiler_rt/floatunsidf.zig deleted file mode 100644 index 94949c7bff4eafff900a0b22e53998a930c3d7ea..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatunsidf.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_ui2d, "__aeabi_ui2d"); - } else { - symbol(&__floatunsidf, "__floatunsidf"); - } -} - -pub fn __floatunsidf(a: u32) callconv(.c) f64 { - return floatFromInt(f64, a); -} - -fn __aeabi_ui2d(a: u32) callconv(.{ .arm_aapcs = .{} }) f64 { - return floatFromInt(f64, a); -} diff --git a/lib/compiler_rt/floatunsihf.zig b/lib/compiler_rt/floatunsihf.zig deleted file mode 100644 index a2e42ca10f3af950e900f5250fa6a3d23e2b1266..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatunsihf.zig +++ /dev/null @@ -1,10 +0,0 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floatunsihf, "__floatunsihf"); -} - -pub fn __floatunsihf(a: u32) callconv(.c) f16 { - return floatFromInt(f16, a); -} diff --git a/lib/compiler_rt/floatunsisf.zig b/lib/compiler_rt/floatunsisf.zig deleted file mode 100644 index 04da1aa5c03cf76815cccf2273731501d1c8edc0..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatunsisf.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const floatFromInt = @import("./float_from_int.zig").floatFromInt; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_ui2f, "__aeabi_ui2f"); - } else { - symbol(&__floatunsisf, "__floatunsisf"); - } -} - -pub fn __floatunsisf(a: u32) callconv(.c) f32 { - return floatFromInt(f32, a); -} - -fn __aeabi_ui2f(a: u32) callconv(.{ .arm_aapcs = .{} }) f32 { - return floatFromInt(f32, a); -} diff --git a/lib/compiler_rt/floatunsitf.zig b/lib/compiler_rt/floatunsitf.zig deleted file mode 100644 index 2b7c58eab8bd7c2a238062e0cc123f5ce6b8c9e0..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatunsitf.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const floatFromInt = @import("./float_from_int.zig").floatFromInt; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__floatunsitf, "__floatunsikf"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_uitoq, "_Qp_uitoq"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__floatunsitf, "_Q_utoq"); - } - symbol(&__floatunsitf, "__floatunsitf"); -} - -pub fn __floatunsitf(a: u32) callconv(.c) f128 { - return floatFromInt(f128, a); -} - -fn _Qp_uitoq(c: *f128, a: u32) callconv(.c) void { - c.* = floatFromInt(f128, a); -} diff --git a/lib/compiler_rt/floatunsixf.zig b/lib/compiler_rt/floatunsixf.zig deleted file mode 100644 index 906f0270f5c53d28970a0c250b24abcadfa72946..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatunsixf.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floatunsixf, "__floatunsixf"); -} - -fn __floatunsixf(a: u32) callconv(.c) f80 { - return floatFromInt(f80, a); -} diff --git a/lib/compiler_rt/floatuntidf.zig b/lib/compiler_rt/floatuntidf.zig deleted file mode 100644 index b770457bc4992a5bd6237d832e2ca4c0cbed11e0..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatuntidf.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const floatFromInt = @import("./float_from_int.zig").floatFromInt; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - symbol(&__floatuntidf, "__floatuntidf"); -} - -pub fn __floatuntidf(a: u128) callconv(.c) f64 { - return floatFromInt(f64, a); -} diff --git a/lib/compiler_rt/floatuntihf.zig b/lib/compiler_rt/floatuntihf.zig deleted file mode 100644 index 5b4373cb7c496b0acf1a2fe6ef988872b30e8780..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatuntihf.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floatuntihf, "__floatuntihf"); -} - -pub fn __floatuntihf(a: u128) callconv(.c) f16 { - return floatFromInt(f16, a); -} diff --git a/lib/compiler_rt/floatuntisf.zig b/lib/compiler_rt/floatuntisf.zig deleted file mode 100644 index de9a021476edecfcc26761133c0645d799c677da..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatuntisf.zig +++ /dev/null @@ -1,12 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floatuntisf, "__floatuntisf"); -} - -pub fn __floatuntisf(a: u128) callconv(.c) f32 { - return floatFromInt(f32, a); -} diff --git a/lib/compiler_rt/floatuntitf.zig b/lib/compiler_rt/floatuntitf.zig deleted file mode 100644 index 47cd65cc3ff4460d937e0ccd7acabb2455ae704a..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatuntitf.zig +++ /dev/null @@ -1,13 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const floatFromInt = @import("./float_from_int.zig").floatFromInt; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_ppc_abi) - symbol(&__floatuntitf, "__floatuntikf"); - symbol(&__floatuntitf, "__floatuntitf"); -} - -pub fn __floatuntitf(a: u128) callconv(.c) f128 { - return floatFromInt(f128, a); -} diff --git a/lib/compiler_rt/floatuntixf.zig b/lib/compiler_rt/floatuntixf.zig deleted file mode 100644 index 41fb45b3a3a1b8e213c03a4ef5e847feb8d31211..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/floatuntixf.zig +++ /dev/null @@ -1,12 +0,0 @@ -const builtin = @import("builtin"); -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const floatFromInt = @import("./float_from_int.zig").floatFromInt; - -comptime { - symbol(&__floatuntixf, "__floatuntixf"); -} - -pub fn __floatuntixf(a: u128) callconv(.c) f80 { - return floatFromInt(f80, a); -} diff --git a/lib/compiler_rt/floor_ceil.zig b/lib/compiler_rt/floor_ceil.zig index f81d2e0011286a1ea45a3ef147fc704eadac4b4e..f31c352d026c549bd230c9d7d5f15677a85968ce 100644 --- a/lib/compiler_rt/floor_ceil.zig +++ b/lib/compiler_rt/floor_ceil.zig @@ -15,7 +15,7 @@ const mem = std.mem; const expect = std.testing.expect; const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; +const symbol = compiler_rt.symbol; comptime { // floor @@ -41,52 +41,92 @@ comptime { symbol(&ceill, "ceill"); } -pub fn __floorh(x: f16) callconv(.c) f16 { +fn __floorh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(floor_f16(compiler_rt.f16.fromAbi(x))); +} +pub fn floor_f16(x: f16) f16 { return impl(f16, .floor, x); } -pub fn floorf(x: f32) callconv(.c) f32 { +fn floorf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(floor_f32(compiler_rt.f32.fromAbi(x))); +} +pub fn floor_f32(x: f32) f32 { return impl(f32, .floor, x); } -pub fn floor(x: f64) callconv(.c) f64 { +fn floor(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(floor_f64(compiler_rt.f64.fromAbi(x))); +} +pub fn floor_f64(x: f64) f64 { return impl(f64, .floor, x); } -pub fn __floorx(x: f80) callconv(.c) f80 { +fn __floorx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(floor_f80(compiler_rt.f80.fromAbi(x))); +} +pub fn floor_f80(x: f80) f80 { return impl(f80, .floor, x); } -pub fn floorq(x: f128) callconv(.c) f128 { +fn floorq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(floor_f128(compiler_rt.f128.fromAbi(x))); +} +pub fn floor_f128(x: f128) f128 { return impl(f128, .floor, x); } pub fn floorl(x: c_longdouble) callconv(.c) c_longdouble { - return impl(std.meta.Float(@bitSizeOf(c_longdouble)), .floor, x); + switch (@typeInfo(c_longdouble).float.bits) { + 64 => return floor_f64(x), + 80 => return floor_f80(x), + 128 => return floor_f128(x), + else => comptime unreachable, + } } -pub fn __ceilh(x: f16) callconv(.c) f16 { +fn __ceilh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(ceil_f16(compiler_rt.f16.fromAbi(x))); +} +pub fn ceil_f16(x: f16) f16 { return impl(f16, .ceil, x); } -pub fn ceilf(x: f32) callconv(.c) f32 { +fn ceilf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(ceil_f32(compiler_rt.f32.fromAbi(x))); +} +pub fn ceil_f32(x: f32) f32 { return impl(f32, .ceil, x); } -pub fn ceil(x: f64) callconv(.c) f64 { +fn ceil(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(ceil_f64(compiler_rt.f64.fromAbi(x))); +} +pub fn ceil_f64(x: f64) f64 { return impl(f64, .ceil, x); } -pub fn __ceilx(x: f80) callconv(.c) f80 { +fn __ceilx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(ceil_f80(compiler_rt.f80.fromAbi(x))); +} +pub fn ceil_f80(x: f80) f80 { return impl(f80, .ceil, x); } -pub fn ceilq(x: f128) callconv(.c) f128 { +fn ceilq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(ceil_f128(compiler_rt.f128.fromAbi(x))); +} +pub fn ceil_f128(x: f128) f128 { return impl(f128, .ceil, x); } pub fn ceill(x: c_longdouble) callconv(.c) c_longdouble { - return impl(std.meta.Float(@bitSizeOf(c_longdouble)), .ceil, x); + switch (@typeInfo(c_longdouble).float.bits) { + 64 => return ceil_f64(x), + 80 => return ceil_f80(x), + 128 => return ceil_f128(x), + else => comptime unreachable, + } } inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T { @@ -144,142 +184,122 @@ inline fn impl(comptime T: type, comptime op: enum { floor, ceil }, x: T) T { } } -test "floor16" { - try expect(__floorh(1.3) == 1.0); - try expect(__floorh(-1.3) == -2.0); - try expect(__floorh(0.2) == 0.0); -} - -test "floor32" { - try expect(floorf(1.3) == 1.0); - try expect(floorf(-1.3) == -2.0); - try expect(floorf(0.2) == 0.0); -} - -test "floor64" { - try expect(floor(1.3) == 1.0); - try expect(floor(-1.3) == -2.0); - try expect(floor(0.2) == 0.0); -} - -test "floor80" { - try expect(__floorx(1.3) == 1.0); - try expect(__floorx(-1.3) == -2.0); - try expect(__floorx(0.2) == 0.0); -} - -test "floor128" { - try expect(floorq(1.3) == 1.0); - try expect(floorq(-1.3) == -2.0); - try expect(floorq(0.2) == 0.0); -} - -test "floor16.special" { - try expect(__floorh(0.0) == 0.0); - try expect(__floorh(-0.0) == -0.0); - try expect(math.isPositiveInf(__floorh(math.inf(f16)))); - try expect(math.isNegativeInf(__floorh(-math.inf(f16)))); - try expect(math.isNan(__floorh(math.nan(f16)))); -} - -test "floor32.special" { - try expect(floorf(0.0) == 0.0); - try expect(floorf(-0.0) == -0.0); - try expect(math.isPositiveInf(floorf(math.inf(f32)))); - try expect(math.isNegativeInf(floorf(-math.inf(f32)))); - try expect(math.isNan(floorf(math.nan(f32)))); -} - -test "floor64.special" { - try expect(floor(0.0) == 0.0); - try expect(floor(-0.0) == -0.0); - try expect(math.isPositiveInf(floor(math.inf(f64)))); - try expect(math.isNegativeInf(floor(-math.inf(f64)))); - try expect(math.isNan(floor(math.nan(f64)))); -} - -test "floor80.special" { - try expect(__floorx(0.0) == 0.0); - try expect(__floorx(-0.0) == -0.0); - try expect(math.isPositiveInf(__floorx(math.inf(f80)))); - try expect(math.isNegativeInf(__floorx(-math.inf(f80)))); - try expect(math.isNan(__floorx(math.nan(f80)))); -} - -test "floor128.special" { - try expect(floorq(0.0) == 0.0); - try expect(floorq(-0.0) == -0.0); - try expect(math.isPositiveInf(floorq(math.inf(f128)))); - try expect(math.isNegativeInf(floorq(-math.inf(f128)))); - try expect(math.isNan(floorq(math.nan(f128)))); -} - -test "ceil16" { - try expect(__ceilh(1.3) == 2.0); - try expect(__ceilh(-1.3) == -1.0); - try expect(__ceilh(0.2) == 1.0); -} - -test "ceil32" { - try expect(ceilf(1.3) == 2.0); - try expect(ceilf(-1.3) == -1.0); - try expect(ceilf(0.2) == 1.0); -} - -test "ceil64" { - try expect(ceil(1.3) == 2.0); - try expect(ceil(-1.3) == -1.0); - try expect(ceil(0.2) == 1.0); -} - -test "ceil80" { - try expect(__ceilx(1.3) == 2.0); - try expect(__ceilx(-1.3) == -1.0); - try expect(__ceilx(0.2) == 1.0); -} - -test "ceil128" { - try expect(ceilq(1.3) == 2.0); - try expect(ceilq(-1.3) == -1.0); - try expect(ceilq(0.2) == 1.0); -} - -test "ceil16.special" { - try expect(__ceilh(0.0) == 0.0); - try expect(__ceilh(-0.0) == -0.0); - try expect(math.isPositiveInf(__ceilh(math.inf(f16)))); - try expect(math.isNegativeInf(__ceilh(-math.inf(f16)))); - try expect(math.isNan(__ceilh(math.nan(f16)))); -} - -test "ceil32.special" { - try expect(ceilf(0.0) == 0.0); - try expect(ceilf(-0.0) == -0.0); - try expect(math.isPositiveInf(ceilf(math.inf(f32)))); - try expect(math.isNegativeInf(ceilf(-math.inf(f32)))); - try expect(math.isNan(ceilf(math.nan(f32)))); -} - -test "ceil64.special" { - try expect(ceil(0.0) == 0.0); - try expect(ceil(-0.0) == -0.0); - try expect(math.isPositiveInf(ceil(math.inf(f64)))); - try expect(math.isNegativeInf(ceil(-math.inf(f64)))); - try expect(math.isNan(ceil(math.nan(f64)))); -} - -test "ceil80.special" { - try expect(__ceilx(0.0) == 0.0); - try expect(__ceilx(-0.0) == -0.0); - try expect(math.isPositiveInf(__ceilx(math.inf(f80)))); - try expect(math.isNegativeInf(__ceilx(-math.inf(f80)))); - try expect(math.isNan(__ceilx(math.nan(f80)))); -} - -test "ceil128.special" { - try expect(ceilq(0.0) == 0.0); - try expect(ceilq(-0.0) == -0.0); - try expect(math.isPositiveInf(ceilq(math.inf(f128)))); - try expect(math.isNegativeInf(ceilq(-math.inf(f128)))); - try expect(math.isNan(ceilq(math.nan(f128)))); +test floor_f16 { + try expect(floor_f16(1.3) == 1.0); + try expect(floor_f16(-1.3) == -2.0); + try expect(floor_f16(-0.2) == -1.0); + try expect(math.isPositiveZero(floor_f16(0.2))); + try expect(math.isPositiveZero(floor_f16(0.0))); + try expect(math.isNegativeZero(floor_f16(-0.0))); + try expect(math.isPositiveInf(floor_f16(math.inf(f16)))); + try expect(math.isNegativeInf(floor_f16(-math.inf(f16)))); + try expect(math.isNan(floor_f16(math.nan(f16)))); +} + +test floor_f32 { + try expect(floor_f32(1.3) == 1.0); + try expect(floor_f32(-1.3) == -2.0); + try expect(floor_f32(-0.2) == -1.0); + try expect(math.isPositiveZero(floor_f32(0.2))); + try expect(math.isPositiveZero(floor_f32(0.0))); + try expect(math.isNegativeZero(floor_f32(-0.0))); + try expect(math.isPositiveInf(floor_f32(math.inf(f32)))); + try expect(math.isNegativeInf(floor_f32(-math.inf(f32)))); + try expect(math.isNan(floor_f32(math.nan(f32)))); +} + +test floor_f64 { + try expect(floor_f64(1.3) == 1.0); + try expect(floor_f64(-1.3) == -2.0); + try expect(floor_f64(-0.2) == -1.0); + try expect(math.isPositiveZero(floor_f64(0.2))); + try expect(math.isPositiveZero(floor_f64(0.0))); + try expect(math.isNegativeZero(floor_f64(-0.0))); + try expect(math.isPositiveInf(floor_f64(math.inf(f64)))); + try expect(math.isNegativeInf(floor_f64(-math.inf(f64)))); + try expect(math.isNan(floor_f64(math.nan(f64)))); +} + +test floor_f80 { + try expect(floor_f80(1.3) == 1.0); + try expect(floor_f80(-1.3) == -2.0); + try expect(floor_f80(-0.2) == -1.0); + try expect(math.isPositiveZero(floor_f80(0.2))); + try expect(math.isPositiveZero(floor_f80(0.0))); + try expect(math.isNegativeZero(floor_f80(-0.0))); + try expect(math.isPositiveInf(floor_f80(math.inf(f80)))); + try expect(math.isNegativeInf(floor_f80(-math.inf(f80)))); + try expect(math.isNan(floor_f80(math.nan(f80)))); +} + +test floor_f128 { + try expect(floor_f128(1.3) == 1.0); + try expect(floor_f128(-1.3) == -2.0); + try expect(floor_f128(-0.2) == -1.0); + try expect(math.isPositiveZero(floor_f128(0.2))); + try expect(math.isPositiveZero(floor_f128(0.0))); + try expect(math.isNegativeZero(floor_f128(-0.0))); + try expect(math.isPositiveInf(floor_f128(math.inf(f128)))); + try expect(math.isNegativeInf(floor_f128(-math.inf(f128)))); + try expect(math.isNan(floor_f128(math.nan(f128)))); +} + +test ceil_f16 { + try expect(ceil_f16(1.3) == 2.0); + try expect(ceil_f16(-1.3) == -1.0); + try expect(ceil_f16(0.2) == 1.0); + try expect(math.isNegativeZero(ceil_f16(-0.2))); + try expect(math.isPositiveZero(ceil_f16(0.0))); + try expect(math.isNegativeZero(ceil_f16(-0.0))); + try expect(math.isPositiveInf(ceil_f16(math.inf(f16)))); + try expect(math.isNegativeInf(ceil_f16(-math.inf(f16)))); + try expect(math.isNan(ceil_f16(math.nan(f16)))); +} + +test ceil_f32 { + try expect(ceil_f32(1.3) == 2.0); + try expect(ceil_f32(-1.3) == -1.0); + try expect(ceil_f32(0.2) == 1.0); + try expect(math.isNegativeZero(ceil_f32(-0.2))); + try expect(math.isPositiveZero(ceil_f32(0.0))); + try expect(math.isNegativeZero(ceil_f32(-0.0))); + try expect(math.isPositiveInf(ceil_f32(math.inf(f32)))); + try expect(math.isNegativeInf(ceil_f32(-math.inf(f32)))); + try expect(math.isNan(ceil_f32(math.nan(f32)))); +} + +test ceil_f64 { + try expect(ceil_f64(1.3) == 2.0); + try expect(ceil_f64(-1.3) == -1.0); + try expect(ceil_f64(0.2) == 1.0); + try expect(math.isNegativeZero(ceil_f64(-0.2))); + try expect(math.isPositiveZero(ceil_f64(0.0))); + try expect(math.isNegativeZero(ceil_f64(-0.0))); + try expect(math.isPositiveInf(ceil_f64(math.inf(f64)))); + try expect(math.isNegativeInf(ceil_f64(-math.inf(f64)))); + try expect(math.isNan(ceil_f64(math.nan(f64)))); +} + +test ceil_f80 { + try expect(ceil_f80(1.3) == 2.0); + try expect(ceil_f80(-1.3) == -1.0); + try expect(ceil_f80(0.2) == 1.0); + try expect(math.isNegativeZero(ceil_f80(-0.2))); + try expect(math.isPositiveZero(ceil_f80(0.0))); + try expect(math.isNegativeZero(ceil_f80(-0.0))); + try expect(math.isPositiveInf(ceil_f80(math.inf(f80)))); + try expect(math.isNegativeInf(ceil_f80(-math.inf(f80)))); + try expect(math.isNan(ceil_f80(math.nan(f80)))); +} + +test ceil_f128 { + try expect(ceil_f128(1.3) == 2.0); + try expect(ceil_f128(-1.3) == -1.0); + try expect(ceil_f128(0.2) == 1.0); + try expect(math.isNegativeZero(ceil_f128(-0.2))); + try expect(math.isPositiveZero(ceil_f128(0.0))); + try expect(math.isNegativeZero(ceil_f128(-0.0))); + try expect(math.isPositiveInf(ceil_f128(math.inf(f128)))); + try expect(math.isNegativeInf(ceil_f128(-math.inf(f128)))); + try expect(math.isNan(ceil_f128(math.nan(f128)))); } diff --git a/lib/compiler_rt/fma.zig b/lib/compiler_rt/fma.zig index 61732585db2ece3fb84c3029293cab41662781d2..f10d08fc63f2038fa98cd4b28c5d4ee8a2ca0a84 100644 --- a/lib/compiler_rt/fma.zig +++ b/lib/compiler_rt/fma.zig @@ -23,12 +23,18 @@ comptime { symbol(&fmal, "fmal"); } -pub fn __fmah(x: f16, y: f16, z: f16) callconv(.c) f16 { +fn __fmah(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi, z: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(fma_f16(compiler_rt.f16.fromAbi(x), compiler_rt.f16.fromAbi(y), compiler_rt.f16.fromAbi(z))); +} +pub fn fma_f16(x: f16, y: f16, z: f16) f16 { // TODO: more efficient implementation - return @floatCast(fmaf(x, y, z)); + return @floatCast(fma_f32(x, y, z)); } -pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 { +fn fmaf(x: compiler_rt.f32.Abi, y: compiler_rt.f32.Abi, z: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(fma_f32(compiler_rt.f32.fromAbi(x), compiler_rt.f32.fromAbi(y), compiler_rt.f32.fromAbi(z))); +} +pub fn fma_f32(x: f32, y: f32, z: f32) f32 { const xy = @as(f64, x) * y; const xy_z = xy + z; const u = @as(u64, @bitCast(xy_z)); @@ -42,8 +48,11 @@ pub fn fmaf(x: f32, y: f32, z: f32) callconv(.c) f32 { } } +fn fma(x: compiler_rt.f64.Abi, y: compiler_rt.f64.Abi, z: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(fma_f64(compiler_rt.f64.fromAbi(x), compiler_rt.f64.fromAbi(y), compiler_rt.f64.fromAbi(z))); +} /// NOTE: Upstream fma.c has been rewritten completely to raise fp exceptions more accurately. -pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 { +pub fn fma_f64(x: f64, y: f64, z: f64) f64 { if (!math.isFinite(x) or !math.isFinite(y)) { return x * y + z; } @@ -90,11 +99,17 @@ pub fn fma(x: f64, y: f64, z: f64) callconv(.c) f64 { } } -pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 { +fn __fmax(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi, c: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(fma_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b), compiler_rt.f80.fromAbi(c))); +} +pub fn fma_f80(a: f80, b: f80, c: f80) f80 { // TODO: more efficient implementation - return @floatCast(fmaq(a, b, c)); + return @floatCast(fma_f128(a, b, c)); } +fn fmaq(x: compiler_rt.f128.Abi, y: compiler_rt.f128.Abi, z: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(fma_f128(compiler_rt.f128.fromAbi(x), compiler_rt.f128.fromAbi(y), compiler_rt.f128.fromAbi(z))); +} /// Fused multiply-add: Compute x * y + z with a single rounding error. /// /// We use scaling to avoid overflow/underflow, along with the @@ -102,7 +117,7 @@ pub fn __fmax(a: f80, b: f80, c: f80) callconv(.c) f80 { /// /// Dekker, T. A Floating-Point Technique for Extending the /// Available Precision. Numer. Math. 18, 224-242 (1971). -pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 { +pub fn fma_f128(x: f128, y: f128, z: f128) f128 { if (!math.isFinite(x) or !math.isFinite(y)) { return x * y + z; } @@ -151,10 +166,10 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.c) f128 { pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return fma(x, y, z), - 80 => return __fmax(x, y, z), - 128 => return fmaq(x, y, z), - else => @compileError("unreachable"), + 64 => return fma_f64(x, y, z), + 80 => return fma_f80(x, y, z), + 128 => return fma_f128(x, y, z), + else => comptime unreachable, } } @@ -316,35 +331,35 @@ fn dd_mul128(a: f128, b: f128) dd128 { test "32" { const epsilon = 0.000001; - try expect(math.approxEqAbs(f32, fmaf(0.0, 5.0, 9.124), 9.124, epsilon)); - try expect(math.approxEqAbs(f32, fmaf(0.2, 5.0, 9.124), 10.124, epsilon)); - try expect(math.approxEqAbs(f32, fmaf(0.8923, 5.0, 9.124), 13.5855, epsilon)); - try expect(math.approxEqAbs(f32, fmaf(1.5, 5.0, 9.124), 16.624, epsilon)); - try expect(math.approxEqAbs(f32, fmaf(37.45, 5.0, 9.124), 196.374004, epsilon)); - try expect(math.approxEqAbs(f32, fmaf(89.123, 5.0, 9.124), 454.739005, epsilon)); - try expect(math.approxEqAbs(f32, fmaf(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); + try expect(math.approxEqAbs(f32, fma_f32(0.0, 5.0, 9.124), 9.124, epsilon)); + try expect(math.approxEqAbs(f32, fma_f32(0.2, 5.0, 9.124), 10.124, epsilon)); + try expect(math.approxEqAbs(f32, fma_f32(0.8923, 5.0, 9.124), 13.5855, epsilon)); + try expect(math.approxEqAbs(f32, fma_f32(1.5, 5.0, 9.124), 16.624, epsilon)); + try expect(math.approxEqAbs(f32, fma_f32(37.45, 5.0, 9.124), 196.374004, epsilon)); + try expect(math.approxEqAbs(f32, fma_f32(89.123, 5.0, 9.124), 454.739005, epsilon)); + try expect(math.approxEqAbs(f32, fma_f32(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); } test "64" { const epsilon = 0.000001; - try expect(math.approxEqAbs(f64, fma(0.0, 5.0, 9.124), 9.124, epsilon)); - try expect(math.approxEqAbs(f64, fma(0.2, 5.0, 9.124), 10.124, epsilon)); - try expect(math.approxEqAbs(f64, fma(0.8923, 5.0, 9.124), 13.5855, epsilon)); - try expect(math.approxEqAbs(f64, fma(1.5, 5.0, 9.124), 16.624, epsilon)); - try expect(math.approxEqAbs(f64, fma(37.45, 5.0, 9.124), 196.374, epsilon)); - try expect(math.approxEqAbs(f64, fma(89.123, 5.0, 9.124), 454.739, epsilon)); - try expect(math.approxEqAbs(f64, fma(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); + try expect(math.approxEqAbs(f64, fma_f64(0.0, 5.0, 9.124), 9.124, epsilon)); + try expect(math.approxEqAbs(f64, fma_f64(0.2, 5.0, 9.124), 10.124, epsilon)); + try expect(math.approxEqAbs(f64, fma_f64(0.8923, 5.0, 9.124), 13.5855, epsilon)); + try expect(math.approxEqAbs(f64, fma_f64(1.5, 5.0, 9.124), 16.624, epsilon)); + try expect(math.approxEqAbs(f64, fma_f64(37.45, 5.0, 9.124), 196.374, epsilon)); + try expect(math.approxEqAbs(f64, fma_f64(89.123, 5.0, 9.124), 454.739, epsilon)); + try expect(math.approxEqAbs(f64, fma_f64(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); } test "128" { const epsilon = 0.000001; - try expect(math.approxEqAbs(f128, fmaq(0.0, 5.0, 9.124), 9.124, epsilon)); - try expect(math.approxEqAbs(f128, fmaq(0.2, 5.0, 9.124), 10.124, epsilon)); - try expect(math.approxEqAbs(f128, fmaq(0.8923, 5.0, 9.124), 13.5855, epsilon)); - try expect(math.approxEqAbs(f128, fmaq(1.5, 5.0, 9.124), 16.624, epsilon)); - try expect(math.approxEqAbs(f128, fmaq(37.45, 5.0, 9.124), 196.374, epsilon)); - try expect(math.approxEqAbs(f128, fmaq(89.123, 5.0, 9.124), 454.739, epsilon)); - try expect(math.approxEqAbs(f128, fmaq(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); + try expect(math.approxEqAbs(f128, fma_f128(0.0, 5.0, 9.124), 9.124, epsilon)); + try expect(math.approxEqAbs(f128, fma_f128(0.2, 5.0, 9.124), 10.124, epsilon)); + try expect(math.approxEqAbs(f128, fma_f128(0.8923, 5.0, 9.124), 13.5855, epsilon)); + try expect(math.approxEqAbs(f128, fma_f128(1.5, 5.0, 9.124), 16.624, epsilon)); + try expect(math.approxEqAbs(f128, fma_f128(37.45, 5.0, 9.124), 196.374, epsilon)); + try expect(math.approxEqAbs(f128, fma_f128(89.123, 5.0, 9.124), 454.739, epsilon)); + try expect(math.approxEqAbs(f128, fma_f128(123123.234375, 5.0, 9.124), 615625.295875, epsilon)); } diff --git a/lib/compiler_rt/fmax.zig b/lib/compiler_rt/fmax.zig index 317d93f2d3e42fcfb88c4f36fe2203dab6bfeed2..cf323533952e542e126e11f69ec5a8352c37bcdb 100644 --- a/lib/compiler_rt/fmax.zig +++ b/lib/compiler_rt/fmax.zig @@ -17,32 +17,47 @@ comptime { symbol(&fmaxl, "fmaxl"); } -pub fn __fmaxh(x: f16, y: f16) callconv(.c) f16 { +fn __fmaxh(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(fmax_f16(compiler_rt.f16.fromAbi(x), compiler_rt.f16.fromAbi(y))); +} +pub fn fmax_f16(x: f16, y: f16) f16 { return generic_fmax(f16, x, y); } -pub fn fmaxf(x: f32, y: f32) callconv(.c) f32 { +fn fmaxf(x: compiler_rt.f32.Abi, y: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(fmax_f32(compiler_rt.f32.fromAbi(x), compiler_rt.f32.fromAbi(y))); +} +pub fn fmax_f32(x: f32, y: f32) f32 { return generic_fmax(f32, x, y); } -pub fn fmax(x: f64, y: f64) callconv(.c) f64 { +fn fmax(x: compiler_rt.f64.Abi, y: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(fmax_f64(compiler_rt.f64.fromAbi(x), compiler_rt.f64.fromAbi(y))); +} +pub fn fmax_f64(x: f64, y: f64) f64 { return generic_fmax(f64, x, y); } -pub fn __fmaxx(x: f80, y: f80) callconv(.c) f80 { +fn __fmaxx(x: compiler_rt.f80.Abi, y: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(fmax_f80(compiler_rt.f80.fromAbi(x), compiler_rt.f80.fromAbi(y))); +} +pub fn fmax_f80(x: f80, y: f80) f80 { return generic_fmax(f80, x, y); } -pub fn fmaxq(x: f128, y: f128) callconv(.c) f128 { +fn fmaxq(x: compiler_rt.f128.Abi, y: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(fmax_f128(compiler_rt.f128.fromAbi(x), compiler_rt.f128.fromAbi(y))); +} +pub fn fmax_f128(x: f128, y: f128) f128 { return generic_fmax(f128, x, y); } pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return fmax(x, y), - 80 => return __fmaxx(x, y), - 128 => return fmaxq(x, y), - else => @compileError("unreachable"), + 64 => return fmax_f64(x, y), + 80 => return fmax_f80(x, y), + 128 => return fmax_f128(x, y), + else => comptime unreachable, } } diff --git a/lib/compiler_rt/fmin.zig b/lib/compiler_rt/fmin.zig index 36cf9c121bbf17c1e282cfcf982f69ce7f1ec17c..48b5dcdc225118ce3a2096b15c98b0b534f75ae3 100644 --- a/lib/compiler_rt/fmin.zig +++ b/lib/compiler_rt/fmin.zig @@ -17,32 +17,47 @@ comptime { symbol(&fminl, "fminl"); } -pub fn __fminh(x: f16, y: f16) callconv(.c) f16 { +fn __fminh(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(fmin_f16(compiler_rt.f16.fromAbi(x), compiler_rt.f16.fromAbi(y))); +} +pub fn fmin_f16(x: f16, y: f16) f16 { return generic_fmin(f16, x, y); } -pub fn fminf(x: f32, y: f32) callconv(.c) f32 { +fn fminf(x: compiler_rt.f32.Abi, y: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(fmin_f32(compiler_rt.f32.fromAbi(x), compiler_rt.f32.fromAbi(y))); +} +pub fn fmin_f32(x: f32, y: f32) f32 { return generic_fmin(f32, x, y); } -pub fn fmin(x: f64, y: f64) callconv(.c) f64 { +fn fmin(x: compiler_rt.f64.Abi, y: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(fmin_f64(compiler_rt.f64.fromAbi(x), compiler_rt.f64.fromAbi(y))); +} +pub fn fmin_f64(x: f64, y: f64) f64 { return generic_fmin(f64, x, y); } -pub fn __fminx(x: f80, y: f80) callconv(.c) f80 { +fn __fminx(x: compiler_rt.f80.Abi, y: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(fmin_f80(compiler_rt.f80.fromAbi(x), compiler_rt.f80.fromAbi(y))); +} +pub fn fmin_f80(x: f80, y: f80) f80 { return generic_fmin(f80, x, y); } -pub fn fminq(x: f128, y: f128) callconv(.c) f128 { +fn fminq(x: compiler_rt.f128.Abi, y: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(fmin_f128(compiler_rt.f128.fromAbi(x), compiler_rt.f128.fromAbi(y))); +} +pub fn fmin_f128(x: f128, y: f128) f128 { return generic_fmin(f128, x, y); } pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return fmin(x, y), - 80 => return __fminx(x, y), - 128 => return fminq(x, y), - else => @compileError("unreachable"), + 64 => return fmin_f64(x, y), + 80 => return fmin_f80(x, y), + 128 => return fmin_f128(x, y), + else => comptime unreachable, } } diff --git a/lib/compiler_rt/fmod.zig b/lib/compiler_rt/fmod.zig index 009eedd8ac84ab7eb905a74900fc17d07e8be421..636138516bf1f13d2a15b597d21fd6a617e7ee0d 100644 --- a/lib/compiler_rt/fmod.zig +++ b/lib/compiler_rt/fmod.zig @@ -19,22 +19,34 @@ comptime { symbol(&fmodl, "fmodl"); } -pub fn __fmodh(x: f16, y: f16) callconv(.c) f16 { +fn __fmodh(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(fmod_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); +} +pub fn fmod_f16(x: f16, y: f16) f16 { // TODO: more efficient implementation - return @floatCast(fmodf(x, y)); + return @floatCast(fmod_f32(x, y)); } -pub fn fmodf(x: f32, y: f32) callconv(.c) f32 { +fn fmodf(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(fmod_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); +} +pub fn fmod_f32(x: f32, y: f32) f32 { return generic_fmod(f32, x, y); } -pub fn fmod(x: f64, y: f64) callconv(.c) f64 { +fn fmod(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(fmod_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); +} +pub fn fmod_f64(x: f64, y: f64) f64 { return generic_fmod(f64, x, y); } +fn __fmodx(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(fmod_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); +} /// fmodx - floating modulo large, returns the remainder of division for f80 types /// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits -pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 { +pub fn fmod_f80(a: f80, b: f80) f80 { const T = f80; const Z = @Int(.unsigned, @bitSizeOf(T)); @@ -130,9 +142,12 @@ pub fn __fmodx(a: f80, b: f80) callconv(.c) f80 { } } +fn fmodq(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(fmod_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); +} /// fmodq - floating modulo large, returns the remainder of division for f128 types /// Logic and flow heavily inspired by MUSL fmodl for 113 mantissa digits -pub fn fmodq(a: f128, b: f128) callconv(.c) f128 { +pub fn fmod_f128(a: f128, b: f128) f128 { var amod = a; var bmod = b; const aPtr_u64: [*]u64 = @ptrCast(&amod); @@ -251,10 +266,10 @@ pub fn fmodq(a: f128, b: f128) callconv(.c) f128 { pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return fmod(a, b), - 80 => return __fmodx(a, b), - 128 => return fmodq(a, b), - else => @compileError("unreachable"), + 64 => return fmod_f64(a, b), + 80 => return fmod_f80(a, b), + 128 => return fmod_f128(a, b), + else => comptime unreachable, } } @@ -342,42 +357,42 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T { return @bitCast(ux); } -test "fmodf" { +test fmod_f32 { const nan_val = math.nan(f32); const inf_val = math.inf(f32); - try std.testing.expect(math.isNan(fmodf(nan_val, 1.0))); - try std.testing.expect(math.isNan(fmodf(1.0, nan_val))); - try std.testing.expect(math.isNan(fmodf(inf_val, 1.0))); - try std.testing.expect(math.isNan(fmodf(0.0, 0.0))); - try std.testing.expect(math.isNan(fmodf(1.0, 0.0))); + try std.testing.expect(math.isNan(fmod_f32(nan_val, 1.0))); + try std.testing.expect(math.isNan(fmod_f32(1.0, nan_val))); + try std.testing.expect(math.isNan(fmod_f32(inf_val, 1.0))); + try std.testing.expect(math.isNan(fmod_f32(0.0, 0.0))); + try std.testing.expect(math.isNan(fmod_f32(1.0, 0.0))); - try std.testing.expectEqual(@as(f32, 0.0), fmodf(0.0, 2.0)); - try std.testing.expectEqual(@as(f32, -0.0), fmodf(-0.0, 2.0)); + try std.testing.expectEqual(@as(f32, 0.0), fmod_f32(0.0, 2.0)); + try std.testing.expectEqual(@as(f32, -0.0), fmod_f32(-0.0, 2.0)); - try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, 10.0)); - try std.testing.expectEqual(@as(f32, -2.0), fmodf(-32.0, -10.0)); - try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, 10.0)); - try std.testing.expectEqual(@as(f32, 2.0), fmodf(32.0, -10.0)); + try std.testing.expectEqual(@as(f32, -2.0), fmod_f32(-32.0, 10.0)); + try std.testing.expectEqual(@as(f32, -2.0), fmod_f32(-32.0, -10.0)); + try std.testing.expectEqual(@as(f32, 2.0), fmod_f32(32.0, 10.0)); + try std.testing.expectEqual(@as(f32, 2.0), fmod_f32(32.0, -10.0)); } -test "fmod" { +test fmod_f64 { const nan_val = math.nan(f64); const inf_val = math.inf(f64); - try std.testing.expect(math.isNan(fmod(nan_val, 1.0))); - try std.testing.expect(math.isNan(fmod(1.0, nan_val))); - try std.testing.expect(math.isNan(fmod(inf_val, 1.0))); - try std.testing.expect(math.isNan(fmod(0.0, 0.0))); - try std.testing.expect(math.isNan(fmod(1.0, 0.0))); + try std.testing.expect(math.isNan(fmod_f64(nan_val, 1.0))); + try std.testing.expect(math.isNan(fmod_f64(1.0, nan_val))); + try std.testing.expect(math.isNan(fmod_f64(inf_val, 1.0))); + try std.testing.expect(math.isNan(fmod_f64(0.0, 0.0))); + try std.testing.expect(math.isNan(fmod_f64(1.0, 0.0))); - try std.testing.expectEqual(@as(f64, 0.0), fmod(0.0, 2.0)); - try std.testing.expectEqual(@as(f64, -0.0), fmod(-0.0, 2.0)); + try std.testing.expectEqual(@as(f64, 0.0), fmod_f64(0.0, 2.0)); + try std.testing.expectEqual(@as(f64, -0.0), fmod_f64(-0.0, 2.0)); - try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, 10.0)); - try std.testing.expectEqual(@as(f64, -2.0), fmod(-32.0, -10.0)); - try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, 10.0)); - try std.testing.expectEqual(@as(f64, 2.0), fmod(32.0, -10.0)); + try std.testing.expectEqual(@as(f64, -2.0), fmod_f64(-32.0, 10.0)); + try std.testing.expectEqual(@as(f64, -2.0), fmod_f64(-32.0, -10.0)); + try std.testing.expectEqual(@as(f64, 2.0), fmod_f64(32.0, 10.0)); + try std.testing.expectEqual(@as(f64, 2.0), fmod_f64(32.0, -10.0)); } test { diff --git a/lib/compiler_rt/fmodq_test.zig b/lib/compiler_rt/fmodq_test.zig index 07ddb8d182e41fe2ff80414aeff256728e1ce365..b98dc0762e664f09b0d648e290658bf4502da416 100644 --- a/lib/compiler_rt/fmodq_test.zig +++ b/lib/compiler_rt/fmodq_test.zig @@ -1,52 +1,52 @@ const std = @import("std"); -const fmod = @import("fmod.zig"); +const fmod_f128 = @import("fmod.zig").fmod_f128; const testing = std.testing; -fn test_fmodq(a: f128, b: f128, exp: f128) !void { - const res = fmod.fmodq(a, b); +fn test_fmod_f128(a: f128, b: f128, exp: f128) !void { + const res = fmod_f128(a, b); try testing.expect(exp == res); } -fn test_fmodq_nans() !void { - try testing.expect(std.math.isNan(fmod.fmodq(1.0, std.math.nan(f128)))); - try testing.expect(std.math.isNan(fmod.fmodq(1.0, -std.math.nan(f128)))); - try testing.expect(std.math.isNan(fmod.fmodq(std.math.nan(f128), 1.0))); - try testing.expect(std.math.isNan(fmod.fmodq(-std.math.nan(f128), 1.0))); +fn test_fmod_f128_nans() !void { + try testing.expect(std.math.isNan(fmod_f128(1.0, std.math.nan(f128)))); + try testing.expect(std.math.isNan(fmod_f128(1.0, -std.math.nan(f128)))); + try testing.expect(std.math.isNan(fmod_f128(std.math.nan(f128), 1.0))); + try testing.expect(std.math.isNan(fmod_f128(-std.math.nan(f128), 1.0))); } -fn test_fmodq_infs() !void { - try testing.expect(fmod.fmodq(1.0, std.math.inf(f128)) == 1.0); - try testing.expect(fmod.fmodq(1.0, -std.math.inf(f128)) == 1.0); - try testing.expect(std.math.isNan(fmod.fmodq(std.math.inf(f128), 1.0))); - try testing.expect(std.math.isNan(fmod.fmodq(-std.math.inf(f128), 1.0))); +fn test_fmod_f128_infs() !void { + try testing.expect(fmod_f128(1.0, std.math.inf(f128)) == 1.0); + try testing.expect(fmod_f128(1.0, -std.math.inf(f128)) == 1.0); + try testing.expect(std.math.isNan(fmod_f128(std.math.inf(f128), 1.0))); + try testing.expect(std.math.isNan(fmod_f128(-std.math.inf(f128), 1.0))); } -test "fmodq" { - try test_fmodq(6.8, 4.0, 2.8); - try test_fmodq(6.8, -4.0, 2.8); - try test_fmodq(-6.8, 4.0, -2.8); - try test_fmodq(-6.8, -4.0, -2.8); - try test_fmodq(3.0, 2.0, 1.0); - try test_fmodq(-5.0, 3.0, -2.0); - try test_fmodq(3.0, 2.0, 1.0); - try test_fmodq(1.0, 2.0, 1.0); - try test_fmodq(0.0, 1.0, 0.0); - try test_fmodq(-0.0, 1.0, -0.0); - try test_fmodq(7046119.0, 5558362.0, 1487757.0); - try test_fmodq(9010357.0, 1957236.0, 1181413.0); - try test_fmodq(5192296858534827628530496329220095, 10.0, 5.0); - try test_fmodq(5192296858534827628530496329220095, 922337203681230954775807, 220474884073715748246157); +test fmod_f128 { + try test_fmod_f128(6.8, 4.0, 2.8); + try test_fmod_f128(6.8, -4.0, 2.8); + try test_fmod_f128(-6.8, 4.0, -2.8); + try test_fmod_f128(-6.8, -4.0, -2.8); + try test_fmod_f128(3.0, 2.0, 1.0); + try test_fmod_f128(-5.0, 3.0, -2.0); + try test_fmod_f128(3.0, 2.0, 1.0); + try test_fmod_f128(1.0, 2.0, 1.0); + try test_fmod_f128(0.0, 1.0, 0.0); + try test_fmod_f128(-0.0, 1.0, -0.0); + try test_fmod_f128(7046119.0, 5558362.0, 1487757.0); + try test_fmod_f128(9010357.0, 1957236.0, 1181413.0); + try test_fmod_f128(5192296858534827628530496329220095, 10.0, 5.0); + try test_fmod_f128(5192296858534827628530496329220095, 922337203681230954775807, 220474884073715748246157); // Denormals const a1: f128 = 0xedcb34a235253948765432134674p-16494; const b1: f128 = 0x5d2e38791cfbc0737402da5a9518p-16494; const exp1: f128 = 0x336ec3affb2db8618e4e7d5e1c44p-16494; - try test_fmodq(a1, b1, exp1); + try test_fmod_f128(a1, b1, exp1); const a2: f128 = 0x0.7654_3210_fdec_ba98_7654_3210_fdecp-16382; const b2: f128 = 0x0.0012_fdac_bdef_1234_fdec_3222_1111p-16382; const exp2: f128 = 0x0.0001_aecd_9d66_4a6e_67b7_d7d0_a901p-16382; - try test_fmodq(a2, b2, exp2); + try test_fmod_f128(a2, b2, exp2); - try test_fmodq_nans(); - try test_fmodq_infs(); + try test_fmod_f128_nans(); + try test_fmod_f128_infs(); } diff --git a/lib/compiler_rt/fmodx_test.zig b/lib/compiler_rt/fmodx_test.zig index ca8229147ab693264b555676af664e7bf8acccbc..b32d354094ed97a1ab8d7c9d840610b9a8ac12a7 100644 --- a/lib/compiler_rt/fmodx_test.zig +++ b/lib/compiler_rt/fmodx_test.zig @@ -1,52 +1,52 @@ const std = @import("std"); const builtin = @import("builtin"); -const fmod = @import("fmod.zig"); +const fmod_f80 = @import("fmod.zig").fmod_f80; const testing = std.testing; -fn test_fmodx(a: f80, b: f80, exp: f80) !void { - const res = fmod.__fmodx(a, b); +fn test_fmod_f80(a: f80, b: f80, exp: f80) !void { + const res = fmod_f80(a, b); try testing.expect(exp == res); } -fn test_fmodx_nans() !void { - try testing.expect(std.math.isNan(fmod.__fmodx(1.0, std.math.nan(f80)))); - try testing.expect(std.math.isNan(fmod.__fmodx(1.0, -std.math.nan(f80)))); - try testing.expect(std.math.isNan(fmod.__fmodx(std.math.nan(f80), 1.0))); - try testing.expect(std.math.isNan(fmod.__fmodx(-std.math.nan(f80), 1.0))); +fn test_fmod_f80_nans() !void { + try testing.expect(std.math.isNan(fmod_f80(1.0, std.math.nan(f80)))); + try testing.expect(std.math.isNan(fmod_f80(1.0, -std.math.nan(f80)))); + try testing.expect(std.math.isNan(fmod_f80(std.math.nan(f80), 1.0))); + try testing.expect(std.math.isNan(fmod_f80(-std.math.nan(f80), 1.0))); } -fn test_fmodx_infs() !void { - try testing.expect(fmod.__fmodx(1.0, std.math.inf(f80)) == 1.0); - try testing.expect(fmod.__fmodx(1.0, -std.math.inf(f80)) == 1.0); - try testing.expect(std.math.isNan(fmod.__fmodx(std.math.inf(f80), 1.0))); - try testing.expect(std.math.isNan(fmod.__fmodx(-std.math.inf(f80), 1.0))); +fn test_fmod_f80_infs() !void { + try testing.expect(fmod_f80(1.0, std.math.inf(f80)) == 1.0); + try testing.expect(fmod_f80(1.0, -std.math.inf(f80)) == 1.0); + try testing.expect(std.math.isNan(fmod_f80(std.math.inf(f80), 1.0))); + try testing.expect(std.math.isNan(fmod_f80(-std.math.inf(f80), 1.0))); } -test "fmodx" { - try test_fmodx(6.4, 4.0, 2.4); - try test_fmodx(6.4, -4.0, 2.4); - try test_fmodx(-6.4, 4.0, -2.4); - try test_fmodx(-6.4, -4.0, -2.4); - try test_fmodx(3.0, 2.0, 1.0); - try test_fmodx(-5.0, 3.0, -2.0); - try test_fmodx(3.0, 2.0, 1.0); - try test_fmodx(1.0, 2.0, 1.0); - try test_fmodx(0.0, 1.0, 0.0); - try test_fmodx(-0.0, 1.0, -0.0); - try test_fmodx(7046119.0, 5558362.0, 1487757.0); - try test_fmodx(9010357.0, 1957236.0, 1181413.0); - try test_fmodx(9223372036854775807, 10.0, 7.0); +test fmod_f80 { + try test_fmod_f80(6.4, 4.0, 2.4); + try test_fmod_f80(6.4, -4.0, 2.4); + try test_fmod_f80(-6.4, 4.0, -2.4); + try test_fmod_f80(-6.4, -4.0, -2.4); + try test_fmod_f80(3.0, 2.0, 1.0); + try test_fmod_f80(-5.0, 3.0, -2.0); + try test_fmod_f80(3.0, 2.0, 1.0); + try test_fmod_f80(1.0, 2.0, 1.0); + try test_fmod_f80(0.0, 1.0, 0.0); + try test_fmod_f80(-0.0, 1.0, -0.0); + try test_fmod_f80(7046119.0, 5558362.0, 1487757.0); + try test_fmod_f80(9010357.0, 1957236.0, 1181413.0); + try test_fmod_f80(9223372036854775807, 10.0, 7.0); // Denormals const a1: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381; const b1: f80 = 0x0.2e97_1c3c_8e7d_e03ap-16381; const exp1: f80 = 0x0.19b7_61d7_fd96_dc30p-16381; - try test_fmodx(a1, b1, exp1); + try test_fmod_f80(a1, b1, exp1); const a2: f80 = 0x0.76e5_9a51_1a92_9ca4p-16381; const b2: f80 = 0x0.0e97_1c3c_8e7d_e03ap-16381; const exp2: f80 = 0x0.022c_b86c_a6a3_9ad4p-16381; - try test_fmodx(a2, b2, exp2); + try test_fmod_f80(a2, b2, exp2); - try test_fmodx_nans(); - try test_fmodx_infs(); + try test_fmod_f80_nans(); + try test_fmod_f80_infs(); } diff --git a/lib/compiler_rt/gedf2.zig b/lib/compiler_rt/gedf2.zig deleted file mode 100644 index f6b4b6d718fd20d8068244cfa6250f030f890e92..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/gedf2.zig +++ /dev/null @@ -1,35 +0,0 @@ -///! The quoted behavior definitions are from -///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines -const compiler_rt = @import("../compiler_rt.zig"); -const comparef = @import("./comparef.zig"); -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_dcmpge, "__aeabi_dcmpge"); - symbol(&__aeabi_dcmpgt, "__aeabi_dcmpgt"); - } else { - symbol(&__gedf2, "__gedf2"); - symbol(&__gtdf2, "__gtdf2"); - } -} - -/// "These functions return a value greater than or equal to zero if neither -/// argument is NaN, and a is greater than or equal to b." -pub fn __gedf2(a: f64, b: f64) callconv(.c) i32 { - return @backingInt(comparef.cmpf2(f64, comparef.GE, a, b)); -} - -/// "These functions return a value greater than zero if neither argument is NaN, -/// and a is strictly greater than b." -pub fn __gtdf2(a: f64, b: f64) callconv(.c) i32 { - return __gedf2(a, b); -} - -fn __aeabi_dcmpge(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { - return @intFromBool(comparef.cmpf2(f64, comparef.GE, a, b) != .Less); -} - -fn __aeabi_dcmpgt(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { - return @intFromBool(comparef.cmpf2(f64, comparef.GE, a, b) == .Greater); -} diff --git a/lib/compiler_rt/gehf2.zig b/lib/compiler_rt/gehf2.zig deleted file mode 100644 index 8008a06849887d2f317be4517a5cb6c485c2675a..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/gehf2.zig +++ /dev/null @@ -1,21 +0,0 @@ -///! The quoted behavior definitions are from -///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines -const symbol = @import("../compiler_rt.zig").symbol; -const comparef = @import("./comparef.zig"); - -comptime { - symbol(&__gehf2, "__gehf2"); - symbol(&__gthf2, "__gthf2"); -} - -/// "These functions return a value greater than or equal to zero if neither -/// argument is NaN, and a is greater than or equal to b." -pub fn __gehf2(a: f16, b: f16) callconv(.c) i32 { - return @backingInt(comparef.cmpf2(f16, comparef.GE, a, b)); -} - -/// "These functions return a value greater than zero if neither argument is NaN, -/// and a is strictly greater than b." -pub fn __gthf2(a: f16, b: f16) callconv(.c) i32 { - return __gehf2(a, b); -} diff --git a/lib/compiler_rt/gesf2.zig b/lib/compiler_rt/gesf2.zig deleted file mode 100644 index 7f5022104eba9378efe6184befcd7f40f479306f..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/gesf2.zig +++ /dev/null @@ -1,35 +0,0 @@ -///! The quoted behavior definitions are from -///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const comparef = @import("./comparef.zig"); - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_fcmpge, "__aeabi_fcmpge"); - symbol(&__aeabi_fcmpgt, "__aeabi_fcmpgt"); - } else { - symbol(&__gesf2, "__gesf2"); - symbol(&__gtsf2, "__gtsf2"); - } -} - -/// "These functions return a value greater than or equal to zero if neither -/// argument is NaN, and a is greater than or equal to b." -pub fn __gesf2(a: f32, b: f32) callconv(.c) i32 { - return @backingInt(comparef.cmpf2(f32, comparef.GE, a, b)); -} - -/// "These functions return a value greater than zero if neither argument is NaN, -/// and a is strictly greater than b." -pub fn __gtsf2(a: f32, b: f32) callconv(.c) i32 { - return __gesf2(a, b); -} - -fn __aeabi_fcmpge(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { - return @intFromBool(comparef.cmpf2(f32, comparef.GE, a, b) != .Less); -} - -fn __aeabi_fcmpgt(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) i32 { - return @intFromBool(comparef.cmpf2(f32, comparef.LE, a, b) == .Greater); -} diff --git a/lib/compiler_rt/getf2.zig b/lib/compiler_rt/getf2.zig deleted file mode 100644 index 88a91600f1e32c5f7124f5e9be9d5828b2471f2e..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/getf2.zig +++ /dev/null @@ -1,26 +0,0 @@ -///! The quoted behavior definitions are from -///! https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gccint/Soft-float-library-routines.html#Soft-float-library-routines -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const comparef = @import("./comparef.zig"); - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__getf2, "__gekf2"); - symbol(&__gttf2, "__gtkf2"); - } - symbol(&__getf2, "__getf2"); - symbol(&__gttf2, "__gttf2"); -} - -/// "These functions return a value greater than or equal to zero if neither -/// argument is NaN, and a is greater than or equal to b." -fn __getf2(a: f128, b: f128) callconv(.c) i32 { - return @backingInt(comparef.cmpf2(f128, comparef.GE, a, b)); -} - -/// "These functions return a value greater than zero if neither argument is NaN, -/// and a is strictly greater than b." -fn __gttf2(a: f128, b: f128) callconv(.c) i32 { - return __getf2(a, b); -} diff --git a/lib/compiler_rt/gexf2.zig b/lib/compiler_rt/gexf2.zig deleted file mode 100644 index 9f1f356187cdf9c7b85be2d49f9e2e73439f381b..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/gexf2.zig +++ /dev/null @@ -1,15 +0,0 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const comparef = @import("./comparef.zig"); - -comptime { - symbol(&__gexf2, "__gexf2"); - symbol(&__gtxf2, "__gtxf2"); -} - -fn __gexf2(a: f80, b: f80) callconv(.c) i32 { - return @backingInt(comparef.cmp_f80(comparef.GE, a, b)); -} - -fn __gtxf2(a: f80, b: f80) callconv(.c) i32 { - return __gexf2(a, b); -} diff --git a/lib/compiler_rt/int.zig b/lib/compiler_rt/int.zig index 48c900207bce8946adf6bb9cafe9407b214946d4..e387be858213a7afb575bd3b81f62e016e16a19e 100644 --- a/lib/compiler_rt/int.zig +++ b/lib/compiler_rt/int.zig @@ -36,7 +36,7 @@ comptime { pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.c) i128 { const d = __divti3(a, b); - rem.* = a -% (d * b); + rem.* = a - d *% b; return d; } @@ -69,7 +69,7 @@ fn test_one_divmodti4(a: i128, b: i128, expected_q: i128, expected_r: i128) !voi pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.c) i64 { const d = __divdi3(a, b); - rem.* = a -% (d * b); + rem.* = a - d *% b; return d; } @@ -79,21 +79,20 @@ fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void { try testing.expect(q == expected_q and r == expected_r); } -const cases__divmoddi4 = - [_][4]i64{ - [_]i64{ 0, 1, 0, 0 }, - [_]i64{ 0, -1, 0, 0 }, - [_]i64{ 2, 1, 2, 0 }, - [_]i64{ 2, -1, -2, 0 }, - [_]i64{ -2, 1, -2, 0 }, - [_]i64{ -2, -1, 2, 0 }, - [_]i64{ 7, 5, 1, 2 }, - [_]i64{ -7, 5, -1, -2 }, - [_]i64{ 19, 5, 3, 4 }, - [_]i64{ 19, -5, -3, 4 }, - [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 }, - [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 }, - }; +const cases__divmoddi4 = [_][4]i64{ + [_]i64{ 0, 1, 0, 0 }, + [_]i64{ 0, -1, 0, 0 }, + [_]i64{ 2, 1, 2, 0 }, + [_]i64{ 2, -1, -2, 0 }, + [_]i64{ -2, 1, -2, 0 }, + [_]i64{ -2, -1, 2, 0 }, + [_]i64{ 7, 5, 1, 2 }, + [_]i64{ -7, 5, -1, -2 }, + [_]i64{ 19, 5, 3, 4 }, + [_]i64{ 19, -5, -3, 4 }, + [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 }, + [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 }, +}; test "test_divmoddi4" { for (cases__divmoddi4) |case| { @@ -105,10 +104,6 @@ pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.c) u64 { return udivmod(u64, a, b, maybe_rem); } -test "test_udivmoddi4" { - _ = @import("udivmoddi4_test.zig"); -} - pub fn __divdi3(a: i64, b: i64) callconv(.c) i64 { // Set aside the sign of the quotient. const sign: u64 = @bitCast((a ^ b) >> 63); @@ -209,25 +204,24 @@ fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) !void { pub fn __divmodsi4(a: i32, b: i32, rem: *i32) callconv(.c) i32 { const d = __divsi3(a, b); - rem.* = a -% (d * b); + rem.* = a - d *% b; return d; } -const cases__divmodsi4 = - [_][4]i32{ - [_]i32{ 0, 1, 0, 0 }, - [_]i32{ 0, -1, 0, 0 }, - [_]i32{ 2, 1, 2, 0 }, - [_]i32{ 2, -1, -2, 0 }, - [_]i32{ -2, 1, -2, 0 }, - [_]i32{ -2, -1, 2, 0 }, - [_]i32{ 7, 5, 1, 2 }, - [_]i32{ -7, 5, -1, -2 }, - [_]i32{ 19, 5, 3, 4 }, - [_]i32{ 19, -5, -3, 4 }, - [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 }, - [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 }, - }; +const cases__divmodsi4 = [_][4]i32{ + [_]i32{ 0, 1, 0, 0 }, + [_]i32{ 0, -1, 0, 0 }, + [_]i32{ 2, 1, 2, 0 }, + [_]i32{ 2, -1, -2, 0 }, + [_]i32{ -2, 1, -2, 0 }, + [_]i32{ -2, -1, 2, 0 }, + [_]i32{ 7, 5, 1, 2 }, + [_]i32{ -7, 5, -1, -2 }, + [_]i32{ 19, 5, 3, 4 }, + [_]i32{ 19, -5, -3, 4 }, + [_]i32{ @bitCast(@as(u32, 0x80000000)), 8, @bitCast(@as(u32, 0xf0000000)), 0 }, + [_]i32{ @bitCast(@as(u32, 0x80000007)), 8, @bitCast(@as(u32, 0xf0000001)), -1 }, +}; fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void { var r: i32 = undefined; @@ -243,7 +237,7 @@ test "test_divmodsi4" { pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.c) u32 { const d = __udivsi3(a, b); - rem.* = @bitCast(@as(i32, @bitCast(a)) -% (@as(i32, @bitCast(d)) * @as(i32, @bitCast(b)))); + rem.* = a - d * b; return d; } @@ -486,7 +480,7 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void { } pub fn __modsi3(n: i32, d: i32) callconv(.c) i32 { - return n -% __divsi3(n, d) * d; + return n - __divsi3(n, d) *% d; } test "test_modsi3" { @@ -515,7 +509,7 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void { } pub fn __umodsi3(n: u32, d: u32) callconv(.c) u32 { - return n -% __udivsi3(n, d) * d; + return n - __udivsi3(n, d) * d; } test "test_umodsi3" { @@ -663,3 +657,8 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void { const r: u32 = __umodsi3(a, b); try testing.expect(r == expected_r); } + +test { + _ = @import("udivmodsi4_test.zig"); + _ = @import("udivmoddi4_test.zig"); +} diff --git a/lib/compiler_rt/int_from_float.zig b/lib/compiler_rt/int_from_float.zig index 5445e7fb7c6d36111d89112350b5bfc9ced375c8..8eb4c2fcbc79f9d254255372062e473443bffdde 100644 --- a/lib/compiler_rt/int_from_float.zig +++ b/lib/compiler_rt/int_from_float.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("std"); const math = std.math; const Log2Int = std.math.Log2Int; @@ -6,29 +7,532 @@ const compiler_rt = @import("../compiler_rt.zig"); const symbol = compiler_rt.symbol; comptime { - symbol(&__fixxfti, "__fixxfti"); symbol(&__fixhfsi, "__fixhfsi"); symbol(&__fixhfdi, "__fixhfdi"); symbol(&__fixhfti, "__fixhfti"); + symbol(&__fixhfei, "__fixhfei"); + + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_f2iz, "__aeabi_f2iz"); + symbol(&__aeabi_f2lz, "__aeabi_f2lz"); + symbol(&__aeabi_fixsfti, "__fixsfti"); + } else { + symbol(&__fixsfsi, "__fixsfsi"); + symbol(&__fixsfdi, "__fixsfdi"); + if (compiler_rt.want_windows_arm_abi) symbol(&__fixsfdi, "__stoi64"); + symbol(&__fixsfti, "__fixsfti"); + } + symbol(&__fixsfei, "__fixsfei"); + + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_d2iz, "__aeabi_d2iz"); + symbol(&__aeabi_d2lz, "__aeabi_d2lz"); + symbol(&__aeabi_fixdfti, "__fixdfti"); + } else { + symbol(&__fixdfsi, "__fixdfsi"); + symbol(&__fixdfdi, "__fixdfdi"); + if (compiler_rt.want_windows_arm_abi) symbol(&__fixdfdi, "__dtoi64"); + symbol(&__fixdfti, "__fixdfti"); + } + symbol(&__fixdfei, "__fixdfei"); + + symbol(&__fixxfsi, "__fixxfsi"); + symbol(&__fixxfdi, "__fixxfdi"); + symbol(&__fixxfti, "__fixxfti"); + symbol(&__fixxfei, "__fixxfei"); + + if (compiler_rt.want_ppc_abi) { + symbol(&__fixtfsi, "__fixkfsi"); + symbol(&__fixtfdi, "__fixkfdi"); + } else if (compiler_rt.want_sparc64_abi) { + symbol(&_Qp_qtoi, "_Qp_qtoi"); + symbol(&_Qp_qtox, "_Qp_qtox"); + } else if (compiler_rt.want_sparc32_abi) { + symbol(&__fixtfsi, "_Q_qtoi"); + symbol(&__fixtfdi, "_Q_qtoll"); + } else { + symbol(&__fixtfsi, "__fixtfsi"); + symbol(&__fixtfdi, "__fixtfdi"); + } + if (compiler_rt.want_ppc_abi) { + symbol(&__fixtfti, "__fixkfti"); + symbol(&__fixtfei, "__fixkfei"); + } else { + symbol(&__fixtfti, "__fixtfti"); + symbol(&__fixtfei, "__fixtfei"); + } +} + +fn __fixhfsi(a: compiler_rt.f16.Abi) callconv(.c) i32 { + return i32_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); +} +pub fn i32_intFromFloat_f16(a: f16) i32 { + return intFromFloat(i32, a); } -pub fn __fixhfti(a: f16) callconv(.c) i128 { +fn __fixhfdi(a: compiler_rt.f16.Abi) callconv(.c) i64 { + return i64_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); +} +pub fn i64_intFromFloat_f16(a: f16) i64 { + return intFromFloat(i64, a); +} + +fn __fixhfti(a: compiler_rt.f16.Abi) callconv(.c) i128 { + return i128_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); +} +pub fn i128_intFromFloat_f16(a: f16) i128 { return intFromFloat(i128, a); } -fn __fixhfdi(a: f16) callconv(.c) i64 { +fn __fixhfei(r: [*]u8, bits: usize, a: compiler_rt.f16.Abi) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return signed_intFromFloat_f16(r[0..byte_size], compiler_rt.f16.fromAbi(a)); +} +pub fn signed_intFromFloat_f16(result: []u8, a: f16) void { + bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); +} + +fn __fixsfsi(a: compiler_rt.f32.Abi) callconv(.c) i32 { + return i32_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); +} +fn __aeabi_f2iz(a: f32) callconv(.{ .arm_aapcs = .{} }) i32 { + return i32_intFromFloat_f32(a); +} +pub fn i32_intFromFloat_f32(a: f32) i32 { + return intFromFloat(i32, a); +} + +fn __fixsfdi(a: compiler_rt.f32.Abi) callconv(.c) i64 { + return i64_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); +} +fn __aeabi_f2lz(a: f32) callconv(.{ .arm_aapcs = .{} }) i64 { + return i64_intFromFloat_f32(a); +} +pub fn i64_intFromFloat_f32(a: f32) i64 { return intFromFloat(i64, a); } -fn __fixhfsi(a: f16) callconv(.c) i32 { +fn __fixsfti(a: compiler_rt.f32.Abi) callconv(.c) i128 { + return i128_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); +} +fn __aeabi_fixsfti(_: compiler_rt.f32.Abi) callconv(.naked) i128 { + switch (builtin.abi.float()) { + .soft => asm volatile ( + \\ push {r0-r4, lr} + \\ mov r1, r0 + \\ mov r0, sp + \\ bl %[__fixsfti] + \\ pop {r0-r4, pc} + : + : [__fixsfti] "X" (&__fixsfti), + ), + .hard => asm volatile ( + \\ push {r0-r4, lr} + \\ mov r0, sp + \\ bl %[__fixsfti] + \\ pop {r0-r4, pc} + : + : [__fixsfti] "X" (&__fixsfti), + ), + } +} +pub fn i128_intFromFloat_f32(a: f32) i128 { + return intFromFloat(i128, a); +} + +fn __fixsfei(r: [*]u8, bits: usize, a: compiler_rt.f32.Abi) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return signed_intFromFloat_f32(r[0..byte_size], compiler_rt.f32.fromAbi(a)); +} +pub fn signed_intFromFloat_f32(result: []u8, a: f32) void { + bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); +} + +fn __fixdfsi(a: compiler_rt.f64.Abi) callconv(.c) i32 { + return i32_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); +} +fn __aeabi_d2iz(a: f64) callconv(.{ .arm_aapcs = .{} }) i32 { + return i32_intFromFloat_f64(a); +} +pub fn i32_intFromFloat_f64(a: f64) i32 { return intFromFloat(i32, a); } -pub fn __fixxfti(a: f80) callconv(.c) i128 { +fn __fixdfdi(a: compiler_rt.f64.Abi) callconv(.c) i64 { + return i64_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); +} +fn __aeabi_d2lz(a: f64) callconv(.{ .arm_aapcs = .{} }) i64 { + return i64_intFromFloat_f64(a); +} +pub fn i64_intFromFloat_f64(a: f64) i64 { + return intFromFloat(i64, a); +} + +fn __fixdfti(a: compiler_rt.f64.Abi) callconv(.c) i128 { + return i128_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); +} +fn __aeabi_fixdfti(_: compiler_rt.f64.Abi) callconv(.naked) i128 { + switch (builtin.abi.float()) { + .soft => asm volatile ( + \\ push {r0-r4, lr} + \\ mov r3, r1 + \\ mov r2, r0 + \\ mov r0, sp + \\ bl %[__fixdfti] + \\ pop {r0-r4, pc} + : + : [__fixdfti] "X" (&__fixdfti), + ), + .hard => asm volatile ( + \\ push {r0-r4, lr} + \\ mov r0, sp + \\ bl %[__fixdfti] + \\ pop {r0-r4, pc} + : + : [__fixdfti] "X" (&__fixdfti), + ), + } +} +pub fn i128_intFromFloat_f64(a: f64) i128 { return intFromFloat(i128, a); } -pub inline fn intFromFloat(comptime I: type, a: anytype) I { +fn __fixdfei(r: [*]u8, bits: usize, a: compiler_rt.f64.Abi) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return signed_intFromFloat_f64(r[0..byte_size], compiler_rt.f64.fromAbi(a)); +} +pub fn signed_intFromFloat_f64(result: []u8, a: f64) void { + bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); +} + +fn __fixxfsi(a: compiler_rt.f80.Abi) callconv(.c) i32 { + return i32_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); +} +pub fn i32_intFromFloat_f80(a: f80) i32 { + return intFromFloat(i32, a); +} + +fn __fixxfdi(a: compiler_rt.f80.Abi) callconv(.c) i64 { + return i64_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); +} +pub fn i64_intFromFloat_f80(a: f80) i64 { + return intFromFloat(i64, a); +} + +fn __fixxfti(a: compiler_rt.f80.Abi) callconv(.c) i128 { + return i128_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); +} +pub fn i128_intFromFloat_f80(a: f80) i128 { + return intFromFloat(i128, a); +} + +fn __fixxfei(r: [*]u8, bits: usize, a: compiler_rt.f80.Abi) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return signed_intFromFloat_f80(r[0..byte_size], compiler_rt.f80.fromAbi(a)); +} +pub fn signed_intFromFloat_f80(result: []u8, a: f80) void { + bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); +} + +fn __fixtfsi(a: compiler_rt.f128.Abi) callconv(.c) i32 { + return i32_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); +} +fn _Qp_qtoi(a: *const f128) callconv(.c) i32 { + return i32_intFromFloat_f128(a.*); +} +pub fn i32_intFromFloat_f128(a: f128) i32 { + return intFromFloat(i32, a); +} + +fn __fixtfdi(a: compiler_rt.f128.Abi) callconv(.c) i64 { + return i64_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); +} +fn _Qp_qtox(a: *const f128) callconv(.c) i64 { + return i64_intFromFloat_f128(a.*); +} +pub fn i64_intFromFloat_f128(a: f128) i64 { + return intFromFloat(i64, a); +} + +fn __fixtfti(a: compiler_rt.f128.Abi) callconv(.c) i128 { + return i128_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); +} +pub fn i128_intFromFloat_f128(a: f128) i128 { + return intFromFloat(i128, a); +} + +fn __fixtfei(r: [*]u8, bits: usize, a: compiler_rt.f128.Abi) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return signed_intFromFloat_f128(r[0..byte_size], compiler_rt.f128.fromAbi(a)); +} +pub fn signed_intFromFloat_f128(result: []u8, a: f128) void { + bigIntFromFloat(.signed, @ptrCast(@alignCast(result)), a); +} + +comptime { + symbol(&__fixunshfsi, "__fixunshfsi"); + symbol(&__fixunshfdi, "__fixunshfdi"); + symbol(&__fixunshfti, "__fixunshfti"); + symbol(&__fixunshfei, "__fixunshfei"); + + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_f2uiz, "__aeabi_f2uiz"); + symbol(&__aeabi_f2ulz, "__aeabi_f2ulz"); + symbol(&__aeabi_fixunssfti, "__fixunssfti"); + } else { + symbol(&__fixunssfsi, "__fixunssfsi"); + symbol(&__fixunssfdi, "__fixunssfdi"); + if (compiler_rt.want_windows_arm_abi) symbol(&__fixunssfdi, "__stou64"); + symbol(&__fixunssfti, "__fixunssfti"); + } + symbol(&__fixunssfei, "__fixunssfei"); + + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_d2uiz, "__aeabi_d2uiz"); + symbol(&__aeabi_d2ulz, "__aeabi_d2ulz"); + symbol(&__aeabi_fixunsdfti, "__fixunsdfti"); + } else { + symbol(&__fixunsdfsi, "__fixunsdfsi"); + symbol(&__fixunsdfdi, "__fixunsdfdi"); + if (compiler_rt.want_windows_arm_abi) symbol(&__fixunsdfdi, "__dtou64"); + symbol(&__fixunsdfti, "__fixunsdfti"); + } + symbol(&__fixunsdfei, "__fixunsdfei"); + + symbol(&__fixunsxfsi, "__fixunsxfsi"); + symbol(&__fixunsxfdi, "__fixunsxfdi"); + symbol(&__fixunsxfti, "__fixunsxfti"); + symbol(&__fixunsxfei, "__fixunsxfei"); + + if (compiler_rt.want_ppc_abi) { + symbol(&__fixunstfsi, "__fixunskfsi"); + symbol(&__fixunstfdi, "__fixunskfdi"); + } else if (compiler_rt.want_sparc64_abi) { + symbol(&_Qp_qtoui, "_Qp_qtoui"); + symbol(&_Qp_qtoux, "_Qp_qtoux"); + } else if (compiler_rt.want_sparc32_abi) { + symbol(&__fixunstfsi, "_Q_qtou"); + symbol(&__fixunstfdi, "_Q_qtoull"); + } else { + symbol(&__fixunstfsi, "__fixunstfsi"); + symbol(&__fixunstfdi, "__fixunstfdi"); + } + if (compiler_rt.want_ppc_abi) { + symbol(&__fixunstfti, "__fixunskfti"); + symbol(&__fixunstfei, "__fixunskfei"); + } else { + symbol(&__fixunstfti, "__fixunstfti"); + symbol(&__fixunstfei, "__fixunstfei"); + } +} + +fn __fixunshfsi(a: compiler_rt.f16.Abi) callconv(.c) u32 { + return u32_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); +} +pub fn u32_intFromFloat_f16(a: f16) u32 { + return intFromFloat(u32, a); +} + +fn __fixunshfdi(a: compiler_rt.f16.Abi) callconv(.c) u64 { + return u64_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); +} +pub fn u64_intFromFloat_f16(a: f16) u64 { + return intFromFloat(u64, a); +} + +fn __fixunshfti(a: compiler_rt.f16.Abi) callconv(.c) u128 { + return u128_intFromFloat_f16(compiler_rt.f16.fromAbi(a)); +} +pub fn u128_intFromFloat_f16(a: f16) u128 { + return intFromFloat(u128, a); +} + +fn __fixunshfei(r: [*]u8, bits: usize, a: compiler_rt.f16.Abi) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return unsigned_intFromFloat_f16(r[0..byte_size], compiler_rt.f16.fromAbi(a)); +} +pub fn unsigned_intFromFloat_f16(result: []u8, a: f16) void { + bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); +} + +fn __fixunssfsi(a: compiler_rt.f32.Abi) callconv(.c) u32 { + return u32_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); +} +fn __aeabi_f2uiz(a: f32) callconv(.{ .arm_aapcs = .{} }) u32 { + return u32_intFromFloat_f32(a); +} +pub fn u32_intFromFloat_f32(a: f32) u32 { + return intFromFloat(u32, a); +} + +fn __fixunssfdi(a: compiler_rt.f32.Abi) callconv(.c) u64 { + return u64_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); +} +fn __aeabi_f2ulz(a: f32) callconv(.{ .arm_aapcs = .{} }) u64 { + return u64_intFromFloat_f32(a); +} +pub fn u64_intFromFloat_f32(a: f32) u64 { + return intFromFloat(u64, a); +} + +fn __fixunssfti(a: compiler_rt.f32.Abi) callconv(.c) u128 { + return u128_intFromFloat_f32(compiler_rt.f32.fromAbi(a)); +} +fn __aeabi_fixunssfti(_: compiler_rt.f32.Abi) callconv(.naked) u128 { + switch (builtin.abi.float()) { + .soft => asm volatile ( + \\ push {r0-r4, lr} + \\ mov r1, r0 + \\ mov r0, sp + \\ bl %[__fixunssfti] + \\ pop {r0-r4, pc} + : + : [__fixunssfti] "X" (&__fixunssfti), + ), + .hard => asm volatile ( + \\ push {r0-r4, lr} + \\ mov r0, sp + \\ bl %[__fixunssfti] + \\ pop {r0-r4, pc} + : + : [__fixunssfti] "X" (&__fixunssfti), + ), + } +} +pub fn u128_intFromFloat_f32(a: f32) u128 { + return intFromFloat(u128, a); +} + +fn __fixunssfei(r: [*]u8, bits: usize, a: compiler_rt.f32.Abi) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return unsigned_intFromFloat_f32(r[0..byte_size], compiler_rt.f32.fromAbi(a)); +} +pub fn unsigned_intFromFloat_f32(result: []u8, a: f32) void { + bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); +} + +fn __fixunsdfsi(a: compiler_rt.f64.Abi) callconv(.c) u32 { + return u32_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); +} +fn __aeabi_d2uiz(a: f64) callconv(.{ .arm_aapcs = .{} }) u32 { + return u32_intFromFloat_f64(a); +} +pub fn u32_intFromFloat_f64(a: f64) u32 { + return intFromFloat(u32, a); +} + +fn __fixunsdfdi(a: compiler_rt.f64.Abi) callconv(.c) u64 { + return u64_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); +} +fn __aeabi_d2ulz(a: f64) callconv(.{ .arm_aapcs = .{} }) u64 { + return u64_intFromFloat_f64(a); +} +pub fn u64_intFromFloat_f64(a: f64) u64 { + return intFromFloat(u64, a); +} + +fn __fixunsdfti(a: compiler_rt.f64.Abi) callconv(.c) u128 { + return u128_intFromFloat_f64(compiler_rt.f64.fromAbi(a)); +} +fn __aeabi_fixunsdfti(_: compiler_rt.f64.Abi) callconv(.naked) u128 { + switch (builtin.abi.float()) { + .soft => asm volatile ( + \\ push {r0-r4, lr} + \\ mov r3, r1 + \\ mov r2, r0 + \\ mov r0, sp + \\ bl %[__fixunsdfti] + \\ pop {r0-r4, pc} + : + : [__fixunsdfti] "X" (&__fixunsdfti), + ), + .hard => asm volatile ( + \\ push {r0-r4, lr} + \\ mov r0, sp + \\ bl %[__fixunsdfti] + \\ pop {r0-r4, pc} + : + : [__fixunsdfti] "X" (&__fixunsdfti), + ), + } +} +pub fn u128_intFromFloat_f64(a: f64) u128 { + return intFromFloat(u128, a); +} + +fn __fixunsdfei(r: [*]u8, bits: usize, a: compiler_rt.f64.Abi) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return unsigned_intFromFloat_f64(r[0..byte_size], compiler_rt.f64.fromAbi(a)); +} +pub fn unsigned_intFromFloat_f64(result: []u8, a: f64) void { + bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); +} + +fn __fixunsxfsi(a: compiler_rt.f80.Abi) callconv(.c) u32 { + return u32_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); +} +pub fn u32_intFromFloat_f80(a: f80) u32 { + return intFromFloat(u32, a); +} + +fn __fixunsxfdi(a: compiler_rt.f80.Abi) callconv(.c) u64 { + return u64_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); +} +pub fn u64_intFromFloat_f80(a: f80) u64 { + return intFromFloat(u64, a); +} + +fn __fixunsxfti(a: compiler_rt.f80.Abi) callconv(.c) u128 { + return u128_intFromFloat_f80(compiler_rt.f80.fromAbi(a)); +} +pub fn u128_intFromFloat_f80(a: f80) u128 { + return intFromFloat(u128, a); +} + +fn __fixunsxfei(r: [*]u8, bits: usize, a: compiler_rt.f80.Abi) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return unsigned_intFromFloat_f80(r[0..byte_size], compiler_rt.f80.fromAbi(a)); +} +pub fn unsigned_intFromFloat_f80(result: []u8, a: f80) void { + bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); +} + +fn __fixunstfsi(a: compiler_rt.f128.Abi) callconv(.c) u32 { + return u32_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); +} +fn _Qp_qtoui(a: *const f128) callconv(.c) u32 { + return u32_intFromFloat_f128(a.*); +} +pub fn u32_intFromFloat_f128(a: f128) u32 { + return intFromFloat(u32, a); +} + +fn __fixunstfdi(a: compiler_rt.f128.Abi) callconv(.c) u64 { + return u64_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); +} +fn _Qp_qtoux(a: *const f128) callconv(.c) u64 { + return u64_intFromFloat_f128(a.*); +} +pub fn u64_intFromFloat_f128(a: f128) u64 { + return intFromFloat(u64, a); +} + +fn __fixunstfti(a: compiler_rt.f128.Abi) callconv(.c) u128 { + return u128_intFromFloat_f128(compiler_rt.f128.fromAbi(a)); +} +pub fn u128_intFromFloat_f128(a: f128) u128 { + return intFromFloat(u128, a); +} + +fn __fixunstfei(r: [*]u8, bits: usize, a: compiler_rt.f128.Abi) callconv(.c) void { + const byte_size = std.zig.target.intByteSize(&builtin.target, @intCast(bits)); + return unsigned_intFromFloat_f128(r[0..byte_size], compiler_rt.f128.fromAbi(a)); +} +pub fn unsigned_intFromFloat_f128(result: []u8, a: f128) void { + bigIntFromFloat(.unsigned, @ptrCast(@alignCast(result)), a); +} + +inline fn intFromFloat(comptime I: type, a: anytype) I { const F = @TypeOf(a); const float_bits = @typeInfo(F).float.bits; const int_bits = @typeInfo(I).int.bits; @@ -76,13 +580,14 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I { return result; } -pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, result: []u32, a: anytype) void { +inline fn bigIntFromFloat(comptime signedness: std.lang.Signedness, result: []u32, a: anytype) void { + const endian = builtin.cpu.arch.endian(); switch (result.len) { 0 => return, inline 1...4 => |limbs_len| { const I = @Int(signedness, 32 * limbs_len); const low_to_high: [limbs_len]u32 = @bitCast(@as(I, @intFromFloat(a))); - result[0..limbs_len].* = switch (@import("builtin").cpu.arch.endian()) { + result[0..limbs_len].* = switch (endian) { .little => low_to_high, .big => switch (limbs_len) { 1 => .{low_to_high[0]}, @@ -111,7 +616,6 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul }); switch (signedness) { .signed => { - const endian = @import("builtin").cpu.arch.endian(); const exponent_limb = switch (endian) { .little => exponent / 32, .big => result.len - 1 - exponent / 32, diff --git a/lib/compiler_rt/int_from_float_test.zig b/lib/compiler_rt/int_from_float_test.zig index de96954dd15474c6d9f9c5109c717b3d5b6417c2..23f04e2b88a2a01756ad608cb2d9774b54d38c25 100644 --- a/lib/compiler_rt/int_from_float_test.zig +++ b/lib/compiler_rt/int_from_float_test.zig @@ -2,1023 +2,1039 @@ const std = @import("std"); const testing = std.testing; const math = std.math; -const __fixunshfti = @import("fixunshfti.zig").__fixunshfti; -const __fixunsxfti = @import("fixunsxfti.zig").__fixunsxfti; - -// Conversion from f32 -const __fixsfsi = @import("fixsfsi.zig").__fixsfsi; -const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi; -const __fixsfdi = @import("fixsfdi.zig").__fixsfdi; -const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi; -const __fixsfti = @import("fixsfti.zig").__fixsfti; -const __fixunssfti = @import("fixunssfti.zig").__fixunssfti; -const __fixsfei = @import("fixsfei.zig").__fixsfei; -const __fixunssfei = @import("fixunssfei.zig").__fixunssfei; - -// Conversion from f64 -const __fixdfsi = @import("fixdfsi.zig").__fixdfsi; -const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi; -const __fixdfdi = @import("fixdfdi.zig").__fixdfdi; -const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi; -const __fixdfti = @import("fixdfti.zig").__fixdfti; -const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti; -const __fixdfei = @import("fixdfei.zig").__fixdfei; -const __fixunsdfei = @import("fixunsdfei.zig").__fixunsdfei; - -// Conversion from f128 -const __fixtfsi = @import("fixtfsi.zig").__fixtfsi; -const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi; -const __fixtfdi = @import("fixtfdi.zig").__fixtfdi; -const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi; -const __fixtfti = @import("fixtfti.zig").__fixtfti; -const __fixunstfti = @import("fixunstfti.zig").__fixunstfti; - -fn test__fixsfsi(a: f32, expected: i32) !void { - const x = __fixsfsi(a); +const impl = @import("int_from_float.zig"); + +const i32_intFromFloat_f16 = impl.i32_intFromFloat_f16; +const u32_intFromFloat_f16 = impl.u32_intFromFloat_f16; +const i64_intFromFloat_f16 = impl.i64_intFromFloat_f16; +const u64_intFromFloat_f16 = impl.u64_intFromFloat_f16; +const i128_intFromFloat_f16 = impl.i128_intFromFloat_f16; +const u128_intFromFloat_f16 = impl.u128_intFromFloat_f16; +const signed_intFromFloat_f16 = impl.signed_intFromFloat_f16; +const unsigned_intFromFloat_f16 = impl.unsigned_intFromFloat_f16; + +const i32_intFromFloat_f32 = impl.i32_intFromFloat_f32; +const u32_intFromFloat_f32 = impl.u32_intFromFloat_f32; +const i64_intFromFloat_f32 = impl.i64_intFromFloat_f32; +const u64_intFromFloat_f32 = impl.u64_intFromFloat_f32; +const i128_intFromFloat_f32 = impl.i128_intFromFloat_f32; +const u128_intFromFloat_f32 = impl.u128_intFromFloat_f32; +const signed_intFromFloat_f32 = impl.signed_intFromFloat_f32; +const unsigned_intFromFloat_f32 = impl.unsigned_intFromFloat_f32; + +const i32_intFromFloat_f64 = impl.i32_intFromFloat_f64; +const u32_intFromFloat_f64 = impl.u32_intFromFloat_f64; +const i64_intFromFloat_f64 = impl.i64_intFromFloat_f64; +const u64_intFromFloat_f64 = impl.u64_intFromFloat_f64; +const i128_intFromFloat_f64 = impl.i128_intFromFloat_f64; +const u128_intFromFloat_f64 = impl.u128_intFromFloat_f64; +const signed_intFromFloat_f64 = impl.signed_intFromFloat_f64; +const unsigned_intFromFloat_f64 = impl.unsigned_intFromFloat_f64; + +const i32_intFromFloat_f80 = impl.i32_intFromFloat_f80; +const u32_intFromFloat_f80 = impl.u32_intFromFloat_f80; +const i64_intFromFloat_f80 = impl.i64_intFromFloat_f80; +const u64_intFromFloat_f80 = impl.u64_intFromFloat_f80; +const i128_intFromFloat_f80 = impl.i128_intFromFloat_f80; +const u128_intFromFloat_f80 = impl.u128_intFromFloat_f80; +const signed_intFromFloat_f80 = impl.signed_intFromFloat_f80; +const unsigned_intFromFloat_f80 = impl.unsigned_intFromFloat_f80; + +const i32_intFromFloat_f128 = impl.i32_intFromFloat_f128; +const u32_intFromFloat_f128 = impl.u32_intFromFloat_f128; +const i64_intFromFloat_f128 = impl.i64_intFromFloat_f128; +const u64_intFromFloat_f128 = impl.u64_intFromFloat_f128; +const i128_intFromFloat_f128 = impl.i128_intFromFloat_f128; +const u128_intFromFloat_f128 = impl.u128_intFromFloat_f128; +const signed_intFromFloat_f128 = impl.signed_intFromFloat_f128; +const unsigned_intFromFloat_f128 = impl.unsigned_intFromFloat_f128; + +fn test_i32_intFromFloat_f32(a: f32, expected: i32) !void { + const x = i32_intFromFloat_f32(a); try testing.expect(x == expected); } -fn test__fixunssfsi(a: f32, expected: u32) !void { - const x = __fixunssfsi(a); +fn test_u32_intFromFloat_f32(a: f32, expected: u32) !void { + const x = u32_intFromFloat_f32(a); try testing.expect(x == expected); } -test "fixsfsi" { - try test__fixsfsi(-math.floatMax(f32), math.minInt(i32)); - - try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); - try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); - - try test__fixsfsi(-0x1.0000000000000p+127, -0x80000000); - try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); - try test__fixsfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); - - try test__fixsfsi(-0x1.0000000000001p+63, -0x80000000); - try test__fixsfsi(-0x1.0000000000000p+63, -0x80000000); - try test__fixsfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); - try test__fixsfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); - - try test__fixsfsi(-0x1.FFFFFEp+62, -0x80000000); - try test__fixsfsi(-0x1.FFFFFCp+62, -0x80000000); - - try test__fixsfsi(-0x1.000000p+31, -0x80000000); - try test__fixsfsi(-0x1.FFFFFFp+30, -0x80000000); - try test__fixsfsi(-0x1.FFFFFEp+30, -0x7FFFFF80); - try test__fixsfsi(-0x1.FFFFFCp+30, -0x7FFFFF00); - - try test__fixsfsi(-2.01, -2); - try test__fixsfsi(-2.0, -2); - try test__fixsfsi(-1.99, -1); - try test__fixsfsi(-1.0, -1); - try test__fixsfsi(-0.99, 0); - try test__fixsfsi(-0.5, 0); - - try test__fixsfsi(-math.floatMin(f32), 0); - try test__fixsfsi(0.0, 0); - try test__fixsfsi(math.floatMin(f32), 0); - try test__fixsfsi(0.5, 0); - try test__fixsfsi(0.99, 0); - try test__fixsfsi(1.0, 1); - try test__fixsfsi(1.5, 1); - try test__fixsfsi(1.99, 1); - try test__fixsfsi(2.0, 2); - try test__fixsfsi(2.01, 2); - - try test__fixsfsi(0x1.FFFFFCp+30, 0x7FFFFF00); - try test__fixsfsi(0x1.FFFFFEp+30, 0x7FFFFF80); - try test__fixsfsi(0x1.FFFFFFp+30, 0x7FFFFFFF); - try test__fixsfsi(0x1.000000p+31, 0x7FFFFFFF); - - try test__fixsfsi(0x1.FFFFFCp+62, 0x7FFFFFFF); - try test__fixsfsi(0x1.FFFFFEp+62, 0x7FFFFFFF); - - try test__fixsfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); - try test__fixsfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); - try test__fixsfsi(0x1.0000000000000p+63, 0x7FFFFFFF); - try test__fixsfsi(0x1.0000000000001p+63, 0x7FFFFFFF); - - try test__fixsfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); - try test__fixsfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); - try test__fixsfsi(0x1.0000000000000p+127, 0x7FFFFFFF); - - try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); - try test__fixsfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); - - try test__fixsfsi(math.floatMax(f32), math.maxInt(i32)); -} - -test "fixunssfsi" { - try test__fixunssfsi(0.0, 0); - - try test__fixunssfsi(0.5, 0); - try test__fixunssfsi(0.99, 0); - try test__fixunssfsi(1.0, 1); - try test__fixunssfsi(1.5, 1); - try test__fixunssfsi(1.99, 1); - try test__fixunssfsi(2.0, 2); - try test__fixunssfsi(2.01, 2); - try test__fixunssfsi(-0.5, 0); - try test__fixunssfsi(-0.99, 0); - - try test__fixunssfsi(-1.0, 0); - try test__fixunssfsi(-1.5, 0); - try test__fixunssfsi(-1.99, 0); - try test__fixunssfsi(-2.0, 0); - try test__fixunssfsi(-2.01, 0); - - try test__fixunssfsi(0x1.000000p+31, 0x80000000); - try test__fixunssfsi(0x1.000000p+32, 0xFFFFFFFF); - try test__fixunssfsi(0x1.FFFFFEp+31, 0xFFFFFF00); - try test__fixunssfsi(0x1.FFFFFEp+30, 0x7FFFFF80); - try test__fixunssfsi(0x1.FFFFFCp+30, 0x7FFFFF00); - - try test__fixunssfsi(-0x1.FFFFFEp+30, 0); - try test__fixunssfsi(-0x1.FFFFFCp+30, 0); -} - -fn test__fixsfdi(a: f32, expected: i64) !void { - const x = __fixsfdi(a); +test i32_intFromFloat_f32 { + try test_i32_intFromFloat_f32(-math.floatMax(f32), math.minInt(i32)); + + try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); + try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); + + try test_i32_intFromFloat_f32(-0x1.0000000000000p+127, -0x80000000); + try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); + try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); + + try test_i32_intFromFloat_f32(-0x1.0000000000001p+63, -0x80000000); + try test_i32_intFromFloat_f32(-0x1.0000000000000p+63, -0x80000000); + try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); + try test_i32_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); + + try test_i32_intFromFloat_f32(-0x1.FFFFFEp+62, -0x80000000); + try test_i32_intFromFloat_f32(-0x1.FFFFFCp+62, -0x80000000); + + try test_i32_intFromFloat_f32(-0x1.000000p+31, -0x80000000); + try test_i32_intFromFloat_f32(-0x1.FFFFFFp+30, -0x80000000); + try test_i32_intFromFloat_f32(-0x1.FFFFFEp+30, -0x7FFFFF80); + try test_i32_intFromFloat_f32(-0x1.FFFFFCp+30, -0x7FFFFF00); + + try test_i32_intFromFloat_f32(-2.01, -2); + try test_i32_intFromFloat_f32(-2.0, -2); + try test_i32_intFromFloat_f32(-1.99, -1); + try test_i32_intFromFloat_f32(-1.0, -1); + try test_i32_intFromFloat_f32(-0.99, 0); + try test_i32_intFromFloat_f32(-0.5, 0); + + try test_i32_intFromFloat_f32(-math.floatMin(f32), 0); + try test_i32_intFromFloat_f32(0.0, 0); + try test_i32_intFromFloat_f32(math.floatMin(f32), 0); + try test_i32_intFromFloat_f32(0.5, 0); + try test_i32_intFromFloat_f32(0.99, 0); + try test_i32_intFromFloat_f32(1.0, 1); + try test_i32_intFromFloat_f32(1.5, 1); + try test_i32_intFromFloat_f32(1.99, 1); + try test_i32_intFromFloat_f32(2.0, 2); + try test_i32_intFromFloat_f32(2.01, 2); + + try test_i32_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00); + try test_i32_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80); + try test_i32_intFromFloat_f32(0x1.FFFFFFp+30, 0x7FFFFFFF); + try test_i32_intFromFloat_f32(0x1.000000p+31, 0x7FFFFFFF); + + try test_i32_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFFFF); + try test_i32_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFFFF); + + try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); + try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); + try test_i32_intFromFloat_f32(0x1.0000000000000p+63, 0x7FFFFFFF); + try test_i32_intFromFloat_f32(0x1.0000000000001p+63, 0x7FFFFFFF); + + try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); + try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); + try test_i32_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFF); + + try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); + try test_i32_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); + + try test_i32_intFromFloat_f32(math.floatMax(f32), math.maxInt(i32)); +} + +test u32_intFromFloat_f32 { + try test_u32_intFromFloat_f32(0.0, 0); + + try test_u32_intFromFloat_f32(0.5, 0); + try test_u32_intFromFloat_f32(0.99, 0); + try test_u32_intFromFloat_f32(1.0, 1); + try test_u32_intFromFloat_f32(1.5, 1); + try test_u32_intFromFloat_f32(1.99, 1); + try test_u32_intFromFloat_f32(2.0, 2); + try test_u32_intFromFloat_f32(2.01, 2); + try test_u32_intFromFloat_f32(-0.5, 0); + try test_u32_intFromFloat_f32(-0.99, 0); + + try test_u32_intFromFloat_f32(-1.0, 0); + try test_u32_intFromFloat_f32(-1.5, 0); + try test_u32_intFromFloat_f32(-1.99, 0); + try test_u32_intFromFloat_f32(-2.0, 0); + try test_u32_intFromFloat_f32(-2.01, 0); + + try test_u32_intFromFloat_f32(0x1.000000p+31, 0x80000000); + try test_u32_intFromFloat_f32(0x1.000000p+32, 0xFFFFFFFF); + try test_u32_intFromFloat_f32(0x1.FFFFFEp+31, 0xFFFFFF00); + try test_u32_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80); + try test_u32_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00); + + try test_u32_intFromFloat_f32(-0x1.FFFFFEp+30, 0); + try test_u32_intFromFloat_f32(-0x1.FFFFFCp+30, 0); +} + +fn test_i64_intFromFloat_f32(a: f32, expected: i64) !void { + const x = i64_intFromFloat_f32(a); try testing.expect(x == expected); } -fn test__fixunssfdi(a: f32, expected: u64) !void { - const x = __fixunssfdi(a); +fn test_u64_intFromFloat_f32(a: f32, expected: u64) !void { + const x = u64_intFromFloat_f32(a); try testing.expect(x == expected); } -test "fixsfdi" { - try test__fixsfdi(-math.floatMax(f32), math.minInt(i64)); - - try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); - try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); - - try test__fixsfdi(-0x1.0000000000000p+127, -0x8000000000000000); - try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); - try test__fixsfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); - - try test__fixsfdi(-0x1.0000000000001p+63, -0x8000000000000000); - try test__fixsfdi(-0x1.0000000000000p+63, -0x8000000000000000); - try test__fixsfdi(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000); - try test__fixsfdi(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000); - - try test__fixsfdi(-0x1.FFFFFFp+62, -0x8000000000000000); - try test__fixsfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000); - try test__fixsfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000); - - try test__fixsfdi(-2.01, -2); - try test__fixsfdi(-2.0, -2); - try test__fixsfdi(-1.99, -1); - try test__fixsfdi(-1.0, -1); - try test__fixsfdi(-0.99, 0); - try test__fixsfdi(-0.5, 0); - try test__fixsfdi(-math.floatMin(f32), 0); - try test__fixsfdi(0.0, 0); - try test__fixsfdi(math.floatMin(f32), 0); - try test__fixsfdi(0.5, 0); - try test__fixsfdi(0.99, 0); - try test__fixsfdi(1.0, 1); - try test__fixsfdi(1.5, 1); - try test__fixsfdi(1.99, 1); - try test__fixsfdi(2.0, 2); - try test__fixsfdi(2.01, 2); - - try test__fixsfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); - try test__fixsfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); - try test__fixsfdi(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF); - - try test__fixsfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF); - try test__fixsfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF); - try test__fixsfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); - try test__fixsfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); - - try test__fixsfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); - try test__fixsfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); - try test__fixsfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); - - try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); - try test__fixsfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); - - try test__fixsfdi(math.floatMax(f32), math.maxInt(i64)); -} - -test "fixunssfdi" { - try test__fixunssfdi(0.0, 0); - - try test__fixunssfdi(0.5, 0); - try test__fixunssfdi(0.99, 0); - try test__fixunssfdi(1.0, 1); - try test__fixunssfdi(1.5, 1); - try test__fixunssfdi(1.99, 1); - try test__fixunssfdi(2.0, 2); - try test__fixunssfdi(2.01, 2); - try test__fixunssfdi(-0.5, 0); - try test__fixunssfdi(-0.99, 0); - - try test__fixunssfdi(-1.0, 0); - try test__fixunssfdi(-1.5, 0); - try test__fixunssfdi(-1.99, 0); - try test__fixunssfdi(-2.0, 0); - try test__fixunssfdi(-2.01, 0); - - try test__fixunssfdi(0x1.FFFFFEp+63, 0xFFFFFF0000000000); - try test__fixunssfdi(0x1.000000p+63, 0x8000000000000000); - try test__fixunssfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); - try test__fixunssfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); - - try test__fixunssfdi(-0x1.FFFFFEp+62, 0x0000000000000000); - try test__fixunssfdi(-0x1.FFFFFCp+62, 0x0000000000000000); -} - -fn test__fixsfti(a: f32, expected: i128) !void { - const x = __fixsfti(a); +test i64_intFromFloat_f32 { + try test_i64_intFromFloat_f32(-math.floatMax(f32), math.minInt(i64)); + + try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); + try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); + + try test_i64_intFromFloat_f32(-0x1.0000000000000p+127, -0x8000000000000000); + try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); + try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); + + try test_i64_intFromFloat_f32(-0x1.0000000000001p+63, -0x8000000000000000); + try test_i64_intFromFloat_f32(-0x1.0000000000000p+63, -0x8000000000000000); + try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000); + try test_i64_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000); + + try test_i64_intFromFloat_f32(-0x1.FFFFFFp+62, -0x8000000000000000); + try test_i64_intFromFloat_f32(-0x1.FFFFFEp+62, -0x7fffff8000000000); + try test_i64_intFromFloat_f32(-0x1.FFFFFCp+62, -0x7fffff0000000000); + + try test_i64_intFromFloat_f32(-2.01, -2); + try test_i64_intFromFloat_f32(-2.0, -2); + try test_i64_intFromFloat_f32(-1.99, -1); + try test_i64_intFromFloat_f32(-1.0, -1); + try test_i64_intFromFloat_f32(-0.99, 0); + try test_i64_intFromFloat_f32(-0.5, 0); + try test_i64_intFromFloat_f32(-math.floatMin(f32), 0); + try test_i64_intFromFloat_f32(0.0, 0); + try test_i64_intFromFloat_f32(math.floatMin(f32), 0); + try test_i64_intFromFloat_f32(0.5, 0); + try test_i64_intFromFloat_f32(0.99, 0); + try test_i64_intFromFloat_f32(1.0, 1); + try test_i64_intFromFloat_f32(1.5, 1); + try test_i64_intFromFloat_f32(1.99, 1); + try test_i64_intFromFloat_f32(2.0, 2); + try test_i64_intFromFloat_f32(2.01, 2); + + try test_i64_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000); + try test_i64_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000); + try test_i64_intFromFloat_f32(0x1.FFFFFFp+62, 0x7FFFFFFFFFFFFFFF); + + try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f32(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f32(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); + + try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); + + try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); + + try test_i64_intFromFloat_f32(math.floatMax(f32), math.maxInt(i64)); +} + +test u64_intFromFloat_f32 { + try test_u64_intFromFloat_f32(0.0, 0); + + try test_u64_intFromFloat_f32(0.5, 0); + try test_u64_intFromFloat_f32(0.99, 0); + try test_u64_intFromFloat_f32(1.0, 1); + try test_u64_intFromFloat_f32(1.5, 1); + try test_u64_intFromFloat_f32(1.99, 1); + try test_u64_intFromFloat_f32(2.0, 2); + try test_u64_intFromFloat_f32(2.01, 2); + try test_u64_intFromFloat_f32(-0.5, 0); + try test_u64_intFromFloat_f32(-0.99, 0); + + try test_u64_intFromFloat_f32(-1.0, 0); + try test_u64_intFromFloat_f32(-1.5, 0); + try test_u64_intFromFloat_f32(-1.99, 0); + try test_u64_intFromFloat_f32(-2.0, 0); + try test_u64_intFromFloat_f32(-2.01, 0); + + try test_u64_intFromFloat_f32(0x1.FFFFFEp+63, 0xFFFFFF0000000000); + try test_u64_intFromFloat_f32(0x1.000000p+63, 0x8000000000000000); + try test_u64_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000); + try test_u64_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000); + + try test_u64_intFromFloat_f32(-0x1.FFFFFEp+62, 0x0000000000000000); + try test_u64_intFromFloat_f32(-0x1.FFFFFCp+62, 0x0000000000000000); +} + +fn test_i128_intFromFloat_f32(a: f32, expected: i128) !void { + const x = i128_intFromFloat_f32(a); try testing.expect(x == expected); } -fn test__fixunssfti(a: f32, expected: u128) !void { - const x = __fixunssfti(a); +fn test_u128_intFromFloat_f32(a: f32, expected: u128) !void { + const x = u128_intFromFloat_f32(a); try testing.expect(x == expected); } -test "fixsfti" { - try test__fixsfti(-math.floatMax(f32), math.minInt(i128)); - - try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); - try test__fixsfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); - - try test__fixsfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); - try test__fixsfti(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000); - try test__fixsfti(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000); - try test__fixsfti(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000); - try test__fixsfti(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000); - try test__fixsfti(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000); - - try test__fixsfti(-0x1.0000000000001p+63, -0x8000000000000000); - try test__fixsfti(-0x1.0000000000000p+63, -0x8000000000000000); - try test__fixsfti(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000); - try test__fixsfti(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000); - - try test__fixsfti(-0x1.FFFFFFp+62, -0x8000000000000000); - try test__fixsfti(-0x1.FFFFFEp+62, -0x7fffff8000000000); - try test__fixsfti(-0x1.FFFFFCp+62, -0x7fffff0000000000); - - try test__fixsfti(-0x1.000000p+31, -0x80000000); - try test__fixsfti(-0x1.FFFFFFp+30, -0x80000000); - try test__fixsfti(-0x1.FFFFFEp+30, -0x7FFFFF80); - try test__fixsfti(-0x1.FFFFFCp+30, -0x7FFFFF00); - - try test__fixsfti(-2.01, -2); - try test__fixsfti(-2.0, -2); - try test__fixsfti(-1.99, -1); - try test__fixsfti(-1.0, -1); - try test__fixsfti(-0.99, 0); - try test__fixsfti(-0.5, 0); - try test__fixsfti(-math.floatMin(f32), 0); - try test__fixsfti(0.0, 0); - try test__fixsfti(math.floatMin(f32), 0); - try test__fixsfti(0.5, 0); - try test__fixsfti(0.99, 0); - try test__fixsfti(1.0, 1); - try test__fixsfti(1.5, 1); - try test__fixsfti(1.99, 1); - try test__fixsfti(2.0, 2); - try test__fixsfti(2.01, 2); - - try test__fixsfti(0x1.FFFFFCp+30, 0x7FFFFF00); - try test__fixsfti(0x1.FFFFFEp+30, 0x7FFFFF80); - try test__fixsfti(0x1.FFFFFFp+30, 0x80000000); - try test__fixsfti(0x1.000000p+31, 0x80000000); - - try test__fixsfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); - try test__fixsfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); - try test__fixsfti(0x1.FFFFFFp+62, 0x8000000000000000); - - try test__fixsfti(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000); - try test__fixsfti(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000); - try test__fixsfti(0x1.0000000000000p+63, 0x8000000000000000); - try test__fixsfti(0x1.0000000000001p+63, 0x8000000000000000); - - try test__fixsfti(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000); - try test__fixsfti(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000); - try test__fixsfti(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); - try test__fixsfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); - try test__fixsfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); - try test__fixsfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); - - try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); - try test__fixsfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); - - try test__fixsfti(math.floatMax(f32), math.maxInt(i128)); -} - -test "fixunssfti" { - try test__fixunssfti(0.0, 0); - - try test__fixunssfti(0.5, 0); - try test__fixunssfti(0.99, 0); - try test__fixunssfti(1.0, 1); - try test__fixunssfti(1.5, 1); - try test__fixunssfti(1.99, 1); - try test__fixunssfti(2.0, 2); - try test__fixunssfti(2.01, 2); - try test__fixunssfti(-0.5, 0); - try test__fixunssfti(-0.99, 0); - - try test__fixunssfti(-1.0, 0); - try test__fixunssfti(-1.5, 0); - try test__fixunssfti(-1.99, 0); - try test__fixunssfti(-2.0, 0); - try test__fixunssfti(-2.01, 0); - - try test__fixunssfti(0x1.FFFFFEp+63, 0xFFFFFF0000000000); - try test__fixunssfti(0x1.000000p+63, 0x8000000000000000); - try test__fixunssfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); - try test__fixunssfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); - try test__fixunssfti(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000); - try test__fixunssfti(0x1.000000p+127, 0x80000000000000000000000000000000); - try test__fixunssfti(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000); - try test__fixunssfti(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000); - - try test__fixunssfti(-0x1.FFFFFEp+62, 0x0000000000000000); - try test__fixunssfti(-0x1.FFFFFCp+62, 0x0000000000000000); - try test__fixunssfti(-0x1.FFFFFEp+126, 0x0000000000000000); - try test__fixunssfti(-0x1.FFFFFCp+126, 0x0000000000000000); - try test__fixunssfti(math.floatMax(f32), 0xffffff00000000000000000000000000); - try test__fixunssfti(math.inf(f32), math.maxInt(u128)); -} - -fn test_fixsfei(comptime T: type, expected: T, a: f32) !void { +test i128_intFromFloat_f32 { + try test_i128_intFromFloat_f32(-math.floatMax(f32), math.minInt(i128)); + + try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); + try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); + + try test_i128_intFromFloat_f32(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); + try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+126, -0x80000000000000000000000000000000); + try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+126, -0x80000000000000000000000000000000); + try test_i128_intFromFloat_f32(-0x1.FFFFFF0000000p+126, -0x80000000000000000000000000000000); + try test_i128_intFromFloat_f32(-0x1.FFFFFE0000000p+126, -0x7FFFFF80000000000000000000000000); + try test_i128_intFromFloat_f32(-0x1.FFFFFC0000000p+126, -0x7FFFFF00000000000000000000000000); + + try test_i128_intFromFloat_f32(-0x1.0000000000001p+63, -0x8000000000000000); + try test_i128_intFromFloat_f32(-0x1.0000000000000p+63, -0x8000000000000000); + try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFFp+62, -0x8000000000000000); + try test_i128_intFromFloat_f32(-0x1.FFFFFFFFFFFFEp+62, -0x8000000000000000); + + try test_i128_intFromFloat_f32(-0x1.FFFFFFp+62, -0x8000000000000000); + try test_i128_intFromFloat_f32(-0x1.FFFFFEp+62, -0x7fffff8000000000); + try test_i128_intFromFloat_f32(-0x1.FFFFFCp+62, -0x7fffff0000000000); + + try test_i128_intFromFloat_f32(-0x1.000000p+31, -0x80000000); + try test_i128_intFromFloat_f32(-0x1.FFFFFFp+30, -0x80000000); + try test_i128_intFromFloat_f32(-0x1.FFFFFEp+30, -0x7FFFFF80); + try test_i128_intFromFloat_f32(-0x1.FFFFFCp+30, -0x7FFFFF00); + + try test_i128_intFromFloat_f32(-2.01, -2); + try test_i128_intFromFloat_f32(-2.0, -2); + try test_i128_intFromFloat_f32(-1.99, -1); + try test_i128_intFromFloat_f32(-1.0, -1); + try test_i128_intFromFloat_f32(-0.99, 0); + try test_i128_intFromFloat_f32(-0.5, 0); + try test_i128_intFromFloat_f32(-math.floatMin(f32), 0); + try test_i128_intFromFloat_f32(0.0, 0); + try test_i128_intFromFloat_f32(math.floatMin(f32), 0); + try test_i128_intFromFloat_f32(0.5, 0); + try test_i128_intFromFloat_f32(0.99, 0); + try test_i128_intFromFloat_f32(1.0, 1); + try test_i128_intFromFloat_f32(1.5, 1); + try test_i128_intFromFloat_f32(1.99, 1); + try test_i128_intFromFloat_f32(2.0, 2); + try test_i128_intFromFloat_f32(2.01, 2); + + try test_i128_intFromFloat_f32(0x1.FFFFFCp+30, 0x7FFFFF00); + try test_i128_intFromFloat_f32(0x1.FFFFFEp+30, 0x7FFFFF80); + try test_i128_intFromFloat_f32(0x1.FFFFFFp+30, 0x80000000); + try test_i128_intFromFloat_f32(0x1.000000p+31, 0x80000000); + + try test_i128_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000); + try test_i128_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000); + try test_i128_intFromFloat_f32(0x1.FFFFFFp+62, 0x8000000000000000); + + try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+62, 0x8000000000000000); + try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+62, 0x8000000000000000); + try test_i128_intFromFloat_f32(0x1.0000000000000p+63, 0x8000000000000000); + try test_i128_intFromFloat_f32(0x1.0000000000001p+63, 0x8000000000000000); + + try test_i128_intFromFloat_f32(0x1.FFFFFC0000000p+126, 0x7FFFFF00000000000000000000000000); + try test_i128_intFromFloat_f32(0x1.FFFFFE0000000p+126, 0x7FFFFF80000000000000000000000000); + try test_i128_intFromFloat_f32(0x1.FFFFFF0000000p+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + try test_i128_intFromFloat_f32(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + try test_i128_intFromFloat_f32(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); + + try test_i128_intFromFloat_f32(math.floatMax(f32), math.maxInt(i128)); +} + +test u128_intFromFloat_f32 { + try test_u128_intFromFloat_f32(0.0, 0); + + try test_u128_intFromFloat_f32(0.5, 0); + try test_u128_intFromFloat_f32(0.99, 0); + try test_u128_intFromFloat_f32(1.0, 1); + try test_u128_intFromFloat_f32(1.5, 1); + try test_u128_intFromFloat_f32(1.99, 1); + try test_u128_intFromFloat_f32(2.0, 2); + try test_u128_intFromFloat_f32(2.01, 2); + try test_u128_intFromFloat_f32(-0.5, 0); + try test_u128_intFromFloat_f32(-0.99, 0); + + try test_u128_intFromFloat_f32(-1.0, 0); + try test_u128_intFromFloat_f32(-1.5, 0); + try test_u128_intFromFloat_f32(-1.99, 0); + try test_u128_intFromFloat_f32(-2.0, 0); + try test_u128_intFromFloat_f32(-2.01, 0); + + try test_u128_intFromFloat_f32(0x1.FFFFFEp+63, 0xFFFFFF0000000000); + try test_u128_intFromFloat_f32(0x1.000000p+63, 0x8000000000000000); + try test_u128_intFromFloat_f32(0x1.FFFFFEp+62, 0x7FFFFF8000000000); + try test_u128_intFromFloat_f32(0x1.FFFFFCp+62, 0x7FFFFF0000000000); + try test_u128_intFromFloat_f32(0x1.FFFFFEp+127, 0xFFFFFF00000000000000000000000000); + try test_u128_intFromFloat_f32(0x1.000000p+127, 0x80000000000000000000000000000000); + try test_u128_intFromFloat_f32(0x1.FFFFFEp+126, 0x7FFFFF80000000000000000000000000); + try test_u128_intFromFloat_f32(0x1.FFFFFCp+126, 0x7FFFFF00000000000000000000000000); + + try test_u128_intFromFloat_f32(-0x1.FFFFFEp+62, 0x0000000000000000); + try test_u128_intFromFloat_f32(-0x1.FFFFFCp+62, 0x0000000000000000); + try test_u128_intFromFloat_f32(-0x1.FFFFFEp+126, 0x0000000000000000); + try test_u128_intFromFloat_f32(-0x1.FFFFFCp+126, 0x0000000000000000); + try test_u128_intFromFloat_f32(math.floatMax(f32), 0xffffff00000000000000000000000000); + try test_u128_intFromFloat_f32(math.inf(f32), math.maxInt(u128)); +} + +fn test_intFromFloat_f32(comptime T: type, expected: T, a: f32) !void { const int = @typeInfo(T).int; var actual: T = undefined; _ = switch (int.signedness) { - .signed => __fixsfei, - .unsigned => __fixunssfei, - }(@ptrCast(&actual), int.bits, a); + .signed => signed_intFromFloat_f32, + .unsigned => unsigned_intFromFloat_f32, + }(@ptrCast(&actual), a); try testing.expect(expected == actual); } -test "fixsfei" { - try test_fixsfei(i256, -1 << 127, -0x1p127); - try test_fixsfei(i256, -1 << 100, -0x1p100); - try test_fixsfei(i256, -1 << 50, -0x1p50); - try test_fixsfei(i256, -1 << 1, -0x1p1); - try test_fixsfei(i256, -1 << 0, -0x1p0); - try test_fixsfei(i256, 0, 0); - try test_fixsfei(i256, 1 << 0, 0x1p0); - try test_fixsfei(i256, 1 << 1, 0x1p1); - try test_fixsfei(i256, 1 << 50, 0x1p50); - try test_fixsfei(i256, 1 << 100, 0x1p100); - try test_fixsfei(i256, 1 << 127, 0x1p127); +test signed_intFromFloat_f32 { + try test_intFromFloat_f32(i256, -1 << 127, -0x1p127); + try test_intFromFloat_f32(i256, -1 << 100, -0x1p100); + try test_intFromFloat_f32(i256, -1 << 50, -0x1p50); + try test_intFromFloat_f32(i256, -1 << 1, -0x1p1); + try test_intFromFloat_f32(i256, -1 << 0, -0x1p0); + try test_intFromFloat_f32(i256, 0, 0); + try test_intFromFloat_f32(i256, 1 << 0, 0x1p0); + try test_intFromFloat_f32(i256, 1 << 1, 0x1p1); + try test_intFromFloat_f32(i256, 1 << 50, 0x1p50); + try test_intFromFloat_f32(i256, 1 << 100, 0x1p100); + try test_intFromFloat_f32(i256, 1 << 127, 0x1p127); } -test "fixunsfei" { - try test_fixsfei(u256, 0, 0); - try test_fixsfei(u256, 1 << 0, 0x1p0); - try test_fixsfei(u256, 1 << 1, 0x1p1); - try test_fixsfei(u256, 1 << 50, 0x1p50); - try test_fixsfei(u256, 1 << 100, 0x1p100); - try test_fixsfei(u256, 1 << 127, 0x1p127); +test unsigned_intFromFloat_f32 { + try test_intFromFloat_f32(u256, 0, 0); + try test_intFromFloat_f32(u256, 1 << 0, 0x1p0); + try test_intFromFloat_f32(u256, 1 << 1, 0x1p1); + try test_intFromFloat_f32(u256, 1 << 50, 0x1p50); + try test_intFromFloat_f32(u256, 1 << 100, 0x1p100); + try test_intFromFloat_f32(u256, 1 << 127, 0x1p127); } -fn test__fixdfsi(a: f64, expected: i32) !void { - const x = __fixdfsi(a); +fn test_i32_intFromFloat_f64(a: f64, expected: i32) !void { + const x = i32_intFromFloat_f64(a); try testing.expect(x == expected); } -fn test__fixunsdfsi(a: f64, expected: u32) !void { - const x = __fixunsdfsi(a); +fn test_u32_intFromFloat_f64(a: f64, expected: u32) !void { + const x = u32_intFromFloat_f64(a); try testing.expect(x == expected); } -test "fixdfsi" { - try test__fixdfsi(-math.floatMax(f64), math.minInt(i32)); - - try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); - try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); - - try test__fixdfsi(-0x1.0000000000000p+127, -0x80000000); - try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); - try test__fixdfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); - - try test__fixdfsi(-0x1.0000000000001p+63, -0x80000000); - try test__fixdfsi(-0x1.0000000000000p+63, -0x80000000); - try test__fixdfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); - try test__fixdfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); - - try test__fixdfsi(-0x1.FFFFFEp+62, -0x80000000); - try test__fixdfsi(-0x1.FFFFFCp+62, -0x80000000); - - try test__fixdfsi(-0x1.000000p+31, -0x80000000); - try test__fixdfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0); - try test__fixdfsi(-0x1.FFFFFEp+30, -0x7FFFFF80); - - try test__fixdfsi(-2.01, -2); - try test__fixdfsi(-2.0, -2); - try test__fixdfsi(-1.99, -1); - try test__fixdfsi(-1.0, -1); - try test__fixdfsi(-0.99, 0); - try test__fixdfsi(-0.5, 0); - try test__fixdfsi(-math.floatMin(f64), 0); - try test__fixdfsi(0.0, 0); - try test__fixdfsi(math.floatMin(f64), 0); - try test__fixdfsi(0.5, 0); - try test__fixdfsi(0.99, 0); - try test__fixdfsi(1.0, 1); - try test__fixdfsi(1.5, 1); - try test__fixdfsi(1.99, 1); - try test__fixdfsi(2.0, 2); - try test__fixdfsi(2.01, 2); - - try test__fixdfsi(0x1.FFFFFEp+30, 0x7FFFFF80); - try test__fixdfsi(0x1.FFFFFFp+30, 0x7FFFFFC0); - try test__fixdfsi(0x1.000000p+31, 0x7FFFFFFF); - - try test__fixdfsi(0x1.FFFFFCp+62, 0x7FFFFFFF); - try test__fixdfsi(0x1.FFFFFEp+62, 0x7FFFFFFF); - - try test__fixdfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); - try test__fixdfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); - try test__fixdfsi(0x1.0000000000000p+63, 0x7FFFFFFF); - try test__fixdfsi(0x1.0000000000001p+63, 0x7FFFFFFF); - - try test__fixdfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); - try test__fixdfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); - try test__fixdfsi(0x1.0000000000000p+127, 0x7FFFFFFF); - - try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); - try test__fixdfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); - - try test__fixdfsi(math.floatMax(f64), math.maxInt(i32)); -} - -test "fixunsdfsi" { - try test__fixunsdfsi(0.0, 0); - - try test__fixunsdfsi(0.5, 0); - try test__fixunsdfsi(0.99, 0); - try test__fixunsdfsi(1.0, 1); - try test__fixunsdfsi(1.5, 1); - try test__fixunsdfsi(1.99, 1); - try test__fixunsdfsi(2.0, 2); - try test__fixunsdfsi(2.01, 2); - try test__fixunsdfsi(-0.5, 0); - try test__fixunsdfsi(-0.99, 0); - try test__fixunsdfsi(-1.0, 0); - try test__fixunsdfsi(-1.5, 0); - try test__fixunsdfsi(-1.99, 0); - try test__fixunsdfsi(-2.0, 0); - try test__fixunsdfsi(-2.01, 0); - - try test__fixunsdfsi(0x1.000000p+31, 0x80000000); - try test__fixunsdfsi(0x1.000000p+32, 0xFFFFFFFF); - try test__fixunsdfsi(0x1.FFFFFEp+31, 0xFFFFFF00); - try test__fixunsdfsi(0x1.FFFFFEp+30, 0x7FFFFF80); - try test__fixunsdfsi(0x1.FFFFFCp+30, 0x7FFFFF00); - - try test__fixunsdfsi(-0x1.FFFFFEp+30, 0); - try test__fixunsdfsi(-0x1.FFFFFCp+30, 0); - - try test__fixunsdfsi(0x1.FFFFFFFEp+31, 0xFFFFFFFF); - try test__fixunsdfsi(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF); - try test__fixunsdfsi(0x1.FFFFFFF800000p+30, 0x7FFFFFFE); -} - -fn test__fixdfdi(a: f64, expected: i64) !void { - const x = __fixdfdi(a); +test i32_intFromFloat_f64 { + try test_i32_intFromFloat_f64(-math.floatMax(f64), math.minInt(i32)); + + try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); + try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); + + try test_i32_intFromFloat_f64(-0x1.0000000000000p+127, -0x80000000); + try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); + try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); + + try test_i32_intFromFloat_f64(-0x1.0000000000001p+63, -0x80000000); + try test_i32_intFromFloat_f64(-0x1.0000000000000p+63, -0x80000000); + try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); + try test_i32_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); + + try test_i32_intFromFloat_f64(-0x1.FFFFFEp+62, -0x80000000); + try test_i32_intFromFloat_f64(-0x1.FFFFFCp+62, -0x80000000); + + try test_i32_intFromFloat_f64(-0x1.000000p+31, -0x80000000); + try test_i32_intFromFloat_f64(-0x1.FFFFFFp+30, -0x7FFFFFC0); + try test_i32_intFromFloat_f64(-0x1.FFFFFEp+30, -0x7FFFFF80); + + try test_i32_intFromFloat_f64(-2.01, -2); + try test_i32_intFromFloat_f64(-2.0, -2); + try test_i32_intFromFloat_f64(-1.99, -1); + try test_i32_intFromFloat_f64(-1.0, -1); + try test_i32_intFromFloat_f64(-0.99, 0); + try test_i32_intFromFloat_f64(-0.5, 0); + try test_i32_intFromFloat_f64(-math.floatMin(f64), 0); + try test_i32_intFromFloat_f64(0.0, 0); + try test_i32_intFromFloat_f64(math.floatMin(f64), 0); + try test_i32_intFromFloat_f64(0.5, 0); + try test_i32_intFromFloat_f64(0.99, 0); + try test_i32_intFromFloat_f64(1.0, 1); + try test_i32_intFromFloat_f64(1.5, 1); + try test_i32_intFromFloat_f64(1.99, 1); + try test_i32_intFromFloat_f64(2.0, 2); + try test_i32_intFromFloat_f64(2.01, 2); + + try test_i32_intFromFloat_f64(0x1.FFFFFEp+30, 0x7FFFFF80); + try test_i32_intFromFloat_f64(0x1.FFFFFFp+30, 0x7FFFFFC0); + try test_i32_intFromFloat_f64(0x1.000000p+31, 0x7FFFFFFF); + + try test_i32_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFFFF); + try test_i32_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFFFF); + + try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); + try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); + try test_i32_intFromFloat_f64(0x1.0000000000000p+63, 0x7FFFFFFF); + try test_i32_intFromFloat_f64(0x1.0000000000001p+63, 0x7FFFFFFF); + + try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); + try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); + try test_i32_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFF); + + try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); + try test_i32_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); + + try test_i32_intFromFloat_f64(math.floatMax(f64), math.maxInt(i32)); +} + +test u32_intFromFloat_f64 { + try test_u32_intFromFloat_f64(0.0, 0); + + try test_u32_intFromFloat_f64(0.5, 0); + try test_u32_intFromFloat_f64(0.99, 0); + try test_u32_intFromFloat_f64(1.0, 1); + try test_u32_intFromFloat_f64(1.5, 1); + try test_u32_intFromFloat_f64(1.99, 1); + try test_u32_intFromFloat_f64(2.0, 2); + try test_u32_intFromFloat_f64(2.01, 2); + try test_u32_intFromFloat_f64(-0.5, 0); + try test_u32_intFromFloat_f64(-0.99, 0); + try test_u32_intFromFloat_f64(-1.0, 0); + try test_u32_intFromFloat_f64(-1.5, 0); + try test_u32_intFromFloat_f64(-1.99, 0); + try test_u32_intFromFloat_f64(-2.0, 0); + try test_u32_intFromFloat_f64(-2.01, 0); + + try test_u32_intFromFloat_f64(0x1.000000p+31, 0x80000000); + try test_u32_intFromFloat_f64(0x1.000000p+32, 0xFFFFFFFF); + try test_u32_intFromFloat_f64(0x1.FFFFFEp+31, 0xFFFFFF00); + try test_u32_intFromFloat_f64(0x1.FFFFFEp+30, 0x7FFFFF80); + try test_u32_intFromFloat_f64(0x1.FFFFFCp+30, 0x7FFFFF00); + + try test_u32_intFromFloat_f64(-0x1.FFFFFEp+30, 0); + try test_u32_intFromFloat_f64(-0x1.FFFFFCp+30, 0); + + try test_u32_intFromFloat_f64(0x1.FFFFFFFEp+31, 0xFFFFFFFF); + try test_u32_intFromFloat_f64(0x1.FFFFFFFC00000p+30, 0x7FFFFFFF); + try test_u32_intFromFloat_f64(0x1.FFFFFFF800000p+30, 0x7FFFFFFE); +} + +fn test_i64_intFromFloat_f64(a: f64, expected: i64) !void { + const x = i64_intFromFloat_f64(a); try testing.expect(x == expected); } -fn test__fixunsdfdi(a: f64, expected: u64) !void { - const x = __fixunsdfdi(a); +fn test_u64_intFromFloat_f64(a: f64, expected: u64) !void { + const x = u64_intFromFloat_f64(a); try testing.expect(x == expected); } -test "fixdfdi" { - try test__fixdfdi(-math.floatMax(f64), math.minInt(i64)); - - try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); - try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); - - try test__fixdfdi(-0x1.0000000000000p+127, -0x8000000000000000); - try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); - try test__fixdfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); - - try test__fixdfdi(-0x1.0000000000001p+63, -0x8000000000000000); - try test__fixdfdi(-0x1.0000000000000p+63, -0x8000000000000000); - try test__fixdfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); - try test__fixdfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); - - try test__fixdfdi(-0x1.FFFFFEp+62, -0x7fffff8000000000); - try test__fixdfdi(-0x1.FFFFFCp+62, -0x7fffff0000000000); - - try test__fixdfdi(-2.01, -2); - try test__fixdfdi(-2.0, -2); - try test__fixdfdi(-1.99, -1); - try test__fixdfdi(-1.0, -1); - try test__fixdfdi(-0.99, 0); - try test__fixdfdi(-0.5, 0); - try test__fixdfdi(-math.floatMin(f64), 0); - try test__fixdfdi(0.0, 0); - try test__fixdfdi(math.floatMin(f64), 0); - try test__fixdfdi(0.5, 0); - try test__fixdfdi(0.99, 0); - try test__fixdfdi(1.0, 1); - try test__fixdfdi(1.5, 1); - try test__fixdfdi(1.99, 1); - try test__fixdfdi(2.0, 2); - try test__fixdfdi(2.01, 2); - - try test__fixdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); - try test__fixdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); - - try test__fixdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); - try test__fixdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); - try test__fixdfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); - try test__fixdfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); - - try test__fixdfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); - try test__fixdfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); - try test__fixdfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); - - try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); - try test__fixdfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); - - try test__fixdfdi(math.floatMax(f64), math.maxInt(i64)); -} - -test "fixunsdfdi" { - try test__fixunsdfdi(0.0, 0); - try test__fixunsdfdi(0.5, 0); - try test__fixunsdfdi(0.99, 0); - try test__fixunsdfdi(1.0, 1); - try test__fixunsdfdi(1.5, 1); - try test__fixunsdfdi(1.99, 1); - try test__fixunsdfdi(2.0, 2); - try test__fixunsdfdi(2.01, 2); - try test__fixunsdfdi(-0.5, 0); - try test__fixunsdfdi(-0.99, 0); - try test__fixunsdfdi(-1.0, 0); - try test__fixunsdfdi(-1.5, 0); - try test__fixunsdfdi(-1.99, 0); - try test__fixunsdfdi(-2.0, 0); - try test__fixunsdfdi(-2.01, 0); - - try test__fixunsdfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); - try test__fixunsdfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); - - try test__fixunsdfdi(-0x1.FFFFFEp+62, 0); - try test__fixunsdfdi(-0x1.FFFFFCp+62, 0); - - try test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); - try test__fixunsdfdi(0x1.0000000000000p+63, 0x8000000000000000); - try test__fixunsdfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); - try test__fixunsdfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); - - try test__fixunsdfdi(-0x1.FFFFFFFFFFFFFp+62, 0); - try test__fixunsdfdi(-0x1.FFFFFFFFFFFFEp+62, 0); -} - -fn test__fixdfti(a: f64, expected: i128) !void { - const x = __fixdfti(a); +test i64_intFromFloat_f64 { + try test_i64_intFromFloat_f64(-math.floatMax(f64), math.minInt(i64)); + + try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); + try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); + + try test_i64_intFromFloat_f64(-0x1.0000000000000p+127, -0x8000000000000000); + try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); + try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); + + try test_i64_intFromFloat_f64(-0x1.0000000000001p+63, -0x8000000000000000); + try test_i64_intFromFloat_f64(-0x1.0000000000000p+63, -0x8000000000000000); + try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); + try test_i64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); + + try test_i64_intFromFloat_f64(-0x1.FFFFFEp+62, -0x7fffff8000000000); + try test_i64_intFromFloat_f64(-0x1.FFFFFCp+62, -0x7fffff0000000000); + + try test_i64_intFromFloat_f64(-2.01, -2); + try test_i64_intFromFloat_f64(-2.0, -2); + try test_i64_intFromFloat_f64(-1.99, -1); + try test_i64_intFromFloat_f64(-1.0, -1); + try test_i64_intFromFloat_f64(-0.99, 0); + try test_i64_intFromFloat_f64(-0.5, 0); + try test_i64_intFromFloat_f64(-math.floatMin(f64), 0); + try test_i64_intFromFloat_f64(0.0, 0); + try test_i64_intFromFloat_f64(math.floatMin(f64), 0); + try test_i64_intFromFloat_f64(0.5, 0); + try test_i64_intFromFloat_f64(0.99, 0); + try test_i64_intFromFloat_f64(1.0, 1); + try test_i64_intFromFloat_f64(1.5, 1); + try test_i64_intFromFloat_f64(1.99, 1); + try test_i64_intFromFloat_f64(2.0, 2); + try test_i64_intFromFloat_f64(2.01, 2); + + try test_i64_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000); + try test_i64_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000); + + try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); + try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); + try test_i64_intFromFloat_f64(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f64(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); + + try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); + + try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); + + try test_i64_intFromFloat_f64(math.floatMax(f64), math.maxInt(i64)); +} + +test u64_intFromFloat_f64 { + try test_u64_intFromFloat_f64(0.0, 0); + try test_u64_intFromFloat_f64(0.5, 0); + try test_u64_intFromFloat_f64(0.99, 0); + try test_u64_intFromFloat_f64(1.0, 1); + try test_u64_intFromFloat_f64(1.5, 1); + try test_u64_intFromFloat_f64(1.99, 1); + try test_u64_intFromFloat_f64(2.0, 2); + try test_u64_intFromFloat_f64(2.01, 2); + try test_u64_intFromFloat_f64(-0.5, 0); + try test_u64_intFromFloat_f64(-0.99, 0); + try test_u64_intFromFloat_f64(-1.0, 0); + try test_u64_intFromFloat_f64(-1.5, 0); + try test_u64_intFromFloat_f64(-1.99, 0); + try test_u64_intFromFloat_f64(-2.0, 0); + try test_u64_intFromFloat_f64(-2.01, 0); + + try test_u64_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000); + try test_u64_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000); + + try test_u64_intFromFloat_f64(-0x1.FFFFFEp+62, 0); + try test_u64_intFromFloat_f64(-0x1.FFFFFCp+62, 0); + + try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); + try test_u64_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000); + try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); + try test_u64_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); + + try test_u64_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, 0); + try test_u64_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, 0); +} + +fn test_i128_intFromFloat_f64(a: f64, expected: i128) !void { + const x = i128_intFromFloat_f64(a); try testing.expect(x == expected); } -fn test__fixunsdfti(a: f64, expected: u128) !void { - const x = __fixunsdfti(a); +fn test_u128_intFromFloat_f64(a: f64, expected: u128) !void { + const x = u128_intFromFloat_f64(a); try testing.expect(x == expected); } -test "fixdfti" { - try test__fixdfti(-math.floatMax(f64), math.minInt(i128)); - - try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); - try test__fixdfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); - - try test__fixdfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); - try test__fixdfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000); - try test__fixdfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000); - - try test__fixdfti(-0x1.0000000000001p+63, -0x8000000000000800); - try test__fixdfti(-0x1.0000000000000p+63, -0x8000000000000000); - try test__fixdfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); - try test__fixdfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); - - try test__fixdfti(-0x1.FFFFFEp+62, -0x7fffff8000000000); - try test__fixdfti(-0x1.FFFFFCp+62, -0x7fffff0000000000); - - try test__fixdfti(-2.01, -2); - try test__fixdfti(-2.0, -2); - try test__fixdfti(-1.99, -1); - try test__fixdfti(-1.0, -1); - try test__fixdfti(-0.99, 0); - try test__fixdfti(-0.5, 0); - try test__fixdfti(-math.floatMin(f64), 0); - try test__fixdfti(0.0, 0); - try test__fixdfti(math.floatMin(f64), 0); - try test__fixdfti(0.5, 0); - try test__fixdfti(0.99, 0); - try test__fixdfti(1.0, 1); - try test__fixdfti(1.5, 1); - try test__fixdfti(1.99, 1); - try test__fixdfti(2.0, 2); - try test__fixdfti(2.01, 2); - - try test__fixdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); - try test__fixdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); - - try test__fixdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); - try test__fixdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); - try test__fixdfti(0x1.0000000000000p+63, 0x8000000000000000); - try test__fixdfti(0x1.0000000000001p+63, 0x8000000000000800); - - try test__fixdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); - try test__fixdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); - try test__fixdfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); - - try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); - try test__fixdfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); - - try test__fixdfti(math.floatMax(f64), math.maxInt(i128)); -} - -test "fixunsdfti" { - try test__fixunsdfti(0.0, 0); - - try test__fixunsdfti(0.5, 0); - try test__fixunsdfti(0.99, 0); - try test__fixunsdfti(1.0, 1); - try test__fixunsdfti(1.5, 1); - try test__fixunsdfti(1.99, 1); - try test__fixunsdfti(2.0, 2); - try test__fixunsdfti(2.01, 2); - try test__fixunsdfti(-0.5, 0); - try test__fixunsdfti(-0.99, 0); - try test__fixunsdfti(-1.0, 0); - try test__fixunsdfti(-1.5, 0); - try test__fixunsdfti(-1.99, 0); - try test__fixunsdfti(-2.0, 0); - try test__fixunsdfti(-2.01, 0); - - try test__fixunsdfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); - try test__fixunsdfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); - - try test__fixunsdfti(-0x1.FFFFFEp+62, 0); - try test__fixunsdfti(-0x1.FFFFFCp+62, 0); - - try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); - try test__fixunsdfti(0x1.0000000000000p+63, 0x8000000000000000); - try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); - try test__fixunsdfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); - - try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000); - try test__fixunsdfti(0x1.0000000000000p+127, 0x80000000000000000000000000000000); - try test__fixunsdfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); - try test__fixunsdfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); - try test__fixunsdfti(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); - - try test__fixunsdfti(-0x1.FFFFFFFFFFFFFp+62, 0); - try test__fixunsdfti(-0x1.FFFFFFFFFFFFEp+62, 0); -} - -fn test_fixdfei(comptime T: type, expected: T, a: f64) !void { +test i128_intFromFloat_f64 { + try test_i128_intFromFloat_f64(-math.floatMax(f64), math.minInt(i128)); + + try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); + try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); + + try test_i128_intFromFloat_f64(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); + try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000); + try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000); + + try test_i128_intFromFloat_f64(-0x1.0000000000001p+63, -0x8000000000000800); + try test_i128_intFromFloat_f64(-0x1.0000000000000p+63, -0x8000000000000000); + try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); + try test_i128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); + + try test_i128_intFromFloat_f64(-0x1.FFFFFEp+62, -0x7fffff8000000000); + try test_i128_intFromFloat_f64(-0x1.FFFFFCp+62, -0x7fffff0000000000); + + try test_i128_intFromFloat_f64(-2.01, -2); + try test_i128_intFromFloat_f64(-2.0, -2); + try test_i128_intFromFloat_f64(-1.99, -1); + try test_i128_intFromFloat_f64(-1.0, -1); + try test_i128_intFromFloat_f64(-0.99, 0); + try test_i128_intFromFloat_f64(-0.5, 0); + try test_i128_intFromFloat_f64(-math.floatMin(f64), 0); + try test_i128_intFromFloat_f64(0.0, 0); + try test_i128_intFromFloat_f64(math.floatMin(f64), 0); + try test_i128_intFromFloat_f64(0.5, 0); + try test_i128_intFromFloat_f64(0.99, 0); + try test_i128_intFromFloat_f64(1.0, 1); + try test_i128_intFromFloat_f64(1.5, 1); + try test_i128_intFromFloat_f64(1.99, 1); + try test_i128_intFromFloat_f64(2.0, 2); + try test_i128_intFromFloat_f64(2.01, 2); + + try test_i128_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000); + try test_i128_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000); + + try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); + try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); + try test_i128_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000); + try test_i128_intFromFloat_f64(0x1.0000000000001p+63, 0x8000000000000800); + + try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); + try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); + try test_i128_intFromFloat_f64(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + try test_i128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); + + try test_i128_intFromFloat_f64(math.floatMax(f64), math.maxInt(i128)); +} + +test u128_intFromFloat_f64 { + try test_u128_intFromFloat_f64(0.0, 0); + + try test_u128_intFromFloat_f64(0.5, 0); + try test_u128_intFromFloat_f64(0.99, 0); + try test_u128_intFromFloat_f64(1.0, 1); + try test_u128_intFromFloat_f64(1.5, 1); + try test_u128_intFromFloat_f64(1.99, 1); + try test_u128_intFromFloat_f64(2.0, 2); + try test_u128_intFromFloat_f64(2.01, 2); + try test_u128_intFromFloat_f64(-0.5, 0); + try test_u128_intFromFloat_f64(-0.99, 0); + try test_u128_intFromFloat_f64(-1.0, 0); + try test_u128_intFromFloat_f64(-1.5, 0); + try test_u128_intFromFloat_f64(-1.99, 0); + try test_u128_intFromFloat_f64(-2.0, 0); + try test_u128_intFromFloat_f64(-2.01, 0); + + try test_u128_intFromFloat_f64(0x1.FFFFFEp+62, 0x7FFFFF8000000000); + try test_u128_intFromFloat_f64(0x1.FFFFFCp+62, 0x7FFFFF0000000000); + + try test_u128_intFromFloat_f64(-0x1.FFFFFEp+62, 0); + try test_u128_intFromFloat_f64(-0x1.FFFFFCp+62, 0); + + try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+63, 0xFFFFFFFFFFFFF800); + try test_u128_intFromFloat_f64(0x1.0000000000000p+63, 0x8000000000000000); + try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); + try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); + + try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+127, 0xFFFFFFFFFFFFF8000000000000000000); + try test_u128_intFromFloat_f64(0x1.0000000000000p+127, 0x80000000000000000000000000000000); + try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); + try test_u128_intFromFloat_f64(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); + try test_u128_intFromFloat_f64(0x1.0000000000000p+128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + try test_u128_intFromFloat_f64(-0x1.FFFFFFFFFFFFFp+62, 0); + try test_u128_intFromFloat_f64(-0x1.FFFFFFFFFFFFEp+62, 0); +} + +fn test_intFromFloat_f64(comptime T: type, expected: T, a: f64) !void { const int = @typeInfo(T).int; var actual: T = undefined; _ = switch (int.signedness) { - .signed => __fixdfei, - .unsigned => __fixunsdfei, - }(@ptrCast(&actual), int.bits, a); + .signed => signed_intFromFloat_f64, + .unsigned => unsigned_intFromFloat_f64, + }(@ptrCast(&actual), a); try testing.expect(expected == actual); } -test "fixdfei" { - try test_fixdfei(i256, -1 << 255, -0x1p255); - try test_fixdfei(i256, -1 << 127, -0x1p127); - try test_fixdfei(i256, -1 << 100, -0x1p100); - try test_fixdfei(i256, -1 << 50, -0x1p50); - try test_fixdfei(i256, -1 << 1, -0x1p1); - try test_fixdfei(i256, -1 << 0, -0x1p0); - try test_fixdfei(i256, 0, 0); - try test_fixdfei(i256, 1 << 0, 0x1p0); - try test_fixdfei(i256, 1 << 1, 0x1p1); - try test_fixdfei(i256, 1 << 50, 0x1p50); - try test_fixdfei(i256, 1 << 100, 0x1p100); - try test_fixdfei(i256, 1 << 127, 0x1p127); - try test_fixdfei(i256, 1 << 254, 0x1p254); -} - -test "fixundfei" { - try test_fixdfei(u256, 0, 0); - try test_fixdfei(u256, 1 << 0, 0x1p0); - try test_fixdfei(u256, 1 << 1, 0x1p1); - try test_fixdfei(u256, 1 << 50, 0x1p50); - try test_fixdfei(u256, 1 << 100, 0x1p100); - try test_fixdfei(u256, 1 << 127, 0x1p127); - try test_fixdfei(u256, 1 << 255, 0x1p255); -} - -fn test__fixtfsi(a: f128, expected: i32) !void { - const x = __fixtfsi(a); - try testing.expect(x == expected); +test signed_intFromFloat_f64 { + try test_intFromFloat_f64(i256, -1 << 255, -0x1p255); + try test_intFromFloat_f64(i256, -1 << 127, -0x1p127); + try test_intFromFloat_f64(i256, -1 << 100, -0x1p100); + try test_intFromFloat_f64(i256, -1 << 50, -0x1p50); + try test_intFromFloat_f64(i256, -1 << 1, -0x1p1); + try test_intFromFloat_f64(i256, -1 << 0, -0x1p0); + try test_intFromFloat_f64(i256, 0, 0); + try test_intFromFloat_f64(i256, 1 << 0, 0x1p0); + try test_intFromFloat_f64(i256, 1 << 1, 0x1p1); + try test_intFromFloat_f64(i256, 1 << 50, 0x1p50); + try test_intFromFloat_f64(i256, 1 << 100, 0x1p100); + try test_intFromFloat_f64(i256, 1 << 127, 0x1p127); + try test_intFromFloat_f64(i256, 1 << 254, 0x1p254); } -fn test__fixunstfsi(a: f128, expected: u32) !void { - const x = __fixunstfsi(a); - try testing.expect(x == expected); +test unsigned_intFromFloat_f64 { + try test_intFromFloat_f64(u256, 0, 0); + try test_intFromFloat_f64(u256, 1 << 0, 0x1p0); + try test_intFromFloat_f64(u256, 1 << 1, 0x1p1); + try test_intFromFloat_f64(u256, 1 << 50, 0x1p50); + try test_intFromFloat_f64(u256, 1 << 100, 0x1p100); + try test_intFromFloat_f64(u256, 1 << 127, 0x1p127); + try test_intFromFloat_f64(u256, 1 << 255, 0x1p255); } -test "fixtfsi" { - try test__fixtfsi(-math.floatMax(f128), math.minInt(i32)); - - try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); - try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); - - try test__fixtfsi(-0x1.0000000000000p+127, -0x80000000); - try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); - try test__fixtfsi(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); - - try test__fixtfsi(-0x1.0000000000001p+63, -0x80000000); - try test__fixtfsi(-0x1.0000000000000p+63, -0x80000000); - try test__fixtfsi(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); - try test__fixtfsi(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); - - try test__fixtfsi(-0x1.FFFFFEp+62, -0x80000000); - try test__fixtfsi(-0x1.FFFFFCp+62, -0x80000000); - - try test__fixtfsi(-0x1.000000p+31, -0x80000000); - try test__fixtfsi(-0x1.FFFFFFp+30, -0x7FFFFFC0); - try test__fixtfsi(-0x1.FFFFFEp+30, -0x7FFFFF80); - try test__fixtfsi(-0x1.FFFFFCp+30, -0x7FFFFF00); - - try test__fixtfsi(-2.01, -2); - try test__fixtfsi(-2.0, -2); - try test__fixtfsi(-1.99, -1); - try test__fixtfsi(-1.0, -1); - try test__fixtfsi(-0.99, 0); - try test__fixtfsi(-0.5, 0); - try test__fixtfsi(-math.floatMin(f32), 0); - try test__fixtfsi(0.0, 0); - try test__fixtfsi(math.floatMin(f32), 0); - try test__fixtfsi(0.5, 0); - try test__fixtfsi(0.99, 0); - try test__fixtfsi(1.0, 1); - try test__fixtfsi(1.5, 1); - try test__fixtfsi(1.99, 1); - try test__fixtfsi(2.0, 2); - try test__fixtfsi(2.01, 2); - - try test__fixtfsi(0x1.FFFFFCp+30, 0x7FFFFF00); - try test__fixtfsi(0x1.FFFFFEp+30, 0x7FFFFF80); - try test__fixtfsi(0x1.FFFFFFp+30, 0x7FFFFFC0); - try test__fixtfsi(0x1.000000p+31, 0x7FFFFFFF); - - try test__fixtfsi(0x1.FFFFFCp+62, 0x7FFFFFFF); - try test__fixtfsi(0x1.FFFFFEp+62, 0x7FFFFFFF); - - try test__fixtfsi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); - try test__fixtfsi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); - try test__fixtfsi(0x1.0000000000000p+63, 0x7FFFFFFF); - try test__fixtfsi(0x1.0000000000001p+63, 0x7FFFFFFF); - - try test__fixtfsi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); - try test__fixtfsi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); - try test__fixtfsi(0x1.0000000000000p+127, 0x7FFFFFFF); - - try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); - try test__fixtfsi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); - - try test__fixtfsi(math.floatMax(f128), math.maxInt(i32)); -} - -test "fixunstfsi" { - try test__fixunstfsi(math.inf(f128), 0xffffffff); - try test__fixunstfsi(0, 0x0); - try test__fixunstfsi(0x1.23456789abcdefp+5, 0x24); - try test__fixunstfsi(0x1.23456789abcdefp-3, 0x0); - try test__fixunstfsi(0x1.23456789abcdefp+20, 0x123456); - try test__fixunstfsi(0x1.23456789abcdefp+40, 0xffffffff); - try test__fixunstfsi(0x1.23456789abcdefp+256, 0xffffffff); - try test__fixunstfsi(-0x1.23456789abcdefp+3, 0x0); - - try test__fixunstfsi(0x1p+32, 0xFFFFFFFF); -} - -fn test__fixtfdi(a: f128, expected: i64) !void { - const x = __fixtfdi(a); +fn test_i32_intFromFloat_f128(a: f128, expected: i32) !void { + const x = i32_intFromFloat_f128(a); try testing.expect(x == expected); } -fn test__fixunstfdi(a: f128, expected: u64) !void { - const x = __fixunstfdi(a); +fn test_u32_intFromFloat_f128(a: f128, expected: u32) !void { + const x = u32_intFromFloat_f128(a); try testing.expect(x == expected); } -test "fixtfdi" { - try test__fixtfdi(-math.floatMax(f128), math.minInt(i64)); - - try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); - try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); - - try test__fixtfdi(-0x1.0000000000000p+127, -0x8000000000000000); - try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); - try test__fixtfdi(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); - - try test__fixtfdi(-0x1.0000000000001p+63, -0x8000000000000000); - try test__fixtfdi(-0x1.0000000000000p+63, -0x8000000000000000); - try test__fixtfdi(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); - try test__fixtfdi(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); - - try test__fixtfdi(-0x1.FFFFFEp+62, -0x7FFFFF8000000000); - try test__fixtfdi(-0x1.FFFFFCp+62, -0x7FFFFF0000000000); - - try test__fixtfdi(-0x1.000000p+31, -0x80000000); - try test__fixtfdi(-0x1.FFFFFFp+30, -0x7FFFFFC0); - try test__fixtfdi(-0x1.FFFFFEp+30, -0x7FFFFF80); - try test__fixtfdi(-0x1.FFFFFCp+30, -0x7FFFFF00); - - try test__fixtfdi(-2.01, -2); - try test__fixtfdi(-2.0, -2); - try test__fixtfdi(-1.99, -1); - try test__fixtfdi(-1.0, -1); - try test__fixtfdi(-0.99, 0); - try test__fixtfdi(-0.5, 0); - try test__fixtfdi(-math.floatMin(f64), 0); - try test__fixtfdi(0.0, 0); - try test__fixtfdi(math.floatMin(f64), 0); - try test__fixtfdi(0.5, 0); - try test__fixtfdi(0.99, 0); - try test__fixtfdi(1.0, 1); - try test__fixtfdi(1.5, 1); - try test__fixtfdi(1.99, 1); - try test__fixtfdi(2.0, 2); - try test__fixtfdi(2.01, 2); - - try test__fixtfdi(0x1.FFFFFCp+30, 0x7FFFFF00); - try test__fixtfdi(0x1.FFFFFEp+30, 0x7FFFFF80); - try test__fixtfdi(0x1.FFFFFFp+30, 0x7FFFFFC0); - try test__fixtfdi(0x1.000000p+31, 0x80000000); - - try test__fixtfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); - try test__fixtfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); - - try test__fixtfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); - try test__fixtfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); - try test__fixtfdi(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); - try test__fixtfdi(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); - - try test__fixtfdi(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); - try test__fixtfdi(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); - try test__fixtfdi(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); - - try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); - try test__fixtfdi(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); - - try test__fixtfdi(math.floatMax(f128), math.maxInt(i64)); -} - -test "fixunstfdi" { - try test__fixunstfdi(0.0, 0); - - try test__fixunstfdi(0.5, 0); - try test__fixunstfdi(0.99, 0); - try test__fixunstfdi(1.0, 1); - try test__fixunstfdi(1.5, 1); - try test__fixunstfdi(1.99, 1); - try test__fixunstfdi(2.0, 2); - try test__fixunstfdi(2.01, 2); - try test__fixunstfdi(-0.5, 0); - try test__fixunstfdi(-0.99, 0); - try test__fixunstfdi(-1.0, 0); - try test__fixunstfdi(-1.5, 0); - try test__fixunstfdi(-1.99, 0); - try test__fixunstfdi(-2.0, 0); - try test__fixunstfdi(-2.01, 0); - - try test__fixunstfdi(0x1.FFFFFEp+62, 0x7FFFFF8000000000); - try test__fixunstfdi(0x1.FFFFFCp+62, 0x7FFFFF0000000000); - - try test__fixunstfdi(-0x1.FFFFFEp+62, 0); - try test__fixunstfdi(-0x1.FFFFFCp+62, 0); - - try test__fixunstfdi(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); - try test__fixunstfdi(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); - - try test__fixunstfdi(-0x1.FFFFFFFFFFFFFp+62, 0); - try test__fixunstfdi(-0x1.FFFFFFFFFFFFEp+62, 0); - - try test__fixunstfdi(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF); - try test__fixunstfdi(0x1.0000000000000002p+63, 0x8000000000000001); - try test__fixunstfdi(0x1.0000000000000000p+63, 0x8000000000000000); - try test__fixunstfdi(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF); - try test__fixunstfdi(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE); - try test__fixunstfdi(0x1p+64, 0xFFFFFFFFFFFFFFFF); - - try test__fixunstfdi(-0x1.0000000000000000p+63, 0); - try test__fixunstfdi(-0x1.FFFFFFFFFFFFFFFCp+62, 0); - try test__fixunstfdi(-0x1.FFFFFFFFFFFFFFF8p+62, 0); -} - -fn test__fixtfti(a: f128, expected: i128) !void { - const x = __fixtfti(a); - try testing.expect(x == expected); +test i32_intFromFloat_f128 { + try test_i32_intFromFloat_f128(-math.floatMax(f128), math.minInt(i32)); + + try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i32)); + try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000); + + try test_i32_intFromFloat_f128(-0x1.0000000000000p+127, -0x80000000); + try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x80000000); + try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x80000000); + + try test_i32_intFromFloat_f128(-0x1.0000000000001p+63, -0x80000000); + try test_i32_intFromFloat_f128(-0x1.0000000000000p+63, -0x80000000); + try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x80000000); + try test_i32_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x80000000); + + try test_i32_intFromFloat_f128(-0x1.FFFFFEp+62, -0x80000000); + try test_i32_intFromFloat_f128(-0x1.FFFFFCp+62, -0x80000000); + + try test_i32_intFromFloat_f128(-0x1.000000p+31, -0x80000000); + try test_i32_intFromFloat_f128(-0x1.FFFFFFp+30, -0x7FFFFFC0); + try test_i32_intFromFloat_f128(-0x1.FFFFFEp+30, -0x7FFFFF80); + try test_i32_intFromFloat_f128(-0x1.FFFFFCp+30, -0x7FFFFF00); + + try test_i32_intFromFloat_f128(-2.01, -2); + try test_i32_intFromFloat_f128(-2.0, -2); + try test_i32_intFromFloat_f128(-1.99, -1); + try test_i32_intFromFloat_f128(-1.0, -1); + try test_i32_intFromFloat_f128(-0.99, 0); + try test_i32_intFromFloat_f128(-0.5, 0); + try test_i32_intFromFloat_f128(-math.floatMin(f32), 0); + try test_i32_intFromFloat_f128(0.0, 0); + try test_i32_intFromFloat_f128(math.floatMin(f32), 0); + try test_i32_intFromFloat_f128(0.5, 0); + try test_i32_intFromFloat_f128(0.99, 0); + try test_i32_intFromFloat_f128(1.0, 1); + try test_i32_intFromFloat_f128(1.5, 1); + try test_i32_intFromFloat_f128(1.99, 1); + try test_i32_intFromFloat_f128(2.0, 2); + try test_i32_intFromFloat_f128(2.01, 2); + + try test_i32_intFromFloat_f128(0x1.FFFFFCp+30, 0x7FFFFF00); + try test_i32_intFromFloat_f128(0x1.FFFFFEp+30, 0x7FFFFF80); + try test_i32_intFromFloat_f128(0x1.FFFFFFp+30, 0x7FFFFFC0); + try test_i32_intFromFloat_f128(0x1.000000p+31, 0x7FFFFFFF); + + try test_i32_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFFFF); + try test_i32_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFFFF); + + try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFF); + try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFF); + try test_i32_intFromFloat_f128(0x1.0000000000000p+63, 0x7FFFFFFF); + try test_i32_intFromFloat_f128(0x1.0000000000001p+63, 0x7FFFFFFF); + + try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFF); + try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFF); + try test_i32_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFF); + + try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFF); + try test_i32_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i32)); + + try test_i32_intFromFloat_f128(math.floatMax(f128), math.maxInt(i32)); } -fn test__fixunstfti(a: f128, expected: u128) !void { - const x = __fixunstfti(a); - try testing.expect(x == expected); +test u32_intFromFloat_f128 { + try test_u32_intFromFloat_f128(math.inf(f128), 0xffffffff); + try test_u32_intFromFloat_f128(0, 0x0); + try test_u32_intFromFloat_f128(0x1.23456789abcdefp+5, 0x24); + try test_u32_intFromFloat_f128(0x1.23456789abcdefp-3, 0x0); + try test_u32_intFromFloat_f128(0x1.23456789abcdefp+20, 0x123456); + try test_u32_intFromFloat_f128(0x1.23456789abcdefp+40, 0xffffffff); + try test_u32_intFromFloat_f128(0x1.23456789abcdefp+256, 0xffffffff); + try test_u32_intFromFloat_f128(-0x1.23456789abcdefp+3, 0x0); + + try test_u32_intFromFloat_f128(0x1p+32, 0xFFFFFFFF); } -test "fixtfti" { - try test__fixtfti(-math.floatMax(f128), math.minInt(i128)); - - try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); - try test__fixtfti(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); - - try test__fixtfti(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); - try test__fixtfti(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000); - try test__fixtfti(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000); - - try test__fixtfti(-0x1.0000000000001p+63, -0x8000000000000800); - try test__fixtfti(-0x1.0000000000000p+63, -0x8000000000000000); - try test__fixtfti(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); - try test__fixtfti(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); - - try test__fixtfti(-0x1.FFFFFEp+62, -0x7fffff8000000000); - try test__fixtfti(-0x1.FFFFFCp+62, -0x7fffff0000000000); +fn test_i64_intFromFloat_f128(a: f128, expected: i64) !void { + const x = i64_intFromFloat_f128(a); + try testing.expect(x == expected); +} - try test__fixtfti(-2.01, -2); - try test__fixtfti(-2.0, -2); - try test__fixtfti(-1.99, -1); - try test__fixtfti(-1.0, -1); - try test__fixtfti(-0.99, 0); - try test__fixtfti(-0.5, 0); - try test__fixtfti(-math.floatMin(f128), 0); - try test__fixtfti(0.0, 0); - try test__fixtfti(math.floatMin(f128), 0); - try test__fixtfti(0.5, 0); - try test__fixtfti(0.99, 0); - try test__fixtfti(1.0, 1); - try test__fixtfti(1.5, 1); - try test__fixtfti(1.99, 1); - try test__fixtfti(2.0, 2); - try test__fixtfti(2.01, 2); +fn test_u64_intFromFloat_f128(a: f128, expected: u64) !void { + const x = u64_intFromFloat_f128(a); + try testing.expect(x == expected); +} - try test__fixtfti(0x1.FFFFFCp+62, 0x7FFFFF0000000000); - try test__fixtfti(0x1.FFFFFEp+62, 0x7FFFFF8000000000); +test i64_intFromFloat_f128 { + try test_i64_intFromFloat_f128(-math.floatMax(f128), math.minInt(i64)); + + try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i64)); + try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x8000000000000000); + + try test_i64_intFromFloat_f128(-0x1.0000000000000p+127, -0x8000000000000000); + try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x8000000000000000); + try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x8000000000000000); + + try test_i64_intFromFloat_f128(-0x1.0000000000001p+63, -0x8000000000000000); + try test_i64_intFromFloat_f128(-0x1.0000000000000p+63, -0x8000000000000000); + try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); + try test_i64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); + + try test_i64_intFromFloat_f128(-0x1.FFFFFEp+62, -0x7FFFFF8000000000); + try test_i64_intFromFloat_f128(-0x1.FFFFFCp+62, -0x7FFFFF0000000000); + + try test_i64_intFromFloat_f128(-0x1.000000p+31, -0x80000000); + try test_i64_intFromFloat_f128(-0x1.FFFFFFp+30, -0x7FFFFFC0); + try test_i64_intFromFloat_f128(-0x1.FFFFFEp+30, -0x7FFFFF80); + try test_i64_intFromFloat_f128(-0x1.FFFFFCp+30, -0x7FFFFF00); + + try test_i64_intFromFloat_f128(-2.01, -2); + try test_i64_intFromFloat_f128(-2.0, -2); + try test_i64_intFromFloat_f128(-1.99, -1); + try test_i64_intFromFloat_f128(-1.0, -1); + try test_i64_intFromFloat_f128(-0.99, 0); + try test_i64_intFromFloat_f128(-0.5, 0); + try test_i64_intFromFloat_f128(-math.floatMin(f64), 0); + try test_i64_intFromFloat_f128(0.0, 0); + try test_i64_intFromFloat_f128(math.floatMin(f64), 0); + try test_i64_intFromFloat_f128(0.5, 0); + try test_i64_intFromFloat_f128(0.99, 0); + try test_i64_intFromFloat_f128(1.0, 1); + try test_i64_intFromFloat_f128(1.5, 1); + try test_i64_intFromFloat_f128(1.99, 1); + try test_i64_intFromFloat_f128(2.0, 2); + try test_i64_intFromFloat_f128(2.01, 2); + + try test_i64_intFromFloat_f128(0x1.FFFFFCp+30, 0x7FFFFF00); + try test_i64_intFromFloat_f128(0x1.FFFFFEp+30, 0x7FFFFF80); + try test_i64_intFromFloat_f128(0x1.FFFFFFp+30, 0x7FFFFFC0); + try test_i64_intFromFloat_f128(0x1.000000p+31, 0x80000000); + + try test_i64_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000); + try test_i64_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000); + + try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); + try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); + try test_i64_intFromFloat_f128(0x1.0000000000000p+63, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f128(0x1.0000000000001p+63, 0x7FFFFFFFFFFFFFFF); + + try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFF); + + try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFF); + try test_i64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i64)); + + try test_i64_intFromFloat_f128(math.floatMax(f128), math.maxInt(i64)); +} - try test__fixtfti(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); - try test__fixtfti(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); - try test__fixtfti(0x1.0000000000000p+63, 0x8000000000000000); - try test__fixtfti(0x1.0000000000001p+63, 0x8000000000000800); +test u64_intFromFloat_f128 { + try test_u64_intFromFloat_f128(0.0, 0); + + try test_u64_intFromFloat_f128(0.5, 0); + try test_u64_intFromFloat_f128(0.99, 0); + try test_u64_intFromFloat_f128(1.0, 1); + try test_u64_intFromFloat_f128(1.5, 1); + try test_u64_intFromFloat_f128(1.99, 1); + try test_u64_intFromFloat_f128(2.0, 2); + try test_u64_intFromFloat_f128(2.01, 2); + try test_u64_intFromFloat_f128(-0.5, 0); + try test_u64_intFromFloat_f128(-0.99, 0); + try test_u64_intFromFloat_f128(-1.0, 0); + try test_u64_intFromFloat_f128(-1.5, 0); + try test_u64_intFromFloat_f128(-1.99, 0); + try test_u64_intFromFloat_f128(-2.0, 0); + try test_u64_intFromFloat_f128(-2.01, 0); + + try test_u64_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000); + try test_u64_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000); + + try test_u64_intFromFloat_f128(-0x1.FFFFFEp+62, 0); + try test_u64_intFromFloat_f128(-0x1.FFFFFCp+62, 0); + + try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); + try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); + + try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, 0); + try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, 0); + + try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFFEp+63, 0xFFFFFFFFFFFFFFFF); + try test_u64_intFromFloat_f128(0x1.0000000000000002p+63, 0x8000000000000001); + try test_u64_intFromFloat_f128(0x1.0000000000000000p+63, 0x8000000000000000); + try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFFCp+62, 0x7FFFFFFFFFFFFFFF); + try test_u64_intFromFloat_f128(0x1.FFFFFFFFFFFFFFF8p+62, 0x7FFFFFFFFFFFFFFE); + try test_u64_intFromFloat_f128(0x1p+64, 0xFFFFFFFFFFFFFFFF); + + try test_u64_intFromFloat_f128(-0x1.0000000000000000p+63, 0); + try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFFFCp+62, 0); + try test_u64_intFromFloat_f128(-0x1.FFFFFFFFFFFFFFF8p+62, 0); +} - try test__fixtfti(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); - try test__fixtfti(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); - try test__fixtfti(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); +fn test_i128_intFromFloat_f128(a: f128, expected: i128) !void { + const x = i128_intFromFloat_f128(a); + try testing.expect(x == expected); +} - try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); - try test__fixtfti(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); +fn test_u128_intFromFloat_f128(a: f128, expected: u128) !void { + const x = u128_intFromFloat_f128(a); + try testing.expect(x == expected); +} - try test__fixtfti(math.floatMax(f128), math.maxInt(i128)); +test i128_intFromFloat_f128 { + try test_i128_intFromFloat_f128(-math.floatMax(f128), math.minInt(i128)); + + try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, math.minInt(i128)); + try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+1023, -0x80000000000000000000000000000000); + + try test_i128_intFromFloat_f128(-0x1.0000000000000p+127, -0x80000000000000000000000000000000); + try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+126, -0x7FFFFFFFFFFFFC000000000000000000); + try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+126, -0x7FFFFFFFFFFFF8000000000000000000); + + try test_i128_intFromFloat_f128(-0x1.0000000000001p+63, -0x8000000000000800); + try test_i128_intFromFloat_f128(-0x1.0000000000000p+63, -0x8000000000000000); + try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFFp+62, -0x7FFFFFFFFFFFFC00); + try test_i128_intFromFloat_f128(-0x1.FFFFFFFFFFFFEp+62, -0x7FFFFFFFFFFFF800); + + try test_i128_intFromFloat_f128(-0x1.FFFFFEp+62, -0x7fffff8000000000); + try test_i128_intFromFloat_f128(-0x1.FFFFFCp+62, -0x7fffff0000000000); + + try test_i128_intFromFloat_f128(-2.01, -2); + try test_i128_intFromFloat_f128(-2.0, -2); + try test_i128_intFromFloat_f128(-1.99, -1); + try test_i128_intFromFloat_f128(-1.0, -1); + try test_i128_intFromFloat_f128(-0.99, 0); + try test_i128_intFromFloat_f128(-0.5, 0); + try test_i128_intFromFloat_f128(-math.floatMin(f128), 0); + try test_i128_intFromFloat_f128(0.0, 0); + try test_i128_intFromFloat_f128(math.floatMin(f128), 0); + try test_i128_intFromFloat_f128(0.5, 0); + try test_i128_intFromFloat_f128(0.99, 0); + try test_i128_intFromFloat_f128(1.0, 1); + try test_i128_intFromFloat_f128(1.5, 1); + try test_i128_intFromFloat_f128(1.99, 1); + try test_i128_intFromFloat_f128(2.0, 2); + try test_i128_intFromFloat_f128(2.01, 2); + + try test_i128_intFromFloat_f128(0x1.FFFFFCp+62, 0x7FFFFF0000000000); + try test_i128_intFromFloat_f128(0x1.FFFFFEp+62, 0x7FFFFF8000000000); + + try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+62, 0x7FFFFFFFFFFFF800); + try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+62, 0x7FFFFFFFFFFFFC00); + try test_i128_intFromFloat_f128(0x1.0000000000000p+63, 0x8000000000000000); + try test_i128_intFromFloat_f128(0x1.0000000000001p+63, 0x8000000000000800); + + try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFEp+126, 0x7FFFFFFFFFFFF8000000000000000000); + try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+126, 0x7FFFFFFFFFFFFC000000000000000000); + try test_i128_intFromFloat_f128(0x1.0000000000000p+127, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + + try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); + try test_i128_intFromFloat_f128(0x1.FFFFFFFFFFFFFp+1023, math.maxInt(i128)); + + try test_i128_intFromFloat_f128(math.floatMax(f128), math.maxInt(i128)); } -test "fixunstfti" { - try test__fixunstfti(math.inf(f128), 0xffffffffffffffffffffffffffffffff); +test u128_intFromFloat_f128 { + try test_u128_intFromFloat_f128(math.inf(f128), 0xffffffffffffffffffffffffffffffff); - try test__fixunstfti(0.0, 0); + try test_u128_intFromFloat_f128(0.0, 0); - try test__fixunstfti(0.5, 0); - try test__fixunstfti(0.99, 0); - try test__fixunstfti(1.0, 1); - try test__fixunstfti(1.5, 1); - try test__fixunstfti(1.99, 1); - try test__fixunstfti(2.0, 2); - try test__fixunstfti(2.01, 2); - try test__fixunstfti(-0.01, 0); - try test__fixunstfti(-0.99, 0); + try test_u128_intFromFloat_f128(0.5, 0); + try test_u128_intFromFloat_f128(0.99, 0); + try test_u128_intFromFloat_f128(1.0, 1); + try test_u128_intFromFloat_f128(1.5, 1); + try test_u128_intFromFloat_f128(1.99, 1); + try test_u128_intFromFloat_f128(2.0, 2); + try test_u128_intFromFloat_f128(2.01, 2); + try test_u128_intFromFloat_f128(-0.01, 0); + try test_u128_intFromFloat_f128(-0.99, 0); - try test__fixunstfti(0x1p+128, 0xffffffffffffffffffffffffffffffff); + try test_u128_intFromFloat_f128(0x1p+128, 0xffffffffffffffffffffffffffffffff); - try test__fixunstfti(0x1.FFFFFEp+126, 0x7fffff80000000000000000000000000); - try test__fixunstfti(0x1.FFFFFEp+127, 0xffffff00000000000000000000000000); - try test__fixunstfti(0x1.FFFFFEp+128, 0xffffffffffffffffffffffffffffffff); - try test__fixunstfti(0x1.FFFFFEp+129, 0xffffffffffffffffffffffffffffffff); + try test_u128_intFromFloat_f128(0x1.FFFFFEp+126, 0x7fffff80000000000000000000000000); + try test_u128_intFromFloat_f128(0x1.FFFFFEp+127, 0xffffff00000000000000000000000000); + try test_u128_intFromFloat_f128(0x1.FFFFFEp+128, 0xffffffffffffffffffffffffffffffff); + try test_u128_intFromFloat_f128(0x1.FFFFFEp+129, 0xffffffffffffffffffffffffffffffff); } -fn test__fixunshfti(a: f16, expected: u128) !void { - const x = __fixunshfti(a); +fn test_u128_intFromFloat_f16(a: f16, expected: u128) !void { + const x = impl.u128_intFromFloat_f16(a); try testing.expect(x == expected); } -test "fixunshfti for f16" { - try test__fixunshfti(math.inf(f16), math.maxInt(u128)); - try test__fixunshfti(math.floatMax(f16), 65504); +test u128_intFromFloat_f16 { + try test_u128_intFromFloat_f16(math.inf(f16), math.maxInt(u128)); + try test_u128_intFromFloat_f16(math.floatMax(f16), 65504); } -fn test__fixunsxfti(a: f80, expected: u128) !void { - const x = __fixunsxfti(a); +fn test_u128_intFromFloat_f80(a: f80, expected: u128) !void { + const x = impl.u128_intFromFloat_f80(a); try testing.expect(x == expected); } -test "fixunsxfti for f80" { - try test__fixunsxfti(math.inf(f80), math.maxInt(u128)); - try test__fixunsxfti(math.floatMax(f80), math.maxInt(u128)); - try test__fixunsxfti(math.maxInt(u64), math.maxInt(u64)); +test u128_intFromFloat_f80 { + try test_u128_intFromFloat_f80(math.inf(f80), math.maxInt(u128)); + try test_u128_intFromFloat_f80(math.floatMax(f80), math.maxInt(u128)); + try test_u128_intFromFloat_f80(math.maxInt(u64), math.maxInt(u64)); } diff --git a/lib/compiler_rt/limb64.zig b/lib/compiler_rt/limb64.zig index bfe4c441f0525b2e7f5e858e3fa98f81a2e9c865..1d41c0ff1f673c4822b69ccbf0eee69faad19b51 100644 --- a/lib/compiler_rt/limb64.zig +++ b/lib/compiler_rt/limb64.zig @@ -6,7 +6,7 @@ const minInt = std.math.minInt; const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; +const symbol = compiler_rt.symbol; const endian = builtin.cpu.arch.endian(); diff --git a/lib/compiler_rt/log.zig b/lib/compiler_rt/log.zig index da3757d8224c2ab62e88affd269170b5c64cae6b..9f632f69ff93a9c05663104c5429c7c8e787e761 100644 --- a/lib/compiler_rt/log.zig +++ b/lib/compiler_rt/log.zig @@ -11,7 +11,7 @@ const expectEqual = std.testing.expectEqual; const expectApproxEqRel = std.testing.expectApproxEqRel; const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; +const symbol = compiler_rt.symbol; comptime { symbol(&__logh, "__logh"); @@ -25,12 +25,18 @@ comptime { symbol(&logl, "logl"); } -pub fn __logh(a: f16) callconv(.c) f16 { +fn __logh(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(log_f16(compiler_rt.f16.fromAbi(a))); +} +pub fn log_f16(a: f16) f16 { // TODO: more efficient implementation - return @floatCast(logf(a)); + return @floatCast(log_f32(a)); } -pub fn logf(x_: f32) callconv(.c) f32 { +fn logf(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(log_f32(compiler_rt.f32.fromAbi(a))); +} +pub fn log_f32(x_: f32) f32 { const ln2_hi: f32 = 6.9313812256e-01; const ln2_lo: f32 = 9.0580006145e-06; const Lg1: f32 = 0xaaaaaa.0p-24; @@ -82,7 +88,10 @@ pub fn logf(x_: f32) callconv(.c) f32 { return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; } -pub fn log(x: f64) callconv(.c) f64 { +fn log(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(log_f64(compiler_rt.f64.fromAbi(a))); +} +pub fn log_f64(x: f64) f64 { const poly1 = [_]f64{ -0x1p-1, 0x1.5555555555577p-2, @@ -432,11 +441,17 @@ pub fn log(x: f64) callconv(.c) f64 { return @bitCast(y); } -pub fn __logx(a: f80) callconv(.c) f80 { +fn __logx(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(log_f80(compiler_rt.f80.fromAbi(a))); +} +pub fn log_f80(a: f80) f80 { // TODO: more efficient implementation - return @floatCast(logq(a)); + return @floatCast(log_f128(a)); } +fn logq(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(log_f128(compiler_rt.f128.fromAbi(a))); +} /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 /// @@ -449,7 +464,7 @@ pub fn __logx(a: f80) callconv(.c) f80 { /// /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): /// <= 0.5 ulp: 99.96%, worst case <= 0.528 ulp -pub fn logq(x: f128) callconv(.c) f128 { +pub fn log_f128(x: f128) f128 { const impl = @import("log_f128.zig"); if (impl.specialCases(x)) |y| @@ -626,123 +641,123 @@ pub fn logq(x: f128) callconv(.c) f128 { pub fn logl(x: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return log(x), - 80 => return __logx(x), - 128 => return logq(x), - else => @compileError("unreachable"), + 64 => return log_f64(x), + 80 => return log_f80(x), + 128 => return log_f128(x), + else => comptime unreachable, } } test "logf() special" { - try expectEqual(logf(0.0), -math.inf(f32)); - try expectEqual(logf(-0.0), -math.inf(f32)); - try expect(math.isPositiveZero(logf(1.0))); - try expectEqual(logf(math.e), 1.0); - try expectEqual(logf(math.inf(f32)), math.inf(f32)); - try expect(math.isNan(logf(-1.0))); - try expect(math.isNan(logf(-math.inf(f32)))); - try expect(math.isNan(logf(math.nan(f32)))); - try expect(math.isNan(logf(math.snan(f32)))); + try expectEqual(log_f32(0.0), -math.inf(f32)); + try expectEqual(log_f32(-0.0), -math.inf(f32)); + try expect(math.isPositiveZero(log_f32(1.0))); + try expectEqual(log_f32(math.e), 1.0); + try expectEqual(log_f32(math.inf(f32)), math.inf(f32)); + try expect(math.isNan(log_f32(-1.0))); + try expect(math.isNan(log_f32(-math.inf(f32)))); + try expect(math.isNan(log_f32(math.nan(f32)))); + try expect(math.isNan(log_f32(math.snan(f32)))); } test "logf() sanity" { - try expect(math.isNan(logf(-0x1.0223a0p+3))); - try expectEqual(logf(0x1.161868p+2), 0x1.7815b0p+0); - try expect(math.isNan(logf(-0x1.0c34b4p+3))); - try expect(math.isNan(logf(-0x1.a206f0p+2))); - try expectEqual(logf(0x1.288bbcp+3), 0x1.1cfcd6p+1); - try expectEqual(logf(0x1.52efd0p-1), -0x1.a6694cp-2); - try expect(math.isNan(logf(-0x1.a05cc8p-2))); - try expectEqual(logf(0x1.1f9efap-1), -0x1.2742bap-1); - try expectEqual(logf(0x1.8c5db0p-1), -0x1.062160p-2); - try expect(math.isNan(logf(-0x1.5b86eap-1))); + try expect(math.isNan(log_f32(-0x1.0223a0p+3))); + try expectEqual(log_f32(0x1.161868p+2), 0x1.7815b0p+0); + try expect(math.isNan(log_f32(-0x1.0c34b4p+3))); + try expect(math.isNan(log_f32(-0x1.a206f0p+2))); + try expectEqual(log_f32(0x1.288bbcp+3), 0x1.1cfcd6p+1); + try expectEqual(log_f32(0x1.52efd0p-1), -0x1.a6694cp-2); + try expect(math.isNan(log_f32(-0x1.a05cc8p-2))); + try expectEqual(log_f32(0x1.1f9efap-1), -0x1.2742bap-1); + try expectEqual(log_f32(0x1.8c5db0p-1), -0x1.062160p-2); + try expect(math.isNan(log_f32(-0x1.5b86eap-1))); } test "logf() boundary" { - try expectEqual(logf(0x1.fffffep+127), 0x1.62e430p+6); // Max input value - try expectEqual(logf(0x1p-149), -0x1.9d1da0p+6); // Min positive input value - try expect(math.isNan(logf(-0x1p-149))); // Min negative input value - try expectEqual(logf(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0 - try expectEqual(logf(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0 - try expectEqual(logf(0x1p-126), -0x1.5d58a0p+6); // First subnormal - try expect(math.isNan(logf(-0x1p-126))); // First negative subnormal + try expectEqual(log_f32(0x1.fffffep+127), 0x1.62e430p+6); // Max input value + try expectEqual(log_f32(0x1p-149), -0x1.9d1da0p+6); // Min positive input value + try expect(math.isNan(log_f32(-0x1p-149))); // Min negative input value + try expectEqual(log_f32(0x1.000002p+0), 0x1.fffffep-24); // Last value before result reaches +0 + try expectEqual(log_f32(0x1.fffffep-1), -0x1p-24); // Last value before result reaches -0 + try expectEqual(log_f32(0x1p-126), -0x1.5d58a0p+6); // First subnormal + try expect(math.isNan(log_f32(-0x1p-126))); // First negative subnormal } test "log() special" { - try expectEqual(log(0.0), -math.inf(f64)); - try expectEqual(log(-0.0), -math.inf(f64)); - try expect(math.isPositiveZero(log(1.0))); - try expectEqual(log(math.e), 1.0); - try expectEqual(log(math.inf(f64)), math.inf(f64)); - try expect(math.isNan(log(-1.0))); - try expect(math.isNan(log(-math.inf(f64)))); - try expect(math.isNan(log(math.nan(f64)))); - try expect(math.isNan(log(math.snan(f64)))); + try expectEqual(log_f64(0.0), -math.inf(f64)); + try expectEqual(log_f64(-0.0), -math.inf(f64)); + try expect(math.isPositiveZero(log_f64(1.0))); + try expectEqual(log_f64(math.e), 1.0); + try expectEqual(log_f64(math.inf(f64)), math.inf(f64)); + try expect(math.isNan(log_f64(-1.0))); + try expect(math.isNan(log_f64(-math.inf(f64)))); + try expect(math.isNan(log_f64(math.nan(f64)))); + try expect(math.isNan(log_f64(math.snan(f64)))); } test "log() sanity" { - try expect(math.isNan(log(-0x1.02239f3c6a8f1p+3))); - try expectEqual(log(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0); - try expect(math.isNan(log(-0x1.0c34b3e01e6e7p+3))); - try expect(math.isNan(log(-0x1.a206f0a19dcc4p+2))); - try expectEqual(log(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1); - try expectEqual(log(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2); - try expect(math.isNan(log(-0x1.a05cc754481d1p-2))); - try expectEqual(log(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1); - try expectEqual(log(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2); - try expect(math.isNan(log(-0x1.5b86ea8118a0ep-1))); + try expect(math.isNan(log_f64(-0x1.02239f3c6a8f1p+3))); + try expectEqual(log_f64(0x1.161868e18bc67p+2), 0x1.7815b08f99c65p+0); + try expect(math.isNan(log_f64(-0x1.0c34b3e01e6e7p+3))); + try expect(math.isNan(log_f64(-0x1.a206f0a19dcc4p+2))); + try expectEqual(log_f64(0x1.288bbb0d6a1e6p+3), 0x1.1cfcd53d72604p+1); + try expectEqual(log_f64(0x1.52efd0cd80497p-1), -0x1.a6694a4a85621p-2); + try expect(math.isNan(log_f64(-0x1.a05cc754481d1p-2))); + try expectEqual(log_f64(0x1.1f9ef934745cbp-1), -0x1.2742bc03d02ddp-1); + try expectEqual(log_f64(0x1.8c5db097f7442p-1), -0x1.06215de4a3f92p-2); + try expect(math.isNan(log_f64(-0x1.5b86ea8118a0ep-1))); } test "log() boundary" { - try expectEqual(log(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value - try expectEqual(log(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value - try expect(math.isNan(log(-0x1p-1074))); // Min negative input value - try expectEqual(log(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0 - try expectEqual(log(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0 - try expectEqual(log(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal - try expect(math.isNan(log(-0x1p-1022))); // First negative subnormal + try expectEqual(log_f64(0x1.fffffffffffffp+1023), 0x1.62e42fefa39efp+9); // Max input value + try expectEqual(log_f64(0x1p-1074), -0x1.74385446d71c3p+9); // Min positive input value + try expect(math.isNan(log_f64(-0x1p-1074))); // Min negative input value + try expectEqual(log_f64(0x1.0000000000001p+0), 0x1.fffffffffffffp-53); // Last value before result reaches +0 + try expectEqual(log_f64(0x1.fffffffffffffp-1), -0x1p-53); // Last value before result reaches -0 + try expectEqual(log_f64(0x1p-1022), -0x1.6232bdd7abcd2p+9); // First subnormal + try expect(math.isNan(log_f64(-0x1p-1022))); // First negative subnormal } test "logq() special" { - try expectEqual(logq(0.0), -math.inf(f128)); - try expectEqual(logq(-0.0), -math.inf(f128)); - try expect(math.isPositiveZero(logq(1.0))); + try expectEqual(log_f128(0.0), -math.inf(f128)); + try expectEqual(log_f128(-0.0), -math.inf(f128)); + try expect(math.isPositiveZero(log_f128(1.0))); // Sadly, the rounding gods decided that 0.9999999999999999999999999999999999 - // is the correctly rounded value of logq(math.e) - try expectApproxEqRel(logq(math.e), 1.0, math.floatEpsAt(f128, 1.0)); - try expectEqual(logq(math.inf(f128)), math.inf(f128)); - try expect(math.isNan(logq(-1.0))); - try expect(math.isNan(logq(-math.inf(f128)))); - try expect(math.isNan(logq(math.nan(f128)))); - try expect(math.isNan(logq(math.snan(f128)))); + // is the correctly rounded value of log_f128(math.e) + try expectApproxEqRel(log_f128(math.e), 1.0, math.floatEpsAt(f128, 1.0)); + try expectEqual(log_f128(math.inf(f128)), math.inf(f128)); + try expect(math.isNan(log_f128(-1.0))); + try expect(math.isNan(log_f128(-math.inf(f128)))); + try expect(math.isNan(log_f128(math.nan(f128)))); + try expect(math.isNan(log_f128(math.snan(f128)))); } test "logq() boundary" { - try expectEqual(logq(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value - try expectEqual(logq(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value - try expect(math.isNan(logq(-0x1p-16494))); // Min negative input value - try expectEqual(logq(0x1.0000000000000000000000000001p0), 0x1.ffffffffffffffffffffffffffffp-113); // Last value before result reaches +0 - try expectEqual(logq(0x1.ffffffffffffffffffffffffffffp-1), -0x1p-113); // Last value before result reaches -0 - try expectEqual(logq(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal - try expect(math.isNan(logq(-0x1p-16382))); // First negative subnormal + try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.62e42fefa39ef35793c7673007e6p13); // Max input value + try expectEqual(log_f128(0x1p-16494), -0x1.6546282207802c89d24d65e96274p13); // Min positive input value + try expect(math.isNan(log_f128(-0x1p-16494))); // Min negative input value + try expectEqual(log_f128(0x1.0000000000000000000000000001p0), 0x1.ffffffffffffffffffffffffffffp-113); // Last value before result reaches +0 + try expectEqual(log_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1p-113); // Last value before result reaches -0 + try expectEqual(log_f128(0x1p-16382), -0x1.62d918ce2421d65ff90ac8f4ce66p13); // First subnormal + try expect(math.isNan(log_f128(-0x1p-16382))); // First negative subnormal } test "logq() sanity" { - try expectEqual(logq(4.151135979023751199079583784623537e-4), -7.7869583453055243113993340258295346e0); - try expectEqual(logq(9.614234245933828353176667689130293e-14), -2.9972946567656004014786271559909435e1); - try expectEqual(logq(1.012889803704721484375e13), 2.9946413646144315985379677542014356e1); - try expectEqual(logq(2.397741857206453154086912e24), 5.613656963346284538829358703465392e1); - try expectEqual(logq(3.442377567808290806386655232e27), 6.3405959896920645453203836625419693e1); - try expectEqual(logq(1.0689155158234028407981544637594257e-8), -1.835403614606774451014272772421113e1); - try expectEqual(logq(1.4813913545768791536741499811327596e-10), -2.263286917934202003739900705050399e1); - try expectEqual(logq(4.518948965781299591064453125e10), 2.453413036705097282892685629562292e1); - try expectEqual(logq(1.200355637363589375e14), 3.2418809179272977400408325788186897e1); - try expectEqual(logq(6.6145398293682003021240234375e9), 2.261253606737223221601998075023261e1); - try expectEqual(logq(5.16179116383965741056e20), 4.7692985503915646405875629300054525e1); + try expectEqual(log_f128(4.151135979023751199079583784623537e-4), -7.7869583453055243113993340258295346e0); + try expectEqual(log_f128(9.614234245933828353176667689130293e-14), -2.9972946567656004014786271559909435e1); + try expectEqual(log_f128(1.012889803704721484375e13), 2.9946413646144315985379677542014356e1); + try expectEqual(log_f128(2.397741857206453154086912e24), 5.613656963346284538829358703465392e1); + try expectEqual(log_f128(3.442377567808290806386655232e27), 6.3405959896920645453203836625419693e1); + try expectEqual(log_f128(1.0689155158234028407981544637594257e-8), -1.835403614606774451014272772421113e1); + try expectEqual(log_f128(1.4813913545768791536741499811327596e-10), -2.263286917934202003739900705050399e1); + try expectEqual(log_f128(4.518948965781299591064453125e10), 2.453413036705097282892685629562292e1); + try expectEqual(log_f128(1.200355637363589375e14), 3.2418809179272977400408325788186897e1); + try expectEqual(log_f128(6.6145398293682003021240234375e9), 2.261253606737223221601998075023261e1); + try expectEqual(log_f128(5.16179116383965741056e20), 4.7692985503915646405875629300054525e1); // testing near 1 - try expectEqual(logq(1.026586845186097528392910049888087e0), 2.6239557099466251374193777672800004e-2); - try expectEqual(logq(9.878220373715243107115568932385941e-1), -1.2252721576456821219120474521538944e-2); - try expectEqual(logq(9.417921077517196685541245315675951e-1), -5.997072116986790367958922503195352e-2); - try expectEqual(logq(1.043095786320424537962914257605007e0), 4.219300911769055080390811808602425e-2); - try expectEqual(logq(1.019043049323190694932517175175235e0), 1.8863999985309781522599012445793722e-2); + try expectEqual(log_f128(1.026586845186097528392910049888087e0), 2.6239557099466251374193777672800004e-2); + try expectEqual(log_f128(9.878220373715243107115568932385941e-1), -1.2252721576456821219120474521538944e-2); + try expectEqual(log_f128(9.417921077517196685541245315675951e-1), -5.997072116986790367958922503195352e-2); + try expectEqual(log_f128(1.043095786320424537962914257605007e0), 4.219300911769055080390811808602425e-2); + try expectEqual(log_f128(1.019043049323190694932517175175235e0), 1.8863999985309781522599012445793722e-2); } diff --git a/lib/compiler_rt/log10.zig b/lib/compiler_rt/log10.zig index 18479d534a347721c842b682228f29688213909c..6a554e0ea79ff597dfdeeea31477e1c6ebfbac1c 100644 --- a/lib/compiler_rt/log10.zig +++ b/lib/compiler_rt/log10.zig @@ -25,12 +25,18 @@ comptime { symbol(&log10l, "log10l"); } -pub fn __log10h(a: f16) callconv(.c) f16 { +fn __log10h(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(log10_f16(compiler_rt.f16.fromAbi(a))); +} +pub fn log10_f16(a: f16) f16 { // TODO: more efficient implementation - return @floatCast(log10f(a)); + return @floatCast(log10_f32(a)); } -pub fn log10f(x_: f32) callconv(.c) f32 { +fn log10f(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(log10_f32(compiler_rt.f32.fromAbi(a))); +} +pub fn log10_f32(x_: f32) f32 { const ivln10hi: f32 = 4.3432617188e-01; const ivln10lo: f32 = -3.1689971365e-05; const log10_2hi: f32 = 3.0102920532e-01; @@ -90,7 +96,10 @@ pub fn log10f(x_: f32) callconv(.c) f32 { return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi; } -pub fn log10(x_: f64) callconv(.c) f64 { +fn log10(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(log10_f64(compiler_rt.f64.fromAbi(a))); +} +pub fn log10_f64(x_: f64) f64 { const ivln10hi: f64 = 4.34294481878168880939e-01; const ivln10lo: f64 = 2.50829467116452752298e-11; const log10_2hi: f64 = 3.01029995663611771306e-01; @@ -165,11 +174,17 @@ pub fn log10(x_: f64) callconv(.c) f64 { return val_lo + val_hi; } -pub fn __log10x(a: f80) callconv(.c) f80 { +fn __log10x(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(log10_f80(compiler_rt.f80.fromAbi(a))); +} +pub fn log10_f80(a: f80) f80 { // TODO: more efficient implementation - return @floatCast(log10q(a)); + return @floatCast(log10_f128(a)); } +fn log10q(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(log10_f128(compiler_rt.f128.fromAbi(a))); +} /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 /// @@ -182,7 +197,7 @@ pub fn __log10x(a: f80) callconv(.c) f80 { /// /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): /// <= 0.5 ulp: 99.96%, worst case <= 0.565 ulp -pub fn log10q(x: f128) callconv(.c) f128 { +pub fn log10_f128(x: f128) f128 { const impl = @import("log_f128.zig"); if (impl.specialCases(x)) |y| @@ -359,124 +374,124 @@ pub fn log10q(x: f128) callconv(.c) f128 { pub fn log10l(x: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return log10(x), - 80 => return __log10x(x), - 128 => return log10q(x), - else => @compileError("unreachable"), + 64 => return log10_f64(x), + 80 => return log10_f80(x), + 128 => return log10_f128(x), + else => comptime unreachable, } } test "log10f() special" { - try expectEqual(log10f(0.0), -math.inf(f32)); - try expectEqual(log10f(-0.0), -math.inf(f32)); - try expect(math.isPositiveZero(log10f(1.0))); - try expectEqual(log10f(10.0), 1.0); - try expectEqual(log10f(0.1), -1.0); - try expectEqual(log10f(math.inf(f32)), math.inf(f32)); - try expect(math.isNan(log10f(-1.0))); - try expect(math.isNan(log10f(-math.inf(f32)))); - try expect(math.isNan(log10f(math.nan(f32)))); - try expect(math.isNan(log10f(math.snan(f32)))); + try expectEqual(log10_f32(0.0), -math.inf(f32)); + try expectEqual(log10_f32(-0.0), -math.inf(f32)); + try expect(math.isPositiveZero(log10_f32(1.0))); + try expectEqual(log10_f32(10.0), 1.0); + try expectEqual(log10_f32(0.1), -1.0); + try expectEqual(log10_f32(math.inf(f32)), math.inf(f32)); + try expect(math.isNan(log10_f32(-1.0))); + try expect(math.isNan(log10_f32(-math.inf(f32)))); + try expect(math.isNan(log10_f32(math.nan(f32)))); + try expect(math.isNan(log10_f32(math.snan(f32)))); } test "log10f() sanity" { - try expect(math.isNan(log10f(-0x1.0223a0p+3))); - try expectEqual(log10f(0x1.161868p+2), 0x1.46a9bcp-1); - try expect(math.isNan(log10f(-0x1.0c34b4p+3))); - try expect(math.isNan(log10f(-0x1.a206f0p+2))); - try expectEqual(log10f(0x1.288bbcp+3), 0x1.ef1300p-1); - try expectEqual(log10f(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit - try expect(math.isNan(log10f(-0x1.a05cc8p-2))); - try expectEqual(log10f(0x1.1f9efap-1), -0x1.0075ccp-2); - try expectEqual(log10f(0x1.8c5db0p-1), -0x1.c75df8p-4); - try expect(math.isNan(log10f(-0x1.5b86eap-1))); + try expect(math.isNan(log10_f32(-0x1.0223a0p+3))); + try expectEqual(log10_f32(0x1.161868p+2), 0x1.46a9bcp-1); + try expect(math.isNan(log10_f32(-0x1.0c34b4p+3))); + try expect(math.isNan(log10_f32(-0x1.a206f0p+2))); + try expectEqual(log10_f32(0x1.288bbcp+3), 0x1.ef1300p-1); + try expectEqual(log10_f32(0x1.52efd0p-1), -0x1.6ee6dcp-3); // Disagrees with GCC in last bit + try expect(math.isNan(log10_f32(-0x1.a05cc8p-2))); + try expectEqual(log10_f32(0x1.1f9efap-1), -0x1.0075ccp-2); + try expectEqual(log10_f32(0x1.8c5db0p-1), -0x1.c75df8p-4); + try expect(math.isNan(log10_f32(-0x1.5b86eap-1))); } test "log10f() boundary" { - try expectEqual(log10f(0x1.fffffep+127), 0x1.344136p+5); // Max input value - try expectEqual(log10f(0x1p-149), -0x1.66d3e8p+5); // Min positive input value - try expect(math.isNan(log10f(-0x1p-149))); // Min negative input value - try expectEqual(log10f(0x1.000002p+0), 0x1.bcb7b0p-25); // Last value before result reaches +0 - try expectEqual(log10f(0x1.fffffep-1), -0x1.bcb7b2p-26); // Last value before result reaches -0 - try expectEqual(log10f(0x1p-126), -0x1.2f7030p+5); // First subnormal - try expect(math.isNan(log10f(-0x1p-126))); // First negative subnormal + try expectEqual(log10_f32(0x1.fffffep+127), 0x1.344136p+5); // Max input value + try expectEqual(log10_f32(0x1p-149), -0x1.66d3e8p+5); // Min positive input value + try expect(math.isNan(log10_f32(-0x1p-149))); // Min negative input value + try expectEqual(log10_f32(0x1.000002p+0), 0x1.bcb7b0p-25); // Last value before result reaches +0 + try expectEqual(log10_f32(0x1.fffffep-1), -0x1.bcb7b2p-26); // Last value before result reaches -0 + try expectEqual(log10_f32(0x1p-126), -0x1.2f7030p+5); // First subnormal + try expect(math.isNan(log10_f32(-0x1p-126))); // First negative subnormal } test "log10() special" { - try expectEqual(log10(0.0), -math.inf(f64)); - try expectEqual(log10(-0.0), -math.inf(f64)); - try expect(math.isPositiveZero(log10(1.0))); - try expectEqual(log10(10.0), 1.0); - try expectEqual(log10(0.1), -1.0); - try expectEqual(log10(math.inf(f64)), math.inf(f64)); - try expect(math.isNan(log10(-1.0))); - try expect(math.isNan(log10(-math.inf(f64)))); - try expect(math.isNan(log10(math.nan(f64)))); - try expect(math.isNan(log10(math.snan(f64)))); + try expectEqual(log10_f64(0.0), -math.inf(f64)); + try expectEqual(log10_f64(-0.0), -math.inf(f64)); + try expect(math.isPositiveZero(log10_f64(1.0))); + try expectEqual(log10_f64(10.0), 1.0); + try expectEqual(log10_f64(0.1), -1.0); + try expectEqual(log10_f64(math.inf(f64)), math.inf(f64)); + try expect(math.isNan(log10_f64(-1.0))); + try expect(math.isNan(log10_f64(-math.inf(f64)))); + try expect(math.isNan(log10_f64(math.nan(f64)))); + try expect(math.isNan(log10_f64(math.snan(f64)))); } test "log10() sanity" { - try expect(math.isNan(log10(-0x1.02239f3c6a8f1p+3))); - try expectEqual(log10(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1); - try expect(math.isNan(log10(-0x1.0c34b3e01e6e7p+3))); - try expect(math.isNan(log10(-0x1.a206f0a19dcc4p+2))); - try expectEqual(log10(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1); - try expectEqual(log10(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3); - try expect(math.isNan(log10(-0x1.a05cc754481d1p-2))); - try expectEqual(log10(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2); - try expectEqual(log10(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4); - try expect(math.isNan(log10(-0x1.5b86ea8118a0ep-1))); + try expect(math.isNan(log10_f64(-0x1.02239f3c6a8f1p+3))); + try expectEqual(log10_f64(0x1.161868e18bc67p+2), 0x1.46a9bd1d2eb87p-1); + try expect(math.isNan(log10_f64(-0x1.0c34b3e01e6e7p+3))); + try expect(math.isNan(log10_f64(-0x1.a206f0a19dcc4p+2))); + try expectEqual(log10_f64(0x1.288bbb0d6a1e6p+3), 0x1.ef12fff994862p-1); + try expectEqual(log10_f64(0x1.52efd0cd80497p-1), -0x1.6ee6db5a155cbp-3); + try expect(math.isNan(log10_f64(-0x1.a05cc754481d1p-2))); + try expectEqual(log10_f64(0x1.1f9ef934745cbp-1), -0x1.0075cda79d321p-2); + try expectEqual(log10_f64(0x1.8c5db097f7442p-1), -0x1.c75df6442465ap-4); + try expect(math.isNan(log10_f64(-0x1.5b86ea8118a0ep-1))); } test "log10() boundary" { - try expectEqual(log10(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value - try expectEqual(log10(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value - try expect(math.isNan(log10(-0x1p-1074))); // Min negative input value - try expectEqual(log10(0x1.0000000000001p+0), 0x1.bcb7b1526e50dp-54); // Last value before result reaches +0 - try expectEqual(log10(0x1.fffffffffffffp-1), -0x1.bcb7b1526e50fp-55); // Last value before result reaches -0 - try expectEqual(log10(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal - try expect(math.isNan(log10(-0x1p-1022))); // First negative subnormal + try expectEqual(log10_f64(0x1.fffffffffffffp+1023), 0x1.34413509f79ffp+8); // Max input value + try expectEqual(log10_f64(0x1p-1074), -0x1.434e6420f4374p+8); // Min positive input value + try expect(math.isNan(log10_f64(-0x1p-1074))); // Min negative input value + try expectEqual(log10_f64(0x1.0000000000001p+0), 0x1.bcb7b1526e50dp-54); // Last value before result reaches +0 + try expectEqual(log10_f64(0x1.fffffffffffffp-1), -0x1.bcb7b1526e50fp-55); // Last value before result reaches -0 + try expectEqual(log10_f64(0x1p-1022), -0x1.33a7146f72a42p+8); // First subnormal + try expect(math.isNan(log10_f64(-0x1p-1022))); // First negative subnormal } test "log10q() special" { - try expectEqual(log10q(0.0), -math.inf(f128)); - try expectEqual(log10q(-0.0), -math.inf(f128)); - try expect(math.isPositiveZero(log10q(1.0))); - try expectEqual(log10q(10.0), 1.0); - try expectEqual(log10q(0.1), -1.0); - try expectEqual(log10q(math.inf(f128)), math.inf(f128)); - try expect(math.isNan(log10q(-1.0))); - try expect(math.isNan(log10q(-math.inf(f128)))); - try expect(math.isNan(log10q(math.nan(f128)))); - try expect(math.isNan(log10q(math.snan(f128)))); + try expectEqual(log10_f128(0.0), -math.inf(f128)); + try expectEqual(log10_f128(-0.0), -math.inf(f128)); + try expect(math.isPositiveZero(log10_f128(1.0))); + try expectEqual(log10_f128(10.0), 1.0); + try expectEqual(log10_f128(0.1), -1.0); + try expectEqual(log10_f128(math.inf(f128)), math.inf(f128)); + try expect(math.isNan(log10_f128(-1.0))); + try expect(math.isNan(log10_f128(-math.inf(f128)))); + try expect(math.isNan(log10_f128(math.nan(f128)))); + try expect(math.isNan(log10_f128(math.snan(f128)))); } test "log10q() sanity" { - try expectEqual(log10q(2.1744503117482705706605762784484114e1949), 1.949337349488073972035715318447419e3); - try expectEqual(log10q(2.3695331993665660983204066767386505e2150), 2.1503746627979481420243846411400265e3); - try expectEqual(log10q(1.8071775728314983136779370752110857e612), 6.122570008283284411311428111991705e2); - try expectEqual(log10q(2.612170297226630737309271722008693e-2629), -2.628582998513179919647069989114319e3); - try expectEqual(log10q(8.485091636263895897993044621224502e-3748), -3.7470713434630800881474518447042895e3); - try expectEqual(log10q(4.3668077579803801413736022136116655e-4051), -4.0503598359268068567757367259544416e3); - try expectEqual(log10q(2.9321353260885285826237030859036923e4830), 4.830467184010313310864606285356782e3); - try expectEqual(log10q(6.6119754254652455408442826553161645e-1417), -1.416179668769227128601620567685071e3); - try expectEqual(log10q(5.2459104673488555418645321788108695e4178), 4.178719820874155944446586083585479e3); - try expectEqual(log10q(7.809812890804996586377267218360886e-418), -4.1710735937091966815220294599598215e2); + try expectEqual(log10_f128(2.1744503117482705706605762784484114e1949), 1.949337349488073972035715318447419e3); + try expectEqual(log10_f128(2.3695331993665660983204066767386505e2150), 2.1503746627979481420243846411400265e3); + try expectEqual(log10_f128(1.8071775728314983136779370752110857e612), 6.122570008283284411311428111991705e2); + try expectEqual(log10_f128(2.612170297226630737309271722008693e-2629), -2.628582998513179919647069989114319e3); + try expectEqual(log10_f128(8.485091636263895897993044621224502e-3748), -3.7470713434630800881474518447042895e3); + try expectEqual(log10_f128(4.3668077579803801413736022136116655e-4051), -4.0503598359268068567757367259544416e3); + try expectEqual(log10_f128(2.9321353260885285826237030859036923e4830), 4.830467184010313310864606285356782e3); + try expectEqual(log10_f128(6.6119754254652455408442826553161645e-1417), -1.416179668769227128601620567685071e3); + try expectEqual(log10_f128(5.2459104673488555418645321788108695e4178), 4.178719820874155944446586083585479e3); + try expectEqual(log10_f128(7.809812890804996586377267218360886e-418), -4.1710735937091966815220294599598215e2); // testing near 1 - try expectEqual(log10q(1.0291437165967803055610652052109798e0), 1.2476026819466393459130418401605807e-2); - try expectEqual(log10q(1.043095786320424537962914257605007e0), 1.8324191034706598279642145362763252e-2); - try expectEqual(log10q(9.900264873754467234601150948947179e-1), -4.3531860417287584780652055666513634e-3); - try expectEqual(log10q(1.038295346547007736348611217636062e0), 1.6320907588397540309035279023485962e-2); - try expectEqual(log10q(9.821701941230028324703038578036285e-1), -7.813249520562034832371814409278784e-3); - try expectEqual(log10q(9.593555263530179895381522214847791e-1), -1.8020418356217558657107271163588764e-2); + try expectEqual(log10_f128(1.0291437165967803055610652052109798e0), 1.2476026819466393459130418401605807e-2); + try expectEqual(log10_f128(1.043095786320424537962914257605007e0), 1.8324191034706598279642145362763252e-2); + try expectEqual(log10_f128(9.900264873754467234601150948947179e-1), -4.3531860417287584780652055666513634e-3); + try expectEqual(log10_f128(1.038295346547007736348611217636062e0), 1.6320907588397540309035279023485962e-2); + try expectEqual(log10_f128(9.821701941230028324703038578036285e-1), -7.813249520562034832371814409278784e-3); + try expectEqual(log10_f128(9.593555263530179895381522214847791e-1), -1.8020418356217558657107271163588764e-2); } test "log10q() boundary" { - try expectEqual(log10q(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value - try expectEqual(log10q(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value - try expect(math.isNan(log10q(-0x1p-16494))); // Min negative input value - try expectEqual(log10q(0x1.0000000000000000000000000001p0), 0x1.bcb7b1526e50e32a6ab7555f5a67p-114); // Last value before result reaches +0 - try expectEqual(log10q(0x1.ffffffffffffffffffffffffffffp-1), -0x1.bcb7b1526e50e32a6ab7555f5a68p-115); // Last value before result reaches -0 - try expectEqual(log10q(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal - try expect(math.isNan(log10q(-0x1p-16382))); // First negative subnormal + try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1.34413509f79fef311f12b35816f9p12); // Max input value + try expectEqual(log10_f128(0x1p-16494), -0x1.3653051d20c18a143b801b7c5661p12); // Min positive input value + try expect(math.isNan(log10_f128(-0x1p-16494))); // Min negative input value + try expectEqual(log10_f128(0x1.0000000000000000000000000001p0), 0x1.bcb7b1526e50e32a6ab7555f5a67p-114); // Last value before result reaches +0 + try expectEqual(log10_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1.bcb7b1526e50e32a6ab7555f5a68p-115); // Last value before result reaches -0 + try expectEqual(log10_f128(0x1p-16382), -0x1.343793004f503231a589bac27c38p12); // First subnormal + try expect(math.isNan(log10_f128(-0x1p-16382))); // First negative subnormal } diff --git a/lib/compiler_rt/log2.zig b/lib/compiler_rt/log2.zig index 8db17aaf3f26f257482af43b7bc125d4747dbfe2..b748a0af826586065f1f5369a6f1c61492b4cf99 100644 --- a/lib/compiler_rt/log2.zig +++ b/lib/compiler_rt/log2.zig @@ -26,12 +26,18 @@ comptime { symbol(&log2l, "log2l"); } -pub fn __log2h(a: f16) callconv(.c) f16 { +fn __log2h(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(log2_f16(compiler_rt.f16.fromAbi(a))); +} +pub fn log2_f16(a: f16) f16 { // TODO: more efficient implementation - return @floatCast(log2f(a)); + return @floatCast(log2_f32(a)); } -pub fn log2f(x_: f32) callconv(.c) f32 { +fn log2f(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(log2_f32(compiler_rt.f32.fromAbi(a))); +} +pub fn log2_f32(x_: f32) f32 { const ivln2hi: f32 = 1.4428710938e+00; const ivln2lo: f32 = -1.7605285393e-04; const Lg1: f32 = 0xaaaaaa.0p-24; @@ -87,7 +93,10 @@ pub fn log2f(x_: f32) callconv(.c) f32 { return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @as(f32, @floatFromInt(k)); } -pub fn log2(x_: f64) callconv(.c) f64 { +fn log2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(log2_f64(compiler_rt.f64.fromAbi(a))); +} +pub fn log2_f64(x_: f64) f64 { const ivln2hi: f64 = 1.44269504072144627571e+00; const ivln2lo: f64 = 1.67517131648865118353e-10; const Lg1: f64 = 6.666666666666735130e-01; @@ -158,11 +167,17 @@ pub fn log2(x_: f64) callconv(.c) f64 { return val_lo + val_hi; } -pub fn __log2x(a: f80) callconv(.c) f80 { +fn __log2x(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(log2_f80(compiler_rt.f80.fromAbi(a))); +} +pub fn log2_f80(a: f80) f80 { // TODO: more efficient implementation - return @floatCast(log2q(a)); + return @floatCast(log2_f128(a)); } +fn log2q(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(log2_f128(compiler_rt.f128.fromAbi(a))); +} /// Implementation of "Table-driven implementation of the logarithm function in IEEE floating-point arithmetic" /// by PTP Tang in ACM Transactions on Mathematical Software (TOMS), 1990 /// @@ -175,7 +190,7 @@ pub fn __log2x(a: f80) callconv(.c) f80 { /// /// Accuracy on 10 million random numbers near x = 1 (testing the proc2 case): /// <= 0.5 ulp: 99.86%, worst case <= 0.546 ulp -pub fn log2q(x: f128) callconv(.c) f128 { +pub fn log2_f128(x: f128) f128 { const impl = @import("log_f128.zig"); if (impl.specialCases(x)) |y| @@ -351,117 +366,117 @@ pub fn log2q(x: f128) callconv(.c) f128 { pub fn log2l(x: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return log2(x), - 80 => return __log2x(x), - 128 => return log2q(x), - else => @compileError("unreachable"), + 64 => return log2_f64(x), + 80 => return log2_f80(x), + 128 => return log2_f128(x), + else => comptime unreachable, } } test "log2f() special" { - try expectEqual(log2f(0.0), -math.inf(f32)); - try expectEqual(log2f(-0.0), -math.inf(f32)); - try expect(math.isPositiveZero(log2f(1.0))); - try expectEqual(log2f(2.0), 1.0); - try expectEqual(log2f(math.inf(f32)), math.inf(f32)); - try expect(math.isNan(log2f(-1.0))); - try expect(math.isNan(log2f(-math.inf(f32)))); - try expect(math.isNan(log2f(math.nan(f32)))); - try expect(math.isNan(log2f(math.snan(f32)))); + try expectEqual(log2_f32(0.0), -math.inf(f32)); + try expectEqual(log2_f32(-0.0), -math.inf(f32)); + try expect(math.isPositiveZero(log2_f32(1.0))); + try expectEqual(log2_f32(2.0), 1.0); + try expectEqual(log2_f32(math.inf(f32)), math.inf(f32)); + try expect(math.isNan(log2_f32(-1.0))); + try expect(math.isNan(log2_f32(-math.inf(f32)))); + try expect(math.isNan(log2_f32(math.nan(f32)))); + try expect(math.isNan(log2_f32(math.snan(f32)))); } test "log2f() sanity" { - try expect(math.isNan(log2f(-0x1.0223a0p+3))); - try expectEqual(log2f(0x1.161868p+2), 0x1.0f49acp+1); - try expect(math.isNan(log2f(-0x1.0c34b4p+3))); - try expect(math.isNan(log2f(-0x1.a206f0p+2))); - try expectEqual(log2f(0x1.288bbcp+3), 0x1.9b2676p+1); - try expectEqual(log2f(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit - try expect(math.isNan(log2f(-0x1.a05cc8p-2))); - try expectEqual(log2f(0x1.1f9efap-1), -0x1.a9f89ap-1); - try expectEqual(log2f(0x1.8c5db0p-1), -0x1.7a2c96p-2); - try expect(math.isNan(log2f(-0x1.5b86eap-1))); + try expect(math.isNan(log2_f32(-0x1.0223a0p+3))); + try expectEqual(log2_f32(0x1.161868p+2), 0x1.0f49acp+1); + try expect(math.isNan(log2_f32(-0x1.0c34b4p+3))); + try expect(math.isNan(log2_f32(-0x1.a206f0p+2))); + try expectEqual(log2_f32(0x1.288bbcp+3), 0x1.9b2676p+1); + try expectEqual(log2_f32(0x1.52efd0p-1), -0x1.30b494p-1); // Disagrees with GCC in last bit + try expect(math.isNan(log2_f32(-0x1.a05cc8p-2))); + try expectEqual(log2_f32(0x1.1f9efap-1), -0x1.a9f89ap-1); + try expectEqual(log2_f32(0x1.8c5db0p-1), -0x1.7a2c96p-2); + try expect(math.isNan(log2_f32(-0x1.5b86eap-1))); } test "log2f() boundary" { - try expectEqual(log2f(0x1.fffffep+127), 0x1p+7); // Max input value - try expectEqual(log2f(0x1p-149), -0x1.2ap+7); // Min positive input value - try expect(math.isNan(log2f(-0x1p-149))); // Min negative input value - try expectEqual(log2f(0x1.000002p+0), 0x1.715474p-23); // Last value before result reaches +0 - try expectEqual(log2f(0x1.fffffep-1), -0x1.715478p-24); // Last value before result reaches -0 - try expectEqual(log2f(0x1p-126), -0x1.f8p+6); // First subnormal - try expect(math.isNan(log2f(-0x1p-126))); // First negative subnormal + try expectEqual(log2_f32(0x1.fffffep+127), 0x1p+7); // Max input value + try expectEqual(log2_f32(0x1p-149), -0x1.2ap+7); // Min positive input value + try expect(math.isNan(log2_f32(-0x1p-149))); // Min negative input value + try expectEqual(log2_f32(0x1.000002p+0), 0x1.715474p-23); // Last value before result reaches +0 + try expectEqual(log2_f32(0x1.fffffep-1), -0x1.715478p-24); // Last value before result reaches -0 + try expectEqual(log2_f32(0x1p-126), -0x1.f8p+6); // First subnormal + try expect(math.isNan(log2_f32(-0x1p-126))); // First negative subnormal } test "log2() special" { - try expectEqual(log2(0.0), -math.inf(f64)); - try expectEqual(log2(-0.0), -math.inf(f64)); - try expect(math.isPositiveZero(log2(1.0))); - try expectEqual(log2(2.0), 1.0); - try expectEqual(log2(math.inf(f64)), math.inf(f64)); - try expect(math.isNan(log2(-1.0))); - try expect(math.isNan(log2(-math.inf(f64)))); - try expect(math.isNan(log2(math.nan(f64)))); - try expect(math.isNan(log2(math.snan(f64)))); + try expectEqual(log2_f64(0.0), -math.inf(f64)); + try expectEqual(log2_f64(-0.0), -math.inf(f64)); + try expect(math.isPositiveZero(log2_f64(1.0))); + try expectEqual(log2_f64(2.0), 1.0); + try expectEqual(log2_f64(math.inf(f64)), math.inf(f64)); + try expect(math.isNan(log2_f64(-1.0))); + try expect(math.isNan(log2_f64(-math.inf(f64)))); + try expect(math.isNan(log2_f64(math.nan(f64)))); + try expect(math.isNan(log2_f64(math.snan(f64)))); } test "log2() sanity" { - try expect(math.isNan(log2(-0x1.02239f3c6a8f1p+3))); - try expectEqual(log2(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1); - try expect(math.isNan(log2(-0x1.0c34b3e01e6e7p+3))); - try expect(math.isNan(log2(-0x1.a206f0a19dcc4p+2))); - try expectEqual(log2(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1); - try expectEqual(log2(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1); - try expect(math.isNan(log2(-0x1.a05cc754481d1p-2))); - try expectEqual(log2(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1); - try expectEqual(log2(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2); - try expect(math.isNan(log2(-0x1.5b86ea8118a0ep-1))); + try expect(math.isNan(log2_f64(-0x1.02239f3c6a8f1p+3))); + try expectEqual(log2_f64(0x1.161868e18bc67p+2), 0x1.0f49ac3838580p+1); + try expect(math.isNan(log2_f64(-0x1.0c34b3e01e6e7p+3))); + try expect(math.isNan(log2_f64(-0x1.a206f0a19dcc4p+2))); + try expectEqual(log2_f64(0x1.288bbb0d6a1e6p+3), 0x1.9b26760c2a57ep+1); + try expectEqual(log2_f64(0x1.52efd0cd80497p-1), -0x1.30b490ef684c7p-1); + try expect(math.isNan(log2_f64(-0x1.a05cc754481d1p-2))); + try expectEqual(log2_f64(0x1.1f9ef934745cbp-1), -0x1.a9f89b5f5acb8p-1); + try expectEqual(log2_f64(0x1.8c5db097f7442p-1), -0x1.7a2c947173f06p-2); + try expect(math.isNan(log2_f64(-0x1.5b86ea8118a0ep-1))); } test "log2() boundary" { - try expectEqual(log2(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value - try expectEqual(log2(0x1p-1074), -0x1.0c8p+10); // Min positive input value - try expect(math.isNan(log2(-0x1p-1074))); // Min negative input value - try expectEqual(log2(0x1.0000000000001p+0), 0x1.71547652b82fdp-52); // Last value before result reaches +0 - try expectEqual(log2(0x1.fffffffffffffp-1), -0x1.71547652b82fep-53); // Last value before result reaches -0 - try expectEqual(log2(0x1p-1022), -0x1.ffp+9); // First subnormal - try expect(math.isNan(log2(-0x1p-1022))); // First negative subnormal + try expectEqual(log2_f64(0x1.fffffffffffffp+1023), 0x1p+10); // Max input value + try expectEqual(log2_f64(0x1p-1074), -0x1.0c8p+10); // Min positive input value + try expect(math.isNan(log2_f64(-0x1p-1074))); // Min negative input value + try expectEqual(log2_f64(0x1.0000000000001p+0), 0x1.71547652b82fdp-52); // Last value before result reaches +0 + try expectEqual(log2_f64(0x1.fffffffffffffp-1), -0x1.71547652b82fep-53); // Last value before result reaches -0 + try expectEqual(log2_f64(0x1p-1022), -0x1.ffp+9); // First subnormal + try expect(math.isNan(log2_f64(-0x1p-1022))); // First negative subnormal } test "log2q() special" { - try expectEqual(log2q(0.0), -math.inf(f128)); - try expectEqual(log2q(-0.0), -math.inf(f128)); - try expect(math.isPositiveZero(log2q(1.0))); - try expectEqual(log2q(2.0), 1.0); - try expectEqual(log2q(math.inf(f128)), math.inf(f128)); - try expect(math.isNan(log2q(-1.0))); - try expect(math.isNan(log2q(-math.inf(f128)))); - try expect(math.isNan(log2q(math.nan(f128)))); - try expect(math.isNan(log2q(math.snan(f128)))); + try expectEqual(log2_f128(0.0), -math.inf(f128)); + try expectEqual(log2_f128(-0.0), -math.inf(f128)); + try expect(math.isPositiveZero(log2_f128(1.0))); + try expectEqual(log2_f128(2.0), 1.0); + try expectEqual(log2_f128(math.inf(f128)), math.inf(f128)); + try expect(math.isNan(log2_f128(-1.0))); + try expect(math.isNan(log2_f128(-math.inf(f128)))); + try expect(math.isNan(log2_f128(math.nan(f128)))); + try expect(math.isNan(log2_f128(math.snan(f128)))); } test "log2q() boundary" { - try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value - try expectEqual(log2q(0x1p-16494), -0x1.01b8p14); // Min positive input value - try expect(math.isNan(log2q(-0x1p-16494))); // Min negative input value - try expectEqual(log2q(0x1.0000000000000000000000000001p0), 0x1.71547652b82fe1777d0ffda0d23ap-112); // Last value before result reaches +0 - try expectEqual(log2q(0x1.ffffffffffffffffffffffffffffp-1), -0x1.71547652b82fe1777d0ffda0d23bp-113); // Last value before result reaches -0 - try expectEqual(log2q(0x1p-16382), -0x1.fffp13); // First subnormal - try expect(math.isNan(log2q(-0x1p-16382))); // First negative subnormal + try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp16383), 0x1p14); // Max input value + try expectEqual(log2_f128(0x1p-16494), -0x1.01b8p14); // Min positive input value + try expect(math.isNan(log2_f128(-0x1p-16494))); // Min negative input value + try expectEqual(log2_f128(0x1.0000000000000000000000000001p0), 0x1.71547652b82fe1777d0ffda0d23ap-112); // Last value before result reaches +0 + try expectEqual(log2_f128(0x1.ffffffffffffffffffffffffffffp-1), -0x1.71547652b82fe1777d0ffda0d23bp-113); // Last value before result reaches -0 + try expectEqual(log2_f128(0x1p-16382), -0x1.fffp13); // First subnormal + try expect(math.isNan(log2_f128(-0x1p-16382))); // First negative subnormal } test "log2q() sanity" { - try expectEqual(log2q(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1); - try expectEqual(log2q(8.346531942223744e15), 5.28900982928636641107356163006646e1); - try expectEqual(log2q(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1); - try expectEqual(log2q(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1); - try expectEqual(log2q(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1); - try expectEqual(log2q(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1); + try expectEqual(log2_f128(8.0965013884643408203125e11), 3.955850767769801288865582596068254e1); + try expectEqual(log2_f128(8.346531942223744e15), 5.28900982928636641107356163006646e1); + try expectEqual(log2_f128(9.707809913413123613777865431464565e-20), -6.315941603809020445822192336703809e1); + try expectEqual(log2_f128(1.9179565888043380306021427656243352e-24), -7.878670421065570557450089031998522e1); + try expectEqual(log2_f128(2.5260048200126556877075044745936796e-25), -8.17113449801679676275805009400338e1); + try expectEqual(log2_f128(3.1170134002568967640399932861328125e7), 2.489366102143423848582774267206741e1); // test near 1 - try expectEqual(log2q(1.026586845186097528392910049888087e0), 3.7855678902522753591699367969189364e-2); - try expectEqual(log2q(1.0005582850578053877743656130405725e0), 8.052103367568488432896147152682078e-4); - try expectEqual(log2q(1.0370174103591254835765589348284266e0), 5.244011558596899945639244281954306e-2); - try expectEqual(log2q(1.0429996503525671713075162472250667e0), 6.073867421942172944687194557176633e-2); - try expectEqual(log2q(1.0383384027961064621892184334228659e0), 5.4276706191956281784022630732940314e-2); + try expectEqual(log2_f128(1.026586845186097528392910049888087e0), 3.7855678902522753591699367969189364e-2); + try expectEqual(log2_f128(1.0005582850578053877743656130405725e0), 8.052103367568488432896147152682078e-4); + try expectEqual(log2_f128(1.0370174103591254835765589348284266e0), 5.244011558596899945639244281954306e-2); + try expectEqual(log2_f128(1.0429996503525671713075162472250667e0), 6.073867421942172944687194557176633e-2); + try expectEqual(log2_f128(1.0383384027961064621892184334228659e0), 5.4276706191956281784022630732940314e-2); } diff --git a/lib/compiler_rt/mulc3.zig b/lib/compiler_rt/mulc3.zig index eea753245f7687b2e3e9b65c12bdd278f1a3c757..fc0f2d24b4f603d9c933eb1328dbf5b73e4f41bc 100644 --- a/lib/compiler_rt/mulc3.zig +++ b/lib/compiler_rt/mulc3.zig @@ -3,19 +3,80 @@ const isNan = std.math.isNan; const isInf = std.math.isInf; const copysign = std.math.copysign; -pub fn Complex(comptime T: type) type { - return extern struct { - real: T, - imag: T, - }; +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; +const Complex = compiler_rt.Complex; + +comptime { + if (@import("builtin").zig_backend != .stage2_c) { + symbol(&__mulhc3, "__mulhc3"); + symbol(&__mulsc3, "__mulsc3"); + symbol(&__muldc3, "__muldc3"); + symbol(&__mulxc3, "__mulxc3"); + if (compiler_rt.want_ppc_abi) { + symbol(&__multc3, "__mulkc3"); + } else { + symbol(&__multc3, "__multc3"); + } + } +} + +fn __mulhc3(lhs_real: compiler_rt.f16.Abi, lhs_imag: compiler_rt.f16.Abi, rhs_real: compiler_rt.f16.Abi, rhs_imag: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.complex.Abi { + return compiler_rt.f16.complex.toAbi(mul_cf16( + compiler_rt.f16.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), + compiler_rt.f16.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), + )); +} +pub fn mul_cf16(a: Complex(f16), b: Complex(f16)) Complex(f16) { + return mulc3(f16, a, b); +} + +fn __mulsc3(lhs_real: compiler_rt.f32.Abi, lhs_imag: compiler_rt.f32.Abi, rhs_real: compiler_rt.f32.Abi, rhs_imag: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.complex.Abi { + return compiler_rt.f32.complex.toAbi(mul_cf32( + compiler_rt.f32.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), + compiler_rt.f32.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), + )); +} +pub fn mul_cf32(a: Complex(f32), b: Complex(f32)) Complex(f32) { + return mulc3(f32, a, b); +} + +fn __muldc3(lhs_real: compiler_rt.f64.Abi, lhs_imag: compiler_rt.f64.Abi, rhs_real: compiler_rt.f64.Abi, rhs_imag: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.complex.Abi { + return compiler_rt.f64.complex.toAbi(mul_cf64( + compiler_rt.f64.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), + compiler_rt.f64.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), + )); +} +pub fn mul_cf64(a: Complex(f64), b: Complex(f64)) Complex(f64) { + return mulc3(f64, a, b); +} + +fn __mulxc3(lhs_real: compiler_rt.f80.Abi, lhs_imag: compiler_rt.f80.Abi, rhs_real: compiler_rt.f80.Abi, rhs_imag: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.complex.Abi { + return compiler_rt.f80.complex.toAbi(mul_cf80( + compiler_rt.f80.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), + compiler_rt.f80.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), + )); +} +pub fn mul_cf80(a: Complex(f80), b: Complex(f80)) Complex(f80) { + return mulc3(f80, a, b); +} + +fn __multc3(lhs_real: compiler_rt.f128.Abi, lhs_imag: compiler_rt.f128.Abi, rhs_real: compiler_rt.f128.Abi, rhs_imag: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.complex.Abi { + return compiler_rt.f128.complex.toAbi(mul_cf128( + compiler_rt.f128.complex.fromAbi(.{ .real = lhs_real, .imag = lhs_imag }), + compiler_rt.f128.complex.fromAbi(.{ .real = rhs_real, .imag = rhs_imag }), + )); +} +pub fn mul_cf128(a: Complex(f128), b: Complex(f128)) Complex(f128) { + return mulc3(f128, a, b); } /// Implementation based on Annex G of C17 Standard (N2176) -pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Complex(T) { - var a = a_in; - var b = b_in; - var c = c_in; - var d = d_in; +inline fn mulc3(comptime T: type, lhs: Complex(T), rhs: Complex(T)) Complex(T) { + var a = lhs.real; + var b = lhs.imag; + var c = rhs.real; + var d = rhs.imag; const ac = a * c; const bd = b * d; @@ -77,3 +138,7 @@ pub inline fn mulc3(comptime T: type, a_in: T, b_in: T, c_in: T, d_in: T) Comple } return z; } + +test { + _ = @import("mulc3_test.zig"); +} diff --git a/lib/compiler_rt/mulc3_test.zig b/lib/compiler_rt/mulc3_test.zig index 3872cb34a6f9198dce4b482be03de720dce17696..748a3bc120ad6cfa3f82b2226f537a6bc63771b6 100644 --- a/lib/compiler_rt/mulc3_test.zig +++ b/lib/compiler_rt/mulc3_test.zig @@ -2,64 +2,45 @@ const std = @import("std"); const math = std.math; const expect = std.testing.expect; -const Complex = @import("./mulc3.zig").Complex; -const __mulhc3 = @import("./mulhc3.zig").__mulhc3; -const __mulsc3 = @import("./mulsc3.zig").__mulsc3; -const __muldc3 = @import("./muldc3.zig").__muldc3; -const __mulxc3 = @import("./mulxc3.zig").__mulxc3; -const __multc3 = @import("./multc3.zig").__multc3; +const Complex = @import("../compiler_rt.zig").Complex; +const impl = @import("mulc3.zig"); +const mul_cf16 = impl.mul_cf16; +const mul_cf32 = impl.mul_cf32; +const mul_cf64 = impl.mul_cf64; +const mul_cf80 = impl.mul_cf80; +const mul_cf128 = impl.mul_cf128; test "mulc3" { - try testMul(f16, __mulhc3); - try testMul(f32, __mulsc3); - try testMul(f64, __muldc3); - try testMul(f80, __mulxc3); - try testMul(f128, __multc3); + try testMul(f16, mul_cf16); + try testMul(f32, mul_cf32); + try testMul(f64, mul_cf64); + try testMul(f80, mul_cf80); + try testMul(f128, mul_cf128); } -fn testMul(comptime T: type, comptime f: fn (T, T, T, T) callconv(.c) Complex(T)) !void { +fn testMul(comptime T: type, comptime f: fn (Complex(T), Complex(T)) Complex(T)) !void { { - const a: T = 1.0; - const b: T = 0.0; - const c: T = -1.0; - const d: T = 0.0; - - const result = f(a, b, c, d); + const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -1.0, .imag = 0.0 }); try expect(result.real == -1.0); - try expect(result.imag == 0.0); + try expect(math.isPositiveZero(result.imag)); } { - const a: T = 1.0; - const b: T = 0.0; - const c: T = -4.0; - const d: T = 0.0; - - const result = f(a, b, c, d); + const result = f(.{ .real = 1.0, .imag = 0.0 }, .{ .real = -4.0, .imag = 0.0 }); try expect(result.real == -4.0); - try expect(result.imag == 0.0); + try expect(math.isPositiveZero(result.imag)); } { // if one operand is an infinity and the other operand is a nonzero finite number or an infinity, // then the result of the * operator is an infinity; - const a: T = math.inf(T); - const b: T = -math.inf(T); - const c: T = 1.0; - const d: T = 0.0; - - const result = f(a, b, c, d); - try expect(result.real == math.inf(T)); - try expect(result.imag == -math.inf(T)); + const result = f(.{ .real = math.inf(T), .imag = -math.inf(T) }, .{ .real = 1.0, .imag = 0.0 }); + try expect(math.isPositiveInf(result.real)); + try expect(math.isNegativeInf(result.imag)); } { // if one operand is an infinity and the other operand is a nonzero finite number or an infinity, // then the result of the * operator is an infinity; - const a: T = math.inf(T); - const b: T = -1.0; - const c: T = 1.0; - const d: T = math.inf(T); - - const result = f(a, b, c, d); - try expect(result.real == math.inf(T)); - try expect(result.imag == math.inf(T)); + const result = f(.{ .real = math.inf(T), .imag = -1.0 }, .{ .real = 1.0, .imag = math.inf(T) }); + try expect(math.isPositiveInf(result.real)); + try expect(math.isPositiveInf(result.imag)); } } diff --git a/lib/compiler_rt/muldc3.zig b/lib/compiler_rt/muldc3.zig deleted file mode 100644 index d5facaa2b645670b6bf6e0953ec6b73342342329..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/muldc3.zig +++ /dev/null @@ -1,12 +0,0 @@ -const mulc3 = @import("./mulc3.zig"); -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (@import("builtin").zig_backend != .stage2_c) { - symbol(&__muldc3, "__muldc3"); - } -} - -pub fn __muldc3(a: f64, b: f64, c: f64, d: f64) callconv(.c) mulc3.Complex(f64) { - return mulc3.mulc3(f64, a, b, c, d); -} diff --git a/lib/compiler_rt/muldf3.zig b/lib/compiler_rt/muldf3.zig deleted file mode 100644 index b8809e76da8d11e04c181d9dea86911aaac1cb29..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/muldf3.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; -const mulf3 = @import("./mulf3.zig").mulf3; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_dmul, "__aeabi_dmul"); - } else { - symbol(&__muldf3, "__muldf3"); - } -} - -pub fn __muldf3(a: f64, b: f64) callconv(.c) f64 { - return mulf3(f64, a, b); -} - -fn __aeabi_dmul(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { - return mulf3(f64, a, b); -} diff --git a/lib/compiler_rt/mulf3.zig b/lib/compiler_rt/mulf3.zig index d6b5a4719068cf2e27345f73e5f29994fc72e6d3..7367339dbc82f74dc99a9f6de7f842e8cbb71968 100644 --- a/lib/compiler_rt/mulf3.zig +++ b/lib/compiler_rt/mulf3.zig @@ -2,10 +2,76 @@ const std = @import("std"); const math = std.math; const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; + +comptime { + symbol(&__mulhf3, "__mulhf3"); + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_fmul, "__aeabi_fmul"); + symbol(&__aeabi_dmul, "__aeabi_dmul"); + } else { + symbol(&__mulsf3, "__mulsf3"); + symbol(&__muldf3, "__muldf3"); + } + symbol(&__mulxf3, "__mulxf3"); + if (compiler_rt.want_ppc_abi) { + symbol(&__multf3, "__mulkf3"); + } else if (compiler_rt.want_sparc64_abi) { + symbol(&_Qp_mul, "_Qp_mul"); + } else if (compiler_rt.want_sparc32_abi) { + symbol(&__multf3, "_Q_mul"); + } else { + symbol(&__multf3, "__multf3"); + } +} + +fn __mulhf3(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(mul_f16(compiler_rt.f16.fromAbi(a), compiler_rt.f16.fromAbi(b))); +} +pub fn mul_f16(a: f16, b: f16) f16 { + return mulf3(f16, a, b); +} + +fn __mulsf3(a: compiler_rt.f32.Abi, b: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(mul_f32(compiler_rt.f32.fromAbi(a), compiler_rt.f32.fromAbi(b))); +} +fn __aeabi_fmul(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { + return mul_f32(a, b); +} +pub fn mul_f32(a: f32, b: f32) f32 { + return mulf3(f32, a, b); +} + +fn __muldf3(a: compiler_rt.f64.Abi, b: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(mul_f64(compiler_rt.f64.fromAbi(a), compiler_rt.f64.fromAbi(b))); +} +fn __aeabi_dmul(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { + return mul_f64(a, b); +} +pub fn mul_f64(a: f64, b: f64) f64 { + return mulf3(f64, a, b); +} + +fn __mulxf3(a: compiler_rt.f80.Abi, b: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(mul_f80(compiler_rt.f80.fromAbi(a), compiler_rt.f80.fromAbi(b))); +} +pub fn mul_f80(a: f80, b: f80) f80 { + return mulf3(f80, a, b); +} + +fn __multf3(a: compiler_rt.f128.Abi, b: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(mul_f128(compiler_rt.f128.fromAbi(a), compiler_rt.f128.fromAbi(b))); +} +fn _Qp_mul(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { + c.* = mul_f128(a.*, b.*); +} +pub fn mul_f128(a: f128, b: f128) f128 { + return mulf3(f128, a, b); +} /// Ported from: /// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/lib/builtins/fp_mul_impl.inc -pub inline fn mulf3(comptime T: type, a: T, b: T) T { +inline fn mulf3(comptime T: type, a: T, b: T) T { @setRuntimeSafety(compiler_rt.test_safety); const typeWidth = @typeInfo(T).float.bits; const significandBits = math.floatMantissaBits(T); diff --git a/lib/compiler_rt/mulf3_test.zig b/lib/compiler_rt/mulf3_test.zig index 751b8933f65bc20e4b630c125fa60f42d5e27529..a2595e21a6d1ca5dd44f1ce67e6dfb6b4ee4cd9f 100644 --- a/lib/compiler_rt/mulf3_test.zig +++ b/lib/compiler_rt/mulf3_test.zig @@ -7,10 +7,12 @@ const math = std.math; const qnan128: f128 = @bitCast(@as(u128, 0x7fff800000000000) << 64); const inf128: f128 = @bitCast(@as(u128, 0x7fff000000000000) << 64); -const __multf3 = @import("multf3.zig").__multf3; -const __mulxf3 = @import("mulxf3.zig").__mulxf3; -const __muldf3 = @import("muldf3.zig").__muldf3; -const __mulsf3 = @import("mulsf3.zig").__mulsf3; +const impl = @import("mulf3.zig"); +const mul_f16 = impl.mul_f16; +const mul_f32 = impl.mul_f32; +const mul_f64 = impl.mul_f64; +const mul_f80 = impl.mul_f80; +const mul_f128 = impl.mul_f128; // return true if equal // use two 64-bit integers instead of one 128-bit integer @@ -34,8 +36,8 @@ fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { return false; } -fn test__multf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { - const x = __multf3(a, b); +fn test_mul_f128(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { + const x = mul_f128(a, b); if (compareResultLD(x, expected_hi, expected_lo)) return; @@ -49,68 +51,68 @@ fn makeNaN128(rand: u64) f128 { } test "multf3" { // qNaN * any = qNaN - try test__multf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); + try test_mul_f128(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); // NaN * any = NaN const a = makeNaN128(0x800030000000); - try test__multf3(a, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); + try test_mul_f128(a, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); // inf * any = inf - try test__multf3(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0); + try test_mul_f128(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0); // any * any - try test__multf3( + try test_mul_f128( @as(f128, @bitCast(@as(u128, 0x40042eab345678439abcdefea5678234))), @as(f128, @bitCast(@as(u128, 0x3ffeedcb34a235253948765432134675))), 0x400423e7f9e3c9fc, 0xd906c2c2a85777c4, ); - try test__multf3( + try test_mul_f128( @as(f128, @bitCast(@as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50))), @as(f128, @bitCast(@as(u128, 0x3ff6ed8764648369535adf4be3214568))), 0x3fc52a163c6223fc, 0xc94c4bf0430768b4, ); - try test__multf3( + try test_mul_f128( 0x1.234425696abcad34a35eeffefdcbap+456, 0x451.ed98d76e5d46e5f24323dff21ffp+600, 0x44293a91de5e0e94, 0xe8ed17cc2cdf64ac, ); - try test__multf3( + try test_mul_f128( @as(f128, @bitCast(@as(u128, 0x3f154356473c82a9fabf2d22ace345df))), @as(f128, @bitCast(@as(u128, 0x3e38eda98765476743ab21da23d45679))), 0x3d4f37c1a3137cae, 0xfc6807048bc2836a, ); - try test__multf3(0x1.23456734245345p-10000, 0x1.edcba524498724p-6497, 0x0, 0x0); + try test_mul_f128(0x1.23456734245345p-10000, 0x1.edcba524498724p-6497, 0x0, 0x0); // Denormal operands. - try test__multf3( + try test_mul_f128( 0x0.0000000000000000000000000001p-16382, 0x1p16383, 0x3f90000000000000, 0x0, ); - try test__multf3( + try test_mul_f128( 0x1p16383, 0x0.0000000000000000000000000001p-16382, 0x3f90000000000000, 0x0, ); - try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0001p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0002); - try test__multf3(0x1.0000_0000_0000_0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003); - try test__multf3(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002); + try test_mul_f128(0x1.0000_0000_0000_0000_0000_0000_0001p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0002); + try test_mul_f128(0x1.0000_0000_0000_0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_8000_0000_0000, 0x0000_0000_0000_0003); + try test_mul_f128(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002); } const qnan80: f80 = @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))); -fn test__mulxf3(a: f80, b: f80, expected: u80) !void { - const x = __mulxf3(a, b); +fn test_mul_f80(a: f80, b: f80, expected: u80) !void { + const x = mul_f80(a, b); const rep: u80 = @bitCast(x); if (rep == expected) @@ -124,47 +126,47 @@ fn test__mulxf3(a: f80, b: f80, expected: u80) !void { test "mulxf3" { // NaN * any = NaN - try test__mulxf3(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80))); - try test__mulxf3(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80))); + try test_mul_f80(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80))); + try test_mul_f80(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80))); // any * NaN = NaN - try test__mulxf3(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80))); - try test__mulxf3(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80))); + try test_mul_f80(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80))); + try test_mul_f80(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80))); // NaN * inf = NaN - try test__mulxf3(qnan80, math.inf(f80), @as(u80, @bitCast(qnan80))); + try test_mul_f80(qnan80, math.inf(f80), @as(u80, @bitCast(qnan80))); // inf * NaN = NaN - try test__mulxf3(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80))); + try test_mul_f80(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80))); // inf * inf = inf - try test__mulxf3(math.inf(f80), math.inf(f80), @as(u80, @bitCast(math.inf(f80)))); + try test_mul_f80(math.inf(f80), math.inf(f80), @as(u80, @bitCast(math.inf(f80)))); // inf * -inf = -inf - try test__mulxf3(math.inf(f80), -math.inf(f80), @as(u80, @bitCast(-math.inf(f80)))); + try test_mul_f80(math.inf(f80), -math.inf(f80), @as(u80, @bitCast(-math.inf(f80)))); // -inf + inf = -inf - try test__mulxf3(-math.inf(f80), math.inf(f80), @as(u80, @bitCast(-math.inf(f80)))); + try test_mul_f80(-math.inf(f80), math.inf(f80), @as(u80, @bitCast(-math.inf(f80)))); // inf * any = inf - try test__mulxf3(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @as(u80, @bitCast(math.inf(f80)))); + try test_mul_f80(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @as(u80, @bitCast(math.inf(f80)))); // any * inf = inf - try test__mulxf3(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @as(u80, @bitCast(math.inf(f80)))); + try test_mul_f80(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @as(u80, @bitCast(math.inf(f80)))); // any * any - try test__mulxf3(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800); - try test__mulxf3(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact + try test_mul_f80(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800); + try test_mul_f80(0x1.0000_0000_0000_0004p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0003); // exact - try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact - try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.7ffep+5, 0x4004_BFFF_0000_0000_0001); // round down - try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0002); // round up to even - try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.8002p+5, 0x4004_C001_0000_0000_0002); // round up - try test__mulxf3(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact + try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.0p+5, 0x4004_8000_0000_0000_0001); // exact + try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.7ffep+5, 0x4004_BFFF_0000_0000_0001); // round down + try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.8p+5, 0x4004_C000_0000_0000_0002); // round up to even + try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.8002p+5, 0x4004_C001_0000_0000_0002); // round up + try test_mul_f80(0x1.0000_0000_0000_0002p+0, 0x1.0p+6, 0x4005_8000_0000_0000_0001); // exact - try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even - try test__mulxf3(0x1.0000_0001p+0, 0x1.0000_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up - try test__mulxf3(0x0.8000_0000_0000_0000p-16382, 2.0, 0x0001_8000_0000_0000_0000); // denormal -> normal - try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x2.0000_0000_0000_0008p0, 0x0001_8000_0000_0000_0000); // denormal -> normal - try test__mulxf3(0x0.7fff_ffff_ffff_fffep-16382, 0x1.0000_0000_0000_0000p0, 0x0000_3FFF_FFFF_FFFF_FFFF); // denormal -> denormal + try test_mul_f80(0x1.0000_0001p+0, 0x1.0000_0001p+0, 0x3FFF_8000_0001_0000_0000); // round down to even + try test_mul_f80(0x1.0000_0001p+0, 0x1.0000_0001_0002p+0, 0x3FFF_8000_0001_0001_0001); // round up + try test_mul_f80(0x0.8000_0000_0000_0000p-16382, 2.0, 0x0001_8000_0000_0000_0000); // denormal -> normal + try test_mul_f80(0x0.7fff_ffff_ffff_fffep-16382, 0x2.0000_0000_0000_0008p0, 0x0001_8000_0000_0000_0000); // denormal -> normal + try test_mul_f80(0x0.7fff_ffff_ffff_fffep-16382, 0x1.0000_0000_0000_0000p0, 0x0000_3FFF_FFFF_FFFF_FFFF); // denormal -> denormal } diff --git a/lib/compiler_rt/mulhc3.zig b/lib/compiler_rt/mulhc3.zig deleted file mode 100644 index 4e0d3f875389ddf2f02bb7ddb3f75106e6d48513..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/mulhc3.zig +++ /dev/null @@ -1,13 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const mulc3 = @import("./mulc3.zig"); - -comptime { - if (@import("builtin").zig_backend != .stage2_c) { - symbol(&__mulhc3, "__mulhc3"); - } -} - -pub fn __mulhc3(a: f16, b: f16, c: f16, d: f16) callconv(.c) mulc3.Complex(f16) { - return mulc3.mulc3(f16, a, b, c, d); -} diff --git a/lib/compiler_rt/mulhf3.zig b/lib/compiler_rt/mulhf3.zig deleted file mode 100644 index 46ce7a6b999005704db84280e3e83c7be05985b6..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/mulhf3.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const mulf3 = @import("./mulf3.zig").mulf3; - -comptime { - symbol(&__mulhf3, "__mulhf3"); -} - -pub fn __mulhf3(a: f16, b: f16) callconv(.c) f16 { - return mulf3(f16, a, b); -} diff --git a/lib/compiler_rt/mulsc3.zig b/lib/compiler_rt/mulsc3.zig deleted file mode 100644 index e735e65eade6a77f908abe8b4b25e8fc30af7f9f..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/mulsc3.zig +++ /dev/null @@ -1,12 +0,0 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const mulc3 = @import("./mulc3.zig"); - -comptime { - if (@import("builtin").zig_backend != .stage2_c) { - symbol(&__mulsc3, "__mulsc3"); - } -} - -pub fn __mulsc3(a: f32, b: f32, c: f32, d: f32) callconv(.c) mulc3.Complex(f32) { - return mulc3.mulc3(f32, a, b, c, d); -} diff --git a/lib/compiler_rt/mulsf3.zig b/lib/compiler_rt/mulsf3.zig deleted file mode 100644 index 81f9eafae213d8cba10579b86f109bdfd361ba41..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/mulsf3.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const mulf3 = @import("./mulf3.zig").mulf3; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_fmul, "__aeabi_fmul"); - } else { - symbol(&__mulsf3, "__mulsf3"); - } -} - -pub fn __mulsf3(a: f32, b: f32) callconv(.c) f32 { - return mulf3(f32, a, b); -} - -fn __aeabi_fmul(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { - return mulf3(f32, a, b); -} diff --git a/lib/compiler_rt/multc3.zig b/lib/compiler_rt/multc3.zig deleted file mode 100644 index 4914735b10f63ec38d3487738e461769db6f8669..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/multc3.zig +++ /dev/null @@ -1,15 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; -const mulc3 = @import("./mulc3.zig"); - -comptime { - if (@import("builtin").zig_backend != .stage2_c) { - if (compiler_rt.want_ppc_abi) - symbol(&__multc3, "__mulkc3"); - symbol(&__multc3, "__multc3"); - } -} - -pub fn __multc3(a: f128, b: f128, c: f128, d: f128) callconv(.c) mulc3.Complex(f128) { - return mulc3.mulc3(f128, a, b, c, d); -} diff --git a/lib/compiler_rt/multf3.zig b/lib/compiler_rt/multf3.zig deleted file mode 100644 index 7d10c70777176e7a8580eb3b909546e42535785e..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/multf3.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const mulf3 = @import("./mulf3.zig").mulf3; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__multf3, "__mulkf3"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_mul, "_Qp_mul"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__multf3, "_Q_mul"); - } - symbol(&__multf3, "__multf3"); -} - -pub fn __multf3(a: f128, b: f128) callconv(.c) f128 { - return mulf3(f128, a, b); -} - -fn _Qp_mul(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { - c.* = mulf3(f128, a.*, b.*); -} diff --git a/lib/compiler_rt/mulvsi3.zig b/lib/compiler_rt/mulvsi3.zig index 0935ea497afa52a46f515c83c40c2d8cc5bc02db..f2456fa7cb825a36a359d667d26e5f06eb2c95e4 100644 --- a/lib/compiler_rt/mulvsi3.zig +++ b/lib/compiler_rt/mulvsi3.zig @@ -1,7 +1,8 @@ const testing = @import("std").testing; const mulv = @import("mulo.zig"); -const symbol = @import("../compiler_rt.zig").symbol; +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; comptime { symbol(&__mulvsi3, "__mulvsi3"); @@ -10,7 +11,7 @@ comptime { pub fn __mulvsi3(a: i32, b: i32) callconv(.c) i32 { var overflow: c_int = 0; const sum = mulv.__mulosi4(a, b, &overflow); - if (overflow != 0) @panic("compiler-rt: integer overflow"); + if (overflow != 0) @panic("integer overflow"); return sum; } diff --git a/lib/compiler_rt/mulxc3.zig b/lib/compiler_rt/mulxc3.zig deleted file mode 100644 index ac0e189f63ba4d4ce2f0a753c4f7409e0b551d23..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/mulxc3.zig +++ /dev/null @@ -1,13 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const mulc3 = @import("./mulc3.zig"); - -comptime { - if (@import("builtin").zig_backend != .stage2_c) { - symbol(&__mulxc3, "__mulxc3"); - } -} - -pub fn __mulxc3(a: f80, b: f80, c: f80, d: f80) callconv(.c) mulc3.Complex(f80) { - return mulc3.mulc3(f80, a, b, c, d); -} diff --git a/lib/compiler_rt/mulxf3.zig b/lib/compiler_rt/mulxf3.zig deleted file mode 100644 index dcf783a4a6bc434275416e9da0079f65b3354277..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/mulxf3.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const mulf3 = @import("./mulf3.zig").mulf3; - -comptime { - symbol(&__mulxf3, "__mulxf3"); -} - -pub fn __mulxf3(a: f80, b: f80) callconv(.c) f80 { - return mulf3(f80, a, b); -} diff --git a/lib/compiler_rt/negv.zig b/lib/compiler_rt/negv.zig index 7c67a51c34ab72f9c3f0038024e45ca79413d955..c6d61611f1b24d3697dcdc4201f5ff2d8c1cf40c 100644 --- a/lib/compiler_rt/negv.zig +++ b/lib/compiler_rt/negv.zig @@ -33,8 +33,7 @@ inline fn negvXi(comptime ST: type, a: ST) ST { }; const N: UT = @bitSizeOf(ST); const min: ST = @as(ST, @bitCast((@as(UT, 1) << (N - 1)))); - if (a == min) - @panic("compiler_rt negv: overflow"); + if (a == min) @panic("integer overflow"); return -a; } diff --git a/lib/compiler_rt/os_version_check.zig b/lib/compiler_rt/os_version_check.zig index e575fef9ce553fee90cc9f7cc900689c5804cb20..96724a14e8092aae7693e4ab869ab3282a9ea762 100644 --- a/lib/compiler_rt/os_version_check.zig +++ b/lib/compiler_rt/os_version_check.zig @@ -3,7 +3,6 @@ const testing = std.testing; const builtin = @import("builtin"); const compiler_rt = @import("../compiler_rt.zig"); const symbol = compiler_rt.symbol; -const panic = @import("../compiler_rt.zig").panic; const have_availability_version_check = builtin.os.tag.isDarwin() and builtin.os.version_range.semver.min.order(.{ .major = 10, .minor = 15, .patch = 0 }).compare(.gte); diff --git a/lib/compiler_rt/parity.zig b/lib/compiler_rt/parity.zig index e3881699042fafc3fc0da7415e6fb2bb6d1aedde..9540cf49f629556b73f77067ddcf90944afdf21b 100644 --- a/lib/compiler_rt/parity.zig +++ b/lib/compiler_rt/parity.zig @@ -1,6 +1,7 @@ //! parity - if number of bits set is even => 0, else => 1 //! - pariytXi2_generic for big and little endian -const symbol = @import("../compiler_rt.zig").symbol; +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; comptime { symbol(&__paritysi2, "__paritysi2"); diff --git a/lib/compiler_rt/popcount.zig b/lib/compiler_rt/popcount.zig index b1ef500ea117514d08b598e4209770bd4b879b1f..3b9d867548f62d9ab7da321786cb737effa2646d 100644 --- a/lib/compiler_rt/popcount.zig +++ b/lib/compiler_rt/popcount.zig @@ -6,7 +6,8 @@ //! TAOCP: Combinational Algorithms, Bitwise Tricks And Techniques, //! subsubsection "Working with the rightmost bits" and "Sideways addition". -const symbol = @import("../compiler_rt.zig").symbol; +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; comptime { symbol(&__popcountsi2, "__popcountsi2"); diff --git a/lib/compiler_rt/powiXf2.zig b/lib/compiler_rt/powiXf2.zig index b2a1e3e6989ba85538243483d14fd92ad0e3158d..dd8b477f152144ce7206f4ce54caa77c1a4ead36 100644 --- a/lib/compiler_rt/powiXf2.zig +++ b/lib/compiler_rt/powiXf2.zig @@ -4,16 +4,18 @@ //! error propagation and this method is optimized for performance, not accuracy. const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; +const symbol = compiler_rt.symbol; comptime { symbol(&__powihf2, "__powihf2"); symbol(&__powisf2, "__powisf2"); symbol(&__powidf2, "__powidf2"); - if (compiler_rt.want_ppc_abi) - symbol(&__powitf2, "__powikf2"); - symbol(&__powitf2, "__powitf2"); symbol(&__powixf2, "__powixf2"); + if (compiler_rt.want_ppc_abi) { + symbol(&__powitf2, "__powikf2"); + } else { + symbol(&__powitf2, "__powitf2"); + } } inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT { @@ -32,26 +34,41 @@ inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT { return if (is_recip) 1 / r else r; } -pub fn __powihf2(a: f16, b: i32) callconv(.c) f16 { +fn __powihf2(a: compiler_rt.f16.Abi, b: i32) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(powi_f16(compiler_rt.f16.fromAbi(a), b)); +} +pub fn powi_f16(a: f16, b: i32) f16 { return powiXf2(f16, a, b); } -pub fn __powisf2(a: f32, b: i32) callconv(.c) f32 { +fn __powisf2(a: compiler_rt.f32.Abi, b: i32) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(powi_f32(compiler_rt.f32.fromAbi(a), b)); +} +pub fn powi_f32(a: f32, b: i32) f32 { return powiXf2(f32, a, b); } -pub fn __powidf2(a: f64, b: i32) callconv(.c) f64 { +fn __powidf2(a: compiler_rt.f64.Abi, b: i32) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(powi_f64(compiler_rt.f64.fromAbi(a), b)); +} +pub fn powi_f64(a: f64, b: i32) f64 { return powiXf2(f64, a, b); } -pub fn __powitf2(a: f128, b: i32) callconv(.c) f128 { - return powiXf2(f128, a, b); +fn __powixf2(a: compiler_rt.f80.Abi, b: i32) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(powi_f80(compiler_rt.f80.fromAbi(a), b)); } - -pub fn __powixf2(a: f80, b: i32) callconv(.c) f80 { +pub fn powi_f80(a: f80, b: i32) f80 { return powiXf2(f80, a, b); } +fn __powitf2(a: compiler_rt.f128.Abi, b: i32) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(powi_f128(compiler_rt.f128.fromAbi(a), b)); +} +pub fn powi_f128(a: f128, b: i32) f128 { + return powiXf2(f128, a, b); +} + test { _ = @import("powiXf2_test.zig"); } diff --git a/lib/compiler_rt/powiXf2_test.zig b/lib/compiler_rt/powiXf2_test.zig index 7bd43c73c3d2d1a379a6ef66977c55dff1fc8a00..1388a4e7250e7b418fee08cde6d165d2bce80adf 100644 --- a/lib/compiler_rt/powiXf2_test.zig +++ b/lib/compiler_rt/powiXf2_test.zig @@ -2,562 +2,568 @@ // powisf2_test.c, powidf2_test.c, powitf2_test.c, powixf2_test.c // powihf2 adapted from powisf2 tests -const powiXf2 = @import("powiXf2.zig"); const std = @import("std"); -const builtin = @import("builtin"); const testing = std.testing; const math = std.math; -fn test__powihf2(a: f16, b: i32, expected: f16) !void { - const result = powiXf2.__powihf2(a, b); +const impl = @import("powiXf2.zig"); + +const powi_f16 = impl.powi_f16; +const powi_f32 = impl.powi_f32; +const powi_f64 = impl.powi_f64; +const powi_f80 = impl.powi_f80; +const powi_f128 = impl.powi_f128; + +fn test_powi_f16(a: f16, b: i32, expected: f16) !void { + const result = powi_f16(a, b); try testing.expectEqual(expected, result); } -fn test__powisf2(a: f32, b: i32, expected: f32) !void { - const result = powiXf2.__powisf2(a, b); +fn test_powi_f32(a: f32, b: i32, expected: f32) !void { + const result = powi_f32(a, b); try testing.expectEqual(expected, result); } -fn test__powidf2(a: f64, b: i32, expected: f64) !void { - const result = powiXf2.__powidf2(a, b); +fn test_powi_f64(a: f64, b: i32, expected: f64) !void { + const result = powi_f64(a, b); try testing.expectEqual(expected, result); } -fn test__powitf2(a: f128, b: i32, expected: f128) !void { - const result = powiXf2.__powitf2(a, b); +fn test_powi_f80(a: f80, b: i32, expected: f80) !void { + const result = powi_f80(a, b); try testing.expectEqual(expected, result); } -fn test__powixf2(a: f80, b: i32, expected: f80) !void { - const result = powiXf2.__powixf2(a, b); +fn test_powi_f128(a: f128, b: i32, expected: f128) !void { + const result = powi_f128(a, b); try testing.expectEqual(expected, result); } -test "powihf2" { +test powi_f16 { const inf_f16 = math.inf(f16); - try test__powisf2(0, 0, 1); - try test__powihf2(1, 0, 1); - try test__powihf2(1.5, 0, 1); - try test__powihf2(2, 0, 1); - try test__powihf2(inf_f16, 0, 1); + try test_powi_f16(0, 0, 1); + try test_powi_f16(1, 0, 1); + try test_powi_f16(1.5, 0, 1); + try test_powi_f16(2, 0, 1); + try test_powi_f16(inf_f16, 0, 1); - try test__powihf2(-0.0, 0, 1); - try test__powihf2(-1, 0, 1); - try test__powihf2(-1.5, 0, 1); - try test__powihf2(-2, 0, 1); - try test__powihf2(-inf_f16, 0, 1); + try test_powi_f16(-0.0, 0, 1); + try test_powi_f16(-1, 0, 1); + try test_powi_f16(-1.5, 0, 1); + try test_powi_f16(-2, 0, 1); + try test_powi_f16(-inf_f16, 0, 1); - try test__powihf2(0, 1, 0); - try test__powihf2(0, 2, 0); - try test__powihf2(0, 3, 0); - try test__powihf2(0, 4, 0); - try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); - try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); + try test_powi_f16(0, 1, 0); + try test_powi_f16(0, 2, 0); + try test_powi_f16(0, 3, 0); + try test_powi_f16(0, 4, 0); + try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); + try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); - try test__powihf2(-0.0, 1, -0.0); - try test__powihf2(-0.0, 2, 0); - try test__powihf2(-0.0, 3, -0.0); - try test__powihf2(-0.0, 4, 0); - try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); - try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); + try test_powi_f16(-0.0, 1, -0.0); + try test_powi_f16(-0.0, 2, 0); + try test_powi_f16(-0.0, 3, -0.0); + try test_powi_f16(-0.0, 4, 0); + try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); + try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); - try test__powihf2(1, 1, 1); - try test__powihf2(1, 2, 1); - try test__powihf2(1, 3, 1); - try test__powihf2(1, 4, 1); - try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); - try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); + try test_powi_f16(1, 1, 1); + try test_powi_f16(1, 2, 1); + try test_powi_f16(1, 3, 1); + try test_powi_f16(1, 4, 1); + try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); + try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); - try test__powihf2(inf_f16, 1, inf_f16); - try test__powihf2(inf_f16, 2, inf_f16); - try test__powihf2(inf_f16, 3, inf_f16); - try test__powihf2(inf_f16, 4, inf_f16); - try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16); - try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16); + try test_powi_f16(inf_f16, 1, inf_f16); + try test_powi_f16(inf_f16, 2, inf_f16); + try test_powi_f16(inf_f16, 3, inf_f16); + try test_powi_f16(inf_f16, 4, inf_f16); + try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16); + try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16); - try test__powihf2(-inf_f16, 1, -inf_f16); - try test__powihf2(-inf_f16, 2, inf_f16); - try test__powihf2(-inf_f16, 3, -inf_f16); - try test__powihf2(-inf_f16, 4, inf_f16); - try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16); - try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f16); + try test_powi_f16(-inf_f16, 1, -inf_f16); + try test_powi_f16(-inf_f16, 2, inf_f16); + try test_powi_f16(-inf_f16, 3, -inf_f16); + try test_powi_f16(-inf_f16, 4, inf_f16); + try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16); + try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f16); // - try test__powihf2(0, -1, inf_f16); - try test__powihf2(0, -2, inf_f16); - try test__powihf2(0, -3, inf_f16); - try test__powihf2(0, -4, inf_f16); - try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // 0 ^ anything = +inf - try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f16); - try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16); + try test_powi_f16(0, -1, inf_f16); + try test_powi_f16(0, -2, inf_f16); + try test_powi_f16(0, -3, inf_f16); + try test_powi_f16(0, -4, inf_f16); + try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // 0 ^ anything = +inf + try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f16); + try test_powi_f16(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16); - try test__powihf2(-0.0, -1, -inf_f16); - try test__powihf2(-0.0, -2, inf_f16); - try test__powihf2(-0.0, -3, -inf_f16); - try test__powihf2(-0.0, -4, inf_f16); - try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // -0 ^ anything even = +inf - try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f16); // -0 ^ anything odd = -inf - try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16); + try test_powi_f16(-0.0, -1, -inf_f16); + try test_powi_f16(-0.0, -2, inf_f16); + try test_powi_f16(-0.0, -3, -inf_f16); + try test_powi_f16(-0.0, -4, inf_f16); + try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // -0 ^ anything even = +inf + try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f16); // -0 ^ anything odd = -inf + try test_powi_f16(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16); - try test__powihf2(1, -1, 1); - try test__powihf2(1, -2, 1); - try test__powihf2(1, -3, 1); - try test__powihf2(1, -4, 1); - try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1 - try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); - try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); + try test_powi_f16(1, -1, 1); + try test_powi_f16(1, -2, 1); + try test_powi_f16(1, -3, 1); + try test_powi_f16(1, -4, 1); + try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1 + try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); + try test_powi_f16(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); - try test__powihf2(inf_f16, -1, 0); - try test__powihf2(inf_f16, -2, 0); - try test__powihf2(inf_f16, -3, 0); - try test__powihf2(inf_f16, -4, 0); - try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); - try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); - try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); + try test_powi_f16(inf_f16, -1, 0); + try test_powi_f16(inf_f16, -2, 0); + try test_powi_f16(inf_f16, -3, 0); + try test_powi_f16(inf_f16, -4, 0); + try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); + try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); + try test_powi_f16(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); // - try test__powihf2(-inf_f16, -1, -0.0); - try test__powihf2(-inf_f16, -2, 0); - try test__powihf2(-inf_f16, -3, -0.0); - try test__powihf2(-inf_f16, -4, 0); - try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); - try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); - try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); + try test_powi_f16(-inf_f16, -1, -0.0); + try test_powi_f16(-inf_f16, -2, 0); + try test_powi_f16(-inf_f16, -3, -0.0); + try test_powi_f16(-inf_f16, -4, 0); + try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); + try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); + try test_powi_f16(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); - try test__powihf2(2, 10, 1024.0); - try test__powihf2(-2, 10, 1024.0); - try test__powihf2(2, -10, 1.0 / 1024.0); - try test__powihf2(-2, -10, 1.0 / 1024.0); + try test_powi_f16(2, 10, 1024.0); + try test_powi_f16(-2, 10, 1024.0); + try test_powi_f16(2, -10, 1.0 / 1024.0); + try test_powi_f16(-2, -10, 1.0 / 1024.0); - try test__powihf2(2, 14, 16384.0); - try test__powihf2(-2, 14, 16384.0); - try test__powihf2(2, 15, 32768.0); - try test__powihf2(-2, 15, -32768.0); - try test__powihf2(2, 16, inf_f16); - try test__powihf2(-2, 16, inf_f16); + try test_powi_f16(2, 14, 16384.0); + try test_powi_f16(-2, 14, 16384.0); + try test_powi_f16(2, 15, 32768.0); + try test_powi_f16(-2, 15, -32768.0); + try test_powi_f16(2, 16, inf_f16); + try test_powi_f16(-2, 16, inf_f16); - try test__powihf2(2, -13, 1.0 / 8192.0); - try test__powihf2(-2, -13, -1.0 / 8192.0); - try test__powihf2(2, -15, 1.0 / 32768.0); - try test__powihf2(-2, -15, -1.0 / 32768.0); - try test__powihf2(2, -16, 0.0); // expected = 0.0 = 1/(-2**16) - try test__powihf2(-2, -16, 0.0); // expected = 0.0 = 1/(2**16) + try test_powi_f16(2, -13, 1.0 / 8192.0); + try test_powi_f16(-2, -13, -1.0 / 8192.0); + try test_powi_f16(2, -15, 1.0 / 32768.0); + try test_powi_f16(-2, -15, -1.0 / 32768.0); + try test_powi_f16(2, -16, 0.0); // expected = 0.0 = 1/(-2**16) + try test_powi_f16(-2, -16, 0.0); // expected = 0.0 = 1/(2**16) } -test "powisf2" { +test powi_f32 { const inf_f32 = math.inf(f32); - try test__powisf2(0, 0, 1); - try test__powisf2(1, 0, 1); - try test__powisf2(1.5, 0, 1); - try test__powisf2(2, 0, 1); - try test__powisf2(inf_f32, 0, 1); + try test_powi_f32(0, 0, 1); + try test_powi_f32(1, 0, 1); + try test_powi_f32(1.5, 0, 1); + try test_powi_f32(2, 0, 1); + try test_powi_f32(inf_f32, 0, 1); - try test__powisf2(-0.0, 0, 1); - try test__powisf2(-1, 0, 1); - try test__powisf2(-1.5, 0, 1); - try test__powisf2(-2, 0, 1); - try test__powisf2(-inf_f32, 0, 1); + try test_powi_f32(-0.0, 0, 1); + try test_powi_f32(-1, 0, 1); + try test_powi_f32(-1.5, 0, 1); + try test_powi_f32(-2, 0, 1); + try test_powi_f32(-inf_f32, 0, 1); - try test__powisf2(0, 1, 0); - try test__powisf2(0, 2, 0); - try test__powisf2(0, 3, 0); - try test__powisf2(0, 4, 0); - try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); - try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); + try test_powi_f32(0, 1, 0); + try test_powi_f32(0, 2, 0); + try test_powi_f32(0, 3, 0); + try test_powi_f32(0, 4, 0); + try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); + try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); - try test__powisf2(-0.0, 1, -0.0); - try test__powisf2(-0.0, 2, 0); - try test__powisf2(-0.0, 3, -0.0); - try test__powisf2(-0.0, 4, 0); - try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); - try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); + try test_powi_f32(-0.0, 1, -0.0); + try test_powi_f32(-0.0, 2, 0); + try test_powi_f32(-0.0, 3, -0.0); + try test_powi_f32(-0.0, 4, 0); + try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); + try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); - try test__powisf2(1, 1, 1); - try test__powisf2(1, 2, 1); - try test__powisf2(1, 3, 1); - try test__powisf2(1, 4, 1); - try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); - try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); + try test_powi_f32(1, 1, 1); + try test_powi_f32(1, 2, 1); + try test_powi_f32(1, 3, 1); + try test_powi_f32(1, 4, 1); + try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); + try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); - try test__powisf2(inf_f32, 1, inf_f32); - try test__powisf2(inf_f32, 2, inf_f32); - try test__powisf2(inf_f32, 3, inf_f32); - try test__powisf2(inf_f32, 4, inf_f32); - try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32); - try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32); + try test_powi_f32(inf_f32, 1, inf_f32); + try test_powi_f32(inf_f32, 2, inf_f32); + try test_powi_f32(inf_f32, 3, inf_f32); + try test_powi_f32(inf_f32, 4, inf_f32); + try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32); + try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32); - try test__powisf2(-inf_f32, 1, -inf_f32); - try test__powisf2(-inf_f32, 2, inf_f32); - try test__powisf2(-inf_f32, 3, -inf_f32); - try test__powisf2(-inf_f32, 4, inf_f32); - try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32); - try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32); + try test_powi_f32(-inf_f32, 1, -inf_f32); + try test_powi_f32(-inf_f32, 2, inf_f32); + try test_powi_f32(-inf_f32, 3, -inf_f32); + try test_powi_f32(-inf_f32, 4, inf_f32); + try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32); + try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32); - try test__powisf2(0, -1, inf_f32); - try test__powisf2(0, -2, inf_f32); - try test__powisf2(0, -3, inf_f32); - try test__powisf2(0, -4, inf_f32); - try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32); - try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32); - try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32); + try test_powi_f32(0, -1, inf_f32); + try test_powi_f32(0, -2, inf_f32); + try test_powi_f32(0, -3, inf_f32); + try test_powi_f32(0, -4, inf_f32); + try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32); + try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32); + try test_powi_f32(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32); - try test__powisf2(-0.0, -1, -inf_f32); - try test__powisf2(-0.0, -2, inf_f32); - try test__powisf2(-0.0, -3, -inf_f32); - try test__powisf2(-0.0, -4, inf_f32); - try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32); - try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32); - try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32); + try test_powi_f32(-0.0, -1, -inf_f32); + try test_powi_f32(-0.0, -2, inf_f32); + try test_powi_f32(-0.0, -3, -inf_f32); + try test_powi_f32(-0.0, -4, inf_f32); + try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32); + try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32); + try test_powi_f32(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32); - try test__powisf2(1, -1, 1); - try test__powisf2(1, -2, 1); - try test__powisf2(1, -3, 1); - try test__powisf2(1, -4, 1); - try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); - try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); - try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); + try test_powi_f32(1, -1, 1); + try test_powi_f32(1, -2, 1); + try test_powi_f32(1, -3, 1); + try test_powi_f32(1, -4, 1); + try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); + try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); + try test_powi_f32(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); - try test__powisf2(inf_f32, -1, 0); - try test__powisf2(inf_f32, -2, 0); - try test__powisf2(inf_f32, -3, 0); - try test__powisf2(inf_f32, -4, 0); - try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); - try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); - try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); + try test_powi_f32(inf_f32, -1, 0); + try test_powi_f32(inf_f32, -2, 0); + try test_powi_f32(inf_f32, -3, 0); + try test_powi_f32(inf_f32, -4, 0); + try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); + try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); + try test_powi_f32(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); - try test__powisf2(-inf_f32, -1, -0.0); - try test__powisf2(-inf_f32, -2, 0); - try test__powisf2(-inf_f32, -3, -0.0); - try test__powisf2(-inf_f32, -4, 0); - try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); - try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); - try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); + try test_powi_f32(-inf_f32, -1, -0.0); + try test_powi_f32(-inf_f32, -2, 0); + try test_powi_f32(-inf_f32, -3, -0.0); + try test_powi_f32(-inf_f32, -4, 0); + try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); + try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); + try test_powi_f32(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); - try test__powisf2(2.0, 10, 1024.0); - try test__powisf2(-2, 10, 1024.0); - try test__powisf2(2, -10, 1.0 / 1024.0); - try test__powisf2(-2, -10, 1.0 / 1024.0); + try test_powi_f32(2.0, 10, 1024.0); + try test_powi_f32(-2, 10, 1024.0); + try test_powi_f32(2, -10, 1.0 / 1024.0); + try test_powi_f32(-2, -10, 1.0 / 1024.0); // - try test__powisf2(2, 19, 524288.0); - try test__powisf2(-2, 19, -524288.0); - try test__powisf2(2, -19, 1.0 / 524288.0); - try test__powisf2(-2, -19, -1.0 / 524288.0); + try test_powi_f32(2, 19, 524288.0); + try test_powi_f32(-2, 19, -524288.0); + try test_powi_f32(2, -19, 1.0 / 524288.0); + try test_powi_f32(-2, -19, -1.0 / 524288.0); - try test__powisf2(2, 31, 2147483648.0); - try test__powisf2(-2, 31, -2147483648.0); - try test__powisf2(2, -31, 1.0 / 2147483648.0); - try test__powisf2(-2, -31, -1.0 / 2147483648.0); + try test_powi_f32(2, 31, 2147483648.0); + try test_powi_f32(-2, 31, -2147483648.0); + try test_powi_f32(2, -31, 1.0 / 2147483648.0); + try test_powi_f32(-2, -31, -1.0 / 2147483648.0); } -test "powidf2" { +test powi_f64 { const inf_f64 = math.inf(f64); - try test__powidf2(0, 0, 1); - try test__powidf2(1, 0, 1); - try test__powidf2(1.5, 0, 1); - try test__powidf2(2, 0, 1); - try test__powidf2(inf_f64, 0, 1); - - try test__powidf2(-0.0, 0, 1); - try test__powidf2(-1, 0, 1); - try test__powidf2(-1.5, 0, 1); - try test__powidf2(-2, 0, 1); - try test__powidf2(-inf_f64, 0, 1); - - try test__powidf2(0, 1, 0); - try test__powidf2(0, 2, 0); - try test__powidf2(0, 3, 0); - try test__powidf2(0, 4, 0); - try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); - try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); - - try test__powidf2(-0.0, 1, -0.0); - try test__powidf2(-0.0, 2, 0); - try test__powidf2(-0.0, 3, -0.0); - try test__powidf2(-0.0, 4, 0); - try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); - try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); - - try test__powidf2(1, 1, 1); - try test__powidf2(1, 2, 1); - try test__powidf2(1, 3, 1); - try test__powidf2(1, 4, 1); - try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); - try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); - - try test__powidf2(inf_f64, 1, inf_f64); - try test__powidf2(inf_f64, 2, inf_f64); - try test__powidf2(inf_f64, 3, inf_f64); - try test__powidf2(inf_f64, 4, inf_f64); - try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64); - try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64); - - try test__powidf2(-inf_f64, 1, -inf_f64); - try test__powidf2(-inf_f64, 2, inf_f64); - try test__powidf2(-inf_f64, 3, -inf_f64); - try test__powidf2(-inf_f64, 4, inf_f64); - try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64); - try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64); - - try test__powidf2(0, -1, inf_f64); - try test__powidf2(0, -2, inf_f64); - try test__powidf2(0, -3, inf_f64); - try test__powidf2(0, -4, inf_f64); - try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64); - try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64); - try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64); - - try test__powidf2(-0.0, -1, -inf_f64); - try test__powidf2(-0.0, -2, inf_f64); - try test__powidf2(-0.0, -3, -inf_f64); - try test__powidf2(-0.0, -4, inf_f64); - try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64); - try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64); - try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64); - - try test__powidf2(1, -1, 1); - try test__powidf2(1, -2, 1); - try test__powidf2(1, -3, 1); - try test__powidf2(1, -4, 1); - try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); - try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); - try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); - - try test__powidf2(inf_f64, -1, 0); - try test__powidf2(inf_f64, -2, 0); - try test__powidf2(inf_f64, -3, 0); - try test__powidf2(inf_f64, -4, 0); - try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); - try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); - try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); - - try test__powidf2(-inf_f64, -1, -0.0); - try test__powidf2(-inf_f64, -2, 0); - try test__powidf2(-inf_f64, -3, -0.0); - try test__powidf2(-inf_f64, -4, 0); - try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); - try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); - try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); - - try test__powidf2(2, 10, 1024.0); - try test__powidf2(-2, 10, 1024.0); - try test__powidf2(2, -10, 1.0 / 1024.0); - try test__powidf2(-2, -10, 1.0 / 1024.0); - - try test__powidf2(2, 19, 524288.0); - try test__powidf2(-2, 19, -524288.0); - try test__powidf2(2, -19, 1.0 / 524288.0); - try test__powidf2(-2, -19, -1.0 / 524288.0); - - try test__powidf2(2, 31, 2147483648.0); - try test__powidf2(-2, 31, -2147483648.0); - try test__powidf2(2, -31, 1.0 / 2147483648.0); - try test__powidf2(-2, -31, -1.0 / 2147483648.0); -} - -test "powitf2" { - const inf_f128 = math.inf(f128); - try test__powitf2(0, 0, 1); - try test__powitf2(1, 0, 1); - try test__powitf2(1.5, 0, 1); - try test__powitf2(2, 0, 1); - try test__powitf2(inf_f128, 0, 1); - - try test__powitf2(-0.0, 0, 1); - try test__powitf2(-1, 0, 1); - try test__powitf2(-1.5, 0, 1); - try test__powitf2(-2, 0, 1); - try test__powitf2(-inf_f128, 0, 1); - - try test__powitf2(0, 1, 0); - try test__powitf2(0, 2, 0); - try test__powitf2(0, 3, 0); - try test__powitf2(0, 4, 0); - try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); - try test__powitf2(0, 0x7FFFFFFF, 0); - - try test__powitf2(-0.0, 1, -0.0); - try test__powitf2(-0.0, 2, 0); - try test__powitf2(-0.0, 3, -0.0); - try test__powitf2(-0.0, 4, 0); - try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); - try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); - - try test__powitf2(1, 1, 1); - try test__powitf2(1, 2, 1); - try test__powitf2(1, 3, 1); - try test__powitf2(1, 4, 1); - try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); - try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); - - try test__powitf2(inf_f128, 1, inf_f128); - try test__powitf2(inf_f128, 2, inf_f128); - try test__powitf2(inf_f128, 3, inf_f128); - try test__powitf2(inf_f128, 4, inf_f128); - try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128); - try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128); - - try test__powitf2(-inf_f128, 1, -inf_f128); - try test__powitf2(-inf_f128, 2, inf_f128); - try test__powitf2(-inf_f128, 3, -inf_f128); - try test__powitf2(-inf_f128, 4, inf_f128); - try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128); - try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128); - - try test__powitf2(0, -1, inf_f128); - try test__powitf2(0, -2, inf_f128); - try test__powitf2(0, -3, inf_f128); - try test__powitf2(0, -4, inf_f128); - try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128); - try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128); - try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128); - - try test__powitf2(-0.0, -1, -inf_f128); - try test__powitf2(-0.0, -2, inf_f128); - try test__powitf2(-0.0, -3, -inf_f128); - try test__powitf2(-0.0, -4, inf_f128); - try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128); - try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128); - try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128); - - try test__powitf2(1, -1, 1); - try test__powitf2(1, -2, 1); - try test__powitf2(1, -3, 1); - try test__powitf2(1, -4, 1); - try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); - try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); - try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); - - try test__powitf2(inf_f128, -1, 0); - try test__powitf2(inf_f128, -2, 0); - try test__powitf2(inf_f128, -3, 0); - try test__powitf2(inf_f128, -4, 0); - try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); - try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); - try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); - - try test__powitf2(-inf_f128, -1, -0.0); - try test__powitf2(-inf_f128, -2, 0); - try test__powitf2(-inf_f128, -3, -0.0); - try test__powitf2(-inf_f128, -4, 0); - try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); - try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); - try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); - - try test__powitf2(2, 10, 1024.0); - try test__powitf2(-2, 10, 1024.0); - try test__powitf2(2, -10, 1.0 / 1024.0); - try test__powitf2(-2, -10, 1.0 / 1024.0); - - try test__powitf2(2, 19, 524288.0); - try test__powitf2(-2, 19, -524288.0); - try test__powitf2(2, -19, 1.0 / 524288.0); - try test__powitf2(-2, -19, -1.0 / 524288.0); - - try test__powitf2(2, 31, 2147483648.0); - try test__powitf2(-2, 31, -2147483648.0); - try test__powitf2(2, -31, 1.0 / 2147483648.0); - try test__powitf2(-2, -31, -1.0 / 2147483648.0); + try test_powi_f64(0, 0, 1); + try test_powi_f64(1, 0, 1); + try test_powi_f64(1.5, 0, 1); + try test_powi_f64(2, 0, 1); + try test_powi_f64(inf_f64, 0, 1); + + try test_powi_f64(-0.0, 0, 1); + try test_powi_f64(-1, 0, 1); + try test_powi_f64(-1.5, 0, 1); + try test_powi_f64(-2, 0, 1); + try test_powi_f64(-inf_f64, 0, 1); + + try test_powi_f64(0, 1, 0); + try test_powi_f64(0, 2, 0); + try test_powi_f64(0, 3, 0); + try test_powi_f64(0, 4, 0); + try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); + try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); + + try test_powi_f64(-0.0, 1, -0.0); + try test_powi_f64(-0.0, 2, 0); + try test_powi_f64(-0.0, 3, -0.0); + try test_powi_f64(-0.0, 4, 0); + try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); + try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); + + try test_powi_f64(1, 1, 1); + try test_powi_f64(1, 2, 1); + try test_powi_f64(1, 3, 1); + try test_powi_f64(1, 4, 1); + try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); + try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); + + try test_powi_f64(inf_f64, 1, inf_f64); + try test_powi_f64(inf_f64, 2, inf_f64); + try test_powi_f64(inf_f64, 3, inf_f64); + try test_powi_f64(inf_f64, 4, inf_f64); + try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64); + try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64); + + try test_powi_f64(-inf_f64, 1, -inf_f64); + try test_powi_f64(-inf_f64, 2, inf_f64); + try test_powi_f64(-inf_f64, 3, -inf_f64); + try test_powi_f64(-inf_f64, 4, inf_f64); + try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64); + try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64); + + try test_powi_f64(0, -1, inf_f64); + try test_powi_f64(0, -2, inf_f64); + try test_powi_f64(0, -3, inf_f64); + try test_powi_f64(0, -4, inf_f64); + try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64); + try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64); + try test_powi_f64(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64); + + try test_powi_f64(-0.0, -1, -inf_f64); + try test_powi_f64(-0.0, -2, inf_f64); + try test_powi_f64(-0.0, -3, -inf_f64); + try test_powi_f64(-0.0, -4, inf_f64); + try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64); + try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64); + try test_powi_f64(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64); + + try test_powi_f64(1, -1, 1); + try test_powi_f64(1, -2, 1); + try test_powi_f64(1, -3, 1); + try test_powi_f64(1, -4, 1); + try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); + try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); + try test_powi_f64(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); + + try test_powi_f64(inf_f64, -1, 0); + try test_powi_f64(inf_f64, -2, 0); + try test_powi_f64(inf_f64, -3, 0); + try test_powi_f64(inf_f64, -4, 0); + try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); + try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); + try test_powi_f64(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); + + try test_powi_f64(-inf_f64, -1, -0.0); + try test_powi_f64(-inf_f64, -2, 0); + try test_powi_f64(-inf_f64, -3, -0.0); + try test_powi_f64(-inf_f64, -4, 0); + try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); + try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); + try test_powi_f64(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); + + try test_powi_f64(2, 10, 1024.0); + try test_powi_f64(-2, 10, 1024.0); + try test_powi_f64(2, -10, 1.0 / 1024.0); + try test_powi_f64(-2, -10, 1.0 / 1024.0); + + try test_powi_f64(2, 19, 524288.0); + try test_powi_f64(-2, 19, -524288.0); + try test_powi_f64(2, -19, 1.0 / 524288.0); + try test_powi_f64(-2, -19, -1.0 / 524288.0); + + try test_powi_f64(2, 31, 2147483648.0); + try test_powi_f64(-2, 31, -2147483648.0); + try test_powi_f64(2, -31, 1.0 / 2147483648.0); + try test_powi_f64(-2, -31, -1.0 / 2147483648.0); } -test "powixf2" { +test powi_f80 { const inf_f80 = math.inf(f80); - try test__powixf2(0, 0, 1); - try test__powixf2(1, 0, 1); - try test__powixf2(1.5, 0, 1); - try test__powixf2(2, 0, 1); - try test__powixf2(inf_f80, 0, 1); - - try test__powixf2(-0.0, 0, 1); - try test__powixf2(-1, 0, 1); - try test__powixf2(-1.5, 0, 1); - try test__powixf2(-2, 0, 1); - try test__powixf2(-inf_f80, 0, 1); - - try test__powixf2(0, 1, 0); - try test__powixf2(0, 2, 0); - try test__powixf2(0, 3, 0); - try test__powixf2(0, 4, 0); - try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); - try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); - - try test__powixf2(-0.0, 1, -0.0); - try test__powixf2(-0.0, 2, 0); - try test__powixf2(-0.0, 3, -0.0); - try test__powixf2(-0.0, 4, 0); - try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); - try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); - - try test__powixf2(1, 1, 1); - try test__powixf2(1, 2, 1); - try test__powixf2(1, 3, 1); - try test__powixf2(1, 4, 1); - try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); - try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); - - try test__powixf2(inf_f80, 1, inf_f80); - try test__powixf2(inf_f80, 2, inf_f80); - try test__powixf2(inf_f80, 3, inf_f80); - try test__powixf2(inf_f80, 4, inf_f80); - try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80); - try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80); - - try test__powixf2(-inf_f80, 1, -inf_f80); - try test__powixf2(-inf_f80, 2, inf_f80); - try test__powixf2(-inf_f80, 3, -inf_f80); - try test__powixf2(-inf_f80, 4, inf_f80); - try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80); - try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80); - - try test__powixf2(0, -1, inf_f80); - try test__powixf2(0, -2, inf_f80); - try test__powixf2(0, -3, inf_f80); - try test__powixf2(0, -4, inf_f80); - try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80); - try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80); - try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80); - - try test__powixf2(-0.0, -1, -inf_f80); - try test__powixf2(-0.0, -2, inf_f80); - try test__powixf2(-0.0, -3, -inf_f80); - try test__powixf2(-0.0, -4, inf_f80); - try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80); - try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80); - try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80); - - try test__powixf2(1, -1, 1); - try test__powixf2(1, -2, 1); - try test__powixf2(1, -3, 1); - try test__powixf2(1, -4, 1); - try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); - try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); - try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); - - try test__powixf2(inf_f80, -1, 0); - try test__powixf2(inf_f80, -2, 0); - try test__powixf2(inf_f80, -3, 0); - try test__powixf2(inf_f80, -4, 0); - try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); - try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); - try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); - - try test__powixf2(-inf_f80, -1, -0.0); - try test__powixf2(-inf_f80, -2, 0); - try test__powixf2(-inf_f80, -3, -0.0); - try test__powixf2(-inf_f80, -4, 0); - try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); - try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); - try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); - - try test__powixf2(2, 10, 1024.0); - try test__powixf2(-2, 10, 1024.0); - try test__powixf2(2, -10, 1.0 / 1024.0); - try test__powixf2(-2, -10, 1.0 / 1024.0); - - try test__powixf2(2, 19, 524288.0); - try test__powixf2(-2, 19, -524288.0); - try test__powixf2(2, -19, 1.0 / 524288.0); - try test__powixf2(-2, -19, -1.0 / 524288.0); - - try test__powixf2(2, 31, 2147483648.0); - try test__powixf2(-2, 31, -2147483648.0); - try test__powixf2(2, -31, 1.0 / 2147483648.0); - try test__powixf2(-2, -31, -1.0 / 2147483648.0); + try test_powi_f80(0, 0, 1); + try test_powi_f80(1, 0, 1); + try test_powi_f80(1.5, 0, 1); + try test_powi_f80(2, 0, 1); + try test_powi_f80(inf_f80, 0, 1); + + try test_powi_f80(-0.0, 0, 1); + try test_powi_f80(-1, 0, 1); + try test_powi_f80(-1.5, 0, 1); + try test_powi_f80(-2, 0, 1); + try test_powi_f80(-inf_f80, 0, 1); + + try test_powi_f80(0, 1, 0); + try test_powi_f80(0, 2, 0); + try test_powi_f80(0, 3, 0); + try test_powi_f80(0, 4, 0); + try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); + try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0); + + try test_powi_f80(-0.0, 1, -0.0); + try test_powi_f80(-0.0, 2, 0); + try test_powi_f80(-0.0, 3, -0.0); + try test_powi_f80(-0.0, 4, 0); + try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); + try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); + + try test_powi_f80(1, 1, 1); + try test_powi_f80(1, 2, 1); + try test_powi_f80(1, 3, 1); + try test_powi_f80(1, 4, 1); + try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); + try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); + + try test_powi_f80(inf_f80, 1, inf_f80); + try test_powi_f80(inf_f80, 2, inf_f80); + try test_powi_f80(inf_f80, 3, inf_f80); + try test_powi_f80(inf_f80, 4, inf_f80); + try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80); + try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80); + + try test_powi_f80(-inf_f80, 1, -inf_f80); + try test_powi_f80(-inf_f80, 2, inf_f80); + try test_powi_f80(-inf_f80, 3, -inf_f80); + try test_powi_f80(-inf_f80, 4, inf_f80); + try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80); + try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80); + + try test_powi_f80(0, -1, inf_f80); + try test_powi_f80(0, -2, inf_f80); + try test_powi_f80(0, -3, inf_f80); + try test_powi_f80(0, -4, inf_f80); + try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80); + try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80); + try test_powi_f80(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80); + + try test_powi_f80(-0.0, -1, -inf_f80); + try test_powi_f80(-0.0, -2, inf_f80); + try test_powi_f80(-0.0, -3, -inf_f80); + try test_powi_f80(-0.0, -4, inf_f80); + try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80); + try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80); + try test_powi_f80(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80); + + try test_powi_f80(1, -1, 1); + try test_powi_f80(1, -2, 1); + try test_powi_f80(1, -3, 1); + try test_powi_f80(1, -4, 1); + try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); + try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); + try test_powi_f80(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); + + try test_powi_f80(inf_f80, -1, 0); + try test_powi_f80(inf_f80, -2, 0); + try test_powi_f80(inf_f80, -3, 0); + try test_powi_f80(inf_f80, -4, 0); + try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); + try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); + try test_powi_f80(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); + + try test_powi_f80(-inf_f80, -1, -0.0); + try test_powi_f80(-inf_f80, -2, 0); + try test_powi_f80(-inf_f80, -3, -0.0); + try test_powi_f80(-inf_f80, -4, 0); + try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); + try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); + try test_powi_f80(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); + + try test_powi_f80(2, 10, 1024.0); + try test_powi_f80(-2, 10, 1024.0); + try test_powi_f80(2, -10, 1.0 / 1024.0); + try test_powi_f80(-2, -10, 1.0 / 1024.0); + + try test_powi_f80(2, 19, 524288.0); + try test_powi_f80(-2, 19, -524288.0); + try test_powi_f80(2, -19, 1.0 / 524288.0); + try test_powi_f80(-2, -19, -1.0 / 524288.0); + + try test_powi_f80(2, 31, 2147483648.0); + try test_powi_f80(-2, 31, -2147483648.0); + try test_powi_f80(2, -31, 1.0 / 2147483648.0); + try test_powi_f80(-2, -31, -1.0 / 2147483648.0); +} + +test powi_f128 { + const inf_f128 = math.inf(f128); + try test_powi_f128(0, 0, 1); + try test_powi_f128(1, 0, 1); + try test_powi_f128(1.5, 0, 1); + try test_powi_f128(2, 0, 1); + try test_powi_f128(inf_f128, 0, 1); + + try test_powi_f128(-0.0, 0, 1); + try test_powi_f128(-1, 0, 1); + try test_powi_f128(-1.5, 0, 1); + try test_powi_f128(-2, 0, 1); + try test_powi_f128(-inf_f128, 0, 1); + + try test_powi_f128(0, 1, 0); + try test_powi_f128(0, 2, 0); + try test_powi_f128(0, 3, 0); + try test_powi_f128(0, 4, 0); + try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); + try test_powi_f128(0, 0x7FFFFFFF, 0); + + try test_powi_f128(-0.0, 1, -0.0); + try test_powi_f128(-0.0, 2, 0); + try test_powi_f128(-0.0, 3, -0.0); + try test_powi_f128(-0.0, 4, 0); + try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0); + try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0); + + try test_powi_f128(1, 1, 1); + try test_powi_f128(1, 2, 1); + try test_powi_f128(1, 3, 1); + try test_powi_f128(1, 4, 1); + try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1); + try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1); + + try test_powi_f128(inf_f128, 1, inf_f128); + try test_powi_f128(inf_f128, 2, inf_f128); + try test_powi_f128(inf_f128, 3, inf_f128); + try test_powi_f128(inf_f128, 4, inf_f128); + try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128); + try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128); + + try test_powi_f128(-inf_f128, 1, -inf_f128); + try test_powi_f128(-inf_f128, 2, inf_f128); + try test_powi_f128(-inf_f128, 3, -inf_f128); + try test_powi_f128(-inf_f128, 4, inf_f128); + try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128); + try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128); + + try test_powi_f128(0, -1, inf_f128); + try test_powi_f128(0, -2, inf_f128); + try test_powi_f128(0, -3, inf_f128); + try test_powi_f128(0, -4, inf_f128); + try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128); + try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128); + try test_powi_f128(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128); + + try test_powi_f128(-0.0, -1, -inf_f128); + try test_powi_f128(-0.0, -2, inf_f128); + try test_powi_f128(-0.0, -3, -inf_f128); + try test_powi_f128(-0.0, -4, inf_f128); + try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128); + try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128); + try test_powi_f128(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128); + + try test_powi_f128(1, -1, 1); + try test_powi_f128(1, -2, 1); + try test_powi_f128(1, -3, 1); + try test_powi_f128(1, -4, 1); + try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); + try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1); + try test_powi_f128(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1); + + try test_powi_f128(inf_f128, -1, 0); + try test_powi_f128(inf_f128, -2, 0); + try test_powi_f128(inf_f128, -3, 0); + try test_powi_f128(inf_f128, -4, 0); + try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); + try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0); + try test_powi_f128(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); + + try test_powi_f128(-inf_f128, -1, -0.0); + try test_powi_f128(-inf_f128, -2, 0); + try test_powi_f128(-inf_f128, -3, -0.0); + try test_powi_f128(-inf_f128, -4, 0); + try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0); + try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0); + try test_powi_f128(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0); + + try test_powi_f128(2, 10, 1024.0); + try test_powi_f128(-2, 10, 1024.0); + try test_powi_f128(2, -10, 1.0 / 1024.0); + try test_powi_f128(-2, -10, 1.0 / 1024.0); + + try test_powi_f128(2, 19, 524288.0); + try test_powi_f128(-2, 19, -524288.0); + try test_powi_f128(2, -19, 1.0 / 524288.0); + try test_powi_f128(-2, -19, -1.0 / 524288.0); + + try test_powi_f128(2, 31, 2147483648.0); + try test_powi_f128(-2, 31, -2147483648.0); + try test_powi_f128(2, -31, 1.0 / 2147483648.0); + try test_powi_f128(-2, -31, -1.0 / 2147483648.0); } diff --git a/lib/compiler_rt/round.zig b/lib/compiler_rt/round.zig index 590b957922efdbf33ac4fea2728390daad82ee38..6c86984605af2d246a4e582851a5d172a67d7c69 100644 --- a/lib/compiler_rt/round.zig +++ b/lib/compiler_rt/round.zig @@ -18,19 +18,23 @@ comptime { symbol(&roundf, "roundf"); symbol(&round, "round"); symbol(&__roundx, "__roundx"); - if (compiler_rt.want_ppc_abi) { - symbol(&roundq, "roundf128"); - } + if (compiler_rt.want_ppc_abi) symbol(&roundq, "roundf128"); symbol(&roundq, "roundq"); symbol(&roundl, "roundl"); } -pub fn __roundh(x: f16) callconv(.c) f16 { +fn __roundh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(round_f16(compiler_rt.f16.fromAbi(x))); +} +pub fn round_f16(x: f16) f16 { // TODO: more efficient implementation - return @floatCast(roundf(x)); + return @floatCast(round_f32(x)); } -pub fn roundf(x_: f32) callconv(.c) f32 { +fn roundf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(round_f32(compiler_rt.f32.fromAbi(x))); +} +pub fn round_f32(x_: f32) f32 { const f32_toint = 1.0 / math.floatEps(f32); var x = x_; @@ -65,7 +69,10 @@ pub fn roundf(x_: f32) callconv(.c) f32 { } } -pub fn round(x_: f64) callconv(.c) f64 { +fn round(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(round_f64(compiler_rt.f64.fromAbi(x))); +} +pub fn round_f64(x_: f64) f64 { const f64_toint = 1.0 / math.floatEps(f64); var x = x_; @@ -100,12 +107,18 @@ pub fn round(x_: f64) callconv(.c) f64 { } } -pub fn __roundx(x: f80) callconv(.c) f80 { +fn __roundx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(round_f80(compiler_rt.f80.fromAbi(x))); +} +pub fn round_f80(x: f80) f80 { // TODO: more efficient implementation - return @floatCast(roundq(x)); + return @floatCast(round_f128(x)); } -pub fn roundq(x_: f128) callconv(.c) f128 { +fn roundq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(round_f128(compiler_rt.f128.fromAbi(x))); +} +pub fn round_f128(x_: f128) f128 { const f128_toint = 1.0 / math.floatEps(f128); var x = x_; @@ -142,54 +155,79 @@ pub fn roundq(x_: f128) callconv(.c) f128 { pub fn roundl(x: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return round(x), - 80 => return __roundx(x), - 128 => return roundq(x), - else => @compileError("unreachable"), + 64 => return round_f64(x), + 80 => return round_f80(x), + 128 => return round_f128(x), + else => comptime unreachable, } } -test "round32" { - try expect(roundf(1.3) == 1.0); - try expect(roundf(-1.3) == -1.0); - try expect(roundf(0.2) == 0.0); - try expect(roundf(1.8) == 2.0); +test round_f16 { + try expect(round_f16(1.3) == 1.0); + try expect(round_f16(-1.3) == -1.0); + try expect(round_f16(1.8) == 2.0); + try expect(round_f16(-1.8) == -2.0); + try expect(math.isPositiveZero(round_f16(0.2))); + try expect(math.isNegativeZero(round_f16(-0.2))); + try expect(math.isPositiveZero(round_f16(0.0))); + try expect(math.isNegativeZero(round_f16(-0.0))); + try expect(math.isPositiveInf(round_f16(math.inf(f32)))); + try expect(math.isNegativeInf(round_f16(-math.inf(f32)))); + try expect(math.isNan(round_f16(math.nan(f32)))); } -test "round64" { - try expect(round(1.3) == 1.0); - try expect(round(-1.3) == -1.0); - try expect(round(0.2) == 0.0); - try expect(round(1.8) == 2.0); +test round_f32 { + try expect(round_f32(1.3) == 1.0); + try expect(round_f32(-1.3) == -1.0); + try expect(round_f32(1.8) == 2.0); + try expect(round_f32(-1.8) == -2.0); + try expect(math.isPositiveZero(round_f32(0.2))); + try expect(math.isNegativeZero(round_f32(-0.2))); + try expect(math.isPositiveZero(round_f32(0.0))); + try expect(math.isNegativeZero(round_f32(-0.0))); + try expect(math.isPositiveInf(round_f32(math.inf(f32)))); + try expect(math.isNegativeInf(round_f32(-math.inf(f32)))); + try expect(math.isNan(round_f32(math.nan(f32)))); } -test "round128" { - try expect(roundq(1.3) == 1.0); - try expect(roundq(-1.3) == -1.0); - try expect(roundq(0.2) == 0.0); - try expect(roundq(1.8) == 2.0); +test round_f64 { + try expect(round_f64(1.3) == 1.0); + try expect(round_f64(-1.3) == -1.0); + try expect(round_f64(1.8) == 2.0); + try expect(round_f64(-1.8) == -2.0); + try expect(math.isPositiveZero(round_f64(0.2))); + try expect(math.isNegativeZero(round_f64(-0.2))); + try expect(math.isPositiveZero(round_f64(0.0))); + try expect(math.isNegativeZero(round_f64(-0.0))); + try expect(math.isPositiveInf(round_f64(math.inf(f64)))); + try expect(math.isNegativeInf(round_f64(-math.inf(f64)))); + try expect(math.isNan(round_f64(math.nan(f64)))); } -test "round32.special" { - try expect(roundf(0.0) == 0.0); - try expect(roundf(-0.0) == -0.0); - try expect(math.isPositiveInf(roundf(math.inf(f32)))); - try expect(math.isNegativeInf(roundf(-math.inf(f32)))); - try expect(math.isNan(roundf(math.nan(f32)))); +test round_f80 { + try expect(round_f80(1.3) == 1.0); + try expect(round_f80(-1.3) == -1.0); + try expect(round_f80(1.8) == 2.0); + try expect(round_f80(-1.8) == -2.0); + try expect(math.isPositiveZero(round_f80(0.2))); + try expect(math.isNegativeZero(round_f80(-0.2))); + try expect(math.isPositiveZero(round_f80(0.0))); + try expect(math.isNegativeZero(round_f80(-0.0))); + try expect(math.isPositiveInf(round_f80(math.inf(f64)))); + try expect(math.isNegativeInf(round_f80(-math.inf(f64)))); + try expect(math.isNan(round_f80(math.nan(f64)))); } -test "round64.special" { - try expect(round(0.0) == 0.0); - try expect(round(-0.0) == -0.0); - try expect(math.isPositiveInf(round(math.inf(f64)))); - try expect(math.isNegativeInf(round(-math.inf(f64)))); - try expect(math.isNan(round(math.nan(f64)))); -} - -test "round128.special" { - try expect(roundq(0.0) == 0.0); - try expect(roundq(-0.0) == -0.0); - try expect(math.isPositiveInf(roundq(math.inf(f128)))); - try expect(math.isNegativeInf(roundq(-math.inf(f128)))); - try expect(math.isNan(roundq(math.nan(f128)))); +test round_f128 { + try expect(round_f128(1.3) == 1.0); + try expect(round_f128(-1.3) == -1.0); + try expect(round_f128(1.8) == 2.0); + try expect(round_f128(-1.8) == -2.0); + try expect(math.isPositiveZero(round_f128(0.2))); + try expect(math.isNegativeZero(round_f128(-0.2))); + try expect(math.isPositiveZero(round_f128(0.0))); + try expect(math.isNegativeZero(round_f128(-0.0))); + try expect(math.isPositiveInf(round_f128(math.inf(f128)))); + try expect(math.isNegativeInf(round_f128(-math.inf(f128)))); + try expect(math.isNan(round_f128(math.nan(f128)))); } diff --git a/lib/compiler_rt/sin.zig b/lib/compiler_rt/sin.zig index 040cba8cd3ef34e59f6bfd181a3c09036963fb4c..fe818922fe4af6542dc88fd682367860ae4908da 100644 --- a/lib/compiler_rt/sin.zig +++ b/lib/compiler_rt/sin.zig @@ -13,31 +13,37 @@ const expect = std.testing.expect; const expectApproxEqAbs = std.testing.expectApproxEqAbs; const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; +const symbol = compiler_rt.symbol; const trig = @import("trig.zig"); const rem_pio2 = @import("rem_pio2.zig").rem_pio2; const rem_pio2f = @import("rem_pio2f.zig").rem_pio2f; const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; comptime { - symbol(&sinh, "__sinh"); - symbol(&sinl, "__sinl"); + symbol(&__sinh, "__sinh"); symbol(&sinf, "sinf"); symbol(&sin, "sin"); - symbol(&sinx, "__sinx"); + symbol(&__sinx, "__sinx"); if (compiler_rt.want_ppc_abi) { symbol(&sinq, "sinf128"); } symbol(&sinq, "sinq"); symbol(&sinl, "sinl"); + symbol(&sinl, "__sinl"); // required by musl } -pub fn sinh(x: f16) callconv(.c) f16 { +fn __sinh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(sin_f16(compiler_rt.f16.fromAbi(x))); +} +pub fn sin_f16(x: f16) f16 { // TODO: more efficient implementation - return @floatCast(sinf(x)); + return @floatCast(sin_f32(x)); } -pub fn sinf(x: f32) callconv(.c) f32 { +fn sinf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(sin_f32(compiler_rt.f32.fromAbi(x))); +} +pub fn sin_f32(x: f32) f32 { // Small multiples of pi/2 rounded to double precision. const s1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 const s2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 @@ -98,7 +104,10 @@ pub fn sinf(x: f32) callconv(.c) f32 { }; } -pub fn sin(x: f64) callconv(.c) f64 { +fn sin(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(sin_f64(compiler_rt.f64.fromAbi(x))); +} +pub fn sin_f64(x: f64) f64 { var ix = @as(u64, @bitCast(x)) >> 32; ix &= 0x7fffffff; @@ -133,7 +142,10 @@ pub fn sin(x: f64) callconv(.c) f64 { }; } -fn sinx(x: f80) callconv(.c) f80 { +fn __sinx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(sin_f80(compiler_rt.f80.fromAbi(x))); +} +pub fn sin_f80(x: f80) f80 { const se = ld.signExponent(x) & 0x7fff; if (se == 0x7fff) { return x - x; @@ -160,7 +172,10 @@ fn sinx(x: f80) callconv(.c) f80 { }; } -pub fn sinq(x: f128) callconv(.c) f128 { +fn sinq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(sin_f128(compiler_rt.f128.fromAbi(x))); +} +pub fn sin_f128(x: f128) f128 { const se = ld.signExponent(x) & 0x7fff; if (se == 0x7fff) { return x - x; @@ -189,20 +204,21 @@ pub fn sinq(x: f128) callconv(.c) f128 { pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return sin(x), - 80 => return sinx(x), - 128 => return sinq(x), - else => @compileError("unreachable"), + 64 => return sin_f64(x), + 80 => return sin_f80(x), + 128 => return sin_f128(x), + else => comptime unreachable, } } fn testSinSpecial(comptime T: type) !void { const f = switch (T) { - f32 => sinf, - f64 => sin, - f80 => sinx, - f128 => sinq, - else => @compileError("unimplemented"), + f16 => sin_f16, + f32 => sin_f32, + f64 => sin_f64, + f80 => sin_f80, + f128 => sin_f128, + else => comptime unreachable, }; try expect(math.isPositiveZero(f(0.0))); @@ -214,13 +230,13 @@ fn testSinSpecial(comptime T: type) !void { test "sin32.normal" { const epsilon = math.floatEps(f32); - try expectApproxEqAbs(@as(f32, 0.0), sinf(0.0), epsilon); - try expectApproxEqAbs(@as(f32, 0.19866933), sinf(0.2), epsilon); - try expectApproxEqAbs(@as(f32, 0.77851737), sinf(0.8923), epsilon); - try expectApproxEqAbs(@as(f32, 0.997495), sinf(1.5), epsilon); - try expectApproxEqAbs(@as(f32, -0.997495), sinf(-1.5), epsilon); - try expectApproxEqAbs(@as(f32, -0.24654257), sinf(37.45), epsilon); - try expectApproxEqAbs(@as(f32, 0.9161657), sinf(89.123), epsilon); + try expectApproxEqAbs(@as(f32, 0.0), sin_f32(0.0), epsilon); + try expectApproxEqAbs(@as(f32, 0.19866933), sin_f32(0.2), epsilon); + try expectApproxEqAbs(@as(f32, 0.77851737), sin_f32(0.8923), epsilon); + try expectApproxEqAbs(@as(f32, 0.997495), sin_f32(1.5), epsilon); + try expectApproxEqAbs(@as(f32, -0.997495), sin_f32(-1.5), epsilon); + try expectApproxEqAbs(@as(f32, -0.24654257), sin_f32(37.45), epsilon); + try expectApproxEqAbs(@as(f32, 0.9161657), sin_f32(89.123), epsilon); } test "sin32.special" { @@ -229,13 +245,13 @@ test "sin32.special" { test "sin64.normal" { const epsilon = math.floatEps(f64); - try expectApproxEqAbs(@as(f64, 0.0), sin(0.0), epsilon); - try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin(0.2), epsilon); - try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin(0.8923), epsilon); - try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin(1.5), epsilon); - try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin(-1.5), epsilon); - try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin(37.45), epsilon); - try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin(89.123), epsilon); + try expectApproxEqAbs(@as(f64, 0.0), sin_f64(0.0), epsilon); + try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin_f64(0.2), epsilon); + try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin_f64(0.8923), epsilon); + try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin_f64(1.5), epsilon); + try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin_f64(-1.5), epsilon); + try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin_f64(37.45), epsilon); + try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin_f64(89.123), epsilon); } test "sin64.special" { @@ -244,13 +260,13 @@ test "sin64.special" { test "sin80.normal" { const epsilon = math.floatEps(f80); - try expectApproxEqAbs(@as(f80, 0.0), sinx(0.0), epsilon); - try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sinx(0.2), epsilon); - try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sinx(0.8923), epsilon); - try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sinx(1.5), epsilon); - try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sinx(-1.5), epsilon); - try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sinx(37.45), epsilon); - try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sinx(89.123), epsilon); + try expectApproxEqAbs(@as(f80, 0.0), sin_f80(0.0), epsilon); + try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sin_f80(0.2), epsilon); + try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sin_f80(0.8923), epsilon); + try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sin_f80(1.5), epsilon); + try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sin_f80(-1.5), epsilon); + try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sin_f80(37.45), epsilon); + try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sin_f80(89.123), epsilon); } test "sin80.special" { @@ -259,13 +275,13 @@ test "sin80.special" { test "sin128.normal" { const epsilon = math.floatEps(f128); - try expectApproxEqAbs(@as(f128, 0.0), sinq(0.0), epsilon); - try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sinq(0.2), epsilon); - try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sinq(0.8923), epsilon); - try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sinq(1.5), epsilon); - try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sinq(-1.5), epsilon); - try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sinq(37.45), epsilon); - try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sinq(89.123), epsilon); + try expectApproxEqAbs(@as(f128, 0.0), sin_f128(0.0), epsilon); + try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sin_f128(0.2), epsilon); + try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sin_f128(0.8923), epsilon); + try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sin_f128(1.5), epsilon); + try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sin_f128(-1.5), epsilon); + try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sin_f128(37.45), epsilon); + try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sin_f128(89.123), epsilon); } test "sin128.special" { @@ -274,10 +290,10 @@ test "sin128.special" { test "sin32 #9901" { const float: f32 = @bitCast(@as(u32, 0b11100011111111110000000000000000)); - _ = sinf(float); + _ = sin_f32(float); } test "sin64 #9901" { const float: f64 = @bitCast(@as(u64, 0b1111111101000001000000001111110111111111100000000000000000000001)); - _ = sin(float); + _ = sin_f64(float); } diff --git a/lib/compiler_rt/sincos.zig b/lib/compiler_rt/sincos.zig index 24bb751e76e7e93d32b05a4a801dec6d5d474709..6d2b9f007a90f94c158bb636d3fcd1d8e6b40a7c 100644 --- a/lib/compiler_rt/sincos.zig +++ b/lib/compiler_rt/sincos.zig @@ -25,16 +25,23 @@ comptime { symbol(&sincosl, "sincosl"); } -pub fn sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.c) void { +fn sincosh(x: compiler_rt.f16.Abi, r_sin: *compiler_rt.f16.Abi, r_cos: *compiler_rt.f16.Abi) callconv(.c) void { + const s, const c = sincos_f16(compiler_rt.f16.fromAbi(x)); + r_sin.* = compiler_rt.f16.toAbi(s); + r_cos.* = compiler_rt.f16.toAbi(c); +} +pub fn sincos_f16(x: f16) struct { f16, f16 } { // TODO: more efficient implementation - var big_sin: f32 = undefined; - var big_cos: f32 = undefined; - sincosf(x, &big_sin, &big_cos); - r_sin.* = @as(f16, @floatCast(big_sin)); - r_cos.* = @as(f16, @floatCast(big_cos)); + const s, const c = sincos_f32(x); + return .{ @floatCast(s), @floatCast(c) }; } -pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { +fn sincosf(x: compiler_rt.f32.Abi, r_sin: *compiler_rt.f32.Abi, r_cos: *compiler_rt.f32.Abi) callconv(.c) void { + const s, const c = sincos_f32(compiler_rt.f32.fromAbi(x)); + r_sin.* = compiler_rt.f32.toAbi(s); + r_cos.* = compiler_rt.f32.toAbi(c); +} +pub fn sincos_f32(x: f32) struct { f32, f32 } { const sc1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 const sc2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 const sc3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2 @@ -56,13 +63,9 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { mem.doNotOptimizeAway(x + 0x1p120); } } - r_sin.* = x; - r_cos.* = 1.0; - return; + return .{ x, 1.0 }; } - r_sin.* = trig.sindf(x); - r_cos.* = trig.cosdf(x); - return; + return .{ trig.sindf(x), trig.cosdf(x) }; } // |x| ~<= 5*pi/4 @@ -70,18 +73,16 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { // |x| ~<= 3pi/4 if (ix <= 0x4016cbe3) { if (sign) { - r_sin.* = -trig.cosdf(x + sc1pio2); - r_cos.* = trig.sindf(x + sc1pio2); + return .{ -trig.cosdf(x + sc1pio2), trig.sindf(x + sc1pio2) }; } else { - r_sin.* = trig.cosdf(sc1pio2 - x); - r_cos.* = trig.sindf(sc1pio2 - x); + return .{ trig.cosdf(sc1pio2 - x), trig.sindf(sc1pio2 - x) }; } - return; } // -sin(x+c) is not correct if x+c could be 0: -0 vs +0 - r_sin.* = -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2); - r_cos.* = -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2); - return; + return .{ + -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2), + -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2), + }; } // |x| ~<= 9*pi/4 @@ -89,25 +90,21 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { // |x| ~<= 7*pi/4 if (ix <= 0x40afeddf) { if (sign) { - r_sin.* = trig.cosdf(x + sc3pio2); - r_cos.* = -trig.sindf(x + sc3pio2); + return .{ trig.cosdf(x + sc3pio2), -trig.sindf(x + sc3pio2) }; } else { - r_sin.* = -trig.cosdf(x - sc3pio2); - r_cos.* = trig.sindf(x - sc3pio2); + return .{ -trig.cosdf(x - sc3pio2), trig.sindf(x - sc3pio2) }; } - return; } - r_sin.* = trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2); - r_cos.* = trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2); - return; + return .{ + trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2), + trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2), + }; } // sin(Inf or NaN) is NaN if (ix >= 0x7f800000) { const result = x - x; - r_sin.* = result; - r_cos.* = result; - return; + return .{ result, result }; } // general argument reduction needed @@ -115,27 +112,20 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void { const n = rem_pio2f(x, &y); const s = trig.sindf(y); const c = trig.cosdf(y); - switch (n & 3) { - 0 => { - r_sin.* = s; - r_cos.* = c; - }, - 1 => { - r_sin.* = c; - r_cos.* = -s; - }, - 2 => { - r_sin.* = -s; - r_cos.* = -c; - }, - else => { - r_sin.* = -c; - r_cos.* = s; - }, - } + return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) { + 0 => .{ s, c }, + 1 => .{ c, -s }, + 2 => .{ -s, -c }, + 3 => .{ -c, s }, + }; } -pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { +fn sincos(x: compiler_rt.f64.Abi, r_sin: *compiler_rt.f64.Abi, r_cos: *compiler_rt.f64.Abi) callconv(.c) void { + const s, const c = sincos_f64(compiler_rt.f64.fromAbi(x)); + r_sin.* = compiler_rt.f64.toAbi(s); + r_cos.* = compiler_rt.f64.toAbi(c); +} +pub fn sincos_f64(x: f64) struct { f64, f64 } { const ix = @as(u32, @truncate(@as(u64, @bitCast(x)) >> 32)) & 0x7fffffff; // |x| ~< pi/4 @@ -150,21 +140,15 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { mem.doNotOptimizeAway(x + 0x1p120); } } - r_sin.* = x; - r_cos.* = 1.0; - return; + return .{ x, 1.0 }; } - r_sin.* = trig.sin(x, 0.0, 0); - r_cos.* = trig.cos(x, 0.0); - return; + return .{ trig.sin(x, 0.0, 0), trig.cos(x, 0.0) }; } // sincos(Inf or NaN) is NaN if (ix >= 0x7ff00000) { const result = x - x; - r_sin.* = result; - r_cos.* = result; - return; + return .{ result, result }; } // argument reduction needed @@ -172,33 +156,24 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void { const n = rem_pio2(x, &y); const s = trig.sin(y[0], y[1], 1); const c = trig.cos(y[0], y[1]); - switch (n & 3) { - 0 => { - r_sin.* = s; - r_cos.* = c; - }, - 1 => { - r_sin.* = c; - r_cos.* = -s; - }, - 2 => { - r_sin.* = -s; - r_cos.* = -c; - }, - else => { - r_sin.* = -c; - r_cos.* = s; - }, - } + return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) { + 0 => .{ s, c }, + 1 => .{ c, -s }, + 2 => .{ -s, -c }, + 3 => .{ -c, s }, + }; } -pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void { +fn sincosx(x: compiler_rt.f80.Abi, r_sin: *compiler_rt.f80.Abi, r_cos: *compiler_rt.f80.Abi) callconv(.c) void { + const s, const c = sincos_f80(compiler_rt.f80.fromAbi(x)); + r_sin.* = compiler_rt.f80.toAbi(s); + r_cos.* = compiler_rt.f80.toAbi(c); +} +pub fn sincos_f80(x: f80) struct { f80, f80 } { const se = ld.signExponent(x) & 0x7fff; if (se == 0x7fff) { const result = x - x; - r_sin.* = result; - r_cos.* = result; - return; + return .{ result, result }; } if (@abs(x) < trig.pi_4) { @@ -207,47 +182,34 @@ pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void { if (compiler_rt.want_float_exceptions and se == 0) { mem.doNotOptimizeAway(x * 0x1p-120); } - r_sin.* = x; // raise inexact if x!=0 - r_cos.* = 1.0 + x; - return; + return .{ x, 1.0 + x }; } - r_sin.* = trig.sinx(x, 0.0, 0); - r_cos.* = trig.cosx(x, 0.0); - return; + return .{ trig.sinx(x, 0.0, 0), trig.cosx(x, 0.0) }; } var y: [2]f80 = undefined; const n = rem_pio2l(f80, x, &y); const s = trig.sinx(y[0], y[1], 1); const c = trig.cosx(y[0], y[1]); - switch (n & 3) { - 0 => { - r_sin.* = s; - r_cos.* = c; - }, - 1 => { - r_sin.* = c; - r_cos.* = -s; - }, - 2 => { - r_sin.* = -s; - r_cos.* = -c; - }, - else => { - r_sin.* = -c; - r_cos.* = s; - }, - } + return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) { + 0 => .{ s, c }, + 1 => .{ c, -s }, + 2 => .{ -s, -c }, + 3 => .{ -c, s }, + }; } -pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void { +fn sincosq(x: compiler_rt.f128.Abi, r_sin: *compiler_rt.f128.Abi, r_cos: *compiler_rt.f128.Abi) callconv(.c) void { + const s, const c = sincos_f128(compiler_rt.f128.fromAbi(x)); + r_sin.* = compiler_rt.f128.toAbi(s); + r_cos.* = compiler_rt.f128.toAbi(c); +} +pub fn sincos_f128(x: f128) struct { f128, f128 } { const se = ld.signExponent(x) & 0x7fff; if (se == 0x7fff) { const result = x - x; - r_sin.* = result; - r_cos.* = result; - return; + return .{ result, result }; } if (@abs(x) < trig.pi_4) { @@ -256,78 +218,63 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void { if (compiler_rt.want_float_exceptions and se == 0) { mem.doNotOptimizeAway(x * 0x1p-120); } - r_sin.* = x; // raise inexact if x!=0 - r_cos.* = 1.0 + x; - return; + return .{ x, 1.0 + x }; } - r_sin.* = trig.sinq(x, 0.0, 0); - r_cos.* = trig.cosq(x, 0.0); - return; + return .{ trig.sinq(x, 0.0, 0), trig.cosq(x, 0.0) }; } var y: [2]f128 = undefined; const n = rem_pio2l(f128, x, &y); const s = trig.sinq(y[0], y[1], 1); const c = trig.cosq(y[0], y[1]); - switch (n & 3) { - 0 => { - r_sin.* = s; - r_cos.* = c; - }, - 1 => { - r_sin.* = c; - r_cos.* = -s; - }, - 2 => { - r_sin.* = -s; - r_cos.* = -c; - }, - else => { - r_sin.* = -c; - r_cos.* = s; - }, - } + return switch (@as(u2, @truncate(@as(u32, @bitCast(n))))) { + 0 => .{ s, c }, + 1 => .{ c, -s }, + 2 => .{ -s, -c }, + 3 => .{ -c, s }, + }; } pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void { - switch (@typeInfo(c_longdouble).float.bits) { - 64 => return sincos(x, r_sin, r_cos), - 80 => return sincosx(x, r_sin, r_cos), - 128 => return sincosq(x, r_sin, r_cos), - else => @compileError("unreachable"), - } + r_sin.*, r_cos.* = switch (@typeInfo(c_longdouble).float.bits) { + 64 => sincos_f64(x), + 80 => sincos_f80(x), + 128 => sincos_f128(x), + else => comptime unreachable, + }; } fn testSincosSpecial(comptime T: type) !void { const f = switch (T) { - f32 => sincosf, - f64 => sincos, - f80 => sincosx, - f128 => sincosq, + f16 => sincos_f16, + f32 => sincos_f32, + f64 => sincos_f64, + f80 => sincos_f80, + f128 => sincos_f128, else => @compileError("unimplemented"), }; var s: T = undefined; var c: T = undefined; - f(0.0, &s, &c); + s, c = f(0.0); try expect(math.isPositiveZero(s)); try expect(c == 1.0); - f(-0.0, &s, &c); + s, c = f(-0.0); try expect(math.isNegativeZero(s)); try expect(c == 1.0); - f(math.inf(T), &s, &c); + s, c = f(math.inf(T)); try expect(math.isNan(s)); try expect(math.isNan(c)); - f(-math.inf(T), &s, &c); + s, c = f(-math.inf(T)); try expect(math.isNan(s)); try expect(math.isNan(c)); - f(math.nan(T), &s, &c); + s, c = f(math.nan(T)); try expect(math.isNan(s)); try expect(math.isNan(c)); } @@ -337,31 +284,31 @@ test "sincos32.normal" { var s: f32 = undefined; var c: f32 = undefined; - sincosf(0.0, &s, &c); + s, c = sincos_f32(0.0); try expectApproxEqAbs(@as(f32, 0.0), s, epsilon); try expectApproxEqAbs(@as(f32, 1.0), c, epsilon); - sincosf(0.2, &s, &c); + s, c = sincos_f32(0.2); try expectApproxEqAbs(@as(f32, 0.19866933), s, epsilon); try expectApproxEqAbs(@as(f32, 0.9800666), c, epsilon); - sincosf(0.8923, &s, &c); + s, c = sincos_f32(0.8923); try expectApproxEqAbs(@as(f32, 0.77851737), s, epsilon); try expectApproxEqAbs(@as(f32, 0.6276231), c, epsilon); - sincosf(1.5, &s, &c); + s, c = sincos_f32(1.5); try expectApproxEqAbs(@as(f32, 0.997495), s, epsilon); try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon); - sincosf(-1.5, &s, &c); + s, c = sincos_f32(-1.5); try expectApproxEqAbs(@as(f32, -0.997495), s, epsilon); try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon); - sincosf(37.45, &s, &c); + s, c = sincos_f32(37.45); try expectApproxEqAbs(@as(f32, -0.24654257), s, epsilon); try expectApproxEqAbs(@as(f32, 0.96913195), c, epsilon); - sincosf(89.123, &s, &c); + s, c = sincos_f32(89.123); try expectApproxEqAbs(@as(f32, 0.9161657), s, epsilon); try expectApproxEqAbs(@as(f32, 0.40079966), c, epsilon); } @@ -375,31 +322,31 @@ test "sincos64.normal" { var s: f64 = undefined; var c: f64 = undefined; - sincos(0.0, &s, &c); + s, c = sincos_f64(0.0); try expectApproxEqAbs(@as(f64, 0.0), s, epsilon); try expectApproxEqAbs(@as(f64, 1.0), c, epsilon); - sincos(0.2, &s, &c); + s, c = sincos_f64(0.2); try expectApproxEqAbs(@as(f64, 0.19866933079506122), s, epsilon); try expectApproxEqAbs(@as(f64, 0.9800665778412416), c, epsilon); - sincos(0.8923, &s, &c); + s, c = sincos_f64(0.8923); try expectApproxEqAbs(@as(f64, 0.7785173385577349), s, epsilon); try expectApproxEqAbs(@as(f64, 0.6276230983360804), c, epsilon); - sincos(1.5, &s, &c); + s, c = sincos_f64(1.5); try expectApproxEqAbs(@as(f64, 0.9974949866040544), s, epsilon); try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon); - sincos(-1.5, &s, &c); + s, c = sincos_f64(-1.5); try expectApproxEqAbs(@as(f64, -0.9974949866040544), s, epsilon); try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon); - sincos(37.45, &s, &c); + s, c = sincos_f64(37.45); try expectApproxEqAbs(@as(f64, -0.24654331551411082), s, epsilon); try expectApproxEqAbs(@as(f64, 0.9691317730707778), c, epsilon); - sincos(89.123, &s, &c); + s, c = sincos_f64(89.123); try expectApproxEqAbs(@as(f64, 0.9161652766622714), s, epsilon); try expectApproxEqAbs(@as(f64, 0.4008006809354791), c, epsilon); } @@ -413,31 +360,31 @@ test "sincos80.normal" { var s: f80 = undefined; var c: f80 = undefined; - sincosx(0.0, &s, &c); + s, c = sincos_f80(0.0); try expectApproxEqAbs(@as(f80, 0.0), s, epsilon); try expectApproxEqAbs(@as(f80, 1.0), c, epsilon); - sincosx(0.2, &s, &c); + s, c = sincos_f80(0.2); try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), s, epsilon); try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), c, epsilon); - sincosx(0.8923, &s, &c); + s, c = sincos_f80(0.8923); try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), s, epsilon); try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), c, epsilon); - sincosx(1.5, &s, &c); + s, c = sincos_f80(1.5); try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), s, epsilon); try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon); - sincosx(-1.5, &s, &c); + s, c = sincos_f80(-1.5); try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), s, epsilon); try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon); - sincosx(37.45, &s, &c); + s, c = sincos_f80(37.45); try expectApproxEqAbs(@as(f80, -0.24654331551411356504), s, epsilon); try expectApproxEqAbs(@as(f80, 0.9691317730707771246), c, epsilon); - sincosx(89.123, &s, &c); + s, c = sincos_f80(89.123); try expectApproxEqAbs(@as(f80, 0.91616527666226951006), s, epsilon); try expectApproxEqAbs(@as(f80, 0.4008006809354834001), c, epsilon); } @@ -451,31 +398,31 @@ test "sincos128.normal" { var s: f128 = undefined; var c: f128 = undefined; - sincosq(0.0, &s, &c); + s, c = sincos_f128(0.0); try expectApproxEqAbs(@as(f128, 0.0), s, epsilon); try expectApproxEqAbs(@as(f128, 1.0), c, epsilon); - sincosq(0.2, &s, &c); + s, c = sincos_f128(0.2); try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), s, epsilon); try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), c, epsilon); - sincosq(0.8923, &s, &c); + s, c = sincos_f128(0.8923); try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), s, epsilon); try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), c, epsilon); - sincosq(1.5, &s, &c); + s, c = sincos_f128(1.5); try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), s, epsilon); try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon); - sincosq(-1.5, &s, &c); + s, c = sincos_f128(-1.5); try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), s, epsilon); try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon); - sincosq(37.45, &s, &c); + s, c = sincos_f128(37.45); try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), s, epsilon); try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), c, epsilon); - sincosq(89.123, &s, &c); + s, c = sincos_f128(89.123); try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), s, epsilon); try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), c, epsilon); } diff --git a/lib/compiler_rt/sqrt.zig b/lib/compiler_rt/sqrt.zig index 739285af0eaa66af2cf6ed31a3dcc142a708b590..56e43a42fcdd437811ad00d7290de45d5cee82f3 100644 --- a/lib/compiler_rt/sqrt.zig +++ b/lib/compiler_rt/sqrt.zig @@ -28,7 +28,10 @@ comptime { symbol(&sqrtl, "sqrtl"); } -pub fn __sqrth(x: f16) callconv(.c) f16 { +fn __sqrth(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(sqrt_f16(compiler_rt.f16.fromAbi(x))); +} +pub fn sqrt_f16(x: f16) f16 { var ix: u16 = @bitCast(x); var top = ix >> 10; @@ -93,7 +96,10 @@ pub fn __sqrth(x: f16) callconv(.c) f16 { return y; } -pub fn sqrtf(x: f32) callconv(.c) f32 { +fn sqrtf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(sqrt_f32(compiler_rt.f32.fromAbi(x))); +} +pub fn sqrt_f32(x: f32) f32 { var ix: u32 = @bitCast(x); if (ix < @as(u32, @bitCast(@as(f32, 0x1p-126))) or @as(u32, @bitCast(std.math.inf(f32))) <= ix) { @@ -147,7 +153,10 @@ pub fn sqrtf(x: f32) callconv(.c) f32 { return y + t; } -pub fn sqrt(x: f64) callconv(.c) f64 { +fn sqrt(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(sqrt_f64(compiler_rt.f64.fromAbi(x))); +} +pub fn sqrt_f64(x: f64) f64 { var ix: u64 = @bitCast(x); var top = ix >> 52; @@ -284,7 +293,10 @@ pub fn sqrt(x: f64) callconv(.c) f64 { return y; } -pub fn __sqrtx(x: f80) callconv(.c) f80 { +fn __sqrtx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(sqrt_f80(compiler_rt.f80.fromAbi(x))); +} +pub fn sqrt_f80(x: f80) f80 { var ix: u80 = @bitCast(x); var top = ix >> 64; @@ -381,7 +393,10 @@ pub fn __sqrtx(x: f80) callconv(.c) f80 { return y; } -pub fn sqrtq(x: f128) callconv(.c) f128 { +fn sqrtq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(sqrt_f128(compiler_rt.f128.fromAbi(x))); +} +pub fn sqrt_f128(x: f128) f128 { var ix: u128 = @bitCast(x); var top = ix >> 112; @@ -483,10 +498,10 @@ fn _Qp_sqrt(c: *f128, a: *f128) callconv(.c) void { pub fn sqrtl(x: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return sqrt(x), - 80 => return __sqrtx(x), - 128 => return sqrtq(x), - else => @compileError("unreachable"), + 64 => return sqrt_f64(x), + 80 => return sqrt_f80(x), + 128 => return sqrt_f128(x), + else => comptime unreachable, } } @@ -545,187 +560,187 @@ inline fn mul80_tail(a: u80, b: u80) u80 { return alo * blo +% ((ahi * blo) << 40) +% ((alo * bhi) << 40); } -test "__sqrth" { +test "sqrt_f16" { // sqrt(±0) is ±0 - try std.testing.expectEqual(__sqrth(0x0.0p0), 0x0.0p0); - try std.testing.expectEqual(__sqrth(-0x0.0p0), -0x0.0p0); + try std.testing.expectEqual(sqrt_f16(0x0.0p0), 0x0.0p0); + try std.testing.expectEqual(sqrt_f16(-0x0.0p0), -0x0.0p0); // sqrt(+max) is finite - try std.testing.expectEqual(__sqrth(0x1.FFCp15), 0x1.FFCp7); + try std.testing.expectEqual(sqrt_f16(0x1.FFCp15), 0x1.FFCp7); // sqrt(4)=2 - try std.testing.expectEqual(__sqrth(0x1p2), 0x1p1); + try std.testing.expectEqual(sqrt_f16(0x1p2), 0x1p1); // sqrt(x) for x=1, 1±ulp - try std.testing.expectEqual(__sqrth(0x1p0), 0x1p0); - try std.testing.expectEqual(__sqrth(0x1.004p0), 0x1p0); - try std.testing.expectEqual(__sqrth(0x1.FF8p-1), 0x1.FFCp-1); + try std.testing.expectEqual(sqrt_f16(0x1p0), 0x1p0); + try std.testing.expectEqual(sqrt_f16(0x1.004p0), 0x1p0); + try std.testing.expectEqual(sqrt_f16(0x1.FF8p-1), 0x1.FFCp-1); // sqrt(+min) is non-zero - try std.testing.expectEqual(__sqrth(0x1p-14), 0x1p-7); + try std.testing.expectEqual(sqrt_f16(0x1p-14), 0x1p-7); // sqrt(min subnormal) is non-zero - try std.testing.expectEqual(__sqrth(0x0.004p-14), 0x1p-12); + try std.testing.expectEqual(sqrt_f16(0x0.004p-14), 0x1p-12); // sqrt(inf) is inf - try std.testing.expect(math.isInf(__sqrth(math.inf(f16)))); + try std.testing.expect(math.isInf(sqrt_f16(math.inf(f16)))); // sqrt(nan) is nan - try std.testing.expect(math.isNan(__sqrth(math.nan(f16)))); + try std.testing.expect(math.isNan(sqrt_f16(math.nan(f16)))); // sqrt(-ve) is nan - try std.testing.expect(math.isNan(__sqrth(-0x1p-14))); - try std.testing.expect(math.isNan(__sqrth(-0x1p+0))); - try std.testing.expect(math.isNan(__sqrth(-math.inf(f16)))); + try std.testing.expect(math.isNan(sqrt_f16(-0x1p-14))); + try std.testing.expect(math.isNan(sqrt_f16(-0x1p+0))); + try std.testing.expect(math.isNan(sqrt_f16(-math.inf(f16)))); // random arguments - try std.testing.expectEqual(__sqrth(0x1.1p14), 0x1.08p7); - try std.testing.expectEqual(__sqrth(0x1.C9p-12), 0x1.56p-6); - try std.testing.expectEqual(__sqrth(0x1.CE8p-7), 0x1.E68p-4); - try std.testing.expectEqual(__sqrth(0x1.134p-7), 0x1.778p-4); - try std.testing.expectEqual(__sqrth(0x1.E9Cp-10), 0x1.62p-5); - try std.testing.expectEqual(__sqrth(0x1.3Dp9), 0x1.92Cp4); - try std.testing.expectEqual(__sqrth(0x1.AA4p8), 0x1.4A4p4); - try std.testing.expectEqual(__sqrth(0x1.8A8p4), 0x1.3DCp2); - try std.testing.expectEqual(__sqrth(0x1.8Fp-7), 0x1.C4p-4); - try std.testing.expectEqual(__sqrth(0x1.584p-11), 0x1.A3Cp-6); + try std.testing.expectEqual(sqrt_f16(0x1.1p14), 0x1.08p7); + try std.testing.expectEqual(sqrt_f16(0x1.C9p-12), 0x1.56p-6); + try std.testing.expectEqual(sqrt_f16(0x1.CE8p-7), 0x1.E68p-4); + try std.testing.expectEqual(sqrt_f16(0x1.134p-7), 0x1.778p-4); + try std.testing.expectEqual(sqrt_f16(0x1.E9Cp-10), 0x1.62p-5); + try std.testing.expectEqual(sqrt_f16(0x1.3Dp9), 0x1.92Cp4); + try std.testing.expectEqual(sqrt_f16(0x1.AA4p8), 0x1.4A4p4); + try std.testing.expectEqual(sqrt_f16(0x1.8A8p4), 0x1.3DCp2); + try std.testing.expectEqual(sqrt_f16(0x1.8Fp-7), 0x1.C4p-4); + try std.testing.expectEqual(sqrt_f16(0x1.584p-11), 0x1.A3Cp-6); } -test "sqrtf" { +test "sqrt_f32" { // sqrt(±0) is ±0 - try std.testing.expectEqual(sqrtf(0x0.0p0), 0x0.0p0); - try std.testing.expectEqual(sqrtf(-0x0.0p0), -0x0.0p0); + try std.testing.expectEqual(sqrt_f32(0x0.0p0), 0x0.0p0); + try std.testing.expectEqual(sqrt_f32(-0x0.0p0), -0x0.0p0); // sqrt(+max) is finite - try std.testing.expectEqual(sqrtf(0x1.FFFFFEp127), 0x1.FFFFFEp63); + try std.testing.expectEqual(sqrt_f32(0x1.FFFFFEp127), 0x1.FFFFFEp63); // sqrt(4)=2 - try std.testing.expectEqual(sqrtf(0x1p2), 0x1p1); + try std.testing.expectEqual(sqrt_f32(0x1p2), 0x1p1); // sqrt(x) for x=1, 1±ulp - try std.testing.expectEqual(sqrtf(0x1p0), 0x1p0); - try std.testing.expectEqual(sqrtf(0x1.000002p0), 0x1p0); - try std.testing.expectEqual(sqrtf(0x1.FFFFFEp-1), 0x1.FFFFFEp-1); + try std.testing.expectEqual(sqrt_f32(0x1p0), 0x1p0); + try std.testing.expectEqual(sqrt_f32(0x1.000002p0), 0x1p0); + try std.testing.expectEqual(sqrt_f32(0x1.FFFFFEp-1), 0x1.FFFFFEp-1); // sqrt(+min) is non-zero - try std.testing.expectEqual(sqrtf(0x1p-126), 0x1p-63); + try std.testing.expectEqual(sqrt_f32(0x1p-126), 0x1p-63); // sqrt(min subnormal) is non-zero - try std.testing.expectEqual(sqrtf(0x0.000002p-126), 0x1.6a09e6p-75); + try std.testing.expectEqual(sqrt_f32(0x0.000002p-126), 0x1.6a09e6p-75); // sqrt(inf) is inf - try std.testing.expect(math.isInf(sqrtf(math.inf(f32)))); + try std.testing.expect(math.isInf(sqrt_f32(math.inf(f32)))); // sqrt(nan) is nan - try std.testing.expect(math.isNan(sqrtf(math.nan(f32)))); + try std.testing.expect(math.isNan(sqrt_f32(math.nan(f32)))); // sqrt(-ve) is nan - try std.testing.expect(math.isNan(sqrtf(-0x1p-149))); - try std.testing.expect(math.isNan(sqrtf(-0x1p0))); - try std.testing.expect(math.isNan(sqrtf(-math.inf(f32)))); + try std.testing.expect(math.isNan(sqrt_f32(-0x1p-149))); + try std.testing.expect(math.isNan(sqrt_f32(-0x1p0))); + try std.testing.expect(math.isNan(sqrt_f32(-math.inf(f32)))); // random arguments - try std.testing.expectEqual(sqrtf(0x1.4DD57Ep77), 0x1.9D6DA8p38); - try std.testing.expectEqual(sqrtf(0x1.871848p102), 0x1.3C6AFAp51); - try std.testing.expectEqual(sqrtf(0x1.A1D748p-112), 0x1.470EFCp-56); - try std.testing.expectEqual(sqrtf(0x1.E626C2p18), 0x1.60C80Ep9); - try std.testing.expectEqual(sqrtf(0x1.E80E66p-29), 0x1.F3E282p-15); - try std.testing.expectEqual(sqrtf(0x1.B47204p89), 0x1.D8B732p44); - try std.testing.expectEqual(sqrtf(0x1.77F45p15), 0x1.B6BC3Ap7); - try std.testing.expectEqual(sqrtf(0x1.AD5F5p-48), 0x1.4B8A72p-24); - try std.testing.expectEqual(sqrtf(0x1.91A39p-76), 0x1.40A7A8p-38); - try std.testing.expectEqual(sqrtf(0x1.DAE088p79), 0x1.ED16DCp39); + try std.testing.expectEqual(sqrt_f32(0x1.4DD57Ep77), 0x1.9D6DA8p38); + try std.testing.expectEqual(sqrt_f32(0x1.871848p102), 0x1.3C6AFAp51); + try std.testing.expectEqual(sqrt_f32(0x1.A1D748p-112), 0x1.470EFCp-56); + try std.testing.expectEqual(sqrt_f32(0x1.E626C2p18), 0x1.60C80Ep9); + try std.testing.expectEqual(sqrt_f32(0x1.E80E66p-29), 0x1.F3E282p-15); + try std.testing.expectEqual(sqrt_f32(0x1.B47204p89), 0x1.D8B732p44); + try std.testing.expectEqual(sqrt_f32(0x1.77F45p15), 0x1.B6BC3Ap7); + try std.testing.expectEqual(sqrt_f32(0x1.AD5F5p-48), 0x1.4B8A72p-24); + try std.testing.expectEqual(sqrt_f32(0x1.91A39p-76), 0x1.40A7A8p-38); + try std.testing.expectEqual(sqrt_f32(0x1.DAE088p79), 0x1.ED16DCp39); } -test "sqrt" { +test "sqrt_f64" { // sqrt(±0) is ±0 - try std.testing.expectEqual(sqrt(0x0.0p0), 0x0.0p0); - try std.testing.expectEqual(sqrt(-0x0.0p0), -0x0.0p0); + try std.testing.expectEqual(sqrt_f64(0x0.0p0), 0x0.0p0); + try std.testing.expectEqual(sqrt_f64(-0x0.0p0), -0x0.0p0); // sqrt(+max) is finite - try std.testing.expectEqual(sqrt(math.floatMax(f64)), 0x1.FFFFFFFFFFFFFp511); + try std.testing.expectEqual(sqrt_f64(math.floatMax(f64)), 0x1.FFFFFFFFFFFFFp511); // sqrt(4)=2 - try std.testing.expectEqual(sqrt(0x1p2), 0x1p1); + try std.testing.expectEqual(sqrt_f64(0x1p2), 0x1p1); // sqrt(x) for x=1, 1±ulp - try std.testing.expectEqual(sqrt(0x1p0), 0x1p0); - try std.testing.expectEqual(sqrt(0x1p0 + math.floatEps(f64)), 0x1p0); - try std.testing.expectEqual(sqrt(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1); + try std.testing.expectEqual(sqrt_f64(0x1p0), 0x1p0); + try std.testing.expectEqual(sqrt_f64(0x1p0 + math.floatEps(f64)), 0x1p0); + try std.testing.expectEqual(sqrt_f64(0x1p0 - math.floatEps(f64)), 0x1.FFFFFFFFFFFFFp-1); // sqrt(+min) is non-zero - try std.testing.expectEqual(sqrt(math.floatMin(f64)), 0x1p-511); + try std.testing.expectEqual(sqrt_f64(math.floatMin(f64)), 0x1p-511); // sqrt(min subnormal) is non-zero - try std.testing.expectEqual(sqrt(math.floatTrueMin(f64)), 0x1p-537); + try std.testing.expectEqual(sqrt_f64(math.floatTrueMin(f64)), 0x1p-537); // sqrt(inf) is inf - try std.testing.expect(math.isInf(sqrt(math.inf(f64)))); + try std.testing.expect(math.isInf(sqrt_f64(math.inf(f64)))); // sqrt(nan) is nan - try std.testing.expect(math.isNan(sqrt(math.nan(f64)))); + try std.testing.expect(math.isNan(sqrt_f64(math.nan(f64)))); // sqrt(-ve) is nan - try std.testing.expect(math.isNan(sqrt(-0x1p-1074))); - try std.testing.expect(math.isNan(sqrt(-0x1p0))); - try std.testing.expect(math.isNan(sqrt(-math.inf(f64)))); + try std.testing.expect(math.isNan(sqrt_f64(-0x1p-1074))); + try std.testing.expect(math.isNan(sqrt_f64(-0x1p0))); + try std.testing.expect(math.isNan(sqrt_f64(-math.inf(f64)))); // random arguments - try std.testing.expectEqual(sqrt(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235); - try std.testing.expectEqual(sqrt(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395); - try std.testing.expectEqual(sqrt(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69); - try std.testing.expectEqual(sqrt(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139); - try std.testing.expectEqual(sqrt(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458); - try std.testing.expectEqual(sqrt(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125); - try std.testing.expectEqual(sqrt(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243); - try std.testing.expectEqual(sqrt(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169); - try std.testing.expectEqual(sqrt(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133); - try std.testing.expectEqual(sqrt(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178); + try std.testing.expectEqual(sqrt_f64(0x1.27D3510D4789Bp471), 0x1.852E97E58CFB7p235); + try std.testing.expectEqual(sqrt_f64(0x1.8C4FCD5A07846p791), 0x1.C27504E56D938p395); + try std.testing.expectEqual(sqrt_f64(0x1.B1B69324F96E7p-137), 0x1.D73BD0414D8BFp-69); + try std.testing.expectEqual(sqrt_f64(0x1.1CBD179A811FEp278), 0x1.0DFCB9A114A61p139); + try std.testing.expectEqual(sqrt_f64(0x1.1D0C7EFB04A56p917), 0x1.7E0708A25DDCDp458); + try std.testing.expectEqual(sqrt_f64(0x1.21B355DA8C94Bp-249), 0x1.8121CBE2608E3p-125); + try std.testing.expectEqual(sqrt_f64(0x1.63024D4C5E987p487), 0x1.AA56AEA589DCDp243); + try std.testing.expectEqual(sqrt_f64(0x1.45AC3BE941F6Ep339), 0x1.9857F3F453E2Dp169); + try std.testing.expectEqual(sqrt_f64(0x1.3B719C733AA24p267), 0x1.91E12E3AC8F71p133); + try std.testing.expectEqual(sqrt_f64(0x1.0B150433A2275p357), 0x1.71CAB87F8277Cp178); } test "__sqrtx" { // sqrt(±0) is ±0 - try std.testing.expectEqual(__sqrtx(0x0.0p0), 0x0.0p0); - try std.testing.expectEqual(__sqrtx(-0x0.0p0), -0x0.0p0); + try std.testing.expectEqual(sqrt_f80(0x0.0p0), 0x0.0p0); + try std.testing.expectEqual(sqrt_f80(-0x0.0p0), -0x0.0p0); // sqrt(+max) is finite - try std.testing.expectEqual(__sqrtx(math.floatMax(f80)), 0x1.FFFFFFFFFFFFFFFEp8191); + try std.testing.expectEqual(sqrt_f80(math.floatMax(f80)), 0x1.FFFFFFFFFFFFFFFEp8191); // sqrt(4)=2 - try std.testing.expectEqual(__sqrtx(0x1p2), 0x1p1); + try std.testing.expectEqual(sqrt_f80(0x1p2), 0x1p1); // sqrt(x) for x=1, 1±ulp - try std.testing.expectEqual(__sqrtx(0x1p0), 0x1p0); - try std.testing.expectEqual(__sqrtx(0x1p0 + math.floatEps(f80)), 0x1p0); - try std.testing.expectEqual(__sqrtx(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1); + try std.testing.expectEqual(sqrt_f80(0x1p0), 0x1p0); + try std.testing.expectEqual(sqrt_f80(0x1p0 + math.floatEps(f80)), 0x1p0); + try std.testing.expectEqual(sqrt_f80(0x1p0 - math.floatEps(f80)), 0x1.FFFFFFFFFFFFFFFEp-1); // sqrt(+min) is non-zero - try std.testing.expectEqual(__sqrtx(math.floatMin(f80)), 0x1p-8191); + try std.testing.expectEqual(sqrt_f80(math.floatMin(f80)), 0x1p-8191); // sqrt(min subnormal) is non-zero - try std.testing.expectEqual(__sqrtx(math.floatTrueMin(f80)), 0x1.6A09E667F3BCC908p-8223); + try std.testing.expectEqual(sqrt_f80(math.floatTrueMin(f80)), 0x1.6A09E667F3BCC908p-8223); // sqrt(inf) is inf - try std.testing.expect(math.isInf(__sqrtx(math.inf(f80)))); + try std.testing.expect(math.isInf(sqrt_f80(math.inf(f80)))); // sqrt(nan) is nan - try std.testing.expect(math.isNan(__sqrtx(math.nan(f80)))); + try std.testing.expect(math.isNan(sqrt_f80(math.nan(f80)))); // sqrt(-ve) is nan - try std.testing.expect(math.isNan(__sqrtx(-0x1p-16442))); - try std.testing.expect(math.isNan(__sqrtx(-0x1p0))); - try std.testing.expect(math.isNan(__sqrtx(-math.inf(f80)))); + try std.testing.expect(math.isNan(sqrt_f80(-0x1p-16442))); + try std.testing.expect(math.isNan(sqrt_f80(-0x1p0))); + try std.testing.expect(math.isNan(sqrt_f80(-math.inf(f80)))); // random arguments - try std.testing.expectEqual(__sqrtx(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741); - try std.testing.expectEqual(__sqrtx(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165); - try std.testing.expectEqual(__sqrtx(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856); - try std.testing.expectEqual(__sqrtx(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432); - try std.testing.expectEqual(__sqrtx(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591); - try std.testing.expectEqual(__sqrtx(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315); - try std.testing.expectEqual(__sqrtx(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517); - try std.testing.expectEqual(__sqrtx(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706); - try std.testing.expectEqual(__sqrtx(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760); - try std.testing.expectEqual(__sqrtx(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685); + try std.testing.expectEqual(sqrt_f80(0x1.087F3953486918A4p15482), 0x1.0436BBE03D02F32p7741); + try std.testing.expectEqual(sqrt_f80(0x1.530CF9E2AE84D8Fp-6330), 0x1.269CFEF51933BE58p-3165); + try std.testing.expectEqual(sqrt_f80(0x1.3F971515EADD574Ap5713), 0x1.9483232AB780B006p2856); + try std.testing.expectEqual(sqrt_f80(0x1.4CC0DC7379222954p864), 0x1.23DD4D0A4758C2Cp432); + try std.testing.expectEqual(sqrt_f80(0x1.920E5649559A839Ep-3181), 0x1.C5B5BC0F98DD83D2p-1591); + try std.testing.expectEqual(sqrt_f80(0x1.2E59726F87CD1746p-629), 0x1.8973327E95CB350Cp-315); + try std.testing.expectEqual(sqrt_f80(0x1.D3A16391F57B4D64p-9034), 0x1.59FF08B7DEEF5DB2p-4517); + try std.testing.expectEqual(sqrt_f80(0x1.E7053D8DAA49BCEEp-11411), 0x1.F35AA3EA5E18E344p-5706); + try std.testing.expectEqual(sqrt_f80(0x1.797ED0B05DD4A984p7521), 0x1.B7A22E40C6A7867Ap3760); + try std.testing.expectEqual(sqrt_f80(0x1.FC50806445C7226Ap15371), 0x1.FE2766142653F5BEp7685); } -test "sqrtq" { +test "sqrt_f128" { // sqrt(±0) is ±0 - try std.testing.expectEqual(sqrtq(0x0.0p0), 0x0.0p0); - try std.testing.expectEqual(sqrtq(-0x0.0p0), -0x0.0p0); + try std.testing.expectEqual(sqrt_f128(0x0.0p0), 0x0.0p0); + try std.testing.expectEqual(sqrt_f128(-0x0.0p0), -0x0.0p0); // sqrt(+max) is finite - try std.testing.expectEqual(sqrtq(math.floatMax(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp8191); + try std.testing.expectEqual(sqrt_f128(math.floatMax(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp8191); // sqrt(4)=2 - try std.testing.expectEqual(sqrtq(0x1p2), 0x1p1); + try std.testing.expectEqual(sqrt_f128(0x1p2), 0x1p1); // sqrt(x) for x=1, 1±ulp - try std.testing.expectEqual(sqrtq(0x1p0), 0x1p0); - try std.testing.expectEqual(sqrtq(0x1p0 + math.floatEps(f128)), 0x1p0); - try std.testing.expectEqual(sqrtq(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1); + try std.testing.expectEqual(sqrt_f128(0x1p0), 0x1p0); + try std.testing.expectEqual(sqrt_f128(0x1p0 + math.floatEps(f128)), 0x1p0); + try std.testing.expectEqual(sqrt_f128(0x1p0 - math.floatEps(f128)), 0x1.FFFFFFFFFFFFFFFFFFFFFFFFFFFFp-1); // sqrt(+min) is non-zero - try std.testing.expectEqual(sqrtq(math.floatMin(f128)), 0x1p-8191); + try std.testing.expectEqual(sqrt_f128(math.floatMin(f128)), 0x1p-8191); // sqrt(min subnormal) is non-zero - try std.testing.expectEqual(sqrtq(math.floatTrueMin(f128)), 0x1p-8247); + try std.testing.expectEqual(sqrt_f128(math.floatTrueMin(f128)), 0x1p-8247); // sqrt(inf) is inf - try std.testing.expect(math.isInf(sqrtq(math.inf(f128)))); + try std.testing.expect(math.isInf(sqrt_f128(math.inf(f128)))); // sqrt(nan) is nan - try std.testing.expect(math.isNan(sqrtq(math.nan(f128)))); + try std.testing.expect(math.isNan(sqrt_f128(math.nan(f128)))); // sqrt(-ve) is nan - try std.testing.expect(math.isNan(sqrtq(-0x1p-16442))); - try std.testing.expect(math.isNan(sqrtq(-0x1p0))); - try std.testing.expect(math.isNan(sqrtq(-math.inf(f128)))); + try std.testing.expect(math.isNan(sqrt_f128(-0x1p-16442))); + try std.testing.expect(math.isNan(sqrt_f128(-0x1p0))); + try std.testing.expect(math.isNan(sqrt_f128(-math.inf(f128)))); // random arguments - try std.testing.expectEqual(sqrtq(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681); - try std.testing.expectEqual(sqrtq(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882); - try std.testing.expectEqual(sqrtq(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812); - try std.testing.expectEqual(sqrtq(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031); - try std.testing.expectEqual(sqrtq(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513); - try std.testing.expectEqual(sqrtq(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917); - try std.testing.expectEqual(sqrtq(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256); - try std.testing.expectEqual(sqrtq(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476); - try std.testing.expectEqual(sqrtq(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446); - try std.testing.expectEqual(sqrtq(0x1.0E2115475E64A92340914E7F7B37p-13951), 0x1.73E536F82F414134012F55BA5368p-6976); + try std.testing.expectEqual(sqrt_f128(0x1.B6942D29A331751600C9F3AF7E5Fp3363), 0x1.D9DE9AFEF0F2D25586A50CA39D4Dp1681); + try std.testing.expectEqual(sqrt_f128(0x1.5E65C405F84D471A8070ADD7A42Dp11765), 0x1.A78F7F9452B4D9EC2403C81D9D42p5882); + try std.testing.expectEqual(sqrt_f128(0x1.B42334D68F8016D8AE6F5E22B044p-5624), 0x1.4E247A7F2FF2A325E9377BB09C8p-2812); + try std.testing.expectEqual(sqrt_f128(0x1.E61715047F80F2E0B9382B38E06Bp10062), 0x1.60C25D9DFDC0116B78EF5AFDE0E9p5031); + try std.testing.expectEqual(sqrt_f128(0x1.2ED0B53B494CB55A7B04E653D40Ep-1026), 0x1.166CE78D658D2453D700B04C5748p-513); + try std.testing.expectEqual(sqrt_f128(0x1.1BA756B9790E78A4E6F0B083AA89p1835), 0x1.7D1767EA3303DB7A46940033988p917); + try std.testing.expectEqual(sqrt_f128(0x1.5B6C574319C1120335C8E1609704p4512), 0x1.2A3A8A415BB1648C548FBA2A4182p2256); + try std.testing.expectEqual(sqrt_f128(0x1.FF91E8CDEE1552A2B74E77B602Ep14953), 0x1.FFC8F171267D4FE75CBE7AB4D851p7476); + try std.testing.expectEqual(sqrt_f128(0x1.9B1837CFC629A1B6B1BB97099E7Dp2892), 0x1.4468511B909EAF8641BD59105A6Bp1446); + try std.testing.expectEqual(sqrt_f128(0x1.0E2115475E64A92340914E7F7B37p-13951), 0x1.73E536F82F414134012F55BA5368p-6976); } diff --git a/lib/compiler_rt/subdf3.zig b/lib/compiler_rt/subdf3.zig deleted file mode 100644 index 4d00a7f03ae71c4f9bf2ffecbcd1123216dff6b6..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/subdf3.zig +++ /dev/null @@ -1,24 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const addf3 = @import("./addf3.zig").addf3; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_dsub, "__aeabi_dsub"); - } else { - symbol(&__subdf3, "__subdf3"); - } -} - -fn __subdf3(a: f64, b: f64) callconv(.c) f64 { - return sub(a, b); -} - -fn __aeabi_dsub(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) f64 { - return sub(a, b); -} - -inline fn sub(a: f64, b: f64) f64 { - const neg_b = @as(f64, @bitCast(@as(u64, @bitCast(b)) ^ (@as(u64, 1) << 63))); - return addf3(f64, a, neg_b); -} diff --git a/lib/compiler_rt/subhf3.zig b/lib/compiler_rt/subhf3.zig deleted file mode 100644 index 258401d2957a6d3aafcd0aa02c6de63ca0211952..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/subhf3.zig +++ /dev/null @@ -1,12 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const addf3 = @import("./addf3.zig").addf3; - -comptime { - symbol(&__subhf3, "__subhf3"); -} - -fn __subhf3(a: f16, b: f16) callconv(.c) f16 { - const neg_b = @as(f16, @bitCast(@as(u16, @bitCast(b)) ^ (@as(u16, 1) << 15))); - return addf3(f16, a, neg_b); -} diff --git a/lib/compiler_rt/subsf3.zig b/lib/compiler_rt/subsf3.zig deleted file mode 100644 index 94d47220166aff38656455d3f50fa2b061df3f61..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/subsf3.zig +++ /dev/null @@ -1,24 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const addf3 = @import("./addf3.zig").addf3; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_fsub, "__aeabi_fsub"); - } else { - symbol(&__subsf3, "__subsf3"); - } -} - -fn __subsf3(a: f32, b: f32) callconv(.c) f32 { - return sub(a, b); -} - -fn __aeabi_fsub(a: f32, b: f32) callconv(.{ .arm_aapcs = .{} }) f32 { - return sub(a, b); -} - -inline fn sub(a: f32, b: f32) f32 { - const neg_b = @as(f32, @bitCast(@as(u32, @bitCast(b)) ^ (@as(u32, 1) << 31))); - return addf3(f32, a, neg_b); -} diff --git a/lib/compiler_rt/subtf3.zig b/lib/compiler_rt/subtf3.zig deleted file mode 100644 index 46580f1728d70b85c83259dce39cb860e46ac10e..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/subtf3.zig +++ /dev/null @@ -1,27 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const addf3 = @import("./addf3.zig").addf3; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__subtf3, "__subkf3"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_sub, "_Qp_sub"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__subtf3, "_Q_sub"); - } - symbol(&__subtf3, "__subtf3"); -} - -pub fn __subtf3(a: f128, b: f128) callconv(.c) f128 { - return sub(a, b); -} - -fn _Qp_sub(c: *f128, a: *const f128, b: *const f128) callconv(.c) void { - c.* = sub(a.*, b.*); -} - -inline fn sub(a: f128, b: f128) f128 { - const neg_b = @as(f128, @bitCast(@as(u128, @bitCast(b)) ^ (@as(u128, 1) << 127))); - return addf3(f128, a, neg_b); -} diff --git a/lib/compiler_rt/subvdi3.zig b/lib/compiler_rt/subvdi3.zig index 62bb1b406835c1a72588cd9c1d08705f6663bbd2..2fedc77ee2c07fe42ded5f5da11191a41fc17a0f 100644 --- a/lib/compiler_rt/subvdi3.zig +++ b/lib/compiler_rt/subvdi3.zig @@ -1,5 +1,6 @@ -const symbol = @import("../compiler_rt.zig").symbol; const testing = @import("std").testing; +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; comptime { symbol(&__subvdi3, "__subvdi3"); @@ -9,7 +10,7 @@ pub fn __subvdi3(a: i64, b: i64) callconv(.c) i64 { const sum = a -% b; // Overflow occurred iff the operands have opposite signs, and the sign of the // sum is the opposite of the lhs sign. - if (((a ^ b) & (sum ^ a)) < 0) @panic("compiler-rt: integer overflow"); + if (((a ^ b) & (sum ^ a)) < 0) @panic("integer overflow"); return sum; } diff --git a/lib/compiler_rt/subvsi3.zig b/lib/compiler_rt/subvsi3.zig index 0744585770237d034f35947a927155efe23eaef9..0d2a47e7cbfa8beb25cbeedc1809e549481db97e 100644 --- a/lib/compiler_rt/subvsi3.zig +++ b/lib/compiler_rt/subvsi3.zig @@ -10,7 +10,7 @@ pub fn __subvsi3(a: i32, b: i32) callconv(.c) i32 { const sum = a -% b; // Overflow occurred iff the operands have opposite signs, and the sign of the // sum is the opposite of the lhs sign. - if (((a ^ b) & (sum ^ a)) < 0) @panic("compiler-rt: integer overflow"); + if (((a ^ b) & (sum ^ a)) < 0) @panic("integer overflow"); return sum; } diff --git a/lib/compiler_rt/subxf3.zig b/lib/compiler_rt/subxf3.zig deleted file mode 100644 index 1c2dcd65429596c975937432aae6eaefb89c2f72..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/subxf3.zig +++ /dev/null @@ -1,13 +0,0 @@ -const std = @import("std"); -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - symbol(&__subxf3, "__subxf3"); -} - -fn __subxf3(a: f80, b: f80) callconv(.c) f80 { - var b_rep = std.math.F80.fromFloat(b); - b_rep.exp ^= 0x8000; - const neg_b = b_rep.toFloat(); - return a + neg_b; -} diff --git a/lib/compiler_rt/tan.zig b/lib/compiler_rt/tan.zig index 6cbc3cb098acd1f6a719451d103574b935a8bb2c..038ac85b6dc2dd9e7d742936bd0df3095dc4b9ec 100644 --- a/lib/compiler_rt/tan.zig +++ b/lib/compiler_rt/tan.zig @@ -21,13 +21,13 @@ const rem_pio2l = @import("rem_pio2l.zig").rem_pio2l; const arch = builtin.cpu.arch; const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; +const symbol = compiler_rt.symbol; comptime { - symbol(&tanh, "__tanh"); + symbol(&__tanh, "__tanh"); symbol(&tanf, "tanf"); symbol(&tan, "tan"); - symbol(&tanx, "__tanx"); + symbol(&__tanx, "__tanx"); if (compiler_rt.want_ppc_abi) { symbol(&tanq, "tanf128"); } @@ -35,12 +35,18 @@ comptime { symbol(&tanl, "tanl"); } -pub fn tanh(x: f16) callconv(.c) f16 { +fn __tanh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(tan_f16(compiler_rt.f16.fromAbi(x))); +} +pub fn tan_f16(x: f16) f16 { // TODO: more efficient implementation - return @floatCast(tanf(x)); + return @floatCast(tan_f32(x)); } -pub fn tanf(x: f32) callconv(.c) f32 { +fn tanf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(tan_f32(compiler_rt.f32.fromAbi(x))); +} +pub fn tan_f32(x: f32) f32 { // Small multiples of pi/2 rounded to double precision. const t1pio2: f64 = 1.0 * math.pi / 2.0; // 0x3FF921FB, 0x54442D18 const t2pio2: f64 = 2.0 * math.pi / 2.0; // 0x400921FB, 0x54442D18 @@ -90,7 +96,10 @@ pub fn tanf(x: f32) callconv(.c) f32 { return kernel.tandf(y, n & 1 != 0); } -pub fn tan(x: f64) callconv(.c) f64 { +fn tan(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(tan_f64(compiler_rt.f64.fromAbi(x))); +} +pub fn tan_f64(x: f64) f64 { var ix = @as(u64, @bitCast(x)) >> 32; ix &= 0x7fffffff; @@ -120,7 +129,10 @@ pub fn tan(x: f64) callconv(.c) f64 { return kernel.tan(y[0], y[1], n & 1 != 0); } -pub fn tanx(x: f80) callconv(.c) f80 { +fn __tanx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(tan_f80(compiler_rt.f80.fromAbi(x))); +} +pub fn tan_f80(x: f80) f80 { const se = ld.signExponent(x) & 0x7fff; if (se == 0x7fff) { return x - x; @@ -141,7 +153,10 @@ pub fn tanx(x: f80) callconv(.c) f80 { return kernel.tanx(y[0], y[1], n & 1); } -pub fn tanq(x: f128) callconv(.c) f128 { +fn tanq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(tan_f128(compiler_rt.f128.fromAbi(x))); +} +pub fn tan_f128(x: f128) f128 { const se = ld.signExponent(x) & 0x7fff; if (se == 0x7fff) { return x - x; @@ -164,18 +179,21 @@ pub fn tanq(x: f128) callconv(.c) f128 { pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return tan(x), - 80 => return tanx(x), - 128 => return tanq(x), - else => @compileError("unreachable"), + 64 => return tan_f64(x), + 80 => return tan_f80(x), + 128 => return tan_f128(x), + else => comptime unreachable, } } fn testTanNormal(comptime T: type) !void { const f = switch (T) { - f32 => tanf, - f64 => tan, - else => @compileError("unimplemented"), + f16 => tan_f16, + f32 => tan_f32, + f64 => tan_f64, + f80 => tan_f80, + f128 => tan_f128, + else => comptime unreachable, }; const epsilon = 0.00001; @@ -189,11 +207,12 @@ fn testTanNormal(comptime T: type) !void { fn testTanSpecial(comptime T: type) !void { const f = switch (T) { - f32 => tanf, - f64 => tan, - f80 => tanx, - f128 => tanq, - else => @compileError("unimplemented"), + f16 => tan_f16, + f32 => tan_f32, + f64 => tan_f64, + f80 => tan_f80, + f128 => tan_f128, + else => comptime unreachable, }; try expect(math.isPositiveZero(f(0.0))); @@ -214,23 +233,23 @@ test "tan64.normal" { test "tan80.normal" { const epsilon = math.floatEps(f80); - try expectApproxEqAbs(@as(f80, 0.0), tanx(0.0), epsilon); - try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tanx(0.2), epsilon); - try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tanx(0.8923), epsilon); - try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tanx(1.5), epsilon); - try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tanx(37.45), epsilon); - try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tanx(89.123), epsilon); + try expectApproxEqAbs(@as(f80, 0.0), tan_f80(0.0), epsilon); + try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tan_f80(0.2), epsilon); + try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tan_f80(0.8923), epsilon); + try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tan_f80(1.5), epsilon); + try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tan_f80(37.45), epsilon); + try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tan_f80(89.123), epsilon); } test "tan128.normal" { const epsilon = math.floatEps(f128); - try expectApproxEqAbs(@as(f128, 0.0), tanq(0.0), epsilon); - try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tanq(0.2), epsilon); - try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tanq(0.8923), epsilon); - try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tanq(1.5), epsilon); - try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tanq(37.45), epsilon); - try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tanq(89.123), epsilon); + try expectApproxEqAbs(@as(f128, 0.0), tan_f128(0.0), epsilon); + try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tan_f128(0.2), epsilon); + try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tan_f128(0.8923), epsilon); + try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tan_f128(1.5), epsilon); + try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tan_f128(37.45), epsilon); + try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tan_f128(89.123), epsilon); } test "tan32.special" { diff --git a/lib/compiler_rt/trunc.zig b/lib/compiler_rt/trunc.zig index aa2eb560dfd8035f14aa07c8e51c5c117daad042..0653178b54b50256e43168d377f59377f34dcc14 100644 --- a/lib/compiler_rt/trunc.zig +++ b/lib/compiler_rt/trunc.zig @@ -24,12 +24,18 @@ comptime { symbol(&truncl, "truncl"); } -pub fn __trunch(x: f16) callconv(.c) f16 { +fn __trunch(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi { + return compiler_rt.f16.toAbi(trunc_f16(compiler_rt.f16.fromAbi(x))); +} +pub fn trunc_f16(x: f16) f16 { // TODO: more efficient implementation - return @floatCast(truncf(x)); + return @floatCast(trunc_f32(x)); } -pub fn truncf(x: f32) callconv(.c) f32 { +fn truncf(x: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(trunc_f32(compiler_rt.f32.fromAbi(x))); +} +pub fn trunc_f32(x: f32) f32 { const u: u32 = @bitCast(x); var e = @as(i32, @intCast(((u >> 23) & 0xFF))) - 0x7F + 9; var m: u32 = undefined; @@ -50,7 +56,10 @@ pub fn truncf(x: f32) callconv(.c) f32 { } } -pub fn trunc(x: f64) callconv(.c) f64 { +fn trunc(x: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(trunc_f64(compiler_rt.f64.fromAbi(x))); +} +pub fn trunc_f64(x: f64) f64 { const u: u64 = @bitCast(x); var e = @as(i32, @intCast(((u >> 52) & 0x7FF))) - 0x3FF + 12; var m: u64 = undefined; @@ -71,12 +80,18 @@ pub fn trunc(x: f64) callconv(.c) f64 { } } -pub fn __truncx(x: f80) callconv(.c) f80 { +fn __truncx(x: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(trunc_f80(compiler_rt.f80.fromAbi(x))); +} +pub fn trunc_f80(x: f80) f80 { // TODO: more efficient implementation - return @floatCast(truncq(x)); + return @floatCast(trunc_f128(x)); } -pub fn truncq(x: f128) callconv(.c) f128 { +fn truncq(x: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f128.Abi { + return compiler_rt.f128.toAbi(trunc_f128(compiler_rt.f128.fromAbi(x))); +} +pub fn trunc_f128(x: f128) f128 { const u: u128 = @bitCast(x); var e = @as(i32, @intCast(((u >> 112) & 0x7FFF))) - 0x3FFF + 16; var m: u128 = undefined; @@ -99,51 +114,69 @@ pub fn truncq(x: f128) callconv(.c) f128 { pub fn truncl(x: c_longdouble) callconv(.c) c_longdouble { switch (@typeInfo(c_longdouble).float.bits) { - 64 => return trunc(x), - 80 => return __truncx(x), - 128 => return truncq(x), - else => @compileError("unreachable"), + 64 => return trunc_f64(x), + 80 => return trunc_f80(x), + 128 => return trunc_f128(x), + else => comptime unreachable, } } -test "trunc32" { - try expect(truncf(1.3) == 1.0); - try expect(truncf(-1.3) == -1.0); - try expect(truncf(0.2) == 0.0); +test trunc_f16 { + try expect(trunc_f16(1.3) == 1.0); + try expect(trunc_f16(-1.3) == -1.0); + try expect(math.isPositiveZero(trunc_f16(0.2))); + try expect(math.isNegativeZero(trunc_f16(-0.2))); + try expect(math.isPositiveZero(trunc_f16(0.0))); + try expect(math.isNegativeZero(trunc_f16(-0.0))); + try expect(math.isPositiveInf(trunc_f16(math.inf(f32)))); + try expect(math.isNegativeInf(trunc_f16(-math.inf(f32)))); + try expect(math.isNan(trunc_f16(math.nan(f32)))); } -test "trunc64" { - try expect(trunc(1.3) == 1.0); - try expect(trunc(-1.3) == -1.0); - try expect(trunc(0.2) == 0.0); +test trunc_f32 { + try expect(trunc_f32(1.3) == 1.0); + try expect(trunc_f32(-1.3) == -1.0); + try expect(math.isPositiveZero(trunc_f32(0.2))); + try expect(math.isNegativeZero(trunc_f32(-0.2))); + try expect(math.isPositiveZero(trunc_f32(0.0))); + try expect(math.isNegativeZero(trunc_f32(-0.0))); + try expect(math.isPositiveInf(trunc_f32(math.inf(f32)))); + try expect(math.isNegativeInf(trunc_f32(-math.inf(f32)))); + try expect(math.isNan(trunc_f32(math.nan(f32)))); } -test "trunc128" { - try expect(truncq(1.3) == 1.0); - try expect(truncq(-1.3) == -1.0); - try expect(truncq(0.2) == 0.0); +test trunc_f64 { + try expect(trunc_f64(1.3) == 1.0); + try expect(trunc_f64(-1.3) == -1.0); + try expect(math.isPositiveZero(trunc_f64(0.2))); + try expect(math.isNegativeZero(trunc_f64(-0.2))); + try expect(math.isPositiveZero(trunc_f64(0.0))); + try expect(math.isNegativeZero(trunc_f64(-0.0))); + try expect(math.isPositiveInf(trunc_f64(math.inf(f64)))); + try expect(math.isNegativeInf(trunc_f64(-math.inf(f64)))); + try expect(math.isNan(trunc_f64(math.nan(f64)))); } -test "trunc32.special" { - try expect(truncf(0.0) == 0.0); // 0x3F800000 - try expect(truncf(-0.0) == -0.0); - try expect(math.isPositiveInf(truncf(math.inf(f32)))); - try expect(math.isNegativeInf(truncf(-math.inf(f32)))); - try expect(math.isNan(truncf(math.nan(f32)))); +test trunc_f80 { + try expect(trunc_f80(1.3) == 1.0); + try expect(trunc_f80(-1.3) == -1.0); + try expect(math.isPositiveZero(trunc_f80(0.2))); + try expect(math.isNegativeZero(trunc_f80(-0.2))); + try expect(math.isPositiveZero(trunc_f80(0.0))); + try expect(math.isNegativeZero(trunc_f80(-0.0))); + try expect(math.isPositiveInf(trunc_f80(math.inf(f64)))); + try expect(math.isNegativeInf(trunc_f80(-math.inf(f64)))); + try expect(math.isNan(trunc_f80(math.nan(f64)))); } -test "trunc64.special" { - try expect(trunc(0.0) == 0.0); - try expect(trunc(-0.0) == -0.0); - try expect(math.isPositiveInf(trunc(math.inf(f64)))); - try expect(math.isNegativeInf(trunc(-math.inf(f64)))); - try expect(math.isNan(trunc(math.nan(f64)))); -} - -test "trunc128.special" { - try expect(truncq(0.0) == 0.0); - try expect(truncq(-0.0) == -0.0); - try expect(math.isPositiveInf(truncq(math.inf(f128)))); - try expect(math.isNegativeInf(truncq(-math.inf(f128)))); - try expect(math.isNan(truncq(math.nan(f128)))); +test trunc_f128 { + try expect(trunc_f128(1.3) == 1.0); + try expect(trunc_f128(-1.3) == -1.0); + try expect(math.isPositiveZero(trunc_f128(0.2))); + try expect(math.isNegativeZero(trunc_f128(-0.2))); + try expect(math.isPositiveZero(trunc_f128(0.0))); + try expect(math.isNegativeZero(trunc_f128(-0.0))); + try expect(math.isPositiveInf(trunc_f128(math.inf(f128)))); + try expect(math.isNegativeInf(trunc_f128(-math.inf(f128)))); + try expect(math.isNan(trunc_f128(math.nan(f128)))); } diff --git a/lib/compiler_rt/truncdfhf2.zig b/lib/compiler_rt/truncdfhf2.zig deleted file mode 100644 index e01e1877633eee7077c64ef42e6cde56a0a17aee..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/truncdfhf2.zig +++ /dev/null @@ -1,18 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const truncf = @import("./truncf.zig").truncf; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_d2h, "__aeabi_d2h"); - } - symbol(&__truncdfhf2, "__truncdfhf2"); -} - -pub fn __truncdfhf2(a: f64) callconv(.c) compiler_rt.F16T(f64) { - return @bitCast(truncf(f16, f64, a)); -} - -fn __aeabi_d2h(a: f64) callconv(.{ .arm_aapcs = .{} }) u16 { - return @bitCast(truncf(f16, f64, a)); -} diff --git a/lib/compiler_rt/truncdfsf2.zig b/lib/compiler_rt/truncdfsf2.zig deleted file mode 100644 index f1bada18449130344f213ad0f8272794d38f23bf..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/truncdfsf2.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const truncf = @import("./truncf.zig").truncf; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_d2f, "__aeabi_d2f"); - } else { - symbol(&__truncdfsf2, "__truncdfsf2"); - } -} - -pub fn __truncdfsf2(a: f64) callconv(.c) f32 { - return truncf(f32, f64, a); -} - -fn __aeabi_d2f(a: f64) callconv(.{ .arm_aapcs = .{} }) f32 { - return truncf(f32, f64, a); -} diff --git a/lib/compiler_rt/truncf.zig b/lib/compiler_rt/truncf.zig index a03f3b67113028ba8a69c4fc72023b9d26f87e23..9a1cb491e27bc214a2c5c7a4a91f8f236efae1ef 100644 --- a/lib/compiler_rt/truncf.zig +++ b/lib/compiler_rt/truncf.zig @@ -1,6 +1,204 @@ const std = @import("std"); -pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t { +const compiler_rt = @import("../compiler_rt.zig"); +const symbol = compiler_rt.symbol; + +comptime { + if (compiler_rt.want_aeabi) { + if (compiler_rt.gnu_f16_abi) { + symbol(&__aeabi_f2h, "__gnu_f2h_ieee"); + } else { + symbol(&__aeabi_f2h, "__aeabi_f2h"); + } + symbol(&__aeabi_d2h, "__aeabi_d2h"); + } else if (compiler_rt.gnu_f16_abi) { + symbol(&__truncsfhf2, "__gnu_f2h_ieee"); + } + symbol(&__truncsfhf2, "__truncsfhf2"); + symbol(&__truncdfhf2, "__truncdfhf2"); + symbol(&__truncxfhf2, "__truncxfhf2"); + if (compiler_rt.want_ppc_abi) { + symbol(&__trunctfhf2, "__trunckfhf2"); + } else { + symbol(&__trunctfhf2, "__trunctfhf2"); + } + + if (compiler_rt.want_aeabi) { + symbol(&__aeabi_d2f, "__aeabi_d2f"); + } else { + symbol(&__truncdfsf2, "__truncdfsf2"); + } + symbol(&__truncxfsf2, "__truncxfsf2"); + if (compiler_rt.want_ppc_abi) { + symbol(&__trunctfsf2, "__trunckfsf2"); + } else if (compiler_rt.want_sparc64_abi) { + symbol(&_Qp_qtos, "_Qp_qtos"); + } else if (compiler_rt.want_sparc32_abi) { + symbol(&__trunctfsf2, "_Q_qtos"); + } else { + symbol(&__trunctfsf2, "__trunctfsf2"); + } + + symbol(&__truncxfdf2, "__truncxfdf2"); + + if (compiler_rt.want_ppc_abi) { + symbol(&__trunctfdf2, "__trunckfdf2"); + } else if (compiler_rt.want_sparc64_abi) { + symbol(&_Qp_qtod, "_Qp_qtod"); + } else if (compiler_rt.want_sparc32_abi) { + symbol(&__trunctfdf2, "_Q_qtod"); + } else { + symbol(&__trunctfdf2, "__trunctfdf2"); + } + + if (compiler_rt.want_ppc_abi) { + symbol(&__trunctfxf2, "__trunckfxf2"); + } else { + symbol(&__trunctfxf2, "__trunctfxf2"); + } +} + +fn __truncsfhf2(a: compiler_rt.f32.Abi) callconv(.c) compiler_rt.f16Conv(f32).Abi { + return compiler_rt.f16Conv(f32).toAbi(f16_floatCast_f32(compiler_rt.f32.fromAbi(a))); +} +fn __aeabi_f2h(a: u32) callconv(.{ .arm_aapcs = .{} }) u16 { + return @bitCast(f16_floatCast_f32(@bitCast(a))); +} +pub fn f16_floatCast_f32(a: f32) f16 { + return truncf(f16, f32, a); +} + +fn __truncdfhf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f16Conv(f64).Abi { + return compiler_rt.f16Conv(f64).toAbi(f16_floatCast_f64(compiler_rt.f64.fromAbi(a))); +} +fn __aeabi_d2h(a: u64) callconv(.{ .arm_aapcs = .{} }) u16 { + return @bitCast(f16_floatCast_f64(@bitCast(a))); +} +pub fn f16_floatCast_f64(a: f64) f16 { + return truncf(f16, f64, a); +} + +fn __truncxfhf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f16Conv(f80).Abi { + return compiler_rt.f16Conv(f80).toAbi(f16_floatCast_f80(compiler_rt.f80.fromAbi(a))); +} +pub fn f16_floatCast_f80(a: f80) f16 { + return trunc_f80(f16, a); +} + +fn __trunctfhf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f16Conv(f128).Abi { + return compiler_rt.f16Conv(f128).toAbi(f16_floatCast_f128(compiler_rt.f128.fromAbi(a))); +} +pub fn f16_floatCast_f128(a: f128) f16 { + return truncf(f16, f128, a); +} + +fn __truncdfsf2(a: compiler_rt.f64.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(f32_floatCast_f64(compiler_rt.f64.fromAbi(a))); +} +fn __aeabi_d2f(a: f64) callconv(.{ .arm_aapcs = .{} }) f32 { + return f32_floatCast_f64(a); +} +pub fn f32_floatCast_f64(a: f64) f32 { + return truncf(f32, f64, a); +} + +fn __truncxfsf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(f32_floatCast_f80(compiler_rt.f80.fromAbi(a))); +} +pub fn f32_floatCast_f80(a: f80) f32 { + return trunc_f80(f32, a); +} + +fn __trunctfsf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f32.Abi { + return compiler_rt.f32.toAbi(f32_floatCast_f128(compiler_rt.f128.fromAbi(a))); +} +fn _Qp_qtos(a: *const f128) callconv(.c) f32 { + return f32_floatCast_f128(a.*); +} +pub fn f32_floatCast_f128(a: f128) f32 { + return truncf(f32, f128, a); +} + +fn __truncxfdf2(a: compiler_rt.f80.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(f64_floatCast_f80(compiler_rt.f80.fromAbi(a))); +} +pub fn f64_floatCast_f80(a: f80) f64 { + return trunc_f80(f64, a); +} + +fn __trunctfdf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f64.Abi { + return compiler_rt.f64.toAbi(f64_floatCast_f128(compiler_rt.f128.fromAbi(a))); +} +fn _Qp_qtod(a: *const f128) callconv(.c) f64 { + return f64_floatCast_f128(a.*); +} +pub fn f64_floatCast_f128(a: f128) f64 { + return truncf(f64, f128, a); +} + +fn __trunctfxf2(a: compiler_rt.f128.Abi) callconv(.c) compiler_rt.f80.Abi { + return compiler_rt.f80.toAbi(f80_floatCast_f128(compiler_rt.f128.fromAbi(a))); +} +pub fn f80_floatCast_f128(a: f128) f80 { + const src_sig_bits = std.math.floatMantissaBits(f128); + const dst_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit + + // Various constants whose values follow from the type parameters. + // Any reasonable optimizer will fold and propagate all of these. + const src_bits = @typeInfo(f128).float.bits; + const src_exp_bits = src_bits - src_sig_bits - 1; + const src_inf_exp = 0x7FFF; + + const src_inf = src_inf_exp << src_sig_bits; + const src_sign_mask = 1 << (src_sig_bits + src_exp_bits); + const src_abs_mask = src_sign_mask - 1; + const round_mask = (1 << (src_sig_bits - dst_sig_bits)) - 1; + const halfway = 1 << (src_sig_bits - dst_sig_bits - 1); + + // Break a into a sign and representation of the absolute value + const a_rep: u128 = @bitCast(a); + const a_abs = a_rep & src_abs_mask; + const sign: u16 = if (a_rep & src_sign_mask != 0) 0x8000 else 0; + const integer_bit = 1 << 63; + + var res: std.math.F80 = undefined; + + if (a_abs > src_inf) { + // a is NaN. + // Conjure the result by beginning with infinity, setting the qNaN + // bit and inserting the (truncated) trailing NaN field. + res.exp = 0x7fff; + res.fraction = 0x8000000000000000; + res.fraction |= @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))); + } else { + // The exponent of a is within the range of normal numbers in the + // destination format. We can convert by simply right-shifting with + // rounding, adding the explicit integer bit, and adjusting the exponent + res.fraction = @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))) | integer_bit; + res.exp = @truncate(a_abs >> src_sig_bits); + + const round_bits = a_abs & round_mask; + if (round_bits > halfway) { + // Round to nearest + const ov = @addWithOverflow(res.fraction, 1); + res.fraction = ov[0]; + res.exp += ov[1]; + res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry + } else if (round_bits == halfway) { + // Ties to even + const ov = @addWithOverflow(res.fraction, res.fraction & 1); + res.fraction = ov[0]; + res.exp += ov[1]; + res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry + } + if (res.exp == 0) res.fraction &= ~@as(u64, integer_bit); // Remove integer bit for de-normals + } + + res.exp |= sign; + return res.toFloat(); +} + +inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t { const src_rep_t = @Int(.unsigned, @typeInfo(src_t).float.bits); const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits); const srcSigBits = std.math.floatMantissaBits(src_t); @@ -99,7 +297,7 @@ pub inline fn truncf(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t return @bitCast(result); } -pub inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t { +inline fn trunc_f80(comptime dst_t: type, a: f80) dst_t { const dst_rep_t = @Int(.unsigned, @typeInfo(dst_t).float.bits); const src_sig_bits = std.math.floatMantissaBits(f80) - 1; // -1 for the integer bit const dst_sig_bits = std.math.floatMantissaBits(dst_t); diff --git a/lib/compiler_rt/truncf_test.zig b/lib/compiler_rt/truncf_test.zig index 8da6fe0a19456e9898f32ea4dec4c7b8ccb221b4..6595c47b52d8f868d019c1728ae3d57735e12323 100644 --- a/lib/compiler_rt/truncf_test.zig +++ b/lib/compiler_rt/truncf_test.zig @@ -1,79 +1,82 @@ const std = @import("std"); const testing = std.testing; -const __truncsfhf2 = @import("truncsfhf2.zig").__truncsfhf2; -const __truncdfhf2 = @import("truncdfhf2.zig").__truncdfhf2; -const __truncdfsf2 = @import("truncdfsf2.zig").__truncdfsf2; -const __trunctfhf2 = @import("trunctfhf2.zig").__trunctfhf2; -const __trunctfsf2 = @import("trunctfsf2.zig").__trunctfsf2; -const __trunctfdf2 = @import("trunctfdf2.zig").__trunctfdf2; -const __trunctfxf2 = @import("trunctfxf2.zig").__trunctfxf2; - -fn test__truncsfhf2(a: u32, expected: u16) !void { - const actual: u16 = @bitCast(__truncsfhf2(@bitCast(a))); - - if (actual == expected) { - return; - } - - return error.TestFailure; +const impl = @import("truncf.zig"); + +const f16_floatCast_f32 = impl.f16_floatCast_f32; +const f16_floatCast_f64 = impl.f16_floatCast_f64; +const f16_floatCast_f80 = impl.f16_floatCast_f80; +const f16_floatCast_f128 = impl.f16_floatCast_f128; + +const f32_floatCast_f64 = impl.f32_floatCast_f64; +const f32_floatCast_f80 = impl.f32_floatCast_f80; +const f32_floatCast_f128 = impl.f32_floatCast_f128; + +const f64_floatCast_f80 = impl.f64_floatCast_f80; +const f64_floatCast_f128 = impl.f64_floatCast_f128; + +const f80_floatCast_f128 = impl.f80_floatCast_f128; + +fn test_f16_floatCast_f32(a: u32, expected: u16) !void { + const actual: u16 = @bitCast(f16_floatCast_f32(@bitCast(a))); + try testing.expect(actual == expected); } -test "truncsfhf2" { - try test__truncsfhf2(0x7fc00000, 0x7e00); // qNaN - try test__truncsfhf2(0x7fe00000, 0x7f00); // sNaN +test f16_floatCast_f32 { + try test_f16_floatCast_f32(0x7fc00000, 0x7e00); // qNaN + try test_f16_floatCast_f32(0x7fe00000, 0x7f00); // sNaN - try test__truncsfhf2(0, 0); // 0 - try test__truncsfhf2(0x80000000, 0x8000); // -0 + try test_f16_floatCast_f32(0, 0); // 0 + try test_f16_floatCast_f32(0x80000000, 0x8000); // -0 - try test__truncsfhf2(0x7f800000, 0x7c00); // inf - try test__truncsfhf2(0xff800000, 0xfc00); // -inf + try test_f16_floatCast_f32(0x7f800000, 0x7c00); // inf + try test_f16_floatCast_f32(0xff800000, 0xfc00); // -inf - try test__truncsfhf2(0x477ff000, 0x7c00); // 65520 -> inf - try test__truncsfhf2(0xc77ff000, 0xfc00); // -65520 -> -inf + try test_f16_floatCast_f32(0x477ff000, 0x7c00); // 65520 -> inf + try test_f16_floatCast_f32(0xc77ff000, 0xfc00); // -65520 -> -inf - try test__truncsfhf2(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf - try test__truncsfhf2(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf + try test_f16_floatCast_f32(0x71cc3892, 0x7c00); // 0x1.987124876876324p+100 -> inf + try test_f16_floatCast_f32(0xf1cc3892, 0xfc00); // -0x1.987124876876324p+100 -> -inf - try test__truncsfhf2(0x38800000, 0x0400); // normal (min), 2**-14 - try test__truncsfhf2(0xb8800000, 0x8400); // normal (min), -2**-14 + try test_f16_floatCast_f32(0x38800000, 0x0400); // normal (min), 2**-14 + try test_f16_floatCast_f32(0xb8800000, 0x8400); // normal (min), -2**-14 - try test__truncsfhf2(0x477fe000, 0x7bff); // normal (max), 65504 - try test__truncsfhf2(0xc77fe000, 0xfbff); // normal (max), -65504 + try test_f16_floatCast_f32(0x477fe000, 0x7bff); // normal (max), 65504 + try test_f16_floatCast_f32(0xc77fe000, 0xfbff); // normal (max), -65504 - try test__truncsfhf2(0x477fe100, 0x7bff); // normal, 65505 -> 65504 - try test__truncsfhf2(0xc77fe100, 0xfbff); // normal, -65505 -> -65504 + try test_f16_floatCast_f32(0x477fe100, 0x7bff); // normal, 65505 -> 65504 + try test_f16_floatCast_f32(0xc77fe100, 0xfbff); // normal, -65505 -> -65504 - try test__truncsfhf2(0x477fef00, 0x7bff); // normal, 65519 -> 65504 - try test__truncsfhf2(0xc77fef00, 0xfbff); // normal, -65519 -> -65504 + try test_f16_floatCast_f32(0x477fef00, 0x7bff); // normal, 65519 -> 65504 + try test_f16_floatCast_f32(0xc77fef00, 0xfbff); // normal, -65519 -> -65504 - try test__truncsfhf2(0x3f802000, 0x3c01); // normal, 1 + 2**-10 - try test__truncsfhf2(0xbf802000, 0xbc01); // normal, -1 - 2**-10 + try test_f16_floatCast_f32(0x3f802000, 0x3c01); // normal, 1 + 2**-10 + try test_f16_floatCast_f32(0xbf802000, 0xbc01); // normal, -1 - 2**-10 - try test__truncsfhf2(0x3eaaa000, 0x3555); // normal, approx. 1/3 - try test__truncsfhf2(0xbeaaa000, 0xb555); // normal, approx. -1/3 + try test_f16_floatCast_f32(0x3eaaa000, 0x3555); // normal, approx. 1/3 + try test_f16_floatCast_f32(0xbeaaa000, 0xb555); // normal, approx. -1/3 - try test__truncsfhf2(0x40490fdb, 0x4248); // normal, 3.1415926535 - try test__truncsfhf2(0xc0490fdb, 0xc248); // normal, -3.1415926535 + try test_f16_floatCast_f32(0x40490fdb, 0x4248); // normal, 3.1415926535 + try test_f16_floatCast_f32(0xc0490fdb, 0xc248); // normal, -3.1415926535 - try test__truncsfhf2(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+12 + try test_f16_floatCast_f32(0x45cc3892, 0x6e62); // normal, 0x1.987124876876324p+12 - try test__truncsfhf2(0x3f800000, 0x3c00); // normal, 1 - try test__truncsfhf2(0x38800000, 0x0400); // normal, 0x1.0p-14 + try test_f16_floatCast_f32(0x3f800000, 0x3c00); // normal, 1 + try test_f16_floatCast_f32(0x38800000, 0x0400); // normal, 0x1.0p-14 - try test__truncsfhf2(0x33800000, 0x0001); // denormal (min), 2**-24 - try test__truncsfhf2(0xb3800000, 0x8001); // denormal (min), -2**-24 + try test_f16_floatCast_f32(0x33800000, 0x0001); // denormal (min), 2**-24 + try test_f16_floatCast_f32(0xb3800000, 0x8001); // denormal (min), -2**-24 - try test__truncsfhf2(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-24 - try test__truncsfhf2(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-24 + try test_f16_floatCast_f32(0x387fc000, 0x03ff); // denormal (max), 2**-14 - 2**-24 + try test_f16_floatCast_f32(0xb87fc000, 0x83ff); // denormal (max), -2**-14 + 2**-24 - try test__truncsfhf2(0x35800000, 0x0010); // denormal, 0x1.0p-20 - try test__truncsfhf2(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-24 - try test__truncsfhf2(0x33000000, 0x0000); // 0x1.0p-25 -> zero + try test_f16_floatCast_f32(0x35800000, 0x0010); // denormal, 0x1.0p-20 + try test_f16_floatCast_f32(0x33280000, 0x0001); // denormal, 0x1.5p-25 -> 0x1.0p-24 + try test_f16_floatCast_f32(0x33000000, 0x0000); // 0x1.0p-25 -> zero } -fn test__truncdfhf2(a: f64, expected: u16) void { - const rep: u16 = @bitCast(__truncdfhf2(a)); +fn test_f16_floatCast_f64(a: f64, expected: u16) !void { + const rep: u16 = @bitCast(f16_floatCast_f64(a)); if (rep == expected) { return; @@ -84,62 +87,56 @@ fn test__truncdfhf2(a: f64, expected: u16) void { return; } } - - @panic("__truncdfhf2 test failure"); + return error.TestFailure; } -fn test__truncdfhf2_raw(a: u64, expected: u16) void { - const actual: u16 = @bitCast(__truncdfhf2(@bitCast(a))); - - if (actual == expected) { - return; - } - - @panic("__truncdfhf2 test failure"); +fn test_f16_floatCast_f64_raw(a: u64, expected: u16) !void { + const actual: u16 = @bitCast(f16_floatCast_f64(@bitCast(a))); + try testing.expect(actual == expected); } -test "truncdfhf2" { - test__truncdfhf2_raw(0x7ff8000000000000, 0x7e00); // qNaN - test__truncdfhf2_raw(0x7ff0000000008000, 0x7e00); // NaN +test f16_floatCast_f64 { + try test_f16_floatCast_f64_raw(0x7ff8000000000000, 0x7e00); // qNaN + try test_f16_floatCast_f64_raw(0x7ff0000000008000, 0x7e00); // NaN - test__truncdfhf2_raw(0x7ff0000000000000, 0x7c00); //inf - test__truncdfhf2_raw(0xfff0000000000000, 0xfc00); // -inf + try test_f16_floatCast_f64_raw(0x7ff0000000000000, 0x7c00); //inf + try test_f16_floatCast_f64_raw(0xfff0000000000000, 0xfc00); // -inf - test__truncdfhf2(0.0, 0x0); // zero - test__truncdfhf2_raw(0x80000000 << 32, 0x8000); // -zero + try test_f16_floatCast_f64(0.0, 0x0); // zero + try test_f16_floatCast_f64_raw(0x80000000 << 32, 0x8000); // -zero - test__truncdfhf2(3.1415926535, 0x4248); - test__truncdfhf2(-3.1415926535, 0xc248); + try test_f16_floatCast_f64(3.1415926535, 0x4248); + try test_f16_floatCast_f64(-3.1415926535, 0xc248); - test__truncdfhf2(0x1.987124876876324p+1000, 0x7c00); - test__truncdfhf2(0x1.987124876876324p+12, 0x6e62); - test__truncdfhf2(0x1.0p+0, 0x3c00); - test__truncdfhf2(0x1.0p-14, 0x0400); + try test_f16_floatCast_f64(0x1.987124876876324p+1000, 0x7c00); + try test_f16_floatCast_f64(0x1.987124876876324p+12, 0x6e62); + try test_f16_floatCast_f64(0x1.0p+0, 0x3c00); + try test_f16_floatCast_f64(0x1.0p-14, 0x0400); // denormal - test__truncdfhf2(0x1.0p-20, 0x0010); - test__truncdfhf2(0x1.0p-24, 0x0001); - test__truncdfhf2(-0x1.0p-24, 0x8001); - test__truncdfhf2(0x1.5p-25, 0x0001); + try test_f16_floatCast_f64(0x1.0p-20, 0x0010); + try test_f16_floatCast_f64(0x1.0p-24, 0x0001); + try test_f16_floatCast_f64(-0x1.0p-24, 0x8001); + try test_f16_floatCast_f64(0x1.5p-25, 0x0001); // and back to zero - test__truncdfhf2(0x1.0p-25, 0x0000); - test__truncdfhf2(-0x1.0p-25, 0x8000); + try test_f16_floatCast_f64(0x1.0p-25, 0x0000); + try test_f16_floatCast_f64(-0x1.0p-25, 0x8000); // max (precise) - test__truncdfhf2(65504.0, 0x7bff); + try test_f16_floatCast_f64(65504.0, 0x7bff); // max (rounded) - test__truncdfhf2(65519.0, 0x7bff); + try test_f16_floatCast_f64(65519.0, 0x7bff); // max (to +inf) - test__truncdfhf2(65520.0, 0x7c00); - test__truncdfhf2(-65520.0, 0xfc00); - test__truncdfhf2(65536.0, 0x7c00); + try test_f16_floatCast_f64(65520.0, 0x7c00); + try test_f16_floatCast_f64(-65520.0, 0xfc00); + try test_f16_floatCast_f64(65536.0, 0x7c00); } -fn test__trunctfsf2(a: f128, expected: u32) void { - const x = __trunctfsf2(a); +fn test_f32_floatCast_f128(a: f128, expected: u32) !void { + const x = f32_floatCast_f128(a); const rep: u32 = @bitCast(x); if (rep == expected) { @@ -151,28 +148,27 @@ fn test__trunctfsf2(a: f128, expected: u32) void { return; } } - - @panic("__trunctfsf2 test failure"); + return error.TestFailure; } -test "trunctfsf2" { +test f32_floatCast_f128 { // qnan - test__trunctfsf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000); + try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7fc00000); // nan - test__trunctfsf2(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7fc08000); + try test_f32_floatCast_f128(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7fc08000); // inf - test__trunctfsf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000); + try test_f32_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7f800000); // zero - test__trunctfsf2(0.0, 0x0); + try test_f32_floatCast_f128(0.0, 0x0); - test__trunctfsf2(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x4211d156); - test__trunctfsf2(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x3b71e9e2); - test__trunctfsf2(0x1.234eebb5faa678f4488693abcdefp+4534, 0x7f800000); - test__trunctfsf2(0x1.edcba9bb8c76a5a43dd21f334634p-435, 0x0); + try test_f32_floatCast_f128(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x4211d156); + try test_f32_floatCast_f128(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x3b71e9e2); + try test_f32_floatCast_f128(0x1.234eebb5faa678f4488693abcdefp+4534, 0x7f800000); + try test_f32_floatCast_f128(0x1.edcba9bb8c76a5a43dd21f334634p-435, 0x0); } -fn test__trunctfdf2(a: f128, expected: u64) void { - const x = __trunctfdf2(a); +fn test_f64_floatCast_f128(a: f128, expected: u64) !void { + const x = f64_floatCast_f128(a); const rep: u64 = @bitCast(x); if (rep == expected) { @@ -184,28 +180,27 @@ fn test__trunctfdf2(a: f128, expected: u64) void { return; } } - - @panic("__trunctfsf2 test failure"); + return error.TestFailure; } -test "trunctfdf2" { +test f64_floatCast_f128 { // qnan - test__trunctfdf2(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000); + try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000); // nan - test__trunctfdf2(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7ff8100000000000); + try test_f64_floatCast_f128(@bitCast(@as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7ff8100000000000); // inf - test__trunctfdf2(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000); + try test_f64_floatCast_f128(@bitCast(@as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000); // zero - test__trunctfdf2(0.0, 0x0); + try test_f64_floatCast_f128(0.0, 0x0); - test__trunctfdf2(0x1.af23456789bbaaab347645365cdep+5, 0x404af23456789bbb); - test__trunctfdf2(0x1.dedafcff354b6ae9758763545432p-9, 0x3f6dedafcff354b7); - test__trunctfdf2(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000); - test__trunctfdf2(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab); + try test_f64_floatCast_f128(0x1.af23456789bbaaab347645365cdep+5, 0x404af23456789bbb); + try test_f64_floatCast_f128(0x1.dedafcff354b6ae9758763545432p-9, 0x3f6dedafcff354b7); + try test_f64_floatCast_f128(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000); + try test_f64_floatCast_f128(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab); } -fn test__truncdfsf2(a: f64, expected: u32) void { - const x = __truncdfsf2(a); +fn test_f32_floatCast_f64(a: f64, expected: u32) !void { + const x = f32_floatCast_f64(a); const rep: u32 = @bitCast(x); if (rep == expected) { @@ -217,90 +212,81 @@ fn test__truncdfsf2(a: f64, expected: u32) void { return; } } - - std.debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected }); - - @panic("__trunctfsf2 test failure"); + return error.TestFailure; } -test "truncdfsf2" { +test f32_floatCast_f64 { // nan & qnan - test__truncdfsf2(@bitCast(@as(u64, 0x7ff8000000000000)), 0x7fc00000); - test__truncdfsf2(@bitCast(@as(u64, 0x7ff0000000000001)), 0x7fc00000); + try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff8000000000000)), 0x7fc00000); + try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff0000000000001)), 0x7fc00000); // inf - test__truncdfsf2(@bitCast(@as(u64, 0x7ff0000000000000)), 0x7f800000); - test__truncdfsf2(@bitCast(@as(u64, 0xfff0000000000000)), 0xff800000); + try test_f32_floatCast_f64(@bitCast(@as(u64, 0x7ff0000000000000)), 0x7f800000); + try test_f32_floatCast_f64(@bitCast(@as(u64, 0xfff0000000000000)), 0xff800000); - test__truncdfsf2(0.0, 0x0); - test__truncdfsf2(1.0, 0x3f800000); - test__truncdfsf2(-1.0, 0xbf800000); + try test_f32_floatCast_f64(0.0, 0x0); + try test_f32_floatCast_f64(1.0, 0x3f800000); + try test_f32_floatCast_f64(-1.0, 0xbf800000); // huge number becomes inf - test__truncdfsf2(340282366920938463463374607431768211456.0, 0x7f800000); + try test_f32_floatCast_f64(340282366920938463463374607431768211456.0, 0x7f800000); } -fn test__trunctfhf2(a: f128, expected: u16) void { - const x = __trunctfhf2(a); +fn test_f16_floatCast_f128(a: f128, expected: u16) !void { + const x = f16_floatCast_f128(a); const rep: u16 = @bitCast(x); - if (rep == expected) { - return; - } - - std.debug.print("got 0x{x} wanted 0x{x}\n", .{ rep, expected }); - - @panic("__trunctfhf2 test failure"); + try testing.expect(rep == expected); } -test "trunctfhf2" { +test f16_floatCast_f128 { // qNaN - test__trunctfhf2(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00); + try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff8000000000000000000000000000)), 0x7e00); // NaN - test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00); + try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000001)), 0x7e00); // inf - test__trunctfhf2(@bitCast(@as(u128, 0x7fff0000000000000000000000000000)), 0x7c00); - test__trunctfhf2(-@as(f128, @bitCast(@as(u128, 0x7fff0000000000000000000000000000))), 0xfc00); + try test_f16_floatCast_f128(@bitCast(@as(u128, 0x7fff0000000000000000000000000000)), 0x7c00); + try test_f16_floatCast_f128(-@as(f128, @bitCast(@as(u128, 0x7fff0000000000000000000000000000))), 0xfc00); // zero - test__trunctfhf2(0.0, 0x0); - test__trunctfhf2(-0.0, 0x8000); + try test_f16_floatCast_f128(0.0, 0x0); + try test_f16_floatCast_f128(-0.0, 0x8000); - test__trunctfhf2(3.1415926535, 0x4248); - test__trunctfhf2(-3.1415926535, 0xc248); - test__trunctfhf2(0x1.987124876876324p+100, 0x7c00); - test__trunctfhf2(0x1.987124876876324p+12, 0x6e62); - test__trunctfhf2(0x1.0p+0, 0x3c00); - test__trunctfhf2(0x1.0p-14, 0x0400); + try test_f16_floatCast_f128(3.1415926535, 0x4248); + try test_f16_floatCast_f128(-3.1415926535, 0xc248); + try test_f16_floatCast_f128(0x1.987124876876324p+100, 0x7c00); + try test_f16_floatCast_f128(0x1.987124876876324p+12, 0x6e62); + try test_f16_floatCast_f128(0x1.0p+0, 0x3c00); + try test_f16_floatCast_f128(0x1.0p-14, 0x0400); // denormal - test__trunctfhf2(0x1.0p-20, 0x0010); - test__trunctfhf2(0x1.0p-24, 0x0001); - test__trunctfhf2(-0x1.0p-24, 0x8001); - test__trunctfhf2(0x1.5p-25, 0x0001); + try test_f16_floatCast_f128(0x1.0p-20, 0x0010); + try test_f16_floatCast_f128(0x1.0p-24, 0x0001); + try test_f16_floatCast_f128(-0x1.0p-24, 0x8001); + try test_f16_floatCast_f128(0x1.5p-25, 0x0001); // and back to zero - test__trunctfhf2(0x1.0p-25, 0x0000); - test__trunctfhf2(-0x1.0p-25, 0x8000); + try test_f16_floatCast_f128(0x1.0p-25, 0x0000); + try test_f16_floatCast_f128(-0x1.0p-25, 0x8000); // max (precise) - test__trunctfhf2(65504.0, 0x7bff); + try test_f16_floatCast_f128(65504.0, 0x7bff); // max (rounded) - test__trunctfhf2(65519.0, 0x7bff); + try test_f16_floatCast_f128(65519.0, 0x7bff); // max (to +inf) - test__trunctfhf2(65520.0, 0x7c00); - test__trunctfhf2(65536.0, 0x7c00); - test__trunctfhf2(-65520.0, 0xfc00); + try test_f16_floatCast_f128(65520.0, 0x7c00); + try test_f16_floatCast_f128(65536.0, 0x7c00); + try test_f16_floatCast_f128(-65520.0, 0xfc00); - test__trunctfhf2(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x508f); - test__trunctfhf2(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x1b8f); - test__trunctfhf2(0x1.234eebb5faa678f4488693abcdefp+453, 0x7c00); - test__trunctfhf2(0x1.edcba9bb8c76a5a43dd21f334634p-43, 0x0); + try test_f16_floatCast_f128(0x1.23a2abb4a2ddee355f36789abcdep+5, 0x508f); + try test_f16_floatCast_f128(0x1.e3d3c45bd3abfd98b76a54cc321fp-9, 0x1b8f); + try test_f16_floatCast_f128(0x1.234eebb5faa678f4488693abcdefp+453, 0x7c00); + try test_f16_floatCast_f128(0x1.edcba9bb8c76a5a43dd21f334634p-43, 0x0); } -test "trunctfxf2" { - try test__trunctfxf2(1.5, 1.5); - try test__trunctfxf2(2.5, 2.5); - try test__trunctfxf2(-2.5, -2.5); - try test__trunctfxf2(0.0, 0.0); -} - -fn test__trunctfxf2(a: f128, expected: f80) !void { - const x = __trunctfxf2(a); +fn test_f80_floatCast_f128(a: f128, expected: f80) !void { + const x = f80_floatCast_f128(a); try testing.expect(x == expected); } + +test f80_floatCast_f128 { + try test_f80_floatCast_f128(1.5, 1.5); + try test_f80_floatCast_f128(2.5, 2.5); + try test_f80_floatCast_f128(-2.5, -2.5); + try test_f80_floatCast_f128(0.0, 0.0); +} diff --git a/lib/compiler_rt/truncsfhf2.zig b/lib/compiler_rt/truncsfhf2.zig deleted file mode 100644 index e0b2b1e4bf2f15400c568f1c1656c8cb70bc03c8..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/truncsfhf2.zig +++ /dev/null @@ -1,24 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const truncf = @import("./truncf.zig").truncf; - -comptime { - if (compiler_rt.gnu_f16_abi) { - symbol(&__gnu_f2h_ieee, "__gnu_f2h_ieee"); - } else if (compiler_rt.want_aeabi) { - symbol(&__aeabi_f2h, "__aeabi_f2h"); - } - symbol(&__truncsfhf2, "__truncsfhf2"); -} - -pub fn __truncsfhf2(a: f32) callconv(.c) compiler_rt.F16T(f32) { - return @bitCast(truncf(f16, f32, a)); -} - -fn __gnu_f2h_ieee(a: f32) callconv(.c) compiler_rt.F16T(f32) { - return @bitCast(truncf(f16, f32, a)); -} - -fn __aeabi_f2h(a: f32) callconv(.{ .arm_aapcs = .{} }) u16 { - return @bitCast(truncf(f16, f32, a)); -} diff --git a/lib/compiler_rt/trunctfdf2.zig b/lib/compiler_rt/trunctfdf2.zig deleted file mode 100644 index ba909de73bf144b2f023e4f6366dac5a4ad0ea40..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/trunctfdf2.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const truncf = @import("./truncf.zig").truncf; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__trunctfdf2, "__trunckfdf2"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_qtod, "_Qp_qtod"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__trunctfdf2, "_Q_qtod"); - } - symbol(&__trunctfdf2, "__trunctfdf2"); -} - -pub fn __trunctfdf2(a: f128) callconv(.c) f64 { - return truncf(f64, f128, a); -} - -fn _Qp_qtod(a: *const f128) callconv(.c) f64 { - return truncf(f64, f128, a.*); -} diff --git a/lib/compiler_rt/trunctfhf2.zig b/lib/compiler_rt/trunctfhf2.zig deleted file mode 100644 index 5af87f9c127180b49a15b8f3906252d7da162d26..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/trunctfhf2.zig +++ /dev/null @@ -1,14 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; -const truncf = @import("./truncf.zig").truncf; - -comptime { - symbol(&__trunctfhf2, "__trunctfhf2"); - if (compiler_rt.want_ppc_abi) { - symbol(&__trunctfhf2, "__trunckfhf2"); - } -} - -pub fn __trunctfhf2(a: f128) callconv(.c) compiler_rt.F16T(f128) { - return @bitCast(truncf(f16, f128, a)); -} diff --git a/lib/compiler_rt/trunctfsf2.zig b/lib/compiler_rt/trunctfsf2.zig deleted file mode 100644 index 8af51ca82f95b1dd36c7f27df20e6756b8e15396..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/trunctfsf2.zig +++ /dev/null @@ -1,22 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const truncf = @import("./truncf.zig").truncf; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_ppc_abi) { - symbol(&__trunctfsf2, "__trunckfsf2"); - } else if (compiler_rt.want_sparc64_abi) { - symbol(&_Qp_qtos, "_Qp_qtos"); - } else if (compiler_rt.want_sparc32_abi) { - symbol(&__trunctfsf2, "_Q_qtos"); - } - symbol(&__trunctfsf2, "__trunctfsf2"); -} - -pub fn __trunctfsf2(a: f128) callconv(.c) f32 { - return truncf(f32, f128, a); -} - -fn _Qp_qtos(a: *const f128) callconv(.c) f32 { - return truncf(f32, f128, a.*); -} diff --git a/lib/compiler_rt/trunctfxf2.zig b/lib/compiler_rt/trunctfxf2.zig deleted file mode 100644 index dfb9ef80402cda0360a111e436ba1f7c460bbc1f..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/trunctfxf2.zig +++ /dev/null @@ -1,67 +0,0 @@ -const math = @import("std").math; -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = compiler_rt.symbol; -const trunc_f80 = @import("./truncf.zig").trunc_f80; - -comptime { - symbol(&__trunctfxf2, "__trunctfxf2"); -} - -pub fn __trunctfxf2(a: f128) callconv(.c) f80 { - const src_sig_bits = math.floatMantissaBits(f128); - const dst_sig_bits = math.floatMantissaBits(f80) - 1; // -1 for the integer bit - - // Various constants whose values follow from the type parameters. - // Any reasonable optimizer will fold and propagate all of these. - const src_bits = @typeInfo(f128).float.bits; - const src_exp_bits = src_bits - src_sig_bits - 1; - const src_inf_exp = 0x7FFF; - - const src_inf = src_inf_exp << src_sig_bits; - const src_sign_mask = 1 << (src_sig_bits + src_exp_bits); - const src_abs_mask = src_sign_mask - 1; - const round_mask = (1 << (src_sig_bits - dst_sig_bits)) - 1; - const halfway = 1 << (src_sig_bits - dst_sig_bits - 1); - - // Break a into a sign and representation of the absolute value - const a_rep = @as(u128, @bitCast(a)); - const a_abs = a_rep & src_abs_mask; - const sign: u16 = if (a_rep & src_sign_mask != 0) 0x8000 else 0; - const integer_bit = 1 << 63; - - var res: math.F80 = undefined; - - if (a_abs > src_inf) { - // a is NaN. - // Conjure the result by beginning with infinity, setting the qNaN - // bit and inserting the (truncated) trailing NaN field. - res.exp = 0x7fff; - res.fraction = 0x8000000000000000; - res.fraction |= @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))); - } else { - // The exponent of a is within the range of normal numbers in the - // destination format. We can convert by simply right-shifting with - // rounding, adding the explicit integer bit, and adjusting the exponent - res.fraction = @as(u64, @truncate(a_abs >> (src_sig_bits - dst_sig_bits))) | integer_bit; - res.exp = @truncate(a_abs >> src_sig_bits); - - const round_bits = a_abs & round_mask; - if (round_bits > halfway) { - // Round to nearest - const ov = @addWithOverflow(res.fraction, 1); - res.fraction = ov[0]; - res.exp += ov[1]; - res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry - } else if (round_bits == halfway) { - // Ties to even - const ov = @addWithOverflow(res.fraction, res.fraction & 1); - res.fraction = ov[0]; - res.exp += ov[1]; - res.fraction |= @as(u64, ov[1]) << 63; // Restore integer bit after carry - } - if (res.exp == 0) res.fraction &= ~@as(u64, integer_bit); // Remove integer bit for de-normals - } - - res.exp |= sign; - return res.toFloat(); -} diff --git a/lib/compiler_rt/truncxfdf2.zig b/lib/compiler_rt/truncxfdf2.zig deleted file mode 100644 index 6140d94181fbe10a5e83e880dff805e87b34fae8..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/truncxfdf2.zig +++ /dev/null @@ -1,10 +0,0 @@ -const symbol = @import("../compiler_rt.zig").symbol; -const trunc_f80 = @import("./truncf.zig").trunc_f80; - -comptime { - symbol(&__truncxfdf2, "__truncxfdf2"); -} - -fn __truncxfdf2(a: f80) callconv(.c) f64 { - return trunc_f80(f64, a); -} diff --git a/lib/compiler_rt/truncxfhf2.zig b/lib/compiler_rt/truncxfhf2.zig deleted file mode 100644 index 4c3e951bfe9b67ff88818e6a89f210851ddfcfb0..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/truncxfhf2.zig +++ /dev/null @@ -1,11 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; -const trunc_f80 = @import("./truncf.zig").trunc_f80; - -comptime { - symbol(&__truncxfhf2, "__truncxfhf2"); -} - -fn __truncxfhf2(a: f80) callconv(.c) compiler_rt.F16T(f80) { - return @bitCast(trunc_f80(f16, a)); -} diff --git a/lib/compiler_rt/truncxfsf2.zig b/lib/compiler_rt/truncxfsf2.zig deleted file mode 100644 index 8aaf7e6906a9da938835d2c36e931bfb21d07037..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/truncxfsf2.zig +++ /dev/null @@ -1,10 +0,0 @@ -const trunc_f80 = @import("./truncf.zig").trunc_f80; -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - symbol(&__truncxfsf2, "__truncxfsf2"); -} - -fn __truncxfsf2(a: f80) callconv(.c) f32 { - return trunc_f80(f32, a); -} diff --git a/lib/compiler_rt/udivmodei4.zig b/lib/compiler_rt/udivmodei4.zig index 41ba32cdbef1532de8b77e0f91db4bbf4b39f29a..e7c4f52cd1f0360307c5e0ab2232c8925b0b1792 100644 --- a/lib/compiler_rt/udivmodei4.zig +++ b/lib/compiler_rt/udivmodei4.zig @@ -6,7 +6,7 @@ const shr = std.math.shr; const shl = std.math.shl; const compiler_rt = @import("../compiler_rt.zig"); -const symbol = @import("../compiler_rt.zig").symbol; +const symbol = compiler_rt.symbol; const max_limbs = @divCeil(65535, 32); // max supported type is u65535 diff --git a/lib/compiler_rt/unorddf2.zig b/lib/compiler_rt/unorddf2.zig deleted file mode 100644 index 90da7451992ab5f8b003e5e2f85f93947f932197..0000000000000000000000000000000000000000 --- a/lib/compiler_rt/unorddf2.zig +++ /dev/null @@ -1,19 +0,0 @@ -const compiler_rt = @import("../compiler_rt.zig"); -const comparef = @import("./comparef.zig"); -const symbol = @import("../compiler_rt.zig").symbol; - -comptime { - if (compiler_rt.want_aeabi) { - symbol(&__aeabi_dcmpun, "__aeabi_dcmpun"); - } else { - symbol(&__unorddf2, "__unorddf2"); - } -} - -pub fn __unorddf2(a: f64, b: f64) callconv(.c) i32 { - return comparef.unordcmp(f64, a, b); -} - -fn __aeabi_dcmpun(a: f64, b: f64) callconv(.{ .arm_aapcs = .{} }) i32 { - return comparef.unordcmp(f64, a, b); -} diff --git a/lib/std/crypto/Certificate.zig b/lib/std/crypto/Certificate.zig index 33502074f661d86b2b6778361e85ab89172242d9..aa36b73ac3e36e51bea58c59fea780d1cc222ae8 100644 --- a/lib/std/crypto/Certificate.zig +++ b/lib/std/crypto/Certificate.zig @@ -1211,7 +1211,7 @@ pub const rsa = struct { 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40, }, - else => @compileError("unreachable"), + else => comptime unreachable, }; em_index -= hash_der.len; @memcpy(em[em_index..][0..hash_der.len], hash_der); diff --git a/lib/std/math.zig b/lib/std/math.zig index b43bc8f5981ec9083596a17ac90df631fc31d33f..0beb62ae6a9eb10cdb78e887f900bebcde0612f4 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -75,7 +75,7 @@ pub const snan = float.snan; /// /// NaN values are never considered equal to any value. pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool { - assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float); + comptime assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float); assert(tolerance >= 0); // Fast path for equal values (and signed zeros and infinites). @@ -103,7 +103,7 @@ pub fn approxEqAbs(comptime T: type, x: T, y: T, tolerance: T) bool { /// /// NaN values are never considered equal to any value. pub fn approxEqRel(comptime T: type, x: T, y: T, tolerance: T) bool { - assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float); + comptime assert(@typeInfo(T) == .float or @typeInfo(T) == .comptime_float); assert(tolerance > 0); // Fast path for equal values (and signed zeros and infinites). diff --git a/lib/std/math/atan2.zig b/lib/std/math/atan2.zig index f0c8aa0792046a94b900fba216dde87724ec8e1c..7c7bb4bb78e34d8d3b2c3403eba2e63d3ed1d3ce 100644 --- a/lib/std/math/atan2.zig +++ b/lib/std/math/atan2.zig @@ -252,8 +252,8 @@ test "atan2_32.special" { try expect(math.isNan(atan2_32(1.0, math.nan(f32)))); try expect(math.isNan(atan2_32(math.nan(f32), 1.0))); - try expect(atan2_32(0.0, 5.0) == 0.0); - try expect(atan2_32(-0.0, 5.0) == -0.0); + try expect(math.isPositiveZero(atan2_32(0.0, 5.0))); + try expect(math.isNegativeZero(atan2_32(-0.0, 5.0))); try expect(math.approxEqAbs(f32, atan2_32(0.0, -5.0), math.pi, epsilon)); //expect(math.approxEqAbs(f32, atan2_32(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero? try expect(math.approxEqAbs(f32, atan2_32(1.0, 0.0), math.pi / 2.0, epsilon)); @@ -276,8 +276,8 @@ test "atan2_64.special" { try expect(math.isNan(atan2_64(1.0, math.nan(f64)))); try expect(math.isNan(atan2_64(math.nan(f64), 1.0))); - try expect(atan2_64(0.0, 5.0) == 0.0); - try expect(atan2_64(-0.0, 5.0) == -0.0); + try expect(math.isPositiveZero(atan2_64(0.0, 5.0))); + try expect(math.isNegativeZero(atan2_64(-0.0, 5.0))); try expect(math.approxEqAbs(f64, atan2_64(0.0, -5.0), math.pi, epsilon)); //expect(math.approxEqAbs(f64, atan2_64(-0.0, -5.0), -math.pi, .{.rel=0,.abs=epsilon})); TODO support negative zero? try expect(math.approxEqAbs(f64, atan2_64(1.0, 0.0), math.pi / 2.0, epsilon)); diff --git a/lib/std/zig/target.zig b/lib/std/zig/target.zig index 0ac83c50dc57047ff1a937182b717960b14e8f82..2315405a9e89549e26a875b00b51390fc3bc1b3d 100644 --- a/lib/std/zig/target.zig +++ b/lib/std/zig/target.zig @@ -527,6 +527,20 @@ pub fn intAlignment(target: *const std.Target, bits: u16) u16 { }; } +pub fn compilerRtFloatAbi(target: *const std.Target, bits: u16) std.Target.Abi.Float { + if (target.cpu.has(.x86, .soft_float)) return .soft; + // Marks targets where clang does not even provide a usable C type. + const no_c_type_available = .soft; + switch (bits) { + else => unreachable, + 16 => if (target.cpu.arch.isMIPS() or target.cpu.arch.isPowerPC()) return no_c_type_available, + 32, 64 => {}, + 80 => if (target.cTypeBitSize(.longdouble) != 80) return no_c_type_available, + 128 => if (target.cTypeBitSize(.longdouble) <= 64) return no_c_type_available, + } + return .hard; +} + const std = @import("std"); const assert = std.debug.assert; const Allocator = std.mem.Allocator; diff --git a/src/link.zig b/src/link.zig index 84cbcbdcb78ea45a0e9e93242686f7f8f0f01748..7ce8363a3d77d9191b813cc86f2896e0285bec4e 100644 --- a/src/link.zig +++ b/src/link.zig @@ -2127,7 +2127,7 @@ pub fn resolveInputs( continue; }, } - @compileError("unreachable"); + comptime unreachable; } if (failed_libs.items.len > 0) { diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index d13fc8e83d36590bb20b329f3accd39eae411a4d..0117c647880eb21fb9226abfc816a22ad2bcd2a7 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1845,7 +1845,7 @@ test "coerce between pointers of compatible differently-named floats" { 64 => f64, 80 => f80, 128 => f128, - else => @compileError("unreachable"), + else => comptime unreachable, }; var f1: F = 12.34; const f2: *c_longdouble = &f1; diff --git a/test/behavior/floatop.zig b/test/behavior/floatop.zig index 76b21b6f15316a95c3ee6d98a759ff06e8c03715..74a71249c65f6c2f839356c99bbd8416d5df1cd5 100644 --- a/test/behavior/floatop.zig +++ b/test/behavior/floatop.zig @@ -431,9 +431,9 @@ fn testSqrt(comptime T: type) !void { var inf: T = math.inf(T); try expect(math.isPositiveInf(@sqrt(inf))); var zero: T = 0.0; - try expect(@sqrt(zero) == 0.0); + try expect(math.isPositiveZero(@sqrt(zero))); var neg_zero: T = -0.0; - try expect(@sqrt(neg_zero) == 0.0); + try expect(math.isNegativeZero(@sqrt(neg_zero))); var neg_one: T = -1.0; try expect(math.isNan(@sqrt(neg_one))); var nan: T = math.nan(T); @@ -1501,9 +1501,9 @@ fn testNeg(comptime T: type) !void { // subnormals var zero: T = 0.0; - try expect(-zero == -0.0); + try expect(math.isNegativeZero(-zero)); var neg_zero: T = -0.0; - try expect(-neg_zero == 0.0); + try expect(math.isPositiveZero(-neg_zero)); var true_min: T = math.floatTrueMin(T); try expect(-true_min == -math.floatTrueMin(T)); var neg_true_min: T = -math.floatTrueMin(T); diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index 6a44290f859261ad1c2f02974eb8525022fc0b25..c5ffdfa3e1872bfa58edb53b414b523660e9a9bb 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -1267,7 +1267,7 @@ test "switch with complex item expressions" { test "switch evaluation order" { const eu: anyerror!u32 = 0; _ = eu catch |err| switch (err) { - if (true) @compileError("unreachable") => unreachable, + if (true) comptime unreachable => unreachable, else => unreachable, }; } diff --git a/test/behavior/switch_on_captured_error.zig b/test/behavior/switch_on_captured_error.zig index c4353cd5df381e080489b9b5594df9d356277cc0..a57e93d0d1ca4bd502123b9e13ddcaeb7cbd9b68 100644 --- a/test/behavior/switch_on_captured_error.zig +++ b/test/behavior/switch_on_captured_error.zig @@ -243,7 +243,7 @@ test "switch on error union catch capture" { var a: error{}!u64 = 0; _ = &a; const b = a catch |err| switch (err) { - undefined => @compileError("unreachable"), + undefined => comptime unreachable, }; try expectEqual(@as(u64, 0), b); } @@ -829,7 +829,7 @@ test "switch on error union if else capture" { var a: error{}!u64 = 0; _ = &a; const b = if (a) |x| x else |err| switch (err) { - undefined => @compileError("unreachable"), + undefined => comptime unreachable, }; try expectEqual(@as(u64, 0), b); } @@ -840,7 +840,7 @@ test "switch on error union if else capture" { var a: error{}!u64 = 0; _ = &a; const b = if (a) |*x| x.* else |err| switch (err) { - undefined => @compileError("unreachable"), + undefined => comptime unreachable, }; try expectEqual(@as(u64, 0), b); }