Hi all,
On 7/3/2025 9:21 PM, Jakub Jelinek wrote:
On Thu, Jul 03, 2025 at 02:43:43PM +0200, Michael Matz wrote:
Hello,
On Thu, 3 Jul 2025, Yuao Ma wrote:
This patch adds the required function for Fortran trigonometric functions to
work with glibc versions prior to 2.26. It's based on glibc source commit
632d895f3e5d98162f77b9c3c1da4ec19968b671.
I've built it successfully on my end. Documentation is also included.
Please take a look when you have a moment.
+__float128
+cospiq (__float128 x)
+{
...
+ if (__builtin_islessequal (x, 0.25Q))
+ return cosq (M_PIq * x);
Isn't the whole raison d'etre for the trig-pi functions that the internal
argument reduction against multiples of pi becomes trivial and hence (a)
performant, and (b) doesn't introduce rounding artifacts? Expressing the
trig-pi functions in terms of their counterparts completely defeats this
purpose. The other way around would be more sensible for the cases where
it works, but the above doesn't seem very attractive.
glibc has
FLOAT
M_DECL_FUNC (__cospi) (FLOAT x)
{
if (isless (M_FABS (x), M_EPSILON))
return M_LIT (1.0);
if (__glibc_unlikely (isinf (x)))
__set_errno (EDOM);
x = M_FABS (x - M_LIT (2.0) * M_SUF (round) (M_LIT (0.5) * x));
if (islessequal (x, M_LIT (0.25)))
return M_SUF (__cos) (M_MLIT (M_PI) * x);
else if (x == M_LIT (0.5))
return M_LIT (0.0);
else if (islessequal (x, M_LIT (0.75)))
return M_SUF (__sin) (M_MLIT (M_PI) * (M_LIT (0.5) - x));
else
return -M_SUF (__cos) (M_MLIT (M_PI) * (M_LIT (1.0) - x));
}
for this case, so if it is incorrect, has too bad precision
or there are better ways to do it, then perhaps it should be changed
on the glibc side first and then ported to libquadmath.
That's exactly what I want to say. I only touched the generation script;
the other main changes are borrowed from glibc. Therefore, it should be
at least as precise as the glibc generic implementation. If the current
implementation isn't sufficient, we can update glibc first and then
mirror the changes back. This is only used for systems with glibc
versions prior to 2.26. Modern systems will use the implementation
directly from glibc, which should avoid this potential issue.
Regarding math function implementation, I think LLVM-libc provides a
great example. While it may not be as performant as its glibc
equivalent, its structure is very clear. Even for a newcomer like me,
who isn't very familiar with computational mathematics, I can grasp the
basic ideas of implementation and testing, such as nan/inf handling,
polynomial curve fitting, exception values, and range reduction. I'd
love to learn from and contribute to the glibc generic implementation as
Joseph suggested, but it seems it will take more time to get familiar
with the glibc source code. Hopefully, I'll be able to do that one day.
Regarding the patch itself, the previous version was missing the
declaration in the header file. The newly attached version fixes this.
Is this patch good to go, or does it need further amendment? Looking
forward to your further review comments.
Thanks,
Yuao
From 719886689fd21555c9ba1bd63a44111408c0f01d Mon Sep 17 00:00:00 2001
From: Yuao Ma <c...@outlook.com>
Date: Thu, 3 Jul 2025 23:01:38 +0800
Subject: [PATCH] libquadmath: add quad support for trig-pi functions
This function is required for Fortran trigonometric functions with glibc <2.26.
Use glibc commit 632d895f3e5d98162f77b9c3c1da4ec19968b671.
libquadmath/ChangeLog:
* Makefile.am: Add sources to makefile.
* Makefile.in: Regen makefile.
* libquadmath.texi: Add doc for trig-pi funcs.
* quadmath.h (acospiq, asinpiq, atanpiq, atan2piq, cospiq, sinpiq,
tanpiq): New.
* update-quadmath.py: Update generation script.
* math/acospiq.c: New file.
* math/asinpiq.c: New file.
* math/atan2piq.c: New file.
* math/atanpiq.c: New file.
* math/cospiq.c: New file.
* math/sinpiq.c: New file.
* math/tanpiq.c: New file.
Signed-off-by: Yuao Ma <c...@outlook.com>
---
libquadmath/Makefile.am | 2 ++
libquadmath/Makefile.in | 26 ++++++++++++--
libquadmath/libquadmath.texi | 7 ++++
libquadmath/math/acospiq.c | 33 ++++++++++++++++++
libquadmath/math/asinpiq.c | 40 ++++++++++++++++++++++
libquadmath/math/atan2piq.c | 36 ++++++++++++++++++++
libquadmath/math/atanpiq.c | 35 +++++++++++++++++++
libquadmath/math/cospiq.c | 37 ++++++++++++++++++++
libquadmath/math/sinpiq.c | 44 ++++++++++++++++++++++++
libquadmath/math/tanpiq.c | 62 ++++++++++++++++++++++++++++++++++
libquadmath/quadmath.h | 7 ++++
libquadmath/update-quadmath.py | 48 ++++++++++++++++++--------
12 files changed, 359 insertions(+), 18 deletions(-)
create mode 100644 libquadmath/math/acospiq.c
create mode 100644 libquadmath/math/asinpiq.c
create mode 100644 libquadmath/math/atan2piq.c
create mode 100644 libquadmath/math/atanpiq.c
create mode 100644 libquadmath/math/cospiq.c
create mode 100644 libquadmath/math/sinpiq.c
create mode 100644 libquadmath/math/tanpiq.c
diff --git a/libquadmath/Makefile.am b/libquadmath/Makefile.am
index 93806106abb..a1b17fd7897 100644
--- a/libquadmath/Makefile.am
+++ b/libquadmath/Makefile.am
@@ -70,6 +70,8 @@ libquadmath_la_SOURCES = \
math/llrintq.c math/log2q.c math/lrintq.c math/nearbyintq.c math/remquoq.c \
math/ccoshq.c math/cexpq.c math/clog10q.c math/clogq.c math/csinq.c \
math/csinhq.c math/csqrtq.c math/ctanq.c math/ctanhq.c \
+ math/acospiq.c math/asinpiq.c math/atanpiq.c math/atan2piq.c \
+ math/cospiq.c math/sinpiq.c math/tanpiq.c \
printf/addmul_1.c printf/add_n.c printf/cmp.c printf/divrem.c \
printf/flt1282mpn.c printf/fpioconst.c printf/lshift.c printf/mul_1.c \
printf/mul_n.c printf/mul.c printf/printf_fphex.c printf/printf_fp.c \
diff --git a/libquadmath/Makefile.in b/libquadmath/Makefile.in
index ff3373064b1..b1d6666542c 100644
--- a/libquadmath/Makefile.in
+++ b/libquadmath/Makefile.in
@@ -197,9 +197,13 @@ am__dirstamp = $(am__leading_dot)dirstamp
@BUILD_LIBQUADMATH_TRUE@ math/clog10q.lo math/clogq.lo \
@BUILD_LIBQUADMATH_TRUE@ math/csinq.lo math/csinhq.lo \
@BUILD_LIBQUADMATH_TRUE@ math/csqrtq.lo math/ctanq.lo \
-@BUILD_LIBQUADMATH_TRUE@ math/ctanhq.lo printf/addmul_1.lo \
-@BUILD_LIBQUADMATH_TRUE@ printf/add_n.lo printf/cmp.lo \
-@BUILD_LIBQUADMATH_TRUE@ printf/divrem.lo printf/flt1282mpn.lo \
+@BUILD_LIBQUADMATH_TRUE@ math/ctanhq.lo math/acospiq.lo \
+@BUILD_LIBQUADMATH_TRUE@ math/asinpiq.lo math/atanpiq.lo \
+@BUILD_LIBQUADMATH_TRUE@ math/atan2piq.lo math/cospiq.lo \
+@BUILD_LIBQUADMATH_TRUE@ math/sinpiq.lo math/tanpiq.lo \
+@BUILD_LIBQUADMATH_TRUE@ printf/addmul_1.lo printf/add_n.lo \
+@BUILD_LIBQUADMATH_TRUE@ printf/cmp.lo printf/divrem.lo \
+@BUILD_LIBQUADMATH_TRUE@ printf/flt1282mpn.lo \
@BUILD_LIBQUADMATH_TRUE@ printf/fpioconst.lo printf/lshift.lo \
@BUILD_LIBQUADMATH_TRUE@ printf/mul_1.lo printf/mul_n.lo \
@BUILD_LIBQUADMATH_TRUE@ printf/mul.lo printf/printf_fphex.lo \
@@ -495,6 +499,8 @@ AUTOMAKE_OPTIONS = foreign info-in-builddir
@BUILD_LIBQUADMATH_TRUE@ math/llrintq.c math/log2q.c math/lrintq.c
math/nearbyintq.c math/remquoq.c \
@BUILD_LIBQUADMATH_TRUE@ math/ccoshq.c math/cexpq.c math/clog10q.c
math/clogq.c math/csinq.c \
@BUILD_LIBQUADMATH_TRUE@ math/csinhq.c math/csqrtq.c math/ctanq.c
math/ctanhq.c \
+@BUILD_LIBQUADMATH_TRUE@ math/acospiq.c math/asinpiq.c math/atanpiq.c
math/atan2piq.c \
+@BUILD_LIBQUADMATH_TRUE@ math/cospiq.c math/sinpiq.c math/tanpiq.c \
@BUILD_LIBQUADMATH_TRUE@ printf/addmul_1.c printf/add_n.c printf/cmp.c
printf/divrem.c \
@BUILD_LIBQUADMATH_TRUE@ printf/flt1282mpn.c printf/fpioconst.c
printf/lshift.c printf/mul_1.c \
@BUILD_LIBQUADMATH_TRUE@ printf/mul_n.c printf/mul.c printf/printf_fphex.c
printf/printf_fp.c \
@@ -780,6 +786,13 @@ math/csinhq.lo: math/$(am__dirstamp)
math/$(DEPDIR)/$(am__dirstamp)
math/csqrtq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
math/ctanq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
math/ctanhq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
+math/acospiq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
+math/asinpiq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
+math/atanpiq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
+math/atan2piq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
+math/cospiq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
+math/sinpiq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
+math/tanpiq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
printf/$(am__dirstamp):
@$(MKDIR_P) printf
@: > printf/$(am__dirstamp)
@@ -845,11 +858,15 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/acoshq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/acospiq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/acosq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/asinhq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/asinpiq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/asinq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/atan2piq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/atan2q.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/atanhq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/atanpiq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/atanq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/cacoshq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/cacosq.Plo@am__quote@
@@ -869,6 +886,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/conjq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/copysignq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/coshq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/cospiq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/cosq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/cosq_kernel.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/cprojq.Plo@am__quote@
@@ -929,10 +947,12 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/sincosq.Plo@am__quote@
@AMDEP_TRUE@@am__include@
@am__quote@math/$(DEPDIR)/sincosq_kernel.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/sinhq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/sinpiq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/sinq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/sinq_kernel.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/sqrtq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/tanhq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/tanpiq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/tanq.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/tanq_kernel.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/tgammaq.Plo@am__quote@
diff --git a/libquadmath/libquadmath.texi b/libquadmath/libquadmath.texi
index af0a774b1df..ea17dde6f74 100644
--- a/libquadmath/libquadmath.texi
+++ b/libquadmath/libquadmath.texi
@@ -145,15 +145,20 @@ The following mathematical functions are available:
@table @asis
@item @code{acosq}: arc cosine function
@item @code{acoshq}: inverse hyperbolic cosine function
+@item @code{acospiq}: arc cosine function, divided by pi
@item @code{asinq}: arc sine function
@item @code{asinhq}: inverse hyperbolic sine function
+@item @code{asinpiq}: arc sine function, divided by pi
@item @code{atanq}: arc tangent function
@item @code{atanhq}: inverse hyperbolic tangent function
+@item @code{atanpiq}: arc tangent function, divided by pi
@item @code{atan2q}: arc tangent function
+@item @code{atan2piq}: arc tangent function, divided by pi
@item @code{cbrtq}: cube root function
@item @code{ceilq}: ceiling value function
@item @code{copysignq}: copy sign of a number
@item @code{coshq}: hyperbolic cosine function
+@item @code{cospiq}: cosine function, divided by pi
@item @code{cosq}: cosine function
@item @code{erfq}: error function
@item @code{erfcq}: complementary error function
@@ -204,10 +209,12 @@ The following mathematical functions are available:
@item @code{signbitq}: return sign bit
@item @code{sincosq}: calculate sine and cosine simultaneously
@item @code{sinhq}: hyperbolic sine function
+@item @code{sinpiq}: sine function, divided by pi
@item @code{sinq}: sine function
@item @code{sqrtq}: square root function
@item @code{tanq}: tangent function
@item @code{tanhq}: hyperbolic tangent function
+@item @code{tanpiq}: tangent function, divided by pi
@need 800
@item @code{tgammaq}: true gamma function
@item @code{truncq}: round to integer, towards zero
diff --git a/libquadmath/math/acospiq.c b/libquadmath/math/acospiq.c
new file mode 100644
index 00000000000..272e8914ce3
--- /dev/null
+++ b/libquadmath/math/acospiq.c
@@ -0,0 +1,33 @@
+/* Return arc cosine of X, divided by pi.
+ Copyright (C) 2024-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include "quadmath-imp.h"
+
+__float128
+acospiq (__float128 x)
+{
+ if (__glibc_unlikely (__builtin_isgreater (fabsq (x), 1.0Q)))
+ {
+ errno = EDOM;
+ return (x - x) / (x - x);
+ }
+ __float128 ret = acosq (x) / M_PIq;
+ /* Ensure that rounding upward for both acos and the division cannot
+ yield a return value from acospi greater than 1. */
+ return __builtin_isgreater (ret, 1.0Q) ? 1.0Q : ret;
+}
diff --git a/libquadmath/math/asinpiq.c b/libquadmath/math/asinpiq.c
new file mode 100644
index 00000000000..5e72d11d32d
--- /dev/null
+++ b/libquadmath/math/asinpiq.c
@@ -0,0 +1,40 @@
+/* Return arc sine of X, divided by pi.
+ Copyright (C) 2024-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include "quadmath-imp.h"
+
+__float128
+asinpiq (__float128 x)
+{
+ if (__glibc_unlikely (!__builtin_islessequal (fabsq (x), 1.0Q)))
+ {
+ if (!isnanq (x))
+ errno = EDOM;
+ return (x - x) / (x - x);
+ }
+ __float128 ret = math_narrow_eval (asinq (x) / M_PIq);
+ math_check_force_underflow (ret);
+ if (x != 0 && ret == 0)
+ errno = ERANGE;
+ /* Ensure that rounding away from zero for both asin and the
+ division cannot yield a return value from asinpi with absolute
+ value greater than 0.5. */
+ return (__builtin_isgreater (fabsq (ret), 0.5Q)
+ ? copysignq (0.5Q, ret)
+ : ret);
+}
diff --git a/libquadmath/math/atan2piq.c b/libquadmath/math/atan2piq.c
new file mode 100644
index 00000000000..e60d0c8222b
--- /dev/null
+++ b/libquadmath/math/atan2piq.c
@@ -0,0 +1,36 @@
+/* Return arc tangent of Y/X, divided by pi.
+ Copyright (C) 2024-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include "quadmath-imp.h"
+
+__float128
+atan2piq (__float128 y, __float128 x)
+{
+ __float128 ret = math_narrow_eval (atan2q (y, x)
+ / M_PIq);
+ if (__glibc_likely (!isnanq (ret)))
+ math_check_force_underflow (ret);
+ if (ret == 0 && y != 0 && finiteq (x))
+ errno = ERANGE;
+ /* Ensure that rounding away from zero for both atan2 and the
+ division cannot yield a return value from atan2pi with absolute
+ value greater than 1. */
+ return (__builtin_isgreater (fabsq (ret), 1.0Q)
+ ? copysignq (1.0Q, ret)
+ : ret);
+}
diff --git a/libquadmath/math/atanpiq.c b/libquadmath/math/atanpiq.c
new file mode 100644
index 00000000000..975ae94f819
--- /dev/null
+++ b/libquadmath/math/atanpiq.c
@@ -0,0 +1,35 @@
+/* Return arc tangent of X, divided by pi.
+ Copyright (C) 2024-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include "quadmath-imp.h"
+
+__float128
+atanpiq (__float128 x)
+{
+ __float128 ret = math_narrow_eval (atanq (x) / M_PIq);
+ if (__glibc_likely (!isnanq (x)))
+ math_check_force_underflow (ret);
+ if (x != 0 && ret == 0)
+ errno = ERANGE;
+ /* Ensure that rounding away from zero for both atan and the
+ division cannot yield a return value from atanpi with absolute
+ value greater than 0.5. */
+ return (__builtin_isgreater (fabsq (ret), 0.5Q)
+ ? copysignq (0.5Q, ret)
+ : ret);
+}
diff --git a/libquadmath/math/cospiq.c b/libquadmath/math/cospiq.c
new file mode 100644
index 00000000000..3e28504d146
--- /dev/null
+++ b/libquadmath/math/cospiq.c
@@ -0,0 +1,37 @@
+/* Return cosine of pi * X.
+ Copyright (C) 2024-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include "quadmath-imp.h"
+
+__float128
+cospiq (__float128 x)
+{
+ if (__builtin_isless (fabsq (x), FLT128_EPSILON))
+ return 1.0Q;
+ if (__glibc_unlikely (isinfq (x)))
+ errno = EDOM;
+ x = fabsq (x - 2.0Q * roundq (0.5Q * x));
+ if (__builtin_islessequal (x, 0.25Q))
+ return cosq (M_PIq * x);
+ else if (x == 0.5Q)
+ return 0.0Q;
+ else if (__builtin_islessequal (x, 0.75Q))
+ return sinq (M_PIq * (0.5Q - x));
+ else
+ return -cosq (M_PIq * (1.0Q - x));
+}
diff --git a/libquadmath/math/sinpiq.c b/libquadmath/math/sinpiq.c
new file mode 100644
index 00000000000..3c16616fedd
--- /dev/null
+++ b/libquadmath/math/sinpiq.c
@@ -0,0 +1,44 @@
+/* Return sine of pi * X.
+ Copyright (C) 2024-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include "quadmath-imp.h"
+
+__float128
+sinpiq (__float128 x)
+{
+ if (__builtin_isless (fabsq (x), FLT128_EPSILON))
+ {
+ __float128 ret = M_PIq * x;
+ math_check_force_underflow (ret);
+ return ret;
+ }
+ if (__glibc_unlikely (isinfq (x)))
+ errno = EDOM;
+ __float128 y = x - 2.0Q * roundq (0.5Q * x);
+ __float128 absy = fabsq (y);
+ if (absy == 0.0Q || absy == 1.0Q)
+ return copysignq (0.0Q, x);
+ else if (__builtin_islessequal (absy, 0.25Q))
+ return sinq (M_PIq * y);
+ else if (__builtin_islessequal (absy, 0.75Q))
+ return copysignq (cosq (M_PIq * (0.5Q - absy)),
+ y);
+ else
+ return copysignq (sinq (M_PIq * (1.0Q - absy)),
+ y);
+}
diff --git a/libquadmath/math/tanpiq.c b/libquadmath/math/tanpiq.c
new file mode 100644
index 00000000000..e7aac0538e9
--- /dev/null
+++ b/libquadmath/math/tanpiq.c
@@ -0,0 +1,62 @@
+/* Return tangent of pi * X.
+ Copyright (C) 2024-2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include "quadmath-imp.h"
+
+__float128
+tanpiq (__float128 x)
+{
+ if (__builtin_isless (fabsq (x), FLT128_EPSILON))
+ {
+ __float128 ret = M_PIq * x;
+ math_check_force_underflow (ret);
+ return ret;
+ }
+ if (__glibc_unlikely (isinfq (x)))
+ errno = EDOM;
+ __float128 y = x - 2.0Q * roundq (0.5Q * x);
+ __float128 absy = fabsq (y);
+ if (absy == 0.0Q)
+ /* For even integers, return +0 if positive and -0 if negative (so
+ matching sinpi(x)/cospi(x)). */
+ return copysignq (0.0Q, x);
+ else if (absy == 1.0Q)
+ /* For odd integers, return -0 if positive and +0 if negative (so
+ matching sinpi(x)/cospi(x)). */
+ return copysignq (0.0Q, -x);
+ else if (absy == 0.5Q)
+ {
+ /* Return infinity with positive sign for an even integer + 0.5
+ and negative sign for an odd integer + 0.5 (so matching
+ sinpi(x)/cospi(x)). */
+ errno = ERANGE;
+ return 1.0 / copysignq (0.0Q, y);
+ }
+ /* Now we only care about the value of X mod 1, not mod 2. */
+ else if (__builtin_isgreater (absy, 0.5))
+ {
+ y -= copysignq (1.0Q, y);
+ absy = fabsq (y);
+ }
+ if (__builtin_islessequal (absy, 0.25Q))
+ return tanq (M_PIq * y);
+ else
+ return copysignq (1.0Q
+ / tanq (M_PIq * (0.5Q - absy)),
+ y);
+}
diff --git a/libquadmath/quadmath.h b/libquadmath/quadmath.h
index 81eb957d2fa..5996a6f0c7c 100644
--- a/libquadmath/quadmath.h
+++ b/libquadmath/quadmath.h
@@ -46,15 +46,20 @@ typedef _Complex float __attribute__((mode(KC)))
__complex128;
/* Prototypes for real functions */
extern __float128 acosq (__float128) __quadmath_throw;
extern __float128 acoshq (__float128) __quadmath_throw;
+extern __float128 acospiq (__float128) __quadmath_throw;
extern __float128 asinq (__float128) __quadmath_throw;
extern __float128 asinhq (__float128) __quadmath_throw;
+extern __float128 asinpiq (__float128) __quadmath_throw;
extern __float128 atanq (__float128) __quadmath_throw;
extern __float128 atanhq (__float128) __quadmath_throw;
+extern __float128 atanpiq (__float128) __quadmath_throw;
extern __float128 atan2q (__float128, __float128) __quadmath_throw;
+extern __float128 atan2piq (__float128, __float128) __quadmath_throw;
extern __float128 cbrtq (__float128) __quadmath_throw;
extern __float128 ceilq (__float128) __quadmath_throw;
extern __float128 copysignq (__float128, __float128) __quadmath_throw;
extern __float128 coshq (__float128) __quadmath_throw;
+extern __float128 cospiq (__float128) __quadmath_throw;
extern __float128 cosq (__float128) __quadmath_throw;
extern __float128 erfq (__float128) __quadmath_throw;
extern __float128 erfcq (__float128) __quadmath_throw;
@@ -103,10 +108,12 @@ extern __float128 scalbnq (__float128, int)
__quadmath_throw;
extern int signbitq (__float128) __quadmath_throw;
extern void sincosq (__float128, __float128 *, __float128 *) __quadmath_throw;
extern __float128 sinhq (__float128) __quadmath_throw;
+extern __float128 sinpiq (__float128) __quadmath_throw;
extern __float128 sinq (__float128) __quadmath_throw;
extern __float128 sqrtq (__float128) __quadmath_throw;
extern __float128 tanq (__float128) __quadmath_throw;
extern __float128 tanhq (__float128) __quadmath_throw;
+extern __float128 tanpiq (__float128) __quadmath_throw;
extern __float128 tgammaq (__float128) __quadmath_throw;
extern __float128 truncq (__float128) __quadmath_throw;
extern __float128 y0q (__float128) __quadmath_throw;
diff --git a/libquadmath/update-quadmath.py b/libquadmath/update-quadmath.py
index d40b2724dd3..252f836161c 100755
--- a/libquadmath/update-quadmath.py
+++ b/libquadmath/update-quadmath.py
@@ -178,21 +178,39 @@ def update_sources(glibc_srcdir, quadmath_srcdir):
's_truncl.c': 'truncq.c', 'x2y2m1l.c': 'x2y2m1q.c'
}
template_files = {
- 's_cacosh_template.c': 'cacoshq.c', 's_cacos_template.c': 'cacosq.c',
- 's_casinh_template.c': 'casinhq.c',
- 'k_casinh_template.c': 'casinhq_kernel.c',
- 's_casin_template.c': 'casinq.c', 's_catanh_template.c': 'catanhq.c',
- 's_catan_template.c': 'catanq.c', 's_ccosh_template.c': 'ccoshq.c',
- 's_cexp_template.c': 'cexpq.c', 'cimag_template.c': 'cimagq.c',
- 's_clog10_template.c': 'clog10q.c', 's_clog_template.c': 'clogq.c',
- 'conj_template.c': 'conjq.c', 's_cproj_template.c': 'cprojq.c',
- 'creal_template.c': 'crealq.c', 's_csinh_template.c': 'csinhq.c',
- 's_csin_template.c': 'csinq.c', 's_csqrt_template.c': 'csqrtq.c',
- 's_ctanh_template.c': 'ctanhq.c', 's_ctan_template.c': 'ctanq.c',
- 'e_exp2_template.c': 'exp2q.c', 's_fdim_template.c': 'fdimq.c',
- 's_fmax_template.c': 'fmaxq.c', 's_fmin_template.c': 'fminq.c',
- 's_ldexp_template.c': 'ldexpq.c'
- }
+ "s_acospi_template.c": "acospiq.c",
+ "s_asinpi_template.c": "asinpiq.c",
+ "s_atan2pi_template.c": "atan2piq.c",
+ "s_atanpi_template.c": "atanpiq.c",
+ "s_cacosh_template.c": "cacoshq.c",
+ "s_cacos_template.c": "cacosq.c",
+ "s_casinh_template.c": "casinhq.c",
+ "k_casinh_template.c": "casinhq_kernel.c",
+ "s_casin_template.c": "casinq.c",
+ "s_catanh_template.c": "catanhq.c",
+ "s_catan_template.c": "catanq.c",
+ "s_ccosh_template.c": "ccoshq.c",
+ "s_cexp_template.c": "cexpq.c",
+ "cimag_template.c": "cimagq.c",
+ "s_clog10_template.c": "clog10q.c",
+ "s_clog_template.c": "clogq.c",
+ "conj_template.c": "conjq.c",
+ "s_cospi_template.c": "cospiq.c",
+ "s_cproj_template.c": "cprojq.c",
+ "creal_template.c": "crealq.c",
+ "s_csinh_template.c": "csinhq.c",
+ "s_csin_template.c": "csinq.c",
+ "s_csqrt_template.c": "csqrtq.c",
+ "s_ctanh_template.c": "ctanhq.c",
+ "s_ctan_template.c": "ctanq.c",
+ "e_exp2_template.c": "exp2q.c",
+ "s_fdim_template.c": "fdimq.c",
+ "s_fmax_template.c": "fmaxq.c",
+ "s_fmin_template.c": "fminq.c",
+ "s_ldexp_template.c": "ldexpq.c",
+ "s_sinpi_template.c": "sinpiq.c",
+ "s_tanpi_template.c": "tanpiq.c",
+ }
# Some files have extra substitutions to apply.
extra_maps = defaultdict(dict)
extra_maps['expq.c'] = {r'#include "quadmath-imp\.h"\n':
--
2.43.0