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.
This commit is contained in:
David S. Miller 2012-05-27 21:02:14 -07:00
parent 04fb54b507
commit d66ef399f5
7 changed files with 78 additions and 80 deletions

View File

@ -1,3 +1,28 @@
2012-05-27 David S. Miller <davem@davemloft.net>
* 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 <thomas@codesourcery.com> 2012-05-27 Thomas Schwinge <thomas@codesourcery.com>
* sysdeps/sh/sh4/fpu/fclrexcpt.c (feclearexcept): Use fpu_control_t for * sysdeps/sh/sh4/fpu/fclrexcpt.c (feclearexcept): Use fpu_control_t for

View File

@ -1,7 +1,7 @@
/* Software floating-point emulation. /* Software floating-point emulation.
Helper routine for _Q_* routines. Helper routine for _Q_* routines.
Simulate exceptions using double arithmetics. 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. This file is part of the GNU C Library.
Contributed by Jakub Jelinek (jj@ultra.linux.cz). Contributed by Jakub Jelinek (jj@ultra.linux.cz).
@ -21,36 +21,23 @@
#include "soft-fp.h" #include "soft-fp.h"
unsigned long long ___Q_numbers [] = { unsigned long long ___Q_zero = 0x0000000000000000ULL;
0x0000000000000000ULL, /* Zero */
0x0010100000000000ULL, /* Very tiny number */
0x0010000000000000ULL, /* Minimum normalized number */
0x7fef000000000000ULL, /* A huge double number */
};
double ___Q_simulate_exceptions(int exceptions) void ___Q_simulate_exceptions(int exceptions)
{ {
double d, *p = (double *)___Q_numbers; fpu_control_t fcw;
if (exceptions & FP_EX_INVALID) int tem, ou;
d = p[0]/p[0];
if (exceptions & FP_EX_OVERFLOW) _FPU_GETCW(fcw);
{
d = p[3] + p[3]; tem = (fcw >> 23) & 0x1f;
exceptions &= ~FP_EX_INEXACT;
} ou = exceptions & (FP_EX_OVERFLOW | FP_EX_UNDERFLOW);
if (exceptions & FP_EX_UNDERFLOW) if (ou & tem)
{ exceptions &= ~FP_EX_INVALID;
if (exceptions & FP_EX_INEXACT)
{ fcw &= ~0x1f;
d = p[2] * p[2]; fcw |= (exceptions | (exceptions << 5));
exceptions &= ~FP_EX_INEXACT;
} _FPU_SETCW(fcw);
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;
} }

View File

@ -184,15 +184,18 @@
#define FP_EX_DIVZERO (1 << 1) #define FP_EX_DIVZERO (1 << 1)
#define FP_EX_INEXACT (1 << 0) #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 \ #define FP_INIT_ROUNDMODE \
do { \ do { \
_FPU_GETCW(_fcw); \ _FPU_GETCW(_fcw); \
} while (0) } while (0)
#define FP_INHIBIT_RESULTS ((_fcw >> 23) & _fex)
/* Simulate exceptions using double arithmetics. */ /* Simulate exceptions using double arithmetics. */
extern double ___Q_simulate_exceptions(int exc); extern void ___Q_simulate_exceptions(int exc);
#define FP_HANDLE_EXCEPTIONS \ #define FP_HANDLE_EXCEPTIONS \
do { \ do { \
@ -201,11 +204,10 @@ do { \
/* This is the common case, so we do it inline. \ /* This is the common case, so we do it inline. \
* We need to clear cexc bits if any. \ * We need to clear cexc bits if any. \
*/ \ */ \
extern unsigned long long ___Q_numbers[]; \ extern unsigned long long ___Q_zero; \
__asm__ __volatile__("\ __asm__ __volatile__("ldd [%0], %%f30\n\t" \
ldd [%0], %%f30\n\ "faddd %%f30, %%f30, %%f30" \
faddd %%f30, %%f30, %%f30\ : : "r" (&___Q_zero) : "f30"); \
" : : "r" (___Q_numbers) : "f30"); \
} \ } \
else \ else \
___Q_simulate_exceptions (_fex); \ ___Q_simulate_exceptions (_fex); \

View File

@ -3,6 +3,6 @@ libc {
_Qp_add; _Qp_cmp; _Qp_cmpe; _Qp_div; _Qp_dtoq; _Qp_feq; _Qp_fge; _Qp_fgt; _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_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_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;
} }
} }

