mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-27 03:41:23 +08:00
[BZ #4096]
2007-03-01 Jakub Jelinek <jakub@redhat.com> [BZ #4096] * 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.
This commit is contained in:
parent
245a1481d7
commit
8f3edfee15
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
|||||||
|
2007-03-01 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
[BZ #4096]
|
||||||
|
* 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-10 Mike Frysinger <vapier@gentoo.org>
|
2007-02-10 Mike Frysinger <vapier@gentoo.org>
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/sh/Makefile: Remove sys/io.h
|
* sysdeps/unix/sysv/linux/sh/Makefile: Remove sys/io.h
|
||||||
|
@ -4614,6 +4614,17 @@ pow_test (void)
|
|||||||
|
|
||||||
/* pow (x, NaN) == NaN. */
|
/* pow (x, NaN) == NaN. */
|
||||||
TEST_ff_f (pow, 3.0, nan_value, nan_value);
|
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);
|
||||||
TEST_ff_f (pow, -1, plus_infty, 1);
|
TEST_ff_f (pow, -1, plus_infty, 1);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ix87 specific implementation of pow function.
|
/* ix87 specific implementation of pow function.
|
||||||
Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005
|
Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005, 2007
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||||
@ -161,10 +161,11 @@ ENTRY(__ieee754_pow)
|
|||||||
2: /* y is a real number. */
|
2: /* y is a real number. */
|
||||||
fxch // x : y
|
fxch // x : y
|
||||||
fldl MO(one) // 1.0 : x : y
|
fldl MO(one) // 1.0 : x : y
|
||||||
fld %st(1) // x : 1.0 : x : y
|
fldl MO(limit) // 0.29 : 1.0 : x : y
|
||||||
fsub %st(1) // x-1 : 1.0 : x : y
|
fld %st(2) // x : 0.29 : 1.0 : x : y
|
||||||
fabs // |x-1| : 1.0 : x : y
|
fsub %st(2) // x-1 : 0.29 : 1.0 : x : y
|
||||||
fcompl MO(limit) // 1.0 : x : y
|
fabs // |x-1| : 0.29 : 1.0 : x : y
|
||||||
|
fucompp // 1.0 : x : y
|
||||||
fnstsw
|
fnstsw
|
||||||
fxch // x : 1.0 : y
|
fxch // x : 1.0 : y
|
||||||
sahf
|
sahf
|
||||||
@ -197,9 +198,10 @@ ENTRY(__ieee754_pow)
|
|||||||
// y == ±inf
|
// y == ±inf
|
||||||
.align ALIGNARG(4)
|
.align ALIGNARG(4)
|
||||||
12: fstp %st(0) // pop y
|
12: fstp %st(0) // pop y
|
||||||
fldl 4(%esp) // x
|
fldl MO(one) // 1
|
||||||
fabs
|
fldl 4(%esp) // x : 1
|
||||||
fcompl MO(one) // < 1, == 1, or > 1
|
fabs // abs(x) : 1
|
||||||
|
fucompp // < 1, == 1, or > 1
|
||||||
fnstsw
|
fnstsw
|
||||||
andb $0x45, %ah
|
andb $0x45, %ah
|
||||||
cmpb $0x45, %ah
|
cmpb $0x45, %ah
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ix87 specific implementation of pow function.
|
/* ix87 specific implementation of pow function.
|
||||||
Copyright (C) 1996, 1997, 1999, 2001, 2004, 2005
|
Copyright (C) 1996, 1997, 1999, 2001, 2004, 2005, 2007
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||||
@ -155,10 +155,11 @@ ENTRY(__ieee754_powf)
|
|||||||
2: /* y is a real number. */
|
2: /* y is a real number. */
|
||||||
fxch // x : y
|
fxch // x : y
|
||||||
fldl MO(one) // 1.0 : x : y
|
fldl MO(one) // 1.0 : x : y
|
||||||
fld %st(1) // x : 1.0 : x : y
|
fldl MO(limit) // 0.29 : 1.0 : x : y
|
||||||
fsub %st(1) // x-1 : 1.0 : x : y
|
fld %st(2) // x : 0.29 : 1.0 : x : y
|
||||||
fabs // |x-1| : 1.0 : x : y
|
fsub %st(2) // x-1 : 0.29 : 1.0 : x : y
|
||||||
fcompl MO(limit) // 1.0 : x : y
|
fabs // |x-1| : 0.29 : 1.0 : x : y
|
||||||
|
fucompp // 1.0 : x : y
|
||||||
fnstsw
|
fnstsw
|
||||||
fxch // x : 1.0 : y
|
fxch // x : 1.0 : y
|
||||||
sahf
|
sahf
|
||||||
@ -191,9 +192,10 @@ ENTRY(__ieee754_powf)
|
|||||||
// y == ±inf
|
// y == ±inf
|
||||||
.align ALIGNARG(4)
|
.align ALIGNARG(4)
|
||||||
12: fstp %st(0) // pop y
|
12: fstp %st(0) // pop y
|
||||||
flds 4(%esp) // x
|
fldl MO(one) // 1
|
||||||
fabs
|
flds 4(%esp) // x : 1
|
||||||
fcompl MO(one) // < 1, == 1, or > 1
|
fabs // abs(x) : 1
|
||||||
|
fucompp // < 1, == 1, or > 1
|
||||||
fnstsw
|
fnstsw
|
||||||
andb $0x45, %ah
|
andb $0x45, %ah
|
||||||
cmpb $0x45, %ah
|
cmpb $0x45, %ah
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ix87 specific implementation of pow function.
|
/* ix87 specific implementation of pow function.
|
||||||
Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005
|
Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005, 2007
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||||
@ -161,10 +161,11 @@ ENTRY(__ieee754_powl)
|
|||||||
2: /* y is a real number. */
|
2: /* y is a real number. */
|
||||||
fxch // x : y
|
fxch // x : y
|
||||||
fldl MO(one) // 1.0 : x : y
|
fldl MO(one) // 1.0 : x : y
|
||||||
fld %st(1) // x : 1.0 : x : y
|
fldl MO(limit) // 0.29 : 1.0 : x : y
|
||||||
fsub %st(1) // x-1 : 1.0 : x : y
|
fld %st(2) // x : 0.29 : 1.0 : x : y
|
||||||
fabs // |x-1| : 1.0 : x : y
|
fsub %st(2) // x-1 : 0.29 : 1.0 : x : y
|
||||||
fcompl MO(limit) // 1.0 : x : y
|
fabs // |x-1| : 0.29 : 1.0 : x : y
|
||||||
|
fucompp // 1.0 : x : y
|
||||||
fnstsw
|
fnstsw
|
||||||
fxch // x : 1.0 : y
|
fxch // x : 1.0 : y
|
||||||
sahf
|
sahf
|
||||||
@ -210,9 +211,10 @@ ENTRY(__ieee754_powl)
|
|||||||
// y == ±inf
|
// y == ±inf
|
||||||
.align ALIGNARG(4)
|
.align ALIGNARG(4)
|
||||||
12: fstp %st(0) // pop y
|
12: fstp %st(0) // pop y
|
||||||
fldt 4(%esp) // x
|
fldl MO(one) // 1
|
||||||
fabs
|
fldt 4(%esp) // x : 1
|
||||||
fcompl MO(one) // < 1, == 1, or > 1
|
fabs // abs(x) : 1
|
||||||
|
fucompp // < 1, == 1, or > 1
|
||||||
fnstsw
|
fnstsw
|
||||||
andb $0x45, %ah
|
andb $0x45, %ah
|
||||||
cmpb $0x45, %ah
|
cmpb $0x45, %ah
|
||||||
|
@ -106,20 +106,28 @@ double __ieee754_pow(double x, double y) {
|
|||||||
else
|
else
|
||||||
return y < 0 ? 1.0/ABS(x) : 0.0; /* return 0 */
|
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 x<0 */
|
||||||
if (u.i[HIGH_HALF] < 0) {
|
if (u.i[HIGH_HALF] < 0) {
|
||||||
k = checkint(y);
|
k = checkint(y);
|
||||||
if (k==0) {
|
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;
|
if (x == -1.0) return 1.0;
|
||||||
else if (x > -1.0) return v.i[HIGH_HALF] < 0 ? INF.x : 0.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 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 y < 0 ? 0.0 : INF.x;
|
||||||
return NaNQ.x; /* y not integer and x<0 */
|
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)
|
if (k < 0)
|
||||||
return y < 0 ? nZERO.x : nINF.x;
|
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 */
|
return (k==1)?__ieee754_pow(-x,y):-__ieee754_pow(-x,y); /* if y even or odd */
|
||||||
}
|
}
|
||||||
/* x>0 */
|
/* 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 (qx == 0x7ff00000) /* x= 2^-0x3ff */
|
||||||
{if (y == 0) return NaNQ.x;
|
{if (y == 0) return NaNQ.x;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* ix87 specific implementation of pow function.
|
/* ix87 specific implementation of pow function.
|
||||||
Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004 Free Software Foundation, Inc.
|
Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2007
|
||||||
|
Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||||
|
|
||||||
@ -146,10 +147,11 @@ ENTRY(__ieee754_powl)
|
|||||||
2: /* y is a real number. */
|
2: /* y is a real number. */
|
||||||
fxch // x : y
|
fxch // x : y
|
||||||
fldl MO(one) // 1.0 : x : y
|
fldl MO(one) // 1.0 : x : y
|
||||||
fld %st(1) // x : 1.0 : x : y
|
fldl MO(limit) // 0.29 : 1.0 : x : y
|
||||||
fsub %st(1) // x-1 : 1.0 : x : y
|
fld %st(2) // x : 0.29 : 1.0 : x : y
|
||||||
fabs // |x-1| : 1.0 : x : y
|
fsub %st(2) // x-1 : 0.29 : 1.0 : x : y
|
||||||
fcompl MO(limit) // 1.0 : x : y
|
fabs // |x-1| : 0.29 : 1.0 : x : y
|
||||||
|
fucompp // 1.0 : x : y
|
||||||
fnstsw
|
fnstsw
|
||||||
fxch // x : 1.0 : y
|
fxch // x : 1.0 : y
|
||||||
test $4500,%eax
|
test $4500,%eax
|
||||||
@ -190,9 +192,10 @@ ENTRY(__ieee754_powl)
|
|||||||
// y == ±inf
|
// y == ±inf
|
||||||
.align ALIGNARG(4)
|
.align ALIGNARG(4)
|
||||||
12: fstp %st(0) // pop y
|
12: fstp %st(0) // pop y
|
||||||
fldt 8(%rsp) // x
|
fldl MO(one) // 1
|
||||||
fabs
|
fldt 8(%rsp) // x : 1
|
||||||
fcompl MO(one) // < 1, == 1, or > 1
|
fabs // abs(x) : 1
|
||||||
|
fucompp // < 1, == 1, or > 1
|
||||||
fnstsw
|
fnstsw
|
||||||
andb $0x45, %ah
|
andb $0x45, %ah
|
||||||
cmpb $0x45, %ah
|
cmpb $0x45, %ah
|
||||||
|
Loading…
Reference in New Issue
Block a user