File libm-x86-64-exceptions.diff of Package glibc

Index: sysdeps/x86_64/fpu/libm_inlines_amd.h
===================================================================
--- sysdeps/x86_64/fpu/libm_inlines_amd.h.orig
+++ sysdeps/x86_64/fpu/libm_inlines_amd.h
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
+(C) 2002, 2009 Advanced Micro Devices, Inc. 
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH 
     THIS LIBRARY**
 */
 
@@ -254,6 +254,33 @@ static inline void clear_fpsw_flags(int
 
 
 #if defined(USE_RAISE_FPSW_FLAGS)
+static inline void raise_fp_exc(int flags)
+{
+    if((flags & AMD_F_UNDERFLOW) == AMD_F_UNDERFLOW)
+    {
+        double a = 0x1.0p-1022;
+        __asm __volatile ("mulsd %1, %0" :  "+x" (a));
+    }
+
+    if((flags & AMD_F_OVERFLOW) == AMD_F_OVERFLOW)
+    {
+        double a = 0x1.fffffffffffffp1023;
+        __asm __volatile ("mulsd %1, %0" :  "+x" (a));
+    }
+
+    if((flags & AMD_F_DIVBYZERO) == AMD_F_DIVBYZERO)
+    {
+        double a = 1.0, b = 0.0;
+        __asm __volatile ("divsd %1, %0" :  "+x" (a) : "x" (b));
+    }
+
+    if((flags & AMD_F_INVALID) == AMD_F_INVALID)
+    {
+        double a = 0.0;
+        __asm __volatile ("divsd %1, %0" :  "+x" (a));
+    }
+}
+
 /* Raises floating-point status flags. The argument should be
    the bitwise or of the flags to be raised, from the
    list above, e.g.
@@ -269,11 +296,7 @@ static inline void raise_fpsw_flags(int
   /* Put the floating-point environment back */
   __asm fldenv fenv;
 #elif defined(linux)
-  unsigned int cw;
-  /* Get the current floating-point control/status word */
-  asm volatile ("STMXCSR %0" : "=m" (cw));
-  cw |= flags;
-  asm volatile ("LDMXCSR %0" : : "m" (cw));
+  raise_fp_exc(flags);
 #else
 #error Unknown machine
 #endif
Index: sysdeps/x86_64/fpu/s_atan2.c
===================================================================
--- sysdeps/x86_64/fpu/s_atan2.c.orig
+++ sysdeps/x86_64/fpu/s_atan2.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
+(C) 2002, 2009 Advanced Micro Devices, Inc. 
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH 
     THIS LIBRARY**
 */
 
@@ -595,6 +595,14 @@ double __atan2(double y, double x)
       if (yneg) return val_with_flags(-piby2,AMD_F_INEXACT);
       else val_with_flags(piby2,AMD_F_INEXACT);
     }
+   else if((!xneg) && xinf && (!yinf) && (!yzero))
+            {
+                if(yneg)
+                     return -0.0;
+                else
+                      return 0.0;
+            }
+
 
   /* Scale up both x and y if they are both below 1/4.
      This avoids any possible later denormalised arithmetic. */
Index: sysdeps/x86_64/fpu/s_atan2f.c
===================================================================
--- sysdeps/x86_64/fpu/s_atan2f.c.orig
+++ sysdeps/x86_64/fpu/s_atan2f.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
+(C) 2002, 2009 Advanced Micro Devices, Inc. 
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH 
     THIS LIBRARY**
 */
 
@@ -349,6 +349,14 @@ float __atan2f(float fy, float fx)
       if (yneg) return val_with_flags(-piby2,AMD_F_INEXACT);
       else val_with_flags(piby2,AMD_F_INEXACT);
     }
+    else if((!xneg) && xinf && (!yinf) && (!yzero))
+        {
+           if(yneg)
+              return -0.0;
+           else
+              return 0.0;
+         }
+
 
   if (diffexp > 26)
     { /* abs(y)/abs(x) > 2^26 => arctan(x/y) 
Index: sysdeps/x86_64/fpu/s_atan.c
===================================================================
--- sysdeps/x86_64/fpu/s_atan.c.orig
+++ sysdeps/x86_64/fpu/s_atan.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc.
+(C) 2002, 2009 Advanced Micro Devices, Inc.
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH
     THIS LIBRARY**
 */
 
@@ -67,7 +67,7 @@ double __atan (double x)
       if (aux == 0)  /* if x=0, then result is precise */
           return x;
       else
-          return val_with_flags(x, AMD_F_INEXACT);
+          return val_with_flags(x, AMD_F_INEXACT | AMD_F_UNDERFLOW);
   }
 
   /* Argument reduction to range [-7/16,7/16] */
