From b8c005732e1f799ffcd522d83aa2a826b6248752 Mon Sep 17 00:00:00 2001 From: Wilco Date: Tue, 24 Jun 2014 15:05:23 +0000 Subject: Optimize fesetenv Improve fesetenv to use an optimized implementation similar to feupdateenv. 2014-06-24 Wilco * sysdeps/arm/fesetenv.c (fesetenv): Optimize implementation. --- ChangeLog | 4 ++++ sysdeps/arm/fesetenv.c | 35 ++++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 67759941ca..b855439303 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2014-06-24 Wilco + + * sysdeps/arm/fesetenv.c (fesetenv): Optimize implementation. + 2014-06-24 Wilco * sysdeps/arm/fpu_control.h (_FPU_MASK_RM): Define. 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 @@ . */ #include -#include #include 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; -- cgit v1.2.3