This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 1/2] ARM: Improve fenv implementation
- From: "Wilco" <wdijkstr at arm dot com>
- To: <libc-alpha at sourceware dot org>
- Date: Tue, 25 Mar 2014 18:44:28 -0000
- Subject: [PATCH 1/2] ARM: Improve fenv implementation
- Authentication-results: sourceware.org; auth=none
Hi,
This is a series of patches which improves the fenv implementation to make it more similar to the
inline functions in fenv_private.h.
The first patch is a cleanup with no functional changes. It uses fpu_control_t consistently with
meaningful variable names, fixes some coding style mistakes, improves comments and avoids
unnecessary indentation due to the ARM_HAVE_VFP check.
Wilco
---
sysdeps/arm/fclrexcpt.c | 27 +++++++------------
sysdeps/arm/fedisblxcpt.c | 24 +++++++----------
sysdeps/arm/feenablxcpt.c | 42 ++++++++++++-----------------
sysdeps/arm/fegetenv.c | 21 +++++++--------
sysdeps/arm/fegetexcept.c | 14 +++++-----
sysdeps/arm/fegetround.c | 17 +++++-------
sysdeps/arm/feholdexcpt.c | 28 +++++++++-----------
sysdeps/arm/fesetenv.c | 56 +++++++++++++++++++--------------------
sysdeps/arm/fesetround.c | 39 +++++++++++----------------
sysdeps/arm/feupdateenv.c | 25 +++++++----------
sysdeps/arm/fgetexcptflg.c | 19 +++++--------
sysdeps/arm/fraiseexcpt.c | 10 +++----
sysdeps/arm/fsetexcptflg.c | 27 ++++++++-----------
sysdeps/arm/ftestexcept.c | 16 +++++------
sysdeps/arm/get-rounding-mode.h | 16 +++++------
sysdeps/arm/setfpucw.c | 23 ++++++++--------
16 files changed, 171 insertions(+), 233 deletions(-)
diff --git a/sysdeps/arm/fclrexcpt.c b/sysdeps/arm/fclrexcpt.c
index 8b54114..1453192 100644
--- a/sysdeps/arm/fclrexcpt.c
+++ b/sysdeps/arm/fclrexcpt.c
@@ -24,28 +24,21 @@
int
__feclearexcept (int excepts)
{
- if (ARM_HAVE_VFP)
- {
- unsigned long int temp;
+ fpu_control_t fpscr;
- /* Mask out unsupported bits/exceptions. */
- excepts &= FE_ALL_EXCEPT;
+ /* Fail if a VFP unit isn't present unless nothing needs to be done. */
+ if (!ARM_HAVE_VFP)
+ return (excepts != 0);
- /* Get the current floating point status. */
- _FPU_GETCW (temp);
+ _FPU_GETCW (fpscr);
+ excepts &= FE_ALL_EXCEPT;
- /* Clear the relevant bits. */
- temp = (temp & ~FE_ALL_EXCEPT) | (temp & FE_ALL_EXCEPT & ~excepts);
+ /* Clear the relevant bits. */
+ fpscr = (fpscr & ~FE_ALL_EXCEPT) | (fpscr & FE_ALL_EXCEPT & ~excepts);
- /* Put the new data in effect. */
- _FPU_SETCW (temp);
+ _FPU_SETCW (fpscr);
- /* Success. */
- return 0;
- }
-
- /* Unsupported, so fail unless nothing needs to be done. */
- return (excepts != 0);
+ return 0;
}
#include <shlib-compat.h>
diff --git a/sysdeps/arm/fedisblxcpt.c b/sysdeps/arm/fedisblxcpt.c
index 88da539..f2956cd 100644
--- a/sysdeps/arm/fedisblxcpt.c
+++ b/sysdeps/arm/fedisblxcpt.c
@@ -25,23 +25,17 @@
int
fedisableexcept (int excepts)
{
- if (ARM_HAVE_VFP)
- {
- unsigned long int new_exc, old_exc;
+ fpu_control_t fpscr, new_fpscr;
- _FPU_GETCW(new_exc);
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return -1;
- old_exc = (new_exc >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
+ _FPU_GETCW (fpscr);
+ excepts &= FE_ALL_EXCEPT;
+ new_fpscr = fpscr & ~(excepts << FE_EXCEPT_SHIFT);
- excepts &= FE_ALL_EXCEPT;
+ _FPU_SETCW (new_fpscr);
- new_exc &= ~(excepts << FE_EXCEPT_SHIFT);
-
- _FPU_SETCW(new_exc);
-
- return old_exc;
- }
-
- /* Unsupported, so return -1 for failure. */
- return -1;
+ return (fpscr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
}
diff --git a/sysdeps/arm/feenablxcpt.c b/sysdeps/arm/feenablxcpt.c
index b286ec5..afd8943 100644
--- a/sysdeps/arm/feenablxcpt.c
+++ b/sysdeps/arm/feenablxcpt.c
@@ -25,35 +25,27 @@
int
feenableexcept (int excepts)
{
- if (ARM_HAVE_VFP)
- {
- unsigned long int new_exc, old_exc;
-
- _FPU_GETCW(new_exc);
-
- old_exc = (new_exc >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
+ fpu_control_t fpscr, new_fpscr;
- excepts &= FE_ALL_EXCEPT;
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return -1;
- new_exc |= (excepts << FE_EXCEPT_SHIFT);
+ _FPU_GETCW (fpscr);
+ excepts &= FE_ALL_EXCEPT;
+ new_fpscr = fpscr | (excepts << FE_EXCEPT_SHIFT);
- _FPU_SETCW(new_exc);
+ _FPU_SETCW (new_fpscr);
- if (excepts != 0)
- {
- /* VFPv3 and VFPv4 do not support trapping exceptions, so
- test whether the relevant bits were set and fail if
- not. */
- unsigned int temp;
- _FPU_GETCW (temp);
- if ((temp & (excepts << FE_EXCEPT_SHIFT))
- != (excepts << FE_EXCEPT_SHIFT))
- return -1;
- }
-
- return old_exc;
+ 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 & (excepts << FE_EXCEPT_SHIFT))
+ != (excepts << FE_EXCEPT_SHIFT))
+ return -1;
}
- /* Unsupported, so return -1 for failure. */
- return -1;
+ return (fpscr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
}
diff --git a/sysdeps/arm/fegetenv.c b/sysdeps/arm/fegetenv.c
index 7003a01..8dc043b 100644
--- a/sysdeps/arm/fegetenv.c
+++ b/sysdeps/arm/fegetenv.c
@@ -24,18 +24,15 @@
int
__fegetenv (fenv_t *envp)
{
- if (ARM_HAVE_VFP)
- {
- unsigned long int temp;
- _FPU_GETCW (temp);
- envp->__cw = temp;
-
- /* Success. */
- return 0;
- }
-
- /* Unsupported, so fail. */
- return 1;
+ fpu_control_t fpscr;
+
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 1;
+
+ _FPU_GETCW (fpscr);
+ envp->__cw = fpscr;
+ return 0;
}
#include <shlib-compat.h>
diff --git a/sysdeps/arm/fegetexcept.c b/sysdeps/arm/fegetexcept.c
index 5974c63..aa244d0 100644
--- a/sysdeps/arm/fegetexcept.c
+++ b/sysdeps/arm/fegetexcept.c
@@ -25,15 +25,13 @@
int
fegetexcept (void)
{
- if (ARM_HAVE_VFP)
- {
- unsigned long temp;
+ fpu_control_t fpscr;
- _FPU_GETCW (temp);
+ /* Return with all exceptions disabled if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 0;
- return (temp >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
- }
+ _FPU_GETCW (fpscr);
- /* Unsupported. Return all exceptions disabled. */
- return 0;
+ return (fpscr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT;
}
diff --git a/sysdeps/arm/fegetround.c b/sysdeps/arm/fegetround.c
index cb4cf1b..1c9c151 100644
--- a/sysdeps/arm/fegetround.c
+++ b/sysdeps/arm/fegetround.c
@@ -24,17 +24,14 @@
int
fegetround (void)
{
- if (ARM_HAVE_VFP)
- {
- unsigned int temp;
+ fpu_control_t fpscr;
- /* Get the current environment. */
- _FPU_GETCW (temp);
+ /* FE_TONEAREST is the only supported rounding mode
+ if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return FE_TONEAREST;
- return temp & FE_TOWARDZERO;
- }
-
- /* The current soft-float implementation only handles TONEAREST. */
- 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 9ca673c..258ba66 100644
--- a/sysdeps/arm/feholdexcpt.c
+++ b/sysdeps/arm/feholdexcpt.c
@@ -24,27 +24,23 @@
int
feholdexcept (fenv_t *envp)
{
- if (ARM_HAVE_VFP)
- {
- unsigned long int temp;
+ fpu_control_t fpscr;
- /* Store the environment. */
- _FPU_GETCW(temp);
- envp->__cw = temp;
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 1;
- /* Now set all exceptions to non-stop. */
- temp &= ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT);
+ _FPU_GETCW (fpscr);
+ envp->__cw = fpscr;
- /* And clear all exception flags. */
- temp &= ~FE_ALL_EXCEPT;
+ /* Now set all exceptions to non-stop. */
+ fpscr &= ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT);
- _FPU_SETCW(temp);
+ /* And clear all exception flags. */
+ fpscr &= ~FE_ALL_EXCEPT;
- return 0;
- }
-
- /* Unsupported, so fail. */
- return 1;
+ _FPU_SETCW (fpscr);
+ return 0;
}
libm_hidden_def (feholdexcept)
diff --git a/sysdeps/arm/fesetenv.c b/sysdeps/arm/fesetenv.c
index af4f25d..43b9b47 100644
--- a/sysdeps/arm/fesetenv.c
+++ b/sysdeps/arm/fesetenv.c
@@ -24,38 +24,36 @@
int
__fesetenv (const fenv_t *envp)
{
- if (ARM_HAVE_VFP)
+ fpu_control_t fpscr;
+
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 1;
+
+ _FPU_GETCW (fpscr);
+
+ /* Preserve the reserved FPSCR flags. */
+ fpscr &= _FPU_RESERVED;
+
+ if (envp == FE_DFL_ENV)
+ fpscr |= _FPU_DEFAULT;
+ else if (envp == FE_NOMASK_ENV)
+ fpscr |= _FPU_IEEE;
+ else
+ fpscr |= envp->__cw & ~_FPU_RESERVED;
+
+ _FPU_SETCW (fpscr);
+
+ if (envp == FE_NOMASK_ENV)
{
- unsigned int temp;
-
- _FPU_GETCW (temp);
- temp &= _FPU_RESERVED;
-
- if (envp == FE_DFL_ENV)
- temp |= _FPU_DEFAULT;
- else if (envp == FE_NOMASK_ENV)
- temp |= _FPU_IEEE;
- else
- temp |= envp->__cw & ~_FPU_RESERVED;
-
- _FPU_SETCW (temp);
-
- if (envp == FE_NOMASK_ENV)
- {
- /* VFPv3 and VFPv4 do not support trapping exceptions, so
- test whether the relevant bits were set and fail if
- not. */
- _FPU_GETCW (temp);
- if ((temp & _FPU_IEEE) != _FPU_IEEE)
- return 1;
- }
-
- /* Success. */
- return 0;
+ /* 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;
}
- /* Unsupported, so fail. */
- return 1;
+ return 0;
}
#include <shlib-compat.h>
diff --git a/sysdeps/arm/fesetround.c b/sysdeps/arm/fesetround.c
index 6f533d1..d1b92dc 100644
--- a/sysdeps/arm/fesetround.c
+++ b/sysdeps/arm/fesetround.c
@@ -24,30 +24,21 @@
int
fesetround (int round)
{
- if (ARM_HAVE_VFP)
- {
- fpu_control_t temp;
-
- switch (round)
- {
- case FE_TONEAREST:
- case FE_UPWARD:
- case FE_DOWNWARD:
- case FE_TOWARDZERO:
- _FPU_GETCW (temp);
- temp = (temp & ~FE_TOWARDZERO) | round;
- _FPU_SETCW (temp);
- return 0;
- default:
- return 1;
- }
- }
- else if (round == FE_TONEAREST)
- /* This is the only supported rounding mode for soft-fp. */
- return 0;
-
- /* Unsupported, so fail. */
- return 1;
+ 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;
+
+ _FPU_GETCW (fpscr);
+ fpscr = (fpscr & ~FE_TOWARDZERO) | round;
+ _FPU_SETCW (fpscr);
+ return 0;
}
libm_hidden_def (fesetround)
diff --git a/sysdeps/arm/feupdateenv.c b/sysdeps/arm/feupdateenv.c
index 58ec5f6..7cf6206 100644
--- a/sysdeps/arm/feupdateenv.c
+++ b/sysdeps/arm/feupdateenv.c
@@ -25,25 +25,20 @@
int
__feupdateenv (const fenv_t *envp)
{
- if (ARM_HAVE_VFP)
- {
- unsigned int temp;
+ fpu_control_t fpscr;
- /* Get the current exception state. */
- _FPU_GETCW (temp);
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 1;
- /* Install new environment. */
- fesetenv (envp);
+ _FPU_GETCW (fpscr);
- /* Raise the saved exceptions. */
- feraiseexcept (temp & FE_ALL_EXCEPT);
+ /* Install new environment. */
+ fesetenv (envp);
- /* Success. */
- return 0;
- }
-
- /* Unsupported, so fail. */
- return 1;
+ /* Raise the saved exceptions. */
+ feraiseexcept (fpscr & FE_ALL_EXCEPT);
+ return 0;
}
#include <shlib-compat.h>
diff --git a/sysdeps/arm/fgetexcptflg.c b/sysdeps/arm/fgetexcptflg.c
index 1145979..e1eb420 100644
--- a/sysdeps/arm/fgetexcptflg.c
+++ b/sysdeps/arm/fgetexcptflg.c
@@ -25,21 +25,16 @@
int
__fegetexceptflag (fexcept_t *flagp, int excepts)
{
- if (ARM_HAVE_VFP)
- {
- unsigned long temp;
+ fpu_control_t fpscr;
- /* Get the current exceptions. */
- _FPU_GETCW (temp);
+ /* Fail if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 1;
- *flagp = temp & excepts & FE_ALL_EXCEPT;
+ _FPU_GETCW (fpscr);
- /* Success. */
- return 0;
- }
-
- /* Unsupported, so fail. */
- return 1;
+ *flagp = fpscr & excepts & FE_ALL_EXCEPT;
+ return 0;
}
#include <shlib-compat.h>
diff --git a/sysdeps/arm/fraiseexcpt.c b/sysdeps/arm/fraiseexcpt.c
index 8b32065..a964cb0 100644
--- a/sysdeps/arm/fraiseexcpt.c
+++ b/sysdeps/arm/fraiseexcpt.c
@@ -25,9 +25,12 @@
int
feraiseexcept (int excepts)
{
- if (ARM_HAVE_VFP)
+ /* Fail if a VFP unit isn't present unless nothing needs to be done. */
+ if (!ARM_HAVE_VFP)
+ return (excepts != 0);
+ else
{
- int fpscr;
+ fpu_control_t fpscr;
const float fp_zero = 0.0, fp_one = 1.0, fp_max = FLT_MAX,
fp_min = FLT_MIN, fp_1e32 = 1.0e32f, fp_two = 2.0,
fp_three = 3.0;
@@ -98,9 +101,6 @@ feraiseexcept (int excepts)
/* Success. */
return 0;
}
-
- /* Unsupported, so fail unless nothing needs to be done. */
- return (excepts != 0);
}
libm_hidden_def (feraiseexcept)
diff --git a/sysdeps/arm/fsetexcptflg.c b/sysdeps/arm/fsetexcptflg.c
index 0c88c0f..a594e15 100644
--- a/sysdeps/arm/fsetexcptflg.c
+++ b/sysdeps/arm/fsetexcptflg.c
@@ -25,26 +25,21 @@
int
__fesetexceptflag (const fexcept_t *flagp, int excepts)
{
- if (ARM_HAVE_VFP)
- {
- fexcept_t temp;
+ fpu_control_t fpscr;
- /* Get the current environment. */
- _FPU_GETCW (temp);
+ /* Fail if a VFP unit isn't present unless nothing needs to be done. */
+ if (!ARM_HAVE_VFP)
+ return (excepts != 0);
- /* Set the desired exception mask. */
- temp &= ~(excepts & FE_ALL_EXCEPT);
- temp |= (*flagp & excepts & FE_ALL_EXCEPT);
+ _FPU_GETCW (fpscr);
- /* Save state back to the FPU. */
- _FPU_SETCW (temp);
+ /* Set the desired exception mask. */
+ fpscr &= ~(excepts & FE_ALL_EXCEPT);
+ fpscr |= (*flagp & excepts & FE_ALL_EXCEPT);
- /* Success. */
- return 0;
- }
-
- /* Unsupported, so fail unless nothing needs to be done. */
- return (excepts != 0);
+ /* Save state back to the FPU. */
+ _FPU_SETCW (fpscr);
+ return 0;
}
#include <shlib-compat.h>
diff --git a/sysdeps/arm/ftestexcept.c b/sysdeps/arm/ftestexcept.c
index 9295c0f..de082b2 100644
--- a/sysdeps/arm/ftestexcept.c
+++ b/sysdeps/arm/ftestexcept.c
@@ -24,17 +24,15 @@
int
fetestexcept (int excepts)
{
- if (ARM_HAVE_VFP)
- {
- fexcept_t temp;
+ fpu_control_t fpscr;
- /* Get current exceptions. */
- _FPU_GETCW(temp);
+ /* Return no exception flags if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return 0;
- return temp & excepts & FE_ALL_EXCEPT;
- }
+ /* Get current exceptions. */
+ _FPU_GETCW (fpscr);
- /* Unsupported, return 0. */
- return 0;
+ return fpscr & excepts & FE_ALL_EXCEPT;
}
libm_hidden_def (fetestexcept)
diff --git a/sysdeps/arm/get-rounding-mode.h b/sysdeps/arm/get-rounding-mode.h
index 7d6054c..a1ecf51 100644
--- a/sysdeps/arm/get-rounding-mode.h
+++ b/sysdeps/arm/get-rounding-mode.h
@@ -28,15 +28,15 @@
static inline int
get_rounding_mode (void)
{
- if (ARM_HAVE_VFP)
- {
- fpu_control_t fc;
-
- _FPU_GETCW (fc);
- return fc & FE_TOWARDZERO;
- }
- else
+ 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;
}
#endif /* get-rounding-mode.h */
diff --git a/sysdeps/arm/setfpucw.c b/sysdeps/arm/setfpucw.c
index 92333eb..7416377 100644
--- a/sysdeps/arm/setfpucw.c
+++ b/sysdeps/arm/setfpucw.c
@@ -24,20 +24,19 @@
void
__setfpucw (fpu_control_t set)
{
- if (ARM_HAVE_VFP)
- {
- fpu_control_t cw;
+ fpu_control_t fpscr;
- /* Fetch the current control word. */
- _FPU_GETCW (cw);
+ /* Do nothing if a VFP unit isn't present. */
+ if (!ARM_HAVE_VFP)
+ return;
- /* Preserve the reserved bits, and set the rest as the user
- specified (or the default, if the user gave zero). */
- cw &= _FPU_RESERVED;
- cw |= set & ~_FPU_RESERVED;
+ /* Fetch the current control word. */
+ _FPU_GETCW (fpscr);
- _FPU_SETCW (cw);
- }
+ /* 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;
- /* Do nothing if a VFP unit isn't present. */
+ _FPU_SETCW (fpscr);
}
--
1.7.9.5