]> Savannah Git Hosting - gnulib.git/commitdiff
fpe-trapping: Simplify.
authorBruno Haible <bruno@clisp.org>
Sun, 5 Nov 2023 13:34:39 +0000 (14:34 +0100)
committerBruno Haible <bruno@clisp.org>
Sun, 5 Nov 2023 13:42:01 +0000 (14:42 +0100)
* lib/fpe-trapping.h (sigfpe_on_invalid): Remove all platform specific
code. Just rely on feclearexcept and feenableexcept.
* m4/fpe-trapping.m4: Renamed from m4/fpe.m4.
(gl_FPE_TRAPPING): Greatly simplify.
* modules/fpe-trapping (Files): Use m4/fpe-trapping.m4 instead of
m4/fpe.m4. Remove m4/mathfunc.m4, m4/musl.m4.
(Depends-on): Add fenv-exceptions-trapping.
* tests/test-fenv-except-state-2.c (main): Update skip message.
* tests/test-fenv-except-tracking-2.c (main): Likewise.
* tests/test-fenv-except-tracking-3.c (main): Likewise.
* tests/test-fenv-except-tracking-5.c (main): Likewise.
* tests/test-nan-2.c (main): Likewise.
* tests/test-snan-2.c (main): Likewise.

ChangeLog
lib/fpe-trapping.h
m4/fpe-trapping.m4 [new file with mode: 0644]
m4/fpe.m4 [deleted file]
modules/fpe-trapping
tests/test-fenv-except-state-2.c
tests/test-fenv-except-tracking-2.c
tests/test-fenv-except-tracking-3.c
tests/test-fenv-except-tracking-5.c
tests/test-nan-2.c
tests/test-snan-2.c

index 3b2951ff6e9939ab4e553f8b8cc6f304aa0173b2..3e8c6cf2a76bc372fa48b2a7498a9ca3f6888b35 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2023-11-05  Bruno Haible  <bruno@clisp.org>
+
+       fpe-trapping: Simplify.
+       * lib/fpe-trapping.h (sigfpe_on_invalid): Remove all platform specific
+       code. Just rely on feclearexcept and feenableexcept.
+       * m4/fpe-trapping.m4: Renamed from m4/fpe.m4.
+       (gl_FPE_TRAPPING): Greatly simplify.
+       * modules/fpe-trapping (Files): Use m4/fpe-trapping.m4 instead of
+       m4/fpe.m4. Remove m4/mathfunc.m4, m4/musl.m4.
+       (Depends-on): Add fenv-exceptions-trapping.
+       * tests/test-fenv-except-state-2.c (main): Update skip message.
+       * tests/test-fenv-except-tracking-2.c (main): Likewise.
+       * tests/test-fenv-except-tracking-3.c (main): Likewise.
+       * tests/test-fenv-except-tracking-5.c (main): Likewise.
+       * tests/test-nan-2.c (main): Likewise.
+       * tests/test-snan-2.c (main): Likewise.
+
 2023-11-05  Bruno Haible  <bruno@clisp.org>
 
        fpe-tracking: Remove module.
index 9040a218ce60b7abf5e7c2dcb4d71155e43fcaad..005ede6bf01ec6b9ec4f8dcf7567abd259d45df3 100644 (file)
    Returns >= 0 when successful, -1 upon failure.  */
 
 
-#define HAVE_FPE_TRAPPING 1
-
 #include <fenv.h>
 
