mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-27 19:09:47 +03:00
compiler_rt: Dissolve math_utils.zig into long_double.zig & trig.zig
The closest namespace the pi/4 constant could belong to is `trig.zig` since it's used across trig function implementations. On the other hand, chucking `long double` bit slicing functions into `trig.zig` seems a little more awkward, so they're put into their own namespace.
This commit is contained in:
@@ -17,7 +17,7 @@ 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;
|
||||
const utils = @import("math_utils.zig");
|
||||
const ld = @import("long_double.zig");
|
||||
|
||||
comptime {
|
||||
symbol(&__cosh, "__cosh");
|
||||
@@ -124,12 +124,12 @@ pub fn cos(x: f64) callconv(.c) f64 {
|
||||
}
|
||||
|
||||
fn coslGeneric(comptime T: type, x: T) T {
|
||||
const se = utils.ldSignExponent(x) & 0x7fff;
|
||||
const se = ld.signExponent(x) & 0x7fff;
|
||||
if (se == 0x7fff) {
|
||||
return x - x;
|
||||
}
|
||||
|
||||
if (@abs(x) < utils.pi_4) {
|
||||
if (@abs(x) < trig.pi_4) {
|
||||
if (se < 0x3fff - math.floatMantissaBits(T)) {
|
||||
// raise inexact if x!=0
|
||||
return 1.0 + x;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
//! Utilities for dealing with the `long double` type (`f80` or `f128`)
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
pub const U80 = std.meta.Int(.unsigned, 80);
|
||||
/// pi divided by 4
|
||||
pub const pi_4 = 0.78539816339744830962;
|
||||
|
||||
/// Returns the sign + exponent bits of a `long double`
|
||||
pub fn ldSignExponent(x: anytype) u16 {
|
||||
pub fn signExponent(x: anytype) u16 {
|
||||
const T = @TypeOf(x);
|
||||
switch (T) {
|
||||
f80 => {
|
||||
@@ -16,12 +16,12 @@ pub fn ldSignExponent(x: anytype) u16 {
|
||||
const bits: u128 = @bitCast(x);
|
||||
return @intCast(bits >> 112);
|
||||
},
|
||||
else => @compileError("`ldSignExponent` supports only `f80` and `f128`, got: " ++ @typeName(T)),
|
||||
else => @compileError("`signExponent` supports only `f80` and `f128`, got: " ++ @typeName(T)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Takes the top 16 bits of a `long double`'s mantissa
|
||||
pub fn ldMantissaTop(x: anytype) u16 {
|
||||
pub fn mantissaTop(x: anytype) u16 {
|
||||
const T = @TypeOf(x);
|
||||
switch (T) {
|
||||
f80 => {
|
||||
@@ -32,6 +32,6 @@ pub fn ldMantissaTop(x: anytype) u16 {
|
||||
const bits: u128 = @bitCast(x);
|
||||
return @intCast((bits >> 96) & 0xFFFF);
|
||||
},
|
||||
else => @compileError("`ldMantissaTop` supports only `f80` and `f128`, got: " ++ @typeName(T)),
|
||||
else => @compileError("`mantissaTop` supports only `f80` and `f128`, got: " ++ @typeName(T)),
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
const std = @import("std");
|
||||
const math = std.math;
|
||||
|
||||
const utils = @import("math_utils.zig");
|
||||
const ld = @import("long_double.zig");
|
||||
const rem_pio2_large = @import("rem_pio2_large.zig").rem_pio2_large;
|
||||
|
||||
pub fn rem_pio2l(comptime T: type, x: T, y: *[2]T) i32 {
|
||||
@@ -34,8 +34,8 @@ pub fn rem_pio2l(comptime T: type, x: T, y: *[2]T) i32 {
|
||||
const pio2_3: f64 = 6.36831716351370313614e-25; // 0x18a2e037074000.0p-133
|
||||
|
||||
fn small(x_val: T) bool {
|
||||
const se = utils.ldSignExponent(x_val);
|
||||
const top = utils.ldMantissaTop(x_val);
|
||||
const se = ld.signExponent(x_val);
|
||||
const top = ld.mantissaTop(x_val);
|
||||
const lhs = (@as(u32, se & 0x7fff) << 16) | top;
|
||||
const rhs: u32 = ((0x3fff + 25) << 16) | 0x921f >> 1 | 0x8000;
|
||||
return lhs < rhs;
|
||||
@@ -62,8 +62,8 @@ pub fn rem_pio2l(comptime T: type, x: T, y: *[2]T) i32 {
|
||||
const pio2_3t: T = -2.5650587247459238361625433492959285e-65;
|
||||
|
||||
fn small(x_val: T) bool {
|
||||
const se = utils.ldSignExponent(x_val);
|
||||
const top = utils.ldMantissaTop(x_val);
|
||||
const se = ld.signExponent(x_val);
|
||||
const top = ld.mantissaTop(x_val);
|
||||
const lhs = (@as(u32, se & 0x7fff) << 16) | top;
|
||||
const rhs: u32 = ((0x3fff + 45) << 16) | 0x921f;
|
||||
return lhs < rhs;
|
||||
@@ -77,7 +77,7 @@ pub fn rem_pio2l(comptime T: type, x: T, y: *[2]T) i32 {
|
||||
else => @compileError("rem_pio2l supports only f80 and f128, got: " ++ @typeName(T)),
|
||||
};
|
||||
|
||||
const x_se = utils.ldSignExponent(x);
|
||||
const x_se = ld.signExponent(x);
|
||||
const ex: i32 = @intCast(x_se & 0x7fff);
|
||||
|
||||
if (impl.small(x)) {
|
||||
@@ -105,14 +105,14 @@ pub fn rem_pio2l(comptime T: type, x: T, y: *[2]T) i32 {
|
||||
|
||||
y[0] = r - w;
|
||||
|
||||
const ey: i32 = @intCast(utils.ldSignExponent(y[0]) & 0x7fff);
|
||||
const ey: i32 = @intCast(ld.signExponent(y[0]) & 0x7fff);
|
||||
if (ex - ey > impl.round1) {
|
||||
var t = r;
|
||||
w = fn_ * impl.pio2_2;
|
||||
r = t - w;
|
||||
w = fn_ * impl.pio2_2t - ((t - r) - w);
|
||||
y[0] = r - w;
|
||||
const ey2: i32 = @intCast(utils.ldSignExponent(y[0]) & 0x7fff);
|
||||
const ey2: i32 = @intCast(ld.signExponent(y[0]) & 0x7fff);
|
||||
if (ex - ey2 > impl.round2) {
|
||||
t = r;
|
||||
w = fn_ * impl.pio2_3;
|
||||
|
||||
@@ -17,7 +17,7 @@ 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;
|
||||
const utils = @import("math_utils.zig");
|
||||
const ld = @import("long_double.zig");
|
||||
|
||||
comptime {
|
||||
symbol(&__sinh, "__sinh");
|
||||
@@ -134,12 +134,12 @@ pub fn sin(x: f64) callconv(.c) f64 {
|
||||
}
|
||||
|
||||
fn sinlGeneric(comptime T: type, x: T) T {
|
||||
const se = utils.ldSignExponent(x) & 0x7fff;
|
||||
const se = ld.signExponent(x) & 0x7fff;
|
||||
if (se == 0x7fff) {
|
||||
return x - x;
|
||||
}
|
||||
|
||||
if (@abs(x) < utils.pi_4) {
|
||||
if (@abs(x) < trig.pi_4) {
|
||||
if (se < 0x3fff - (math.floatMantissaBits(T) / 2)) {
|
||||
// raise inexact if x!=0 and underflow if subnormal
|
||||
if (compiler_rt.want_float_exceptions) {
|
||||
|
||||
@@ -9,7 +9,7 @@ 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;
|
||||
const utils = @import("math_utils.zig");
|
||||
const ld = @import("long_double.zig");
|
||||
const compiler_rt = @import("../compiler_rt.zig");
|
||||
const symbol = compiler_rt.symbol;
|
||||
|
||||
@@ -197,7 +197,7 @@ fn sincoslGeneric(comptime T: type, x: T, r_sin: *T, r_cos: *T) void {
|
||||
@compileError("`sincoslGeneric` implemented only for `f80` and `f128`, got: " ++ @typeName(T));
|
||||
}
|
||||
|
||||
const se = utils.ldSignExponent(x) & 0x7fff;
|
||||
const se = ld.signExponent(x) & 0x7fff;
|
||||
if (se == 0x7fff) {
|
||||
const result = x - x;
|
||||
r_sin.* = result;
|
||||
@@ -205,7 +205,7 @@ fn sincoslGeneric(comptime T: type, x: T, r_sin: *T, r_cos: *T) void {
|
||||
return;
|
||||
}
|
||||
|
||||
if (@abs(x) < utils.pi_4) {
|
||||
if (@abs(x) < trig.pi_4) {
|
||||
if (se < 0x3fff - math.floatMantissaBits(T)) {
|
||||
// raise underflow if subnormal
|
||||
if (compiler_rt.want_float_exceptions and se == 0) {
|
||||
|
||||
@@ -17,7 +17,7 @@ const kernel = @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;
|
||||
const utils = @import("math_utils.zig");
|
||||
const ld = @import("long_double.zig");
|
||||
|
||||
const arch = builtin.cpu.arch;
|
||||
const compiler_rt = @import("../compiler_rt.zig");
|
||||
@@ -125,12 +125,12 @@ fn tanlGeneric(comptime T: type, x: T) T {
|
||||
@compileError("`tanlGeneric` implemented only for `f80` and `f128`, got: " ++ T);
|
||||
}
|
||||
|
||||
const se = utils.ldSignExponent(x) & 0x7fff;
|
||||
const se = ld.signExponent(x) & 0x7fff;
|
||||
if (se == 0x7fff) {
|
||||
return x - x;
|
||||
}
|
||||
|
||||
if (@abs(x) < utils.pi_4) {
|
||||
if (@abs(x) < kernel.pi_4) {
|
||||
if (se < 0x3fff - math.floatMantissaBits(T) / 2) {
|
||||
if (compiler_rt.want_float_exceptions) {
|
||||
mem.doNotOptimizeAway(if (se == 0) x * 0x1p-120 else x + 0x1p120);
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
// https://git.musl-libc.org/cgit/musl/tree/src/math/__cosl.c
|
||||
// https://git.musl-libc.org/cgit/musl/tree/src/math/__tanl.c
|
||||
|
||||
/// pi divided by 4
|
||||
pub const pi_4 = 0.78539816339744830962;
|
||||
|
||||
/// kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
|
||||
/// Input x is assumed to be bounded by ~pi/4 in magnitude.
|
||||
/// Input y is the tail of x.
|
||||
|
||||
Reference in New Issue
Block a user