diff options
author | David S. Miller <davem@davemloft.net> | 2012-05-30 23:09:25 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-05-30 23:09:25 -0700 |
commit | 1c58d5dcebbc41172316b3d28ee3fc58cf09aa13 (patch) | |
tree | 23d872b5da4c809858cf4f194afe44798003eb2c /sysdeps/sparc | |
parent | 0e20515a17445ec961a05b14a7355b79fc421564 (diff) | |
download | glibc-1c58d5dcebbc41172316b3d28ee3fc58cf09aa13.tar.gz glibc-1c58d5dcebbc41172316b3d28ee3fc58cf09aa13.tar.xz glibc-1c58d5dcebbc41172316b3d28ee3fc58cf09aa13.zip |
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.c | 49 | ||||
-rw-r--r-- | sysdeps/sparc/sparc64/soft-fp/qp_util.c | 49 |
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 c4efc10bf8..47e34c7c59 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 358d0e4ec0..4a1280b07d 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)); + } } |