]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
2007-03-01 Jakub Jelinek <jakub@redhat.com>
authorJakub Jelinek <jakub@redhat.com>
Thu, 12 Jul 2007 14:58:05 +0000 (14:58 +0000)
committerJakub Jelinek <jakub@redhat.com>
Thu, 12 Jul 2007 14:58:05 +0000 (14:58 +0000)
[BZ #4069]
* sysdeps/ieee754/dbl-64/e_pow.c (__ieee754_pow): Check for NaN
earlier.
* math/libm-test.inc (pow_test): Add more tests involving NaNs.

* sysdeps/i386/fpu/e_powf.S (__ieee754_powf): Avoid invalid exception
for x qNaN and y either +-inf or non-integer value.
* sysdeps/i386/fpu/e_pow.S (__ieee754_pow): Likewise.
* sysdeps/i386/fpu/e_powl.S (__ieee754_powl): Likewise.
* sysdeps/x86_64/fpu/e_powl.S (__ieee754_powl): Likewise.

ChangeLog
math/libm-test.inc
sysdeps/i386/fpu/e_pow.S
sysdeps/i386/fpu/e_powf.S
sysdeps/i386/fpu/e_powl.S
sysdeps/ieee754/dbl-64/e_pow.c
sysdeps/x86_64/fpu/e_powl.S

index 431be14395bb43d0f6b27a4cc86602554f9343d1..8b32d0ae82d411bab24b280d354994007a2aaa00 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2007-03-01  Jakub Jelinek  <jakub@redhat.com>
+
+       [BZ #4069]
+       * sysdeps/ieee754/dbl-64/e_pow.c (__ieee754_pow): Check for NaN
+       earlier.
+       * math/libm-test.inc (pow_test): Add more tests involving NaNs.
+
+       * sysdeps/i386/fpu/e_powf.S (__ieee754_powf): Avoid invalid exception
+       for x qNaN and y either +-inf or non-integer value.
+       * sysdeps/i386/fpu/e_pow.S (__ieee754_pow): Likewise.
+       * sysdeps/i386/fpu/e_powl.S (__ieee754_powl): Likewise.
+       * sysdeps/x86_64/fpu/e_powl.S (__ieee754_powl): Likewise.
+
 2007-02-21  Ulrich Drepper  <drepper@redhat.com>
 
        [BZ #4076]
index 23ee6beaa8aa831c9d95d8490f54f76a816a20c7..972309f85f0ee37aa19827f1a85db613fef51234 100644 (file)
@@ -4614,6 +4614,17 @@ pow_test (void)
 
   /* pow (x, NaN) == NaN.  */
   TEST_ff_f (pow, 3.0, nan_value, nan_value);
+  TEST_ff_f (pow, minus_zero, nan_value, nan_value);
+  TEST_ff_f (pow, plus_infty, nan_value, nan_value);
+  TEST_ff_f (pow, -3.0, nan_value, nan_value);
+  TEST_ff_f (pow, minus_infty, nan_value, nan_value);
+
+  TEST_ff_f (pow, nan_value, 3.0, nan_value);
+  TEST_ff_f (pow, nan_value, -3.0, nan_value);
+  TEST_ff_f (pow, nan_value, plus_infty, nan_value);
+  TEST_ff_f (pow, nan_value, minus_infty, nan_value);
+  TEST_ff_f (pow, nan_value, 2.5, nan_value);
+  TEST_ff_f (pow, nan_value, -2.5, nan_value);
 
   TEST_ff_f (pow, 1, plus_infty, 1);
   TEST_ff_f (pow, -1, plus_infty, 1);
index c554ca4ecbb0ece6be0edf25a6523bb475ddb83a..4f287be1dd960a6bbff24df7353da7897e348c22 100644 (file)
@@ -161,10 +161,11 @@ ENTRY(__ieee754_pow)
 2:     /* y is a real number.  */
        fxch                    // x : y
        fldl    MO(one)         // 1.0 : x : y
-       fld     %st(1)          // x : 1.0 : x : y
-       fsub    %st(1)          // x-1 : 1.0 : x : y
-       fabs                    // |x-1| : 1.0 : x : y
-       fcompl  MO(limit)       // 1.0 : x : y
+       fldl    MO(limit)       // 0.29 : 1.0 : x : y
+       fld     %st(2)          // x : 0.29 : 1.0 : x : y
+       fsub    %st(2)          // x-1 : 0.29 : 1.0 : x : y
+       fabs                    // |x-1| : 0.29 : 1.0 : x : y
+       fucompp                 // 1.0 : x : y
        fnstsw
        fxch                    // x : 1.0 : y
        sahf
@@ -197,9 +198,10 @@ ENTRY(__ieee754_pow)
        // y == ±inf
        .align ALIGNARG(4)
 12:    fstp    %st(0)          // pop y
-       fldl    4(%esp)         // x
-       fabs
-       fcompl  MO(one)         // < 1, == 1, or > 1
+       fldl    MO(one)         // 1
+       fldl    4(%esp)         // x : 1
+       fabs                    // abs(x) : 1
+       fucompp                 // < 1, == 1, or > 1
        fnstsw
        andb    $0x45, %ah
        cmpb    $0x45, %ah
index c835b978b9fce6fc5c95511f523f88331ccd016f..63368ac0bf2908c23c0833befb224c814266af1b 100644 (file)
@@ -155,10 +155,11 @@ ENTRY(__ieee754_powf)
 2:     /* y is a real number.  */
        fxch                    // x : y
        fldl    MO(one)         // 1.0 : x : y
-       fld     %st(1)          // x : 1.0 : x : y
-       fsub    %st(1)          // x-1 : 1.0 : x : y
-       fabs                    // |x-1| : 1.0 : x : y
-       fcompl  MO(limit)       // 1.0 : x : y
+       fldl    MO(limit)       // 0.29 : 1.0 : x : y
+       fld     %st(2)          // x : 0.29 : 1.0 : x : y
+       fsub    %st(2)          // x-1 : 0.29 : 1.0 : x : y
+       fabs                    // |x-1| : 0.29 : 1.0 : x : y
+       fucompp                 // 1.0 : x : y
        fnstsw
        fxch                    // x : 1.0 : y
        sahf
@@ -191,9 +192,10 @@ ENTRY(__ieee754_powf)
        // y == ±inf
        .align ALIGNARG(4)
 12:    fstp    %st(0)          // pop y
-       flds    4(%esp)         // x
-       fabs
-       fcompl  MO(one)         // < 1, == 1, or > 1
+       fldl    MO(one)         // 1
+       flds    4(%esp)         // x : 1
+       fabs                    // abs(x) : 1
+       fucompp                 // < 1, == 1, or > 1
        fnstsw
        andb    $0x45, %ah
        cmpb    $0x45, %ah
index 74f422816a4d31a6f9a47ec5f29a4ecda2397272..ec80eb8ae38e53a7428bfd3d89732bbad91e7a86 100644 (file)
@@ -161,10 +161,11 @@ ENTRY(__ieee754_powl)
 2:     /* y is a real number.  */
        fxch                    // x : y
        fldl    MO(one)         // 1.0 : x : y
-       fld     %st(1)          // x : 1.0 : x : y
-       fsub    %st(1)          // x-1 : 1.0 : x : y
-       fabs                    // |x-1| : 1.0 : x : y
-       fcompl  MO(limit)       // 1.0 : x : y
+       fldl    MO(limit)       // 0.29 : 1.0 : x : y
+       fld     %st(2)          // x : 0.29 : 1.0 : x : y
+       fsub    %st(2)          // x-1 : 0.29 : 1.0 : x : y
+       fabs                    // |x-1| : 0.29 : 1.0 : x : y
+       fucompp                 // 1.0 : x : y
        fnstsw
        fxch                    // x : 1.0 : y
        sahf
@@ -210,9 +211,10 @@ ENTRY(__ieee754_powl)
        // y == ±inf
        .align ALIGNARG(4)
 12:    fstp    %st(0)          // pop y
-       fldt    4(%esp)         // x
-       fabs
-       fcompl  MO(one)         // < 1, == 1, or > 1
+       fldl    MO(one)         // 1
+       fldt    4(%esp)         // x : 1
+       fabs                    // abs(x) : 1
+       fucompp                 // < 1, == 1, or > 1
        fnstsw
        andb    $0x45, %ah
        cmpb    $0x45, %ah
index d9bd8b479f4aa8dce3a4e476575f5848b69499b0..1e159f2c0b2702682bca759b4ffa9cbaf503c1c9 100644 (file)
@@ -106,20 +106,28 @@ double __ieee754_pow(double x, double y) {
     else
       return y < 0 ? 1.0/ABS(x) : 0.0;                               /* return 0 */
   }
+
+  qx = u.i[HIGH_HALF]&0x7fffffff;  /*   no sign   */
+  qy = v.i[HIGH_HALF]&0x7fffffff;  /*   no sign   */
+
+  if (qx >= 0x7ff00000 && (qx > 0x7ff00000 || u.i[LOW_HALF] != 0)) return NaNQ.x;
+  if (qy >= 0x7ff00000 && (qy > 0x7ff00000 || v.i[LOW_HALF] != 0))
+    return x == 1.0 ? 1.0 : NaNQ.x;
+
   /* if x<0 */
   if (u.i[HIGH_HALF] < 0) {
     k = checkint(y);
     if (k==0) {
-      if ((v.i[HIGH_HALF] & 0x7fffffff) == 0x7ff00000 && v.i[LOW_HALF] == 0) {
+      if (qy == 0x7ff00000) {
        if (x == -1.0) return 1.0;
        else if (x > -1.0) return v.i[HIGH_HALF] < 0 ? INF.x : 0.0;
        else return v.i[HIGH_HALF] < 0 ? 0.0 : INF.x;
       }
-      else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0)
+      else if (qx == 0x7ff00000)
        return y < 0 ? 0.0 : INF.x;
       return NaNQ.x;                              /* y not integer and x<0 */
     }
-    else if (u.i[HIGH_HALF] == 0xfff00000 && u.i[LOW_HALF] == 0)
+    else if (qx == 0x7ff00000)
       {
        if (k < 0)
          return y < 0 ? nZERO.x : nINF.x;
@@ -129,14 +137,6 @@ double __ieee754_pow(double x, double y) {
     return (k==1)?__ieee754_pow(-x,y):-__ieee754_pow(-x,y); /* if y even or odd */
   }
   /* x>0 */
-  qx = u.i[HIGH_HALF]&0x7fffffff;  /*   no sign   */
-  qy = v.i[HIGH_HALF]&0x7fffffff;  /*   no sign   */
-
-  if (qx > 0x7ff00000 || (qx == 0x7ff00000 && u.i[LOW_HALF] != 0)) return NaNQ.x;
-                                                                 /*  if 0<x<2^-0x7fe */
-  if (qy > 0x7ff00000 || (qy == 0x7ff00000 && v.i[LOW_HALF] != 0))
-    return x == 1.0 ? 1.0 : NaNQ.x;
-                                                                 /*  if y<2^-0x7fe   */
 
   if (qx == 0x7ff00000)                              /* x= 2^-0x3ff */
     {if (y == 0) return NaNQ.x;
index 85f4deb3c7e0772db16c8dd5f5a0a061c6906aaf..623fb4c417dd27c890159fb66f139c18a3076bcd 100644 (file)
@@ -146,10 +146,11 @@ ENTRY(__ieee754_powl)
 2:     /* y is a real number.  */
        fxch                    // x : y
        fldl    MO(one)         // 1.0 : x : y
-       fld     %st(1)          // x : 1.0 : x : y
-       fsub    %st(1)          // x-1 : 1.0 : x : y
-       fabs                    // |x-1| : 1.0 : x : y
-       fcompl  MO(limit)       // 1.0 : x : y
+       fldl    MO(limit)       // 0.29 : 1.0 : x : y
+       fld     %st(2)          // x : 0.29 : 1.0 : x : y
+       fsub    %st(2)          // x-1 : 0.29 : 1.0 : x : y
+       fabs                    // |x-1| : 0.29 : 1.0 : x : y
+       fucompp                 // 1.0 : x : y
        fnstsw
        fxch                    // x : 1.0 : y
        test    $4500,%eax
@@ -190,9 +191,10 @@ ENTRY(__ieee754_powl)
        // y == ±inf
        .align ALIGNARG(4)
 12:    fstp    %st(0)          // pop y
-       fldt    8(%rsp)         // x
-       fabs
-       fcompl  MO(one)         // < 1, == 1, or > 1
+       fldl    MO(one)         // 1
+       fldt    8(%rsp)         // x : 1
+       fabs                    // abs(x) : 1
+       fucompp                 // < 1, == 1, or > 1
        fnstsw
        andb    $0x45, %ah
        cmpb    $0x45, %ah