Index: sysdeps/x86_64/fpu/s_atanf.c
===================================================================
--- sysdeps/x86_64/fpu/s_atanf.c.orig
+++ sysdeps/x86_64/fpu/s_atanf.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc.
+(C) 2002, 2009 Advanced Micro Devices, Inc.
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH
     THIS LIBRARY**
 */
 
@@ -68,7 +68,7 @@ float __atanf (float fx)
       if (aux == 0)  /* if x=0, then result is precise */
           return fx;
       else
-          return valf_with_flags(fx, AMD_F_INEXACT);
+          return valf_with_flags(fx, AMD_F_INEXACT | AMD_F_UNDERFLOW);
   }
 
   v = x;
Index: sysdeps/x86_64/fpu/s_sincos.c
===================================================================
--- sysdeps/x86_64/fpu/s_sincos.c.orig
+++ sysdeps/x86_64/fpu/s_sincos.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
-** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
-    AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+(C) 2002, 2009 Advanced Micro Devices, Inc.
+** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS
+    AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH
     THIS LIBRARY**
 */
 
@@ -97,7 +97,7 @@ void __sincos(double x, double *s, doubl
                 }
               else
                 {
-                  *s = x;
+                  *s = val_with_flags(x, AMD_F_INEXACT);
                   *c = val_with_flags(1.0, AMD_F_INEXACT);
                 }
 	    }
Index: sysdeps/x86_64/fpu/s_sincosf.c
===================================================================
--- sysdeps/x86_64/fpu/s_sincosf.c.orig
+++ sysdeps/x86_64/fpu/s_sincosf.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
-** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
-    AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+(C) 2002 Advanced Micro Devices, Inc.
+** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS
+    AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC
+    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH
     THIS LIBRARY**
 */
 
Index: sysdeps/x86_64/fpu/s_tanf.c
===================================================================
--- sysdeps/x86_64/fpu/s_tanf.c.orig
+++ sysdeps/x86_64/fpu/s_tanf.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
-** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
-    AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+(C) 2002 Advanced Micro Devices, Inc.
+** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS
+    AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC
+    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH
     THIS LIBRARY**
 */
 
@@ -18,7 +18,7 @@
 #undef USE_NAN_WITH_FLAGS
 #undef USE_REMAINDER_PIBY2F_INLINE
 
