| author | |
| committer | |
| log | e355bcce36fc5d704fede510002d4b22bf9594b7 |
| tree | 1e49088fedccb30ae26abfae6481e22fad10460c |
| parent | ff4fde767faec604958783f29fc2439b1badb0e0 |
Add __floatdisf and __aeabi_l2f
Closes #61885 files changed, 138 insertions(+), 78 deletions(-)
lib/std/special/compiler_rt.zig+3-1| ... | @@ -100,7 +100,8 @@ comptime { | ... | @@ -100,7 +100,8 @@ comptime { |
| 100 | @export(@import("compiler_rt/floatditf.zig").__floatditf, .{ .name = "__floatditf", .linkage = linkage }); | 100 | @export(@import("compiler_rt/floatditf.zig").__floatditf, .{ .name = "__floatditf", .linkage = linkage }); |
| 101 | @export(@import("compiler_rt/floattitf.zig").__floattitf, .{ .name = "__floattitf", .linkage = linkage }); | 101 | @export(@import("compiler_rt/floattitf.zig").__floattitf, .{ .name = "__floattitf", .linkage = linkage }); |
| 102 | @export(@import("compiler_rt/floattidf.zig").__floattidf, .{ .name = "__floattidf", .linkage = linkage }); | 102 | @export(@import("compiler_rt/floattidf.zig").__floattidf, .{ .name = "__floattidf", .linkage = linkage }); |
| 103 | @export(@import("compiler_rt/floattisf.zig").__floattisf, .{ .name = "__floattisf", .linkage = linkage }); | 103 | @export(@import("compiler_rt/floatXisf.zig").__floattisf, .{ .name = "__floattisf", .linkage = linkage }); |
| 104 | @export(@import("compiler_rt/floatXisf.zig").__floatdisf, .{ .name = "__floatdisf", .linkage = linkage }); | ||
| 104 | 105 | ||
| 105 | @export(@import("compiler_rt/floatunditf.zig").__floatunditf, .{ .name = "__floatunditf", .linkage = linkage }); | 106 | @export(@import("compiler_rt/floatunditf.zig").__floatunditf, .{ .name = "__floatunditf", .linkage = linkage }); |
| 106 | @export(@import("compiler_rt/floatunsitf.zig").__floatunsitf, .{ .name = "__floatunsitf", .linkage = linkage }); | 107 | @export(@import("compiler_rt/floatunsitf.zig").__floatunsitf, .{ .name = "__floatunsitf", .linkage = linkage }); |
| ... | @@ -204,6 +205,7 @@ comptime { | ... | @@ -204,6 +205,7 @@ comptime { |
| 204 | @export(@import("compiler_rt/extendXfYf2.zig").__aeabi_f2d, .{ .name = "__aeabi_f2d", .linkage = linkage }); | 205 | @export(@import("compiler_rt/extendXfYf2.zig").__aeabi_f2d, .{ .name = "__aeabi_f2d", .linkage = linkage }); |
| 205 | @export(@import("compiler_rt/floatsiXf.zig").__aeabi_i2d, .{ .name = "__aeabi_i2d", .linkage = linkage }); | 206 | @export(@import("compiler_rt/floatsiXf.zig").__aeabi_i2d, .{ .name = "__aeabi_i2d", .linkage = linkage }); |
| 206 | @export(@import("compiler_rt/floatdidf.zig").__aeabi_l2d, .{ .name = "__aeabi_l2d", .linkage = linkage }); | 207 | @export(@import("compiler_rt/floatdidf.zig").__aeabi_l2d, .{ .name = "__aeabi_l2d", .linkage = linkage }); |
| 208 | @export(@import("compiler_rt/floatXisf.zig").__aeabi_l2f, .{ .name = "__aeabi_l2f", .linkage = linkage }); | ||
| 207 | @export(@import("compiler_rt/floatunsidf.zig").__aeabi_ui2d, .{ .name = "__aeabi_ui2d", .linkage = linkage }); | 209 | @export(@import("compiler_rt/floatunsidf.zig").__aeabi_ui2d, .{ .name = "__aeabi_ui2d", .linkage = linkage }); |
| 208 | @export(@import("compiler_rt/floatundidf.zig").__aeabi_ul2d, .{ .name = "__aeabi_ul2d", .linkage = linkage }); | 210 | @export(@import("compiler_rt/floatundidf.zig").__aeabi_ul2d, .{ .name = "__aeabi_ul2d", .linkage = linkage }); |
| 209 | @export(@import("compiler_rt/floatunsisf.zig").__aeabi_ui2f, .{ .name = "__aeabi_ui2f", .linkage = linkage }); | 211 | @export(@import("compiler_rt/floatunsisf.zig").__aeabi_ui2f, .{ .name = "__aeabi_ui2f", .linkage = linkage }); |
lib/std/special/compiler_rt/floatXisf.zig created+97| ... | @@ -0,0 +1,97 @@ | ||
| 1 | // SPDX-License-Identifier: MIT | ||
| 2 | // Copyright (c) 2015-2020 Zig Contributors | ||
| 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. | ||
| 4 | // The MIT license requires this copyright notice to be included in all copies | ||
| 5 | // and substantial portions of the software. | ||
| 6 | const builtin = @import("builtin"); | ||
| 7 | const std = @import("std"); | ||
| 8 | const maxInt = std.math.maxInt; | ||
| 9 | |||
| 10 | const FLT_MANT_DIG = 24; | ||
| 11 | |||
| 12 | fn __floatXisf(comptime T: type, arg: T) f32 { | ||
| 13 | @setRuntimeSafety(builtin.is_test); | ||
| 14 | |||
| 15 | const Z = std.meta.Int(false, T.bit_count); | ||
| 16 | const S = std.meta.Int(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1)); | ||
| 17 | |||
| 18 | if (arg == 0) { | ||
| 19 | return @as(f32, 0.0); | ||
| 20 | } | ||
| 21 | |||
| 22 | var ai = arg; | ||
| 23 | const N: u32 = T.bit_count; | ||
| 24 | const si = ai >> @intCast(S, (N - 1)); | ||
| 25 | ai = ((ai ^ si) -% si); | ||
| 26 | var a = @bitCast(Z, ai); | ||
| 27 | |||
| 28 | const sd = @bitCast(i32, N - @clz(Z, a)); // number of significant digits | ||
| 29 | var e: i32 = sd - 1; // exponent | ||
| 30 | |||
| 31 | if (sd > FLT_MANT_DIG) { | ||
| 32 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx | ||
| 33 | // finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR | ||
| 34 | // 12345678901234567890123456 | ||
| 35 | // 1 = msb 1 bit | ||
| 36 | // P = bit FLT_MANT_DIG-1 bits to the right of 1 | ||
| 37 | // Q = bit FLT_MANT_DIG bits to the right of 1 | ||
| 38 | // R = "or" of all bits to the right of Q | ||
| 39 | switch (sd) { | ||
| 40 | FLT_MANT_DIG + 1 => { | ||
| 41 | a <<= 1; | ||
| 42 | }, | ||
| 43 | FLT_MANT_DIG + 2 => {}, | ||
| 44 | else => { | ||
| 45 | const shift1_amt = @intCast(i32, sd - (FLT_MANT_DIG + 2)); | ||
| 46 | const shift1_amt_u7 = @intCast(S, shift1_amt); | ||
| 47 | |||
| 48 | const shift2_amt = @intCast(i32, N + (FLT_MANT_DIG + 2)) - sd; | ||
| 49 | const shift2_amt_u7 = @intCast(S, shift2_amt); | ||
| 50 | |||
| 51 | a = (a >> shift1_amt_u7) | @boolToInt((a & (@intCast(Z, maxInt(Z)) >> shift2_amt_u7)) != 0); | ||
| 52 | }, | ||
| 53 | } | ||
| 54 | // finish | ||
| 55 | a |= @boolToInt((a & 4) != 0); // Or P into R | ||
| 56 | a += 1; // round - this step may add a significant bit | ||
| 57 | a >>= 2; // dump Q and R | ||
| 58 | // a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits | ||
| 59 | if ((a & (@as(Z, 1) << FLT_MANT_DIG)) != 0) { | ||
| 60 | a >>= 1; | ||
| 61 | e += 1; | ||
| 62 | } | ||
| 63 | // a is now rounded to FLT_MANT_DIG bits | ||
| 64 | } else { | ||
| 65 | a <<= @intCast(S, FLT_MANT_DIG - sd); | ||
| 66 | // a is now rounded to FLT_MANT_DIG bits | ||
| 67 | } | ||
| 68 | |||
| 69 | const s = @bitCast(Z, arg) >> (T.bit_count - 32); | ||
| 70 | const r = (@intCast(u32, s) & 0x80000000) | // sign | ||
| 71 | (@intCast(u32, (e + 127)) << 23) | // exponent | ||
| 72 | (@truncate(u32, a) & 0x007fffff); // mantissa-high | ||
| 73 | |||
| 74 | return @bitCast(f32, r); | ||
| 75 | } | ||
| 76 | |||
| 77 | pub fn __floatdisf(arg: i64) callconv(.C) f32 { | ||
| 78 | @setRuntimeSafety(builtin.is_test); | ||
| 79 | return @call(.{ .modifier = .always_inline }, __floatXisf, .{ i64, arg }); | ||
| 80 | } | ||
| 81 | |||
| 82 | pub fn __floattisf(arg: i128) callconv(.C) f32 { | ||
| 83 | @setRuntimeSafety(builtin.is_test); | ||
| 84 | return @call(.{ .modifier = .always_inline }, __floatXisf, .{ i128, arg }); | ||
| 85 | } | ||
| 86 | |||
| 87 | pub fn __aeabi_l2f(arg: i64) callconv(.AAPCS) f32 { | ||
| 88 | @setRuntimeSafety(false); | ||
| 89 | return @call(.{ .modifier = .always_inline }, __floatdisf, .{arg}); | ||
| 90 | } | ||
| 91 | |||
| 92 | test "import floattisf" { | ||
| 93 | _ = @import("floattisf_test.zig"); | ||
| 94 | } | ||
| 95 | test "import floatdisf" { | ||
| 96 | _ = @import("floattisf_test.zig"); | ||
| 97 | } | ||
lib/std/special/compiler_rt/floatdisf_test.zig created+37| ... | @@ -0,0 +1,37 @@ | ||
| 1 | // SPDX-License-Identifier: MIT | ||
| 2 | // Copyright (c) 2015-2020 Zig Contributors | ||
| 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. | ||
| 4 | // The MIT license requires this copyright notice to be included in all copies | ||
| 5 | // and substantial portions of the software. | ||
| 6 | const __floatdisf = @import("floatXisf.zig").__floatdisf; | ||
| 7 | const testing = @import("std").testing; | ||
| 8 | |||
| 9 | fn test__floatdisf(a: i64, expected: f32) void { | ||
| 10 | const x = __floatdisf(a); | ||
| 11 | testing.expect(x == expected); | ||
| 12 | } | ||
| 13 | |||
| 14 | test "floatdisf" { | ||
| 15 | test__floatdisf(0, 0.0); | ||
| 16 | test__floatdisf(1, 1.0); | ||
| 17 | test__floatdisf(2, 2.0); | ||
| 18 | test__floatdisf(-1, -1.0); | ||
| 19 | test__floatdisf(-2, -2.0); | ||
| 20 | test__floatdisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); | ||
| 21 | test__floatdisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); | ||
| 22 | test__floatdisf(0x8000008000000000, -0x1.FFFFFEp+62); | ||
| 23 | test__floatdisf(0x8000010000000000, -0x1.FFFFFCp+62); | ||
| 24 | test__floatdisf(0x8000000000000000, -0x1.000000p+63); | ||
| 25 | test__floatdisf(0x8000000000000001, -0x1.000000p+63); | ||
| 26 | test__floatdisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); | ||
| 27 | test__floatdisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); | ||
| 28 | test__floatdisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); | ||
| 29 | test__floatdisf(0x0007FB72EBFFFFFF, 0x1.FEDCBAp+50); | ||
| 30 | test__floatdisf(0x0007FB72EC000000, 0x1.FEDCBCp+50); | ||
| 31 | test__floatdisf(0x0007FB72E8000001, 0x1.FEDCBAp+50); | ||
| 32 | test__floatdisf(0x0007FB72E6000000, 0x1.FEDCBAp+50); | ||
| 33 | test__floatdisf(0x0007FB72E7000000, 0x1.FEDCBAp+50); | ||
| 34 | test__floatdisf(0x0007FB72E7FFFFFF, 0x1.FEDCBAp+50); | ||
| 35 | test__floatdisf(0x0007FB72E4000001, 0x1.FEDCBAp+50); | ||
| 36 | test__floatdisf(0x0007FB72E4000000, 0x1.FEDCB8p+50); | ||
| 37 | } | ||
lib/std/special/compiler_rt/floattisf.zig deleted-76| ... | @@ -1,76 +0,0 @@ | ||
| 1 | // SPDX-License-Identifier: MIT | ||
| 2 | // Copyright (c) 2015-2020 Zig Contributors | ||
| 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. | ||
| 4 | // The MIT license requires this copyright notice to be included in all copies | ||
| 5 | // and substantial portions of the software. | ||
| 6 | const builtin = @import("builtin"); | ||
| 7 | const is_test = builtin.is_test; | ||
| 8 | const std = @import("std"); | ||
| 9 | const maxInt = std.math.maxInt; | ||
| 10 | |||
| 11 | const FLT_MANT_DIG = 24; | ||
| 12 | |||
| 13 | pub fn __floattisf(arg: i128) callconv(.C) f32 { | ||
| 14 | @setRuntimeSafety(is_test); | ||
| 15 | |||
| 16 | if (arg == 0) | ||
| 17 | return 0.0; | ||
| 18 | |||
| 19 | var ai = arg; | ||
| 20 | const N: u32 = 128; | ||
| 21 | const si = ai >> @intCast(u7, (N - 1)); | ||
| 22 | ai = ((ai ^ si) -% si); | ||
| 23 | var a = @bitCast(u128, ai); | ||
| 24 | |||
| 25 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits | ||
| 26 | var e: i32 = sd - 1; // exponent | ||
| 27 | |||
| 28 | if (sd > FLT_MANT_DIG) { | ||
| 29 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx | ||
| 30 | // finish: 000000000000000000000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQR | ||
| 31 | // 12345678901234567890123456 | ||
| 32 | // 1 = msb 1 bit | ||
| 33 | // P = bit FLT_MANT_DIG-1 bits to the right of 1 | ||
| 34 | // Q = bit FLT_MANT_DIG bits to the right of 1 | ||
| 35 | // R = "or" of all bits to the right of Q | ||
| 36 | switch (sd) { | ||
| 37 | FLT_MANT_DIG + 1 => { | ||
| 38 | a <<= 1; | ||
| 39 | }, | ||
| 40 | FLT_MANT_DIG + 2 => {}, | ||
| 41 | else => { | ||
| 42 | const shift1_amt = @intCast(i32, sd - (FLT_MANT_DIG + 2)); | ||
| 43 | const shift1_amt_u7 = @intCast(u7, shift1_amt); | ||
| 44 | |||
| 45 | const shift2_amt = @intCast(i32, N + (FLT_MANT_DIG + 2)) - sd; | ||
| 46 | const shift2_amt_u7 = @intCast(u7, shift2_amt); | ||
| 47 | |||
| 48 | a = (a >> shift1_amt_u7) | @boolToInt((a & (@intCast(u128, maxInt(u128)) >> shift2_amt_u7)) != 0); | ||
| 49 | }, | ||
| 50 | } | ||
| 51 | // finish | ||
| 52 | a |= @boolToInt((a & 4) != 0); // Or P into R | ||
| 53 | a += 1; // round - this step may add a significant bit | ||
| 54 | a >>= 2; // dump Q and R | ||
| 55 | // a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits | ||
| 56 | if ((a & (@as(u128, 1) << FLT_MANT_DIG)) != 0) { | ||
| 57 | a >>= 1; | ||
| 58 | e += 1; | ||
| 59 | } | ||
| 60 | // a is now rounded to FLT_MANT_DIG bits | ||
| 61 | } else { | ||
| 62 | a <<= @intCast(u7, FLT_MANT_DIG - sd); | ||
| 63 | // a is now rounded to FLT_MANT_DIG bits | ||
| 64 | } | ||
| 65 | |||
| 66 | const s = @bitCast(u128, arg) >> (128 - 32); | ||
| 67 | const r = (@intCast(u32, s) & 0x80000000) | // sign | ||
| 68 | (@intCast(u32, (e + 127)) << 23) | // exponent | ||
| 69 | (@truncate(u32, a) & 0x007fffff); // mantissa-high | ||
| 70 | |||
| 71 | return @bitCast(f32, r); | ||
| 72 | } | ||
| 73 | |||
| 74 | test "import floattisf" { | ||
| 75 | _ = @import("floattisf_test.zig"); | ||
| 76 | } | ||
lib/std/special/compiler_rt/floattisf_test.zig+1-1| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. | 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. |
| 4 | // The MIT license requires this copyright notice to be included in all copies | 4 | // The MIT license requires this copyright notice to be included in all copies |
| 5 | // and substantial portions of the software. | 5 | // and substantial portions of the software. |
| 6 | const __floattisf = @import("floattisf.zig").__floattisf; | 6 | const __floattisf = @import("floatXisf.zig").__floattisf; |
| 7 | const testing = @import("std").testing; | 7 | const testing = @import("std").testing; |
| 8 | 8 | ||
| 9 | fn test__floattisf(a: i128, expected: f32) void { | 9 | fn test__floattisf(a: i128, expected: f32) void { |