diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | sysdeps/arm/fclrexcpt.c | 10 | ||||
-rw-r--r-- | sysdeps/arm/fedisblxcpt.c | 4 | ||||
-rw-r--r-- | sysdeps/arm/feenablxcpt.c | 14 | ||||
-rw-r--r-- | sysdeps/arm/fsetexcptflg.c | 13 | ||||
-rw-r--r-- | sysdeps/arm/setfpucw.c | 11 |
6 files changed, 38 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog index 28bc633e37..0b0f61affa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2014-06-24 Wilco <wdijkstr@arm.com> + * sysdeps/arm/fclrexcpt.c (feclearexcept): + Optimize to avoid unnecessary FPSCR writes. + * sysdeps/arm/fedisblxcpt.c (fedisableexcept): Likewise. + * sysdeps/arm/feenablxcpt.c (feenableexcept): Likewise. + * sysdeps/arm/fsetexcptflg.c (fesetexceptflag): Likewise. + * sysdeps/arm/setfpucw.c (__setfpucw): Likewise. + +2014-06-24 Wilco <wdijkstr@arm.com> + * sysdeps/arm/fegetround.c (fegetround): Call get_rounding_mode. * sysdeps/arm/feholdexcpt.c (feholdexcept): Call libc_feholdexcept_vfp. * sysdeps/arm/fesetround.c (fesetround): Call libc_fesetround_vfp. diff --git a/sysdeps/arm/fclrexcpt.c b/sysdeps/arm/fclrexcpt.c index cbf61a6f4a..31420ed3c7 100644 --- a/sysdeps/arm/fclrexcpt.c +++ b/sysdeps/arm/fclrexcpt.c @@ -24,7 +24,7 @@ int feclearexcept (int excepts) { - fpu_control_t fpscr; + fpu_control_t fpscr, new_fpscr; /* Fail if a VFP unit isn't present unless nothing needs to be done. */ if (!ARM_HAVE_VFP) @@ -32,11 +32,11 @@ feclearexcept (int excepts) _FPU_GETCW (fpscr); excepts &= FE_ALL_EXCEPT; + new_fpscr = fpscr & ~excepts; - /* Clear the relevant bits. */ - fpscr = (fpscr & ~FE_ALL_EXCEPT) | (fpscr & FE_ALL_EXCEPT & ~excepts); - - _FPU_SETCW (fpscr); + /* Write new exception flags if changed. */ + if (new_fpscr != fpscr) + _FPU_SETCW (new_fpscr); return 0; } diff --git a/sysdeps/arm/fedisblxcpt.c b/sysdeps/arm/fedisblxcpt.c index f2956cd32a..d5e0f0031a 100644 --- a/sysdeps/arm/fedisblxcpt.c +++ b/sysdeps/arm/fedisblxcpt.c @@ -35,7 +35,9 @@ fedisableexcept (int excepts) excepts &= FE_ALL_EXCEPT; new_fpscr = fpscr & ~(excepts << FE_EXCEPT_SHIFT); - _FPU_SETCW (new_fpscr); + /* Write new exceptions if changed. */ + if (new_fpscr != fpscr) + _FPU_SETCW (new_fpscr); return (fpscr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; } diff --git a/sysdeps/arm/feenablxcpt.c b/sysdeps/arm/feenablxcpt.c index afd8943638..f54ca6edf4 100644 --- a/sysdeps/arm/feenablxcpt.c +++ b/sysdeps/arm/feenablxcpt.c @@ -25,7 +25,7 @@ int feenableexcept (int excepts) { - fpu_control_t fpscr, new_fpscr; + fpu_control_t fpscr, new_fpscr, updated_fpscr; /* Fail if a VFP unit isn't present. */ if (!ARM_HAVE_VFP) @@ -35,15 +35,15 @@ feenableexcept (int excepts) excepts &= FE_ALL_EXCEPT; new_fpscr = fpscr | (excepts << FE_EXCEPT_SHIFT); - _FPU_SETCW (new_fpscr); - - if (excepts != 0) + if (new_fpscr != fpscr) { + _FPU_SETCW (new_fpscr); + /* Not all VFP architectures support trapping exceptions, so test whether the relevant bits were set and fail if not. */ - _FPU_GETCW (new_fpscr); - if ((new_fpscr & (excepts << FE_EXCEPT_SHIFT)) - != (excepts << FE_EXCEPT_SHIFT)) + _FPU_GETCW (updated_fpscr); + + if (new_fpscr & ~updated_fpscr) return -1; } diff --git a/sysdeps/arm/fsetexcptflg.c b/sysdeps/arm/fsetexcptflg.c index 1a610ff912..28810d3ec8 100644 --- a/sysdeps/arm/fsetexcptflg.c +++ b/sysdeps/arm/fsetexcptflg.c @@ -25,19 +25,22 @@ int fesetexceptflag (const fexcept_t *flagp, int excepts) { - fpu_control_t fpscr; + fpu_control_t fpscr, new_fpscr; /* Fail if a VFP unit isn't present unless nothing needs to be done. */ if (!ARM_HAVE_VFP) return (excepts != 0); _FPU_GETCW (fpscr); + excepts &= FE_ALL_EXCEPT; /* Set the desired exception mask. */ - fpscr &= ~(excepts & FE_ALL_EXCEPT); - fpscr |= (*flagp & excepts & FE_ALL_EXCEPT); + new_fpscr = fpscr & ~excepts; + new_fpscr |= *flagp & excepts; + + /* Write new exception flags if changed. */ + if (new_fpscr != fpscr) + _FPU_SETCW (new_fpscr); - /* Save state back to the FPU. */ - _FPU_SETCW (fpscr); return 0; } diff --git a/sysdeps/arm/setfpucw.c b/sysdeps/arm/setfpucw.c index 7416377f9e..259b020f81 100644 --- a/sysdeps/arm/setfpucw.c +++ b/sysdeps/arm/setfpucw.c @@ -24,19 +24,20 @@ void __setfpucw (fpu_control_t set) { - fpu_control_t fpscr; + fpu_control_t fpscr, new_fpscr; /* Do nothing if a VFP unit isn't present. */ if (!ARM_HAVE_VFP) return; - /* Fetch the current control word. */ _FPU_GETCW (fpscr); /* Preserve the reserved bits, and set the rest as the user specified (or the default, if the user gave zero). */ - fpscr &= _FPU_RESERVED; - fpscr |= set & ~_FPU_RESERVED; + new_fpscr = fpscr & _FPU_RESERVED; + new_fpscr |= set & ~_FPU_RESERVED; - _FPU_SETCW (fpscr); + /* Write FPSCR if changed. */ + if (new_fpscr != fpscr) + _FPU_SETCW (fpscr); } |