From b7434f8243547189c14e42559c09c14c41d521ad Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 20 Mar 2000 20:32:11 +0000 Subject: * sysdeps/alpha/fpu/fraiseexcpt.c: Use get/set_fp_control instead of arithmetic instructions. * sysdeps/alpha/fpu/s_ceil.c: Use round to -inf instead of playing with the fpcr. Protect from INV exception. * sysdeps/alpha/fpu/s_ceilf.c: Likewise. * sysdeps/alpha/fpu/s_floor.c: Protect from INV exception. * sysdeps/alpha/fpu/s_floorf.c: Likewise. * sysdeps/alpha/fpu/s_copysign.c: New. * sysdeps/alpha/fpu/s_copysignf.c: New. * sysdeps/alpha/fpu/s_fabs.c: New. * sysdeps/alpha/fpu/s_fabsf.c: New. * sysdeps/alpha/fpu/s_rint.c: New. * sysdeps/alpha/fpu/s_rintf.c: New. * sysdeps/alpha/fpu/fraiseexcpt.c: Use get/set_fp_control instead of arithmetic instructions. * sysdeps/alpha/fpu/s_ceil.c: Use round to -inf instead of playing with the fpcr. Protect from INV exception. * sysdeps/alpha/fpu/s_ceilf.c: Likewise. * sysdeps/alpha/fpu/s_floor.c: Protect from INV exception. * sysdeps/alpha/fpu/s_floorf.c: Likewise. * sysdeps/alpha/fpu/s_copysign.c: New. * sysdeps/alpha/fpu/s_copysignf.c: New. * sysdeps/alpha/fpu/s_fabs.c: New. * sysdeps/alpha/fpu/s_fabsf.c: New. * sysdeps/alpha/fpu/s_rint.c: New. * sysdeps/alpha/fpu/s_rintf.c: New. --- sysdeps/alpha/fpu/fraiseexcpt.c | 41 +++++++---------------------------------- 1 file changed, 7 insertions(+), 34 deletions(-) (limited to 'sysdeps/alpha/fpu/fraiseexcpt.c') 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; -- cgit v1.2.3