-#if HAVE_FEENABLEEXCEPT
-/* glibc, FreeBSD ≥ 6.0, NetBSD ≥ 7.0, OpenBSD ≥ 5.0, Cygwin ≥ 1.7.8, Android, Haiku.  */
-
 static int
 sigfpe_on_invalid ()
 {
@@ -39,591 +34,20 @@ sigfpe_on_invalid ()
   /* An FE_INVALID exception shall trigger a SIGFPE signal.
      This call may fail on arm, arm64, riscv64 CPUs.
      Also, possibly a bug in glibc/sysdeps/m68k/fpu/feenablxcpt.c: it sets
-     only bit 13, but should better set both bit 14 and bit 13 of the
-     control register.  */
+     only bit 13, but should better set bits 15, 14, 13 of the control
+     register together.  See
+     <https://sourceware.org/bugzilla/show_bug.cgi?id=30993>.  */
   int ret = feenableexcept (FE_INVALID);
   if (ret == -1)
     return -1;
 
-  #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ < 20) || defined __FreeBSD__ || defined __NetBSD__) && defined __aarch64__
-  /* Work around a bug with glibc 2.19 and FreeBSD 12.2 on arm64 CPUs:
-     feenableexcept returns success even if the CPU does not support the
-     request.  */
-  fenv_t env;
-  fegetenv (&env);
-  #if __GLIBC__ >= 2 || defined __NetBSD__
-  /* fenv_t is a struct { unsigned int __fpcr, __fpsr; }  */
-  if (((FE_INVALID << 8) & ~env.__fpcr) != 0)
-    return -1;
-  #else /* defined __FreeBSD__ */
-  /* fenv_t is an 'uint64_t' that merges fpcr and fpsr.
-     But watch out for this incompatible change:
-     <https://cgit.freebsd.org/src/commit/?id=34cc08e336987a8ebc316595e3f552a4c09f1fd4>  */
-  #if __FreeBSD__ < 14
-  if (((FE_INVALID << 8) & ~env) != 0)
-  #else
-  if (((FE_INVALID << 8) & ~(env >> 32)) != 0)
-  #endif
-    return -1;
-  #endif
-  #endif
-
-  #if (defined __FreeBSD__ || defined __NetBSD__) && defined __arm__
-  /* Work around a bug with FreeBSD 12.2 on arm CPUs:
-     feenableexcept returns success even if the CPU does not support the
-     request.  */
-  /* Test whether fpscr was actually changed as desired.  */
-  fenv_t env;
-  fegetenv (&env);
-  if (((FE_INVALID << 8) & ~env) != 0)
-    return -1;
-  #endif
-
   return 0;
 }
 
 /* But it does not work on RISC-V.  That's because the fcsr register has only
    bits for floating-point exception status, but no bits for trapping
    floating-point exceptions.  */
