From 1c58d5dcebbc41172316b3d28ee3fc58cf09aa13 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 30 May 2012 23:09:25 -0700 Subject: [PATCH] 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. --- ChangeLog | 8 ++++++ sysdeps/sparc/sparc32/soft-fp/q_util.c | 49 +++++++++++++++++++++++---------- sysdeps/sparc/sparc64/soft-fp/qp_util.c | 49 +++++++++++++++++++++++---------- 3 files changed, 76 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index f7090ec..067a91a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2012-05-30 David S. Miller + + * 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. + 2012-05-30 H.J. Lu [BZ #14117] 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 . */ +#include +#include +#include #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 . */ +#include +#include +#include #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)); + } } -- 2.7.4