mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 20:40:05 +00:00
[BZ #258]
Update. 2004-07-19 Jakub Jelinek <jakub@redhat.com> [BZ #258] * math/libm-test.inc (max_value, min_value): New variables. (initialize): Initialize them. (pow_test): Add a couple of new tests. * sysdeps/i386/fpu/e_powf.S (__ieee754_powf): Don't generate invalid exception if |y| >= 1U<<31. * sysdeps/i386/fpu/e_pow.S (__ieee754_pow): Don't generate invalid exception if |y| >= 1L<<63. * sysdeps/i386/fpu/e_powl.S (__ieee754_powl): Likewise. If y*log2(x) overflows to +-inf, return still +inf/+0 instead of NaN. * sysdeps/x86_64/fpu/e_powl.S (__ieee754_powl): Likewise.
This commit is contained in:
parent
c747e725e3
commit
164f863efd
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
||||
2004-07-19 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
[BZ #258]
|
||||
* math/libm-test.inc (max_value, min_value): New variables.
|
||||
(initialize): Initialize them.
|
||||
(pow_test): Add a couple of new tests.
|
||||
* sysdeps/i386/fpu/e_powf.S (__ieee754_powf): Don't generate invalid
|
||||
exception if |y| >= 1U<<31.
|
||||
* sysdeps/i386/fpu/e_pow.S (__ieee754_pow): Don't generate invalid
|
||||
exception if |y| >= 1L<<63.
|
||||
* sysdeps/i386/fpu/e_powl.S (__ieee754_powl): Likewise.
|
||||
If y*log2(x) overflows to +-inf, return still +inf/+0 instead of NaN.
|
||||
* sysdeps/x86_64/fpu/e_powl.S (__ieee754_powl): Likewise.
|
||||
|
||||
2004-07-18 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* nscd/pwdcache.c (cache_addpw): Optimize case of unsuccessful
|
||||
|
@ -169,7 +169,7 @@ static int output_points; /* Should the single function results printed? */
|
||||
static int ignore_max_ulp; /* Should we ignore max_ulp? */
|
||||
|
||||
static FLOAT minus_zero, plus_zero;
|
||||
static FLOAT plus_infty, minus_infty, nan_value;
|
||||
static FLOAT plus_infty, minus_infty, nan_value, max_value, min_value;
|
||||
|
||||
static FLOAT max_error, real_max_error, imag_max_error;
|
||||
|
||||
@ -3593,6 +3593,28 @@ pow_test (void)
|
||||
TEST_ff_f (pow, -1, plus_infty, 1);
|
||||
TEST_ff_f (pow, 1, minus_infty, 1);
|
||||
TEST_ff_f (pow, -1, minus_infty, 1);
|
||||
TEST_ff_f (pow, 1, 1, 1);
|
||||
TEST_ff_f (pow, 1, -1, 1);
|
||||
TEST_ff_f (pow, 1, 1.25, 1);
|
||||
TEST_ff_f (pow, 1, -1.25, 1);
|
||||
TEST_ff_f (pow, 1, 0x1p62L, 1);
|
||||
TEST_ff_f (pow, 1, 0x1p63L, 1);
|
||||
TEST_ff_f (pow, 1, 0x1p64L, 1);
|
||||
TEST_ff_f (pow, 1, 0x1p72L, 1);
|
||||
|
||||
/* pow (x, +-0) == 1. */
|
||||
TEST_ff_f (pow, plus_infty, 0, 1);
|
||||
TEST_ff_f (pow, plus_infty, minus_zero, 1);
|
||||
TEST_ff_f (pow, minus_infty, 0, 1);
|
||||
TEST_ff_f (pow, minus_infty, minus_zero, 1);
|
||||
TEST_ff_f (pow, 32.75L, 0, 1);
|
||||
TEST_ff_f (pow, 32.75L, minus_zero, 1);
|
||||
TEST_ff_f (pow, -32.75L, 0, 1);
|
||||
TEST_ff_f (pow, -32.75L, minus_zero, 1);
|
||||
TEST_ff_f (pow, 0x1p72L, 0, 1);
|
||||
TEST_ff_f (pow, 0x1p72L, minus_zero, 1);
|
||||
TEST_ff_f (pow, 0x1p-72L, 0, 1);
|
||||
TEST_ff_f (pow, 0x1p-72L, minus_zero, 1);
|
||||
|
||||
TEST_ff_f (pow, -0.1L, 1.1L, nan_value, INVALID_EXCEPTION);
|
||||
TEST_ff_f (pow, -0.1L, -1.1L, nan_value, INVALID_EXCEPTION);
|
||||
@ -3609,6 +3631,10 @@ pow_test (void)
|
||||
TEST_ff_f (pow, minus_zero, -2, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
|
||||
TEST_ff_f (pow, minus_zero, -11.1L, plus_infty, DIVIDE_BY_ZERO_EXCEPTION);
|
||||
|
||||
TEST_ff_f (pow, 0x1p72L, 0x1p72L, plus_infty);
|
||||
TEST_ff_f (pow, 10, -0x1p72L, 0);
|
||||
TEST_ff_f (pow, max_value, max_value, plus_infty);
|
||||
TEST_ff_f (pow, 10, -max_value, 0);
|
||||
|
||||
TEST_ff_f (pow, 0, 1, 0);
|
||||
TEST_ff_f (pow, 0, 11, 0);
|
||||
@ -3623,6 +3649,8 @@ pow_test (void)
|
||||
|
||||
TEST_ff_f (pow, minus_zero, 2, 0);
|
||||
TEST_ff_f (pow, minus_zero, 11.1L, 0);
|
||||
TEST_ff_f (pow, 0, plus_infty, 0);
|
||||
TEST_ff_f (pow, minus_zero, plus_infty, 0);
|
||||
|
||||
#ifndef TEST_INLINE
|
||||
/* pow (x, +inf) == +inf for |x| > 1. */
|
||||
@ -3667,6 +3695,11 @@ pow_test (void)
|
||||
/* pow (-0, y) == +0 for y > 0 and not an odd integer. */
|
||||
TEST_ff_f (pow, minus_zero, 4, 0.0);
|
||||
|
||||
TEST_ff_f (pow, 16, 0.25L, 2);
|
||||
TEST_ff_f (pow, 0x1p64L, 0.125L, 256);
|
||||
TEST_ff_f (pow, 2, 4, 16);
|
||||
TEST_ff_f (pow, 256, 8, 0x1p64L);
|
||||
|
||||
TEST_ff_f (pow, 0.75L, 1.25L, 0.697953644326574699205914060237425566L);
|
||||
|
||||
#if defined TEST_DOUBLE || defined TEST_LDOUBLE
|
||||
@ -4312,12 +4345,18 @@ initialize (void)
|
||||
HUGE_VALL, HUGE_VAL, HUGE_VALF);
|
||||
minus_infty = CHOOSE (-HUGE_VALL, -HUGE_VAL, -HUGE_VALF,
|
||||
-HUGE_VALL, -HUGE_VAL, -HUGE_VALF);
|
||||
max_value = CHOOSE (LDBL_MAX, DBL_MAX, FLT_MAX,
|
||||
LDBL_MAX, DBL_MAX, FLT_MAX);
|
||||
min_value = CHOOSE (LDBL_MIN, DBL_MIN, FLT_MIN,
|
||||
LDBL_MIN, DBL_MIN, FLT_MIN);
|
||||
|
||||
(void) &plus_zero;
|
||||
(void) &nan_value;
|
||||
(void) &minus_zero;
|
||||
(void) &plus_infty;
|
||||
(void) &minus_infty;
|
||||
(void) &max_value;
|
||||
(void) &min_value;
|
||||
|
||||
/* Clear all exceptions. From now on we must not get random exceptions. */
|
||||
feclearexcept (FE_ALL_EXCEPT);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* ix87 specific implementation of pow function.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -48,6 +49,9 @@ one: .double 1.0
|
||||
ASM_TYPE_DIRECTIVE(limit,@object)
|
||||
limit: .double 0.29
|
||||
ASM_SIZE_DIRECTIVE(limit)
|
||||
ASM_TYPE_DIRECTIVE(p63,@object)
|
||||
p63: .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43
|
||||
ASM_SIZE_DIRECTIVE(p63)
|
||||
|
||||
#ifdef PIC
|
||||
#define MO(op) op##@GOTOFF(%ecx)
|
||||
@ -96,6 +100,14 @@ ENTRY(__ieee754_pow)
|
||||
|
||||
fxch // y : x
|
||||
|
||||
/* fistpll raises invalid exception for |y| >= 1L<<63. */
|
||||
fld %st // y : y : x
|
||||
fabs // |y| : y : x
|
||||
fcompl MO(p63) // y : x
|
||||
fnstsw
|
||||
sahf
|
||||
jnc 2f
|
||||
|
||||
/* First see whether `y' is a natural number. In this case we
|
||||
can use a more precise algorithm. */
|
||||
fld %st // y : y : x
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* ix87 specific implementation of pow function.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -48,6 +49,9 @@ one: .double 1.0
|
||||
ASM_TYPE_DIRECTIVE(limit,@object)
|
||||
limit: .double 0.29
|
||||
ASM_SIZE_DIRECTIVE(limit)
|
||||
ASM_TYPE_DIRECTIVE(p63,@object)
|
||||
p63: .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43
|
||||
ASM_SIZE_DIRECTIVE(p63)
|
||||
|
||||
#ifdef PIC
|
||||
#define MO(op) op##@GOTOFF(%ecx)
|
||||
@ -96,6 +100,14 @@ ENTRY(__ieee754_powl)
|
||||
|
||||
fxch // y : x
|
||||
|
||||
/* fistpll raises invalid exception for |y| >= 1L<<63. */
|
||||
fld %st // y : y : x
|
||||
fabs // |y| : y : x
|
||||
fcompl MO(p63) // y : x
|
||||
fnstsw
|
||||
sahf
|
||||
jnc 2f
|
||||
|
||||
/* First see whether `y' is a natural number. In this case we
|
||||
can use a more precise algorithm. */
|
||||
fld %st // y : y : x
|
||||
@ -161,6 +173,11 @@ ENTRY(__ieee754_powl)
|
||||
|
||||
7: fyl2x // log2(x) : y
|
||||
8: fmul %st(1) // y*log2(x) : y
|
||||
fxam
|
||||
fnstsw
|
||||
andb $0x45, %ah
|
||||
cmpb $0x05, %ah // is y*log2(x) == ±inf ?
|
||||
je 28f
|
||||
fst %st(1) // y*log2(x) : y*log2(x)
|
||||
frndint // int(y*log2(x)) : y*log2(x)
|
||||
fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x))
|
||||
@ -172,6 +189,12 @@ ENTRY(__ieee754_powl)
|
||||
fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x))
|
||||
ret
|
||||
|
||||
28: fstp %st(1) // y*log2(x)
|
||||
fldl MO(one) // 1 : y*log2(x)
|
||||
fscale // 2^(y*log2(x)) : y*log2(x)
|
||||
addl $8, %esp
|
||||
fstp %st(1) // 2^(y*log2(x))
|
||||
ret
|
||||
|
||||
// pow(x,±0) = 1
|
||||
.align ALIGNARG(4)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* ix87 specific implementation of pow function.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -48,6 +48,10 @@ one: .double 1.0
|
||||
ASM_TYPE_DIRECTIVE(limit,@object)
|
||||
limit: .double 0.29
|
||||
ASM_SIZE_DIRECTIVE(limit)
|
||||
ASM_TYPE_DIRECTIVE(p63,@object)
|
||||
p63:
|
||||
.byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43
|
||||
ASM_SIZE_DIRECTIVE(p63)
|
||||
|
||||
#ifdef PIC
|
||||
#define MO(op) op##(%rip)
|
||||
@ -87,6 +91,14 @@ ENTRY(__ieee754_powl)
|
||||
|
||||
fxch // y : x
|
||||
|
||||
/* fistpll raises invalid exception for |y| >= 1L<<63. */
|
||||
fldl MO(p63) // 1L<<63 : y : x
|
||||
fld %st(1) // y : 1L<<63 : y : x
|
||||
fabs // |y| : 1L<<63 : y : x
|
||||
fcomip %st(1), %st // 1L<<63 : y : x
|
||||
fstp %st(0) // y : x
|
||||
jnc 2f
|
||||
|
||||
/* First see whether `y' is a natural number. In this case we
|
||||
can use a more precise algorithm. */
|
||||
fld %st // y : y : x
|
||||
@ -148,6 +160,11 @@ ENTRY(__ieee754_powl)
|
||||
|
||||
7: fyl2x // log2(x) : y
|
||||
8: fmul %st(1) // y*log2(x) : y
|
||||
fxam
|
||||
fnstsw
|
||||
andb $0x45, %ah
|
||||
cmpb $0x05, %ah // is y*log2(x) == ±inf ?
|
||||
je 28f
|
||||
fst %st(1) // y*log2(x) : y*log2(x)
|
||||
frndint // int(y*log2(x)) : y*log2(x)
|
||||
fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x))
|
||||
@ -158,6 +175,11 @@ ENTRY(__ieee754_powl)
|
||||
fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x))
|
||||
ret
|
||||
|
||||
28: fstp %st(1) // y*log2(x)
|
||||
fldl MO(one) // 1 : y*log2(x)
|
||||
fscale // 2^(y*log2(x)) : y*log2(x)
|
||||
fstp %st(1) // 2^(y*log2(x))
|
||||
ret
|
||||
|
||||
// pow(x,±0) = 1
|
||||
.align ALIGNARG(4)
|
||||
|
Loading…
Reference in New Issue
Block a user