aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--sysdeps/arm/fclrexcpt.c10
-rw-r--r--sysdeps/arm/fedisblxcpt.c4
-rw-r--r--sysdeps/arm/feenablxcpt.c10
-rw-r--r--sysdeps/arm/fegetround.c14
-rw-r--r--sysdeps/arm/feholdexcpt.c16
-rw-r--r--sysdeps/arm/fesetenv.c42
-rw-r--r--sysdeps/arm/fesetround.c10
-rw-r--r--sysdeps/arm/feupdateenv.c24
-rw-r--r--sysdeps/arm/fgetexcptflg.c9
-rw-r--r--sysdeps/arm/fsetexcptflg.c13
-rw-r--r--sysdeps/arm/ftestexcept.c11
-rw-r--r--sysdeps/arm/setfpucw.c11
13 files changed, 99 insertions, 93 deletions
diff --git a/ChangeLog b/ChangeLog
index c606b0d5cd..0a9a26584d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1013,24 +1013,6 @@
2014-05-14 Wilco <wdijkstr@arm.com>
- * sysdeps/arm/fclrexcpt.c: Optimize to avoid unnecessary FPSCR writes.
- * sysdeps/arm/fedisblxcpt.c: Likewise.
- * sysdeps/arm/feenablxcpt.c: Likewise.
- * sysdeps/arm/fegetround.c: Call (get_rounding_mode).
- * sysdeps/arm/feholdexcpt.c: Call optimized (libc_feholdexcept_vfp).
- * sysdeps/arm/fesetenv.c: Special case FE_DFL_ENV and FE_NOMASK_ENV.
- Call optimized (libc_fesetenv_vfp).
- * sysdeps/arm/fesetround.c: Call optimized (libc_fesetround_vfp).
- * sysdeps/arm/feupdateenv.c: Special case FE_DFL_ENV and FE_NOMASK_ENV.
- Call optimized (libc_feupdateenv_vfp).
- * sysdeps/arm/fgetexcptflg.c: Call optimized (libc_fetestexcept_vfp).
- * sysdeps/arm/fsetexcptflg.c: Optimize to avoid unnecessary FPSCR
- writes.
- * sysdeps/arm/ftestexcept.c: Call optimized (libc_fetestexcept_vfp).
- * sysdeps/arm/setfpucw.c: Optimize to avoid unnecessary FPSCR writes.
-
-2014-05-14 Wilco <wdijkstr@arm.com>
-
* sysdeps/arm/fclrexcpt.c: Cleanup.
* sysdeps/arm/fedisblxcpt.c: Cleanup.
* sysdeps/arm/feenablxcpt.c: Cleanup.
diff --git a/sysdeps/arm/fclrexcpt.c b/sysdeps/arm/fclrexcpt.c
index 31420ed3c7..cbf61a6f4a 100644
--- a/sysdeps/arm/fclrexcpt.c
+++ b/sysdeps/arm/fclrexcpt.c
@@ -24,7 +24,7 @@
int
feclearexcept (int excepts)
{
- fpu_control_t fpscr, new_fpscr;
+ fpu_control_t 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;
- /* Write new exception flags if changed. */
- if (new_fpscr != fpscr)
- _FPU_SETCW (new_fpscr);
+ /* Clear the relevant bits. */
+ fpscr = (fpscr & ~FE_ALL_EXCEPT) | (fpscr & FE_ALL_EXCEPT & ~excepts);
+
+ _FPU_SETCW (fpscr);
return 0;
}
diff --git a/sysdeps/arm/fedisblxcpt.c b/sysdeps/arm/fedisblxcpt.c
index d5e0f0031a..f2956cd32a 100644
--- a/sysdeps/arm/fedisblxcpt.c
+++ b/sysdeps/arm/fedisblxcpt.c
@@ -35,9 +35,7 @@ fedisableexcept (int excepts)
excepts &= FE_ALL_EXCEPT;
new_fpscr = fpscr & ~(excepts << FE_EXCEPT_SHIFT);
- /* Write new exceptions if changed. */
- if (new_fpscr != fpscr)
- _FPU_SETCW (new_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 e649b2f1e1..afd8943638 100644
--- a/sysdeps/arm/feenablxcpt.c
+++ b/sysdeps/arm/feenablxcpt.c
@@ -35,15 +35,15 @@ feenableexcept (int excepts)
excepts &= FE_ALL_EXCEPT;
new_fpscr = fpscr | (excepts << FE_EXCEPT_SHIFT);
- if (new_fpscr != fpscr)
- {
- _FPU_SETCW (new_fpscr);
+ _FPU_SETCW (new_fpscr);
+ if (excepts != 0)
+ {
/* 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 >> FE_EXCEPT_SHIFT) & excepts) != excepts)
+ if ((new_fpscr & (excepts << FE_EXCEPT_SHIFT))
+ != (excepts << FE_EXCEPT_SHIFT))
return -1;
}
diff --git a/sysdeps/arm/fegetround.c b/sysdeps/arm/fegetround.c
index fbad0b3078..1c9c151a16 100644
--- a/sysdeps/arm/fegetround.c
+++ b/sysdeps/arm/fegetround.c
@@ -16,12 +16,22 @@
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#include <get-rounding-mode.h>
+#include <fenv.h>
+#include <fpu_control.h>
+#include <arm-features.h>
int
fegetround (void)
{
- return get_rounding_mode ();
+ fpu_control_t fpscr;
+
+ /* FE_TONEAREST is the only supported rounding mode
+ if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return FE_TONEAREST;
+
+ _FPU_GETCW (fpscr);
+ return fpscr & FE_TOWARDZERO;
}
libm_hidden_def (fegetround)
diff --git a/sysdeps/arm/feholdexcpt.c b/sysdeps/arm/feholdexcpt.c
index 2d79e0c46d..258ba6637f 100644
--- a/sysdeps/arm/feholdexcpt.c
+++ b/sysdeps/arm/feholdexcpt.c
@@ -16,18 +16,30 @@
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#include <fenv_private.h>
+#include <fenv.h>
+#include <fpu_control.h>
#include <arm-features.h>
int
feholdexcept (fenv_t *envp)
{
+ fpu_control_t fpscr;
+
/* Fail if a VFP unit isn't present. */
if (!ARM_HAVE_VFP)
return 1;
- libc_feholdexcept_vfp (envp);
+ _FPU_GETCW (fpscr);
+ envp->__cw = fpscr;
+
+ /* Now set all exceptions to non-stop. */
+ fpscr &= ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT);
+
+ /* And clear all exception flags. */
+ fpscr &= ~FE_ALL_EXCEPT;
+
+ _FPU_SETCW (fpscr);
return 0;
}
diff --git a/sysdeps/arm/fesetenv.c b/sysdeps/arm/fesetenv.c
index 9e2aa81f9b..62031d596d 100644
--- a/sysdeps/arm/fesetenv.c
+++ b/sysdeps/arm/fesetenv.c
@@ -16,43 +16,43 @@
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#include <fenv_private.h>
+#include <fenv.h>
+#include <fpu_control.h>
#include <arm-features.h>
int
fesetenv (const fenv_t *envp)
{
+ fpu_control_t fpscr;
+
/* Fail if a VFP unit isn't present. */
if (!ARM_HAVE_VFP)
return 1;
- if ((envp == FE_DFL_ENV) || (envp == FE_NOMASK_ENV))
- {
- fpu_control_t fpscr, new_fpscr;
-
- _FPU_GETCW (fpscr);
+ _FPU_GETCW (fpscr);
- /* Preserve the reserved FPSCR flags. */
- new_fpscr = fpscr & _FPU_RESERVED;
+ /* Preserve the reserved FPSCR flags. */
+ fpscr &= _FPU_RESERVED;
- if (envp == FE_DFL_ENV)
- _FPU_SETCW (new_fpscr | _FPU_DEFAULT);
- else
- {
- _FPU_SETCW (new_fpscr | _FPU_IEEE);
- /* Not all VFP architectures support trapping exceptions, so
- test whether the relevant bits were set and fail if not. */
- _FPU_GETCW (fpscr);
+ if (envp == FE_DFL_ENV)
+ fpscr |= _FPU_DEFAULT;
+ else if (envp == FE_NOMASK_ENV)
+ fpscr |= _FPU_IEEE;
+ else
+ fpscr |= envp->__cw & ~_FPU_RESERVED;
- if ((fpscr & _FPU_IEEE) != _FPU_IEEE)
- return 1;
- }
+ _FPU_SETCW (fpscr);
- return 0;
+ if (envp == FE_NOMASK_ENV)
+ {
+ /* 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;
}
- libc_fesetenv_vfp (envp);
return 0;
}
diff --git a/sysdeps/arm/fesetround.c b/sysdeps/arm/fesetround.c
index f52c50aec4..d1b92dc255 100644
--- a/sysdeps/arm/fesetround.c
+++ b/sysdeps/arm/fesetround.c
@@ -16,22 +16,28 @@
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#include <fenv_private.h>
+#include <fenv.h>
+#include <fpu_control.h>
#include <arm-features.h>
int
fesetround (int round)
{
+ fpu_control_t fpscr;
+
/* FE_TONEAREST is the only supported rounding mode
if a VFP unit isn't present. */
if (!ARM_HAVE_VFP)
return (round == FE_TONEAREST) ? 0 : 1;
+ /* Fail if the rounding mode is not valid. */
if (round & ~FE_TOWARDZERO)
return 1;
- libc_fesetround_vfp (round);
+ _FPU_GETCW (fpscr);
+ fpscr = (fpscr & ~FE_TOWARDZERO) | round;
+ _FPU_SETCW (fpscr);
return 0;
}
diff --git a/sysdeps/arm/feupdateenv.c b/sysdeps/arm/feupdateenv.c
index 2a7b3ec894..55a15025c6 100644
--- a/sysdeps/arm/feupdateenv.c
+++ b/sysdeps/arm/feupdateenv.c
@@ -17,35 +17,27 @@
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#include <fenv_private.h>
+#include <fenv.h>
+#include <fpu_control.h>
#include <arm-features.h>
int
feupdateenv (const fenv_t *envp)
{
- fenv_t fenv;
+ fpu_control_t fpscr;
/* Fail if a VFP unit isn't present. */
if (!ARM_HAVE_VFP)
return 1;
- if ((envp == FE_DFL_ENV) || (envp == FE_NOMASK_ENV))
- {
- fpu_control_t fpscr;
+ _FPU_GETCW (fpscr);
- _FPU_GETCW (fpscr);
+ /* Install new environment. */
+ fesetenv (envp);
- /* Preserve the reserved FPSCR flags. */
- fpscr &= _FPU_RESERVED;
- fpscr |= (envp == FE_DFL_ENV) ? _FPU_DEFAULT : _FPU_IEEE;
-
- /* Create a valid fenv to pass to libc_feupdateenv_vfp. */
- fenv.__cw = fpscr;
- envp = &fenv;
- }
-
- libc_feupdateenv_vfp (envp);
+ /* Raise the saved exceptions. */
+ feraiseexcept (fpscr & FE_ALL_EXCEPT);
return 0;
}
libm_hidden_def (feupdateenv)
diff --git a/sysdeps/arm/fgetexcptflg.c b/sysdeps/arm/fgetexcptflg.c
index 994555ca19..63fdfbf747 100644
--- a/sysdeps/arm/fgetexcptflg.c
+++ b/sysdeps/arm/fgetexcptflg.c
@@ -17,17 +17,22 @@
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#include <fenv_private.h>
+#include <fenv.h>
+#include <fpu_control.h>
#include <arm-features.h>
int
fegetexceptflag (fexcept_t *flagp, int excepts)
{
+ fpu_control_t fpscr;
+
/* Fail if a VFP unit isn't present. */
if (!ARM_HAVE_VFP)
return 1;
- *flagp = libc_fetestexcept_vfp (excepts);
+ _FPU_GETCW (fpscr);
+
+ *flagp = fpscr & excepts & FE_ALL_EXCEPT;
return 0;
}
diff --git a/sysdeps/arm/fsetexcptflg.c b/sysdeps/arm/fsetexcptflg.c
index 28810d3ec8..1a610ff912 100644
--- a/sysdeps/arm/fsetexcptflg.c
+++ b/sysdeps/arm/fsetexcptflg.c
@@ -25,22 +25,19 @@
int
fesetexceptflag (const fexcept_t *flagp, int excepts)
{
- fpu_control_t fpscr, new_fpscr;
+ fpu_control_t 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. */
- new_fpscr = fpscr & ~excepts;
- new_fpscr |= *flagp & excepts;
-
- /* Write new exception flags if changed. */
- if (new_fpscr != fpscr)
- _FPU_SETCW (new_fpscr);
+ fpscr &= ~(excepts & FE_ALL_EXCEPT);
+ fpscr |= (*flagp & excepts & FE_ALL_EXCEPT);
+ /* Save state back to the FPU. */
+ _FPU_SETCW (fpscr);
return 0;
}
diff --git a/sysdeps/arm/ftestexcept.c b/sysdeps/arm/ftestexcept.c
index 6c5d3a8288..de082b281a 100644
--- a/sysdeps/arm/ftestexcept.c
+++ b/sysdeps/arm/ftestexcept.c
@@ -16,18 +16,23 @@
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
-#include <fenv_private.h>
+#include <fenv.h>
+#include <fpu_control.h>
#include <arm-features.h>
int
fetestexcept (int excepts)
{
+ fpu_control_t fpscr;
+
/* Return no exception flags if a VFP unit isn't present. */
if (!ARM_HAVE_VFP)
return 0;
- return libc_fetestexcept_vfp (excepts);
-}
+ /* Get current exceptions. */
+ _FPU_GETCW (fpscr);
+ return fpscr & excepts & FE_ALL_EXCEPT;
+}
libm_hidden_def (fetestexcept)
diff --git a/sysdeps/arm/setfpucw.c b/sysdeps/arm/setfpucw.c
index 259b020f81..7416377f9e 100644
--- a/sysdeps/arm/setfpucw.c
+++ b/sysdeps/arm/setfpucw.c
@@ -24,20 +24,19 @@
void
__setfpucw (fpu_control_t set)
{
- fpu_control_t fpscr, new_fpscr;
+ fpu_control_t 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). */
- new_fpscr = fpscr & _FPU_RESERVED;
- new_fpscr |= set & ~_FPU_RESERVED;
+ fpscr &= _FPU_RESERVED;
+ fpscr |= set & ~_FPU_RESERVED;
- /* Write FPSCR if changed. */
- if (new_fpscr != fpscr)
- _FPU_SETCW (fpscr);
+ _FPU_SETCW (fpscr);
}