Now that proper modules for tracking and trapping floating-point exceptions
are in place (that work on all platforms, and with unit tests), the modules
fpe-tracking and fpe-trapping can take advantage of them:

* The module fpe-tracking can be removed. fenv-exceptions-tracking-c99 is
  its replacement. (The module was not yet picked up by any package outside
  gnulib.)

* The module fpe-trapping becomes a trivial combination of
  fenv-exceptions-tracking-c99 and fenv-exceptions-trapping.


2023-11-05  Bruno Haible  <br...@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  <br...@clisp.org>

        fpe-tracking: Remove module.
        * modules/fpe-tracking: Remove file.
        * m4/fpe.m4 (gl_FPE_TRACKING): Remove macro.
        (gl_FPE_TRAPPING): Require gl_FENV_EXCEPTIONS_TRACKING instead of
        gl_FPE_TRACKING. Use FENV_EXCEPTIONS_TRACKING_LIBM instead of
        FPE_TRACKING_LIBM.
        * modules/nan-tests (Depends-on): Add fenv-exceptions-tracking-c99.
        Remove fpe-tracking.
        (Makefile.am): Use FENV_EXCEPTIONS_TRACKING_LIBM instead of
        FPE_TRACKING_LIBM.
        * modules/snan-tests (Depends-on): Add fenv-exceptions-tracking-c99.
        Remove fpe-tracking.
        (Makefile.am): Use FENV_EXCEPTIONS_TRACKING_LIBM instead of
        FPE_TRACKING_LIBM.
        * tests/test-nan-1.c: Assume HAVE_FE_INVALID is 1.
        * tests/test-snan-1.c: Likewise.

>From 6facb2ddab273a8798374897af23e9ad45aba899 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Sun, 5 Nov 2023 14:27:47 +0100
Subject: [PATCH 1/2] fpe-tracking: Remove module.

* modules/fpe-tracking: Remove file.
* m4/fpe.m4 (gl_FPE_TRACKING): Remove macro.
(gl_FPE_TRAPPING): Require gl_FENV_EXCEPTIONS_TRACKING instead of
gl_FPE_TRACKING. Use FENV_EXCEPTIONS_TRACKING_LIBM instead of
FPE_TRACKING_LIBM.
* modules/nan-tests (Depends-on): Add fenv-exceptions-tracking-c99.
Remove fpe-tracking.
(Makefile.am): Use FENV_EXCEPTIONS_TRACKING_LIBM instead of
FPE_TRACKING_LIBM.
* modules/snan-tests (Depends-on): Add fenv-exceptions-tracking-c99.
Remove fpe-tracking.
(Makefile.am): Use FENV_EXCEPTIONS_TRACKING_LIBM instead of
FPE_TRACKING_LIBM.
* tests/test-nan-1.c: Assume HAVE_FE_INVALID is 1.
* tests/test-snan-1.c: Likewise.
---
 ChangeLog            | 19 ++++++++++++++++++
 m4/fpe.m4            | 47 +++-----------------------------------------
 modules/fpe-tracking | 27 -------------------------
 modules/nan-tests    |  4 ++--
 modules/snan-tests   |  4 ++--
 tests/test-nan-1.c   | 27 +++++--------------------
 tests/test-snan-1.c  | 27 +++++--------------------
 7 files changed, 36 insertions(+), 119 deletions(-)
 delete mode 100644 modules/fpe-tracking

diff --git a/ChangeLog b/ChangeLog
index 0955567775..3b2951ff6e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2023-11-05  Bruno Haible  <br...@clisp.org>
+
+	fpe-tracking: Remove module.
+	* modules/fpe-tracking: Remove file.
+	* m4/fpe.m4 (gl_FPE_TRACKING): Remove macro.
+	(gl_FPE_TRAPPING): Require gl_FENV_EXCEPTIONS_TRACKING instead of
+	gl_FPE_TRACKING. Use FENV_EXCEPTIONS_TRACKING_LIBM instead of
+	FPE_TRACKING_LIBM.
+	* modules/nan-tests (Depends-on): Add fenv-exceptions-tracking-c99.
+	Remove fpe-tracking.
+	(Makefile.am): Use FENV_EXCEPTIONS_TRACKING_LIBM instead of
+	FPE_TRACKING_LIBM.
+	* modules/snan-tests (Depends-on): Add fenv-exceptions-tracking-c99.
+	Remove fpe-tracking.
+	(Makefile.am): Use FENV_EXCEPTIONS_TRACKING_LIBM instead of
+	FPE_TRACKING_LIBM.
+	* tests/test-nan-1.c: Assume HAVE_FE_INVALID is 1.
+	* tests/test-snan-1.c: Likewise.
+
 2023-11-05  Bruno Haible  <br...@clisp.org>
 
 	fenv-exceptions-trapping: Avoid test failure on NetBSD/sparc.
