(feraiseexcept): Add delayed exception flushing, FE_UNDERFLOW is DBL_MIN/3.0,

FE_INEXACT is triggered by M_PI/69.69 converted to single precision.
This commit is contained in:
Ulrich Drepper 2003-12-18 03:58:09 +00:00
parent 1bff455e8a
commit 2da72a511e
1 changed files with 37 additions and 26 deletions

View File

@ -22,6 +22,9 @@
#include <float.h> #include <float.h>
#include <math.h> #include <math.h>
/* Please see section 10,
page 10-5 "Delayed Trapping" in the PA-RISC 2.0 Architecture manual */
int int
feraiseexcept (int excepts) feraiseexcept (int excepts)
{ {
@ -35,54 +38,62 @@ feraiseexcept (int excepts)
away something important, and so we can force delayed traps to away something important, and so we can force delayed traps to
occur. */ occur. */
/* FIXME: These all need verification! */ /* We use "fldd 0(%%sr0,%%sp),%0" to flush the delayed exception */
/* First: invalid exception. */ /* First: Invalid exception. */
if (excepts & FE_INVALID) if (excepts & FE_INVALID)
{ {
/* One example of a invalid operation is 0 * Infinity. */ /* One example of a invalid operation is 0 * Infinity. */
double d = HUGE_VAL; double d = HUGE_VAL;
__asm__ __volatile__ ("fmpy,dbl %1,%%fr0,%0\n\t" __asm__ __volatile__ (
/* FIXME: is this a proper trap barrier? */ " fcpy,dbl %%fr0,%%fr22\n"
"fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d)); " fmpy,dbl %0,%%fr22,%0\n"
" fldd 0(%%sr0,%%sp),%0"
: "+f" (d) : : "%fr22" );
} }
/* Next: division by zero. */ /* Second: Division by zero. */
if (excepts & FE_DIVBYZERO) if (excepts & FE_DIVBYZERO)
{ {
double d = 1.0; double d = 1.0;
__asm__ __volatile__ ("fdiv,dbl %1,%%fr0,%0\n\t" __asm__ __volatile__ (
"fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d)); " fcpy,dbl %%fr0,%%fr22\n"
" fdiv,dbl %0,%%fr22,%0\n"
" fldd 0(%%sr0,%%sp),%0"
: "+f" (d) : : "%fr22" );
} }
/* Next: overflow. */ /* Third: Overflow. */
/* FIXME: Compare with IA-64 - do we have the same problem? */
if (excepts & FE_OVERFLOW) if (excepts & FE_OVERFLOW)
{ {
double d = DBL_MAX; double d = DBL_MAX;
__asm__ __volatile__ (
__asm__ __volatile__ ("fmpy,dbl %1,%1,%0\n\t" " fadd,dbl %0,%0,%0\n"
"fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d)); " fldd 0(%%sr0,%%sp),%0"
: "+f" (d) );
} }
/* Next: underflow. */ /* Fourth: Underflow. */
if (excepts & FE_UNDERFLOW) if (excepts & FE_UNDERFLOW)
{ {
double d = DBL_MIN; double d = DBL_MIN;
double e = 69.69; double e = 3.0;
__asm__ __volatile__ (
__asm__ __volatile__ ("fdiv,dbl %1,%2,%0\n\t" " fdiv,dbl %0,%1,%0\n"
"fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d), "f" (e)); " fldd 0(%%sr0,%%sp),%0"
: "+f" (d) : "f" (e) );
} }
/* Last: inexact. */ /* Fifth: Inexact */
if (excepts & FE_INEXACT) if (excepts & FE_INEXACT)
{ {
double d = 1.0; double d = M_PI;
double e = M_PI; double e = 69.69;
__asm__ __volatile__ (
__asm__ __volatile__ ("fdiv,dbl %1,%2,%0\n\t" " fdiv,dbl %0,%1,%%fr22\n"
"fcpy,dbl %%fr0,%%fr0" : "=f" (d) : "0" (d), "f" (e)); " fcnvfxt,dbl,sgl %%fr22,%%fr22L\n"
" fldd 0(%%sr0,%%sp),%%fr22"
: : "f" (d), "f" (e) : "%fr22" );
} }
/* Success. */ /* Success. */