diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/soft-fp/q_util.c | 49 | ||||
-rw-r--r-- | sysdeps/sparc/sparc64/soft-fp/qp_util.c | 49 |
3 files changed, 76 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog index f7090ecefd..067a91a621 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2012-05-30 David S. Miller <davem@davemloft.net> + + * 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 <hongjiu.lu@intel.com> [BZ #14117] 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)); + } } |