diff --git a/m4/fpe.m4 b/m4/fpe.m4
index f8a81030a6..94ca0d5cc1 100644
--- a/m4/fpe.m4
+++ b/m4/fpe.m4
@@ -1,50 +1,9 @@
-# fpe.m4 serial 1
+# 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 tracking FE_INVALID exceptions.
-AC_DEFUN_ONCE([gl_FPE_TRACKING],
-[
-  AC_CACHE_CHECK([whether FE_INVALID exceptions can be tracked],
-    [gl_cv_fenv_invalid_api],
-    [AC_COMPILE_IFELSE(
-       [AC_LANG_PROGRAM(
-          [[#include <fenv.h>
-          ]],
-          [[feclearexcept (FE_INVALID);
-          ]])
-       ],
-       [gl_cv_fenv_invalid_api=yes],
-       [gl_cv_fenv_invalid_api=no])
-    ])
-  if test $gl_cv_fenv_invalid_api = yes; then
-    AC_DEFINE([HAVE_FE_INVALID], [1],
-      [Define if FE_INVALID exceptions can be programmatically tracked.])
-    AC_CACHE_CHECK([whether feclearexcept can be used without linking with libm],
-      [gl_cv_func_feclearexcept_no_libm],
-      [AC_LINK_IFELSE(
-         [AC_LANG_PROGRAM(
-            [[#include <fenv.h>
-            ]],
-            [[feclearexcept (FE_INVALID);
-            ]])
-         ],
-         [gl_cv_func_feclearexcept_no_libm=yes],
-         [gl_cv_func_feclearexcept_no_libm=no])
-      ])
-    if test $gl_cv_func_feclearexcept_no_libm != yes; then
-      FPE_TRACKING_LIBM=-lm
-    else
-      FPE_TRACKING_LIBM=
-    fi
-  else
-    FPE_TRACKING_LIBM=
-  fi
-  AC_SUBST([FPE_TRACKING_LIBM])
-])
-
 # Prerequisites for turning FE_INVALID exceptions into a SIGFPE signal.
 AC_DEFUN_ONCE([gl_FPE_TRAPPING],
 [
@@ -109,7 +68,7 @@ AC_DEFUN_ONCE([gl_FPE_TRAPPING]
       fi
     fi
   fi
-  AC_REQUIRE([gl_FPE_TRACKING])
-  FPE_TRAPPING_LIBM="$FPE_TRAPPING_LIBM $FPE_TRACKING_LIBM"
+  AC_REQUIRE([gl_FENV_EXCEPTIONS_TRACKING])
+  FPE_TRAPPING_LIBM="$FPE_TRAPPING_LIBM $FENV_EXCEPTIONS_TRACKING_LIBM"
   AC_SUBST([FPE_TRAPPING_LIBM])
 ])
diff --git a/modules/fpe-tracking b/modules/fpe-tracking
deleted file mode 100644
index d1afcf94f0..0000000000
--- a/modules/fpe-tracking
+++ /dev/null
@@ -1,27 +0,0 @@
-Description:
-Tracking floating-point exceptions, i.e. determining whether
-a floating-point exception has occurred during a certain computation.
-
-Files:
-m4/fpe.m4
-
-Depends-on:
-
-configure.ac:
-gl_FPE_TRACKING
-
-Makefile.am:
-
-Include:
-#if HAVE_FE_INVALID
-# include <fenv.h>
-#endif
-
-Link:
-$(FPE_TRACKING_LIBM)
-
-License:
-GPL
-
-Maintainer:
-all
diff --git a/modules/nan-tests b/modules/nan-tests
index 607e35f63b..ec549b8919 100644
--- a/modules/nan-tests
+++ b/modules/nan-tests
@@ -4,7 +4,7 @@ tests/test-nan-2.c
 tests/macros.h
 
 Depends-on:
-fpe-tracking
+fenv-exceptions-tracking-c99
 fpe-trapping
 
 configure.ac:
@@ -12,5 +12,5 @@ configure.ac:
 Makefile.am:
 TESTS += test-nan-1 test-nan-2
 check_PROGRAMS += test-nan-1 test-nan-2
-test_nan_1_LDADD = $(LDADD) @FPE_TRACKING_LIBM@
+test_nan_1_LDADD = $(LDADD) $(FENV_EXCEPTIONS_TRACKING_LIBM)
 test_nan_2_LDADD = $(LDADD) @FPE_TRAPPING_LIBM@
diff --git a/modules/snan-tests b/modules/snan-tests
index 91210d2ea5..6779f6c0bf 100644
--- a/modules/snan-tests
+++ b/modules/snan-tests
@@ -6,7 +6,7 @@ tests/macros.h
 m4/math_h.m4
 
 Depends-on:
-fpe-tracking
+fenv-exceptions-tracking-c99
 fpe-trapping
 
 configure.ac:
@@ -15,5 +15,5 @@ AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE])
 Makefile.am:
 TESTS += test-snan-1 test-snan-2.sh
 check_PROGRAMS += test-snan-1 test-snan-2
