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:
David S. Miller 2012-05-30 23:09:25 -07:00
parent 0e20515a17
commit 1c58d5dceb
3 changed files with 76 additions and 30 deletions

View File

@ -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>
[BZ #14117]

View File

@ -19,25 +19,44 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <float.h>
#include <math.h>
#include <assert.h>
#include "soft-fp.h"
unsigned long long ___Q_zero = 0x0000000000000000ULL;
void ___Q_simulate_exceptions(int exceptions)
{
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);
if (exceptions & FP_EX_INVALID)
{
float f = 0.0;
__asm__ __volatile__ ("fdivs %0, %0, %0" : "+f" (f));
}
if (exceptions & FP_EX_DIVZERO)
{
float f = 1.0, g = 0.0;
__asm__ __volatile__ ("fdivs %0, %1, %0"
: "+f" (f)
: "f" (g));
}
if (exceptions & FP_EX_OVERFLOW)
{
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));
}
}

View File

@ -19,23 +19,42 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <float.h>
#include <math.h>
#include <assert.h>
#include "soft-fp.h"
void __Qp_handle_exceptions(int exceptions)
{
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);
if (exceptions & FP_EX_INVALID)
{
float f = 0.0;
__asm__ __volatile__ ("fdivs %0, %0, %0" : "+f" (f));
}
if (exceptions & FP_EX_DIVZERO)
{
float f = 1.0, g = 0.0;
__asm__ __volatile__ ("fdivs %0, %1, %0"
: "+f" (f)
: "f" (g));
}
if (exceptions & FP_EX_OVERFLOW)
{
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));
}
}