-# if defined __riscv
-#  undef HAVE_FPE_TRAPPING
-# endif
-
-#elif HAVE_FPSETMASK
-/* FreeBSD ≥ 6.0, NetBSD ≥ 1.4, OpenBSD ≥ 3.1, IRIX, Solaris, Minix ≥ 3.2.  */
-
-# include <ieeefp.h>
-  /* The type is called 'fp_except_t' on FreeBSD, but 'fp_except' on
-     all other systems.  */
-# if !defined __FreeBSD__
-#  define fp_except_t fp_except
-# endif
-
-static int
-sigfpe_on_invalid ()
-{
-  /* Clear FE_INVALID exceptions from past operations.  */
-  feclearexcept (FE_INVALID);
-
-  fpsetmask (fpgetmask () | FP_X_INV);
-
-  #if defined __arm__ || defined __aarch64__
-  /* Test whether the CPU supports the request.  */
-  if ((fpgetmask () & ~FP_X_INV) == 0)
-    return -1;
-  #endif
-
-  return 0;
-}
-
-#elif HAVE_FESETTRAPENABLE
-/* HP-UX, QNX */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  /* Clear FE_INVALID exceptions from past operations.  */
-  feclearexcept (FE_INVALID);
-
-  fesettrapenable (fegettrapenable () | FE_INVALID);
-
-  return 0;
-}
-
-#elif defined _AIX
-/* AIX */
-
-# include <fptrap.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  /* Clear FE_INVALID exceptions from past operations.  */
-  feclearexcept (FE_INVALID);
-
-  /* Enable precise trapping mode.
-     Documentation: <https://www.ibm.com/docs/en/aix/7.3?topic=f-fp-trap-subroutine>  */
-  fp_trap (FP_TRAP_SYNC);
-  /* Documentation: <https://www.ibm.com/docs/en/aix/7.3?topic=f-fp-any-enable-fp-is-enabled-fp-enable-all-fp-enable-fp-disable-all-fp-disable-subroutine>  */
-  fp_enable (TRP_INVALID);
-
-  return 0;
-}
-
-#elif __MINGW32__ && defined __x86_64__
-/* mingw/x86_64 */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  /* Clear FE_INVALID exceptions from past operations.  */
-  feclearexcept (FE_INVALID);
-
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
-     fctrl bits 5..2,0 indicate which floating-point exceptions shall, when
-     occurring in the 387 compatible floating-point unit, trigger a trap rather
-     than merely set the corresponding bit in the fstat register.
-     mxcsr bits 12..9,7 indicate which floating-point exceptions shall, when
-     occurring in the SSE registers floating-point unit, trigger a trap rather
-     than merely set the corresponding bit in the lower part of the mxcsr
-     register.  */
-  /* mingw's _controlfp_s implementation
-     <https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-crt/secapi/_controlfp_s.c>
-     is broken.  This code here works.  */
-  {
-    unsigned short fctrl, orig_fctrl;
-    unsigned int mxcsr, orig_mxcsr;
-
-    __asm__ __volatile__ ("fstcw %0" : "=m" (*&fctrl));
-    __asm__ __volatile__ ("stmxcsr %0" : "=m" (*&mxcsr));
-    orig_fctrl = fctrl;
-    orig_mxcsr = mxcsr;
-    fctrl &= ~FE_INVALID;
-    mxcsr &= ~(FE_INVALID << 7);
-    if (!(fctrl == orig_fctrl && mxcsr == orig_mxcsr))
-      {
-        __asm__ __volatile__ ("fldcw %0" : : "m" (*&fctrl));
-        __asm__ __volatile__ ("ldmxcsr %0" : : "m" (*&mxcsr));
-      }
-  }
-
-  return 0;
-}
-
-#elif defined _WIN32 && !defined __CYGWIN__
-/* native Windows */
-
-# include <float.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  /* Documentation:
-     <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/controlfp-s>  */
-  unsigned int control;
-  if (_controlfp_s (&control, 0, 0) == 0)
-    if (_controlfp_s (&control, control & ~_EM_INVALID, _MCW_EM) == 0)
-      return 0;
-
-  return -1;
-}
-
-#elif MUSL_LIBC && defined __x86_64__
-/* musl libc/x86_64 */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  fenv_t env, orig_env;
-  fegetenv (&env);
-  orig_env = env;
-
-  /* Clear FE_INVALID exceptions from past operations.
-     fstat bits 5..2,0 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero, in the 387 compatible
-     floating-point unit.
-     mxcsr bits 5..2,0 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero, in the SSE registers
-     floating-point unit.  */
-  env.__status_word &= ~FE_INVALID;
-  env.__mxcsr &= ~FE_INVALID;
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
-     fctrl bits 5..2,0 indicate which floating-point exceptions shall, when
-     occurring in the 387 compatible floating-point unit, trigger a trap rather
-     than merely set the corresponding bit in the fstat register.
-     mxcsr bits 12..9,7 indicate which floating-point exceptions shall, when
-     occurring in the SSE registers floating-point unit, trigger a trap rather
-     than merely set the corresponding bit in the lower part of the mxcsr
-     register.  */
-  env.__control_word &= ~FE_INVALID;
-  env.__mxcsr &= ~(FE_INVALID << 7);
-
-  if (!(env.__control_word == orig_env.__control_word
-        && env.__status_word == orig_env.__status_word
-        && env.__mxcsr == orig_env.__mxcsr))
-    fesetenv (&env);
-
-  return 0;
-}
-
-#elif MUSL_LIBC && defined __i386__
-/* musl libc/x86 */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  fenv_t env, orig_env;
-  fegetenv (&env);
-  orig_env = env;
-
-  /* The mxcsr register exists, like for x86_64, but only if the CPU supports
-     SSE instructions.  Here it is not part of fenv_t.  Instead, it is
-     transparently handled by the fegetenv and fesetenv functions.  */
-
-  /* Clear FE_INVALID exceptions from past operations.
-     fstat bits 5..2,0 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero, in the 387 compatible
-     floating-point unit.  */
-  env.__status_word &= ~FE_INVALID;
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
-     fctrl bits 5..2,0 indicate which floating-point exceptions shall, when
-     occurring in the 387 compatible floating-point unit, trigger a trap rather
-     than merely set the corresponding bit in the fstat register.  */
-  env.__control_word &= ~FE_INVALID;
-
-  if (!(env.__control_word == orig_env.__control_word
-        && env.__status_word == orig_env.__status_word))
-    fesetenv (&env);
-
-  return 0;
-}
-
-#elif MUSL_LIBC && defined __aarch64__
-/* musl libc/arm64 */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  fenv_t env, orig_env;
-  fegetenv (&env);
-  orig_env = env;
-
-  /* Clear FE_INVALID exceptions from past operations.
-     fpsr bits 4..0 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero.  */
-  env.__fpsr &= ~FE_INVALID;
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
-     fpcr bits 12..8 indicate which floating-point exceptions shall, when
-     occurring, trigger a trap rather than merely set the corresponding bit
-     in the fpsr register.  */
-  env.__fpcr |= (FE_INVALID << 8);
-
-  if (!(env.__fpsr == orig_env.__fpsr && env.__fpcr == orig_env.__fpcr))
-    {
-      fesetenv (&env);
-      /* Test whether __fpcr was actually changed as desired.  */
-      fenv_t new_env;
-      fegetenv (&new_env);
-      if (new_env.__fpcr != env.__fpcr)
-        return -1;
-    }
-
-  return 0;
-}
-
-#elif MUSL_LIBC && defined __arm__
-/* musl libc/arm */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  fenv_t env;
-  unsigned int orig_fpscr;
-  fegetenv (&env);
-  orig_fpscr = env.__cw;
-
-  /* Clear FE_INVALID exceptions from past operations.
-     fpscr bits 4..0 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero.  */
-  env.__cw &= ~FE_INVALID;
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
-     fpscr bits 12..8 indicate which floating-point exceptions shall, when
-     occurring, trigger a trap rather than merely set the corresponding bit
-     in the fpscr register.  */
-  env.__cw |= (FE_INVALID << 8);
-
-  if (!(env.__cw == orig_fpscr))
-    {
-      fesetenv (&env);
-      /* Test whether fpscr was actually changed as desired.  */
-      fenv_t new_env;
-      fegetenv (&new_env);
-      if (new_env.__cw != env.__cw)
-        return -1;
-    }
-
-  return 0;
-}
-
-#elif MUSL_LIBC && defined __m68k__
-/* musl libc/m68k */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  fenv_t env, orig_env;
-  fegetenv (&env);
-  orig_env = env;
-
-  /* Clear FE_INVALID exceptions from past operations.
-     fpsr bits 7..3 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero.  */
-  env.__status_register &= ~FE_INVALID;
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
-     fpcr bits 15..8 indicate which floating-point exceptions shall, when
-     occurring, trigger a trap rather than merely set the corresponding bit
-     in the fpsr register:
-       - bit 15: branch/set on unordered
-       - bit 14: signaling not-a-number
-       - bit 13: operand error
-       - bit 12: overflow
-       - bit 11: underflow
-       - bit 10: divide by zero
-       - bit 9:  inexact operation
-       - bit 8:  inexact decimal input
-     Although (FE_INVALID << 6) has bit 13 set, we need to set bit 14 and
-     bit 13.  */
-  env.__control_register |= (1U << 14) | (FE_INVALID << 6);
-
-  if (!(env.__status_register == orig_env.__status_register
-        && env.__control_register == orig_env.__control_register))
-    fesetenv (&env);
-
-  return 0;
-}
-
-#elif MUSL_LIBC && defined __mips__
-/* musl libc/mips64,mipsn32,mips32 */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  fenv_t env, orig_env;
-  fegetenv (&env);
-  orig_env = env;
-
-  /* Clear FE_INVALID exceptions from past operations.
-     fcsr bits 6..2 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero.
-     fcsr bits 17..12 indicate which floating-point exceptions have occurred
-     in the most recent instruction.  */
-  env.__cw &= ~((FE_INVALID << 10) | FE_INVALID);
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
-     fcsr bits 11..7 indicate which floating-point exceptions shall, when
-     occurring, trigger a trap rather than merely set the corresponding bit
-     in the fcsr register.  */
-  env.__cw |= (FE_INVALID << 5);
-
-  if (!(env.__cw == orig_env.__cw))
-    fesetenv (&env);
-
-  return 0;
-}
-
-#elif MUSL_LIBC && (defined __powerpc__ || defined __powerpc64__)
-/* musl libc/powerpc64,powerpc */
-
-# include <fenv.h>
-# include <sys/prctl.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  /* fenv_t is a 'double'.  */
-  union { unsigned long long u; fenv_t f; } env, orig_env;
-  fegetenv (&env.f);
-  orig_env = env;
-
-  /* Clear FE_INVALID exceptions from past operations.
-     fpscr bits 28..25 indicate which floating-point exceptions, other than
-     FE_INVALID, have occurred since the respective bit was last set to zero.
-     fpscr bits 24..19, 10..8 do the same thing, for various kinds of Invalid
-     Operation.  fpscr bit 29 is the summary (the OR) of all these bits.
-     Instead of clearing FE_INVALID (= bit 29), we need to clear these
-     individual bits.  */
-  env.u &= ~FE_ALL_INVALID; /* not ~FE_INVALID ! */
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
-     fpscr bits 7..3 indicate which floating-point exceptions shall, when
-     occurring, trigger a trap rather than merely set the corresponding bit
-     in the fpscr register.  */
-  env.u |= (FE_INVALID >> 22);
-
-  if (!(env.u == orig_env.u))
-    {
-      /* Enable precise trapping mode.  */
-      prctl (PR_SET_FPEXC, PR_FP_EXC_PRECISE);
-
-      fesetenv (&env.f);
-    }
-
-  return 0;
-}
-
-#elif MUSL_LIBC && (defined __s390__ || defined __s390x__)
-/* musl libc/s390x,s390 */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  fenv_t env, orig_env;
-  fegetenv (&env);
-  orig_env = env;
-
-  /* Clear FE_INVALID exceptions from past operations.
-     fpc bits 23..19 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero.
-     fpc bits 15..11 are part of the "data exception code" (DXC) and have a
-     similar meaning if bits 9..8 are both zero.  */
-  env &= ~FE_INVALID;
-  if ((env & 0x00000300) == 0)
-    env &= ~(FE_INVALID >> 8);
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
-     fpc bits 31..27 indicate which floating-point exceptions shall, when
-     occurring, trigger a trap rather than merely set the corresponding bit
-     in the fpc register.  */
-  env |= ((unsigned int) FE_INVALID << 8);
-
-  if (!(env == orig_env))
-    fesetenv (&env);
-
-  return 0;
-}
-
-#elif MUSL_LIBC && defined __sh__
-/* musl libc/sh4 */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  fenv_t env, orig_env;
-  fegetenv (&env);
-  orig_env = env;
-
-  /* Clear FE_INVALID exceptions from past operations.
-     fpscr bits 6..2 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero.  */
-  env.__cw &= ~FE_INVALID;
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
-     fpscr bits 11..7 indicate which floating-point exceptions shall, when
-     occurring, trigger a trap rather than merely set the corresponding bit
-     in the fpscr register.  */
-  env.__cw |= (FE_INVALID << 5);
-
-  if (!(env.__cw == orig_env.__cw))
-    fesetenv (&env);
-
-  return 0;
-}
-
-#elif (defined __APPLE__ && defined __MACH__) && (defined __i386__ || defined __x86_64__)
-/* Mac OS X/i386,x86_64 */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  fenv_t env, orig_env;
-  fegetenv (&env);
-  orig_env = env;
-
-  /* Clear FE_INVALID exceptions from past operations.
-     fstat bits 5..2,0 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero, in the 387 compatible
-     floating-point unit.
-     mxcsr bits 5..2,0 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero, in the SSE registers
-     floating-point unit.  */
-  env.__status &= ~FE_INVALID;
-  env.__mxcsr &= ~FE_INVALID;
-  /* An FE_INVALID exception shall trigger a SIGFPE signal.
-     fctrl bits 5..2,0 indicate which floating-point exceptions shall, when
-     occurring in the 387 compatible floating-point unit, trigger a trap rather
-     than merely set the corresponding bit in the fstat register.
-     mxcsr bits 12..9,7 indicate which floating-point exceptions shall, when
-     occurring in the SSE registers floating-point unit, trigger a trap rather
-     than merely set the corresponding bit in the lower part of the mxcsr
-     register.  */
-  env.__control &= ~FE_INVALID;
-  env.__mxcsr &= ~(FE_INVALID << 7);
-
-  if (!(env.__control == orig_env.__control
-        && env.__status == orig_env.__status
-        && env.__mxcsr == orig_env.__mxcsr))
-    fesetenv (&env);
-
-  return 0;
-}
-
-#elif (defined __APPLE__ && defined __MACH__) && defined __aarch64__
-/* macOS/arm64 */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  fenv_t env, orig_env;
-  fegetenv (&env);
-  orig_env = env;
-
-  /* Clear FE_INVALID exceptions from past operations.
-     fpsr bits 4..0 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero.  */
-  env.__fpsr &= ~FE_INVALID;
-  /* An FE_INVALID exception shall trigger a SIGILL signal.
-     fpcr bits 12..8 indicate which floating-point exceptions shall, when
-     occurring, trigger a trap rather than merely set the corresponding bit
-     in the fpsr register.  */
-  env.__fpcr |= (FE_INVALID << 8); /* __fpcr_trap_invalid */
-
-  if (!(env.__fpsr == orig_env.__fpsr && env.__fpcr == orig_env.__fpcr))
-    fesetenv (&env);
-
-  return 0;
-}
-
-#elif (defined __APPLE__ && defined __MACH__) && defined __arm__
-/* macOS/arm */
-
-# include <fenv.h>
-
-static int
-sigfpe_on_invalid ()
-{
-  fenv_t env;
-  unsigned int orig_fpscr;
-  fegetenv (&env);
-  orig_fpscr = env.__fpscr;
-
-  /* Clear FE_INVALID exceptions from past operations.
-     fpscr bits 4..0 indicate which floating-point exceptions have occurred
-     since the respective bit was last set to zero.  */
-  env.__fpscr &= ~FE_INVALID;
-  /* An FE_INVALID exception shall trigger a signal.
-     fpscr bits 12..8 indicate which floating-point exceptions shall, when
-     occurring, trigger a trap rather than merely set the corresponding bit
-     in the fpscr register.  */
-  env.__fpscr |= (FE_INVALID << 8); /* __fpscr_trap_invalid */
-
-  if (!(env.__fpscr == orig_fpscr))
-    fesetenv (&env);
-
-  return 0;
-}
-
-#else
-
-# undef HAVE_FPE_TRAPPING
-
+/* And it does not work on arm with software floating-point emulation.  */
+#if !(defined __riscv || (defined __GLIBC__ && defined __arm__ && defined __SOFTFP__))
+# define HAVE_FPE_TRAPPING 1
 #endif