-test_snan_1_LDADD = $(LDADD) @FPE_TRACKING_LIBM@
+test_snan_1_LDADD = $(LDADD) $(FENV_EXCEPTIONS_TRACKING_LIBM)
 test_snan_2_LDADD = $(LDADD) @FPE_TRAPPING_LIBM@
diff --git a/tests/test-nan-1.c b/tests/test-nan-1.c
index 4ebe013e3c..9b48a6853f 100644
--- a/tests/test-nan-1.c
+++ b/tests/test-nan-1.c
@@ -21,11 +21,9 @@
 /* Specification.  */
 #include "nan.h"
 
-#include <stdio.h>
+#if defined __GLIBC__ && defined __arm__ && defined __SOFTFP__
 
-#if HAVE_FE_INVALID
-
-# if defined __GLIBC__ && defined __arm__ && defined __SOFTFP__
+# include <stdio.h>
 
 /* The arm software floating-point emulation (used e.g. on armv5) does not set
    the floating-point exception bits.  */
@@ -37,11 +35,11 @@ main ()
   return 77;
 }
 
-# else
+#else
 
-#  include <fenv.h>
+# include <fenv.h>
 
-#  include "macros.h"
+# include "macros.h"
 
 float volatile resultf;
 double volatile resultd;
@@ -80,19 +78,4 @@ main ()
   return 0;
 }
 
-# endif
-
-#else
-
-/* No <fenv.h> available.
-   We could use the various alternative approaches from
-   libgfortran/config/fpu-*.h, but that's not worth it.  */
-
-int
-main ()
-{
-  fputs ("Skipping test: feclearexcept, fetestexcept, FE_INVALID not available\n", stderr);
-  return 77;
-}
-
 #endif
diff --git a/tests/test-snan-1.c b/tests/test-snan-1.c
index 7b71b9a57b..3b1e0e9427 100644
--- a/tests/test-snan-1.c
+++ b/tests/test-snan-1.c
@@ -21,11 +21,9 @@
 /* Specification.  */
 #include "snan.h"
 
-#include <stdio.h>
+#if defined __GLIBC__ && defined __arm__ && defined __SOFTFP__
 
-#if HAVE_FE_INVALID
-
-# if defined __GLIBC__ && defined __arm__ && defined __SOFTFP__
+# include <stdio.h>
 
 /* The arm software floating-point emulation (used e.g. on armv5) does not set
    the floating-point exception bits.  */
@@ -37,11 +35,11 @@ main ()
   return 77;
 }
 
-# else
+#else
 
-#  include <fenv.h>
+# include <fenv.h>
 
