mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
Simulate sparc fpu exceptions using real FP ops again in soft-fp.
* 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.
This commit is contained in:
@ -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>
|
2012-05-30 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
[BZ #14117]
|
[BZ #14117]
|
||||||
|
@ -19,25 +19,44 @@
|
|||||||
License along with the GNU C Library; if not, see
|
License along with the GNU C Library; if not, see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
#include "soft-fp.h"
|
#include "soft-fp.h"
|
||||||
|
|
||||||
unsigned long long ___Q_zero = 0x0000000000000000ULL;
|
unsigned long long ___Q_zero = 0x0000000000000000ULL;
|
||||||
|
|
||||||
void ___Q_simulate_exceptions(int exceptions)
|
void ___Q_simulate_exceptions(int exceptions)
|
||||||
{
|
{
|
||||||
fpu_control_t fcw;
|
if (exceptions & FP_EX_INVALID)
|
||||||
int tem, ou;
|
{
|
||||||
|
float f = 0.0;
|
||||||
_FPU_GETCW(fcw);
|
__asm__ __volatile__ ("fdivs %0, %0, %0" : "+f" (f));
|
||||||
|
}
|
||||||
tem = (fcw >> 23) & 0x1f;
|
if (exceptions & FP_EX_DIVZERO)
|
||||||
|
{
|
||||||
ou = exceptions & (FP_EX_OVERFLOW | FP_EX_UNDERFLOW);
|
float f = 1.0, g = 0.0;
|
||||||
if (ou & tem)
|
__asm__ __volatile__ ("fdivs %0, %1, %0"
|
||||||
exceptions &= ~FP_EX_INVALID;
|
: "+f" (f)
|
||||||
|
: "f" (g));
|
||||||
fcw &= ~0x1f;
|
}
|
||||||
fcw |= (exceptions | (exceptions << 5));
|
if (exceptions & FP_EX_OVERFLOW)
|
||||||
|
{
|
||||||
_FPU_SETCW(fcw);
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,23 +19,42 @@
|
|||||||
License along with the GNU C Library; if not, see
|
License along with the GNU C Library; if not, see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
#include "soft-fp.h"
|
#include "soft-fp.h"
|
||||||
|
|
||||||
void __Qp_handle_exceptions(int exceptions)
|
void __Qp_handle_exceptions(int exceptions)
|
||||||
{
|
{
|
||||||
fpu_control_t fcw;
|
if (exceptions & FP_EX_INVALID)
|
||||||
int tem, ou;
|
{
|
||||||
|
float f = 0.0;
|
||||||
_FPU_GETCW(fcw);
|
__asm__ __volatile__ ("fdivs %0, %0, %0" : "+f" (f));
|
||||||
|
}
|
||||||
tem = (fcw >> 23) & 0x1f;
|
if (exceptions & FP_EX_DIVZERO)
|
||||||
|
{
|
||||||
ou = exceptions & (FP_EX_OVERFLOW | FP_EX_UNDERFLOW);
|
float f = 1.0, g = 0.0;
|
||||||
if (ou & tem)
|
__asm__ __volatile__ ("fdivs %0, %1, %0"
|
||||||
exceptions &= ~FP_EX_INVALID;
|
: "+f" (f)
|
||||||
|
: "f" (g));
|
||||||
fcw &= ~0x1f;
|
}
|
||||||
fcw |= (exceptions | (exceptions << 5));
|
if (exceptions & FP_EX_OVERFLOW)
|
||||||
|
{
|
||||||
_FPU_SETCW(fcw);
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user