about summary refs log tree commit diff
path: root/sysdeps/powerpc/fpu/fenv_private.h
diff options
context:
space:
mode:
authorPaul A. Clarke <pc@us.ibm.com>2019-09-19 08:35:16 -0500
committerPaul A. Clarke <pc@us.ibm.com>2019-09-19 13:02:30 -0500
commitf1c56cdff09f650ad721fae026eb6a3651631f3d (patch)
treeb06f5014ae1899707cfb059eb9fba3da79877e9e /sysdeps/powerpc/fpu/fenv_private.h
parent64fab3633aecc8eadc1338aa8953f8b2f37e3ebf (diff)
downloadglibc-f1c56cdff09f650ad721fae026eb6a3651631f3d.tar.gz
glibc-f1c56cdff09f650ad721fae026eb6a3651631f3d.tar.xz
glibc-f1c56cdff09f650ad721fae026eb6a3651631f3d.zip
[powerpc] SET_RESTORE_ROUND optimizations and bug fix
SET_RESTORE_ROUND brackets a block of code, temporarily setting and
restoring the rounding mode and letting everything else, including
exceptions generated within the block, pass through.

On powerpc, the current code clears the exception enables, which will hide
exceptions generated within the block.  This issue was introduced by me
in commit e905212627350d54b58426214b5a54ddc852b0c9.

Fix this by not clearing exception enable bits in the prologue.

Also, since we are no longer changing the enable bits in either the
prologue or the epilogue, there is no need to test for entering/exiting
non-stop mode.

Also, optimize the prologue get/save/set rounding mode operations for
POWER9 and later by using 'mffscrn' when possible.

Suggested-by: Paul E. Murphy <murphyp@linux.ibm.com>
Reviewed-by: Paul E. Murphy <murphyp@linux.ibm.com>
Fixes: e905212627350d54b58426214b5a54ddc852b0c9

2019-09-19  Paul A. Clarke  <pc@us.ibm.com>

	* sysdeps/powerpc/fpu/fenv_libc.h (fegetenv_and_set_rn): New.
	(__fe_mffscrn): New.
	* sysdeps/powerpc/fpu/fenv_private.h (libc_feholdsetround_ppc_ctx):
	Do not clear enable bits, remove obsolete code, use
	fegetenv_and_set_rn.
	(libc_feresetround_ppc): Remove obsolete code, use
	fegetenv_and_set_rn.
Diffstat (limited to 'sysdeps/powerpc/fpu/fenv_private.h')
-rw-r--r--sysdeps/powerpc/fpu/fenv_private.h29
1 files changed, 4 insertions, 25 deletions
diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h
index 5f1bcab743..92a3e92787 100644
--- a/sysdeps/powerpc/fpu/fenv_private.h
+++ b/sysdeps/powerpc/fpu/fenv_private.h
@@ -133,16 +133,7 @@ static __always_inline void
 libc_feresetround_ppc (fenv_t *envp)
 {
   fenv_union_t new = { .fenv = *envp };
-
-  /* If the old env has no enabled exceptions and the new env has any enabled
-     exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits.  This will put the
-     hardware into "precise mode" and may cause the FPU to run slower on some
-     hardware.  */
-  if ((new.l & _FPU_ALL_TRAPS) != 0)
-    (void) __fe_nomask_env_priv ();
-
-  /* Atomically enable and raise (if appropriate) exceptions set in `new'.  */
-  fesetenv_mode (new.fenv);
+  fegetenv_and_set_rn (new.l & FPSCR_RN_MASK);
 }
 
 static __always_inline int
@@ -184,22 +175,10 @@ libc_feupdateenv_ppc (fenv_t *e)
 static __always_inline void
 libc_feholdsetround_ppc_ctx (struct rm_ctx *ctx, int r)
 {
-  fenv_union_t old, new;
+  fenv_union_t old;
 
-  old.fenv = fegetenv_status ();
-
-  new.l = (old.l & ~(FPSCR_ENABLES_MASK|FPSCR_RN_MASK)) | r;
-
-  ctx->env = old.fenv;
-  if (__glibc_unlikely (new.l != old.l))
-    {
-      if ((old.l & _FPU_ALL_TRAPS) != 0)
-	(void) __fe_mask_env ();
-      fesetenv_mode (new.fenv);
-      ctx->updated_status = true;
-    }
-  else
-    ctx->updated_status = false;
+  ctx->env = old.fenv = fegetenv_and_set_rn (r);
+  ctx->updated_status = (r != (old.l & FPSCR_RN_MASK));
 }
 
 static __always_inline void