diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-04-26 10:13:55 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-04-27 12:20:44 -0700 |
| commit | 41dd2beaacade94c5c98400a4a655aea07b9e2f3 (patch) | |
| tree | d7cd75c3ded0e8517e801f62dbb883d93f3cd585 /lib/std/special/compiler_rt/fmodx.zig | |
| parent | 6f4343b61afe36a709e713735947561a2b76bce8 (diff) | |
| download | zig-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.zig | 108 |
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"); -} |
