From 6d2dfab57ddfad6bede47999eced62e517e88efd Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 30 Oct 2023 16:32:30 +0100 Subject: [PATCH 01/14] 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. --- ChangeLog | 8 ++++++++ lib/fenv-except-tracking-clear.c | 7 +++---- lib/fenv-except-tracking-raise.c | 16 ++++++---------- lib/fenv-except-tracking-set.c | 20 +++++++++----------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 26686c3fb8..1fc40e4ae2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2023-10-30 Bruno Haible + + 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 fenv-exceptions-tracking-c23: Add tests. diff --git a/lib/fenv-except-tracking-clear.c b/lib/fenv-except-tracking-clear.c index 22c85c98e0..9819832a5f 100644 --- a/lib/fenv-except-tracking-clear.c +++ b/lib/fenv-except-tracking-clear.c @@ -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 ()) { diff --git a/lib/fenv-except-tracking-raise.c b/lib/fenv-except-tracking-raise.c index 8699662ef5..c263151e60 100644 --- a/lib/fenv-except-tracking-raise.c +++ b/lib/fenv-except-tracking-raise.c @@ -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 diff --git a/lib/fenv-except-tracking-set.c b/lib/fenv-except-tracking-set.c index 73b566cb01..d4237015e8 100644 --- a/lib/fenv-except-tracking-set.c +++ b/lib/fenv-except-tracking-set.c @@ -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 -- 2.34.1