diff --git a/SHARED-FILES b/SHARED-FILES index 3bd4e7fb4a..032c407881 100644 --- a/SHARED-FILES +++ b/SHARED-FILES @@ -330,3 +330,7 @@ sysdeps/ieee754/flt-32/e_sinhf.c: (src/binary32/sinh/sinhf.c in CORE-MATH) - the code was adapted to use glibc code style and internal functions to handle errno, overflow, and underflow. +sysdeps/ieee754/flt-32/s_tanhf.c: + (src/binary32/tanh/tanhf.c in CORE-MATH) + - the code was adapted to use glibc code style and internal + functions to handle errno, overflow, and underflow. diff --git a/sysdeps/aarch64/libm-test-ulps b/sysdeps/aarch64/libm-test-ulps index 1e9c5af0ca..190685f893 100644 --- a/sysdeps/aarch64/libm-test-ulps +++ b/sysdeps/aarch64/libm-test-ulps @@ -1665,7 +1665,6 @@ ldouble: 1 Function: "tanh": double: 2 -float: 2 ldouble: 2 Function: "tanh_advsimd": @@ -1674,7 +1673,6 @@ float: 2 Function: "tanh_downward": double: 3 -float: 3 ldouble: 4 Function: "tanh_sve": @@ -1683,12 +1681,10 @@ float: 2 Function: "tanh_towardzero": double: 2 -float: 2 ldouble: 3 Function: "tanh_upward": double: 3 -float: 3 ldouble: 3 Function: "tanpi": diff --git a/sysdeps/alpha/fpu/libm-test-ulps b/sysdeps/alpha/fpu/libm-test-ulps index 7d5fcc7f2e..ddc851b73c 100644 --- a/sysdeps/alpha/fpu/libm-test-ulps +++ b/sysdeps/alpha/fpu/libm-test-ulps @@ -1318,22 +1318,18 @@ ldouble: 1 Function: "tanh": double: 2 -float: 2 ldouble: 2 Function: "tanh_downward": double: 3 -float: 3 ldouble: 4 Function: "tanh_towardzero": double: 2 -float: 2 ldouble: 3 Function: "tanh_upward": double: 3 -float: 3 ldouble: 3 Function: "tgamma": diff --git a/sysdeps/arc/fpu/libm-test-ulps b/sysdeps/arc/fpu/libm-test-ulps index ec42c5eac9..92fad18fc5 100644 --- a/sysdeps/arc/fpu/libm-test-ulps +++ b/sysdeps/arc/fpu/libm-test-ulps @@ -1053,19 +1053,15 @@ double: 1 Function: "tanh": double: 3 -float: 2 Function: "tanh_downward": double: 3 -float: 3 Function: "tanh_towardzero": double: 3 -float: 3 Function: "tanh_upward": double: 3 -float: 3 Function: "tgamma": double: 9 diff --git a/sysdeps/arc/nofpu/libm-test-ulps b/sysdeps/arc/nofpu/libm-test-ulps index 15b2b82187..6fb7ce93f4 100644 --- a/sysdeps/arc/nofpu/libm-test-ulps +++ b/sysdeps/arc/nofpu/libm-test-ulps @@ -251,7 +251,6 @@ double: 2 Function: "tanh": double: 2 -float: 2 Function: "tgamma": double: 9 diff --git a/sysdeps/arm/libm-test-ulps b/sysdeps/arm/libm-test-ulps index 201099d3f2..3ff089c1eb 100644 --- a/sysdeps/arm/libm-test-ulps +++ b/sysdeps/arm/libm-test-ulps @@ -1143,19 +1143,15 @@ double: 1 Function: "tanh": double: 2 -float: 2 Function: "tanh_downward": double: 3 -float: 3 Function: "tanh_towardzero": double: 2 -float: 2 Function: "tanh_upward": double: 3 -float: 3 Function: "tanpi": double: 2 diff --git a/sysdeps/csky/fpu/libm-test-ulps b/sysdeps/csky/fpu/libm-test-ulps index 3824f00415..6ba3cef623 100644 --- a/sysdeps/csky/fpu/libm-test-ulps +++ b/sysdeps/csky/fpu/libm-test-ulps @@ -971,19 +971,15 @@ double: 1 Function: "tanh": double: 2 -float: 2 Function: "tanh_downward": double: 3 -float: 3 Function: "tanh_towardzero": double: 2 -float: 2 Function: "tanh_upward": double: 3 -float: 3 Function: "tgamma": double: 9 diff --git a/sysdeps/csky/nofpu/libm-test-ulps b/sysdeps/csky/nofpu/libm-test-ulps index 34f5eb52a2..4f428a65c5 100644 --- a/sysdeps/csky/nofpu/libm-test-ulps +++ b/sysdeps/csky/nofpu/libm-test-ulps @@ -1002,19 +1002,15 @@ double: 1 Function: "tanh": double: 2 -float: 2 Function: "tanh_downward": double: 3 -float: 3 Function: "tanh_towardzero": double: 2 -float: 2 Function: "tanh_upward": double: 3 -float: 3 Function: "tgamma": double: 9 diff --git a/sysdeps/hppa/fpu/libm-test-ulps b/sysdeps/hppa/fpu/libm-test-ulps index e48fb8a66e..759e224308 100644 --- a/sysdeps/hppa/fpu/libm-test-ulps +++ b/sysdeps/hppa/fpu/libm-test-ulps @@ -1176,19 +1176,15 @@ double: 1 Function: "tanh": double: 2 -float: 2 Function: "tanh_downward": double: 3 -float: 3 Function: "tanh_towardzero": double: 2 -float: 2 Function: "tanh_upward": double: 3 -float: 3 Function: "tanpi": double: 2 diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps index d545682fd9..423061e12e 100644 --- a/sysdeps/i386/fpu/libm-test-ulps +++ b/sysdeps/i386/fpu/libm-test-ulps @@ -1754,25 +1754,21 @@ ldouble: 2 Function: "tanh": double: 2 -float: 2 float128: 2 ldouble: 3 Function: "tanh_downward": double: 3 -float: 3 float128: 4 ldouble: 4 Function: "tanh_towardzero": double: 2 -float: 2 float128: 3 ldouble: 3 Function: "tanh_upward": double: 3 -float: 3 float128: 3 ldouble: 4 diff --git a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps index ad9a52749b..466e68dae0 100644 --- a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps +++ b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps @@ -1759,25 +1759,21 @@ ldouble: 2 Function: "tanh": double: 2 -float: 2 float128: 2 ldouble: 3 Function: "tanh_downward": double: 3 -float: 3 float128: 4 ldouble: 4 Function: "tanh_towardzero": double: 2 -float: 2 float128: 3 ldouble: 3 Function: "tanh_upward": double: 3 -float: 3 float128: 3 ldouble: 4 diff --git a/sysdeps/ieee754/flt-32/s_tanhf.c b/sysdeps/ieee754/flt-32/s_tanhf.c index 2c12f04569..e07f3589b8 100644 --- a/sysdeps/ieee754/flt-32/s_tanhf.c +++ b/sysdeps/ieee754/flt-32/s_tanhf.c @@ -1,63 +1,90 @@ -/* s_tanhf.c -- float version of s_tanh.c. - */ +/* Correctly-rounded hyperbolic tangent function for binary32 value. -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ +Copyright (c) 2022-2024 Alexei Sibidanov. -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: s_tanhf.c,v 1.4 1995/05/10 20:48:24 jtc Exp $"; -#endif +The original version of this file was copied from the CORE-MATH +project (file src/binary32/tanh/tanhf.c, revision b1ecd83). + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ -#include #include -#include -#include +#include #include +#include "math_config.h" -static const float one=1.0, two=2.0, tiny = 1.0e-30; - -float __tanhf(float x) +float +__tanhf (float x) { - float t,z; - int32_t jx,ix; - - GET_FLOAT_WORD(jx,x); - ix = jx&0x7fffffff; - - /* x is INF or NaN */ - if(ix>=0x7f800000) { - if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ - else return one/x-one; /* tanh(NaN) = NaN */ + double z = x; + uint32_t ux = asuint (x); + int e = (ux >> 23) & 0xff; + if (__glibc_unlikely (e == 0xff)) + { + if (ux << 9) + return x + x; /* x = nan */ + static const float ir[] = { 1.0f, -1.0f }; + return ir[ux >> 31]; /* x = +-inf */ + } + if (__glibc_unlikely (e < 115)) + { + if (__glibc_unlikely (e < 102)) + { + if (__glibc_unlikely ((ux << 1) == 0)) + return x; + return fmaf (-x, fabsf (x), x); } - - /* |x| < 22 */ - if (ix < 0x41b00000) { /* |x|<22 */ - if (ix == 0) - return x; /* x == +-0 */ - if (ix<0x24000000) /* |x|<2**-55 */ - { - math_check_force_underflow (x); - return x*(one+x); /* tanh(small) = small */ - } - if (ix>=0x3f800000) { /* |x|>=1 */ - t = __expm1f(two*fabsf(x)); - z = one - two/(t+two); - } else { - t = __expm1f(-two*fabsf(x)); - z= -t/(t+two); - } - /* |x| > 22, return +-1 */ - } else { - z = one - tiny; /* raised inexact flag */ - } - return (jx>=0)? z: -z; + float x2 = x * x; + return fmaf (x, -0x1.555556p-2f * x2, x); + } + if ((ux << 1) > (0x41102cb3u << 1)) + return copysignf (1.0f, x) - copysignf (0x1p-25f, x); + double z2 = z * z; + double z4 = z2 * z2; + double z8 = z4 * z4; + static const double cn[] = + { + 0x1p+0, 0x1.30877b8b72d33p-3, 0x1.694aa09ae9e5ep-8, + 0x1.4101377abb729p-14, 0x1.e0392b1db0018p-22, 0x1.2533756e546f7p-30, + 0x1.d62e5abe6ae8ap-41, 0x1.b06be534182dep-54 + }; + static const double cd[] = + { + 0x1p+0, 0x1.ed99131b0ebeap-2, 0x1.0d27ed6c95a69p-5, + 0x1.7cbdaca0e9fccp-11, 0x1.b4e60b892578ep-18, 0x1.a6f707c5c71abp-26, + 0x1.35a8b6e2cd94cp-35, 0x1.ca8230677aa01p-47 + }; + double n0 = cn[0] + z2 * cn[1]; + double n2 = cn[2] + z2 * cn[3]; + double n4 = cn[4] + z2 * cn[5]; + double n6 = cn[6] + z2 * cn[7]; + n0 += z4 * n2; + n4 += z4 * n6; + n0 += z8 * n4; + double d0 = cd[0] + z2 * cd[1]; + double d2 = cd[2] + z2 * cd[3]; + double d4 = cd[4] + z2 * cd[5]; + double d6 = cd[6] + z2 * cd[7]; + d0 += z4 * d2; + d4 += z4 * d6; + d0 += z8 * d4; + double r = z * n0 / d0; + return r; } libm_alias_float (__tanh, tanh) diff --git a/sysdeps/loongarch/lp64/libm-test-ulps b/sysdeps/loongarch/lp64/libm-test-ulps index 1e57c6a4df..0840e9e190 100644 --- a/sysdeps/loongarch/lp64/libm-test-ulps +++ b/sysdeps/loongarch/lp64/libm-test-ulps @@ -1325,22 +1325,18 @@ ldouble: 1 Function: "tanh": double: 2 -float: 2 ldouble: 2 Function: "tanh_downward": double: 3 -float: 3 ldouble: 4 Function: "tanh_towardzero": double: 2 -float: 2 ldouble: 3 Function: "tanh_upward": double: 3 -float: 3 ldouble: 3 Function: "tgamma": diff --git a/sysdeps/m68k/m680x0/fpu/libm-test-ulps b/sysdeps/m68k/m680x0/fpu/libm-test-ulps index 1ef5e0e5a3..6acb5cd043 100644 --- a/sysdeps/m68k/m680x0/fpu/libm-test-ulps +++ b/sysdeps/m68k/m680x0/fpu/libm-test-ulps @@ -1152,15 +1152,12 @@ double: 1 Function: "tanh_downward": double: 1 -float: 1 Function: "tanh_towardzero": double: 1 -float: 1 Function: "tanh_upward": double: 1 -float: 1 Function: "tgamma": double: 3 diff --git a/sysdeps/microblaze/libm-test-ulps b/sysdeps/microblaze/libm-test-ulps index 0f0e1fb35d..7a6d75f91c 100644 --- a/sysdeps/microblaze/libm-test-ulps +++ b/sysdeps/microblaze/libm-test-ulps @@ -233,7 +233,6 @@ double: 2 Function: "tanh": double: 2 -float: 2 Function: "tgamma": double: 5 diff --git a/sysdeps/mips/mips32/libm-test-ulps b/sysdeps/mips/mips32/libm-test-ulps index 58223df3b4..3ede885f9e 100644 --- a/sysdeps/mips/mips32/libm-test-ulps +++ b/sysdeps/mips/mips32/libm-test-ulps @@ -1050,19 +1050,15 @@ double: 1 Function: "tanh": double: 2 -float: 2 Function: "tanh_downward": double: 3 -float: 3 Function: "tanh_towardzero": double: 2 -float: 2 Function: "tanh_upward": double: 3 -float: 3 Function: "tgamma": double: 9 diff --git a/sysdeps/mips/mips64/libm-test-ulps b/sysdeps/mips/mips64/libm-test-ulps index efa76ec249..891f887030 100644 --- a/sysdeps/mips/mips64/libm-test-ulps +++ b/sysdeps/mips/mips64/libm-test-ulps @@ -1336,22 +1336,18 @@ ldouble: 1 Function: "tanh": double: 2 -float: 2 ldouble: 2 Function: "tanh_downward": double: 3 -float: 3 ldouble: 4 Function: "tanh_towardzero": double: 2 -float: 2 ldouble: 3 Function: "tanh_upward": double: 3 -float: 3 ldouble: 3 Function: "tgamma": diff --git a/sysdeps/or1k/fpu/libm-test-ulps b/sysdeps/or1k/fpu/libm-test-ulps index 5900e6d6d9..c27afc99c8 100644 --- a/sysdeps/or1k/fpu/libm-test-ulps +++ b/sysdeps/or1k/fpu/libm-test-ulps @@ -984,19 +984,15 @@ double: 1 Function: "tanh": double: 2 -float: 2 Function: "tanh_downward": double: 3 -float: 3 Function: "tanh_towardzero": double: 2 -float: 2 Function: "tanh_upward": double: 3 -float: 3 Function: "tgamma": double: 9 diff --git a/sysdeps/or1k/nofpu/libm-test-ulps b/sysdeps/or1k/nofpu/libm-test-ulps index 6f60e83486..46ef288135 100644 --- a/sysdeps/or1k/nofpu/libm-test-ulps +++ b/sysdeps/or1k/nofpu/libm-test-ulps @@ -1013,19 +1013,15 @@ double: 1 Function: "tanh": double: 2 -float: 2 Function: "tanh_downward": double: 3 -float: 3 Function: "tanh_towardzero": double: 2 -float: 2 Function: "tanh_upward": double: 3 -float: 3 Function: "tanpi": double: 2 diff --git a/sysdeps/powerpc/fpu/libm-test-ulps b/sysdeps/powerpc/fpu/libm-test-ulps index 9fe6f82a41..07b91f8534 100644 --- a/sysdeps/powerpc/fpu/libm-test-ulps +++ b/sysdeps/powerpc/fpu/libm-test-ulps @@ -1861,25 +1861,21 @@ ldouble: 3 Function: "tanh": double: 2 -float: 2 float128: 2 ldouble: 1 Function: "tanh_downward": double: 3 -float: 3 float128: 4 ldouble: 4 Function: "tanh_towardzero": double: 2 -float: 2 float128: 3 ldouble: 4 Function: "tanh_upward": double: 3 -float: 3 float128: 3 ldouble: 6 diff --git a/sysdeps/powerpc/nofpu/libm-test-ulps b/sysdeps/powerpc/nofpu/libm-test-ulps index 769c14e81d..3f02dc0be2 100644 --- a/sysdeps/powerpc/nofpu/libm-test-ulps +++ b/sysdeps/powerpc/nofpu/libm-test-ulps @@ -1452,22 +1452,18 @@ ldouble: 3 Function: "tanh": double: 2 -float: 2 ldouble: 1 Function: "tanh_downward": double: 3 -float: 3 ldouble: 4 Function: "tanh_towardzero": double: 2 -float: 2 ldouble: 4 Function: "tanh_upward": double: 3 -float: 3 ldouble: 6 Function: "tgamma": diff --git a/sysdeps/riscv/nofpu/libm-test-ulps b/sysdeps/riscv/nofpu/libm-test-ulps index 3ce20f4bb1..055826625c 100644 --- a/sysdeps/riscv/nofpu/libm-test-ulps +++ b/sysdeps/riscv/nofpu/libm-test-ulps @@ -1265,22 +1265,18 @@ ldouble: 1 Function: "tanh": double: 2 -float: 2 ldouble: 2 Function: "tanh_downward": double: 3 -float: 3 ldouble: 4 Function: "tanh_towardzero": double: 2 -float: 2 ldouble: 3 Function: "tanh_upward": double: 3 -float: 3 ldouble: 3 Function: "tgamma": diff --git a/sysdeps/riscv/rvd/libm-test-ulps b/sysdeps/riscv/rvd/libm-test-ulps index 98146886d9..69e0eb2e42 100644 --- a/sysdeps/riscv/rvd/libm-test-ulps +++ b/sysdeps/riscv/rvd/libm-test-ulps @@ -1323,22 +1323,18 @@ ldouble: 1 Function: "tanh": double: 2 -float: 2 ldouble: 2 Function: "tanh_downward": double: 3 -float: 3 ldouble: 4 Function: "tanh_towardzero": double: 2 -float: 2 ldouble: 3 Function: "tanh_upward": double: 3 -float: 3 ldouble: 3 Function: "tgamma": diff --git a/sysdeps/s390/fpu/libm-test-ulps b/sysdeps/s390/fpu/libm-test-ulps index e8a3754e4c..1a91bffcfe 100644 --- a/sysdeps/s390/fpu/libm-test-ulps +++ b/sysdeps/s390/fpu/libm-test-ulps @@ -1362,22 +1362,18 @@ ldouble: 1 Function: "tanh": double: 2 -float: 2 ldouble: 2 Function: "tanh_downward": double: 3 -float: 3 ldouble: 4 Function: "tanh_towardzero": double: 2 -float: 2 ldouble: 3 Function: "tanh_upward": double: 3 -float: 3 ldouble: 3 Function: "tanpi": diff --git a/sysdeps/sh/libm-test-ulps b/sysdeps/sh/libm-test-ulps index 3c07cd1317..9378516d58 100644 --- a/sysdeps/sh/libm-test-ulps +++ b/sysdeps/sh/libm-test-ulps @@ -486,11 +486,9 @@ double: 1 Function: "tanh": double: 2 -float: 2 Function: "tanh_towardzero": double: 2 -float: 2 Function: "tgamma": double: 9 diff --git a/sysdeps/sparc/fpu/libm-test-ulps b/sysdeps/sparc/fpu/libm-test-ulps index ec9d2d9d21..9123fff50b 100644 --- a/sysdeps/sparc/fpu/libm-test-ulps +++ b/sysdeps/sparc/fpu/libm-test-ulps @@ -1377,22 +1377,18 @@ ldouble: 1 Function: "tanh": double: 2 -float: 2 ldouble: 2 Function: "tanh_downward": double: 3 -float: 3 ldouble: 4 Function: "tanh_towardzero": double: 2 -float: 2 ldouble: 3 Function: "tanh_upward": double: 3 -float: 3 ldouble: 3 Function: "tanpi": diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps index 7ce0714683..ad936ad32f 100644 --- a/sysdeps/x86_64/fpu/libm-test-ulps +++ b/sysdeps/x86_64/fpu/libm-test-ulps @@ -2280,25 +2280,21 @@ float: 2 Function: "tanh": double: 2 -float: 2 float128: 2 ldouble: 3 Function: "tanh_downward": double: 3 -float: 3 float128: 4 ldouble: 4 Function: "tanh_towardzero": double: 2 -float: 2 float128: 3 ldouble: 3 Function: "tanh_upward": double: 3 -float: 3 float128: 3 ldouble: 4