* fenv-exceptions-state-c99: Fix test failures with Oracle cc 12.6
@ 2024-03-29 2:53 Bruno Haible
0 siblings, 0 replies; only message in thread
From: Bruno Haible @ 2024-03-29 2:53 UTC (permalink / raw
To: bug-gnulib
With Oracle Developer Studio 12.6 cc, on Linux/glibc, I see these two
test failures:
FAIL: test-fenv-except-state-2
==============================
../../gltests/test-fenv-except-state-2.c:57: assertion 'fesetexceptflag (&saved_flags_1, FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) == 0' failed
FAIL test-fenv-except-state-2 (exit status: 134)
FAIL: test-fenv-except-state-3
==============================
../../gltests/test-fenv-except-state-3.c:73: assertion 'rc == 0' failed
FAIL test-fenv-except-state-3 (exit status: 134)
This patch fixes them.
2024-03-28 Bruno Haible <bruno@clisp.org>
fenv-exceptions-state-c99: Fix test failures with Oracle cc 12.6.
* lib/fenv-except-state-set.c (mask387cw): New function.
(fesetexceptflag): Use it on glibc.
diff --git a/lib/fenv-except-state-set.c b/lib/fenv-except-state-set.c
index 8ca6818cbe..cafad201e3 100644
--- a/lib/fenv-except-state-set.c
+++ b/lib/fenv-except-state-set.c
@@ -441,15 +441,16 @@ fesetexceptflag (fexcept_t const *saved_flags, int exceptions)
/* The compiler does not support __asm__ statements or equivalent
intrinsics. */
-# if defined __sun && ((defined __x86_64__ || defined _M_X64) || (defined __i386 || defined _M_IX86)) && defined __SUNPRO_C
-/* Solaris/i386, Solaris/x86_64. */
+# if (defined __sun || __GLIBC__ >= 2) && ((defined __x86_64__ || defined _M_X64) || (defined __i386 || defined _M_IX86)) && defined __SUNPRO_C
+/* Solaris/i386, Solaris/x86_64, glibc/i386, glibc/x86_64, with SunPRO C. */
-/* On these platforms, fpsetsticky cannot be used here, because it may generate
- traps (since fpsetsticky calls _putsw, which modifies the control word of the
- 387 unit). Instead, we need to modify only the flags in the SSE unit. */
+/* On these Solaris platforms, fpsetsticky cannot be used here, because it may
+ generate traps (since fpsetsticky calls _putsw, which modifies the control
+ word of the 387 unit). Instead, we need to modify only the flags in the SSE
+ unit. */
-/* Accessors for the mxcsr register. Fortunately, the Solaris cc supports a
- poor form of 'asm'. */
+/* Accessors for the mxcsr register. Fortunately, the SunPRO C compiler
+ supports a poor form of 'asm'. */
static void
getssecw (unsigned int *mxcsr_p)
@@ -477,6 +478,26 @@ setssecw (unsigned int const *mxcsr_p)
# endif
}
+# if __GLIBC__ >= 2
+/* Clears flags in the 387 unit. */
+static void
+mask387cw (unsigned short mask)
+{
+# if defined __x86_64__ || defined _M_X64
+ asm ("fnstenv -32(%rsp)");
+ asm ("andw %di,-28(%rsp)");
+ asm ("fldenv -32(%rsp)");
+# else
+ /* The compiler generates a stack frame. Therefore the first argument is in
+ 8(%ebp), not in 4(%esp). */
+ asm ("movl 8(%ebp),%eax");
+ asm ("fnstenv -32(%esp)");
+ asm ("andw %ax,-28(%esp)");
+ asm ("fldenv -32(%esp)");
+# endif
+}
+# endif
+
int
fesetexceptflag (fexcept_t const *saved_flags, int exceptions)
{
@@ -490,6 +511,12 @@ fesetexceptflag (fexcept_t const *saved_flags, int exceptions)
if (mxcsr != orig_mxcsr)
setssecw (&mxcsr);
+# if __GLIBC__ >= 2
+ /* Modify the flags in the 387 unit, but only by clearing bits, not by
+ setting bits. */
+ mask387cw (~ (exceptions & ~desired_flags));
+# endif
+
return 0;
}
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2024-03-29 2:54 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-29 2:53 fenv-exceptions-state-c99: Fix test failures with Oracle cc 12.6 Bruno Haible
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).