View File

@ -1,7 +1,7 @@
/* Software floating-point emulation. /* Software floating-point emulation.
Helper routine for _Qp_* routines. Helper routine for _Qp_* routines.
Simulate exceptions using double arithmetics. 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. This file is part of the GNU C Library.
Contributed by Jakub Jelinek (jj@ultra.linux.cz). Contributed by Jakub Jelinek (jj@ultra.linux.cz).
@ -21,36 +21,21 @@
#include "soft-fp.h" #include "soft-fp.h"
static unsigned long numbers [] = { void __Qp_handle_exceptions(int exceptions)
0x7fef000000000000UL, /* A huge double number */ {
0x0010100000000000UL, /* Very tiny number */ fpu_control_t fcw;
0x0010000000000000UL, /* Minimum normalized number */ int tem, ou;
0x0000000000000000UL, /* Zero */
};
double __Qp_handle_exceptions(int exceptions) _FPU_GETCW(fcw);
{
double d, *p = (double *)numbers; tem = (fcw >> 23) & 0x1f;
if (exceptions & FP_EX_INVALID)
d = p[3]/p[3]; ou = exceptions & (FP_EX_OVERFLOW | FP_EX_UNDERFLOW);
if (exceptions & FP_EX_OVERFLOW) if (ou & tem)
{ exceptions &= ~FP_EX_INVALID;
d = p[0] + p[0];
exceptions &= ~FP_EX_INEXACT; fcw &= ~0x1f;
} fcw |= (exceptions | (exceptions << 5));
if (exceptions & FP_EX_UNDERFLOW)
{ _FPU_SETCW(fcw);
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;
} }

View File

@ -92,7 +92,8 @@ do { \
#define FP_EX_DIVZERO (1 << 1) #define FP_EX_DIVZERO (1 << 1)
#define FP_EX_INEXACT (1 << 0) #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 \ #define FP_INIT_ROUNDMODE \
do { \ do { \
@ -102,7 +103,7 @@ do { \
#define FP_INHIBIT_RESULTS ((_fcw >> 23) & _fex) #define FP_INHIBIT_RESULTS ((_fcw >> 23) & _fex)
/* Simulate exceptions using double arithmetics. */ /* Simulate exceptions using double arithmetics. */
extern double __Qp_handle_exceptions(int exc); extern void __Qp_handle_exceptions(int exc);
#define FP_HANDLE_EXCEPTIONS \ #define FP_HANDLE_EXCEPTIONS \
do { \ do { \
@ -111,10 +112,9 @@ do { \
/* This is the common case, so we do it inline. \ /* This is the common case, so we do it inline. \
* We need to clear cexc bits if any. \ * We need to clear cexc bits if any. \
*/ \ */ \
__asm__ __volatile__("\n" \ __asm__ __volatile__("fzero %%f62\n\t" \
" fzero %%f62\n" \ "faddd %%f62, %%f62, %%f62" \
" faddd %%f62, %%f62, %%f62\n" \ : : : "f62"); \
" " : : : "f62"); \
} \ } \
else \ else \
{ \ { \
@ -136,7 +136,7 @@ do { \
} while (0) } while (0)
#define QP_NO_EXCEPTIONS \ #define QP_NO_EXCEPTIONS \
__asm ("fzero %%f62\n" \ __asm ("fzero %%f62\n\t" \
"faddd %%f62, %%f62, %%f62" : : : "f62") "faddd %%f62, %%f62, %%f62" : : : "f62")
#define QP_CLOBBER "memory", "f52", "f54", "f56", "f58", "f60", "f62" #define QP_CLOBBER "memory", "f52", "f54", "f56", "f58", "f60", "f62"

View File

@ -248,7 +248,6 @@ GLIBC_2.2
_Qp_uitoq F _Qp_uitoq F
_Qp_uxtoq F _Qp_uxtoq F
_Qp_xtoq F _Qp_xtoq F
__Qp_handle_exceptions F
__adjtimex F __adjtimex F
__after_morecore_hook D 0x8 __after_morecore_hook D 0x8
__align_cpy_1 F __align_cpy_1 F