diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/fedisblxcpt.c | 14 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/feenablxcpt.c | 15 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/fenv_libc.h | 10 | ||||
-rw-r--r-- | sysdeps/powerpc/fpu/fesetmode.c | 15 |
5 files changed, 41 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog index c2d70717ec..1609d16e00 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2019-08-28 Paul A. Clarke <pc@us.ibm.com> + * sysdeps/powerpc/fpu/fenv_libc.h (fesetenv_mode): New. + (FPSCR_FPRF_MASK): New. (FPSCR_STATUS_MASK): New. + * sysdeps/powerpc/fpu/feenablxcpt.c (feenableexcept): Use lighter- + weight access to FPSCR; remove unnecessary second FPSCR read and + validate. + * sysdeps/powerpc/fpu/fedisblxcpt.c (fedisableexcept): Likewise. + * sysdeps/powerpc/fpu/fesetmode.c (fesetmode): Use lighter-weight + access to FPSCR; Use macros in fenv_libc.h in favor of local. + +2019-08-28 Paul A. Clarke <pc@us.ibm.com> + * sysdeps/powerpc/fpu/fenv_libc.h: Define FPSCR bitmasks. (fenv_reg_to_exceptions): Replace bitwise operations with mask-shift. (fenv_exceptions_to_reg): New. diff --git a/sysdeps/powerpc/fpu/fedisblxcpt.c b/sysdeps/powerpc/fpu/fedisblxcpt.c index 5cc87992f0..a2b7addf20 100644 --- a/sysdeps/powerpc/fpu/fedisblxcpt.c +++ b/sysdeps/powerpc/fpu/fedisblxcpt.c @@ -26,23 +26,25 @@ fedisableexcept (int excepts) int result, new; /* Get current exception mask to return. */ - fe.fenv = curr.fenv = fegetenv_register (); + fe.fenv = curr.fenv = fegetenv_status (); result = fenv_reg_to_exceptions (fe.l); if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID) excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID; + new = fenv_exceptions_to_reg (excepts); + + if (fenv_reg_to_exceptions (new) != excepts) + return -1; + /* Sets the new exception mask. */ - fe.l &= ~ fenv_exceptions_to_reg (excepts); + fe.l &= ~new; if (fe.l != curr.l) - fesetenv_register (fe.fenv); + fesetenv_mode (fe.fenv); - new = __fegetexcept (); if (new == 0 && result != 0) (void)__fe_mask_env (); - if ((new & excepts) != 0) - result = -1; return result; } diff --git a/sysdeps/powerpc/fpu/feenablxcpt.c b/sysdeps/powerpc/fpu/feenablxcpt.c index 3b64398ff1..c06a7fdb72 100644 --- a/sysdeps/powerpc/fpu/feenablxcpt.c +++ b/sysdeps/powerpc/fpu/feenablxcpt.c @@ -26,24 +26,25 @@ feenableexcept (int excepts) int result, new; /* Get current exception mask to return. */ - fe.fenv = curr.fenv = fegetenv_register (); + fe.fenv = curr.fenv = fegetenv_status (); result = fenv_reg_to_exceptions (fe.l); if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID) excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID; + new = fenv_exceptions_to_reg (excepts); + + if (fenv_reg_to_exceptions (new) != excepts) + return -1; + /* Sets the new exception mask. */ - fe.l |= fenv_exceptions_to_reg (excepts); + fe.l |= new; if (fe.l != curr.l) - fesetenv_register (fe.fenv); + fesetenv_mode (fe.fenv); - new = __fegetexcept (); if (new != 0 && result == 0) (void) __fe_nomask_env_priv (); - if ((new & excepts) != excepts) - result = -1; - return result; } diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h index 9956136a13..4144d413a2 100644 --- a/sysdeps/powerpc/fpu/fenv_libc.h +++ b/sysdeps/powerpc/fpu/fenv_libc.h @@ -70,6 +70,11 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden; __builtin_mtfsf (0xff, d); \ } while(0) +/* Set the last 2 nibbles of the FPSCR, which contain the + exception enables and the rounding mode. + 'fegetenv_status' retrieves these bits by reading the FPSCR. */ +#define fesetenv_mode(env) __builtin_mtfsf (0b00000011, (env)); + /* This very handy macro: - Sets the rounding mode to 'round to nearest'; - Sets the processor into IEEE mode; and @@ -208,8 +213,11 @@ enum { (FPSCR_VE_MASK|FPSCR_OE_MASK|FPSCR_UE_MASK|FPSCR_ZE_MASK|FPSCR_XE_MASK) #define FPSCR_BASIC_EXCEPTIONS_MASK \ (FPSCR_VX_MASK|FPSCR_OX_MASK|FPSCR_UX_MASK|FPSCR_ZX_MASK|FPSCR_XX_MASK) - +#define FPSCR_FPRF_MASK \ + (FPSCR_FPRF_C_MASK|FPSCR_FPRF_FL_MASK|FPSCR_FPRF_FG_MASK| \ + FPSCR_FPRF_FE_MASK|FPSCR_FPRF_FU_MASK) #define FPSCR_CONTROL_MASK (FPSCR_ENABLES_MASK|FPSCR_NI_MASK|FPSCR_RN_MASK) +#define FPSCR_STATUS_MASK (FPSCR_FR_MASK|FPSCR_FI_MASK|FPSCR_FPRF_MASK) /* The bits in the FENV(1) ABI for exceptions correspond one-to-one with bits in the FPSCR, albeit shifted to different but corresponding locations. diff --git a/sysdeps/powerpc/fpu/fesetmode.c b/sysdeps/powerpc/fpu/fesetmode.c index 4f4f71a3ba..e92559b6d5 100644 --- a/sysdeps/powerpc/fpu/fesetmode.c +++ b/sysdeps/powerpc/fpu/fesetmode.c @@ -19,11 +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) - -#define FPU_STATUS 0xbffff700ULL - int fesetmode (const femode_t *modep) { @@ -32,18 +27,18 @@ fesetmode (const femode_t *modep) /* Logic regarding enabled exceptions as in fesetenv. */ new.fenv = *modep; - old.fenv = fegetenv_register (); - new.l = (new.l & ~FPU_STATUS) | (old.l & FPU_STATUS); + old.fenv = fegetenv_status (); + new.l = (new.l & ~FPSCR_STATUS_MASK) | (old.l & FPSCR_STATUS_MASK); if (old.l == new.l) return 0; - 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 ((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 (new.fenv); + fesetenv_mode (new.fenv); return 0; } |