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/sparc32/soft-fp/q_util.c | |
parent | 0e20515a17445ec961a05b14a7355b79fc421564 (diff) | |
download | glibc-1c58d5dcebbc41172316b3d28ee3fc58cf09aa13.tar.gz |
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/sparc32/soft-fp/q_util.c')
-rw-r--r-- | sysdeps/sparc/sparc32/soft-fp/q_util.c | 49 |
1 files changed, 34 insertions, 15 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)); + } } |