about summary refs log tree commit diff
path: root/sysdeps/alpha/fpu/fraiseexcpt.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/alpha/fpu/fraiseexcpt.c')
-rw-r--r--sysdeps/alpha/fpu/fraiseexcpt.c41
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;