diff options
Diffstat (limited to 'sysdeps/alpha/fpu/fraiseexcpt.c')
-rw-r--r-- | sysdeps/alpha/fpu/fraiseexcpt.c | 41 |
1 files changed, 7 insertions, 34 deletions
diff --git a/sysdeps/alpha/fpu/fraiseexcpt.c b/sysdeps/alpha/fpu/fraiseexcpt.c index a3e60d02eb..b0eab000cb 100644 --- a/sysdeps/alpha/fpu/fraiseexcpt.c +++ b/sysdeps/alpha/fpu/fraiseexcpt.c @@ -24,43 +24,16 @@ int __feraiseexcept (int excepts) { - double tmp; - double dummy; + unsigned long int tmp; - /* Raise exceptions represented by EXPECTS. But we must raise only - one signal at a time. It is important the if the overflow/underflow - exception and the inexact exception are given at the same time, - the overflow/underflow exception precedes the inexact exception. */ + /* Get the current exception state. */ + tmp = __ieee_get_fp_control (); - /* We do these bits in assembly to be certain GCC doesn't optimize - away something important. */ + /* Set all the bits that were called for. */ + tmp |= (excepts & FE_ALL_EXCEPT); - /* First: invalid exception. */ - if (FE_INVALID & excepts) - /* One example of a invalid operation is 0 * Infinity. */ - __asm__ __volatile__("mult/sui $f31,%1,%0; trapb" - : "=&f" (tmp) : "f" (HUGE_VAL)); - - /* Next: division by zero. */ - if (FE_DIVBYZERO & excepts) - __asm__ __volatile__("cmpteq $f31,$f31,%1; divt/sui %1,$f31,%0; trapb" - : "=&f" (tmp), "=f" (dummy)); - - /* Next: overflow. */ - if (FE_OVERFLOW & excepts) - __asm__ __volatile__("mult/sui %1,%1,%0; trapb" - : "=&f" (tmp) : "f" (DBL_MAX)); - - /* Next: underflow. */ - if (FE_UNDERFLOW & excepts) - __asm__ __volatile__("divt/sui %1,%2,%0; trapb" - : "=&f" (tmp) : "f" (DBL_MIN), - "f" ((double) (1UL << 60))); - - /* Last: inexact. */ - if (FE_INEXACT & excepts) - __asm__ __volatile__("divt/sui %1,%2,%0; trapb" - : "=&f" (tmp) : "f" (1.0), "f" (M_PI)); + /* And store it back. */ + __ieee_set_fp_control (tmp); /* Success. */ return 0; |