aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/sparc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-05-30 23:09:25 -0700
committerDavid S. Miller <davem@davemloft.net>2012-05-30 23:09:25 -0700
commit1c58d5dcebbc41172316b3d28ee3fc58cf09aa13 (patch)
tree23d872b5da4c809858cf4f194afe44798003eb2c /sysdeps/sparc
parent0e20515a17445ec961a05b14a7355b79fc421564 (diff)
downloadglibc-1c58d5dcebbc41172316b3d28ee3fc58cf09aa13.zip
glibc-1c58d5dcebbc41172316b3d28ee3fc58cf09aa13.tar.gz
glibc-1c58d5dcebbc41172316b3d28ee3fc58cf09aa13.tar.bz2
Simulate sparc fpu exceptions using real FP ops again in soft-fp.
* sysdeps/sparc/sparc32/soft-fp/q_util.c (___Q_simulate_exceptions): Use real FP ops rather than writing into the %fsr. * sysdeps/sparc/sparc32/soft-fp/q_util.c (__Qp_handle_exceptions): Likewise.
Diffstat (limited to 'sysdeps/sparc')
-rw-r--r--sysdeps/sparc/sparc32/soft-fp/q_util.c49
-rw-r--r--sysdeps/sparc/sparc64/soft-fp/qp_util.c49
2 files changed, 68 insertions, 30 deletions
diff --git a/sysdeps/sparc/sparc32/soft-fp/q_util.c b/sysdeps/sparc/sparc32/soft-fp/q_util.c
index c4efc10..47e34c7 100644
--- a/sysdeps/sparc/sparc32/soft-fp/q_util.c
+++ b/sysdeps/sparc/sparc32/soft-fp/q_util.c
@@ -19,25 +19,44 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include <float.h>
+#include <math.h>
+#include <assert.h>
#include "soft-fp.h"
unsigned long long ___Q_zero = 0x0000000000000000ULL;
void ___Q_simulate_exceptions(int exceptions)
{
- fpu_control_t fcw;
- int tem, ou;
-
- _FPU_GETCW(fcw);
-
- tem = (fcw >> 23) & 0x1f;
-
- ou = exceptions & (FP_EX_OVERFLOW | FP_EX_UNDERFLOW);
- if (ou & tem)
- exceptions &= ~FP_EX_INVALID;
-
- fcw &= ~0x1f;
- fcw |= (exceptions | (exceptions << 5));
-
- _FPU_SETCW(fcw);
+ if (exceptions & FP_EX_INVALID)
+ {
+ float f = 0.0;
+ __asm__ __volatile__ ("fdivs %0, %0, %0" : "+f" (f));
+ }
+ if (exceptions & FP_EX_DIVZERO)
+ {
+ float f = 1.0, g = 0.0;
+ __asm__ __volatile__ ("fdivs %0, %1, %0"
+ : "+f" (f)
+ : "f" (g));
+ }
+ if (exceptions & FP_EX_OVERFLOW)
+ {
+ float f = FLT_MAX;
+ __asm__ __volatile__("fmuls %0, %0, %0" : "+f" (f));
+ exceptions &= ~FP_EX_INEXACT;
+ }
+ if (exceptions & FP_EX_UNDERFLOW)
+ {
+ float f = FLT_MIN;
+ __asm__ __volatile__("fmuls %0, %0, %0" : "+f" (f));
+ exceptions &= ~FP_EX_INEXACT;
+ }
+ if (exceptions & FP_EX_INEXACT)
+ {
+ double d = 1.0, e = M_PI;
+ __asm__ __volatile__ ("fdivd %0, %1, %0"
+ : "+f" (d)
+ : "f" (e));
+ }
}
diff --git a/sysdeps/sparc/sparc64/soft-fp/qp_util.c b/sysdeps/sparc/sparc64/soft-fp/qp_util.c
index 358d0e4..4a1280b 100644
--- a/sysdeps/sparc/sparc64/soft-fp/qp_util.c
+++ b/sysdeps/sparc/sparc64/soft-fp/qp_util.c
@@ -19,23 +19,42 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include <float.h>
+#include <math.h>
+#include <assert.h>
#include "soft-fp.h"
void __Qp_handle_exceptions(int exceptions)
{
- fpu_control_t fcw;
- int tem, ou;
-
- _FPU_GETCW(fcw);
-
- tem = (fcw >> 23) & 0x1f;
-
- ou = exceptions & (FP_EX_OVERFLOW | FP_EX_UNDERFLOW);
- if (ou & tem)
- exceptions &= ~FP_EX_INVALID;
-
- fcw &= ~0x1f;
- fcw |= (exceptions | (exceptions << 5));
-
- _FPU_SETCW(fcw);
+ if (exceptions & FP_EX_INVALID)
+ {
+ float f = 0.0;
+ __asm__ __volatile__ ("fdivs %0, %0, %0" : "+f" (f));
+ }
+ if (exceptions & FP_EX_DIVZERO)
+ {
+ float f = 1.0, g = 0.0;
+ __asm__ __volatile__ ("fdivs %0, %1, %0"
+ : "+f" (f)
+ : "f" (g));
+ }
+ if (exceptions & FP_EX_OVERFLOW)
+ {
+ float f = FLT_MAX;
+ __asm__ __volatile__("fmuls %0, %0, %0" : "+f" (f));
+ exceptions &= ~FP_EX_INEXACT;
+ }
+ if (exceptions & FP_EX_UNDERFLOW)
+ {
+ float f = FLT_MIN;
+ __asm__ __volatile__("fmuls %0, %0, %0" : "+f" (f));
+ exceptions &= ~FP_EX_INEXACT;
+ }
+ if (exceptions & FP_EX_INEXACT)
+ {
+ double d = 1.0, e = M_PI;
+ __asm__ __volatile__ ("fdivd %0, %1, %0"
+ : "+f" (d)
+ : "f" (e));
+ }
}