From d66ef399f5a9e1656fe8e435a8fa655cf271b676 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 27 May 2012 21:02:14 -0700 Subject: Fix underflow reporting and tie up loose ends in sparc soft-fp. * sysdeps/sparc/sparc32/soft-fp/q_util.c (___Q_numbers): Delete. (___Q_zero): New. (__Q_simulate_exceptions): Return void. Change to simulate exceptions by writing into the %fsr. * sysdeps/sparc/sparc64/soft-fp/qp_util.c (__Qp_handle_exceptions): Likewise. (numbers): Delete. * sysdeps/sparc/sparc64/soft-fp/Versions: Remove entry for __Qp_handle_exceptions. * sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist: Remove __Qp_handle_exceptions. * sysdeps/sparc/sparc32/soft-fp/sfp-machine.h (_FP_DECL_EX): Mark as unused and give dummy FP_RND_NEAREST initializer. (FP_INHIBIT_RESULTS): Define. (___Q_simulate_exceptions): Update declaration. (FP_HANDLE_EXCEPTIONS): Use ___Q_zero and tidy inline asm formatting. * sysdeps/sparc/sparc64/soft-fp/sfp-machine.h (_FP_DECL_EX): Mark as unused and give dummy FP_RND_NEAREST initializer. (__Qp_handle_exceptions): Update declaration. (FP_HANDLE_EXCEPTIONS, QP_NO_EXCEPTIONS): Tidy inline asm formatting. --- sysdeps/sparc/sparc64/soft-fp/Versions | 2 +- sysdeps/sparc/sparc64/soft-fp/qp_util.c | 49 ++++++++++------------------- sysdeps/sparc/sparc64/soft-fp/sfp-machine.h | 16 +++++----- 3 files changed, 26 insertions(+), 41 deletions(-) (limited to 'sysdeps/sparc/sparc64') diff --git a/sysdeps/sparc/sparc64/soft-fp/Versions b/sysdeps/sparc/sparc64/soft-fp/Versions index 440482752d..9e89c3c3ef 100644 --- a/sysdeps/sparc/sparc64/soft-fp/Versions +++ b/sysdeps/sparc/sparc64/soft-fp/Versions @@ -3,6 +3,6 @@ libc { _Qp_add; _Qp_cmp; _Qp_cmpe; _Qp_div; _Qp_dtoq; _Qp_feq; _Qp_fge; _Qp_fgt; _Qp_fle; _Qp_flt; _Qp_fne; _Qp_itoq; _Qp_mul; _Qp_neg; _Qp_qtod; _Qp_qtoi; _Qp_qtos; _Qp_qtoui; _Qp_qtoux; _Qp_qtox; _Qp_sqrt; _Qp_stoq; _Qp_sub; - _Qp_uitoq; _Qp_uxtoq; _Qp_xtoq; __Qp_handle_exceptions; + _Qp_uitoq; _Qp_uxtoq; _Qp_xtoq; } } diff --git a/sysdeps/sparc/sparc64/soft-fp/qp_util.c b/sysdeps/sparc/sparc64/soft-fp/qp_util.c index fd3043bb8e..358d0e4ec0 100644 --- a/sysdeps/sparc/sparc64/soft-fp/qp_util.c +++ b/sysdeps/sparc/sparc64/soft-fp/qp_util.c @@ -1,7 +1,7 @@ /* Software floating-point emulation. Helper routine for _Qp_* routines. Simulate exceptions using double arithmetics. - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2012 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek (jj@ultra.linux.cz). @@ -21,36 +21,21 @@ #include "soft-fp.h" -static unsigned long numbers [] = { -0x7fef000000000000UL, /* A huge double number */ -0x0010100000000000UL, /* Very tiny number */ -0x0010000000000000UL, /* Minimum normalized number */ -0x0000000000000000UL, /* Zero */ -}; - -double __Qp_handle_exceptions(int exceptions) +void __Qp_handle_exceptions(int exceptions) { - double d, *p = (double *)numbers; - if (exceptions & FP_EX_INVALID) - d = p[3]/p[3]; - if (exceptions & FP_EX_OVERFLOW) - { - d = p[0] + p[0]; - exceptions &= ~FP_EX_INEXACT; - } - if (exceptions & FP_EX_UNDERFLOW) - { - if (exceptions & FP_EX_INEXACT) - { - d = p[2] * p[2]; - exceptions &= ~FP_EX_INEXACT; - } - else - d = p[1] - p[2]; - } - if (exceptions & FP_EX_DIVZERO) - d = 1.0/p[3]; - if (exceptions & FP_EX_INEXACT) - d = p[0] - p[2]; - return d; + 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); } diff --git a/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h b/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h index 7ec804da51..36f92d64fb 100644 --- a/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h +++ b/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h @@ -92,7 +92,8 @@ do { \ #define FP_EX_DIVZERO (1 << 1) #define FP_EX_INEXACT (1 << 0) -#define _FP_DECL_EX fpu_control_t _fcw +#define _FP_DECL_EX \ + fpu_control_t _fcw __attribute__ ((unused)) = (FP_RND_NEAREST << 30) #define FP_INIT_ROUNDMODE \ do { \ @@ -102,7 +103,7 @@ do { \ #define FP_INHIBIT_RESULTS ((_fcw >> 23) & _fex) /* Simulate exceptions using double arithmetics. */ -extern double __Qp_handle_exceptions(int exc); +extern void __Qp_handle_exceptions(int exc); #define FP_HANDLE_EXCEPTIONS \ do { \ @@ -111,10 +112,9 @@ do { \ /* This is the common case, so we do it inline. \ * We need to clear cexc bits if any. \ */ \ - __asm__ __volatile__("\n" \ -" fzero %%f62\n" \ -" faddd %%f62, %%f62, %%f62\n" \ -" " : : : "f62"); \ + __asm__ __volatile__("fzero %%f62\n\t" \ + "faddd %%f62, %%f62, %%f62" \ + : : : "f62"); \ } \ else \ { \ @@ -136,8 +136,8 @@ do { \ } while (0) #define QP_NO_EXCEPTIONS \ - __asm ("fzero %%f62\n" \ -" faddd %%f62, %%f62, %%f62" : : : "f62") + __asm ("fzero %%f62\n\t" \ + "faddd %%f62, %%f62, %%f62" : : : "f62") #define QP_CLOBBER "memory", "f52", "f54", "f56", "f58", "f60", "f62" #define QP_CLOBBER_CC QP_CLOBBER , "cc" -- cgit 1.4.1