diff options
author | Paul A. Clarke <pc@us.ibm.com> | 2019-09-19 11:18:33 -0500 |
---|---|---|
committer | Paul A. Clarke <pc@us.ibm.com> | 2019-09-27 08:50:48 -0500 |
commit | 7413c188c77adb26a15cf0e98e0a991d09d73c65 (patch) | |
tree | 5c36d2ff3dcff1e0aab3243b81b1176c18805d87 /sysdeps/powerpc/fpu/fenv_private.h | |
parent | e3d85df50b083c9ba68a40f5d45b201cbec4e68b (diff) | |
download | glibc-7413c188c77adb26a15cf0e98e0a991d09d73c65.tar.gz glibc-7413c188c77adb26a15cf0e98e0a991d09d73c65.tar.xz glibc-7413c188c77adb26a15cf0e98e0a991d09d73c65.zip |
[powerpc] libc_feupdateenv_test: optimize FPSCR access
ROUND_TO_ODD and a couple of other places use libc_feupdateenv_test to restore the rounding mode and exception enables, preserve exception flags, and test whether given exception(s) were generated. If the exception flags haven't changed, then it is sufficient and a bit more efficient to just restore the rounding mode and enables, rather than writing the full Floating-Point Status and Control Register (FPSCR). Reviewed-by: Paul E. Murphy <murphyp@linux.ibm.com>
Diffstat (limited to 'sysdeps/powerpc/fpu/fenv_private.h')
-rw-r--r-- | sysdeps/powerpc/fpu/fenv_private.h | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/sysdeps/powerpc/fpu/fenv_private.h b/sysdeps/powerpc/fpu/fenv_private.h index 30cbf301b7..94960262dd 100644 --- a/sysdeps/powerpc/fpu/fenv_private.h +++ b/sysdeps/powerpc/fpu/fenv_private.h @@ -52,8 +52,20 @@ __libc_femergeenv_ppc (const fenv_t *envp, unsigned long long old_mask, __TEST_AND_EXIT_NON_STOP (old.l, new.l); __TEST_AND_ENTER_NON_STOP (old.l, new.l); - /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ - fesetenv_register (new.fenv); + /* If requesting to keep status, replace control, and merge exceptions, + and exceptions haven't changed, we can just set new control instead + of the whole FPSCR. */ + if ((old_mask & (FPSCR_CONTROL_MASK|FPSCR_STATUS_MASK|FPSCR_EXCEPTIONS_MASK)) + == (FPSCR_STATUS_MASK|FPSCR_EXCEPTIONS_MASK) && + (new_mask & (FPSCR_CONTROL_MASK|FPSCR_STATUS_MASK|FPSCR_EXCEPTIONS_MASK)) + == (FPSCR_CONTROL_MASK|FPSCR_EXCEPTIONS_MASK) && + (old.l & FPSCR_EXCEPTIONS_MASK) == (new.l & FPSCR_EXCEPTIONS_MASK)) + { + fesetenv_mode (new.fenv); + } + else + /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ + fesetenv_register (new.fenv); return old.l; } |