mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-23 11:20:07 +00:00
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:
parent
04fb54b507
commit
d66ef399f5
25
ChangeLog
25
ChangeLog
@ -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
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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); \
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user