+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.
/* 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 ())
{
/* 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
{
/* 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