-/* tan(x) approximation valid on the interval [-pi/4,pi/4]. 
+/* tan(x) approximation valid on the interval [-pi/4,pi/4].
    If recip is true return -1/tan(x) instead. */
 static inline double tanf_piby4(double x, int recip)
 {
Index: sysdeps/x86_64/fpu/w_asin.c
===================================================================
--- sysdeps/x86_64/fpu/w_asin.c.orig
+++ sysdeps/x86_64/fpu/w_asin.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
+(C) 2002, 2009 Advanced Micro Devices, Inc. 
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH 
     THIS LIBRARY**
 */
 
@@ -76,7 +76,8 @@ double __asin(double x)
 
   if (xexp < -28)
     { /* y small enough that arcsin(x) = x */
-      return val_with_flags(x, AMD_F_INEXACT);
+	if(aux == 0) return x;
+	return val_with_flags(x, AMD_F_INEXACT | AMD_F_UNDERFLOW);
     }
   else if (xnan) return x + x;
   else if (xexp >= 0) 
Index: sysdeps/x86_64/fpu/w_asinf.c
===================================================================
--- sysdeps/x86_64/fpu/w_asinf.c.orig
+++ sysdeps/x86_64/fpu/w_asinf.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
+(C) 2002, 2009 Advanced Micro Devices, Inc. 
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH 
     THIS LIBRARY**
 */
 
@@ -75,8 +75,11 @@ float __asinf(float x)
   /* Special cases */
 
   if (xexp < -14)
+   {
     /* y small enough that arcsin(x) = x */
-    return valf_with_flags(x, AMD_F_INEXACT);
+    if(aux == 0 ) return x;   	
+    return valf_with_flags(x, AMD_F_INEXACT | AMD_F_UNDERFLOW);
+   }
   else if (xnan) return x + x;
   else if (xexp >= 0) 
     {
Index: sysdeps/x86_64/fpu/w_hypotf.c
===================================================================
--- sysdeps/x86_64/fpu/w_hypotf.c.orig
+++ sysdeps/x86_64/fpu/w_hypotf.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
+(C) 2002, 2009 Advanced Micro Devices, Inc. 
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH 
     THIS LIBRARY**
 */
 
@@ -79,6 +79,20 @@ float __hypotf(float x, float y)
         return retval;
     }
 
+  /* Set x = abs(x) and y = abs(y) */
+  if (ux == 0)
+  {
+    /* x is zero */
+    PUT_BITS_DP64(avy, dy);
+    return dy;
+  }
+  if (uy == 0)
+  {
+    /* y is zero */
+    PUT_BITS_DP64(avx, dx);
+    return dx;
+  }
+
     dr = (dx*dx + dy*dy);
 
 #if USE_SOFTWARE_SQRT
Index: sysdeps/x86_64/fpu/w_pow.c
===================================================================
--- sysdeps/x86_64/fpu/w_pow.c.orig
+++ sysdeps/x86_64/fpu/w_pow.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
+(C) 2002, 2009 Advanced Micro Devices, Inc. 
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH 
     THIS LIBRARY**
 */
 
@@ -364,8 +364,20 @@ double __pow(double x, double y)
         {
           /* y is -ve */
           if (ax == 0)
-            /* abs(x) = 0.0. Return +infinity. */
-            return retval_errno_edom(argx, argy, 1);
+          {
+            if(yinf)
+            {
+                /* Return +infinity with no flags */
+                double sz;
+                PUT_BITS_DP64(PINFBITPATT_DP64, sz);
+                return sz;
+            }
+            else
+            {
+                /* abs(x) = 0.0. Return +infinity. */
+                return retval_errno_edom(argx, argy, 1);
+            }
+          }
           else if (ax < 0x3ff0000000000000)
             {
             /* abs(x) < 1.0; return +infinity. */
Index: sysdeps/x86_64/fpu/w_powf.c
===================================================================
--- sysdeps/x86_64/fpu/w_powf.c.orig
+++ sysdeps/x86_64/fpu/w_powf.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
+(C) 2002, 2009 Advanced Micro Devices, Inc. 
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH 
     THIS LIBRARY**
 */
 
@@ -175,8 +175,20 @@ float __powf(float x, float y)
         {
           /* y is -ve */
           if (ax == 0)
-            /* abs(x) = 0.0. Return +infinity. */
-            return retval_errno_edom(x, y, 1);
+          {
+            if(yinf)
+            {
+                /* Return +infinity with no flags */
+                float sz;
+                PUT_BITS_SP32(PINFBITPATT_SP32, sz);
+                return sz;
+            }
+            else
+            {
+                /* abs(x) = 0.0. Return +infinity. */
+                return retval_errno_edom(x, y, 1);
+            }
+          }
           else if (ax < 0x3f800000)
 	    {
             /* abs(x) < 1.0; return +infinity. */
Index: sysdeps/x86_64/fpu/w_remainder.c
===================================================================
--- sysdeps/x86_64/fpu/w_remainder.c.orig
+++ sysdeps/x86_64/fpu/w_remainder.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
+(C) 2002, 2009 Advanced Micro Devices, Inc. 
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH 
     THIS LIBRARY**
 */
 
@@ -69,11 +69,31 @@ double __remainder(double x, double y)
         {
           /* x is NaN or infinity */
           if (ux & MANTBITS_DP64)
-            /* x is NaN */
-            return dx + dx; /* Raise invalid if it is a signalling NaN */
+          {
+            if( (yexp > BIASEDEMAX_DP64) && (uy & MANTBITS_DP64) )
+            {
+                /* y is also NaN */
+                return dx + dy;
+            }
+            else
+            {
+                /* x is NaN */
+                return dx + dx; /* Raise invalid if it is a signalling NaN */
+            }
+          }
           else
-            /* x is infinity; result is NaN */
-            return nan_with_flags(AMD_F_INVALID);
+          {
+            if((yexp > BIASEDEMAX_DP64) && (uy & MANTBITS_DP64))
+            {
+                /* y is NaN */
+                return dy+dy;
+            }
+            else
+            {
+                /* x is infinity; result is NaN */
+                return nan_with_flags(AMD_F_INVALID);
+            }
+          }
         }
       else if (yexp > BIASEDEMAX_DP64)
         {
Index: sysdeps/x86_64/fpu/w_remainderf.c
===================================================================
--- sysdeps/x86_64/fpu/w_remainderf.c.orig
+++ sysdeps/x86_64/fpu/w_remainderf.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
+(C) 2002, 2009 Advanced Micro Devices, Inc. 
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH 
     THIS LIBRARY**
 */
 
@@ -50,11 +50,31 @@ float __remainderf(float x, float y)
         {
           /* x is NaN or infinity */
           if (ux & MANTBITS_DP64)
-            /* x is NaN */
-            return dx + dx; /* Raise invalid if it is a signalling NaN */
+          {
+            if((yexp > BIASEDEMAX_DP64) && (uy & MANTBITS_DP64))
+            {
+                /* y is also NaN */
+                return dx + dy;
+            }
+            else
+            {
+                /* x is NaN */
+                return dx + dx; /* Raise invalid if it is a signalling NaN */
+            }
+          }
           else
-            /* x is infinity; result is NaN */
-            return nan_with_flags(AMD_F_INVALID);
+          {
+            if((yexp > BIASEDEMAX_DP64) && (uy & MANTBITS_DP64))
+            {
+                /* y is NaN */
+                return dy+dy;
+            }
+            else
+            {
+                /* x is infinity; result is NaN */
+                return nan_with_flags(AMD_F_INVALID);
+            }
+          }
         }
       else if (yexp > BIASEDEMAX_DP64)
         {
Index: sysdeps/x86_64/fpu/w_sinh.c
===================================================================
--- sysdeps/x86_64/fpu/w_sinh.c.orig
+++ sysdeps/x86_64/fpu/w_sinh.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
+(C) 2002, 2009 Advanced Micro Devices, Inc. 
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH 
     THIS LIBRARY**
 */
 
@@ -249,7 +249,7 @@ double __sinh(double x)
         /* with no inexact */
         return x;
       else
-        return val_with_flags(x, AMD_F_INEXACT);
+        return val_with_flags(x, AMD_F_INEXACT | AMD_F_UNDERFLOW);
     }
   else if (aux >= 0x7ff0000000000000) /* |x| is NaN or Inf */
     return x + x;
Index: sysdeps/x86_64/fpu/w_sinhf.c
===================================================================
--- sysdeps/x86_64/fpu/w_sinhf.c.orig
+++ sysdeps/x86_64/fpu/w_sinhf.c
@@ -1,8 +1,8 @@
 /*
-(C) 2002 Advanced Micro Devices, Inc. 
+(C) 2002, 2009 Advanced Micro Devices, Inc. 
 ** YOUR USE OF THIS LIBRARY IS SUBJECT TO THE TERMS 
     AND CONDITIONS OF THE GNU LESSER GENERAL PUBLIC 
-    LICENSE FOUND IN THE "README" FILE THAT IS INCLUDED WITH 
+    LICENSE FOUND IN THE "LICENSE" FILE THAT IS INCLUDED WITH 
     THIS LIBRARY**
 */
 
@@ -13,11 +13,13 @@
 #define USE_SCALEDOUBLE_1
 #define USE_SCALEDOUBLE_2
 #define USE_INFINITY_WITH_FLAGS
+#define USE_VAL_WITH_FLAGS
 #include "libm_inlines_amd.h"
 #undef USE_SPLITEXP
 #undef USE_SCALEDOUBLE_1
 #undef USE_SCALEDOUBLE_2
 #undef USE_INFINITY_WITH_FLAGS
+#undef USE_VAL_WITH_FLAGS
 
 /* Deal with errno for out-of-range result */
 #include "libm_errno_amd.h"
@@ -166,7 +168,8 @@ float __sinhf(float fx)
   if (aux < 0x3f10000000000000) /* |x| small enough that sinh(x) = x */
     {
       if (aux == 0) return x; /* with no inexact */
-      if (LAMBDA_DP64 + x  > 1.0) return x; /* with inexact */
+      else  
+	return val_with_flags(x, AMD_F_INEXACT | AMD_F_UNDERFLOW); /* with inexact */
     }
   else if (aux >= 0x7ff0000000000000) /* |x| is NaN or Inf */
     return x + x;
openSUSE Build Service is sponsored by