aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/aarch64/bits/fenv.h8
-rw-r--r--sysdeps/alpha/fpu/bits/fenv.h8
-rw-r--r--sysdeps/arm/bits/fenv.h8
-rw-r--r--sysdeps/hppa/fpu/bits/fenv.h8
-rw-r--r--sysdeps/i386/fpu/fegetmode.c32
-rw-r--r--sysdeps/i386/fpu/fesetmode.c54
-rw-r--r--sysdeps/ia64/bits/fenv.h8
-rw-r--r--sysdeps/m68k/fpu/bits/fenv.h8
-rw-r--r--sysdeps/microblaze/bits/fenv.h8
-rw-r--r--sysdeps/mips/bits/fenv.h8
-rw-r--r--sysdeps/nacl/libm.abilist2
-rw-r--r--sysdeps/nios2/bits/fenv.h8
-rw-r--r--sysdeps/powerpc/Versions3
-rw-r--r--sysdeps/powerpc/bits/fenv.h9
-rw-r--r--sysdeps/powerpc/fpu/fenv_const.c4
-rw-r--r--sysdeps/powerpc/nofpu/fenv_const.c4
-rw-r--r--sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c4
-rw-r--r--sysdeps/s390/fpu/bits/fenv.h8
-rw-r--r--sysdeps/sh/bits/fenv.h8
-rw-r--r--sysdeps/sparc/fpu/bits/fenv.h8
-rw-r--r--sysdeps/tile/bits/fenv.h8
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/alpha/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/arm/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/hppa/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/i386/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/ia64/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/nios2/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/sh/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/64/libm.abilist2
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist2
-rw-r--r--sysdeps/x86/fpu/bits/fenv.h14
-rw-r--r--sysdeps/x86_64/fpu/fegetmode.c28
-rw-r--r--sysdeps/x86_64/fpu/fesetmode.c50
50 files changed, 364 insertions, 0 deletions
diff --git a/sysdeps/aarch64/bits/fenv.h b/sysdeps/aarch64/bits/fenv.h
index aced0d33b2..9df57a1bbf 100644
--- a/sysdeps/aarch64/bits/fenv.h
+++ b/sysdeps/aarch64/bits/fenv.h
@@ -72,3 +72,11 @@ fenv_t;
/* Floating-point environment where none of the exceptions are masked. */
# define FE_NOMASK_ENV ((const fenv_t *) -2)
#endif
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/alpha/fpu/bits/fenv.h b/sysdeps/alpha/fpu/bits/fenv.h
index b7da4a0eae..0688898ce7 100644
--- a/sysdeps/alpha/fpu/bits/fenv.h
+++ b/sysdeps/alpha/fpu/bits/fenv.h
@@ -131,3 +131,11 @@ typedef unsigned long int fenv_t;
/* The system calls to talk to the kernel's FP code. */
extern unsigned long int __ieee_get_fp_control (void) __THROW;
extern void __ieee_set_fp_control (unsigned long int __value) __THROW;
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned long int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) 0x8800000000000000UL)
+#endif
diff --git a/sysdeps/arm/bits/fenv.h b/sysdeps/arm/bits/fenv.h
index 8e89fc1819..c82fecb48f 100644
--- a/sysdeps/arm/bits/fenv.h
+++ b/sysdeps/arm/bits/fenv.h
@@ -80,3 +80,11 @@ fenv_t;
/* Floating-point environment where none of the exceptions are masked. */
# define FE_NOMASK_ENV ((const fenv_t *) -2)
#endif
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/hppa/fpu/bits/fenv.h b/sysdeps/hppa/fpu/bits/fenv.h
index cae9daeb04..e35e3553f9 100644
--- a/sysdeps/hppa/fpu/bits/fenv.h
+++ b/sysdeps/hppa/fpu/bits/fenv.h
@@ -89,3 +89,11 @@ typedef struct
/* Floating-point environment where none of the exceptions are masked. */
# define FE_NOMASK_ENV ((const fenv_t *) -2)
#endif
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/i386/fpu/fegetmode.c b/sysdeps/i386/fpu/fegetmode.c
new file mode 100644
index 0000000000..06d4d84768
--- /dev/null
+++ b/sysdeps/i386/fpu/fegetmode.c
@@ -0,0 +1,32 @@
+/* Store current floating-point control modes. i386 version.
+ Copyright (C) 2016 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/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+int
+fegetmode (femode_t *modep)
+{
+ _FPU_GETCW (modep->__control_word);
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ __asm__ ("stmxcsr %0" : "=m" (modep->__mxcsr));
+ return 0;
+}
diff --git a/sysdeps/i386/fpu/fesetmode.c b/sysdeps/i386/fpu/fesetmode.c
new file mode 100644
index 0000000000..cca5a1ad0c
--- /dev/null
+++ b/sysdeps/i386/fpu/fesetmode.c
@@ -0,0 +1,54 @@
+/* Install given floating-point control modes. i386 version.
+ Copyright (C) 2016 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/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+#include <dl-procinfo.h>
+
+/* All exceptions, including the x86-specific "denormal operand"
+ exception. */
+#define FE_ALL_EXCEPT_X86 (FE_ALL_EXCEPT | __FE_DENORM)
+
+int
+fesetmode (const femode_t *modep)
+{
+ fpu_control_t cw;
+ if (modep == FE_DFL_MODE)
+ cw = _FPU_DEFAULT;
+ else
+ cw = modep->__control_word;
+ _FPU_SETCW (cw);
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int mxcsr;
+ __asm__ ("stmxcsr %0" : "=m" (mxcsr));
+ /* Preserve SSE exception flags but restore other state in
+ MXCSR. */
+ mxcsr &= FE_ALL_EXCEPT_X86;
+ if (modep == FE_DFL_MODE)
+ /* Default MXCSR state has all bits zero except for those
+ masking exceptions. */
+ mxcsr |= FE_ALL_EXCEPT_X86 << 7;
+ else
+ mxcsr |= modep->__mxcsr & ~FE_ALL_EXCEPT_X86;
+ __asm__ ("ldmxcsr %0" : : "m" (mxcsr));
+ }
+ return 0;
+}
diff --git a/sysdeps/ia64/bits/fenv.h b/sysdeps/ia64/bits/fenv.h
index 9bb20de27b..5945380889 100644
--- a/sysdeps/ia64/bits/fenv.h
+++ b/sysdeps/ia64/bits/fenv.h
@@ -94,3 +94,11 @@ typedef unsigned long int fenv_t;
s0, s2, and s3. */
# define FE_NONIEEE_ENV ((const fenv_t *) 0xc009a04d0270037fUL)
#endif
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned long int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) 0xc009804c0270033fUL)
+#endif
diff --git a/sysdeps/m68k/fpu/bits/fenv.h b/sysdeps/m68k/fpu/bits/fenv.h
index 2228861624..b8e52b290e 100644
--- a/sysdeps/m68k/fpu/bits/fenv.h
+++ b/sysdeps/m68k/fpu/bits/fenv.h
@@ -85,3 +85,11 @@ fenv_t;
/* Floating-point environment where none of the exceptions are masked. */
# define FE_NOMASK_ENV ((const fenv_t *) -2)
#endif
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/microblaze/bits/fenv.h b/sysdeps/microblaze/bits/fenv.h
index 3891f4a186..0d2ab2bc58 100644
--- a/sysdeps/microblaze/bits/fenv.h
+++ b/sysdeps/microblaze/bits/fenv.h
@@ -40,3 +40,11 @@ typedef unsigned int fenv_t;
/* If the default argument is used we use this value. */
#define FE_DFL_ENV ((const fenv_t *) -1l)
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/mips/bits/fenv.h b/sysdeps/mips/bits/fenv.h
index f829bd3807..6341ee279e 100644
--- a/sysdeps/mips/bits/fenv.h
+++ b/sysdeps/mips/bits/fenv.h
@@ -83,3 +83,11 @@ fenv_t;
/* Floating-point environment where none of the exception is masked. */
# define FE_NOMASK_ENV ((const fenv_t *) -2)
#endif
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/nacl/libm.abilist b/sysdeps/nacl/libm.abilist
index 28897730fa..85ee684a1a 100644
--- a/sysdeps/nacl/libm.abilist
+++ b/sysdeps/nacl/libm.abilist
@@ -380,5 +380,7 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
diff --git a/sysdeps/nios2/bits/fenv.h b/sysdeps/nios2/bits/fenv.h
index 9d046217c8..8ac3831ed9 100644
--- a/sysdeps/nios2/bits/fenv.h
+++ b/sysdeps/nios2/bits/fenv.h
@@ -42,3 +42,11 @@ typedef unsigned int fenv_t;
/* If the default argument is used we use this value. */
#define FE_DFL_ENV ((const fenv_t *) -1)
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/powerpc/Versions b/sysdeps/powerpc/Versions
index b959ea49fe..95849668f2 100644
--- a/sysdeps/powerpc/Versions
+++ b/sysdeps/powerpc/Versions
@@ -3,6 +3,9 @@ libm {
# symbols used in macros from sysdeps/powerpc/bits/fenv.h
__fe_dfl_env; __fe_enabled_env; __fe_nonieee_env; __fe_nomask_env;
}
+ GLIBC_2.25 {
+ __fe_dfl_mode;
+ }
}
libc {
diff --git a/sysdeps/powerpc/bits/fenv.h b/sysdeps/powerpc/bits/fenv.h
index d2a6d34a99..8d2bf3d163 100644
--- a/sysdeps/powerpc/bits/fenv.h
+++ b/sysdeps/powerpc/bits/fenv.h
@@ -169,3 +169,12 @@ extern const fenv_t __fe_nonieee_env;
# define FE_MASK_ENV FE_DFL_ENV
#endif
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef double femode_t;
+
+/* Default floating-point control modes. */
+extern const femode_t __fe_dfl_mode;
+# define FE_DFL_MODE (&__fe_dfl_mode)
+#endif
diff --git a/sysdeps/powerpc/fpu/fenv_const.c b/sysdeps/powerpc/fpu/fenv_const.c
index b061daf578..93a4375430 100644
--- a/sysdeps/powerpc/fpu/fenv_const.c
+++ b/sysdeps/powerpc/fpu/fenv_const.c
@@ -23,6 +23,10 @@
const unsigned long long __fe_dfl_env __attribute__ ((aligned (8))) =
0xfff8000000000000ULL;
+/* The same representation is used for femode_t. */
+extern const unsigned long long __fe_dfl_mode
+ __attribute__ ((aligned (8), alias ("__fe_dfl_env")));
+
/* Floating-point environment where none of the exceptions are masked. */
const unsigned long long __fe_enabled_env __attribute__ ((aligned (8))) =
0xfff80000000000f8ULL;
diff --git a/sysdeps/powerpc/nofpu/fenv_const.c b/sysdeps/powerpc/nofpu/fenv_const.c
index ebf5c68fc5..ce1da3c197 100644
--- a/sysdeps/powerpc/nofpu/fenv_const.c
+++ b/sysdeps/powerpc/nofpu/fenv_const.c
@@ -25,6 +25,10 @@
const unsigned long long __fe_dfl_env __attribute__ ((aligned (8))) =
0x000000003e000000ULL;
+/* The same representation is used for femode_t. */
+extern const unsigned long long __fe_dfl_mode
+ __attribute__ ((aligned (8), alias ("__fe_dfl_env")));
+
/* Floating-point environment where none of the exceptions are masked. */
const unsigned long long __fe_enabled_env __attribute__ ((aligned (8))) =
0x0000000000000000ULL;
diff --git a/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c b/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c
index 11e24ca182..eab47c8c0f 100644
--- a/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c
+++ b/sysdeps/powerpc/powerpc32/e500/nofpu/fenv_const.c
@@ -28,6 +28,10 @@
const unsigned long long __fe_dfl_env __attribute__ ((aligned (8))) =
0x3cULL;
+/* The same representation is used for femode_t. */
+extern const unsigned long long __fe_dfl_mode
+ __attribute__ ((aligned (8), alias ("__fe_dfl_env")));
+
/* Floating-point environment where none of the exceptions are masked. */
const unsigned long long __fe_enabled_env __attribute__ ((aligned (8))) =
(((unsigned long long) (PR_FP_EXC_DIV
diff --git a/sysdeps/s390/fpu/bits/fenv.h b/sysdeps/s390/fpu/bits/fenv.h
index 6de74b9939..d33f5d921d 100644
--- a/sysdeps/s390/fpu/bits/fenv.h
+++ b/sysdeps/s390/fpu/bits/fenv.h
@@ -90,3 +90,11 @@ typedef struct
/* Floating-point environment where none of the exceptions are masked. */
# define FE_NOMASK_ENV ((const fenv_t *) -2)
#endif
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/sh/bits/fenv.h b/sysdeps/sh/bits/fenv.h
index 254c50fb97..200b53899b 100644
--- a/sysdeps/sh/bits/fenv.h
+++ b/sysdeps/sh/bits/fenv.h
@@ -74,3 +74,11 @@ fenv_t;
/* If the default argument is used we use this value. */
#define FE_DFL_ENV ((const fenv_t *) -1)
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/sparc/fpu/bits/fenv.h b/sysdeps/sparc/fpu/bits/fenv.h
index 29328f714f..37c82ff5eb 100644
--- a/sysdeps/sparc/fpu/bits/fenv.h
+++ b/sysdeps/sparc/fpu/bits/fenv.h
@@ -91,3 +91,11 @@ typedef unsigned long int fenv_t;
# define __fenv_stfsr(X) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (X))
# define __fenv_ldfsr(X) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (X))
#endif
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned long int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/tile/bits/fenv.h b/sysdeps/tile/bits/fenv.h
index a87a39fc28..eee9e011cc 100644
--- a/sysdeps/tile/bits/fenv.h
+++ b/sysdeps/tile/bits/fenv.h
@@ -43,3 +43,11 @@ typedef unsigned int fenv_t;
/* If the default argument is used we use this value. */
#define FE_DFL_ENV ((const fenv_t *) -1l)
+
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef unsigned int femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/libm.abilist b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
index 1f475cd5c1..aee63a105c 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
@@ -411,5 +411,7 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
diff --git a/sysdeps/unix/sysv/linux/alpha/libm.abilist b/sysdeps/unix/sysv/linux/alpha/libm.abilist
index 11b76e9a10..339b896ac7 100644
--- a/sysdeps/unix/sysv/linux/alpha/libm.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libm.abilist
@@ -421,7 +421,9 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.3.4 GLIBC_2.3.4 A
GLIBC_2.3.4 __c1_cabsf F
diff --git a/sysdeps/unix/sysv/linux/arm/libm.abilist b/sysdeps/unix/sysv/linux/arm/libm.abilist
index 1fc1804bd5..f7b824413b 100644
--- a/sysdeps/unix/sysv/linux/arm/libm.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libm.abilist
@@ -69,7 +69,9 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 _LIB_VERSION D 0x4
diff --git a/sysdeps/unix/sysv/linux/hppa/libm.abilist b/sysdeps/unix/sysv/linux/hppa/libm.abilist
index ed734881dd..576b514a53 100644
--- a/sysdeps/unix/sysv/linux/hppa/libm.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libm.abilist
@@ -381,7 +381,9 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/i386/libm.abilist b/sysdeps/unix/sysv/linux/i386/libm.abilist
index 3a6dcaf064..63b8da9985 100644
--- a/sysdeps/unix/sysv/linux/i386/libm.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libm.abilist
@@ -423,6 +423,8 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
diff --git a/sysdeps/unix/sysv/linux/ia64/libm.abilist b/sysdeps/unix/sysv/linux/ia64/libm.abilist
index ec9916b52e..611a84ff57 100644
--- a/sysdeps/unix/sysv/linux/ia64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libm.abilist
@@ -352,6 +352,8 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
index 1fc1804bd5..f7b824413b 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
@@ -69,7 +69,9 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 _LIB_VERSION D 0x4
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
index 32931f1677..77f9c7bed7 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
@@ -421,6 +421,8 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
diff --git a/sysdeps/unix/sysv/linux/microblaze/libm.abilist b/sysdeps/unix/sysv/linux/microblaze/libm.abilist
index cab693a4e4..c59437fe73 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libm.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libm.abilist
@@ -380,5 +380,7 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
index 20a80ccbf2..31d6f9eb70 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
@@ -382,7 +382,9 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
index 02379f78bf..83e031125b 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
@@ -413,6 +413,8 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
diff --git a/sysdeps/unix/sysv/linux/nios2/libm.abilist b/sysdeps/unix/sysv/linux/nios2/libm.abilist
index b4b377ba19..151574d670 100644
--- a/sysdeps/unix/sysv/linux/nios2/libm.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libm.abilist
@@ -380,5 +380,7 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
index 7eea14aded..456f47e912 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
@@ -422,7 +422,10 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __fe_dfl_mode D 0x8
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 __clog10l F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
index 5eb2e9bb40..b2e4a73fd6 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
@@ -421,7 +421,10 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __fe_dfl_mode D 0x8
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 __clog10l F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist
index 36b8e77d47..907d8b7936 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist
@@ -416,5 +416,8 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __fe_dfl_mode D 0x8
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist
index 2efd4ebb33..307423dc80 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist
@@ -97,7 +97,10 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __fe_dfl_mode D 0x8
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 _LIB_VERSION D 0x4
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
index 62f75baa36..377cea952a 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
@@ -411,7 +411,9 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 __clog10l F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
index c41344a9ff..dafbff15a6 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
@@ -409,7 +409,9 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 __clog10l F
diff --git a/sysdeps/unix/sysv/linux/sh/libm.abilist b/sysdeps/unix/sysv/linux/sh/libm.abilist
index 3baecfb400..a38baceb8f 100644
--- a/sysdeps/unix/sysv/linux/sh/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libm.abilist
@@ -381,7 +381,9 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
index dd5390c313..27166beb55 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
@@ -414,7 +414,9 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
GLIBC_2.4 __clog10l F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
index 394c29b9b5..46f7973465 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
@@ -412,6 +412,8 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist
index d66c886ca5..ec6f0b3600 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist
@@ -381,5 +381,7 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist
index d66c886ca5..ec6f0b3600 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist
@@ -381,5 +381,7 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist
index d66c886ca5..ec6f0b3600 100644
--- a/sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist
@@ -381,5 +381,7 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
index dd79dc4626..65e5baed84 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
@@ -412,6 +412,8 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
GLIBC_2.4 GLIBC_2.4 A
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
index 45abb4fa71..ff520cb084 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
@@ -411,5 +411,7 @@ GLIBC_2.24 nextup F
GLIBC_2.24 nextupf F
GLIBC_2.24 nextupl F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 fegetmode F
GLIBC_2.25 fesetexcept F
+GLIBC_2.25 fesetmode F
GLIBC_2.25 fetestexceptflag F
diff --git a/sysdeps/x86/fpu/bits/fenv.h b/sysdeps/x86/fpu/bits/fenv.h
index 8c8503bd7e..688407281c 100644
--- a/sysdeps/x86/fpu/bits/fenv.h
+++ b/sysdeps/x86/fpu/bits/fenv.h
@@ -101,6 +101,20 @@ fenv_t;
# define FE_NOMASK_ENV ((const fenv_t *) -2)
#endif
+#if __GLIBC_USE (IEC_60559_BFP_EXT)
+/* Type representing floating-point control modes. */
+typedef struct
+ {
+ unsigned short int __control_word;
+ unsigned short int __glibc_reserved;
+ unsigned int __mxcsr;
+ }
+femode_t;
+
+/* Default floating-point control modes. */
+# define FE_DFL_MODE ((const femode_t *) -1L)
+#endif
+
#ifdef __USE_EXTERN_INLINES
__BEGIN_DECLS
diff --git a/sysdeps/x86_64/fpu/fegetmode.c b/sysdeps/x86_64/fpu/fegetmode.c
new file mode 100644
index 0000000000..f4a179d36b
--- /dev/null
+++ b/sysdeps/x86_64/fpu/fegetmode.c
@@ -0,0 +1,28 @@
+/* Store current floating-point control modes. x86_64 version.
+ Copyright (C) 2016 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/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+int
+fegetmode (femode_t *modep)
+{
+ _FPU_GETCW (modep->__control_word);
+ __asm__ ("stmxcsr %0" : "=m" (modep->__mxcsr));
+ return 0;
+}
diff --git a/sysdeps/x86_64/fpu/fesetmode.c b/sysdeps/x86_64/fpu/fesetmode.c
new file mode 100644
index 0000000000..19173f91cb
--- /dev/null
+++ b/sysdeps/x86_64/fpu/fesetmode.c
@@ -0,0 +1,50 @@
+/* Install given floating-point control modes. x86_64 version.
+ Copyright (C) 2016 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/>. */
+
+#include <fenv.h>
+#include <fpu_control.h>
+
+/* All exceptions, including the x86-specific "denormal operand"
+ exception. */
+#define FE_ALL_EXCEPT_X86 (FE_ALL_EXCEPT | __FE_DENORM)
+
+int
+fesetmode (const femode_t *modep)
+{
+ fpu_control_t cw;
+ unsigned int mxcsr;
+ __asm__ ("stmxcsr %0" : "=m" (mxcsr));
+ /* Preserve SSE exception flags but restore other state in
+ MXCSR. */
+ mxcsr &= FE_ALL_EXCEPT_X86;
+ if (modep == FE_DFL_MODE)
+ {
+ cw = _FPU_DEFAULT;
+ /* Default MXCSR state has all bits zero except for those
+ masking exceptions. */
+ mxcsr |= FE_ALL_EXCEPT_X86 << 7;
+ }
+ else
+ {
+ cw = modep->__control_word;
+ mxcsr |= modep->__mxcsr & ~FE_ALL_EXCEPT_X86;
+ }
+ _FPU_SETCW (cw);
+ __asm__ ("ldmxcsr %0" : : "m" (mxcsr));
+ return 0;
+}