diff --git a/m4/fpe-trapping.m4 b/m4/fpe-trapping.m4
new file mode 100644 (file)
index 0000000..a250d37
--- /dev/null
@@ -0,0 +1,20 @@
+# fpe-trapping.m4 serial 1
+dnl Copyright (C) 2023 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Prerequisites for turning FE_INVALID exceptions into a SIGFPE signal.
+AC_DEFUN_ONCE([gl_FPE_TRAPPING],
+[
+  dnl Get FENV_EXCEPTIONS_TRACKING_LIBM.
+  AC_REQUIRE([gl_FENV_EXCEPTIONS_TRACKING])
+  dnl Get FENV_EXCEPTIONS_TRAPPING_LIBM.
+  AC_REQUIRE([gl_FENV_EXCEPTIONS_TRAPPING])
+
+  FPE_TRAPPING_LIBM="$FENV_EXCEPTIONS_TRACKING_LIBM"
+  if test -z "$FPE_TRAPPING_LIBM"; then
+    FPE_TRAPPING_LIBM="$FENV_EXCEPTIONS_TRAPPING_LIBM"
+  fi
+  AC_SUBST([FPE_TRAPPING_LIBM])
+])
diff --git a/m4/fpe.m4 b/m4/fpe.m4
deleted file mode 100644 (file)
index 94ca0d5..0000000
--- a/m4/fpe.m4
+++ /dev/null
@@ -1,74 +0,0 @@
-# fpe.m4 serial 2
-dnl Copyright (C) 2023 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-# Prerequisites for turning FE_INVALID exceptions into a SIGFPE signal.
-AC_DEFUN_ONCE([gl_FPE_TRAPPING],
-[
-  dnl Persuade glibc <fenv.h> to declare feenableexcept().
-  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
-
-  gl_MATHFUNC([feenableexcept], [int], [(int)], [#include <fenv.h>])
-  if test $gl_cv_func_feenableexcept_no_libm = yes \
-     || test $gl_cv_func_feenableexcept_in_libm = yes; then
-    AC_DEFINE([HAVE_FEENABLEEXCEPT], [1],
-      [Define to 1 if you have the 'feenableexcept' function.])
-  fi
-
-  gl_MATHFUNC([fpsetmask], [fp_except_t], [(fp_except_t)],
-    [#include <ieeefp.h>
-     /* The type is called 'fp_except_t' on FreeBSD, but 'fp_except' on
-        all other systems.  */
-     #if !defined __FreeBSD__
-     #define fp_except_t fp_except
-     #endif
-    ])
-  if test $gl_cv_func_fpsetmask_no_libm = yes \
-     || test $gl_cv_func_fpsetmask_in_libm = yes; then
-    AC_DEFINE([HAVE_FPSETMASK], [1],
-      [Define to 1 if you have the 'fpsetmask' function.])
-  fi
-
-  gl_MATHFUNC([fesettrapenable], [int], [(int)], [#include <fenv.h>])
-  if test $gl_cv_func_fesettrapenable_no_libm = yes \
-     || test $gl_cv_func_fesettrapenable_in_libm = yes; then
-    AC_DEFINE([HAVE_FESETTRAPENABLE], [1],
-      [Define to 1 if you have the 'fesettrapenable' function.])
-  fi
-
-  gl_MUSL_LIBC
-
-  if test $gl_cv_func_feenableexcept_no_libm = yes \
-     || test $gl_cv_func_feenableexcept_in_libm = yes; then
-    if test $gl_cv_func_feenableexcept_no_libm != yes; then
-      FPE_TRAPPING_LIBM=-lm
-    else
-      FPE_TRAPPING_LIBM=
-    fi
-  else
-    if test $gl_cv_func_fpsetmask_no_libm = yes \
-       || test $gl_cv_func_fpsetmask_in_libm = yes; then
-      if test $gl_cv_func_fpsetmask_no_libm != yes; then
-        FPE_TRAPPING_LIBM=-lm
-      else
-        FPE_TRAPPING_LIBM=
-      fi
-    else
-      if test $gl_cv_func_fesettrapenable_no_libm = yes \
-         || test $gl_cv_func_fesettrapenable_in_libm = yes; then
-        if test $gl_cv_func_fesettrapenable_no_libm != yes; then
-          FPE_TRAPPING_LIBM=-lm
-        else
-          FPE_TRAPPING_LIBM=
-        fi
-      else
-        FPE_TRAPPING_LIBM=
-      fi
-    fi
-  fi
-  AC_REQUIRE([gl_FENV_EXCEPTIONS_TRACKING])
-  FPE_TRAPPING_LIBM="$FPE_TRAPPING_LIBM $FENV_EXCEPTIONS_TRACKING_LIBM"
-  AC_SUBST([FPE_TRAPPING_LIBM])
-])
index 353e77bdefa9ae667a175069ad4c409b24a920b3..f1d5ecc17f4e10272bd3e5d94a1ab84a69547c7d 100644 (file)
@@ -4,13 +4,12 @@ into a signal.
 
 Files:
 lib/fpe-trapping.h
-m4/fpe.m4
-m4/mathfunc.m4
-m4/musl.m4
+m4/fpe-trapping.m4
 
 Depends-on:
 extensions
 fenv-exceptions-tracking-c99
+fenv-exceptions-trapping
 
 configure.ac:
 gl_FPE_TRAPPING
index b87fbb5a87738250f3717f61dbe483d887e91109..bebcf5f59091b96b2854a7424aafcf06a031451e 100644 (file)
@@ -86,7 +86,7 @@ main ()
 int
 main ()
 {
-  fputs ("Skipping test: feenableexcept or fpsetmask or fp_enable not available\n", stderr);
+  fputs ("Skipping test: feenableexcept not available\n", stderr);
   return 77;
 }
 
index 1d8529ad04274014805dd5311c4a3b43295a13cd..9844166d81f85a58a5aff3e5e55d418aafc87eef 100644 (file)
@@ -94,7 +94,7 @@ main (int argc, char *argv[])
 int
 main ()
 {
-  fputs ("Skipping test: feenableexcept or fpsetmask or fp_enable not available\n", stderr);
+  fputs ("Skipping test: feenableexcept not available\n", stderr);
   return 77;
 }
 
index a7ef77a206d35ae36394ee52b3f704d750b22262..63fabad48f43a320bc4aaae4859db844b885f938 100644 (file)
@@ -57,7 +57,7 @@ main ()
 int
 main ()
 {
-  fputs ("Skipping test: feenableexcept or fpsetmask or fp_enable not available\n", stderr);
+  fputs ("Skipping test: feenableexcept not available\n", stderr);
   return 77;
 }
 
index 0efb5e66649544d6e7668d6ef35e744b25efab1a..449c5d6a2377cc890c1fc4ed0b5f434f6a13eb85 100644 (file)
@@ -72,7 +72,7 @@ main ()
 int
 main ()
 {
-  fputs ("Skipping test: feenableexcept or fpsetmask or fp_enable not available\n", stderr);
+  fputs ("Skipping test: feenableexcept not available\n", stderr);
   return 77;
 }
 
index b82ebabf4bfc6a9073f63d5e4e37e78ca7c3477d..b0d65b0c06136795feb6f5bbde05fcae39647088 100644 (file)
@@ -77,7 +77,7 @@ main ()
 int
 main ()
 {
-  fputs ("Skipping test: feenableexcept or fpsetmask or fp_enable not available\n", stderr);
+  fputs ("Skipping test: feenableexcept not available\n", stderr);
   return 77;
 }
 
index 5e5940609c8e7e197da67d97f3e58f6d21f3edf3..0a722a05ac914a5fb0cc421f8cbedcb614a83fc9 100644 (file)
@@ -147,7 +147,7 @@ main (int argc, char *argv[])
 int
 main ()
 {
-  fputs ("Skipping test: feenableexcept or fpsetmask or fp_enable not available\n", stderr);
+  fputs ("Skipping test: feenableexcept not available\n", stderr);
   return 77;
 }