| author | |
| committer | |
| log | 1f8f434b9c672837d307b50d0fb3c87b8a0ec16a |
| tree | cfc1e161ce8e4d97c3f0bb23790a38999b4c4798 |
| parent | 547e520359b983d301670b8a3b37df67d4ab1a53 |
| signature |
4 files changed, 66 insertions(+), 2 deletions(-)
lib/std/special/compiler_rt.zig+1| ... | @@ -92,6 +92,7 @@ comptime { | ... | @@ -92,6 +92,7 @@ comptime { |
| 92 | @export(@import("compiler_rt/floatunsidf.zig").__floatunsidf, .{ .name = "__floatunsidf", .linkage = linkage }); | 92 | @export(@import("compiler_rt/floatunsidf.zig").__floatunsidf, .{ .name = "__floatunsidf", .linkage = linkage }); |
| 93 | @export(@import("compiler_rt/floatundidf.zig").__floatundidf, .{ .name = "__floatundidf", .linkage = linkage }); | 93 | @export(@import("compiler_rt/floatundidf.zig").__floatundidf, .{ .name = "__floatundidf", .linkage = linkage }); |
| 94 | 94 | ||
| 95 | @export(@import("compiler_rt/floatditf.zig").__floatditf, .{ .name = "__floatditf", .linkage = linkage }); | ||
| 95 | @export(@import("compiler_rt/floattitf.zig").__floattitf, .{ .name = "__floattitf", .linkage = linkage }); | 96 | @export(@import("compiler_rt/floattitf.zig").__floattitf, .{ .name = "__floattitf", .linkage = linkage }); |
| 96 | @export(@import("compiler_rt/floattidf.zig").__floattidf, .{ .name = "__floattidf", .linkage = linkage }); | 97 | @export(@import("compiler_rt/floattidf.zig").__floattidf, .{ .name = "__floattidf", .linkage = linkage }); |
| 97 | @export(@import("compiler_rt/floattisf.zig").__floattisf, .{ .name = "__floattisf", .linkage = linkage }); | 98 | @export(@import("compiler_rt/floattisf.zig").__floattisf, .{ .name = "__floattisf", .linkage = linkage }); |
lib/std/special/compiler_rt/floatditf.zig created+38| ... | @@ -0,0 +1,38 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const is_test = builtin.is_test; | ||
| 3 | const std = @import("std"); | ||
| 4 | const maxInt = std.math.maxInt; | ||
| 5 | |||
| 6 | const significandBits = 112; | ||
| 7 | const exponentBias = 16383; | ||
| 8 | const implicitBit = (@as(u128, 1) << significandBits); | ||
| 9 | |||
| 10 | pub fn __floatditf(arg: i64) callconv(.C) f128 { | ||
| 11 | @setRuntimeSafety(is_test); | ||
| 12 | |||
| 13 | if (arg == 0) | ||
| 14 | return 0.0; | ||
| 15 | |||
| 16 | // All other cases begin by extracting the sign and absolute value of a | ||
| 17 | var sign: u128 = 0; | ||
| 18 | var aAbs = @bitCast(u64, arg); | ||
| 19 | if (arg < 0) { | ||
| 20 | sign = 1 << 127; | ||
| 21 | aAbs = ~@bitCast(u64, arg)+ 1; | ||
| 22 | } | ||
| 23 | |||
| 24 | // Exponent of (fp_t)a is the width of abs(a). | ||
| 25 | const exponent = 63 - @clz(u64, aAbs); | ||
| 26 | var result: u128 = undefined; | ||
| 27 | |||
| 28 | // Shift a into the significand field, rounding if it is a right-shift | ||
| 29 | const shift = significandBits - exponent; | ||
| 30 | result = @as(u128, aAbs) << shift ^ implicitBit; | ||
| 31 | |||
| 32 | result += (@as(u128, exponent) + exponentBias) << significandBits; | ||
| 33 | return @bitCast(f128, result | sign); | ||
| 34 | } | ||
| 35 | |||
| 36 | test "import floatditf" { | ||
| 37 | _ = @import("floatditf_test.zig"); | ||
| 38 | } | ||
lib/std/special/compiler_rt/floatditf_test.zig created+26| ... | @@ -0,0 +1,26 @@ | ||
| 1 | const __floatditf = @import("floatditf.zig").__floatditf; | ||
| 2 | const testing = @import("std").testing; | ||
| 3 | |||
| 4 | fn test__floatditf(a: i64, expected: f128) void { | ||
| 5 | const x = __floatditf(a); | ||
| 6 | testing.expect(x == expected); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "floatditf" { | ||
| 10 | test__floatditf(0x7fffffffffffffff, make_ti(0x403dffffffffffff, 0xfffc000000000000)); | ||
| 11 | test__floatditf(0x123456789abcdef1, make_ti(0x403b23456789abcd, 0xef10000000000000)); | ||
| 12 | test__floatditf(0x2, make_ti(0x4000000000000000, 0x0)); | ||
| 13 | test__floatditf(0x1, make_ti(0x3fff000000000000, 0x0)); | ||
| 14 | test__floatditf(0x0, make_ti(0x0, 0x0)); | ||
| 15 | test__floatditf(@bitCast(i64, @as(u64, 0xffffffffffffffff)), make_ti(0xbfff000000000000, 0x0)); | ||
| 16 | test__floatditf(@bitCast(i64, @as(u64, 0xfffffffffffffffe)), make_ti(0xc000000000000000, 0x0)); | ||
| 17 | test__floatditf(-0x123456789abcdef1, make_ti(0xc03b23456789abcd, 0xef10000000000000)); | ||
| 18 | test__floatditf(@bitCast(i64, @as(u64, 0x8000000000000000)), make_ti(0xc03e000000000000, 0x0)); | ||
| 19 | } | ||
| 20 | |||
| 21 | fn make_ti(high: u64, low: u64) f128 { | ||
| 22 | var result: u128 = high; | ||
| 23 | result <<= 64; | ||
| 24 | result |= low; | ||
| 25 | return @bitCast(f128, result); | ||
| 26 | } | ||
src-self-hosted/value.zig+1-2| ... | @@ -586,8 +586,7 @@ pub const Value = extern union { | ... | @@ -586,8 +586,7 @@ pub const Value = extern union { |
| 586 | 586 | ||
| 587 | .zero => 0, | 587 | .zero => 0, |
| 588 | .int_u64 => @intToFloat(T, self.cast(Payload.Int_u64).?.int), | 588 | .int_u64 => @intToFloat(T, self.cast(Payload.Int_u64).?.int), |
| 589 | // .int_i64 => @intToFloat(f128, self.cast(Payload.Int_i64).?.int), | 589 | .int_i64 => @intToFloat(T, self.cast(Payload.Int_i64).?.int), |
| 590 | .int_i64 => @panic("TODO lld: error: undefined symbol: __floatditf"), | ||
| 591 | 590 | ||
| 592 | .int_big_positive, .int_big_negative => @panic("big int to f128"), | 591 | .int_big_positive, .int_big_negative => @panic("big int to f128"), |
| 593 | else => unreachable, | 592 | else => unreachable, |