diff options
author | Wilco <wdijkstr@arm.com> | 2014-06-24 15:05:23 +0000 |
---|---|---|
committer | Wilco <wdijkstr@arm.com> | 2014-06-24 15:05:23 +0000 |
commit | b8c005732e1f799ffcd522d83aa2a826b6248752 (patch) | |
tree | 4dfa8d720560e4eb211d8026bdf3509b484efca2 /sysdeps/arm | |
parent | b5570d92d6bb6ba9c25ac6ed77ba170dd7f4acd3 (diff) | |
download | glibc-b8c005732e1f799ffcd522d83aa2a826b6248752.tar glibc-b8c005732e1f799ffcd522d83aa2a826b6248752.tar.gz glibc-b8c005732e1f799ffcd522d83aa2a826b6248752.tar.bz2 glibc-b8c005732e1f799ffcd522d83aa2a826b6248752.zip |
Optimize fesetenv
Improve fesetenv to use an optimized implementation similar to
feupdateenv.
2014-06-24 Wilco <wdijkstr@arm.com>
* sysdeps/arm/fesetenv.c (fesetenv): Optimize implementation.
Diffstat (limited to 'sysdeps/arm')
-rw-r--r-- | sysdeps/arm/fesetenv.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/sysdeps/arm/fesetenv.c b/sysdeps/arm/fesetenv.c index b2ed1d3911..ac47ae2d49 100644 --- a/sysdeps/arm/fesetenv.c +++ b/sysdeps/arm/fesetenv.c @@ -17,14 +17,13 @@ <http://www.gnu.org/licenses/>. */ #include <fenv.h> -#include <fpu_control.h> #include <arm-features.h> int fesetenv (const fenv_t *envp) { - fpu_control_t fpscr; + fpu_control_t fpscr, new_fpscr, updated_fpscr; /* Fail if a VFP unit isn't present. */ if (!ARM_HAVE_VFP) @@ -32,25 +31,31 @@ fesetenv (const fenv_t *envp) _FPU_GETCW (fpscr); - /* Preserve the reserved FPSCR flags. */ - fpscr &= _FPU_RESERVED; + if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV)) + { + /* The new FPSCR is valid, so don't merge the reserved flags. */ + new_fpscr = envp->__cw; - if (envp == FE_DFL_ENV) - fpscr |= _FPU_DEFAULT; - else if (envp == FE_NOMASK_ENV) - fpscr |= _FPU_IEEE; - else - fpscr |= envp->__cw & ~_FPU_RESERVED; + /* Write new FPSCR if different (ignoring NZCV flags). */ + if (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0) + _FPU_SETCW (new_fpscr); - _FPU_SETCW (fpscr); + return 0; + } - if (envp == FE_NOMASK_ENV) + /* Preserve the reserved FPSCR flags. */ + new_fpscr = fpscr & _FPU_RESERVED; + new_fpscr |= (envp == FE_DFL_ENV) ? _FPU_DEFAULT : _FPU_IEEE; + + if (((new_fpscr ^ fpscr) & ~_FPU_MASK_NZCV) != 0) { + _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 (fpscr); - if ((fpscr & _FPU_IEEE) != _FPU_IEEE) - return 1; + _FPU_GETCW (updated_fpscr); + + return new_fpscr & ~updated_fpscr; } return 0; |