This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Split fenv_private.h out of math_private.h more consistently [committed]
- From: Joseph Myers <joseph at codesourcery dot com>
- To: <libc-alpha at sourceware dot org>
- Date: Tue, 28 Aug 2018 20:49:32 +0000
- Subject: Split fenv_private.h out of math_private.h more consistently [committed]
On some architectures, the parts of math_private.h relating to the
floating-point environment are in a separate file fenv_private.h
included from math_private.h. As this is purely an
architecture-specific convention used by several architectures,
however, all such architectures still need their own math_private.h,
even if it has nothing to do beyond #include <fenv_private.h> and
#include_next <math_private.h>. The x86_64 case has the further
peculiarity of including the i386 file directly instead of having a
shared file in sysdeps/x86.
This patch makes the fenv_private.h name an architecture-independent
convention in glibc. The include of fenv_private.h from
math_private.h becomes architecture-independent (until callers are
updated to include fenv_private.h directly so the include from
math_private.h is no longer needed). Some architecture math_private.h
headers are removed if no longer needed, or renamed to fenv_private.h
if all they define belongs in that header; architecture fenv_private.h
headers now do require #include_next <fenv_private.h>. The i386
fenv_private.h file moves to sysdeps/x86/fpu/ to reflect how it is
actually shared with x86_64. The generic math_private.h gets a new
include of <stdbool.h>, as needed for bool in some prototypes in that
header (previously that was indirectly included via include/fenv.h,
which now only gets included too late in math_private.h, after those
prototypes).
Tested for x86_64 and x86, and tested with build-many-glibcs.py that
installed stripped shared libraries are unchanged by the patch.
Committed.
2018-08-28 Joseph Myers <joseph@codesourcery.com>
* sysdeps/aarch64/fpu/fenv_private.h: New file. Based on ....
* sysdeps/aarch64/fpu/math_private.h: ... this file. All contents
moved to fenv_private.h except for ...
(TOINT_INTRINSICS): Kept in math_private.h.
(roundtoint): Likewise.
(converttoint): Likewise.
* sysdeps/arm/fenv_private.h: Change multiple-include guard to
[ARM_FENV_PRIVATE_H]. Include next <fenv_private.h>.
* sysdeps/arm/math_private.h: Remove.
* sysdeps/generic/fenv_private.h: New file. Contents moved from
....
* sysdeps/generic/math_private.h: ... this file. Include
<stdbool.h>. Do not include <fenv.h> or <get-rounding-mode.h>.
Include <fenv_private.h>. Remove functions and macros moved to
fenv_private.h.
* sysdeps/i386/fpu/math_private.h: Remove.
* sysdeps/mips/math_private.h: Move to ....
* sysdeps/mips/fpu/fenv_private.h: ... here. Change
multiple-include guard to [MIPS_FENV_PRIVATE_H]. Remove
[__mips_hard_float] conditional. Include next <fenv_private.h>.
* sysdeps/powerpc/fpu/fenv_private.h: Change multiple-include
guard to [POWERPC_FENV_PRIVATE_H]. Include next <fenv_private.h>.
* sysdeps/powerpc/fpu/math_private.h: Do not include
<fenv_private.h>.
* sysdeps/riscv/rvf/math_private.h: Move to ....
* sysdeps/riscv/rvf/fenv_private.h: ... here. Change
multiple-include guard to [RISCV_FENV_PRIVATE_H]. Include next
<fenv_private.h>.
* sysdeps/sparc/fpu/fenv_private.h: Change multiple-include guard
to [SPARC_FENV_PRIVATE_H]. Include next <fenv_private.h>.
* sysdeps/sparc/fpu/math_private.h: Remove.
* sysdeps/i386/fpu/fenv_private.h: Move to ....
* sysdeps/x86/fpu/fenv_private.h: ... here. Change
multiple-include guard to [X86_FENV_PRIVATE_H]. Include next
<fenv_private.h>.
* sysdeps/x86_64/fpu/math_private.h: Do not include
<sysdeps/i386/fpu/fenv_private.h>.
diff --git a/sysdeps/aarch64/fpu/fenv_private.h b/sysdeps/aarch64/fpu/fenv_private.h
new file mode 100644
index 0000000000..e4f2483480
--- /dev/null
+++ b/sysdeps/aarch64/fpu/fenv_private.h
@@ -0,0 +1,303 @@
+/* Private floating point rounding and exceptions handling. AArch64 version.
+ Copyright (C) 2014-2018 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef AARCH64_FENV_PRIVATE_H
+#define AARCH64_FENV_PRIVATE_H 1
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+static __always_inline void
+libc_feholdexcept_aarch64 (fenv_t *envp)
+{
+ fpu_control_t fpcr;
+ fpu_control_t new_fpcr;
+ fpu_fpsr_t fpsr;
+ fpu_fpsr_t new_fpsr;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+ envp->__fpcr = fpcr;
+ envp->__fpsr = fpsr;
+
+ /* Clear exception flags and set all exceptions to non-stop. */
+ new_fpcr = fpcr & ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT);
+ new_fpsr = fpsr & ~FE_ALL_EXCEPT;
+
+ if (__glibc_unlikely (new_fpcr != fpcr))
+ _FPU_SETCW (new_fpcr);
+
+ if (new_fpsr != fpsr)
+ _FPU_SETFPSR (new_fpsr);
+}
+
+#define libc_feholdexcept libc_feholdexcept_aarch64
+#define libc_feholdexceptf libc_feholdexcept_aarch64
+#define libc_feholdexceptl libc_feholdexcept_aarch64
+
+static __always_inline void
+libc_fesetround_aarch64 (int round)
+{
+ fpu_control_t fpcr;
+
+ _FPU_GETCW (fpcr);
+
+ /* Check whether rounding modes are different. */
+ round = (fpcr ^ round) & _FPU_FPCR_RM_MASK;
+
+ /* Set new rounding mode if different. */
+ if (__glibc_unlikely (round != 0))
+ _FPU_SETCW (fpcr ^ round);
+}
+
+#define libc_fesetround libc_fesetround_aarch64
+#define libc_fesetroundf libc_fesetround_aarch64
+#define libc_fesetroundl libc_fesetround_aarch64
+
+static __always_inline void
+libc_feholdexcept_setround_aarch64 (fenv_t *envp, int round)
+{
+ fpu_control_t fpcr;
+ fpu_control_t new_fpcr;
+ fpu_fpsr_t fpsr;
+ fpu_fpsr_t new_fpsr;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+ envp->__fpcr = fpcr;
+ envp->__fpsr = fpsr;
+
+ /* Clear exception flags, set all exceptions to non-stop,
+ and set new rounding mode. */
+ new_fpcr = fpcr & ~((FE_ALL_EXCEPT << FE_EXCEPT_SHIFT) | _FPU_FPCR_RM_MASK);
+ new_fpcr |= round;
+ new_fpsr = fpsr & ~FE_ALL_EXCEPT;
+
+ if (__glibc_unlikely (new_fpcr != fpcr))
+ _FPU_SETCW (new_fpcr);
+
+ if (new_fpsr != fpsr)
+ _FPU_SETFPSR (new_fpsr);
+}
+
+#define libc_feholdexcept_setround libc_feholdexcept_setround_aarch64
+#define libc_feholdexcept_setroundf libc_feholdexcept_setround_aarch64
+#define libc_feholdexcept_setroundl libc_feholdexcept_setround_aarch64
+
+static __always_inline int
+libc_fetestexcept_aarch64 (int ex)
+{
+ fpu_fpsr_t fpsr;
+
+ _FPU_GETFPSR (fpsr);
+ return fpsr & ex & FE_ALL_EXCEPT;
+}
+
+#define libc_fetestexcept libc_fetestexcept_aarch64
+#define libc_fetestexceptf libc_fetestexcept_aarch64
+#define libc_fetestexceptl libc_fetestexcept_aarch64
+
+static __always_inline void
+libc_fesetenv_aarch64 (const fenv_t *envp)
+{
+ fpu_control_t fpcr;
+ fpu_control_t new_fpcr;
+
+ _FPU_GETCW (fpcr);
+ new_fpcr = envp->__fpcr;
+
+ if (__glibc_unlikely (fpcr != new_fpcr))
+ _FPU_SETCW (new_fpcr);
+
+ _FPU_SETFPSR (envp->__fpsr);
+}
+
+#define libc_fesetenv libc_fesetenv_aarch64
+#define libc_fesetenvf libc_fesetenv_aarch64
+#define libc_fesetenvl libc_fesetenv_aarch64
+#define libc_feresetround_noex libc_fesetenv_aarch64
+#define libc_feresetround_noexf libc_fesetenv_aarch64
+#define libc_feresetround_noexl libc_fesetenv_aarch64
+
+static __always_inline int
+libc_feupdateenv_test_aarch64 (const fenv_t *envp, int ex)
+{
+ fpu_control_t fpcr;
+ fpu_control_t new_fpcr;
+ fpu_fpsr_t fpsr;
+ fpu_fpsr_t new_fpsr;
+ int excepts;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+
+ /* Merge current exception flags with the saved fenv. */
+ excepts = fpsr & FE_ALL_EXCEPT;
+ new_fpcr = envp->__fpcr;
+ new_fpsr = envp->__fpsr | excepts;
+
+ if (__glibc_unlikely (fpcr != new_fpcr))
+ _FPU_SETCW (new_fpcr);
+
+ if (fpsr != new_fpsr)
+ _FPU_SETFPSR (new_fpsr);
+
+ /* Raise the exceptions if enabled in the new FP state. */
+ if (__glibc_unlikely (excepts & (new_fpcr >> FE_EXCEPT_SHIFT)))
+ __feraiseexcept (excepts);
+
+ return excepts & ex;
+}
+
+#define libc_feupdateenv_test libc_feupdateenv_test_aarch64
+#define libc_feupdateenv_testf libc_feupdateenv_test_aarch64
+#define libc_feupdateenv_testl libc_feupdateenv_test_aarch64
+
+static __always_inline void
+libc_feupdateenv_aarch64 (const fenv_t *envp)
+{
+ libc_feupdateenv_test_aarch64 (envp, 0);
+}
+
+#define libc_feupdateenv libc_feupdateenv_aarch64
+#define libc_feupdateenvf libc_feupdateenv_aarch64
+#define libc_feupdateenvl libc_feupdateenv_aarch64
+
+static __always_inline void
+libc_feholdsetround_aarch64 (fenv_t *envp, int round)
+{
+ fpu_control_t fpcr;
+ fpu_fpsr_t fpsr;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+ envp->__fpcr = fpcr;
+ envp->__fpsr = fpsr;
+
+ /* Check whether rounding modes are different. */
+ round = (fpcr ^ round) & _FPU_FPCR_RM_MASK;
+
+ /* Set new rounding mode if different. */
+ if (__glibc_unlikely (round != 0))
+ _FPU_SETCW (fpcr ^ round);
+}
+
+#define libc_feholdsetround libc_feholdsetround_aarch64
+#define libc_feholdsetroundf libc_feholdsetround_aarch64
+#define libc_feholdsetroundl libc_feholdsetround_aarch64
+
+static __always_inline void
+libc_feresetround_aarch64 (fenv_t *envp)
+{
+ fpu_control_t fpcr;
+ int round;
+
+ _FPU_GETCW (fpcr);
+
+ /* Check whether rounding modes are different. */
+ round = (envp->__fpcr ^ fpcr) & _FPU_FPCR_RM_MASK;
+
+ /* Restore the rounding mode if it was changed. */
+ if (__glibc_unlikely (round != 0))
+ _FPU_SETCW (fpcr ^ round);
+}
+
+#define libc_feresetround libc_feresetround_aarch64
+#define libc_feresetroundf libc_feresetround_aarch64
+#define libc_feresetroundl libc_feresetround_aarch64
+
+/* We have support for rounding mode context. */
+#define HAVE_RM_CTX 1
+
+static __always_inline void
+libc_feholdsetround_aarch64_ctx (struct rm_ctx *ctx, int r)
+{
+ fpu_control_t fpcr;
+ int round;
+
+ _FPU_GETCW (fpcr);
+ ctx->env.__fpcr = fpcr;
+
+ /* Check whether rounding modes are different. */
+ round = (fpcr ^ r) & _FPU_FPCR_RM_MASK;
+ ctx->updated_status = round != 0;
+
+ /* Set the rounding mode if changed. */
+ if (__glibc_unlikely (round != 0))
+ _FPU_SETCW (fpcr ^ round);
+}
+
+#define libc_feholdsetround_ctx libc_feholdsetround_aarch64_ctx
+#define libc_feholdsetroundf_ctx libc_feholdsetround_aarch64_ctx
+#define libc_feholdsetroundl_ctx libc_feholdsetround_aarch64_ctx
+
+static __always_inline void
+libc_feresetround_aarch64_ctx (struct rm_ctx *ctx)
+{
+ /* Restore the rounding mode if updated. */
+ if (__glibc_unlikely (ctx->updated_status))
+ _FPU_SETCW (ctx->env.__fpcr);
+}
+
+#define libc_feresetround_ctx libc_feresetround_aarch64_ctx
+#define libc_feresetroundf_ctx libc_feresetround_aarch64_ctx
+#define libc_feresetroundl_ctx libc_feresetround_aarch64_ctx
+
+static __always_inline void
+libc_feholdsetround_noex_aarch64_ctx (struct rm_ctx *ctx, int r)
+{
+ fpu_control_t fpcr;
+ fpu_fpsr_t fpsr;
+ int round;
+
+ _FPU_GETCW (fpcr);
+ _FPU_GETFPSR (fpsr);
+ ctx->env.__fpcr = fpcr;
+ ctx->env.__fpsr = fpsr;
+
+ /* Check whether rounding modes are different. */
+ round = (fpcr ^ r) & _FPU_FPCR_RM_MASK;
+ ctx->updated_status = round != 0;
+
+ /* Set the rounding mode if changed. */
+ if (__glibc_unlikely (round != 0))
+ _FPU_SETCW (fpcr ^ round);
+}
+
+#define libc_feholdsetround_noex_ctx libc_feholdsetround_noex_aarch64_ctx
+#define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_aarch64_ctx
+#define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_aarch64_ctx
+
+static __always_inline void
+libc_feresetround_noex_aarch64_ctx (struct rm_ctx *ctx)
+{
+ /* Restore the rounding mode if updated. */
+ if (__glibc_unlikely (ctx->updated_status))
+ _FPU_SETCW (ctx->env.__fpcr);
+
+ /* Write new FPSR to restore exception flags. */
+ _FPU_SETFPSR (ctx->env.__fpsr);
+}
+
+#define libc_feresetround_noex_ctx libc_feresetround_noex_aarch64_ctx
+#define libc_feresetround_noexf_ctx libc_feresetround_noex_aarch64_ctx
+#define libc_feresetround_noexl_ctx libc_feresetround_noex_aarch64_ctx
+
+#include_next <fenv_private.h>
+
+#endif
diff --git a/sysdeps/aarch64/fpu/math_private.h b/sysdeps/aarch64/fpu/math_private.h
index d2e0abc0b2..6740c1423f 100644
--- a/sysdeps/aarch64/fpu/math_private.h
+++ b/sysdeps/aarch64/fpu/math_private.h
@@ -1,5 +1,5 @@
-/* Private floating point rounding and exceptions handling. AArch64 version.
- Copyright (C) 2014-2018 Free Software Foundation, Inc.
+/* Configure optimized libm functions. AArch64 version.
+ Copyright (C) 2017-2018 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
@@ -19,287 +19,9 @@
#ifndef AARCH64_MATH_PRIVATE_H
#define AARCH64_MATH_PRIVATE_H 1
-#include <fenv.h>
-#include <fpu_control.h>
#include <stdint.h>
#include <math.h>
-static __always_inline void
-libc_feholdexcept_aarch64 (fenv_t *envp)
-{
- fpu_control_t fpcr;
- fpu_control_t new_fpcr;
- fpu_fpsr_t fpsr;
- fpu_fpsr_t new_fpsr;
-
- _FPU_GETCW (fpcr);
- _FPU_GETFPSR (fpsr);
- envp->__fpcr = fpcr;
- envp->__fpsr = fpsr;
-
- /* Clear exception flags and set all exceptions to non-stop. */
- new_fpcr = fpcr & ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT);
- new_fpsr = fpsr & ~FE_ALL_EXCEPT;
-
- if (__glibc_unlikely (new_fpcr != fpcr))
- _FPU_SETCW (new_fpcr);
-
- if (new_fpsr != fpsr)
- _FPU_SETFPSR (new_fpsr);
-}
-
-#define libc_feholdexcept libc_feholdexcept_aarch64
-#define libc_feholdexceptf libc_feholdexcept_aarch64
-#define libc_feholdexceptl libc_feholdexcept_aarch64
-
-static __always_inline void
-libc_fesetround_aarch64 (int round)
-{
- fpu_control_t fpcr;
-
- _FPU_GETCW (fpcr);
-
- /* Check whether rounding modes are different. */
- round = (fpcr ^ round) & _FPU_FPCR_RM_MASK;
-
- /* Set new rounding mode if different. */
- if (__glibc_unlikely (round != 0))
- _FPU_SETCW (fpcr ^ round);
-}
-
-#define libc_fesetround libc_fesetround_aarch64
-#define libc_fesetroundf libc_fesetround_aarch64
-#define libc_fesetroundl libc_fesetround_aarch64
-
-static __always_inline void
-libc_feholdexcept_setround_aarch64 (fenv_t *envp, int round)
-{
- fpu_control_t fpcr;
- fpu_control_t new_fpcr;
- fpu_fpsr_t fpsr;
- fpu_fpsr_t new_fpsr;
-
- _FPU_GETCW (fpcr);
- _FPU_GETFPSR (fpsr);
- envp->__fpcr = fpcr;
- envp->__fpsr = fpsr;
-
- /* Clear exception flags, set all exceptions to non-stop,
- and set new rounding mode. */
- new_fpcr = fpcr & ~((FE_ALL_EXCEPT << FE_EXCEPT_SHIFT) | _FPU_FPCR_RM_MASK);
- new_fpcr |= round;
- new_fpsr = fpsr & ~FE_ALL_EXCEPT;
-
- if (__glibc_unlikely (new_fpcr != fpcr))
- _FPU_SETCW (new_fpcr);
-
- if (new_fpsr != fpsr)
- _FPU_SETFPSR (new_fpsr);
-}
-
-#define libc_feholdexcept_setround libc_feholdexcept_setround_aarch64
-#define libc_feholdexcept_setroundf libc_feholdexcept_setround_aarch64
-#define libc_feholdexcept_setroundl libc_feholdexcept_setround_aarch64
-
-static __always_inline int
-libc_fetestexcept_aarch64 (int ex)
-{
- fpu_fpsr_t fpsr;
-
- _FPU_GETFPSR (fpsr);
- return fpsr & ex & FE_ALL_EXCEPT;
-}
-
-#define libc_fetestexcept libc_fetestexcept_aarch64
-#define libc_fetestexceptf libc_fetestexcept_aarch64
-#define libc_fetestexceptl libc_fetestexcept_aarch64
-
-static __always_inline void
-libc_fesetenv_aarch64 (const fenv_t *envp)
-{
- fpu_control_t fpcr;
- fpu_control_t new_fpcr;
-
- _FPU_GETCW (fpcr);
- new_fpcr = envp->__fpcr;
-
- if (__glibc_unlikely (fpcr != new_fpcr))
- _FPU_SETCW (new_fpcr);
-
- _FPU_SETFPSR (envp->__fpsr);
-}
-
-#define libc_fesetenv libc_fesetenv_aarch64
-#define libc_fesetenvf libc_fesetenv_aarch64
-#define libc_fesetenvl libc_fesetenv_aarch64
-#define libc_feresetround_noex libc_fesetenv_aarch64
-#define libc_feresetround_noexf libc_fesetenv_aarch64
-#define libc_feresetround_noexl libc_fesetenv_aarch64
-
-static __always_inline int
-libc_feupdateenv_test_aarch64 (const fenv_t *envp, int ex)
-{
- fpu_control_t fpcr;
- fpu_control_t new_fpcr;
- fpu_fpsr_t fpsr;
- fpu_fpsr_t new_fpsr;
- int excepts;
-
- _FPU_GETCW (fpcr);
- _FPU_GETFPSR (fpsr);
-
- /* Merge current exception flags with the saved fenv. */
- excepts = fpsr & FE_ALL_EXCEPT;
- new_fpcr = envp->__fpcr;
- new_fpsr = envp->__fpsr | excepts;
-
- if (__glibc_unlikely (fpcr != new_fpcr))
- _FPU_SETCW (new_fpcr);
-
- if (fpsr != new_fpsr)
- _FPU_SETFPSR (new_fpsr);
-
- /* Raise the exceptions if enabled in the new FP state. */
- if (__glibc_unlikely (excepts & (new_fpcr >> FE_EXCEPT_SHIFT)))
- __feraiseexcept (excepts);
-
- return excepts & ex;
-}
-
-#define libc_feupdateenv_test libc_feupdateenv_test_aarch64
-#define libc_feupdateenv_testf libc_feupdateenv_test_aarch64
-#define libc_feupdateenv_testl libc_feupdateenv_test_aarch64
-
-static __always_inline void
-libc_feupdateenv_aarch64 (const fenv_t *envp)
-{
- libc_feupdateenv_test_aarch64 (envp, 0);
-}
-
-#define libc_feupdateenv libc_feupdateenv_aarch64
-#define libc_feupdateenvf libc_feupdateenv_aarch64
-#define libc_feupdateenvl libc_feupdateenv_aarch64
-
-static __always_inline void
-libc_feholdsetround_aarch64 (fenv_t *envp, int round)
-{
- fpu_control_t fpcr;
- fpu_fpsr_t fpsr;
-
- _FPU_GETCW (fpcr);
- _FPU_GETFPSR (fpsr);
- envp->__fpcr = fpcr;
- envp->__fpsr = fpsr;
-
- /* Check whether rounding modes are different. */
- round = (fpcr ^ round) & _FPU_FPCR_RM_MASK;
-
- /* Set new rounding mode if different. */
- if (__glibc_unlikely (round != 0))
- _FPU_SETCW (fpcr ^ round);
-}
-
-#define libc_feholdsetround libc_feholdsetround_aarch64
-#define libc_feholdsetroundf libc_feholdsetround_aarch64
-#define libc_feholdsetroundl libc_feholdsetround_aarch64
-
-static __always_inline void
-libc_feresetround_aarch64 (fenv_t *envp)
-{
- fpu_control_t fpcr;
- int round;
-
- _FPU_GETCW (fpcr);
-
- /* Check whether rounding modes are different. */
- round = (envp->__fpcr ^ fpcr) & _FPU_FPCR_RM_MASK;
-
- /* Restore the rounding mode if it was changed. */
- if (__glibc_unlikely (round != 0))
- _FPU_SETCW (fpcr ^ round);
-}
-
-#define libc_feresetround libc_feresetround_aarch64
-#define libc_feresetroundf libc_feresetround_aarch64
-#define libc_feresetroundl libc_feresetround_aarch64
-
-/* We have support for rounding mode context. */
-#define HAVE_RM_CTX 1
-
-static __always_inline void
-libc_feholdsetround_aarch64_ctx (struct rm_ctx *ctx, int r)
-{
- fpu_control_t fpcr;
- int round;
-
- _FPU_GETCW (fpcr);
- ctx->env.__fpcr = fpcr;
-
- /* Check whether rounding modes are different. */
- round = (fpcr ^ r) & _FPU_FPCR_RM_MASK;
- ctx->updated_status = round != 0;
-
- /* Set the rounding mode if changed. */
- if (__glibc_unlikely (round != 0))
- _FPU_SETCW (fpcr ^ round);
-}
-
-#define libc_feholdsetround_ctx libc_feholdsetround_aarch64_ctx
-#define libc_feholdsetroundf_ctx libc_feholdsetround_aarch64_ctx
-#define libc_feholdsetroundl_ctx libc_feholdsetround_aarch64_ctx
-
-static __always_inline void
-libc_feresetround_aarch64_ctx (struct rm_ctx *ctx)
-{
- /* Restore the rounding mode if updated. */
- if (__glibc_unlikely (ctx->updated_status))
- _FPU_SETCW (ctx->env.__fpcr);
-}
-
-#define libc_feresetround_ctx libc_feresetround_aarch64_ctx
-#define libc_feresetroundf_ctx libc_feresetround_aarch64_ctx
-#define libc_feresetroundl_ctx libc_feresetround_aarch64_ctx
-
-static __always_inline void
-libc_feholdsetround_noex_aarch64_ctx (struct rm_ctx *ctx, int r)
-{
- fpu_control_t fpcr;
- fpu_fpsr_t fpsr;
- int round;
-
- _FPU_GETCW (fpcr);
- _FPU_GETFPSR (fpsr);
- ctx->env.__fpcr = fpcr;
- ctx->env.__fpsr = fpsr;
-
- /* Check whether rounding modes are different. */
- round = (fpcr ^ r) & _FPU_FPCR_RM_MASK;
- ctx->updated_status = round != 0;
-
- /* Set the rounding mode if changed. */
- if (__glibc_unlikely (round != 0))
- _FPU_SETCW (fpcr ^ round);
-}
-
-#define libc_feholdsetround_noex_ctx libc_feholdsetround_noex_aarch64_ctx
-#define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_aarch64_ctx
-#define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_aarch64_ctx
-
-static __always_inline void
-libc_feresetround_noex_aarch64_ctx (struct rm_ctx *ctx)
-{
- /* Restore the rounding mode if updated. */
- if (__glibc_unlikely (ctx->updated_status))
- _FPU_SETCW (ctx->env.__fpcr);
-
- /* Write new FPSR to restore exception flags. */
- _FPU_SETFPSR (ctx->env.__fpsr);
-}
-
-#define libc_feresetround_noex_ctx libc_feresetround_noex_aarch64_ctx
-#define libc_feresetround_noexf_ctx libc_feresetround_noex_aarch64_ctx
-#define libc_feresetround_noexl_ctx libc_feresetround_noex_aarch64_ctx
-
/* Use inline round and lround instructions. */
#define TOINT_INTRINSICS 1
diff --git a/sysdeps/arm/fenv_private.h b/sysdeps/arm/fenv_private.h
index 55157c8ae2..b96259dc34 100644
--- a/sysdeps/arm/fenv_private.h
+++ b/sysdeps/arm/fenv_private.h
@@ -16,8 +16,8 @@
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#ifndef FENV_PRIVATE_H
-#define FENV_PRIVATE_H 1
+#ifndef ARM_FENV_PRIVATE_H
+#define ARM_FENV_PRIVATE_H 1
#include <fenv.h>
#include <fpu_control.h>
@@ -246,4 +246,6 @@ libc_fesetenv_vfp_ctx (struct rm_ctx *ctx)
#endif
-#endif /* FENV_PRIVATE_H */
+#include_next <fenv_private.h>
+
+#endif /* ARM_FENV_PRIVATE_H */
diff --git a/sysdeps/arm/math_private.h b/sysdeps/arm/math_private.h
deleted file mode 100644
index c175b15601..0000000000
--- a/sysdeps/arm/math_private.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef ARM_MATH_PRIVATE_H
-#define ARM_MATH_PRIVATE_H 1
-
-#include "fenv_private.h"
-#include_next <math_private.h>
-
-#endif
diff --git a/sysdeps/generic/fenv_private.h b/sysdeps/generic/fenv_private.h
new file mode 100644
index 0000000000..912d23108f
--- /dev/null
+++ b/sysdeps/generic/fenv_private.h
@@ -0,0 +1,417 @@
+/* Optimized inline fenv.h functions for libm. Generic version.
+ Copyright (C) 2011-2018 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _FENV_PRIVATE_H
+#define _FENV_PRIVATE_H 1
+
+#include <fenv.h>
+#include <get-rounding-mode.h>
+
+/* The standards only specify one variant of the fenv.h interfaces.
+ But at least for some architectures we can be more efficient if we
+ know what operations are going to be performed. Therefore we
+ define additional interfaces. By default they refer to the normal
+ interfaces. */
+
+static __always_inline void
+default_libc_feholdexcept (fenv_t *e)
+{
+ (void) __feholdexcept (e);
+}
+
+#ifndef libc_feholdexcept
+# define libc_feholdexcept default_libc_feholdexcept
+#endif
+#ifndef libc_feholdexceptf
+# define libc_feholdexceptf default_libc_feholdexcept
+#endif
+#ifndef libc_feholdexceptl
+# define libc_feholdexceptl default_libc_feholdexcept
+#endif
+
+static __always_inline void
+default_libc_fesetround (int r)
+{
+ (void) __fesetround (r);
+}
+
+#ifndef libc_fesetround
+# define libc_fesetround default_libc_fesetround
+#endif
+#ifndef libc_fesetroundf
+# define libc_fesetroundf default_libc_fesetround
+#endif
+#ifndef libc_fesetroundl
+# define libc_fesetroundl default_libc_fesetround
+#endif
+
+static __always_inline void
+default_libc_feholdexcept_setround (fenv_t *e, int r)
+{
+ __feholdexcept (e);
+ __fesetround (r);
+}
+
+#ifndef libc_feholdexcept_setround
+# define libc_feholdexcept_setround default_libc_feholdexcept_setround
+#endif
+#ifndef libc_feholdexcept_setroundf
+# define libc_feholdexcept_setroundf default_libc_feholdexcept_setround
+#endif
+#ifndef libc_feholdexcept_setroundl
+# define libc_feholdexcept_setroundl default_libc_feholdexcept_setround
+#endif
+
+#ifndef libc_feholdsetround_53bit
+# define libc_feholdsetround_53bit libc_feholdsetround
+#endif
+
+#ifndef libc_fetestexcept
+# define libc_fetestexcept fetestexcept
+#endif
+#ifndef libc_fetestexceptf
+# define libc_fetestexceptf fetestexcept
+#endif
+#ifndef libc_fetestexceptl
+# define libc_fetestexceptl fetestexcept
+#endif
+
+static __always_inline void
+default_libc_fesetenv (fenv_t *e)
+{
+ (void) __fesetenv (e);
+}
+
+#ifndef libc_fesetenv
+# define libc_fesetenv default_libc_fesetenv
+#endif
+#ifndef libc_fesetenvf
+# define libc_fesetenvf default_libc_fesetenv
+#endif
+#ifndef libc_fesetenvl
+# define libc_fesetenvl default_libc_fesetenv
+#endif
+
+static __always_inline void
+default_libc_feupdateenv (fenv_t *e)
+{
+ (void) __feupdateenv (e);
+}
+
+#ifndef libc_feupdateenv
+# define libc_feupdateenv default_libc_feupdateenv
+#endif
+#ifndef libc_feupdateenvf
+# define libc_feupdateenvf default_libc_feupdateenv
+#endif
+#ifndef libc_feupdateenvl
+# define libc_feupdateenvl default_libc_feupdateenv
+#endif
+
+#ifndef libc_feresetround_53bit
+# define libc_feresetround_53bit libc_feresetround
+#endif
+
+static __always_inline int
+default_libc_feupdateenv_test (fenv_t *e, int ex)
+{
+ int ret = fetestexcept (ex);
+ __feupdateenv (e);
+ return ret;
+}
+
+#ifndef libc_feupdateenv_test
+# define libc_feupdateenv_test default_libc_feupdateenv_test
+#endif
+#ifndef libc_feupdateenv_testf
+# define libc_feupdateenv_testf default_libc_feupdateenv_test
+#endif
+#ifndef libc_feupdateenv_testl
+# define libc_feupdateenv_testl default_libc_feupdateenv_test
+#endif
+
+/* Save and set the rounding mode. The use of fenv_t to store the old mode
+ allows a target-specific version of this function to avoid converting the
+ rounding mode from the fpu format. By default we have no choice but to
+ manipulate the entire env. */
+
+#ifndef libc_feholdsetround
+# define libc_feholdsetround libc_feholdexcept_setround
+#endif
+#ifndef libc_feholdsetroundf
+# define libc_feholdsetroundf libc_feholdexcept_setroundf
+#endif
+#ifndef libc_feholdsetroundl
+# define libc_feholdsetroundl libc_feholdexcept_setroundl
+#endif
+
+/* ... and the reverse. */
+
+#ifndef libc_feresetround
+# define libc_feresetround libc_feupdateenv
+#endif
+#ifndef libc_feresetroundf
+# define libc_feresetroundf libc_feupdateenvf
+#endif
+#ifndef libc_feresetroundl
+# define libc_feresetroundl libc_feupdateenvl
+#endif
+
+/* ... and a version that also discards exceptions. */
+
+#ifndef libc_feresetround_noex
+# define libc_feresetround_noex libc_fesetenv
+#endif
+#ifndef libc_feresetround_noexf
+# define libc_feresetround_noexf libc_fesetenvf
+#endif
+#ifndef libc_feresetround_noexl
+# define libc_feresetround_noexl libc_fesetenvl
+#endif
+
+#ifndef HAVE_RM_CTX
+# define HAVE_RM_CTX 0
+#endif
+
+
+/* Default implementation using standard fenv functions.
+ Avoid unnecessary rounding mode changes by first checking the
+ current rounding mode. Note the use of __glibc_unlikely is
+ important for performance. */
+
+static __always_inline void
+default_libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
+{
+ ctx->updated_status = false;
+
+ /* Update rounding mode only if different. */
+ if (__glibc_unlikely (round != get_rounding_mode ()))
+ {
+ ctx->updated_status = true;
+ __fegetenv (&ctx->env);
+ __fesetround (round);
+ }
+}
+
+static __always_inline void
+default_libc_feresetround_ctx (struct rm_ctx *ctx)
+{
+ /* Restore the rounding mode if updated. */
+ if (__glibc_unlikely (ctx->updated_status))
+ __feupdateenv (&ctx->env);
+}
+
+static __always_inline void
+default_libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
+{
+ /* Save exception flags and rounding mode, and disable exception
+ traps. */
+ __feholdexcept (&ctx->env);
+
+ /* Update rounding mode only if different. */
+ if (__glibc_unlikely (round != get_rounding_mode ()))
+ __fesetround (round);
+}
+
+static __always_inline void
+default_libc_feresetround_noex_ctx (struct rm_ctx *ctx)
+{
+ /* Restore exception flags and rounding mode. */
+ __fesetenv (&ctx->env);
+}
+
+#if HAVE_RM_CTX
+/* Set/Restore Rounding Modes only when necessary. If defined, these functions
+ set/restore floating point state only if the state needed within the lexical
+ block is different from the current state. This saves a lot of time when
+ the floating point unit is much slower than the fixed point units. */
+
+# ifndef libc_feholdsetround_noex_ctx
+# define libc_feholdsetround_noex_ctx libc_feholdsetround_ctx
+# endif
+# ifndef libc_feholdsetround_noexf_ctx
+# define libc_feholdsetround_noexf_ctx libc_feholdsetroundf_ctx
+# endif
+# ifndef libc_feholdsetround_noexl_ctx
+# define libc_feholdsetround_noexl_ctx libc_feholdsetroundl_ctx
+# endif
+
+# ifndef libc_feresetround_noex_ctx
+# define libc_feresetround_noex_ctx libc_fesetenv_ctx
+# endif
+# ifndef libc_feresetround_noexf_ctx
+# define libc_feresetround_noexf_ctx libc_fesetenvf_ctx
+# endif
+# ifndef libc_feresetround_noexl_ctx
+# define libc_feresetround_noexl_ctx libc_fesetenvl_ctx
+# endif
+
+#else
+
+# define libc_feholdsetround_ctx default_libc_feholdsetround_ctx
+# define libc_feresetround_ctx default_libc_feresetround_ctx
+# define libc_feholdsetround_noex_ctx default_libc_feholdsetround_noex_ctx
+# define libc_feresetround_noex_ctx default_libc_feresetround_noex_ctx
+
+# define libc_feholdsetroundf_ctx libc_feholdsetround_ctx
+# define libc_feholdsetroundl_ctx libc_feholdsetround_ctx
+# define libc_feresetroundf_ctx libc_feresetround_ctx
+# define libc_feresetroundl_ctx libc_feresetround_ctx
+
+# define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_ctx
+# define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_ctx
+# define libc_feresetround_noexf_ctx libc_feresetround_noex_ctx
+# define libc_feresetround_noexl_ctx libc_feresetround_noex_ctx
+
+#endif
+
+#ifndef libc_feholdsetround_53bit_ctx
+# define libc_feholdsetround_53bit_ctx libc_feholdsetround_ctx
+#endif
+#ifndef libc_feresetround_53bit_ctx
+# define libc_feresetround_53bit_ctx libc_feresetround_ctx
+#endif
+
+#define SET_RESTORE_ROUND_GENERIC(RM,ROUNDFUNC,CLEANUPFUNC) \
+ struct rm_ctx ctx __attribute__((cleanup (CLEANUPFUNC ## _ctx))); \
+ ROUNDFUNC ## _ctx (&ctx, (RM))
+
+/* Set the rounding mode within a lexical block. Restore the rounding mode to
+ the value at the start of the block. The exception mode must be preserved.
+ Exceptions raised within the block must be set in the exception flags.
+ Non-stop mode may be enabled inside the block. */
+
+#define SET_RESTORE_ROUND(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround)
+#define SET_RESTORE_ROUNDF(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundf, libc_feresetroundf)
+#define SET_RESTORE_ROUNDL(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetroundl)
+
+/* Set the rounding mode within a lexical block. Restore the rounding mode to
+ the value at the start of the block. The exception mode must be preserved.
+ Exceptions raised within the block must be discarded, and exception flags
+ are restored to the value at the start of the block.
+ Non-stop mode must be enabled inside the block. */
+
+#define SET_RESTORE_ROUND_NOEX(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noex, \
+ libc_feresetround_noex)
+#define SET_RESTORE_ROUND_NOEXF(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexf, \
+ libc_feresetround_noexf)
+#define SET_RESTORE_ROUND_NOEXL(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexl, \
+ libc_feresetround_noexl)
+
+/* Like SET_RESTORE_ROUND, but also set rounding precision to 53 bits. */
+#define SET_RESTORE_ROUND_53BIT(RM) \
+ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_53bit, \
+ libc_feresetround_53bit)
+
+/* When no floating-point exceptions are defined in <fenv.h>, make
+ feraiseexcept ignore its argument so that unconditional
+ feraiseexcept calls do not cause errors for undefined exceptions.
+ Define it to expand to a void expression so that any calls testing
+ the result of feraiseexcept do produce errors. */
+#if FE_ALL_EXCEPT == 0
+# define feraiseexcept(excepts) ((void) 0)
+# define __feraiseexcept(excepts) ((void) 0)
+#endif
+
+/* Similarly, most <fenv.h> functions have trivial implementations in
+ the absence of support for floating-point exceptions and rounding
+ modes. */
+
+#if !FE_HAVE_ROUNDING_MODES
+# if FE_ALL_EXCEPT == 0
+extern inline int
+fegetenv (fenv_t *__e)
+{
+ return 0;
+}
+
+extern inline int
+__fegetenv (fenv_t *__e)
+{
+ return 0;
+}
+
+extern inline int
+feholdexcept (fenv_t *__e)
+{
+ return 0;
+}
+
+extern inline int
+__feholdexcept (fenv_t *__e)
+{
+ return 0;
+}
+
+extern inline int
+fesetenv (const fenv_t *__e)
+{
+ return 0;
+}
+
+extern inline int
+__fesetenv (const fenv_t *__e)
+{
+ return 0;
+}
+
+extern inline int
+feupdateenv (const fenv_t *__e)
+{
+ return 0;
+}
+
+extern inline int
+__feupdateenv (const fenv_t *__e)
+{
+ return 0;
+}
+# endif
+
+extern inline int
+fegetround (void)
+{
+ return FE_TONEAREST;
+}
+
+extern inline int
+__fegetround (void)
+{
+ return FE_TONEAREST;
+}
+
+extern inline int
+fesetround (int __d)
+{
+ return 0;
+}
+
+extern inline int
+__fesetround (int __d)
+{
+ return 0;
+}
+#endif
+
+#endif /* fenv_private.h. */
diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h
index 1212abaf47..936e3af568 100644
--- a/sysdeps/generic/math_private.h
+++ b/sysdeps/generic/math_private.h
@@ -17,10 +17,9 @@
#define _MATH_PRIVATE_H_
#include <endian.h>
+#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
-#include <fenv.h>
-#include <get-rounding-mode.h>
/* Gather machine dependent _Floatn support. */
#include <bits/floatn.h>
@@ -262,396 +261,6 @@ extern double __mpsin (double __x, double __dx, bool __range_reduce);
extern double __mpcos (double __x, double __dx, bool __range_reduce);
extern void __docos (double __x, double __dx, double __v[]);
-/* The standards only specify one variant of the fenv.h interfaces.
- But at least for some architectures we can be more efficient if we
- know what operations are going to be performed. Therefore we
- define additional interfaces. By default they refer to the normal
- interfaces. */
-
-static __always_inline void
-default_libc_feholdexcept (fenv_t *e)
-{
- (void) __feholdexcept (e);
-}
-
-#ifndef libc_feholdexcept
-# define libc_feholdexcept default_libc_feholdexcept
-#endif
-#ifndef libc_feholdexceptf
-# define libc_feholdexceptf default_libc_feholdexcept
-#endif
-#ifndef libc_feholdexceptl
-# define libc_feholdexceptl default_libc_feholdexcept
-#endif
-
-static __always_inline void
-default_libc_fesetround (int r)
-{
- (void) __fesetround (r);
-}
-
-#ifndef libc_fesetround
-# define libc_fesetround default_libc_fesetround
-#endif
-#ifndef libc_fesetroundf
-# define libc_fesetroundf default_libc_fesetround
-#endif
-#ifndef libc_fesetroundl
-# define libc_fesetroundl default_libc_fesetround
-#endif
-
-static __always_inline void
-default_libc_feholdexcept_setround (fenv_t *e, int r)
-{
- __feholdexcept (e);
- __fesetround (r);
-}
-
-#ifndef libc_feholdexcept_setround
-# define libc_feholdexcept_setround default_libc_feholdexcept_setround
-#endif
-#ifndef libc_feholdexcept_setroundf
-# define libc_feholdexcept_setroundf default_libc_feholdexcept_setround
-#endif
-#ifndef libc_feholdexcept_setroundl
-# define libc_feholdexcept_setroundl default_libc_feholdexcept_setround
-#endif
-
-#ifndef libc_feholdsetround_53bit
-# define libc_feholdsetround_53bit libc_feholdsetround
-#endif
-
-#ifndef libc_fetestexcept
-# define libc_fetestexcept fetestexcept
-#endif
-#ifndef libc_fetestexceptf
-# define libc_fetestexceptf fetestexcept
-#endif
-#ifndef libc_fetestexceptl
-# define libc_fetestexceptl fetestexcept
-#endif
-
-static __always_inline void
-default_libc_fesetenv (fenv_t *e)
-{
- (void) __fesetenv (e);
-}
-
-#ifndef libc_fesetenv
-# define libc_fesetenv default_libc_fesetenv
-#endif
-#ifndef libc_fesetenvf
-# define libc_fesetenvf default_libc_fesetenv
-#endif
-#ifndef libc_fesetenvl
-# define libc_fesetenvl default_libc_fesetenv
-#endif
-
-static __always_inline void
-default_libc_feupdateenv (fenv_t *e)
-{
- (void) __feupdateenv (e);
-}
-
-#ifndef libc_feupdateenv
-# define libc_feupdateenv default_libc_feupdateenv
-#endif
-#ifndef libc_feupdateenvf
-# define libc_feupdateenvf default_libc_feupdateenv
-#endif
-#ifndef libc_feupdateenvl
-# define libc_feupdateenvl default_libc_feupdateenv
-#endif
-
-#ifndef libc_feresetround_53bit
-# define libc_feresetround_53bit libc_feresetround
-#endif
-
-static __always_inline int
-default_libc_feupdateenv_test (fenv_t *e, int ex)
-{
- int ret = fetestexcept (ex);
- __feupdateenv (e);
- return ret;
-}
-
-#ifndef libc_feupdateenv_test
-# define libc_feupdateenv_test default_libc_feupdateenv_test
-#endif
-#ifndef libc_feupdateenv_testf
-# define libc_feupdateenv_testf default_libc_feupdateenv_test
-#endif
-#ifndef libc_feupdateenv_testl
-# define libc_feupdateenv_testl default_libc_feupdateenv_test
-#endif
-
-/* Save and set the rounding mode. The use of fenv_t to store the old mode
- allows a target-specific version of this function to avoid converting the
- rounding mode from the fpu format. By default we have no choice but to
- manipulate the entire env. */
-
-#ifndef libc_feholdsetround
-# define libc_feholdsetround libc_feholdexcept_setround
-#endif
-#ifndef libc_feholdsetroundf
-# define libc_feholdsetroundf libc_feholdexcept_setroundf
-#endif
-#ifndef libc_feholdsetroundl
-# define libc_feholdsetroundl libc_feholdexcept_setroundl
-#endif
-
-/* ... and the reverse. */
-
-#ifndef libc_feresetround
-# define libc_feresetround libc_feupdateenv
-#endif
-#ifndef libc_feresetroundf
-# define libc_feresetroundf libc_feupdateenvf
-#endif
-#ifndef libc_feresetroundl
-# define libc_feresetroundl libc_feupdateenvl
-#endif
-
-/* ... and a version that also discards exceptions. */
-
-#ifndef libc_feresetround_noex
-# define libc_feresetround_noex libc_fesetenv
-#endif
-#ifndef libc_feresetround_noexf
-# define libc_feresetround_noexf libc_fesetenvf
-#endif
-#ifndef libc_feresetround_noexl
-# define libc_feresetround_noexl libc_fesetenvl
-#endif
-
-#ifndef HAVE_RM_CTX
-# define HAVE_RM_CTX 0
-#endif
-
-
-/* Default implementation using standard fenv functions.
- Avoid unnecessary rounding mode changes by first checking the
- current rounding mode. Note the use of __glibc_unlikely is
- important for performance. */
-
-static __always_inline void
-default_libc_feholdsetround_ctx (struct rm_ctx *ctx, int round)
-{
- ctx->updated_status = false;
-
- /* Update rounding mode only if different. */
- if (__glibc_unlikely (round != get_rounding_mode ()))
- {
- ctx->updated_status = true;
- __fegetenv (&ctx->env);
- __fesetround (round);
- }
-}
-
-static __always_inline void
-default_libc_feresetround_ctx (struct rm_ctx *ctx)
-{
- /* Restore the rounding mode if updated. */
- if (__glibc_unlikely (ctx->updated_status))
- __feupdateenv (&ctx->env);
-}
-
-static __always_inline void
-default_libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round)
-{
- /* Save exception flags and rounding mode, and disable exception
- traps. */
- __feholdexcept (&ctx->env);
-
- /* Update rounding mode only if different. */
- if (__glibc_unlikely (round != get_rounding_mode ()))
- __fesetround (round);
-}
-
-static __always_inline void
-default_libc_feresetround_noex_ctx (struct rm_ctx *ctx)
-{
- /* Restore exception flags and rounding mode. */
- __fesetenv (&ctx->env);
-}
-
-#if HAVE_RM_CTX
-/* Set/Restore Rounding Modes only when necessary. If defined, these functions
- set/restore floating point state only if the state needed within the lexical
- block is different from the current state. This saves a lot of time when
- the floating point unit is much slower than the fixed point units. */
-
-# ifndef libc_feholdsetround_noex_ctx
-# define libc_feholdsetround_noex_ctx libc_feholdsetround_ctx
-# endif
-# ifndef libc_feholdsetround_noexf_ctx
-# define libc_feholdsetround_noexf_ctx libc_feholdsetroundf_ctx
-# endif
-# ifndef libc_feholdsetround_noexl_ctx
-# define libc_feholdsetround_noexl_ctx libc_feholdsetroundl_ctx
-# endif
-
-# ifndef libc_feresetround_noex_ctx
-# define libc_feresetround_noex_ctx libc_fesetenv_ctx
-# endif
-# ifndef libc_feresetround_noexf_ctx
-# define libc_feresetround_noexf_ctx libc_fesetenvf_ctx
-# endif
-# ifndef libc_feresetround_noexl_ctx
-# define libc_feresetround_noexl_ctx libc_fesetenvl_ctx
-# endif
-
-#else
-
-# define libc_feholdsetround_ctx default_libc_feholdsetround_ctx
-# define libc_feresetround_ctx default_libc_feresetround_ctx
-# define libc_feholdsetround_noex_ctx default_libc_feholdsetround_noex_ctx
-# define libc_feresetround_noex_ctx default_libc_feresetround_noex_ctx
-
-# define libc_feholdsetroundf_ctx libc_feholdsetround_ctx
-# define libc_feholdsetroundl_ctx libc_feholdsetround_ctx
-# define libc_feresetroundf_ctx libc_feresetround_ctx
-# define libc_feresetroundl_ctx libc_feresetround_ctx
-
-# define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_ctx
-# define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_ctx
-# define libc_feresetround_noexf_ctx libc_feresetround_noex_ctx
-# define libc_feresetround_noexl_ctx libc_feresetround_noex_ctx
-
-#endif
-
-#ifndef libc_feholdsetround_53bit_ctx
-# define libc_feholdsetround_53bit_ctx libc_feholdsetround_ctx
-#endif
-#ifndef libc_feresetround_53bit_ctx
-# define libc_feresetround_53bit_ctx libc_feresetround_ctx
-#endif
-
-#define SET_RESTORE_ROUND_GENERIC(RM,ROUNDFUNC,CLEANUPFUNC) \
- struct rm_ctx ctx __attribute__((cleanup (CLEANUPFUNC ## _ctx))); \
- ROUNDFUNC ## _ctx (&ctx, (RM))
-
-/* Set the rounding mode within a lexical block. Restore the rounding mode to
- the value at the start of the block. The exception mode must be preserved.
- Exceptions raised within the block must be set in the exception flags.
- Non-stop mode may be enabled inside the block. */
-
-#define SET_RESTORE_ROUND(RM) \
- SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround)
-#define SET_RESTORE_ROUNDF(RM) \
- SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundf, libc_feresetroundf)
-#define SET_RESTORE_ROUNDL(RM) \
- SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetroundl)
-
-/* Set the rounding mode within a lexical block. Restore the rounding mode to
- the value at the start of the block. The exception mode must be preserved.
- Exceptions raised within the block must be discarded, and exception flags
- are restored to the value at the start of the block.
- Non-stop mode must be enabled inside the block. */
-
-#define SET_RESTORE_ROUND_NOEX(RM) \
- SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noex, \
- libc_feresetround_noex)
-#define SET_RESTORE_ROUND_NOEXF(RM) \
- SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexf, \
- libc_feresetround_noexf)
-#define SET_RESTORE_ROUND_NOEXL(RM) \
- SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexl, \
- libc_feresetround_noexl)
-
-/* Like SET_RESTORE_ROUND, but also set rounding precision to 53 bits. */
-#define SET_RESTORE_ROUND_53BIT(RM) \
- SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_53bit, \
- libc_feresetround_53bit)
-
-/* When no floating-point exceptions are defined in <fenv.h>, make
- feraiseexcept ignore its argument so that unconditional
- feraiseexcept calls do not cause errors for undefined exceptions.
- Define it to expand to a void expression so that any calls testing
- the result of feraiseexcept do produce errors. */
-#if FE_ALL_EXCEPT == 0
-# define feraiseexcept(excepts) ((void) 0)
-# define __feraiseexcept(excepts) ((void) 0)
-#endif
-
-/* Similarly, most <fenv.h> functions have trivial implementations in
- the absence of support for floating-point exceptions and rounding
- modes. */
-
-#if !FE_HAVE_ROUNDING_MODES
-# if FE_ALL_EXCEPT == 0
-extern inline int
-fegetenv (fenv_t *__e)
-{
- return 0;
-}
-
-extern inline int
-__fegetenv (fenv_t *__e)
-{
- return 0;
-}
-
-extern inline int
-feholdexcept (fenv_t *__e)
-{
- return 0;
-}
-
-extern inline int
-__feholdexcept (fenv_t *__e)
-{
- return 0;
-}
-
-extern inline int
-fesetenv (const fenv_t *__e)
-{
- return 0;
-}
-
-extern inline int
-__fesetenv (const fenv_t *__e)
-{
- return 0;
-}
-
-extern inline int
-feupdateenv (const fenv_t *__e)
-{
- return 0;
-}
-
-extern inline int
-__feupdateenv (const fenv_t *__e)
-{
- return 0;
-}
-# endif
-
-extern inline int
-fegetround (void)
-{
- return FE_TONEAREST;
-}
-
-extern inline int
-__fegetround (void)
-{
- return FE_TONEAREST;
-}
-
-extern inline int
-fesetround (int __d)
-{
- return 0;
-}
-
-extern inline int
-__fesetround (int __d)
-{
- return 0;
-}
-#endif
+#include <fenv_private.h>
#endif /* _MATH_PRIVATE_H_ */
diff --git a/sysdeps/i386/fpu/math_private.h b/sysdeps/i386/fpu/math_private.h
deleted file mode 100644
index 485214391f..0000000000
--- a/sysdeps/i386/fpu/math_private.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef I386_MATH_PRIVATE_H
-#define I386_MATH_PRIVATE_H 1
-
-#include "fenv_private.h"
-#include_next <math_private.h>
-
-#endif
diff --git a/sysdeps/mips/math_private.h b/sysdeps/mips/fpu/fenv_private.h
similarity index 60%
rename from sysdeps/mips/math_private.h
rename to sysdeps/mips/fpu/fenv_private.h
index 01ae8b18fd..ae6f8eb6a8 100644
--- a/sysdeps/mips/math_private.h
+++ b/sysdeps/mips/fpu/fenv_private.h
@@ -16,22 +16,20 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#ifndef MIPS_MATH_PRIVATE_H
-#define MIPS_MATH_PRIVATE_H 1
+#ifndef MIPS_FENV_PRIVATE_H
+#define MIPS_FENV_PRIVATE_H 1
/* Inline functions to speed up the math library implementation. The
- default versions of these routines are in generic/math_private.h
+ default versions of these routines are in generic/fenv_private.h
and call fesetround, feholdexcept, etc. These routines use inlined
code instead. */
-#ifdef __mips_hard_float
+#include <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
-# include <fenv.h>
-# include <fenv_libc.h>
-# include <fpu_control.h>
-
-# define _FPU_MASK_ALL (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O \
- |_FPU_MASK_U | _FPU_MASK_I | FE_ALL_EXCEPT)
+#define _FPU_MASK_ALL (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O \
+ |_FPU_MASK_U | _FPU_MASK_I | FE_ALL_EXCEPT)
static __always_inline void
libc_feholdexcept_mips (fenv_t *envp)
@@ -46,9 +44,9 @@ libc_feholdexcept_mips (fenv_t *envp)
cw &= ~(_FPU_MASK_ALL);
_FPU_SETCW (cw);
}
-# define libc_feholdexcept libc_feholdexcept_mips
-# define libc_feholdexceptf libc_feholdexcept_mips
-# define libc_feholdexceptl libc_feholdexcept_mips
+#define libc_feholdexcept libc_feholdexcept_mips
+#define libc_feholdexceptf libc_feholdexcept_mips
+#define libc_feholdexceptl libc_feholdexcept_mips
static __always_inline void
libc_fesetround_mips (int round)
@@ -65,9 +63,9 @@ libc_fesetround_mips (int round)
/* Set new state. */
_FPU_SETCW (cw);
}
-# define libc_fesetround libc_fesetround_mips
-# define libc_fesetroundf libc_fesetround_mips
-# define libc_fesetroundl libc_fesetround_mips
+#define libc_fesetround libc_fesetround_mips
+#define libc_fesetroundf libc_fesetround_mips
+#define libc_fesetroundl libc_fesetround_mips
static __always_inline void
libc_feholdexcept_setround_mips (fenv_t *envp, int round)
@@ -88,13 +86,13 @@ libc_feholdexcept_setround_mips (fenv_t *envp, int round)
/* Set new state. */
_FPU_SETCW (cw);
}
-# define libc_feholdexcept_setround libc_feholdexcept_setround_mips
-# define libc_feholdexcept_setroundf libc_feholdexcept_setround_mips
-# define libc_feholdexcept_setroundl libc_feholdexcept_setround_mips
+#define libc_feholdexcept_setround libc_feholdexcept_setround_mips
+#define libc_feholdexcept_setroundf libc_feholdexcept_setround_mips
+#define libc_feholdexcept_setroundl libc_feholdexcept_setround_mips
-# define libc_feholdsetround libc_feholdexcept_setround_mips
-# define libc_feholdsetroundf libc_feholdexcept_setround_mips
-# define libc_feholdsetroundl libc_feholdexcept_setround_mips
+#define libc_feholdsetround libc_feholdexcept_setround_mips
+#define libc_feholdsetroundf libc_feholdexcept_setround_mips
+#define libc_feholdsetroundl libc_feholdexcept_setround_mips
static __always_inline void
libc_fesetenv_mips (fenv_t *envp)
@@ -106,9 +104,9 @@ libc_fesetenv_mips (fenv_t *envp)
_FPU_SETCW (envp->__fp_control_register);
}
-# define libc_fesetenv libc_fesetenv_mips
-# define libc_fesetenvf libc_fesetenv_mips
-# define libc_fesetenvl libc_fesetenv_mips
+#define libc_fesetenv libc_fesetenv_mips
+#define libc_fesetenvf libc_fesetenv_mips
+#define libc_fesetenvl libc_fesetenv_mips
static __always_inline int
libc_feupdateenv_test_mips (fenv_t *envp, int excepts)
@@ -131,22 +129,22 @@ libc_feupdateenv_test_mips (fenv_t *envp, int excepts)
return cw & excepts & FE_ALL_EXCEPT;
}
-# define libc_feupdateenv_test libc_feupdateenv_test_mips
-# define libc_feupdateenv_testf libc_feupdateenv_test_mips
-# define libc_feupdateenv_testl libc_feupdateenv_test_mips
+#define libc_feupdateenv_test libc_feupdateenv_test_mips
+#define libc_feupdateenv_testf libc_feupdateenv_test_mips
+#define libc_feupdateenv_testl libc_feupdateenv_test_mips
static __always_inline void
libc_feupdateenv_mips (fenv_t *envp)
{
libc_feupdateenv_test_mips (envp, 0);
}
-# define libc_feupdateenv libc_feupdateenv_mips
-# define libc_feupdateenvf libc_feupdateenv_mips
-# define libc_feupdateenvl libc_feupdateenv_mips
+#define libc_feupdateenv libc_feupdateenv_mips
+#define libc_feupdateenvf libc_feupdateenv_mips
+#define libc_feupdateenvl libc_feupdateenv_mips
-# define libc_feresetround libc_feupdateenv_mips
-# define libc_feresetroundf libc_feupdateenv_mips
-# define libc_feresetroundl libc_feupdateenv_mips
+#define libc_feresetround libc_feupdateenv_mips
+#define libc_feresetroundf libc_feupdateenv_mips
+#define libc_feresetroundl libc_feupdateenv_mips
static __always_inline int
libc_fetestexcept_mips (int excepts)
@@ -158,12 +156,12 @@ libc_fetestexcept_mips (int excepts)
return cw & excepts & FE_ALL_EXCEPT;
}
-# define libc_fetestexcept libc_fetestexcept_mips
-# define libc_fetestexceptf libc_fetestexcept_mips
-# define libc_fetestexceptl libc_fetestexcept_mips
+#define libc_fetestexcept libc_fetestexcept_mips
+#define libc_fetestexceptf libc_fetestexcept_mips
+#define libc_fetestexceptl libc_fetestexcept_mips
/* Enable support for rounding mode context. */
-# define HAVE_RM_CTX 1
+#define HAVE_RM_CTX 1
static __always_inline void
libc_feholdexcept_setround_mips_ctx (struct rm_ctx *ctx, int round)
@@ -188,18 +186,18 @@ libc_feholdexcept_setround_mips_ctx (struct rm_ctx *ctx, int round)
else
ctx->updated_status = false;
}
-# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_mips_ctx
-# define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_mips_ctx
-# define libc_feholdexcept_setroundl_ctx libc_feholdexcept_setround_mips_ctx
+#define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_mips_ctx
+#define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_mips_ctx
+#define libc_feholdexcept_setroundl_ctx libc_feholdexcept_setround_mips_ctx
static __always_inline void
libc_fesetenv_mips_ctx (struct rm_ctx *ctx)
{
libc_fesetenv_mips (&ctx->env);
}
-# define libc_fesetenv_ctx libc_fesetenv_mips_ctx
-# define libc_fesetenvf_ctx libc_fesetenv_mips_ctx
-# define libc_fesetenvl_ctx libc_fesetenv_mips_ctx
+#define libc_fesetenv_ctx libc_fesetenv_mips_ctx
+#define libc_fesetenvf_ctx libc_fesetenv_mips_ctx
+#define libc_fesetenvl_ctx libc_fesetenv_mips_ctx
static __always_inline void
libc_feupdateenv_mips_ctx (struct rm_ctx *ctx)
@@ -207,12 +205,12 @@ libc_feupdateenv_mips_ctx (struct rm_ctx *ctx)
if (__glibc_unlikely (ctx->updated_status))
libc_feupdateenv_test_mips (&ctx->env, 0);
}
-# define libc_feupdateenv_ctx libc_feupdateenv_mips_ctx
-# define libc_feupdateenvf_ctx libc_feupdateenv_mips_ctx
-# define libc_feupdateenvl_ctx libc_feupdateenv_mips_ctx
-# define libc_feresetround_ctx libc_feupdateenv_mips_ctx
-# define libc_feresetroundf_ctx libc_feupdateenv_mips_ctx
-# define libc_feresetroundl_ctx libc_feupdateenv_mips_ctx
+#define libc_feupdateenv_ctx libc_feupdateenv_mips_ctx
+#define libc_feupdateenvf_ctx libc_feupdateenv_mips_ctx
+#define libc_feupdateenvl_ctx libc_feupdateenv_mips_ctx
+#define libc_feresetround_ctx libc_feupdateenv_mips_ctx
+#define libc_feresetroundf_ctx libc_feupdateenv_mips_ctx
+#define libc_feresetroundl_ctx libc_feupdateenv_mips_ctx
static __always_inline void
libc_feholdsetround_mips_ctx (struct rm_ctx *ctx, int round)
@@ -234,12 +232,10 @@ libc_feholdsetround_mips_ctx (struct rm_ctx *ctx, int round)
else
ctx->updated_status = false;
}
-# define libc_feholdsetround_ctx libc_feholdsetround_mips_ctx
-# define libc_feholdsetroundf_ctx libc_feholdsetround_mips_ctx
-# define libc_feholdsetroundl_ctx libc_feholdsetround_mips_ctx
-
-#endif
+#define libc_feholdsetround_ctx libc_feholdsetround_mips_ctx
+#define libc_feholdsetroundf_ctx libc_feholdsetround_mips_ctx
+#define libc_feholdsetroundl_ctx libc_feholdsetround_mips_ctx
-#include_next <math_private.h>
+#include_next <fenv_private.h>
#endif
diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h
index 945ab98018..239c488ea1 100644
--- a/sysdeps/powerpc/fpu/fenv_private.h
+++ b/sysdeps/powerpc/fpu/fenv_private.h
@@ -16,8 +16,8 @@
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#ifndef FENV_PRIVATE_H
-#define FENV_PRIVATE_H 1
+#ifndef POWERPC_FENV_PRIVATE_H
+#define POWERPC_FENV_PRIVATE_H 1
#include <fenv.h>
#include <fenv_libc.h>
@@ -225,4 +225,6 @@ libc_feresetround_ppc_ctx (struct rm_ctx *ctx)
#define libc_feupdateenvf_ctx libc_feupdateenv_ppc_ctx
#define libc_feupdateenvl_ctx libc_feupdateenv_ppc_ctx
+#include_next <fenv_private.h>
+
#endif
diff --git a/sysdeps/powerpc/fpu/math_private.h b/sysdeps/powerpc/fpu/math_private.h
index e642d6c823..36fcb3c654 100644
--- a/sysdeps/powerpc/fpu/math_private.h
+++ b/sysdeps/powerpc/fpu/math_private.h
@@ -22,7 +22,6 @@
#include <sysdep.h>
#include <ldsodefs.h>
#include <dl-procinfo.h>
-#include <fenv_private.h>
#include_next <math_private.h>
diff --git a/sysdeps/riscv/rvf/math_private.h b/sysdeps/riscv/rvf/fenv_private.h
similarity index 98%
rename from sysdeps/riscv/rvf/math_private.h
rename to sysdeps/riscv/rvf/fenv_private.h
index ca587620cb..b5b9f36882 100644
--- a/sysdeps/riscv/rvf/math_private.h
+++ b/sysdeps/riscv/rvf/fenv_private.h
@@ -16,8 +16,8 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#ifndef RISCV_MATH_PRIVATE_H
-#define RISCV_MATH_PRIVATE_H 1
+#ifndef RISCV_FENV_PRIVATE_H
+#define RISCV_FENV_PRIVATE_H 1
#include <fenv.h>
#include <fpu_control.h>
@@ -156,6 +156,6 @@ libc_feresetround_riscv (fenv_t *envp)
#define libc_feresetroundf libc_feresetround_riscv
#define libc_feresetroundl libc_feresetround_riscv
-#include_next <math_private.h>
+#include_next <fenv_private.h>
#endif
diff --git a/sysdeps/sparc/fpu/fenv_private.h b/sysdeps/sparc/fpu/fenv_private.h
index 29b5d123cf..dbd1001ccb 100644
--- a/sysdeps/sparc/fpu/fenv_private.h
+++ b/sysdeps/sparc/fpu/fenv_private.h
@@ -1,5 +1,5 @@
-#ifndef FENV_PRIVATE_H
-#define FENV_PRIVATE_H 1
+#ifndef SPARC_FENV_PRIVATE_H
+#define SPARC_FENV_PRIVATE_H 1
#include <fenv.h>
@@ -179,4 +179,6 @@ libc_feholdsetround_sparc_ctx (struct rm_ctx *ctx, int round)
#define libc_feholdsetroundf_ctx libc_feholdsetround_sparc_ctx
#define libc_feholdsetroundl_ctx libc_feholdsetround_sparc_ctx
-#endif /* FENV_PRIVATE_H */
+#include_next <fenv_private.h>
+
+#endif /* SPARC_FENV_PRIVATE_H */
diff --git a/sysdeps/sparc/fpu/math_private.h b/sysdeps/sparc/fpu/math_private.h
deleted file mode 100644
index 27946cec7b..0000000000
--- a/sysdeps/sparc/fpu/math_private.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef SPARC_MATH_PRIVATE_H
-#define SPARC_MATH_PRIVATE_H 1
-
-#include "fenv_private.h"
-#include_next <math_private.h>
-
-#endif /* SPARC_MATH_PRIVATE_H */
diff --git a/sysdeps/i386/fpu/fenv_private.h b/sysdeps/x86/fpu/fenv_private.h
similarity index 99%
rename from sysdeps/i386/fpu/fenv_private.h
rename to sysdeps/x86/fpu/fenv_private.h
index 637dae5f05..4b081e015b 100644
--- a/sysdeps/i386/fpu/fenv_private.h
+++ b/sysdeps/x86/fpu/fenv_private.h
@@ -1,5 +1,5 @@
-#ifndef FENV_PRIVATE_H
-#define FENV_PRIVATE_H 1
+#ifndef X86_FENV_PRIVATE_H
+#define X86_FENV_PRIVATE_H 1
#include <bits/floatn.h>
#include <fenv.h>
@@ -492,4 +492,6 @@ libc_feupdateenv_387_ctx (struct rm_ctx *ctx)
#undef __mxcsr
-#endif /* FENV_PRIVATE_H */
+#include_next <fenv_private.h>
+
+#endif /* X86_FENV_PRIVATE_H */
diff --git a/sysdeps/x86_64/fpu/math_private.h b/sysdeps/x86_64/fpu/math_private.h
index 13052893ef..fcc8537d40 100644
--- a/sysdeps/x86_64/fpu/math_private.h
+++ b/sysdeps/x86_64/fpu/math_private.h
@@ -45,7 +45,6 @@
f = f__; \
} while (0)
-#include <sysdeps/i386/fpu/fenv_private.h>
#include_next <math_private.h>
#ifdef __SSE4_1__
--
Joseph S. Myers
joseph@codesourcery.com