]> Savannah Git Hosting - gnulib.git/commitdiff
fenv-exceptions-tracking-{c99,c23}: Fix the x86_64 and i386 case.
authorBruno Haible <bruno@clisp.org>
Mon, 30 Oct 2023 15:32:30 +0000 (16:32 +0100)
committerBruno Haible <bruno@clisp.org>
Mon, 30 Oct 2023 15:33:18 +0000 (16:33 +0100)
* lib/fenv-except-tracking-clear.c (feclearexcept): Make sure to restore
the exception trap bits in all cases.
* lib/fenv-except-tracking-raise.c (feraiseexcept): Likewise.
* lib/fenv-except-tracking-set.c (fesetexcept): Likewise.

ChangeLog
lib/fenv-except-tracking-clear.c
lib/fenv-except-tracking-raise.c
lib/fenv-except-tracking-set.c

index 26686c3fb8625d37b700d4ac422f147b4aa65639..1fc40e4ae26f6fdd8599f7dc81776bff0e09e234 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2023-10-30  Bruno Haible  <bruno@clisp.org>
+
+       fenv-exceptions-tracking-{c99,c23}: Fix the x86_64 and i386 case.
+       * lib/fenv-except-tracking-clear.c (feclearexcept): Make sure to restore
+       the exception trap bits in all cases.
+       * lib/fenv-except-tracking-raise.c (feraiseexcept): Likewise.
+       * lib/fenv-except-tracking-set.c (fesetexcept): Likewise.
+
 2023-10-29  Bruno Haible  <bruno@clisp.org>
 
        fenv-exceptions-tracking-c23: Add tests.
index 22c85c98e055dcab9f2af7274037fd51be3f1052..9819832a5fec7ec79f941028d1936d1d4bf67c1e 100644 (file)
@@ -48,12 +48,11 @@ feclearexcept (int exceptions)
 
   /* Clear the bits in the 387 unit.  */
   x86_387_fenv_t env;
-  unsigned short orig_status_word;
   __asm__ __volatile__ ("fnstenv %0" : "=m" (*&env));
-  orig_status_word = env.__status_word;
+  /* Note: fnstenv masks all floating-point exceptions until the fldenv
+     below.  */
   env.__status_word &= ~exceptions;
-  if (env.__status_word != orig_status_word)
-    __asm__ __volatile__ ("fldenv %0" : : "m" (*&env));
+  __asm__ __volatile__ ("fldenv %0" : : "m" (*&env));
 
   if (CPU_HAS_SSE ())
     {
index 8699662ef554477174b05fec420fd36b7a81537a..c263151e6019b379794d6c0935388f88f62a31a5 100644 (file)
@@ -106,18 +106,14 @@ feraiseexcept (int exceptions)
 
       /* Set the bits in the 387 unit.  */
       x86_387_fenv_t env;
-      unsigned short orig_status_word;
       __asm__ __volatile__ ("fnstenv %0" : "=m" (*&env));
-      orig_status_word = env.__status_word;
+      /* Note: fnstenv masks all floating-point exceptions until the fldenv
+         below.  */
       env.__status_word |= exceptions;
-      if (env.__status_word != orig_status_word)
-        {
-          __asm__ __volatile__ ("fldenv %0" : : "m" (*&env));
-          /* A trap (if enabled) is triggered only at the next floating-point
-             instruction.  Force it to occur here.  */
-          __asm__ __volatile__ ("fwait");
-        }
-
+      __asm__ __volatile__ ("fldenv %0" : : "m" (*&env));
+      /* A trap (if enabled) is triggered only at the next floating-point
+         instruction.  Force it to occur here.  */
+      __asm__ __volatile__ ("fwait");
     }
 
 #  endif
index 73b566cb01e4a69e9bfa9bad7df0a3ce5b69dae0..d4237015e870d0d562056a10baabe6369b7600b6 100644 (file)
@@ -69,21 +69,19 @@ fesetexcept (int exceptions)
     {
       /* Set the flags in the 387 unit.  */
       x86_387_fenv_t env;
-      unsigned short orig_status_word;
       __asm__ __volatile__ ("fnstenv %0" : "=m" (*&env));
-      orig_status_word = env.__status_word;
+      /* Note: fnstenv masks all floating-point exceptions until the fldenv
+         or fldcw below.  */
       env.__status_word |= exceptions;
-      if (env.__status_word != orig_status_word)
+      if ((~env.__control_word) & exceptions)
         {
-          if ((~env.__control_word) & exceptions)
-            {
-              /* Setting the exception flags may trigger a trap (at the next
-                 floating-point instruction, but that does not matter).
-                 ISO C 23 § 7.6.4.4 does not allow it.  */
-              return -1;
-            }
-          __asm__ __volatile__ ("fldenv %0" : : "m" (*&env));
+          /* Setting the exception flags may trigger a trap (at the next
+             floating-point instruction, but that does not matter).
+             ISO C 23 § 7.6.4.4 does not allow it.  */
+          __asm__ __volatile__ ("fldcw %0" : : "m" (*&env.__control_word));
+          return -1;
         }
+      __asm__ __volatile__ ("fldenv %0" : : "m" (*&env));
     }
 #   endif
 #  endif