aboutsummaryrefslogtreecommitdiff
path: root/lib/std/special/compiler_rt/fmodx.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-04-26 10:13:55 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-04-27 12:20:44 -0700
commit41dd2beaacade94c5c98400a4a655aea07b9e2f3 (patch)
treed7cd75c3ded0e8517e801f62dbb883d93f3cd585 /lib/std/special/compiler_rt/fmodx.zig
parent6f4343b61afe36a709e713735947561a2b76bce8 (diff)
downloadzig-41dd2beaacade94c5c98400a4a655aea07b9e2f3.tar.gz
zig-41dd2beaacade94c5c98400a4a655aea07b9e2f3.zip
compiler-rt: math functions reorg
* unify the logic for exporting math functions from compiler-rt, with the appropriate suffixes and prefixes. - add all missing f128 and f80 exports. Functions with missing implementations call other functions and have TODO comments. - also add f16 functions * move math functions from freestanding libc to compiler-rt (#7265) * enable all the f128 and f80 code in the stage2 compiler and behavior tests (#11161). * update std lib to use builtins rather than `std.math`.
Diffstat (limited to 'lib/std/special/compiler_rt/fmodx.zig')
-rw-r--r--lib/std/special/compiler_rt/fmodx.zig108
1 files changed, 0 insertions, 108 deletions
diff --git a/lib/std/special/compiler_rt/fmodx.zig b/lib/std/special/compiler_rt/fmodx.zig
deleted file mode 100644
index efe16f9f16..0000000000
--- a/lib/std/special/compiler_rt/fmodx.zig
+++ /dev/null
@@ -1,108 +0,0 @@
-const builtin = @import("builtin");
-const std = @import("std");
-const math = std.math;
-const normalize = @import("divdf3.zig").normalize;
-
-// 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 {
- @setRuntimeSafety(builtin.is_test);
-
- const T = f80;
- const Z = std.meta.Int(.unsigned, @bitSizeOf(T));
-
- const significandBits = math.floatMantissaBits(T);
- const fractionalBits = math.floatFractionalBits(T);
- const exponentBits = math.floatExponentBits(T);
-
- const signBit = (@as(Z, 1) << (significandBits + exponentBits));
- const maxExponent = ((1 << exponentBits) - 1);
-
- var aRep = @bitCast(Z, a);
- var bRep = @bitCast(Z, b);
-
- const signA = aRep & signBit;
- var expA = @intCast(i32, (@bitCast(Z, a) >> significandBits) & maxExponent);
- var expB = @intCast(i32, (@bitCast(Z, b) >> significandBits) & maxExponent);
-
- // There are 3 cases where the answer is undefined, check for:
- // - fmodx(val, 0)
- // - fmodx(val, NaN)
- // - fmodx(inf, val)
- // The sign on checked values does not matter.
- // Doing (a * b) / (a * b) procudes undefined results
- // because the three cases always produce undefined calculations:
- // - 0 / 0
- // - val * NaN
- // - inf / inf
- if (b == 0 or math.isNan(b) or expA == maxExponent) {
- return (a * b) / (a * b);
- }
-
- // Remove the sign from both
- aRep &= ~signBit;
- bRep &= ~signBit;
- if (aRep <= bRep) {
- if (aRep == bRep) {
- return 0 * a;
- }
- return a;
- }
-
- if (expA == 0) expA = normalize(f80, &aRep);
- if (expB == 0) expB = normalize(f80, &bRep);
-
- var highA: u64 = 0;
- var highB: u64 = 0;
- var lowA: u64 = @truncate(u64, aRep);
- var lowB: u64 = @truncate(u64, bRep);
-
- while (expA > expB) : (expA -= 1) {
- var high = highA -% highB;
- var low = lowA -% lowB;
- if (lowA < lowB) {
- high -%= 1;
- }
- if (high >> 63 == 0) {
- if ((high | low) == 0) {
- return 0 * a;
- }
- highA = 2 *% high + (low >> 63);
- lowA = 2 *% low;
- } else {
- highA = 2 *% highA + (lowA >> 63);
- lowA = 2 *% lowA;
- }
- }
-
- var high = highA -% highB;
- var low = lowA -% lowB;
- if (lowA < lowB) {
- high -%= 1;
- }
- if (high >> 63 == 0) {
- if ((high | low) == 0) {
- return 0 * a;
- }
- highA = high;
- lowA = low;
- }
-
- while ((lowA >> fractionalBits) == 0) {
- lowA = 2 *% lowA;
- expA = expA - 1;
- }
-
- // Combine the exponent with the sign and significand, normalize if happened to be denormalized
- if (expA < -fractionalBits) {
- return @bitCast(T, signA);
- } else if (expA <= 0) {
- return @bitCast(T, (lowA >> @intCast(math.Log2Int(u64), 1 - expA)) | signA);
- } else {
- return @bitCast(T, lowA | (@as(Z, @intCast(u16, expA)) << significandBits) | signA);
- }
-}
-
-test {
- _ = @import("fmodx_test.zig");
-}