@@ -23,6 +23,17 @@
#include <fenv_libc.h>
#include <fpu_control.h>
+#ifdef _ARCH_PWR8
+/* There is no performance advantage to non-stop mode. */
+/* The odd syntax here is to innocuously reference the given variables
+ to prevent warnings about unused variables. */
+#define __TEST_AND_BEGIN_NON_STOP(old, new) do {} while ((old) * (new) * 0 != 0)
+#define __TEST_AND_END_NON_STOP(old, new) do {} while ((old) * (new) * 0 != 0)
+#else
+#define __TEST_AND_BEGIN_NON_STOP __TEST_AND_ENTER_NON_STOP
+#define __TEST_AND_END_NON_STOP __TEST_AND_EXIT_NON_STOP
+#endif
+
static __always_inline void
libc_feholdexcept_setround_ppc (fenv_t *envp, int r)
{
@@ -30,7 +41,7 @@ libc_feholdexcept_setround_ppc (fenv_t *envp, int r)
old.fenv = *envp = fegetenv_register ();
- __TEST_AND_ENTER_NON_STOP (old.l, 0ULL);
+ __TEST_AND_BEGIN_NON_STOP (old.l, 0ULL);
/* Clear everything and set the rounding mode. */
new.l = r;
@@ -49,8 +60,8 @@ __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask,
/* Merge bits while masking unwanted bits from new and old env. */
new.l = (old.l & old_mask) | (new.l & new_mask);
- __TEST_AND_EXIT_NON_STOP (old.l, new.l);
- __TEST_AND_ENTER_NON_STOP (old.l, new.l);
+ __TEST_AND_END_NON_STOP (old.l, new.l);
+ __TEST_AND_BEGIN_NON_STOP (old.l, new.l);
/* If requesting to keep status, replace control, and merge exceptions,
and exceptions haven't changed, we can just set new control instead
@@ -141,7 +152,7 @@ libc_feholdsetround_noex_ppc_ctx (struct rm_ctx *ctx, int r)
ctx->env = old.fenv;
if (__glibc_unlikely (new.l != old.l))
{
- __TEST_AND_ENTER_NON_STOP (old.l, 0ULL);
+ __TEST_AND_BEGIN_NON_STOP (old.l, 0ULL);
fesetenv_control (new.fenv);
ctx->updated_status = true;
}
From: "Paul A. Clarke" <pc@us.ibm.com> Since at least POWER8, there is no performance advantage to entering "Ignore Exceptions Mode", and doing so conditionally requires - the conditional logic, and - a system call. Make it a no-op for uses within glibc. --- v2: This was a new patch (#2) in the series "Various FPSCR-related changes". v3: I was a bit uncomfortable with the approach used in v1/v2, which had side effects, although these were expected to be innocuous. I reimplemented this patch to be implemented only for uses that are internal to glibc. These are all cases where the mode is to be changed only temporarily. So, the state will be consistent after the code block is complete -- no unexpected side effects. v4: This is the version committed. New macro names at suggestion by Paul Murphy. I chose "__TEST_AND_{BEGIN,END}_NON_STOP" (instead of appending "P7") because it's not that the decision to independently enter or exit non-stop mode is architecture-specific, but that the uses of the functions including the new macros is to bracket a block of code in which we may care about transitioning temporarily to non-stop mode. In other words, it's not as much a state change as a push/pop (BEGIN/END). And, it just happens to be on PWR8 and above we don't care. sysdeps/powerpc/fpu/fenv_private.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)