commit d34b868bcf759a81275fe51b9c2faeb15bf7bedd (tree)
parent ce3f254526609a9b2088d81070903107c969bb81
Author: Andrew Kelley <andrew@ziglang.org>
Date: Fri, 3 Apr 2026 12:04:32 +0200
Merge pull request '`libzigc`: Implement 12 more math functions' (#31604) from mihael/zig:libzigc/more-math-functions-2 into master
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31604
Reviewed-by: Andrew Kelley <andrew@ziglang.org>
Diffstat:
54 files changed, 1257 insertions(+), 1700 deletions(-)
diff --git a/lib/c/math.zig b/lib/c/math.zig
@@ -36,6 +36,8 @@ comptime {
if (builtin.target.isMinGW() or builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
symbol(&coshf, "coshf");
+ symbol(&frexpf, "frexpf");
+ symbol(&frexpl, "frexpl");
symbol(&hypotf, "hypotf");
symbol(&hypotl, "hypotl");
symbol(&modff, "modff");
@@ -46,6 +48,11 @@ comptime {
symbol(&tanhf, "tanhf");
}
+ if (builtin.target.isMinGW() or builtin.target.isMuslLibC()) {
+ symbol(&rint, "rint");
+ symbol(&rintf, "rintf");
+ }
+
if (builtin.target.isMuslLibC() or builtin.target.isWasiLibC()) {
symbol(&acos, "acos");
symbol(&acosf, "acosf");
@@ -60,7 +67,12 @@ comptime {
symbol(&exp10, "exp10");
symbol(&exp10f, "exp10f");
symbol(&fdim, "fdim");
+ symbol(&finite, "finite");
+ symbol(&finitef, "finitef");
+ symbol(&frexp, "frexp");
symbol(&hypot, "hypot");
+ symbol(&lrint, "lrint");
+ symbol(&lrintf, "lrintf");
symbol(&modf, "modf");
symbol(&pow, "pow");
symbol(&pow10, "pow10");
@@ -71,7 +83,6 @@ comptime {
if (builtin.target.isMuslLibC()) {
symbol(©sign, "copysign");
symbol(©signf, "copysignf");
- symbol(&rint, "rint");
}
symbol(©signl, "copysignl");
@@ -161,6 +172,45 @@ fn fdim(x: f64, y: f64) callconv(.c) f64 {
return 0;
}
+fn finite(x: f64) callconv(.c) c_int {
+ return if (math.isFinite(x)) 1 else 0;
+}
+
+fn finitef(x: f32) callconv(.c) c_int {
+ return if (math.isFinite(x)) 1 else 0;
+}
+
+fn frexpGeneric(comptime T: type, x: T, e: *c_int) T {
+ // libc expects `*e` to be unspecified in this case; an unspecified C value
+ // should be a valid value of the relevant type, yet Zig's std
+ // implementation sets it to `undefined` -- which can even be nonsense
+ // according to the type (int). Therefore, we're setting it to a valid
+ // int value in Zig -- a zero.
+ //
+ // This mirrors the handling of infinities, where libc also expects
+ // unspecified for the value of `*e` and Zig std sets it to a zero.
+ if (math.isNan(x)) {
+ e.* = 0;
+ return x;
+ }
+
+ const r = math.frexp(x);
+ e.* = r.exponent;
+ return r.significand;
+}
+
+fn frexp(x: f64, e: *c_int) callconv(.c) f64 {
+ return frexpGeneric(f64, x, e);
+}
+
+fn frexpf(x: f32, e: *c_int) callconv(.c) f32 {
+ return frexpGeneric(f32, x, e);
+}
+
+fn frexpl(x: c_longdouble, e: *c_int) callconv(.c) c_longdouble {
+ return frexpGeneric(c_longdouble, x, e);
+}
+
fn hypot(x: f64, y: f64) callconv(.c) f64 {
return math.hypot(x, y);
}
@@ -185,6 +235,14 @@ fn isnanl(x: c_longdouble) callconv(.c) c_int {
return if (math.isNan(x)) 1 else 0;
}
+fn lrint(x: f64) callconv(.c) c_long {
+ return @intFromFloat(rint(x));
+}
+
+fn lrintf(x: f32) callconv(.c) c_long {
+ return @intFromFloat(rintf(x));
+}
+
fn modfGeneric(comptime T: type, x: T, iptr: *T) T {
if (math.isNegativeInf(x)) {
iptr.* = -math.inf(T);
@@ -299,7 +357,7 @@ fn pow10f(x: f32) callconv(.c) f32 {
}
fn rint(x: f64) callconv(.c) f64 {
- const toint: f64 = 1.0 / @as(f64, math.floatEps(f64));
+ const toint: f64 = 1.0 / math.floatEps(f64);
const a: u64 = @bitCast(x);
const e = a >> 52 & 0x7ff;
const s = a >> 63;
@@ -319,39 +377,70 @@ fn rint(x: f64) callconv(.c) f64 {
return y;
}
-test "rint" {
+fn rintf(x: f32) callconv(.c) f32 {
+ const toint: f32 = 1.0 / math.floatEps(f32);
+ const a: u32 = @bitCast(x);
+ const e = a >> 23 & 0xff;
+ const s = a >> 31;
+ var y: f32 = undefined;
+
+ if (e >= 0x7f + 23) {
+ return x;
+ }
+
+ if (s == 1) {
+ y = x - toint + toint;
+ } else {
+ y = x + toint - toint;
+ }
+
+ if (y == 0) {
+ return if (s == 1) -0.0 else 0;
+ }
+ return y;
+}
+
+fn testRint(comptime T: type) !void {
+ const f = switch (T) {
+ f32 => rintf,
+ f64 => rint,
+ else => @compileError("rint not implemented for" ++ @typeName(T)),
+ };
+
// Positive numbers round correctly
- try expectEqual(@as(f64, 42.0), rint(42.2));
- try expectEqual(@as(f64, 42.0), rint(41.8));
+ try expectEqual(@as(T, 42.0), f(42.2));
+ try expectEqual(@as(T, 42.0), f(41.8));
// Negative numbers round correctly
- try expectEqual(@as(f64, -6.0), rint(-5.9));
- try expectEqual(@as(f64, -6.0), rint(-6.1));
+ try expectEqual(@as(T, -6.0), f(-5.9));
+ try expectEqual(@as(T, -6.0), f(-6.1));
// No rounding needed test
- try expectEqual(@as(f64, 5.0), rint(5.0));
- try expectEqual(@as(f64, -10.0), rint(-10.0));
- try expectEqual(@as(f64, 0.0), rint(0.0));
+ try expectEqual(@as(T, 5.0), f(5.0));
+ try expectEqual(@as(T, -10.0), f(-10.0));
+ try expectEqual(@as(T, 0.0), f(0.0));
// Very large numbers return unchanged
- const large: f64 = 9007199254740992.0; // 2^53
- try expectEqual(large, rint(large));
- try expectEqual(-large, rint(-large));
+ const large: T = 9007199254740992.0; // 2^53
+ try expectEqual(large, f(large));
+ try expectEqual(-large, f(-large));
// Small positive numbers round to zero
- const pos_result = rint(0.3);
- try expectEqual(@as(f64, 0.0), pos_result);
- try expect(@as(u64, @bitCast(pos_result)) == 0);
+ const pos_result = f(0.3);
+ try expect(math.isPositiveZero(pos_result));
// Small negative numbers round to negative zero
- const neg_result = rint(-0.3);
- try expectEqual(@as(f64, 0.0), neg_result);
- const bits: u64 = @bitCast(neg_result);
- try expect((bits >> 63) == 1);
+ const neg_result = f(-0.3);
+ try expect(math.isNegativeZero(neg_result));
// Exact half rounds to nearest even (banker's rounding)
- try expectEqual(@as(f64, 2.0), rint(2.5));
- try expectEqual(@as(f64, 4.0), rint(3.5));
+ try expectEqual(@as(T, 2.0), f(2.5));
+ try expectEqual(@as(T, 4.0), f(3.5));
+}
+
+test "rint" {
+ try testRint(f32);
+ try testRint(f64);
}
fn tanh(x: f64) callconv(.c) f64 {
diff --git a/lib/compiler_rt/cos.zig b/lib/compiler_rt/cos.zig
@@ -1,19 +1,30 @@
+//! Ported from musl, which is licensed under the MIT license:
+//! https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
+//!
+//! https://git.musl-libc.org/cgit/musl/tree/src/math/cosf.c
+//! https://git.musl-libc.org/cgit/musl/tree/src/math/cos.c
+//! https://git.musl-libc.org/cgit/musl/tree/src/math/cosl.c
+
const std = @import("std");
const math = std.math;
const mem = std.mem;
const expect = std.testing.expect;
+const expectApproxEqAbs = std.testing.expectApproxEqAbs;
const compiler_rt = @import("../compiler_rt.zig");
const symbol = @import("../compiler_rt.zig").symbol;
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 ld = @import("long_double.zig");
comptime {
- symbol(&__cosh, "__cosh");
+ symbol(&cosh, "__cosh");
+ symbol(&cosl, "__cosl");
symbol(&cosf, "cosf");
symbol(&cos, "cos");
- symbol(&__cosx, "__cosx");
+ symbol(&cosx, "__cosx");
if (compiler_rt.want_ppc_abi) {
symbol(&cosq, "cosf128");
}
@@ -21,7 +32,7 @@ comptime {
symbol(&cosl, "cosl");
}
-pub fn __cosh(a: f16) callconv(.c) f16 {
+pub fn cosh(a: f16) callconv(.c) f16 {
// TODO: more efficient implementation
return @floatCast(cosf(a));
}
@@ -43,27 +54,27 @@ pub fn cosf(x: f32) callconv(.c) f32 {
if (compiler_rt.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120);
return 1.0;
}
- return trig.__cosdf(x);
+ return trig.cosdf(x);
}
if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4
if (ix > 0x4016cbe3) { // |x| ~> 3*pi/4
- return -trig.__cosdf(if (sign) x + c2pio2 else x - c2pio2);
+ return -trig.cosdf(if (sign) x + c2pio2 else x - c2pio2);
} else {
if (sign) {
- return trig.__sindf(x + c1pio2);
+ return trig.sindf(x + c1pio2);
} else {
- return trig.__sindf(c1pio2 - x);
+ return trig.sindf(c1pio2 - x);
}
}
}
if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4
if (ix > 0x40afeddf) { // |x| ~> 7*pi/4
- return trig.__cosdf(if (sign) x + c4pio2 else x - c4pio2);
+ return trig.cosdf(if (sign) x + c4pio2 else x - c4pio2);
} else {
if (sign) {
- return trig.__sindf(-x - c3pio2);
+ return trig.sindf(-x - c3pio2);
} else {
- return trig.__sindf(x - c3pio2);
+ return trig.sindf(x - c3pio2);
}
}
}
@@ -76,10 +87,10 @@ pub fn cosf(x: f32) callconv(.c) f32 {
var y: f64 = undefined;
const n = rem_pio2f(x, &y);
return switch (n & 3) {
- 0 => trig.__cosdf(y),
- 1 => trig.__sindf(-y),
- 2 => -trig.__cosdf(y),
- else => trig.__sindf(y),
+ 0 => trig.cosdf(y),
+ 1 => trig.sindf(-y),
+ 2 => -trig.cosdf(y),
+ else => trig.sindf(y),
};
}
@@ -94,7 +105,7 @@ pub fn cos(x: f64) callconv(.c) f64 {
if (compiler_rt.want_float_exceptions) mem.doNotOptimizeAway(x + 0x1p120);
return 1.0;
}
- return trig.__cos(x, 0);
+ return trig.cos(x, 0);
}
// cos(Inf or NaN) is NaN
@@ -105,66 +116,144 @@ pub fn cos(x: f64) callconv(.c) f64 {
var y: [2]f64 = undefined;
const n = rem_pio2(x, &y);
return switch (n & 3) {
- 0 => trig.__cos(y[0], y[1]),
- 1 => -trig.__sin(y[0], y[1], 1),
- 2 => -trig.__cos(y[0], y[1]),
- else => trig.__sin(y[0], y[1], 1),
+ 0 => trig.cos(y[0], y[1]),
+ 1 => -trig.sin(y[0], y[1], 1),
+ 2 => -trig.cos(y[0], y[1]),
+ else => trig.sin(y[0], y[1], 1),
};
}
-pub fn __cosx(a: f80) callconv(.c) f80 {
- // TODO: more efficient implementation
- return @floatCast(cosq(a));
+pub fn cosx(x: f80) callconv(.c) f80 {
+ const se = ld.signExponent(x) & 0x7fff;
+ if (se == 0x7fff) {
+ return x - x;
+ }
+
+ if (@abs(x) < trig.pi_4) {
+ if (se < 0x3fff - math.floatMantissaBits(f80)) {
+ // raise inexact if x!=0
+ return 1.0 + x;
+ }
+ return trig.cosx(x, 0.0);
+ }
+
+ var y: [2]f80 = undefined;
+ const n = rem_pio2l(f80, x, &y);
+ return switch (n & 3) {
+ 0 => trig.cosx(y[0], y[1]),
+ 1 => -trig.sinx(y[0], y[1], 1),
+ 2 => -trig.cosx(y[0], y[1]),
+ else => trig.sinx(y[0], y[1], 1),
+ };
}
-pub fn cosq(a: f128) callconv(.c) f128 {
- // TODO: more correct implementation
- return cos(@floatCast(a));
+pub fn cosq(x: f128) callconv(.c) f128 {
+ const se = ld.signExponent(x) & 0x7fff;
+ if (se == 0x7fff) {
+ return x - x;
+ }
+
+ if (@abs(x) < trig.pi_4) {
+ if (se < 0x3fff - math.floatMantissaBits(f128)) {
+ // raise inexact if x!=0
+ return 1.0 + x;
+ }
+ return trig.cosq(x, 0.0);
+ }
+
+ var y: [2]f128 = undefined;
+ const n = rem_pio2l(f128, x, &y);
+ return switch (n & 3) {
+ 0 => trig.cosq(y[0], y[1]),
+ 1 => -trig.sinq(y[0], y[1], 1),
+ 2 => -trig.cosq(y[0], y[1]),
+ else => trig.sinq(y[0], y[1], 1),
+ };
}
pub fn cosl(x: c_longdouble) callconv(.c) c_longdouble {
switch (@typeInfo(c_longdouble).float.bits) {
- 16 => return __cosh(x),
+ 16 => return cosh(x),
32 => return cosf(x),
64 => return cos(x),
- 80 => return __cosx(x),
+ 80 => return cosx(x),
128 => return cosq(x),
else => @compileError("unreachable"),
}
}
-test "cos32" {
- const epsilon = 0.00001;
+fn testCosSpecial(comptime T: type) !void {
+ const f = switch (T) {
+ f32 => cosf,
+ f64 => cos,
+ f80 => cosx,
+ f128 => cosq,
+ else => @compileError("unimplemented"),
+ };
- try expect(math.approxEqAbs(f32, cosf(0.0), 1.0, epsilon));
- try expect(math.approxEqAbs(f32, cosf(0.2), 0.980067, epsilon));
- try expect(math.approxEqAbs(f32, cosf(0.8923), 0.627623, epsilon));
- try expect(math.approxEqAbs(f32, cosf(1.5), 0.070737, epsilon));
- try expect(math.approxEqAbs(f32, cosf(-1.5), 0.070737, epsilon));
- try expect(math.approxEqAbs(f32, cosf(37.45), 0.969132, epsilon));
- try expect(math.approxEqAbs(f32, cosf(89.123), 0.400798, epsilon));
+ try expect(f(0.0) == 1.0);
+ try expect(f(-0.0) == 1.0);
+ try expect(math.isNan(f(math.inf(T))));
+ try expect(math.isNan(f(-math.inf(T))));
+ try expect(math.isNan(f(math.nan(T))));
}
-test "cos64" {
- const epsilon = 0.000001;
-
- try expect(math.approxEqAbs(f64, cos(0.0), 1.0, epsilon));
- try expect(math.approxEqAbs(f64, cos(0.2), 0.980067, epsilon));
- try expect(math.approxEqAbs(f64, cos(0.8923), 0.627623, epsilon));
- try expect(math.approxEqAbs(f64, cos(1.5), 0.070737, epsilon));
- try expect(math.approxEqAbs(f64, cos(-1.5), 0.070737, epsilon));
- try expect(math.approxEqAbs(f64, cos(37.45), 0.969132, epsilon));
- try expect(math.approxEqAbs(f64, cos(89.123), 0.40080, epsilon));
+test "cos32.normal" {
+ const epsilon = math.floatEps(f32);
+ try expectApproxEqAbs(@as(f32, 1.0), cosf(0.0), epsilon);
+ try expectApproxEqAbs(@as(f32, 0.9800666), cosf(0.2), epsilon);
+ try expectApproxEqAbs(@as(f32, 0.6276231), cosf(0.8923), epsilon);
+ try expectApproxEqAbs(@as(f32, 0.0707372), cosf(1.5), epsilon);
+ try expectApproxEqAbs(@as(f32, 0.0707372), cosf(-1.5), epsilon);
+ try expectApproxEqAbs(@as(f32, 0.96913195), cosf(37.45), epsilon);
+ try expectApproxEqAbs(@as(f32, 0.40079966), cosf(89.123), epsilon);
}
test "cos32.special" {
- try expect(math.isNan(cosf(math.inf(f32))));
- try expect(math.isNan(cosf(-math.inf(f32))));
- try expect(math.isNan(cosf(math.nan(f32))));
+ try testCosSpecial(f32);
+}
+
+test "cos64.normal" {
+ const epsilon = math.floatEps(f64);
+ try expectApproxEqAbs(@as(f64, 1.0), cos(0.0), epsilon);
+ try expectApproxEqAbs(@as(f64, 0.9800665778412416), cos(0.2), epsilon);
+ try expectApproxEqAbs(@as(f64, 0.6276230983360804), cos(0.8923), epsilon);
+ try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(1.5), epsilon);
+ try expectApproxEqAbs(@as(f64, 0.0707372016677029), cos(-1.5), epsilon);
+ try expectApproxEqAbs(@as(f64, 0.9691317730707778), cos(37.45), epsilon);
+ try expectApproxEqAbs(@as(f64, 0.4008006809354791), cos(89.123), epsilon);
}
test "cos64.special" {
- try expect(math.isNan(cos(math.inf(f64))));
- try expect(math.isNan(cos(-math.inf(f64))));
- try expect(math.isNan(cos(math.nan(f64))));
+ try testCosSpecial(f64);
+}
+
+test "cos80.normal" {
+ const epsilon = math.floatEps(f80);
+ try expectApproxEqAbs(@as(f80, 1.0), cosx(0.0), epsilon);
+ try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), cosx(0.2), epsilon);
+ try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), cosx(0.8923), epsilon);
+ try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(1.5), epsilon);
+ try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), cosx(-1.5), epsilon);
+ try expectApproxEqAbs(@as(f80, 0.9691317730707771246), cosx(37.45), epsilon);
+ try expectApproxEqAbs(@as(f80, 0.4008006809354834001), cosx(89.123), epsilon);
+}
+
+test "cos80.special" {
+ try testCosSpecial(f80);
+}
+
+test "cos128.normal" {
+ const epsilon = math.floatEps(f128);
+ try expectApproxEqAbs(@as(f128, 1.0), cosq(0.0), epsilon);
+ try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), cosq(0.2), epsilon);
+ try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), cosq(0.8923), epsilon);
+ try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(1.5), epsilon);
+ try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), cosq(-1.5), epsilon);
+ try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), cosq(37.45), epsilon);
+ try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), cosq(89.123), epsilon);
+}
+
+test "cos128.special" {
+ try testCosSpecial(f128);
}
diff --git a/lib/compiler_rt/long_double.zig b/lib/compiler_rt/long_double.zig
@@ -0,0 +1,37 @@
+//! Utilities for dealing with the `long double` type (`f80` or `f128`)
+
+const std = @import("std");
+
+pub const U80 = std.meta.Int(.unsigned, 80);
+
+/// Returns the sign + exponent bits of a `long double`
+pub fn signExponent(x: anytype) u16 {
+ const T = @TypeOf(x);
+ switch (T) {
+ f80 => {
+ const bits: U80 = @bitCast(x);
+ return @intCast(bits >> 64);
+ },
+ f128 => {
+ const bits: u128 = @bitCast(x);
+ return @intCast(bits >> 112);
+ },
+ else => @compileError("`signExponent` supports only `f80` and `f128`, got: " ++ @typeName(T)),
+ }
+}
+
+/// Takes the top 16 bits of a `long double`'s mantissa
+pub fn mantissaTop(x: anytype) u16 {
+ const T = @TypeOf(x);
+ switch (T) {
+ f80 => {
+ const bits: U80 = @bitCast(x);
+ return @intCast((bits >> 48) & 0xFFFF);
+ },
+ f128 => {
+ const bits: u128 = @bitCast(x);
+ return @intCast((bits >> 96) & 0xFFFF);
+ },
+ else => @compileError("`mantissaTop` supports only `f80` and `f128`, got: " ++ @typeName(T)),
+ }
+}
diff --git a/lib/compiler_rt/rem_pio2l.zig b/lib/compiler_rt/rem_pio2l.zig
@@ -0,0 +1,173 @@
+// Ported from musl, which is licensed under the MIT license:
+// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
+//
+// https://git.musl-libc.org/cgit/musl/tree/src/math/__rem_pio2l.c
+
+const std = @import("std");
+const math = std.math;
+
+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 {
+ const impl = switch (T) {
+ f80 => struct {
+ const round1: i8 = 22;
+ const round2: i8 = 61;
+ const nx: i8 = 3;
+ const ny: i8 = 2;
+
+ const pio4: T = 0x1.921fb54442d1846ap-1;
+ // 64 bits of 2/pi
+ const invpio2: T = 6.36619772367581343076e-01; // 0xa2f9836e4e44152a.0p-64
+ // first 39 bits of pi/2
+ const pio2_1: f64 = 1.57079632679597125389e+00; // 0x3FF921FB, 0x54444000
+ // pi/2 - pio2_1
+ const pio2_1t: T = -1.07463465549719416346e-12; // -0x973dcb3b399d747f.0p-103
+ // second 39 bits of pi/2
+ const pio2_2: f64 = -1.07463465549783099519e-12; // -0x12e7b967674000.0p-92
+ // pi/2 - (pio2_1+pio2_2)
+ const pio2_2t: T = 6.36831716351095013979e-25; // 0xc51701b839a25205.0p-144
+ // pi/2 - (pio2_1+pio2_2+pio2_3)
+ const pio2_3t: T = -2.75299651904407171810e-37; // -0xbb5bf6c7ddd660ce.0p-185
+ // third 39 bits of pi/2
+ const pio2_3: f64 = 6.36831716351370313614e-25; // 0x18a2e037074000.0p-133
+
+ fn small(x_val: T) bool {
+ 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;
+ }
+
+ fn quobits(v: T) i32 {
+ const q: i32 = @intFromFloat(v);
+ return @intCast(@as(u32, @bitCast(q)) & 0x7fffffff);
+ }
+ },
+ f128 => struct {
+ const round1: i8 = 51;
+ const round2: i8 = 119;
+ const nx: i8 = 5;
+ const ny: i8 = 3;
+
+ const pio4: T = 0x1.921fb54442d18469898cc51701b8p-1;
+ const invpio2: T = 6.3661977236758134307553505349005747e-01;
+ const pio2_1: T = 1.5707963267948966192292994253909555e+00;
+ const pio2_1t: T = 2.0222662487959507323996846200947577e-21;
+ const pio2_2: T = 2.0222662487959507323994779168837751e-21;
+ const pio2_2t: T = 2.0670321098263988236496903051604844e-43;
+ const pio2_3: T = 2.0670321098263988236499468110329591e-43;
+ const pio2_3t: T = -2.5650587247459238361625433492959285e-65;
+
+ fn small(x_val: T) bool {
+ 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;
+ }
+
+ fn quobits(fn_val: T) i32 {
+ const q: i64 = @intFromFloat(fn_val);
+ return @intCast(@as(u64, @bitCast(q)) & 0x7fffffff);
+ }
+ },
+ else => @compileError("rem_pio2l supports only f80 and f128, got: " ++ @typeName(T)),
+ };
+
+ const x_se = ld.signExponent(x);
+ const ex: i32 = @intCast(x_se & 0x7fff);
+
+ if (impl.small(x)) {
+ // rint(x/(pi/2))
+ const toint: T = 1.5 / math.floatEps(T);
+ var fn_ = x * impl.invpio2 + toint - toint;
+ var n = impl.quobits(fn_);
+ var r = x - fn_ * @as(T, impl.pio2_1);
+ var w = fn_ * impl.pio2_1t; // 1st round good to 102/180 bits
+
+ // Matters with directed rounding.
+ if (r - w < -impl.pio4) {
+ @branchHint(.unlikely);
+ n -= 1;
+ fn_ -= 1;
+ r = x - fn_ * @as(T, impl.pio2_1);
+ w = fn_ * impl.pio2_1t;
+ } else if (r - w > impl.pio4) {
+ @branchHint(.unlikely);
+ n += 1;
+ fn_ += 1;
+ r = x - fn_ * @as(T, impl.pio2_1);
+ w = fn_ * impl.pio2_1t;
+ }
+
+ y[0] = r - w;
+
+ 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(ld.signExponent(y[0]) & 0x7fff);
+ if (ex - ey2 > impl.round2) {
+ t = r;
+ w = fn_ * impl.pio2_3;
+ r = t - w;
+ w = fn_ * impl.pio2_3t - ((t - r) - w);
+ y[0] = r - w;
+ }
+ }
+ y[1] = (r - y[0]) - w;
+ return n;
+ }
+
+ // all other (large) arguments
+ if (ex == 0x7fff) { // x is inf or NaN
+ y[0] = x - x;
+ y[1] = y[0];
+ return 0;
+ }
+
+ var z: T = math.scalbn(@abs(x), -math.ilogb(x) + 23);
+ var tx: [impl.nx]f64 = undefined;
+ var ty: [impl.ny]f64 = undefined;
+ var i: usize = 0;
+
+ while (i < impl.nx - 1) : (i += 1) {
+ tx[i] = @floatFromInt(@as(i32, @intFromFloat(z)));
+ z = (z - @as(T, tx[i])) * 0x1p24;
+ }
+
+ tx[i] = @floatCast(z);
+ while (tx[i] == 0.0) {
+ i -= 1;
+ }
+
+ const n = rem_pio2_large(
+ tx[0..(i + 1)],
+ ty[0..impl.ny],
+ ex - 0x3fff - 23,
+ @intCast(i + 1),
+ impl.ny,
+ );
+ var w: f64 = ty[1];
+ if (impl.ny == 3) {
+ w += ty[2];
+ }
+ const r = ty[0] + w;
+ w -= r - ty[0];
+
+ if (x_se >> 15 != 0) {
+ y[0] = -@as(T, r);
+ y[1] = -@as(T, w);
+ return -n;
+ }
+
+ y[0] = @as(T, r);
+ y[1] = @as(T, w);
+ return n;
+}
diff --git a/lib/compiler_rt/sin.zig b/lib/compiler_rt/sin.zig
@@ -3,23 +3,28 @@
//!
//! https://git.musl-libc.org/cgit/musl/tree/src/math/sinf.c
//! https://git.musl-libc.org/cgit/musl/tree/src/math/sin.c
+//! https://git.musl-libc.org/cgit/musl/tree/src/math/sinl.c
const std = @import("std");
const math = std.math;
const mem = std.mem;
const expect = std.testing.expect;
+const expectApproxEqAbs = std.testing.expectApproxEqAbs;
const compiler_rt = @import("../compiler_rt.zig");
const symbol = @import("../compiler_rt.zig").symbol;
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 ld = @import("long_double.zig");
comptime {
- symbol(&__sinh, "__sinh");
+ symbol(&sinh, "__sinh");
+ symbol(&sinl, "__sinl");
symbol(&sinf, "sinf");
symbol(&sin, "sin");
- symbol(&__sinx, "__sinx");
+ symbol(&sinx, "__sinx");
if (compiler_rt.want_ppc_abi) {
symbol(&sinq, "sinf128");
}
@@ -27,7 +32,7 @@ comptime {
symbol(&sinl, "sinl");
}
-pub fn __sinh(x: f16) callconv(.c) f16 {
+pub fn sinh(x: f16) callconv(.c) f16 {
// TODO: more efficient implementation
return @floatCast(sinf(x));
}
@@ -55,27 +60,27 @@ pub fn sinf(x: f32) callconv(.c) f32 {
}
return x;
}
- return trig.__sindf(x);
+ return trig.sindf(x);
}
if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4
if (ix <= 0x4016cbe3) { // |x| ~<= 3pi/4
if (sign) {
- return -trig.__cosdf(x + s1pio2);
+ return -trig.cosdf(x + s1pio2);
} else {
- return trig.__cosdf(x - s1pio2);
+ return trig.cosdf(x - s1pio2);
}
}
- return trig.__sindf(if (sign) -(x + s2pio2) else -(x - s2pio2));
+ return trig.sindf(if (sign) -(x + s2pio2) else -(x - s2pio2));
}
if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4
if (ix <= 0x40afeddf) { // |x| ~<= 7*pi/4
if (sign) {
- return trig.__cosdf(x + s3pio2);
+ return trig.cosdf(x + s3pio2);
} else {
- return -trig.__cosdf(x - s3pio2);
+ return -trig.cosdf(x - s3pio2);
}
}
- return trig.__sindf(if (sign) x + s4pio2 else x - s4pio2);
+ return trig.sindf(if (sign) x + s4pio2 else x - s4pio2);
}
// sin(Inf or NaN) is NaN
@@ -86,10 +91,10 @@ pub fn sinf(x: f32) callconv(.c) f32 {
var y: f64 = undefined;
const n = rem_pio2f(x, &y);
return switch (n & 3) {
- 0 => trig.__sindf(y),
- 1 => trig.__cosdf(y),
- 2 => trig.__sindf(-y),
- else => -trig.__cosdf(y),
+ 0 => trig.sindf(y),
+ 1 => trig.cosdf(y),
+ 2 => trig.sindf(-y),
+ else => -trig.cosdf(y),
};
}
@@ -110,7 +115,7 @@ pub fn sin(x: f64) callconv(.c) f64 {
}
return x;
}
- return trig.__sin(x, 0.0, 0);
+ return trig.sin(x, 0.0, 0);
}
// sin(Inf or NaN) is NaN
@@ -121,72 +126,152 @@ pub fn sin(x: f64) callconv(.c) f64 {
var y: [2]f64 = undefined;
const n = rem_pio2(x, &y);
return switch (n & 3) {
- 0 => trig.__sin(y[0], y[1], 1),
- 1 => trig.__cos(y[0], y[1]),
- 2 => -trig.__sin(y[0], y[1], 1),
- else => -trig.__cos(y[0], y[1]),
+ 0 => trig.sin(y[0], y[1], 1),
+ 1 => trig.cos(y[0], y[1]),
+ 2 => -trig.sin(y[0], y[1], 1),
+ else => -trig.cos(y[0], y[1]),
};
}
-pub fn __sinx(x: f80) callconv(.c) f80 {
- // TODO: more efficient implementation
- return @floatCast(sinq(x));
+fn sinx(x: f80) callconv(.c) f80 {
+ const se = ld.signExponent(x) & 0x7fff;
+ if (se == 0x7fff) {
+ return x - x;
+ }
+
+ if (@abs(x) < trig.pi_4) {
+ if (se < 0x3fff - (math.floatMantissaBits(f80) / 2)) {
+ // raise inexact if x!=0 and underflow if subnormal
+ if (compiler_rt.want_float_exceptions) {
+ mem.doNotOptimizeAway(if (se == 0) x * 0x1p-120 else x + 0x1p120);
+ }
+ return x;
+ }
+ return trig.sinx(x, 0.0, 0);
+ }
+
+ var y: [2]f80 = undefined;
+ const n = rem_pio2l(f80, x, &y);
+ return switch (n & 3) {
+ 0 => trig.sinx(y[0], y[1], 1),
+ 1 => trig.cosx(y[0], y[1]),
+ 2 => -trig.sinx(y[0], y[1], 1),
+ else => -trig.cosx(y[0], y[1]),
+ };
}
pub fn sinq(x: f128) callconv(.c) f128 {
- // TODO: more correct implementation
- return sin(@floatCast(x));
+ const se = ld.signExponent(x) & 0x7fff;
+ if (se == 0x7fff) {
+ return x - x;
+ }
+
+ if (@abs(x) < trig.pi_4) {
+ if (se < 0x3fff - (math.floatMantissaBits(f128) / 2)) {
+ // raise inexact if x!=0 and underflow if subnormal
+ if (compiler_rt.want_float_exceptions) {
+ mem.doNotOptimizeAway(if (se == 0) x * 0x1p-120 else x + 0x1p120);
+ }
+ return x;
+ }
+ return trig.sinq(x, 0.0, 0);
+ }
+
+ var y: [2]f128 = undefined;
+ const n = rem_pio2l(f128, x, &y);
+ return switch (n & 3) {
+ 0 => trig.sinq(y[0], y[1], 1),
+ 1 => trig.cosq(y[0], y[1]),
+ 2 => -trig.sinq(y[0], y[1], 1),
+ else => -trig.cosq(y[0], y[1]),
+ };
}
pub fn sinl(x: c_longdouble) callconv(.c) c_longdouble {
switch (@typeInfo(c_longdouble).float.bits) {
- 16 => return __sinh(x),
+ 16 => return sinh(x),
32 => return sinf(x),
64 => return sin(x),
- 80 => return __sinx(x),
+ 80 => return sinx(x),
128 => return sinq(x),
else => @compileError("unreachable"),
}
}
-test "sin32" {
- const epsilon = 0.00001;
+fn testSinSpecial(comptime T: type) !void {
+ const f = switch (T) {
+ f32 => sinf,
+ f64 => sin,
+ f80 => sinx,
+ f128 => sinq,
+ else => @compileError("unimplemented"),
+ };
- try expect(math.approxEqAbs(f32, sinf(0.0), 0.0, epsilon));
- try expect(math.approxEqAbs(f32, sinf(0.2), 0.198669, epsilon));
- try expect(math.approxEqAbs(f32, sinf(0.8923), 0.778517, epsilon));
- try expect(math.approxEqAbs(f32, sinf(1.5), 0.997495, epsilon));
- try expect(math.approxEqAbs(f32, sinf(-1.5), -0.997495, epsilon));
- try expect(math.approxEqAbs(f32, sinf(37.45), -0.246544, epsilon));
- try expect(math.approxEqAbs(f32, sinf(89.123), 0.916166, epsilon));
+ try expect(math.isPositiveZero(f(0.0)));
+ try expect(math.isNegativeZero(f(-0.0)));
+ try expect(math.isNan(f(math.inf(T))));
+ try expect(math.isNan(f(-math.inf(T))));
+ try expect(math.isNan(f(math.nan(T))));
}
-test "sin64" {
- const epsilon = 0.000001;
-
- try expect(math.approxEqAbs(f64, sin(0.0), 0.0, epsilon));
- try expect(math.approxEqAbs(f64, sin(0.2), 0.198669, epsilon));
- try expect(math.approxEqAbs(f64, sin(0.8923), 0.778517, epsilon));
- try expect(math.approxEqAbs(f64, sin(1.5), 0.997495, epsilon));
- try expect(math.approxEqAbs(f64, sin(-1.5), -0.997495, epsilon));
- try expect(math.approxEqAbs(f64, sin(37.45), -0.246543, epsilon));
- try expect(math.approxEqAbs(f64, sin(89.123), 0.916166, epsilon));
+test "sin32.normal" {
+ const epsilon = math.floatEps(f32);
+ try expectApproxEqAbs(@as(f32, 0.0), sinf(0.0), epsilon);
+ try expectApproxEqAbs(@as(f32, 0.19866933), sinf(0.2), epsilon);
+ try expectApproxEqAbs(@as(f32, 0.77851737), sinf(0.8923), epsilon);
+ try expectApproxEqAbs(@as(f32, 0.997495), sinf(1.5), epsilon);
+ try expectApproxEqAbs(@as(f32, -0.997495), sinf(-1.5), epsilon);
+ try expectApproxEqAbs(@as(f32, -0.24654257), sinf(37.45), epsilon);
+ try expectApproxEqAbs(@as(f32, 0.9161657), sinf(89.123), epsilon);
}
test "sin32.special" {
- try expect(sinf(0.0) == 0.0);
- try expect(sinf(-0.0) == -0.0);
- try expect(math.isNan(sinf(math.inf(f32))));
- try expect(math.isNan(sinf(-math.inf(f32))));
- try expect(math.isNan(sinf(math.nan(f32))));
+ try testSinSpecial(f32);
+}
+
+test "sin64.normal" {
+ const epsilon = math.floatEps(f64);
+ try expectApproxEqAbs(@as(f64, 0.0), sin(0.0), epsilon);
+ try expectApproxEqAbs(@as(f64, 0.19866933079506122), sin(0.2), epsilon);
+ try expectApproxEqAbs(@as(f64, 0.7785173385577349), sin(0.8923), epsilon);
+ try expectApproxEqAbs(@as(f64, 0.9974949866040544), sin(1.5), epsilon);
+ try expectApproxEqAbs(@as(f64, -0.9974949866040544), sin(-1.5), epsilon);
+ try expectApproxEqAbs(@as(f64, -0.24654331551411082), sin(37.45), epsilon);
+ try expectApproxEqAbs(@as(f64, 0.9161652766622714), sin(89.123), epsilon);
}
test "sin64.special" {
- try expect(sin(0.0) == 0.0);
- try expect(sin(-0.0) == -0.0);
- try expect(math.isNan(sin(math.inf(f64))));
- try expect(math.isNan(sin(-math.inf(f64))));
- try expect(math.isNan(sin(math.nan(f64))));
+ try testSinSpecial(f64);
+}
+
+test "sin80.normal" {
+ const epsilon = math.floatEps(f80);
+ try expectApproxEqAbs(@as(f80, 0.0), sinx(0.0), epsilon);
+ try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), sinx(0.2), epsilon);
+ try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), sinx(0.8923), epsilon);
+ try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), sinx(1.5), epsilon);
+ try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), sinx(-1.5), epsilon);
+ try expectApproxEqAbs(@as(f80, -0.24654331551411356504), sinx(37.45), epsilon);
+ try expectApproxEqAbs(@as(f80, 0.91616527666226951006), sinx(89.123), epsilon);
+}
+
+test "sin80.special" {
+ try testSinSpecial(f80);
+}
+
+test "sin128.normal" {
+ const epsilon = math.floatEps(f128);
+ try expectApproxEqAbs(@as(f128, 0.0), sinq(0.0), epsilon);
+ try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), sinq(0.2), epsilon);
+ try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), sinq(0.8923), epsilon);
+ try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), sinq(1.5), epsilon);
+ try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), sinq(-1.5), epsilon);
+ try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), sinq(37.45), epsilon);
+ try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), sinq(89.123), epsilon);
+}
+
+test "sin128.special" {
+ try testSinSpecial(f128);
}
test "sin32 #9901" {
diff --git a/lib/compiler_rt/sincos.zig b/lib/compiler_rt/sincos.zig
@@ -3,17 +3,21 @@ const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const math = std.math;
const mem = std.mem;
+const expect = std.testing.expect;
+const expectApproxEqAbs = std.testing.expectApproxEqAbs;
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 ld = @import("long_double.zig");
const compiler_rt = @import("../compiler_rt.zig");
const symbol = compiler_rt.symbol;
comptime {
- symbol(&__sincosh, "__sincosh");
+ symbol(&sincosh, "__sincosh");
symbol(&sincosf, "sincosf");
symbol(&sincos, "sincos");
- symbol(&__sincosx, "__sincosx");
+ symbol(&sincosx, "__sincosx");
if (compiler_rt.want_ppc_abi) {
symbol(&sincosq, "sincosf128");
}
@@ -21,7 +25,7 @@ comptime {
symbol(&sincosl, "sincosl");
}
-pub fn __sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.c) void {
+pub fn sincosh(x: f16, r_sin: *f16, r_cos: *f16) callconv(.c) void {
// TODO: more efficient implementation
var big_sin: f32 = undefined;
var big_cos: f32 = undefined;
@@ -56,8 +60,8 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
r_cos.* = 1.0;
return;
}
- r_sin.* = trig.__sindf(x);
- r_cos.* = trig.__cosdf(x);
+ r_sin.* = trig.sindf(x);
+ r_cos.* = trig.cosdf(x);
return;
}
@@ -66,17 +70,17 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
// |x| ~<= 3pi/4
if (ix <= 0x4016cbe3) {
if (sign) {
- r_sin.* = -trig.__cosdf(x + sc1pio2);
- r_cos.* = trig.__sindf(x + sc1pio2);
+ r_sin.* = -trig.cosdf(x + sc1pio2);
+ r_cos.* = trig.sindf(x + sc1pio2);
} else {
- r_sin.* = trig.__cosdf(sc1pio2 - x);
- r_cos.* = trig.__sindf(sc1pio2 - x);
+ r_sin.* = trig.cosdf(sc1pio2 - x);
+ r_cos.* = trig.sindf(sc1pio2 - x);
}
return;
}
// -sin(x+c) is not correct if x+c could be 0: -0 vs +0
- r_sin.* = -trig.__sindf(if (sign) x + sc2pio2 else x - sc2pio2);
- r_cos.* = -trig.__cosdf(if (sign) x + sc2pio2 else x - sc2pio2);
+ r_sin.* = -trig.sindf(if (sign) x + sc2pio2 else x - sc2pio2);
+ r_cos.* = -trig.cosdf(if (sign) x + sc2pio2 else x - sc2pio2);
return;
}
@@ -85,16 +89,16 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
// |x| ~<= 7*pi/4
if (ix <= 0x40afeddf) {
if (sign) {
- r_sin.* = trig.__cosdf(x + sc3pio2);
- r_cos.* = -trig.__sindf(x + sc3pio2);
+ r_sin.* = trig.cosdf(x + sc3pio2);
+ r_cos.* = -trig.sindf(x + sc3pio2);
} else {
- r_sin.* = -trig.__cosdf(x - sc3pio2);
- r_cos.* = trig.__sindf(x - sc3pio2);
+ r_sin.* = -trig.cosdf(x - sc3pio2);
+ r_cos.* = trig.sindf(x - sc3pio2);
}
return;
}
- r_sin.* = trig.__sindf(if (sign) x + sc4pio2 else x - sc4pio2);
- r_cos.* = trig.__cosdf(if (sign) x + sc4pio2 else x - sc4pio2);
+ r_sin.* = trig.sindf(if (sign) x + sc4pio2 else x - sc4pio2);
+ r_cos.* = trig.cosdf(if (sign) x + sc4pio2 else x - sc4pio2);
return;
}
@@ -109,8 +113,8 @@ pub fn sincosf(x: f32, r_sin: *f32, r_cos: *f32) callconv(.c) void {
// general argument reduction needed
var y: f64 = undefined;
const n = rem_pio2f(x, &y);
- const s = trig.__sindf(y);
- const c = trig.__cosdf(y);
+ const s = trig.sindf(y);
+ const c = trig.cosdf(y);
switch (n & 3) {
0 => {
r_sin.* = s;
@@ -150,8 +154,8 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {
r_cos.* = 1.0;
return;
}
- r_sin.* = trig.__sin(x, 0.0, 0);
- r_cos.* = trig.__cos(x, 0.0);
+ r_sin.* = trig.sin(x, 0.0, 0);
+ r_cos.* = trig.cos(x, 0.0);
return;
}
@@ -166,8 +170,8 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {
// argument reduction needed
var y: [2]f64 = undefined;
const n = rem_pio2(x, &y);
- const s = trig.__sin(y[0], y[1], 1);
- const c = trig.__cos(y[0], y[1]);
+ const s = trig.sin(y[0], y[1], 1);
+ const c = trig.cos(y[0], y[1]);
switch (n & 3) {
0 => {
r_sin.* = s;
@@ -188,50 +192,57 @@ pub fn sincos(x: f64, r_sin: *f64, r_cos: *f64) callconv(.c) void {
}
}
-pub fn __sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void {
- // TODO: more efficient implementation
- //return sincos_generic(f80, x, r_sin, r_cos);
- var big_sin: f128 = undefined;
- var big_cos: f128 = undefined;
- sincosq(x, &big_sin, &big_cos);
- r_sin.* = @as(f80, @floatCast(big_sin));
- r_cos.* = @as(f80, @floatCast(big_cos));
-}
+pub fn sincosx(x: f80, r_sin: *f80, r_cos: *f80) callconv(.c) void {
+ const se = ld.signExponent(x) & 0x7fff;
+ if (se == 0x7fff) {
+ const result = x - x;
+ r_sin.* = result;
+ r_cos.* = result;
+ return;
+ }
-pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void {
- // TODO: more correct implementation
- //return sincos_generic(f128, x, r_sin, r_cos);
- var small_sin: f64 = undefined;
- var small_cos: f64 = undefined;
- sincos(@as(f64, @floatCast(x)), &small_sin, &small_cos);
- r_sin.* = small_sin;
- r_cos.* = small_cos;
-}
+ if (@abs(x) < trig.pi_4) {
+ if (se < 0x3fff - math.floatMantissaBits(f80)) {
+ // raise underflow if subnormal
+ if (compiler_rt.want_float_exceptions and se == 0) {
+ mem.doNotOptimizeAway(x * 0x1p-120);
+ }
+ r_sin.* = x;
+ // raise inexact if x!=0
+ r_cos.* = 1.0 + x;
+ return;
+ }
+ r_sin.* = trig.sinx(x, 0.0, 0);
+ r_cos.* = trig.cosx(x, 0.0);
+ return;
+ }
-pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void {
- switch (@typeInfo(c_longdouble).float.bits) {
- 16 => return __sincosh(x, r_sin, r_cos),
- 32 => return sincosf(x, r_sin, r_cos),
- 64 => return sincos(x, r_sin, r_cos),
- 80 => return __sincosx(x, r_sin, r_cos),
- 128 => return sincosq(x, r_sin, r_cos),
- else => @compileError("unreachable"),
+ var y: [2]f80 = undefined;
+ const n = rem_pio2l(f80, x, &y);
+ const s = trig.sinx(y[0], y[1], 1);
+ const c = trig.cosx(y[0], y[1]);
+ switch (n & 3) {
+ 0 => {
+ r_sin.* = s;
+ r_cos.* = c;
+ },
+ 1 => {
+ r_sin.* = c;
+ r_cos.* = -s;
+ },
+ 2 => {
+ r_sin.* = -s;
+ r_cos.* = -c;
+ },
+ else => {
+ r_sin.* = -c;
+ r_cos.* = s;
+ },
}
}
-pub const rem_pio2_generic = @compileError("TODO");
-
-/// Ported from musl sincosl.c. Needs the following dependencies to be complete:
-/// * rem_pio2_generic ported from __rem_pio2l.c
-/// * trig.sin_generic ported from __sinl.c
-/// * trig.cos_generic ported from __cosl.c
-inline fn sincos_generic(comptime F: type, x: F, r_sin: *F, r_cos: *F) void {
- const sc1pio4: F = 1.0 * math.pi / 4.0;
- const bits = @typeInfo(F).float.bits;
- const I = std.meta.Int(.unsigned, bits);
- const ix = @as(I, @bitCast(x)) & (math.maxInt(I) >> 1);
- const se: u16 = @truncate(ix >> (bits - 16));
-
+pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.c) void {
+ const se = ld.signExponent(x) & 0x7fff;
if (se == 0x7fff) {
const result = x - x;
r_sin.* = result;
@@ -239,26 +250,26 @@ inline fn sincos_generic(comptime F: type, x: F, r_sin: *F, r_cos: *F) void {
return;
}
- if (@as(F, @bitCast(ix)) < sc1pio4) {
- if (se < 0x3fff - math.floatFractionalBits(F) - 1) {
+ if (@abs(x) < trig.pi_4) {
+ if (se < 0x3fff - math.floatMantissaBits(f128)) {
// raise underflow if subnormal
- if (se == 0) {
- if (compiler_rt.want_float_exceptions) mem.doNotOptimizeAway(x * 0x1p-120);
+ if (compiler_rt.want_float_exceptions and se == 0) {
+ mem.doNotOptimizeAway(x * 0x1p-120);
}
r_sin.* = x;
// raise inexact if x!=0
r_cos.* = 1.0 + x;
return;
}
- r_sin.* = trig.sin_generic(F, x, 0, 0);
- r_cos.* = trig.cos_generic(F, x, 0);
+ r_sin.* = trig.sinq(x, 0.0, 0);
+ r_cos.* = trig.cosq(x, 0.0);
return;
}
- var y: [2]F = undefined;
- const n = rem_pio2_generic(F, x, &y);
- const s = trig.sin_generic(F, y[0], y[1], 1);
- const c = trig.cos_generic(F, y[0], y[1]);
+ var y: [2]f128 = undefined;
+ const n = rem_pio2l(f128, x, &y);
+ const s = trig.sinq(y[0], y[1], 1);
+ const c = trig.cosq(y[0], y[1]);
switch (n & 3) {
0 => {
r_sin.* = s;
@@ -278,3 +289,199 @@ inline fn sincos_generic(comptime F: type, x: F, r_sin: *F, r_cos: *F) void {
},
}
}
+
+pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.c) void {
+ switch (@typeInfo(c_longdouble).float.bits) {
+ 16 => return sincosh(x, r_sin, r_cos),
+ 32 => return sincosf(x, r_sin, r_cos),
+ 64 => return sincos(x, r_sin, r_cos),
+ 80 => return sincosx(x, r_sin, r_cos),
+ 128 => return sincosq(x, r_sin, r_cos),
+ else => @compileError("unreachable"),
+ }
+}
+
+fn testSincosSpecial(comptime T: type) !void {
+ const f = switch (T) {
+ f32 => sincosf,
+ f64 => sincos,
+ f80 => sincosx,
+ f128 => sincosq,
+ else => @compileError("unimplemented"),
+ };
+
+ var s: T = undefined;
+ var c: T = undefined;
+
+ f(0.0, &s, &c);
+ try expect(math.isPositiveZero(s));
+ try expect(c == 1.0);
+
+ f(-0.0, &s, &c);
+ try expect(math.isNegativeZero(s));
+ try expect(c == 1.0);
+
+ f(math.inf(T), &s, &c);
+ try expect(math.isNan(s));
+ try expect(math.isNan(c));
+
+ f(-math.inf(T), &s, &c);
+ try expect(math.isNan(s));
+ try expect(math.isNan(c));
+
+ f(math.nan(T), &s, &c);
+ try expect(math.isNan(s));
+ try expect(math.isNan(c));
+}
+
+test "sincos32.normal" {
+ const epsilon = math.floatEps(f32);
+ var s: f32 = undefined;
+ var c: f32 = undefined;
+
+ sincosf(0.0, &s, &c);
+ try expectApproxEqAbs(@as(f32, 0.0), s, epsilon);
+ try expectApproxEqAbs(@as(f32, 1.0), c, epsilon);
+
+ sincosf(0.2, &s, &c);
+ try expectApproxEqAbs(@as(f32, 0.19866933), s, epsilon);
+ try expectApproxEqAbs(@as(f32, 0.9800666), c, epsilon);
+
+ sincosf(0.8923, &s, &c);
+ try expectApproxEqAbs(@as(f32, 0.77851737), s, epsilon);
+ try expectApproxEqAbs(@as(f32, 0.6276231), c, epsilon);
+
+ sincosf(1.5, &s, &c);
+ try expectApproxEqAbs(@as(f32, 0.997495), s, epsilon);
+ try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon);
+
+ sincosf(-1.5, &s, &c);
+ try expectApproxEqAbs(@as(f32, -0.997495), s, epsilon);
+ try expectApproxEqAbs(@as(f32, 0.0707372), c, epsilon);
+
+ sincosf(37.45, &s, &c);
+ try expectApproxEqAbs(@as(f32, -0.24654257), s, epsilon);
+ try expectApproxEqAbs(@as(f32, 0.96913195), c, epsilon);
+
+ sincosf(89.123, &s, &c);
+ try expectApproxEqAbs(@as(f32, 0.9161657), s, epsilon);
+ try expectApproxEqAbs(@as(f32, 0.40079966), c, epsilon);
+}
+
+test "sincos32.special" {
+ try testSincosSpecial(f32);
+}
+
+test "sincos64.normal" {
+ const epsilon = math.floatEps(f64);
+ var s: f64 = undefined;
+ var c: f64 = undefined;
+
+ sincos(0.0, &s, &c);
+ try expectApproxEqAbs(@as(f64, 0.0), s, epsilon);
+ try expectApproxEqAbs(@as(f64, 1.0), c, epsilon);
+
+ sincos(0.2, &s, &c);
+ try expectApproxEqAbs(@as(f64, 0.19866933079506122), s, epsilon);
+ try expectApproxEqAbs(@as(f64, 0.9800665778412416), c, epsilon);
+
+ sincos(0.8923, &s, &c);
+ try expectApproxEqAbs(@as(f64, 0.7785173385577349), s, epsilon);
+ try expectApproxEqAbs(@as(f64, 0.6276230983360804), c, epsilon);
+
+ sincos(1.5, &s, &c);
+ try expectApproxEqAbs(@as(f64, 0.9974949866040544), s, epsilon);
+ try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon);
+
+ sincos(-1.5, &s, &c);
+ try expectApproxEqAbs(@as(f64, -0.9974949866040544), s, epsilon);
+ try expectApproxEqAbs(@as(f64, 0.0707372016677029), c, epsilon);
+
+ sincos(37.45, &s, &c);
+ try expectApproxEqAbs(@as(f64, -0.24654331551411082), s, epsilon);
+ try expectApproxEqAbs(@as(f64, 0.9691317730707778), c, epsilon);
+
+ sincos(89.123, &s, &c);
+ try expectApproxEqAbs(@as(f64, 0.9161652766622714), s, epsilon);
+ try expectApproxEqAbs(@as(f64, 0.4008006809354791), c, epsilon);
+}
+
+test "sincos64.special" {
+ try testSincosSpecial(f64);
+}
+
+test "sincos80.normal" {
+ const epsilon = math.floatEps(f80);
+ var s: f80 = undefined;
+ var c: f80 = undefined;
+
+ sincosx(0.0, &s, &c);
+ try expectApproxEqAbs(@as(f80, 0.0), s, epsilon);
+ try expectApproxEqAbs(@as(f80, 1.0), c, epsilon);
+
+ sincosx(0.2, &s, &c);
+ try expectApproxEqAbs(@as(f80, 0.19866933079506121545941262711838975), s, epsilon);
+ try expectApproxEqAbs(@as(f80, 0.98006657784124163112419651674816888), c, epsilon);
+
+ sincosx(0.8923, &s, &c);
+ try expectApproxEqAbs(@as(f80, 0.77851733855773487830689285621486050), s, epsilon);
+ try expectApproxEqAbs(@as(f80, 0.62762309833608037003563995939286067), c, epsilon);
+
+ sincosx(1.5, &s, &c);
+ try expectApproxEqAbs(@as(f80, 0.99749498660405443094172337114148732), s, epsilon);
+ try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon);
+
+ sincosx(-1.5, &s, &c);
+ try expectApproxEqAbs(@as(f80, -0.99749498660405443094172337114148732), s, epsilon);
+ try expectApproxEqAbs(@as(f80, 0.070737201667702910088189851434268747), c, epsilon);
+
+ sincosx(37.45, &s, &c);
+ try expectApproxEqAbs(@as(f80, -0.24654331551411356504), s, epsilon);
+ try expectApproxEqAbs(@as(f80, 0.9691317730707771246), c, epsilon);
+
+ sincosx(89.123, &s, &c);
+ try expectApproxEqAbs(@as(f80, 0.91616527666226951006), s, epsilon);
+ try expectApproxEqAbs(@as(f80, 0.4008006809354834001), c, epsilon);
+}
+
+test "sincos80.special" {
+ try testSincosSpecial(f80);
+}
+
+test "sincos128.normal" {
+ const epsilon = math.floatEps(f128);
+ var s: f128 = undefined;
+ var c: f128 = undefined;
+
+ sincosq(0.0, &s, &c);
+ try expectApproxEqAbs(@as(f128, 0.0), s, epsilon);
+ try expectApproxEqAbs(@as(f128, 1.0), c, epsilon);
+
+ sincosq(0.2, &s, &c);
+ try expectApproxEqAbs(@as(f128, 0.19866933079506121545941262711838975), s, epsilon);
+ try expectApproxEqAbs(@as(f128, 0.98006657784124163112419651674816888), c, epsilon);
+
+ sincosq(0.8923, &s, &c);
+ try expectApproxEqAbs(@as(f128, 0.77851733855773487830689285621486050), s, epsilon);
+ try expectApproxEqAbs(@as(f128, 0.62762309833608037003563995939286067), c, epsilon);
+
+ sincosq(1.5, &s, &c);
+ try expectApproxEqAbs(@as(f128, 0.99749498660405443094172337114148732), s, epsilon);
+ try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon);
+
+ sincosq(-1.5, &s, &c);
+ try expectApproxEqAbs(@as(f128, -0.99749498660405443094172337114148732), s, epsilon);
+ try expectApproxEqAbs(@as(f128, 0.070737201667702910088189851434268747), c, epsilon);
+
+ sincosq(37.45, &s, &c);
+ try expectApproxEqAbs(@as(f128, -0.24654331551411356571238581321661085), s, epsilon);
+ try expectApproxEqAbs(@as(f128, 0.96913177307077712443149563847233230), c, epsilon);
+
+ sincosq(89.123, &s, &c);
+ try expectApproxEqAbs(@as(f128, 0.91616527666226951075019849560482170), s, epsilon);
+ try expectApproxEqAbs(@as(f128, 0.40080068093548339848199454493704702), c, epsilon);
+}
+
+test "sincos128.special" {
+ try testSincosSpecial(f128);
+}
diff --git a/lib/compiler_rt/tan.zig b/lib/compiler_rt/tan.zig
@@ -3,6 +3,7 @@
//!
//! https://git.musl-libc.org/cgit/musl/tree/src/math/tanf.c
//! https://git.musl-libc.org/cgit/musl/tree/src/math/tan.c
+//! https://git.musl-libc.org/cgit/musl/tree/src/math/tanl.c
//! https://golang.org/src/math/tan.go
const std = @import("std");
@@ -10,20 +11,23 @@ const builtin = @import("builtin");
const math = std.math;
const mem = std.mem;
const expect = std.testing.expect;
+const expectApproxEqAbs = std.testing.expectApproxEqAbs;
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 ld = @import("long_double.zig");
const arch = builtin.cpu.arch;
const compiler_rt = @import("../compiler_rt.zig");
const symbol = @import("../compiler_rt.zig").symbol;
comptime {
- symbol(&__tanh, "__tanh");
+ symbol(&tanh, "__tanh");
symbol(&tanf, "tanf");
symbol(&tan, "tan");
- symbol(&__tanx, "__tanx");
+ symbol(&tanx, "__tanx");
if (compiler_rt.want_ppc_abi) {
symbol(&tanq, "tanf128");
}
@@ -31,7 +35,7 @@ comptime {
symbol(&tanl, "tanl");
}
-pub fn __tanh(x: f16) callconv(.c) f16 {
+pub fn tanh(x: f16) callconv(.c) f16 {
// TODO: more efficient implementation
return @floatCast(tanf(x));
}
@@ -59,20 +63,20 @@ pub fn tanf(x: f32) callconv(.c) f32 {
}
return x;
}
- return kernel.__tandf(x, false);
+ return kernel.tandf(x, false);
}
if (ix <= 0x407b53d1) { // |x| ~<= 5*pi/4
if (ix <= 0x4016cbe3) { // |x| ~<= 3pi/4
- return kernel.__tandf((if (sign) x + t1pio2 else x - t1pio2), true);
+ return kernel.tandf((if (sign) x + t1pio2 else x - t1pio2), true);
} else {
- return kernel.__tandf((if (sign) x + t2pio2 else x - t2pio2), false);
+ return kernel.tandf((if (sign) x + t2pio2 else x - t2pio2), false);
}
}
if (ix <= 0x40e231d5) { // |x| ~<= 9*pi/4
if (ix <= 0x40afeddf) { // |x| ~<= 7*pi/4
- return kernel.__tandf((if (sign) x + t3pio2 else x - t3pio2), true);
+ return kernel.tandf((if (sign) x + t3pio2 else x - t3pio2), true);
} else {
- return kernel.__tandf((if (sign) x + t4pio2 else x - t4pio2), false);
+ return kernel.tandf((if (sign) x + t4pio2 else x - t4pio2), false);
}
}
@@ -83,7 +87,7 @@ pub fn tanf(x: f32) callconv(.c) f32 {
var y: f64 = undefined;
const n = rem_pio2f(x, &y);
- return kernel.__tandf(y, n & 1 != 0);
+ return kernel.tandf(y, n & 1 != 0);
}
pub fn tan(x: f64) callconv(.c) f64 {
@@ -103,7 +107,7 @@ pub fn tan(x: f64) callconv(.c) f64 {
}
return x;
}
- return kernel.__tan(x, 0.0, false);
+ return kernel.tan(x, 0.0, false);
}
// tan(Inf or NaN) is NaN
@@ -113,69 +117,136 @@ pub fn tan(x: f64) callconv(.c) f64 {
var y: [2]f64 = undefined;
const n = rem_pio2(x, &y);
- return kernel.__tan(y[0], y[1], n & 1 != 0);
+ return kernel.tan(y[0], y[1], n & 1 != 0);
}
-pub fn __tanx(x: f80) callconv(.c) f80 {
- // TODO: more efficient implementation
- return @floatCast(tanq(x));
+pub fn tanx(x: f80) callconv(.c) f80 {
+ const se = ld.signExponent(x) & 0x7fff;
+ if (se == 0x7fff) {
+ return x - x;
+ }
+
+ if (@abs(x) < kernel.pi_4) {
+ if (se < 0x3fff - math.floatMantissaBits(f80) / 2) {
+ if (compiler_rt.want_float_exceptions) {
+ mem.doNotOptimizeAway(if (se == 0) x * 0x1p-120 else x + 0x1p120);
+ }
+ return x;
+ }
+ return kernel.tanx(x, 0.0, 0);
+ }
+
+ var y: [2]f80 = undefined;
+ const n = rem_pio2l(f80, x, &y);
+ return kernel.tanx(y[0], y[1], n & 1);
}
pub fn tanq(x: f128) callconv(.c) f128 {
- // TODO: more correct implementation
- return tan(@floatCast(x));
+ const se = ld.signExponent(x) & 0x7fff;
+ if (se == 0x7fff) {
+ return x - x;
+ }
+
+ if (@abs(x) < kernel.pi_4) {
+ if (se < 0x3fff - math.floatMantissaBits(f128) / 2) {
+ if (compiler_rt.want_float_exceptions) {
+ mem.doNotOptimizeAway(if (se == 0) x * 0x1p-120 else x + 0x1p120);
+ }
+ return x;
+ }
+ return kernel.tanq(x, 0.0, 0);
+ }
+
+ var y: [2]f128 = undefined;
+ const n = rem_pio2l(f128, x, &y);
+ return kernel.tanq(y[0], y[1], n & 1);
}
pub fn tanl(x: c_longdouble) callconv(.c) c_longdouble {
switch (@typeInfo(c_longdouble).float.bits) {
- 16 => return __tanh(x),
+ 16 => return tanh(x),
32 => return tanf(x),
64 => return tan(x),
- 80 => return __tanx(x),
+ 80 => return tanx(x),
128 => return tanq(x),
else => @compileError("unreachable"),
}
}
-test "tan" {
- try expect(tan(@as(f32, 0.0)) == tanf(0.0));
- try expect(tan(@as(f64, 0.0)) == tan(0.0));
+fn testTanNormal(comptime T: type) !void {
+ const f = switch (T) {
+ f32 => tanf,
+ f64 => tan,
+ else => @compileError("unimplemented"),
+ };
+ const epsilon = 0.00001;
+
+ try expectApproxEqAbs(@as(T, 0.0), f(0.0), epsilon);
+ try expectApproxEqAbs(@as(T, 0.202710), f(0.2), epsilon);
+ try expectApproxEqAbs(@as(T, 1.240422), f(0.8923), epsilon);
+ try expectApproxEqAbs(@as(T, 14.101420), f(1.5), epsilon);
+ try expectApproxEqAbs(@as(T, -0.254397), f(37.45), epsilon);
+ try expectApproxEqAbs(@as(T, 2.285837), f(89.123), epsilon);
+}
+
+fn testTanSpecial(comptime T: type) !void {
+ const f = switch (T) {
+ f32 => tanf,
+ f64 => tan,
+ f80 => tanx,
+ f128 => tanq,
+ else => @compileError("unimplemented"),
+ };
+
+ try expect(math.isPositiveZero(f(0.0)));
+ try expect(math.isNegativeZero(f(-0.0)));
+ try expect(math.isNan(f(math.inf(f32))));
+ try expect(math.isNan(f(-math.inf(f32))));
+ try expect(math.isNan(f(math.nan(f32))));
}
-test "tan32" {
- const epsilon = 0.00001;
+test "tan32.normal" {
+ try testTanNormal(f32);
+}
+
+test "tan64.normal" {
+ try testTanNormal(f64);
+}
+
+test "tan80.normal" {
+ const epsilon = math.floatEps(f80);
- try expect(math.approxEqAbs(f32, tanf(0.0), 0.0, epsilon));
- try expect(math.approxEqAbs(f32, tanf(0.2), 0.202710, epsilon));
- try expect(math.approxEqAbs(f32, tanf(0.8923), 1.240422, epsilon));
- try expect(math.approxEqAbs(f32, tanf(1.5), 14.101420, epsilon));
- try expect(math.approxEqAbs(f32, tanf(37.45), -0.254397, epsilon));
- try expect(math.approxEqAbs(f32, tanf(89.123), 2.285852, epsilon));
+ try expectApproxEqAbs(@as(f80, 0.0), tanx(0.0), epsilon);
+ try expectApproxEqAbs(@as(f80, 0.2027100355086724833213582716475345), tanx(0.2), epsilon);
+ try expectApproxEqAbs(@as(f80, 1.2404217445497097995561220131857544), tanx(0.8923), epsilon);
+ try expectApproxEqAbs(@as(f80, 14.10141994717171938764), tanx(1.5), epsilon);
+ try expectApproxEqAbs(@as(f80, -0.25439607116885656232), tanx(37.45), epsilon);
+ try expectApproxEqAbs(@as(f80, 2.2858376251355320963), tanx(89.123), epsilon);
}
-test "tan64" {
- const epsilon = 0.000001;
+test "tan128.normal" {
+ const epsilon = math.floatEps(f128);
- try expect(math.approxEqAbs(f64, tan(0.0), 0.0, epsilon));
- try expect(math.approxEqAbs(f64, tan(0.2), 0.202710, epsilon));
- try expect(math.approxEqAbs(f64, tan(0.8923), 1.240422, epsilon));
- try expect(math.approxEqAbs(f64, tan(1.5), 14.101420, epsilon));
- try expect(math.approxEqAbs(f64, tan(37.45), -0.254397, epsilon));
- try expect(math.approxEqAbs(f64, tan(89.123), 2.2858376, epsilon));
+ try expectApproxEqAbs(@as(f128, 0.0), tanq(0.0), epsilon);
+ try expectApproxEqAbs(@as(f128, 0.2027100355086724833213582716475345), tanq(0.2), epsilon);
+ try expectApproxEqAbs(@as(f128, 1.2404217445497097995561220131857544), tanq(0.8923), epsilon);
+ try expectApproxEqAbs(@as(f128, 14.101419947171719387646083651987755), tanq(1.5), epsilon);
+ try expectApproxEqAbs(@as(f128, -0.2543960711688565630469573224504774), tanq(37.45), epsilon);
+ try expectApproxEqAbs(@as(f128, 2.2858376251355321074066028114094292), tanq(89.123), epsilon);
}
test "tan32.special" {
- try expect(tanf(0.0) == 0.0);
- try expect(tanf(-0.0) == -0.0);
- try expect(math.isNan(tanf(math.inf(f32))));
- try expect(math.isNan(tanf(-math.inf(f32))));
- try expect(math.isNan(tanf(math.nan(f32))));
+ try testTanSpecial(f32);
}
test "tan64.special" {
- try expect(tan(0.0) == 0.0);
- try expect(tan(-0.0) == -0.0);
- try expect(math.isNan(tan(math.inf(f64))));
- try expect(math.isNan(tan(-math.inf(f64))));
- try expect(math.isNan(tan(math.nan(f64))));
+ try testTanSpecial(f64);
+}
+
+test "tan80.special" {
+ try testTanSpecial(f80);
+}
+
+test "tan128.special" {
+ try testTanSpecial(f128);
}
diff --git a/lib/compiler_rt/trig.zig b/lib/compiler_rt/trig.zig
@@ -7,6 +7,13 @@
// https://git.musl-libc.org/cgit/musl/tree/src/math/__sindf.c
// https://git.musl-libc.org/cgit/musl/tree/src/math/__tand.c
// https://git.musl-libc.org/cgit/musl/tree/src/math/__tandf.c
+// https://git.musl-libc.org/cgit/musl/tree/src/math/__sinl.c
+// https://git.musl-libc.org/cgit/musl/tree/src/math/__cosl.c
+// https://git.musl-libc.org/cgit/musl/tree/src/math/__tanl.c
+
+const std = @import("std");
+
+pub const pi_4 = std.math.pi / 4.0;
/// kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
/// Input x is assumed to be bounded by ~pi/4 in magnitude.
@@ -43,7 +50,7 @@
/// expression for cos(). Retention happens in all cases tested
/// under FreeBSD, so don't pessimize things by forcibly clipping
/// any extra precision in w.
-pub fn __cos(x: f64, y: f64) f64 {
+pub fn cos(x: f64, y: f64) f64 {
const C1 = 4.16666666666666019037e-02; // 0x3FA55555, 0x5555554C
const C2 = -1.38888888888741095749e-03; // 0xBF56C16C, 0x16C15177
const C3 = 2.48015872894767294178e-05; // 0x3EFA01A0, 0x19CB1590
@@ -59,7 +66,7 @@ pub fn __cos(x: f64, y: f64) f64 {
return w + (((1.0 - w) - hz) + (z * r - x * y));
}
-pub fn __cosdf(x: f64) f32 {
+pub fn cosdf(x: f64) f32 {
// |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]).
const C0 = -0x1ffffffd0c5e81.0p-54; // -0.499999997251031003120
const C1 = 0x155553e1053a42.0p-57; // 0.0416666233237390631894
@@ -73,6 +80,46 @@ pub fn __cosdf(x: f64) f32 {
return @floatCast(((1.0 + z * C0) + w * C1) + (w * z) * r);
}
+pub fn cosx(x: f80, y: f80) f80 {
+ const C1: f80 = 0.0416666666666666666136;
+ const C2: f64 = -0.0013888888888888874;
+ const C3: f64 = 0.000024801587301571716;
+ const C4: f64 = -0.00000027557319215507120;
+ const C5: f64 = 0.0000000020876754400407278;
+ const C6: f64 = -1.1470297442401303e-11;
+ const C7: f64 = 4.7383039476436467e-14;
+
+ const z = x * x;
+ const r = z * (C1 + z * (C2 + z * (C3 + z * (C4 +
+ z * (C5 + z * (C6 + z * C7))))));
+ const hz = 0.5 * z;
+ const w = 1.0 - hz;
+
+ return w + (((1.0 - w) - hz) + (z * r - x * y));
+}
+
+pub fn cosq(x: f128, y: f128) f128 {
+ const C1: f128 = 0.04166666666666666666666666666666658424671;
+ const C2: f128 = -0.001388888888888888888888888888863490893732;
+ const C3: f128 = 0.00002480158730158730158730158600795304914210;
+ const C4: f128 = -0.2755731922398589065255474947078934284324e-6;
+ const C5: f128 = 0.2087675698786809897659225313136400793948e-8;
+ const C6: f128 = -0.1147074559772972315817149986812031204775e-10;
+ const C7: f128 = 0.4779477332386808976875457937252120293400e-13;
+ const C8: f64 = -0.1561920696721507929516718307820958119868e-15;
+ const C9: f64 = 0.4110317413744594971475941557607804508039e-18;
+ const C10: f64 = -0.8896592467191938803288521958313920156409e-21;
+ const C11: f64 = 0.1601061435794535138244346256065192782581e-23;
+
+ const z = x * x;
+ const r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * (C6 +
+ z * (C7 + z * (C8 + z * (C9 + z * (C10 + z * C11))))))))));
+ const hz = 0.5 * z;
+ const w = 1.0 - hz;
+
+ return w + (((1.0 - w) - hz) + (z * r - x * y));
+}
+
/// kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
/// Input x is assumed to be bounded by ~pi/4 in magnitude.
/// Input y is the tail of x.
@@ -100,7 +147,7 @@ pub fn __cosdf(x: f64) f32 {
/// r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
/// then 3 2
/// sin(x) = x + (S1*x + (x *(r-y/2)+y))
-pub fn __sin(x: f64, y: f64, iy: i32) f64 {
+pub fn sin(x: f64, y: f64, iy: i32) f64 {
const S1 = -1.66666666666666324348e-01; // 0xBFC55555, 0x55555549
const S2 = 8.33333333332248946124e-03; // 0x3F811111, 0x1110F8A6
const S3 = -1.98412698298579493134e-04; // 0xBF2A01A0, 0x19C161D5
@@ -119,7 +166,7 @@ pub fn __sin(x: f64, y: f64, iy: i32) f64 {
}
}
-pub fn __sindf(x: f64) f32 {
+pub fn sindf(x: f64) f32 {
// |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]).
const S1 = -0x15555554cbac77.0p-55; // -0.166666666416265235595
const S2 = 0x111110896efbb2.0p-59; // 0.0083333293858894631756
@@ -134,6 +181,52 @@ pub fn __sindf(x: f64) f32 {
return @floatCast((x + s * (S1 + z * S2)) + s * w * r);
}
+pub fn sinx(x: f80, y: f80, iy: i32) f80 {
+ const S1: f80 = -0.166666666666666666671;
+ const S2: f64 = 0.0083333333333333332;
+ const S3: f64 = -0.00019841269841269427;
+ const S4: f64 = 0.0000027557319223597490;
+ const S5: f64 = -0.000000025052108218074604;
+ const S6: f64 = 1.6059006598854211e-10;
+ const S7: f64 = -7.6429779983024564e-13;
+ const S8: f64 = 2.6174587166648325e-15;
+
+ const z = x * x;
+ const v = z * x;
+ const r = S2 + z * (S3 + z * (S4 + z * (S5 +
+ z * (S6 + z * (S7 + z * S8)))));
+
+ if (iy == 0)
+ return x + v * (S1 + z * r);
+
+ return x - ((z * (0.5 * y - v * r) - y) - v * S1);
+}
+
+pub fn sinq(x: f128, y: f128, iy: i32) f128 {
+ const S1: f128 = -0.16666666666666666666666666666666666606732416116558;
+ const S2: f128 = 0.0083333333333333333333333333333331135404851288270047;
+ const S3: f128 = -0.00019841269841269841269841269839935785325638310428717;
+ const S4: f128 = 0.27557319223985890652557316053039946268333231205686e-5;
+ const S5: f128 = -0.25052108385441718775048214826384312253862930064745e-7;
+ const S6: f128 = 0.16059043836821614596571832194524392581082444805729e-9;
+ const S7: f128 = -0.76471637318198151807063387954939213287488216303768e-12;
+ const S8: f128 = 0.28114572543451292625024967174638477283187397621303e-14;
+ const S9: f64 = -0.82206352458348947812512122163446202498005154296863e-17;
+ const S10: f64 = 0.19572940011906109418080609928334380560135358385256e-19;
+ const S11: f64 = -0.38680813379701966970673724299207480965452616911420e-22;
+ const S12: f64 = 0.64038150078671872796678569586315881020659912139412e-25;
+
+ const z = x * x;
+ const v = z * x;
+ const r = S2 + z * (S3 + z * (S4 + z * (S5 + z * (S6 + z * (S7 + z * (S8 +
+ z * (S9 + z * (S10 + z * (S11 + z * S12)))))))));
+
+ if (iy == 0)
+ return x + v * (S1 + z * r);
+
+ return x - ((z * (0.5 * y - v * r) - y) - v * S1);
+}
+
/// kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
/// Input x is assumed to be bounded by ~pi/4 in magnitude.
/// Input y is the tail of x.
@@ -166,7 +259,7 @@ pub fn __sindf(x: f64) f32 {
/// 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
/// tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
/// = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
-pub fn __tan(x_: f64, y_: f64, odd: bool) f64 {
+pub fn tan(x_: f64, y_: f64, odd: bool) f64 {
var x = x_;
var y = y_;
@@ -239,7 +332,7 @@ pub fn __tan(x_: f64, y_: f64, odd: bool) f64 {
return a0 + a * (1.0 + a0 * w0 + a0 * v);
}
-pub fn __tandf(x: f64, odd: bool) f32 {
+pub fn tandf(x: f64, odd: bool) f32 {
// |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]).
const T = [_]f64{
0x15554d3418c99f.0p-54, // 0.333331395030791399758
@@ -271,3 +364,160 @@ pub fn __tandf(x: f64, odd: bool) f32 {
const r0 = (x + s * u) + (s * w) * (t + w * r);
return @floatCast(if (odd) -1.0 / r0 else r0);
}
+
+pub fn tanx(x_: f80, y_: f80, odd: i32) f80 {
+ const pio4: f80 = 0.785398163397448309628;
+ const pio4lo: f80 = -1.25413940316708300586e-20;
+
+ const T3: f80 = 0.333333333333333333180;
+ const T5: f80 = 0.133333333333333372290;
+ const T7: f80 = 0.0539682539682504975744;
+ const T9: f64 = 0.021869488536312216;
+ const T11: f64 = 0.0088632355256619590;
+ const T13: f64 = 0.0035921281113786528;
+ const T15: f64 = 0.0014558334756312418;
+ const T17: f64 = 0.00059003538700862256;
+ const T19: f64 = 0.00023907843576635544;
+ const T21: f64 = 0.000097154625656538905;
+ const T23: f64 = 0.000038440165747303162;
+ const T25: f64 = 0.000018082171885432524;
+ const T27: f64 = 0.0000024196006108814377;
+ const T29: f64 = 0.0000078293456938132840;
+ const T31: f64 = -0.0000032609076735050182;
+ const T33: f64 = 0.0000023261313142559411;
+
+ var x = x_;
+ var y = y_;
+ const big = @abs(x) >= 0.67434;
+ var sign: i8 = 0;
+
+ if (big) {
+ if (x < 0) {
+ sign = -1;
+ x = -x;
+ y = -y;
+ }
+ x = (pio4 - x) + (pio4lo - y);
+ y = 0.0;
+ }
+
+ var z = x * x;
+ var w = z * z;
+
+ var r = T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 +
+ w * (T25 + w * (T29 + w * T33))))));
+
+ var v = z * (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 +
+ w * (T27 + w * T31))))));
+
+ var s = z * x;
+ r = y + z * (s * (r + v) + y) + T3 * s;
+ w = x + r;
+
+ if (big) {
+ s = @as(f80, @floatFromInt(1 - 2 * odd));
+ v = s - 2.0 * (x + (r - w * w / (w + s)));
+ return if (sign == -1) -v else v;
+ }
+
+ if (odd == 0) {
+ return w;
+ }
+
+ // if allow error up to 2 ulp, simply return
+ // -1.0 / (x+r) here
+ //
+ // compute -1.0 / (x+r) accurately
+ z = w + 0x1p32 - 0x1p32;
+ v = r - (z - x);
+ const a = -1.0 / w;
+ const t = a + 0x1p32 - 0x1p32;
+ s = 1.0 + t * z;
+ return t + a * (s + t * v);
+}
+
+pub fn tanq(x_: f128, y_: f128, odd: i32) f128 {
+ const pio4: f128 = 0x1.921fb54442d18469898cc51701b8p-1;
+ const pio4lo: f128 = 0x1.cd129024e088a67cc74020bbea60p-116;
+
+ const T3: f128 = 0x1.5555555555555555555555555553p-2;
+ const T5: f128 = 0x1.1111111111111111111111111eb5p-3;
+ const T7: f128 = 0x1.ba1ba1ba1ba1ba1ba1ba1b694cd6p-5;
+ const T9: f128 = 0x1.664f4882c10f9f32d6bbe09d8bcdp-6;
+ const T11: f128 = 0x1.226e355e6c23c8f5b4f5762322eep-7;
+ const T13: f128 = 0x1.d6d3d0e157ddfb5fed8e84e27b37p-9;
+ const T15: f128 = 0x1.7da36452b75e2b5fce9ee7c2c92ep-10;
+ const T17: f128 = 0x1.355824803674477dfcf726649efep-11;
+ const T19: f128 = 0x1.f57d7734d1656e0aceb716f614c2p-13;
+ const T21: f128 = 0x1.967e18afcb180ed942dfdc518d6cp-14;
+ const T23: f128 = 0x1.497d8eea21e95bc7e2aa79b9f2cdp-15;
+ const T25: f128 = 0x1.0b132d39f055c81be49eff7afd50p-16;
+ const T27: f128 = 0x1.b0f72d33eff7bfa2fbc1059d90b6p-18;
+ const T29: f128 = 0x1.5ef2daf21d1113df38d0fbc00267p-19;
+ const T31: f128 = 0x1.1c77d6eac0234988cdaa04c96626p-20;
+ const T33: f128 = 0x1.cd2a5a292b180e0bdd701057dfe3p-22;
+ const T35: f128 = 0x1.75c7357d0298c01a31d0a6f7d518p-23;
+ const T37: f128 = 0x1.2f3190f4718a9a520f98f50081fcp-24;
+ const T39: f64 = 0.000000028443389121318352;
+ const T41: f64 = 0.000000011981013102001973;
+ const T43: f64 = 0.0000000038303578044958070;
+ const T45: f64 = 0.0000000034664378216909893;
+ const T47: f64 = -0.0000000015090641701997785;
+ const T49: f64 = 0.0000000029449552300483952;
+ const T51: f64 = -0.0000000022006995706097711;
+ const T53: f64 = 0.0000000015468200913196612;
+ const T55: f64 = -0.00000000061311613386849674;
+ const T57: f64 = 1.4912469681508012e-10;
+
+ var x = x_;
+ var y = y_;
+
+ const big = @abs(x) >= 0.67434;
+ var sign: i8 = 0;
+
+ if (big) {
+ if (x < 0) {
+ sign = -1;
+ x = -x;
+ y = -y;
+ }
+ x = (pio4 - x) + (pio4lo - y);
+ y = 0.0;
+ }
+
+ var z = x * x;
+ var w = z * z;
+
+ var r = T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 +
+ w * (T25 + w * (T29 + w * (T33 + w * (T37 + w * (T41 +
+ w * (T45 + w * (T49 + w * (T53 + w * T57))))))))))));
+
+ var v = z * (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 +
+ w * (T27 + w * (T31 + w * (T35 + w * (T39 + w * (T43 +
+ w * (T47 + w * (T51 + w * T55))))))))))));
+
+ var s = z * x;
+ r = y + z * (s * (r + v) + y) + T3 * s;
+ w = x + r;
+
+ if (big) {
+ s = @as(f128, @floatFromInt(1 - 2 * odd));
+ v = s - 2.0 * (x + (r - w * w / (w + s)));
+ return if (sign == -1) -v else v;
+ }
+
+ if (odd == 0) {
+ return w;
+ }
+
+ // if allow error up to 2 ulp, simply return
+ // -1.0 / (x+r) here
+ //
+ // compute -1.0 / (x+r) accurately
+ z = w + 0x1p32 - 0x1p32;
+ v = r - (z - x);
+ const a = -1.0 / w;
+ const t = a + 0x1p32 - 0x1p32;
+ s = 1.0 + t * z;
+ return t + a * (s + t * v);
+}
diff --git a/lib/libc/mingw/math/arm-common/sincosl.c b/lib/libc/mingw/math/arm-common/sincosl.c
@@ -1,13 +0,0 @@
-/**
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER.PD within this package.
- */
-
-#include <math.h>
-
-void sincosl(long double x, long double *s, long double *c)
-{
- *s = sinl(x);
- *c = cosl(x);
-}
diff --git a/lib/libc/mingw/math/arm/sincos.S b/lib/libc/mingw/math/arm/sincos.S
@@ -1,30 +0,0 @@
-/**
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER.PD within this package.
- */
-#include <_mingw_mac.h>
-
- .file "sincos.S"
- .text
- .align 2
- /* zig patch: remove sincos symbol because sincos in compiler_rt is used instead */
- .globl __MINGW_USYMBOL(sincosl)
- .def __MINGW_USYMBOL(sincosl); .scl 2; .type 32; .endef
-__MINGW_USYMBOL(sincosl):
- push {r4, r5, r11, lr}
- add r11, sp, #8
- vpush {d8}
-
- mov r4, r0
- mov r5, r1
- vmov.f64 d8, d0
- bl sin
- vstr d0, [r4]
-
- vmov.f64 d0, d8
- bl cos
- vstr d0, [r5]
-
- vpop {d8}
- pop {r4, r5, r11, pc}
diff --git a/lib/libc/mingw/math/arm64/rint.c b/lib/libc/mingw/math/arm64/rint.c
@@ -1,12 +0,0 @@
-/**
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER.PD within this package.
- */
-#include <math.h>
-
-double rint (double x) {
- double retval = 0.0;
- __asm__ __volatile__ ("frintx %d0, %d1\n\t" : "=w" (retval) : "w" (x));
- return retval;
-}
diff --git a/lib/libc/mingw/math/arm64/rintf.c b/lib/libc/mingw/math/arm64/rintf.c
@@ -1,12 +0,0 @@
-/**
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER.PD within this package.
- */
-#include <math.h>
-
-float rintf (float x) {
- float retval = 0.0F;
- __asm__ __volatile__ ("frintx %s0, %s1\n\t" : "=w" (retval) : "w" (x));
- return retval;
-}
diff --git a/lib/libc/mingw/math/arm64/sincos.S b/lib/libc/mingw/math/arm64/sincos.S
@@ -1,32 +0,0 @@
-/**
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER.PD within this package.
- */
-#include <_mingw_mac.h>
-
- .file "sincos.S"
- .text
- .align 2
- /* zig patch: remove sincos symbol because sincos in compiler_rt is used instead */
- .globl __MINGW_USYMBOL(sincosl)
- .def __MINGW_USYMBOL(sincosl); .scl 2; .type 32; .endef
-__MINGW_USYMBOL(sincosl):
- str d8, [sp, #-32]!
- str x30, [sp, #8]
- stp x19, x20, [sp, #16]
-
- mov x19, x0
- mov x20, x1
- fmov d8, d0
- bl sin
- str d0, [x19]
-
- fmov d0, d8
- bl cos
- str d0, [x20]
-
- ldp x19, x20, [sp, #16]
- ldr x30, [sp, #8]
- ldr d8, [sp], #32
- ret
diff --git a/lib/libc/mingw/math/frexpf.c b/lib/libc/mingw/math/frexpf.c
@@ -1,13 +0,0 @@
-/**
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER.PD within this package.
- */
-extern double __cdecl frexp(double _X,int *_Y);
-
-float frexpf (float, int *);
-float frexpf (float x, int *expn)
-{
- return (float)frexp(x, expn);
-}
-
diff --git a/lib/libc/mingw/math/frexpl.c b/lib/libc/mingw/math/frexpl.c
@@ -1,71 +0,0 @@
-/**
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER.PD within this package.
- */
-long double frexpl(long double value, int* exp);
-
-#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__
-
-double frexp(double value, int* exp);
-
-/* On ARM `long double` is 64 bits. */
-long double frexpl(long double value, int* exp)
-{
- return frexp(value, exp);
-}
-
-#elif defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__)
-
-#include <stdint.h>
-
-/* https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format */
-typedef union x87reg_ {
- struct __attribute__((__packed__)) {
- uint64_t f64;
- uint16_t exp : 15;
- uint16_t sgn : 1;
- };
- long double f;
-} x87reg;
-
-long double frexpl(long double value, int* exp)
-{
- int n;
- x87reg reg;
- reg.f = value;
- if(reg.exp == 0x7FFF) {
- /* The value is an infinity or NaN.
- * Store zero in `*exp`. Return the value as is. */
- *exp = 0;
- return reg.f;
- }
- if(reg.exp != 0) {
- /* The value is normalized.
- * Extract and zero out the exponent. */
- *exp = reg.exp - 0x3FFE;
- reg.exp = 0x3FFE;
- return reg.f;
- }
- if(reg.f64 == 0) {
- /* The value is zero.
- * Store zero in `*exp`. Return the value as is.
- * Note the signness. */
- *exp = 0;
- return reg.f;
- }
- /* The value is denormalized.
- * Extract the exponent, normalize the value, then zero out
- * the exponent. Note that x87 uses an explicit leading bit. */
- n = __builtin_clzll(reg.f64);
- reg.f64 <<= n;
- *exp = 1 - 0x3FFE - n;
- reg.exp = 0x3FFE;
- return reg.f;
-}
-
-#else
-
-#error Please add `frexpl()` implementation for this platform.
-
-#endif
diff --git a/lib/libc/mingw/math/x86/cos.def.h b/lib/libc/mingw/math/x86/cos.def.h
@@ -1,65 +0,0 @@
-/*
- This Software is provided under the Zope Public License (ZPL) Version 2.1.
-
- Copyright (c) 2009, 2010 by the mingw-w64 project
-
- See the AUTHORS file for the list of contributors to the mingw-w64 project.
-
- This license has been certified as open source. It has also been designated
- as GPL compatible by the Free Software Foundation (FSF).
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions in source code must retain the accompanying copyright
- notice, this list of conditions, and the following disclaimer.
- 2. Redistributions in binary form must reproduce the accompanying
- copyright notice, this list of conditions, and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
- 3. Names of the copyright holders must not be used to endorse or promote
- products derived from this software without prior written permission
- from the copyright holders.
- 4. The right to distribute this software or to use it for any purpose does
- not give you the right to use Servicemarks (sm) or Trademarks (tm) of
- the copyright holders. Use of them is covered by separate agreement
- with the copyright holders.
- 5. If any files are modified, you must cause the modified files to carry
- prominent notices stating that you changed the files and the date of
- any change.
-
- Disclaimer
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "../complex/complex_internal.h"
-#include <errno.h>
-
-extern long double __cosl_internal (long double);
-
-__FLT_TYPE
-__FLT_ABI(cos) (__FLT_TYPE x)
-{
- int x_class = fpclassify (x);
- if (x_class == FP_NAN)
- {
- __FLT_RPT_DOMAIN ("cos", x, 0.0, x);
- return x;
- }
- else if (x_class == FP_INFINITE)
- {
- __FLT_RPT_DOMAIN ("cos", x, 0.0, __FLT_NAN);
- return __FLT_NAN;
- }
- return (__FLT_TYPE) __cosl_internal ((long double) x);
-}
diff --git a/lib/libc/mingw/math/x86/cosl.c b/lib/libc/mingw/math/x86/cosl.c
@@ -1,46 +0,0 @@
-/*
- This Software is provided under the Zope Public License (ZPL) Version 2.1.
-
- Copyright (c) 2009, 2010 by the mingw-w64 project
-
- See the AUTHORS file for the list of contributors to the mingw-w64 project.
-
- This license has been certified as open source. It has also been designated
- as GPL compatible by the Free Software Foundation (FSF).
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions in source code must retain the accompanying copyright
- notice, this list of conditions, and the following disclaimer.
- 2. Redistributions in binary form must reproduce the accompanying
- copyright notice, this list of conditions, and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
- 3. Names of the copyright holders must not be used to endorse or promote
- products derived from this software without prior written permission
- from the copyright holders.
- 4. The right to distribute this software or to use it for any purpose does
- not give you the right to use Servicemarks (sm) or Trademarks (tm) of
- the copyright holders. Use of them is covered by separate agreement
- with the copyright holders.
- 5. If any files are modified, you must cause the modified files to carry
- prominent notices stating that you changed the files and the date of
- any change.
-
- Disclaimer
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#define _NEW_COMPLEX_LDOUBLE 1
-#include "cos.def.h"
diff --git a/lib/libc/mingw/math/x86/cosl_internal.S b/lib/libc/mingw/math/x86/cosl_internal.S
@@ -1,55 +0,0 @@
-/**
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER.PD within this package.
- */
-#include <_mingw_mac.h>
-
- .file "cosl_internal.S"
- .text
-#ifdef __x86_64__
- .align 8
-#else
- .align 4
-#endif
-.globl __MINGW_USYMBOL(__cosl_internal)
- .def __MINGW_USYMBOL(__cosl_internal); .scl 2; .type 32; .endef
-__MINGW_USYMBOL(__cosl_internal):
-#ifdef __x86_64__
- fldt (%rdx)
- fcos
- fnstsw %ax
- testl $0x400,%eax
- jz 1f
- fldpi
- fadd %st(0)
- fxch %st(1)
-2: fprem1
- fnstsw %ax
- testl $0x400,%eax
- jnz 2b
- fstp %st(1)
- fcos
-1: movq %rcx,%rax
- movq $0,8(%rcx)
- fstpt (%rcx)
- ret
-#else
- fldt 4(%esp)
- fcos
- fnstsw %ax
- testl $0x400,%eax
- jnz 1f
- ret
-1: fldpi
- fadd %st(0)
- fxch %st(1)
-2: fprem1
- fnstsw %ax
- testl $0x400,%eax
- jnz 2b
- fstp %st(1)
- fcos
- ret
-#endif
-
diff --git a/lib/libc/mingw/math/x86/sin.def.h b/lib/libc/mingw/math/x86/sin.def.h
@@ -1,65 +0,0 @@
-/*
- This Software is provided under the Zope Public License (ZPL) Version 2.1.
-
- Copyright (c) 2009, 2010 by the mingw-w64 project
-
- See the AUTHORS file for the list of contributors to the mingw-w64 project.
-
- This license has been certified as open source. It has also been designated
- as GPL compatible by the Free Software Foundation (FSF).
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions in source code must retain the accompanying copyright
- notice, this list of conditions, and the following disclaimer.
- 2. Redistributions in binary form must reproduce the accompanying
- copyright notice, this list of conditions, and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
- 3. Names of the copyright holders must not be used to endorse or promote
- products derived from this software without prior written permission
- from the copyright holders.
- 4. The right to distribute this software or to use it for any purpose does
- not give you the right to use Servicemarks (sm) or Trademarks (tm) of
- the copyright holders. Use of them is covered by separate agreement
- with the copyright holders.
- 5. If any files are modified, you must cause the modified files to carry
- prominent notices stating that you changed the files and the date of
- any change.
-
- Disclaimer
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "../complex/complex_internal.h"
-#include <errno.h>
-
-extern long double __sinl_internal (long double);
-
-__FLT_TYPE
-__FLT_ABI(sin) (__FLT_TYPE x)
-{
- int x_class = fpclassify (x);
- if (x_class == FP_NAN)
- {
- __FLT_RPT_DOMAIN ("sin", x, 0.0, x);
- return x;
- }
- else if (x_class == FP_INFINITE)
- {
- __FLT_RPT_DOMAIN ("sin", x, 0.0, __FLT_NAN);
- return __FLT_NAN;
- }
- return (__FLT_TYPE) __sinl_internal ((long double) x);
-}
diff --git a/lib/libc/mingw/math/x86/sinl.c b/lib/libc/mingw/math/x86/sinl.c
@@ -1,46 +0,0 @@
-/*
- This Software is provided under the Zope Public License (ZPL) Version 2.1.
-
- Copyright (c) 2009, 2010 by the mingw-w64 project
-
- See the AUTHORS file for the list of contributors to the mingw-w64 project.
-
- This license has been certified as open source. It has also been designated
- as GPL compatible by the Free Software Foundation (FSF).
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions in source code must retain the accompanying copyright
- notice, this list of conditions, and the following disclaimer.
- 2. Redistributions in binary form must reproduce the accompanying
- copyright notice, this list of conditions, and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
- 3. Names of the copyright holders must not be used to endorse or promote
- products derived from this software without prior written permission
- from the copyright holders.
- 4. The right to distribute this software or to use it for any purpose does
- not give you the right to use Servicemarks (sm) or Trademarks (tm) of
- the copyright holders. Use of them is covered by separate agreement
- with the copyright holders.
- 5. If any files are modified, you must cause the modified files to carry
- prominent notices stating that you changed the files and the date of
- any change.
-
- Disclaimer
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#define _NEW_COMPLEX_LDOUBLE 1
-#include "sin.def.h"
diff --git a/lib/libc/mingw/math/x86/sinl_internal.S b/lib/libc/mingw/math/x86/sinl_internal.S
@@ -1,58 +0,0 @@
-/**
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER.PD within this package.
- */
-#include <_mingw_mac.h>
-
- .file "sinl_internal.S"
- .text
-#ifdef __x86_64__
- .align 8
-#else
- .align 4
-#endif
-.globl __MINGW_USYMBOL(__sinl_internal)
- .def __MINGW_USYMBOL(__sinl_internal); .scl 2; .type 32; .endef
-__MINGW_USYMBOL(__sinl_internal):
-#ifdef __x86_64__
- fldt (%rdx)
- fsin
- fnstsw %ax
- testl $0x400,%eax
- jnz 1f
- movq %rcx,%rax
- movq $0,8(%rcx)
- fstpt (%rcx)
- ret
-1: fldpi
- fadd %st(0)
- fxch %st(1)
-2: fprem1
- fnstsw %ax
- testl $0x400,%eax
- jnz 2b
- fstp %st(1)
- fsin
- movq %rcx,%rax
- movq $0,8(%rcx)
- fstpt (%rcx)
- ret
-#else
- fldt 4(%esp)
- fsin
- fnstsw %ax
- testl $0x400,%eax
- jnz 1f
- ret
-1: fldpi
- fadd %st(0)
- fxch %st(1)
-2: fprem1
- fnstsw %ax
- testl $0x400,%eax
- jnz 2b
- fstp %st(1)
- fsin
- ret
-#endif
diff --git a/lib/libc/mingw/math/x86/tanl.S b/lib/libc/mingw/math/x86/tanl.S
@@ -1,62 +0,0 @@
-/**
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is part of the mingw-w64 runtime package.
- * No warranty is given; refer to the file DISCLAIMER.PD within this package.
- */
-#include <_mingw_mac.h>
-
- .file "tanl.S"
- .text
-#ifdef __x86_64__
- .align 8
-#else
- .align 4
-#endif
-.globl __MINGW_USYMBOL(tanl)
- .def __MINGW_USYMBOL(tanl); .scl 2; .type 32; .endef
-__MINGW_USYMBOL(tanl):
-#ifdef __x86_64__
- fldt (%rdx)
- fptan
- fnstsw %ax
- testl $0x400,%eax
- jnz 1f
- fstp %st(0)
- movq %rcx,%rax
- movq $0,8(%rcx)
- fstpt (%rcx)
- ret
-1: fldpi
- fadd %st(0)
- fxch %st(1)
-2: fprem1
- fstsw %ax
- testl $0x400,%eax
- jnz 2b
- fstp %st(1)
- fptan
- fstp %st(0)
- movq %rcx,%rax
- movq $0,8(%rcx)
- fstpt (%rcx)
- ret
-#else
- fldt 4(%esp)
- fptan
- fnstsw %ax
- testl $0x400,%eax
- jnz 1f
- fstp %st(0)
- ret
-1: fldpi
- fadd %st(0)
- fxch %st(1)
-2: fprem1
- fstsw %ax
- testl $0x400,%eax
- jnz 2b
- fstp %st(1)
- fptan
- fstp %st(0)
- ret
-#endif
diff --git a/lib/libc/musl/src/math/__cosl.c b/lib/libc/musl/src/math/__cosl.c
@@ -1,96 +0,0 @@
-/* origin: FreeBSD /usr/src/lib/msun/ld80/k_cosl.c */
-/* origin: FreeBSD /usr/src/lib/msun/ld128/k_cosl.c */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-
-#include "libm.h"
-
-#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
-#if LDBL_MANT_DIG == 64
-/*
- * ld80 version of __cos.c. See __cos.c for most comments.
- */
-/*
- * Domain [-0.7854, 0.7854], range ~[-2.43e-23, 2.425e-23]:
- * |cos(x) - c(x)| < 2**-75.1
- *
- * The coefficients of c(x) were generated by a pari-gp script using
- * a Remez algorithm that searches for the best higher coefficients
- * after rounding leading coefficients to a specified precision.
- *
- * Simpler methods like Chebyshev or basic Remez barely suffice for
- * cos() in 64-bit precision, because we want the coefficient of x^2
- * to be precisely -0.5 so that multiplying by it is exact, and plain
- * rounding of the coefficients of a good polynomial approximation only
- * gives this up to about 64-bit precision. Plain rounding also gives
- * a mediocre approximation for the coefficient of x^4, but a rounding
- * error of 0.5 ulps for this coefficient would only contribute ~0.01
- * ulps to the final error, so this is unimportant. Rounding errors in
- * higher coefficients are even less important.
- *
- * In fact, coefficients above the x^4 one only need to have 53-bit
- * precision, and this is more efficient. We get this optimization
- * almost for free from the complications needed to search for the best
- * higher coefficients.
- */
-static const long double
-C1 = 0.0416666666666666666136L; /* 0xaaaaaaaaaaaaaa9b.0p-68 */
-static const double
-C2 = -0.0013888888888888874, /* -0x16c16c16c16c10.0p-62 */
-C3 = 0.000024801587301571716, /* 0x1a01a01a018e22.0p-68 */
-C4 = -0.00000027557319215507120, /* -0x127e4fb7602f22.0p-74 */
-C5 = 0.0000000020876754400407278, /* 0x11eed8caaeccf1.0p-81 */
-C6 = -1.1470297442401303e-11, /* -0x19393412bd1529.0p-89 */
-C7 = 4.7383039476436467e-14; /* 0x1aac9d9af5c43e.0p-97 */
-#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7)))))))
-#elif LDBL_MANT_DIG == 113
-/*
- * ld128 version of __cos.c. See __cos.c for most comments.
- */
-/*
- * Domain [-0.7854, 0.7854], range ~[-1.80e-37, 1.79e-37]:
- * |cos(x) - c(x))| < 2**-122.0
- *
- * 113-bit precision requires more care than 64-bit precision, since
- * simple methods give a minimax polynomial with coefficient for x^2
- * that is 1 ulp below 0.5, but we want it to be precisely 0.5. See
- * above for more details.
- */
-static const long double
-C1 = 0.04166666666666666666666666666666658424671L,
-C2 = -0.001388888888888888888888888888863490893732L,
-C3 = 0.00002480158730158730158730158600795304914210L,
-C4 = -0.2755731922398589065255474947078934284324e-6L,
-C5 = 0.2087675698786809897659225313136400793948e-8L,
-C6 = -0.1147074559772972315817149986812031204775e-10L,
-C7 = 0.4779477332386808976875457937252120293400e-13L;
-static const double
-C8 = -0.1561920696721507929516718307820958119868e-15,
-C9 = 0.4110317413744594971475941557607804508039e-18,
-C10 = -0.8896592467191938803288521958313920156409e-21,
-C11 = 0.1601061435794535138244346256065192782581e-23;
-#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+ \
- z*(C8+z*(C9+z*(C10+z*C11)))))))))))
-#endif
-
-long double __cosl(long double x, long double y)
-{
- long double hz,z,r,w;
-
- z = x*x;
- r = POLY(z);
- hz = 0.5*z;
- w = 1.0-hz;
- return w + (((1.0-w)-hz) + (z*r-x*y));
-}
-#endif
diff --git a/lib/libc/musl/src/math/__sinl.c b/lib/libc/musl/src/math/__sinl.c
@@ -1,78 +0,0 @@
-/* origin: FreeBSD /usr/src/lib/msun/ld80/k_sinl.c */
-/* origin: FreeBSD /usr/src/lib/msun/ld128/k_sinl.c */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
- *
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include "libm.h"
-
-#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
-#if LDBL_MANT_DIG == 64
-/*
- * ld80 version of __sin.c. See __sin.c for most comments.
- */
-/*
- * Domain [-0.7854, 0.7854], range ~[-1.89e-22, 1.915e-22]
- * |sin(x)/x - s(x)| < 2**-72.1
- *
- * See __cosl.c for more details about the polynomial.
- */
-static const long double
-S1 = -0.166666666666666666671L; /* -0xaaaaaaaaaaaaaaab.0p-66 */
-static const double
-S2 = 0.0083333333333333332, /* 0x11111111111111.0p-59 */
-S3 = -0.00019841269841269427, /* -0x1a01a01a019f81.0p-65 */
-S4 = 0.0000027557319223597490, /* 0x171de3a55560f7.0p-71 */
-S5 = -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */
-S6 = 1.6059006598854211e-10, /* 0x161242b90243b5.0p-85 */
-S7 = -7.6429779983024564e-13, /* -0x1ae42ebd1b2e00.0p-93 */
-S8 = 2.6174587166648325e-15; /* 0x179372ea0b3f64.0p-101 */
-#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*S8))))))
-#elif LDBL_MANT_DIG == 113
-/*
- * ld128 version of __sin.c. See __sin.c for most comments.
- */
-/*
- * Domain [-0.7854, 0.7854], range ~[-1.53e-37, 1.659e-37]
- * |sin(x)/x - s(x)| < 2**-122.1
- *
- * See __cosl.c for more details about the polynomial.
- */
-static const long double
-S1 = -0.16666666666666666666666666666666666606732416116558L,
-S2 = 0.0083333333333333333333333333333331135404851288270047L,
-S3 = -0.00019841269841269841269841269839935785325638310428717L,
-S4 = 0.27557319223985890652557316053039946268333231205686e-5L,
-S5 = -0.25052108385441718775048214826384312253862930064745e-7L,
-S6 = 0.16059043836821614596571832194524392581082444805729e-9L,
-S7 = -0.76471637318198151807063387954939213287488216303768e-12L,
-S8 = 0.28114572543451292625024967174638477283187397621303e-14L;
-static const double
-S9 = -0.82206352458348947812512122163446202498005154296863e-17,
-S10 = 0.19572940011906109418080609928334380560135358385256e-19,
-S11 = -0.38680813379701966970673724299207480965452616911420e-22,
-S12 = 0.64038150078671872796678569586315881020659912139412e-25;
-#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*(S8+ \
- z*(S9+z*(S10+z*(S11+z*S12))))))))))
-#endif
-
-long double __sinl(long double x, long double y, int iy)
-{
- long double z,r,v;
-
- z = x*x;
- v = z*x;
- r = POLY(z);
- if (iy == 0)
- return x+v*(S1+z*r);
- return x-((z*(0.5*y-v*r)-y)-v*S1);
-}
-#endif
diff --git a/lib/libc/musl/src/math/__tanl.c b/lib/libc/musl/src/math/__tanl.c
@@ -1,143 +0,0 @@
-/* origin: FreeBSD /usr/src/lib/msun/ld80/k_tanl.c */
-/* origin: FreeBSD /usr/src/lib/msun/ld128/k_tanl.c */
-/*
- * ====================================================
- * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
- *
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#include "libm.h"
-
-#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
-#if LDBL_MANT_DIG == 64
-/*
- * ld80 version of __tan.c. See __tan.c for most comments.
- */
-/*
- * Domain [-0.67434, 0.67434], range ~[-2.25e-22, 1.921e-22]
- * |tan(x)/x - t(x)| < 2**-71.9
- *
- * See __cosl.c for more details about the polynomial.
- */
-static const long double
-T3 = 0.333333333333333333180L, /* 0xaaaaaaaaaaaaaaa5.0p-65 */
-T5 = 0.133333333333333372290L, /* 0x88888888888893c3.0p-66 */
-T7 = 0.0539682539682504975744L, /* 0xdd0dd0dd0dc13ba2.0p-68 */
-pio4 = 0.785398163397448309628L, /* 0xc90fdaa22168c235.0p-64 */
-pio4lo = -1.25413940316708300586e-20L; /* -0xece675d1fc8f8cbb.0p-130 */
-static const double
-T9 = 0.021869488536312216, /* 0x1664f4882cc1c2.0p-58 */
-T11 = 0.0088632355256619590, /* 0x1226e355c17612.0p-59 */
-T13 = 0.0035921281113786528, /* 0x1d6d3d185d7ff8.0p-61 */
-T15 = 0.0014558334756312418, /* 0x17da354aa3f96b.0p-62 */
-T17 = 0.00059003538700862256, /* 0x13559358685b83.0p-63 */
-T19 = 0.00023907843576635544, /* 0x1f56242026b5be.0p-65 */
-T21 = 0.000097154625656538905, /* 0x1977efc26806f4.0p-66 */
-T23 = 0.000038440165747303162, /* 0x14275a09b3ceac.0p-67 */
-T25 = 0.000018082171885432524, /* 0x12f5e563e5487e.0p-68 */
-T27 = 0.0000024196006108814377, /* 0x144c0d80cc6896.0p-71 */
-T29 = 0.0000078293456938132840, /* 0x106b59141a6cb3.0p-69 */
-T31 = -0.0000032609076735050182, /* -0x1b5abef3ba4b59.0p-71 */
-T33 = 0.0000023261313142559411; /* 0x13835436c0c87f.0p-71 */
-#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \
- w * (T25 + w * (T29 + w * T33)))))))
-#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \
- w * (T27 + w * T31))))))
-#elif LDBL_MANT_DIG == 113
-/*
- * ld128 version of __tan.c. See __tan.c for most comments.
- */
-/*
- * Domain [-0.67434, 0.67434], range ~[-3.37e-36, 1.982e-37]
- * |tan(x)/x - t(x)| < 2**-117.8 (XXX should be ~1e-37)
- *
- * See __cosl.c for more details about the polynomial.
- */
-static const long double
-T3 = 0x1.5555555555555555555555555553p-2L,
-T5 = 0x1.1111111111111111111111111eb5p-3L,
-T7 = 0x1.ba1ba1ba1ba1ba1ba1ba1b694cd6p-5L,
-T9 = 0x1.664f4882c10f9f32d6bbe09d8bcdp-6L,
-T11 = 0x1.226e355e6c23c8f5b4f5762322eep-7L,
-T13 = 0x1.d6d3d0e157ddfb5fed8e84e27b37p-9L,
-T15 = 0x1.7da36452b75e2b5fce9ee7c2c92ep-10L,
-T17 = 0x1.355824803674477dfcf726649efep-11L,
-T19 = 0x1.f57d7734d1656e0aceb716f614c2p-13L,
-T21 = 0x1.967e18afcb180ed942dfdc518d6cp-14L,
-T23 = 0x1.497d8eea21e95bc7e2aa79b9f2cdp-15L,
-T25 = 0x1.0b132d39f055c81be49eff7afd50p-16L,
-T27 = 0x1.b0f72d33eff7bfa2fbc1059d90b6p-18L,
-T29 = 0x1.5ef2daf21d1113df38d0fbc00267p-19L,
-T31 = 0x1.1c77d6eac0234988cdaa04c96626p-20L,
-T33 = 0x1.cd2a5a292b180e0bdd701057dfe3p-22L,
-T35 = 0x1.75c7357d0298c01a31d0a6f7d518p-23L,
-T37 = 0x1.2f3190f4718a9a520f98f50081fcp-24L,
-pio4 = 0x1.921fb54442d18469898cc51701b8p-1L,
-pio4lo = 0x1.cd129024e088a67cc74020bbea60p-116L;
-static const double
-T39 = 0.000000028443389121318352, /* 0x1e8a7592977938.0p-78 */
-T41 = 0.000000011981013102001973, /* 0x19baa1b1223219.0p-79 */
-T43 = 0.0000000038303578044958070, /* 0x107385dfb24529.0p-80 */
-T45 = 0.0000000034664378216909893, /* 0x1dc6c702a05262.0p-81 */
-T47 = -0.0000000015090641701997785, /* -0x19ecef3569ebb6.0p-82 */
-T49 = 0.0000000029449552300483952, /* 0x194c0668da786a.0p-81 */
-T51 = -0.0000000022006995706097711, /* -0x12e763b8845268.0p-81 */
-T53 = 0.0000000015468200913196612, /* 0x1a92fc98c29554.0p-82 */
-T55 = -0.00000000061311613386849674, /* -0x151106cbc779a9.0p-83 */
-T57 = 1.4912469681508012e-10; /* 0x147edbdba6f43a.0p-85 */
-#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \
- w * (T25 + w * (T29 + w * (T33 + w * (T37 + w * (T41 + \
- w * (T45 + w * (T49 + w * (T53 + w * T57)))))))))))))
-#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \
- w * (T27 + w * (T31 + w * (T35 + w * (T39 + w * (T43 + \
- w * (T47 + w * (T51 + w * T55))))))))))))
-#endif
-
-long double __tanl(long double x, long double y, int odd) {
- long double z, r, v, w, s, a, t;
- int big, sign;
-
- big = fabsl(x) >= 0.67434;
- if (big) {
- sign = 0;
- if (x < 0) {
- sign = 1;
- x = -x;
- y = -y;
- }
- x = (pio4 - x) + (pio4lo - y);
- y = 0.0;
- }
- z = x * x;
- w = z * z;
- r = RPOLY(w);
- v = z * VPOLY(w);
- s = z * x;
- r = y + z * (s * (r + v) + y) + T3 * s;
- w = x + r;
- if (big) {
- s = 1 - 2*odd;
- v = s - 2.0 * (x + (r - w * w / (w + s)));
- return sign ? -v : v;
- }
- if (!odd)
- return w;
- /*
- * if allow error up to 2 ulp, simply return
- * -1.0 / (x+r) here
- */
- /* compute -1.0 / (x+r) accurately */
- z = w;
- z = z + 0x1p32 - 0x1p32;
- v = r - (z - x); /* z+v = r+x */
- t = a = -1.0 / w; /* a = -1.0/w */
- t = t + 0x1p32 - 0x1p32;
- s = 1.0 + t * z;
- return t + a * (s + t * v);
-}
-#endif
diff --git a/lib/libc/musl/src/math/aarch64/lrint.c b/lib/libc/musl/src/math/aarch64/lrint.c
@@ -1,10 +0,0 @@
-#include <math.h>
-
-long lrint(double x)
-{
- long n;
- __asm__ (
- "frintx %d1, %d1\n"
- "fcvtzs %x0, %d1\n" : "=r"(n), "+w"(x));
- return n;
-}
diff --git a/lib/libc/musl/src/math/aarch64/lrintf.c b/lib/libc/musl/src/math/aarch64/lrintf.c
@@ -1,10 +0,0 @@
-#include <math.h>
-
-long lrintf(float x)
-{
- long n;
- __asm__ (
- "frintx %s1, %s1\n"
- "fcvtzs %x0, %s1\n" : "=r"(n), "+w"(x));
- return n;
-}
diff --git a/lib/libc/musl/src/math/aarch64/rintf.c b/lib/libc/musl/src/math/aarch64/rintf.c
@@ -1,7 +0,0 @@
-#include <math.h>
-
-float rintf(float x)
-{
- __asm__ ("frintx %s0, %s1" : "=w"(x) : "w"(x));
- return x;
-}
diff --git a/lib/libc/musl/src/math/cosl.c b/lib/libc/musl/src/math/cosl.c
@@ -1,39 +0,0 @@
-#include "libm.h"
-
-#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
-long double cosl(long double x) {
- return cos(x);
-}
-#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
-long double cosl(long double x)
-{
- union ldshape u = {x};
- unsigned n;
- long double y[2], hi, lo;
-
- u.i.se &= 0x7fff;
- if (u.i.se == 0x7fff)
- return x - x;
- x = u.f;
- if (x < M_PI_4) {
- if (u.i.se < 0x3fff - LDBL_MANT_DIG)
- /* raise inexact if x!=0 */
- return 1.0 + x;
- return __cosl(x, 0);
- }
- n = __rem_pio2l(x, y);
- hi = y[0];
- lo = y[1];
- switch (n & 3) {
- case 0:
- return __cosl(hi, lo);
- case 1:
- return -__sinl(hi, lo, 1);
- case 2:
- return -__cosl(hi, lo);
- case 3:
- default:
- return __sinl(hi, lo, 1);
- }
-}
-#endif
diff --git a/lib/libc/musl/src/math/finite.c b/lib/libc/musl/src/math/finite.c
@@ -1,7 +0,0 @@
-#define _GNU_SOURCE
-#include <math.h>
-
-int finite(double x)
-{
- return isfinite(x);
-}
diff --git a/lib/libc/musl/src/math/finitef.c b/lib/libc/musl/src/math/finitef.c
@@ -1,7 +0,0 @@
-#define _GNU_SOURCE
-#include <math.h>
-
-int finitef(float x)
-{
- return isfinite(x);
-}
diff --git a/lib/libc/musl/src/math/frexp.c b/lib/libc/musl/src/math/frexp.c
@@ -1,23 +0,0 @@
-#include <math.h>
-#include <stdint.h>
-
-double frexp(double x, int *e)
-{
- union { double d; uint64_t i; } y = { x };
- int ee = y.i>>52 & 0x7ff;
-
- if (!ee) {
- if (x) {
- x = frexp(x*0x1p64, e);
- *e -= 64;
- } else *e = 0;
- return x;
- } else if (ee == 0x7ff) {
- return x;
- }
-
- *e = ee - 0x3fe;
- y.i &= 0x800fffffffffffffull;
- y.i |= 0x3fe0000000000000ull;
- return y.d;
-}
diff --git a/lib/libc/musl/src/math/frexpf.c b/lib/libc/musl/src/math/frexpf.c
@@ -1,23 +0,0 @@
-#include <math.h>
-#include <stdint.h>
-
-float frexpf(float x, int *e)
-{
- union { float f; uint32_t i; } y = { x };
- int ee = y.i>>23 & 0xff;
-
- if (!ee) {
- if (x) {
- x = frexpf(x*0x1p64, e);
- *e -= 64;
- } else *e = 0;
- return x;
- } else if (ee == 0xff) {
- return x;
- }
-
- *e = ee - 0x7e;
- y.i &= 0x807ffffful;
- y.i |= 0x3f000000ul;
- return y.f;
-}
diff --git a/lib/libc/musl/src/math/frexpl.c b/lib/libc/musl/src/math/frexpl.c
@@ -1,29 +0,0 @@
-#include "libm.h"
-
-#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
-long double frexpl(long double x, int *e)
-{
- return frexp(x, e);
-}
-#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
-long double frexpl(long double x, int *e)
-{
- union ldshape u = {x};
- int ee = u.i.se & 0x7fff;
-
- if (!ee) {
- if (x) {
- x = frexpl(x*0x1p120, e);
- *e -= 120;
- } else *e = 0;
- return x;
- } else if (ee == 0x7fff) {
- return x;
- }
-
- *e = ee - 0x3ffe;
- u.i.se &= 0x8000;
- u.i.se |= 0x3ffe;
- return u.f;
-}
-#endif
diff --git a/lib/libc/musl/src/math/i386/lrint.c b/lib/libc/musl/src/math/i386/lrint.c
@@ -1,8 +0,0 @@
-#include <math.h>
-
-long lrint(double x)
-{
- long r;
- __asm__ ("fistpl %0" : "=m"(r) : "t"(x) : "st");
- return r;
-}
diff --git a/lib/libc/musl/src/math/i386/lrintf.c b/lib/libc/musl/src/math/i386/lrintf.c
@@ -1,8 +0,0 @@
-#include <math.h>
-
-long lrintf(float x)
-{
- long r;
- __asm__ ("fistpl %0" : "=m"(r) : "t"(x) : "st");
- return r;
-}
diff --git a/lib/libc/musl/src/math/i386/rintf.c b/lib/libc/musl/src/math/i386/rintf.c
@@ -1,7 +0,0 @@
-#include <math.h>
-
-float rintf(float x)
-{
- __asm__ ("frndint" : "+t"(x));
- return x;
-}
diff --git a/lib/libc/musl/src/math/lrint.c b/lib/libc/musl/src/math/lrint.c
@@ -1,72 +0,0 @@
-#include <limits.h>
-#include <fenv.h>
-#include <math.h>
-#include "libm.h"
-
-/*
-If the result cannot be represented (overflow, nan), then
-lrint raises the invalid exception.
-
-Otherwise if the input was not an integer then the inexact
-exception is raised.
-
-C99 is a bit vague about whether inexact exception is
-allowed to be raised when invalid is raised.
-(F.9 explicitly allows spurious inexact exceptions, F.9.6.5
-does not make it clear if that rule applies to lrint, but
-IEEE 754r 7.8 seems to forbid spurious inexact exception in
-the ineger conversion functions)
-
-So we try to make sure that no spurious inexact exception is
-raised in case of an overflow.
-
-If the bit size of long > precision of double, then there
-cannot be inexact rounding in case the result overflows,
-otherwise LONG_MAX and LONG_MIN can be represented exactly
-as a double.
-*/
-
-#if LONG_MAX < 1U<<53 && defined(FE_INEXACT)
-#include <float.h>
-#include <stdint.h>
-#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
-#define EPS DBL_EPSILON
-#elif FLT_EVAL_METHOD==2
-#define EPS LDBL_EPSILON
-#endif
-#ifdef __GNUC__
-/* avoid stack frame in lrint */
-__attribute__((noinline))
-#endif
-static long lrint_slow(double x)
-{
- #pragma STDC FENV_ACCESS ON
- int e;
-
- e = fetestexcept(FE_INEXACT);
- x = rint(x);
- if (!e && (x > LONG_MAX || x < LONG_MIN))
- feclearexcept(FE_INEXACT);
- /* conversion */
- return x;
-}
-
-long lrint(double x)
-{
- uint32_t abstop = asuint64(x)>>32 & 0x7fffffff;
- uint64_t sign = asuint64(x) & (1ULL << 63);
-
- if (abstop < 0x41dfffff) {
- /* |x| < 0x7ffffc00, no overflow */
- double_t toint = asdouble(asuint64(1/EPS) | sign);
- double_t y = x + toint - toint;
- return (long)y;
- }
- return lrint_slow(x);
-}
-#else
-long lrint(double x)
-{
- return rint(x);
-}
-#endif
diff --git a/lib/libc/musl/src/math/lrintf.c b/lib/libc/musl/src/math/lrintf.c
@@ -1,8 +0,0 @@
-#include <math.h>
-
-/* uses LONG_MAX > 2^24, see comments in lrint.c */
-
-long lrintf(float x)
-{
- return rintf(x);
-}
diff --git a/lib/libc/musl/src/math/powerpc64/lrint.c b/lib/libc/musl/src/math/powerpc64/lrint.c
@@ -1,16 +0,0 @@
-#include <math.h>
-
-#ifdef _ARCH_PWR5X
-
-long lrint(double x)
-{
- long n;
- __asm__ ("fctid %0, %1" : "=d"(n) : "d"(x));
- return n;
-}
-
-#else
-
-#include "../lrint.c"
-
-#endif
diff --git a/lib/libc/musl/src/math/powerpc64/lrintf.c b/lib/libc/musl/src/math/powerpc64/lrintf.c
@@ -1,16 +0,0 @@
-#include <math.h>
-
-#ifdef _ARCH_PWR5X
-
-long lrintf(float x)
-{
- long n;
- __asm__ ("fctid %0, %1" : "=d"(n) : "f"(x));
- return n;
-}
-
-#else
-
-#include "../lrintf.c"
-
-#endif
diff --git a/lib/libc/musl/src/math/rintf.c b/lib/libc/musl/src/math/rintf.c
@@ -1,30 +0,0 @@
-#include <float.h>
-#include <math.h>
-#include <stdint.h>
-
-#if FLT_EVAL_METHOD==0
-#define EPS FLT_EPSILON
-#elif FLT_EVAL_METHOD==1
-#define EPS DBL_EPSILON
-#elif FLT_EVAL_METHOD==2
-#define EPS LDBL_EPSILON
-#endif
-static const float_t toint = 1/EPS;
-
-float rintf(float x)
-{
- union {float f; uint32_t i;} u = {x};
- int e = u.i>>23 & 0xff;
- int s = u.i>>31;
- float_t y;
-
- if (e >= 0x7f+23)
- return x;
- if (s)
- y = x - toint + toint;
- else
- y = x + toint - toint;
- if (y == 0)
- return s ? -0.0f : 0.0f;
- return y;
-}
diff --git a/lib/libc/musl/src/math/s390x/rintf.c b/lib/libc/musl/src/math/s390x/rintf.c
@@ -1,15 +0,0 @@
-#include <math.h>
-
-#if defined(__HTM__) || __ARCH__ >= 9
-
-float rintf(float x)
-{
- __asm__ ("fiebr %0, 0, %1" : "=f"(x) : "f"(x));
- return x;
-}
-
-#else
-
-#include "../rintf.c"
-
-#endif
diff --git a/lib/libc/musl/src/math/sincosl.c b/lib/libc/musl/src/math/sincosl.c
@@ -1,60 +0,0 @@
-#define _GNU_SOURCE
-#include "libm.h"
-
-#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
-void sincosl(long double x, long double *sin, long double *cos)
-{
- double sind, cosd;
- sincos(x, &sind, &cosd);
- *sin = sind;
- *cos = cosd;
-}
-#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
-void sincosl(long double x, long double *sin, long double *cos)
-{
- union ldshape u = {x};
- unsigned n;
- long double y[2], s, c;
-
- u.i.se &= 0x7fff;
- if (u.i.se == 0x7fff) {
- *sin = *cos = x - x;
- return;
- }
- if (u.f < M_PI_4) {
- if (u.i.se < 0x3fff - LDBL_MANT_DIG) {
- /* raise underflow if subnormal */
- if (u.i.se == 0) FORCE_EVAL(x*0x1p-120f);
- *sin = x;
- /* raise inexact if x!=0 */
- *cos = 1.0 + x;
- return;
- }
- *sin = __sinl(x, 0, 0);
- *cos = __cosl(x, 0);
- return;
- }
- n = __rem_pio2l(x, y);
- s = __sinl(y[0], y[1], 1);
- c = __cosl(y[0], y[1]);
- switch (n & 3) {
- case 0:
- *sin = s;
- *cos = c;
- break;
- case 1:
- *sin = c;
- *cos = -s;
- break;
- case 2:
- *sin = -s;
- *cos = -c;
- break;
- case 3:
- default:
- *sin = -c;
- *cos = s;
- break;
- }
-}
-#endif
diff --git a/lib/libc/musl/src/math/sinl.c b/lib/libc/musl/src/math/sinl.c
@@ -1,41 +0,0 @@
-#include "libm.h"
-
-#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
-long double sinl(long double x)
-{
- return sin(x);
-}
-#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
-long double sinl(long double x)
-{
- union ldshape u = {x};
- unsigned n;
- long double y[2], hi, lo;
-
- u.i.se &= 0x7fff;
- if (u.i.se == 0x7fff)
- return x - x;
- if (u.f < M_PI_4) {
- if (u.i.se < 0x3fff - LDBL_MANT_DIG/2) {
- /* raise inexact if x!=0 and underflow if subnormal */
- FORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f);
- return x;
- }
- return __sinl(x, 0.0, 0);
- }
- n = __rem_pio2l(x, y);
- hi = y[0];
- lo = y[1];
- switch (n & 3) {
- case 0:
- return __sinl(hi, lo, 1);
- case 1:
- return __cosl(hi, lo);
- case 2:
- return -__sinl(hi, lo, 1);
- case 3:
- default:
- return -__cosl(hi, lo);
- }
-}
-#endif
diff --git a/lib/libc/musl/src/math/tanl.c b/lib/libc/musl/src/math/tanl.c
@@ -1,29 +0,0 @@
-#include "libm.h"
-
-#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
-long double tanl(long double x)
-{
- return tan(x);
-}
-#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
-long double tanl(long double x)
-{
- union ldshape u = {x};
- long double y[2];
- unsigned n;
-
- u.i.se &= 0x7fff;
- if (u.i.se == 0x7fff)
- return x - x;
- if (u.f < M_PI_4) {
- if (u.i.se < 0x3fff - LDBL_MANT_DIG/2) {
- /* raise inexact if x!=0 and underflow if subnormal */
- FORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f);
- return x;
- }
- return __tanl(x, 0, 0);
- }
- n = __rem_pio2l(x, y);
- return __tanl(y[0], y[1], n&1);
-}
-#endif
diff --git a/lib/libc/musl/src/math/x32/lrint.s b/lib/libc/musl/src/math/x32/lrint.s
@@ -1,5 +0,0 @@
-.global lrint
-.type lrint,@function
-lrint:
- cvtsd2si %xmm0,%rax
- ret
diff --git a/lib/libc/musl/src/math/x32/lrintf.s b/lib/libc/musl/src/math/x32/lrintf.s
@@ -1,5 +0,0 @@
-.global lrintf
-.type lrintf,@function
-lrintf:
- cvtss2si %xmm0,%rax
- ret
diff --git a/lib/libc/musl/src/math/x86_64/lrint.c b/lib/libc/musl/src/math/x86_64/lrint.c
@@ -1,8 +0,0 @@
-#include <math.h>
-
-long lrint(double x)
-{
- long r;
- __asm__ ("cvtsd2si %1, %0" : "=r"(r) : "x"(x));
- return r;
-}
diff --git a/lib/libc/musl/src/math/x86_64/lrintf.c b/lib/libc/musl/src/math/x86_64/lrintf.c
@@ -1,8 +0,0 @@
-#include <math.h>
-
-long lrintf(float x)
-{
- long r;
- __asm__ ("cvtss2si %1, %0" : "=r"(r) : "x"(x));
- return r;
-}
diff --git a/src/libs/mingw.zig b/src/libs/mingw.zig
@@ -613,8 +613,6 @@ const mingw32_generic_src = [_][]const u8{
"math" ++ path.sep_str ++ "fpclassify.c",
"math" ++ path.sep_str ++ "fpclassifyf.c",
"math" ++ path.sep_str ++ "fpclassifyl.c",
- "math" ++ path.sep_str ++ "frexpf.c",
- "math" ++ path.sep_str ++ "frexpl.c",
"math" ++ path.sep_str ++ "ldexpf.c",
"math" ++ path.sep_str ++ "lgamma.c",
"math" ++ path.sep_str ++ "lgammaf.c",
@@ -942,8 +940,6 @@ const mingw32_x86_src = [_][]const u8{
"math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "atan2l.c",
"math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "atanhl.c",
"math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "atanl.c",
- "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "cosl.c",
- "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "cosl_internal.S",
"math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "cossinl.c",
"math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "exp2l.S",
"math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "expl.c",
@@ -965,9 +961,6 @@ const mingw32_x86_src = [_][]const u8{
"math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "scalbn.S",
"math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "scalbnf.S",
"math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "scalbnl.S",
- "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "sinl.c",
- "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "sinl_internal.S",
- "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "tanl.S",
// ucrtbase
"math" ++ path.sep_str ++ "nextafterl.c",
"math" ++ path.sep_str ++ "nexttoward.c",
@@ -987,22 +980,15 @@ const mingw32_x86_32_src = [_][]const u8{
const mingw32_arm_src = [_][]const u8{
// mingwex
"math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "ldexpl.c",
- "math" ++ path.sep_str ++ "arm-common" ++ path.sep_str ++ "sincosl.c",
};
const mingw32_arm32_src = [_][]const u8{
// mingwex
"math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "s_rint.c",
"math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "s_rintf.c",
- "math" ++ path.sep_str ++ "arm" ++ path.sep_str ++ "sincos.S",
};
-const mingw32_arm64_src = [_][]const u8{
- // mingwex
- "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rint.c",
- "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "rintf.c",
- "math" ++ path.sep_str ++ "arm64" ++ path.sep_str ++ "sincos.S",
-};
+const mingw32_arm64_src = [_][]const u8{};
const mingw32_winpthreads_src = [_][]const u8{
// winpthreads
diff --git a/src/libs/musl.zig b/src/libs/musl.zig
@@ -787,13 +787,10 @@ const src_files = [_][]const u8{
"musl/src/math/aarch64/llrintf.c",
"musl/src/math/aarch64/llround.c",
"musl/src/math/aarch64/llroundf.c",
- "musl/src/math/aarch64/lrint.c",
- "musl/src/math/aarch64/lrintf.c",
"musl/src/math/aarch64/lround.c",
"musl/src/math/aarch64/lroundf.c",
"musl/src/math/aarch64/nearbyint.c",
"musl/src/math/aarch64/nearbyintf.c",
- "musl/src/math/aarch64/rintf.c",
"musl/src/math/acosh.c",
"musl/src/math/acoshl.c",
"musl/src/math/acosl.c",
@@ -814,8 +811,6 @@ const src_files = [_][]const u8{
"musl/src/math/__cos.c",
"musl/src/math/__cosdf.c",
"musl/src/math/coshl.c",
- "musl/src/math/__cosl.c",
- "musl/src/math/cosl.c",
"musl/src/math/erf.c",
"musl/src/math/erff.c",
"musl/src/math/erfl.c",
@@ -831,17 +826,12 @@ const src_files = [_][]const u8{
"musl/src/math/__expo2f.c",
"musl/src/math/fdimf.c",
"musl/src/math/fdiml.c",
- "musl/src/math/finite.c",
- "musl/src/math/finitef.c",
"musl/src/math/fma.c",
"musl/src/math/fmaf.c",
"musl/src/math/fmal.c",
"musl/src/math/__fpclassify.c",
"musl/src/math/__fpclassifyf.c",
"musl/src/math/__fpclassifyl.c",
- "musl/src/math/frexp.c",
- "musl/src/math/frexpf.c",
- "musl/src/math/frexpl.c",
"musl/src/math/i386/acosl.s",
"musl/src/math/i386/asinf.s",
"musl/src/math/i386/asinl.s",
@@ -865,8 +855,6 @@ const src_files = [_][]const u8{
"musl/src/math/i386/log1p.s",
"musl/src/math/i386/log2l.s",
"musl/src/math/i386/logl.s",
- "musl/src/math/i386/lrint.c",
- "musl/src/math/i386/lrintf.c",
"musl/src/math/i386/lrintl.c",
"musl/src/math/i386/remainder.c",
"musl/src/math/i386/remainderf.c",
@@ -874,7 +862,6 @@ const src_files = [_][]const u8{
"musl/src/math/i386/remquof.s",
"musl/src/math/i386/remquol.s",
"musl/src/math/i386/remquo.s",
- "musl/src/math/i386/rintf.c",
"musl/src/math/i386/rintl.c",
"musl/src/math/i386/scalblnf.s",
"musl/src/math/i386/scalblnl.s",
@@ -915,8 +902,6 @@ const src_files = [_][]const u8{
"musl/src/math/logbf.c",
"musl/src/math/logbl.c",
"musl/src/math/logl.c",
- "musl/src/math/lrint.c",
- "musl/src/math/lrintf.c",
"musl/src/math/lrintl.c",
"musl/src/math/lround.c",
"musl/src/math/lroundf.c",
@@ -945,8 +930,6 @@ const src_files = [_][]const u8{
"musl/src/math/pow_data.c",
"musl/src/math/powerpc64/fma.c",
"musl/src/math/powerpc64/fmaf.c",
- "musl/src/math/powerpc64/lrint.c",
- "musl/src/math/powerpc64/lrintf.c",
"musl/src/math/powerpc64/lround.c",
"musl/src/math/powerpc64/lroundf.c",
"musl/src/math/powerpc/fma.c",
@@ -964,7 +947,6 @@ const src_files = [_][]const u8{
"musl/src/math/remquo.c",
"musl/src/math/remquof.c",
"musl/src/math/remquol.c",
- "musl/src/math/rintf.c",
"musl/src/math/rintl.c",
"musl/src/math/riscv32/fma.c",
"musl/src/math/riscv32/fmaf.c",
@@ -975,7 +957,6 @@ const src_files = [_][]const u8{
"musl/src/math/s390x/nearbyint.c",
"musl/src/math/s390x/nearbyintf.c",
"musl/src/math/s390x/nearbyintl.c",
- "musl/src/math/s390x/rintf.c",
"musl/src/math/s390x/rintl.c",
"musl/src/math/scalb.c",
"musl/src/math/scalbf.c",
@@ -992,18 +973,13 @@ const src_files = [_][]const u8{
"musl/src/math/significand.c",
"musl/src/math/significandf.c",
"musl/src/math/__sin.c",
- "musl/src/math/sincosl.c",
"musl/src/math/__sindf.c",
"musl/src/math/sinh.c",
"musl/src/math/sinhf.c",
"musl/src/math/sinhl.c",
- "musl/src/math/__sinl.c",
- "musl/src/math/sinl.c",
"musl/src/math/__tan.c",
"musl/src/math/__tandf.c",
"musl/src/math/tanhl.c",
- "musl/src/math/__tanl.c",
- "musl/src/math/tanl.c",
"musl/src/math/tgamma.c",
"musl/src/math/tgammaf.c",
"musl/src/math/tgammal.c",
@@ -1023,9 +999,7 @@ const src_files = [_][]const u8{
"musl/src/math/x32/log1pl.s",
"musl/src/math/x32/log2l.s",
"musl/src/math/x32/logl.s",
- "musl/src/math/x32/lrintf.s",
"musl/src/math/x32/lrintl.s",
- "musl/src/math/x32/lrint.s",
"musl/src/math/x32/remainderl.s",
"musl/src/math/x32/rintl.s",
"musl/src/math/x86_64/acosl.s",
@@ -1044,8 +1018,6 @@ const src_files = [_][]const u8{
"musl/src/math/x86_64/log1pl.s",
"musl/src/math/x86_64/log2l.s",
"musl/src/math/x86_64/logl.s",
- "musl/src/math/x86_64/lrint.c",
- "musl/src/math/x86_64/lrintf.c",
"musl/src/math/x86_64/lrintl.c",
"musl/src/math/x86_64/remainderl.c",
"musl/src/math/x86_64/remquol.c",
diff --git a/src/libs/wasi_libc.zig b/src/libs/wasi_libc.zig
@@ -682,8 +682,6 @@ const libc_top_half_src_files = [_][]const u8{
"musl/src/math/__cos.c",
"musl/src/math/__cosdf.c",
"musl/src/math/coshl.c",
- "musl/src/math/__cosl.c",
- "musl/src/math/cosl.c",
"musl/src/math/erf.c",
"musl/src/math/erff.c",
"musl/src/math/erfl.c",
@@ -697,13 +695,8 @@ const libc_top_half_src_files = [_][]const u8{
"musl/src/math/expm1l.c",
"musl/src/math/fdimf.c",
"musl/src/math/fdiml.c",
- "musl/src/math/finite.c",
- "musl/src/math/finitef.c",
"musl/src/math/fma.c",
"musl/src/math/fmaf.c",
- "musl/src/math/frexp.c",
- "musl/src/math/frexpf.c",
- "musl/src/math/frexpl.c",
"musl/src/math/ilogb.c",
"musl/src/math/ilogbf.c",
"musl/src/math/ilogbl.c",
@@ -737,8 +730,6 @@ const libc_top_half_src_files = [_][]const u8{
"musl/src/math/logbf.c",
"musl/src/math/logbl.c",
"musl/src/math/logl.c",
- "musl/src/math/lrint.c",
- "musl/src/math/lrintf.c",
"musl/src/math/lrintl.c",
"musl/src/math/lround.c",
"musl/src/math/lroundf.c",
@@ -785,16 +776,11 @@ const libc_top_half_src_files = [_][]const u8{
"musl/src/math/significand.c",
"musl/src/math/significandf.c",
"musl/src/math/__sin.c",
- "musl/src/math/sincosl.c",
"musl/src/math/__sindf.c",
"musl/src/math/sinhl.c",
- "musl/src/math/__sinl.c",
- "musl/src/math/sinl.c",
"musl/src/math/__tan.c",
"musl/src/math/__tandf.c",
"musl/src/math/tanhl.c",
- "musl/src/math/__tanl.c",
- "musl/src/math/tanl.c",
"musl/src/math/tgamma.c",
"musl/src/math/tgammaf.c",
"musl/src/math/tgammal.c",
diff --git a/test/libc.zig b/test/libc.zig
@@ -293,7 +293,7 @@ pub fn addCases(cases: *tests.LibcContext) void {
cases.addLibcTestCase("math/remquo.c", true, .{});
cases.addLibcTestCase("math/remquof.c", true, .{});
cases.addLibcTestCase("math/remquol.c", true, .{});
- // cases.addLibcTestCase("math/rint.c", true, .{});
+ cases.addLibcTestCase("math/rint.c", true, .{});
cases.addLibcTestCase("math/rintf.c", true, .{});
// cases.addLibcTestCase("math/rintl.c", true, .{});
cases.addLibcTestCase("math/round.c", true, .{});