| commit fec2bd2c2d31bc731cf61623e150d047746954bd |
| Author: Paul A. Clarke <pc@us.ibm.com> |
| Date: Tue Aug 6 00:13:45 2019 -0400 |
| |
| [powerpc] fesetenv: optimize FPSCR access |
| |
| fesetenv() reads the current value of the Floating-Point Status and Control |
| Register (FPSCR) to determine the difference between the current state of |
| exception enables and the newly requested state. All of these bits are also |
| returned by the lighter weight 'mffsl' instruction used by fegetenv_status(). |
| Use that instead. |
| |
| Also, remove a local macro _FPU_MASK_ALL in favor of a common macro, |
| FPU_ENABLES_MASK from fenv_libc.h. |
| |
| Finally, use a local variable ('new') in favor of a pointer dereference |
| ('*envp'). |
| |
| diff --git a/sysdeps/powerpc/fpu/fesetenv.c b/sysdeps/powerpc/fpu/fesetenv.c |
| index ad9fda15b12f15e3..ac927c8f3ada40b4 100644 |
| |
| |
| @@ -19,8 +19,6 @@ |
| #include <fenv_libc.h> |
| #include <fpu_control.h> |
| |
| -#define _FPU_MASK_ALL (_FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_XM | _FPU_MASK_IM) |
| - |
| int |
| __fesetenv (const fenv_t *envp) |
| { |
| @@ -28,25 +26,23 @@ __fesetenv (const fenv_t *envp) |
| |
| /* get the currently set exceptions. */ |
| new.fenv = *envp; |
| - old.fenv = fegetenv_register (); |
| - if (old.l == new.l) |
| - return 0; |
| + old.fenv = fegetenv_status (); |
| |
| /* 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 ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0) |
| + if ((old.l & FPSCR_ENABLES_MASK) == 0 && (new.l & FPSCR_ENABLES_MASK) != 0) |
| (void) __fe_nomask_env_priv (); |
| |
| /* If the old env had any enabled exceptions and the new env has no enabled |
| exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the |
| FPU to run faster because it always takes the default action and can not |
| generate SIGFPE. */ |
| - if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0) |
| + if ((old.l & FPSCR_ENABLES_MASK) != 0 && (new.l & FPSCR_ENABLES_MASK) == 0) |
| (void)__fe_mask_env (); |
| |
| - fesetenv_register (*envp); |
| + fesetenv_register (new.fenv); |
| |
| /* Success. */ |
| return 0; |