From d66ef399f5a9e1656fe8e435a8fa655cf271b676 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 27 May 2012 21:02:14 -0700 Subject: [PATCH] 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. --- ChangeLog | 25 ++++++++++ sysdeps/sparc/sparc32/soft-fp/q_util.c | 49 +++++++------------ sysdeps/sparc/sparc32/soft-fp/sfp-machine.h | 16 +++--- 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 +++--- .../linux/sparc/sparc64/nptl/libc.abilist | 1 - 7 files changed, 78 insertions(+), 80 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9a5cd02dce..8f648267b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2012-05-27 David S. Miller + + * 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. + 2012-05-27 Thomas Schwinge * sysdeps/sh/sh4/fpu/fclrexcpt.c (feclearexcept): Use fpu_control_t for diff --git a/sysdeps/sparc/sparc32/soft-fp/q_util.c b/sysdeps/sparc/sparc32/soft-fp/q_util.c index 22f70ba467..c4efc10bf8 100644 --- a/sysdeps/sparc/sparc32/soft-fp/q_util.c +++ b/sysdeps/sparc/sparc32/soft-fp/q_util.c @@ -1,7 +1,7 @@ /* Software floating-point emulation. Helper routine for _Q_* 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,23 @@ #include "soft-fp.h" -unsigned long long ___Q_numbers [] = { -0x0000000000000000ULL, /* Zero */ -0x0010100000000000ULL, /* Very tiny number */ -0x0010000000000000ULL, /* Minimum normalized number */ -0x7fef000000000000ULL, /* A huge double number */ -}; +unsigned long long ___Q_zero = 0x0000000000000000ULL; -double ___Q_simulate_exceptions(int exceptions) +void ___Q_simulate_exceptions(int exceptions) { - double d, *p = (double *)___Q_numbers; - if (exceptions & FP_EX_INVALID) - d = p[0]/p[0]; - if (exceptions & FP_EX_OVERFLOW) - { - d = p[3] + p[3]; - 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[0]; - if (exceptions & FP_EX_INEXACT) - d = p[3] - 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/sparc32/soft-fp/sfp-machine.h b/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h index 8cdc7c2677..4314082f70 100644 --- a/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h +++ b/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h @@ -184,15 +184,18 @@ #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 { \ _FPU_GETCW(_fcw); \ } while (0) +#define FP_INHIBIT_RESULTS ((_fcw >> 23) & _fex) + /* Simulate exceptions using double arithmetics. */ -extern double ___Q_simulate_exceptions(int exc); +extern void ___Q_simulate_exceptions(int exc); #define FP_HANDLE_EXCEPTIONS \ do { \ @@ -201,11 +204,10 @@ do { \ /* This is the common case, so we do it inline. \ * We need to clear cexc bits if any. \ */ \ - extern unsigned long long ___Q_numbers[]; \ - __asm__ __volatile__("\ - ldd [%0], %%f30\n\ - faddd %%f30, %%f30, %%f30\ - " : : "r" (___Q_numbers) : "f30"); \ + extern unsigned long long ___Q_zero; \ + __asm__ __volatile__("ldd [%0], %%f30\n\t" \ + "faddd %%f30, %%f30, %%f30" \ + : : "r" (&___Q_zero) : "f30"); \ } \ else \ ___Q_simulate_exceptions (_fex); \ 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" diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist index 2914d1c211..8571fa8da9 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/nptl/libc.abilist @@ -248,7 +248,6 @@ GLIBC_2.2 _Qp_uitoq F _Qp_uxtoq F _Qp_xtoq F - __Qp_handle_exceptions F __adjtimex F __after_morecore_hook D 0x8 __align_cpy_1 F