-#  include "macros.h"
+# include "macros.h"
 
 float volatile resultf;
 double volatile resultd;
@@ -105,19 +103,4 @@ main ()
   return 0;
 }
 
-# endif
-
-#else
-
-/* No <fenv.h> available.
-   We could use the various alternative approaches from
-   libgfortran/config/fpu-*.h, but that's not worth it.  */
-
-int
-main ()
-{
-  fputs ("Skipping test: feclearexcept, fetestexcept, FE_INVALID not available\n", stderr);
-  return 77;
-}
-
 #endif
-- 
2.34.1

From 45d01c797646d9d89d44405b1841009c949ed325 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Sun, 5 Nov 2023 14:34:39 +0100
Subject: [PATCH 2/2] 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.
---
 ChangeLog                           |  17 +
 lib/fpe-trapping.h                  | 588 +---------------------------
 m4/fpe-trapping.m4                  |  20 +
 m4/fpe.m4                           |  74 ----
 modules/fpe-trapping                |   5 +-
 tests/test-fenv-except-state-2.c    |   2 +-
 tests/test-fenv-except-tracking-2.c |   2 +-
 tests/test-fenv-except-tracking-3.c |   2 +-
 tests/test-fenv-except-tracking-5.c |   2 +-
 tests/test-nan-2.c                  |   2 +-
 tests/test-snan-2.c                 |   2 +-
 11 files changed, 51 insertions(+), 665 deletions(-)
 create mode 100644 m4/fpe-trapping.m4
 delete mode 100644 m4/fpe.m4

diff --git a/ChangeLog b/ChangeLog
index 3b2951ff6e..3e8c6cf2a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2023-11-05  Bruno Haible  <br...@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  <br...@clisp.org>
 
 	fpe-tracking: Remove module.
diff --git a/lib/fpe-trapping.h b/lib/fpe-trapping.h
index 9040a218ce..005ede6bf0 100644
--- a/lib/fpe-trapping.h
+++ b/lib/fpe-trapping.h
@@ -23,13 +23,8 @@
    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
index 0000000000..a250d377f8
--- /dev/null
+++ b/m4/fpe-trapping.m4
@@ -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
index 94ca0d5cc1..0000000000
--- 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])
-])
diff --git a/modules/fpe-trapping b/modules/fpe-trapping
index 353e77bdef..f1d5ecc17f 100644
--- a/modules/fpe-trapping
+++ b/modules/fpe-trapping
@@ -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
diff --git a/tests/test-fenv-except-state-2.c b/tests/test-fenv-except-state-2.c
index b87fbb5a87..bebcf5f590 100644
--- a/tests/test-fenv-except-state-2.c
+++ b/tests/test-fenv-except-state-2.c
@@ -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;
 }
 
diff --git a/tests/test-fenv-except-tracking-2.c b/tests/test-fenv-except-tracking-2.c
index 1d8529ad04..9844166d81 100644
--- a/tests/test-fenv-except-tracking-2.c
+++ b/tests/test-fenv-except-tracking-2.c
@@ -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;
 }
 
diff --git a/tests/test-fenv-except-tracking-3.c b/tests/test-fenv-except-tracking-3.c
index a7ef77a206..63fabad48f 100644
--- a/tests/test-fenv-except-tracking-3.c
+++ b/tests/test-fenv-except-tracking-3.c
@@ -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;
 }
 
diff --git a/tests/test-fenv-except-tracking-5.c b/tests/test-fenv-except-tracking-5.c
index 0efb5e6664..449c5d6a23 100644
--- a/tests/test-fenv-except-tracking-5.c
+++ b/tests/test-fenv-except-tracking-5.c
@@ -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;
 }
 
diff --git a/tests/test-nan-2.c b/tests/test-nan-2.c
index b82ebabf4b..b0d65b0c06 100644
--- a/tests/test-nan-2.c
+++ b/tests/test-nan-2.c
@@ -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;
 }
 
diff --git a/tests/test-snan-2.c b/tests/test-snan-2.c
index 5e5940609c..0a722a05ac 100644
--- a/tests/test-snan-2.c
+++ b/tests/test-snan-2.c
@@ -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;
 }
 
-- 
2.34.1

Reply via email to