mirror of
git://sourceware.org/git/glibc.git
synced 2025-02-17 13:00:43 +08:00
Fix missing exceptions from exp (bugs 13787, 13922, 14036).
This commit is contained in:
parent
6698b8bf43
commit
41498f4db1
23
ChangeLog
23
ChangeLog
@ -1,5 +1,28 @@
|
||||
2012-05-05 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
[BZ #13787]
|
||||
[BZ #13922]
|
||||
[BZ #14036]
|
||||
* sysdeps/i386/fpu/e_expl.S (csat): New constant.
|
||||
(__ieee754_expl): Allow for and saturate large arguments.
|
||||
* sysdeps/ieee754/dbl-64/w_exp.c (o_threshold): Remove variable.
|
||||
(u_threshold): Likewise.
|
||||
(__exp): Call __ieee754_exp before checking for overflow and
|
||||
underflow.
|
||||
* sysdeps/ieee754/flt-32/w_expf.c (o_threshold): Remove variable.
|
||||
(u_threshold): Likewise.
|
||||
(__expf): Call __ieee754_expf before checking for overflow and
|
||||
underflow.
|
||||
* sysdeps/ieee754/ldbl-96/w_expl.c (o_threshold): Remove variable.
|
||||
(u_threshold): Likewise.
|
||||
(__expl): Call __ieee754_expl before checking for overflow and
|
||||
underflow.
|
||||
* sysdeps/x86_64/fpu/e_expl.S (csat): New constant.
|
||||
(__ieee754_expl): Allow for and saturate large arguments.
|
||||
* math/libm-test.inc (exp_test): Add another test. Do not allow
|
||||
missing overflow exception on overflow.
|
||||
(expm1_test): Do not allow missing overflow exception on overflow.
|
||||
|
||||
* sysdeps/i386/fpu/e_expl.c: Move to ...
|
||||
* sysdeps/i386/fpu/e_expl.S: ... here. Write directly in assembly
|
||||
rather than using inline asm.
|
||||
|
12
NEWS
12
NEWS
@ -18,12 +18,12 @@ Version 2.16
|
||||
12047, 12340, 13058, 13525, 13526, 13527, 13528, 13529, 13530, 13531,
|
||||
13532, 13533, 13547, 13551, 13552, 13553, 13555, 13559, 13566, 13583,
|
||||
13592, 13618, 13637, 13656, 13658, 13673, 13691, 13695, 13704, 13705,
|
||||
13706, 13726, 13738, 13739, 13758, 13760, 13761, 13775, 13786, 13792,
|
||||
13806, 13824, 13840, 13841, 13844, 13846, 13851, 13852, 13854, 13871,
|
||||
13872, 13873, 13879, 13883, 13886, 13892, 13895, 13908, 13910, 13911,
|
||||
13912, 13913, 13915, 13916, 13917, 13918, 13919, 13920, 13921, 13924,
|
||||
13926, 13927, 13928, 13938, 13941, 13942, 13963, 13967, 13970, 13973,
|
||||
14027, 14033, 14034, 14040, 14049, 14055
|
||||
13706, 13726, 13738, 13739, 13758, 13760, 13761, 13775, 13786, 13787,
|
||||
13792, 13806, 13824, 13840, 13841, 13844, 13846, 13851, 13852, 13854,
|
||||
13871, 13872, 13873, 13879, 13883, 13886, 13892, 13895, 13908, 13910,
|
||||
13911, 13912, 13913, 13915, 13916, 13917, 13918, 13919, 13920, 13921,
|
||||
13922, 13924, 13926, 13927, 13928, 13938, 13941, 13942, 13963, 13967,
|
||||
13970, 13973, 14027, 14033, 14034, 14040, 14049, 14055
|
||||
|
||||
* ISO C11 support:
|
||||
|
||||
|
@ -3325,8 +3325,11 @@ exp_test (void)
|
||||
TEST_f_f (exp, 1000.0L, 0.197007111401704699388887935224332313e435L);
|
||||
#endif
|
||||
|
||||
/* Bug 13922: OVERFLOW exception may be missing. */
|
||||
TEST_f_f (exp, max_value, plus_infty, OVERFLOW_EXCEPTION_OK);
|
||||
#if !(defined TEST_LDOUBLE && LDBL_MAX_EXP > 1024)
|
||||
TEST_f_f (exp, 710, plus_infty, OVERFLOW_EXCEPTION);
|
||||
#endif
|
||||
TEST_f_f (exp, 1e5, plus_infty, OVERFLOW_EXCEPTION);
|
||||
TEST_f_f (exp, max_value, plus_infty, OVERFLOW_EXCEPTION);
|
||||
TEST_f_f (exp, -max_value, 0);
|
||||
|
||||
END (exp);
|
||||
@ -3547,11 +3550,9 @@ expm1_test (void)
|
||||
#endif
|
||||
|
||||
errno = 0;
|
||||
/* Bug 13787: OVERFLOW exception may be missing. */
|
||||
TEST_f_f (expm1, 100000.0, plus_infty, OVERFLOW_EXCEPTION_OK);
|
||||
TEST_f_f (expm1, 100000.0, plus_infty, OVERFLOW_EXCEPTION);
|
||||
check_int ("errno for expm1(large) == ERANGE", errno, ERANGE, 0, 0, 0);
|
||||
/* Bug 13787: OVERFLOW exception may be missing. */
|
||||
TEST_f_f (expm1, max_value, plus_infty, OVERFLOW_EXCEPTION_OK);
|
||||
TEST_f_f (expm1, max_value, plus_infty, OVERFLOW_EXCEPTION);
|
||||
#ifndef TEST_LDOUBLE /* Bug 13923. */
|
||||
TEST_f_f (expm1, -max_value, -1);
|
||||
#endif
|
||||
|
@ -35,6 +35,10 @@ c0: .byte 0, 0, 0, 0, 0, 0, 0xaa, 0xb8, 0xff, 0x3f
|
||||
c1: .byte 0x20, 0xfa, 0xee, 0xc2, 0x5f, 0x70, 0xa5, 0xec, 0xed, 0x3f
|
||||
.byte 0, 0, 0, 0, 0, 0
|
||||
ASM_SIZE_DIRECTIVE(c1)
|
||||
ASM_TYPE_DIRECTIVE(csat,@object)
|
||||
csat: .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0e, 0x40
|
||||
.byte 0, 0, 0, 0, 0, 0
|
||||
ASM_SIZE_DIRECTIVE(csat)
|
||||
|
||||
#ifdef PIC
|
||||
# define MO(op) op##@GOTOFF(%ecx)
|
||||
@ -53,12 +57,25 @@ ENTRY(__ieee754_expl)
|
||||
#ifdef PIC
|
||||
LOAD_PIC_REG (cx)
|
||||
#endif
|
||||
movzwl 4+8(%esp), %eax
|
||||
andl $0x7fff, %eax
|
||||
cmpl $0x400d, %eax
|
||||
jle 3f
|
||||
/* Overflow, underflow or infinity or NaN as argument. */
|
||||
fstsw %ax
|
||||
movb $0x45, %dh
|
||||
andb %ah, %dh
|
||||
cmpb $0x05, %dh
|
||||
je 1f /* Is +-Inf, jump. */
|
||||
fldl2e /* 1 log2(e) */
|
||||
cmpb $0x01, %dh
|
||||
je 2f /* Is +-NaN, jump. */
|
||||
/* Overflow or underflow; saturate. */
|
||||
fstp %st
|
||||
fldt MO(csat)
|
||||
andb $2, %ah
|
||||
jz 3f
|
||||
fchs
|
||||
3: fldl2e /* 1 log2(e) */
|
||||
fmul %st(1), %st /* 1 x log2(e) */
|
||||
frndint /* 1 i */
|
||||
fld %st(1) /* 2 x */
|
||||
|
@ -19,27 +19,16 @@
|
||||
#include <math.h>
|
||||
#include <math_private.h>
|
||||
|
||||
static const double
|
||||
o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
|
||||
u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */
|
||||
|
||||
|
||||
/* wrapper exp */
|
||||
double
|
||||
__exp (double x)
|
||||
{
|
||||
if (__builtin_expect (isgreater (x, o_threshold), 0))
|
||||
{
|
||||
if (_LIB_VERSION != _IEEE_)
|
||||
return __kernel_standard (x, x, 6);
|
||||
}
|
||||
else if (__builtin_expect (isless (x, u_threshold), 0))
|
||||
{
|
||||
if (_LIB_VERSION != _IEEE_)
|
||||
return __kernel_standard (x, x, 7);
|
||||
}
|
||||
double z = __ieee754_exp (x);
|
||||
if (__builtin_expect (!__finite (z) || z == 0, 0)
|
||||
&& __finite (x) && _LIB_VERSION != _IEEE_)
|
||||
return __kernel_standard (x, x, 6 + !!__signbit (x));
|
||||
|
||||
return __ieee754_exp (x);
|
||||
return z;
|
||||
}
|
||||
hidden_def (__exp)
|
||||
weak_alias (__exp, exp)
|
||||
|
@ -19,27 +19,16 @@
|
||||
#include <math.h>
|
||||
#include <math_private.h>
|
||||
|
||||
static const float
|
||||
o_threshold= 8.8722831726e+01, /* 0x42b17217 */
|
||||
u_threshold= -1.0397208405e+02; /* 0xc2cff1b5 */
|
||||
|
||||
|
||||
/* wrapper expf */
|
||||
float
|
||||
__expf (float x)
|
||||
{
|
||||
if (__builtin_expect (isgreater (x, o_threshold), 0))
|
||||
{
|
||||
if (_LIB_VERSION != _IEEE_)
|
||||
return __kernel_standard_f (x, x, 106);
|
||||
}
|
||||
else if (__builtin_expect (isless (x, u_threshold), 0))
|
||||
{
|
||||
if (_LIB_VERSION != _IEEE_)
|
||||
return __kernel_standard_f (x, x, 107);
|
||||
}
|
||||
float z = __ieee754_expf (x);
|
||||
if (__builtin_expect (!__finitef (z) || z == 0, 0)
|
||||
&& __finitef (x) && _LIB_VERSION != _IEEE_)
|
||||
return __kernel_standard_f (x, x, 106 + !!__signbitf (x));
|
||||
|
||||
return __ieee754_expf (x);
|
||||
return z;
|
||||
}
|
||||
hidden_def (__expf)
|
||||
weak_alias (__expf, expf)
|
||||
|
@ -19,29 +19,16 @@
|
||||
#include <math.h>
|
||||
#include <math_private.h>
|
||||
|
||||
static const long double
|
||||
o_threshold= 1.135652340629414394949193107797076489134e4,
|
||||
/* 0x400C, 0xB17217F7, 0xD1CF79AC */
|
||||
u_threshold= -1.140019167866942050398521670162263001513e4;
|
||||
/* 0x400C, 0xB220C447, 0x69C201E8 */
|
||||
|
||||
|
||||
/* wrapper expl */
|
||||
long double
|
||||
__expl (long double x)
|
||||
{
|
||||
if (__builtin_expect (isgreater (x, o_threshold), 0))
|
||||
{
|
||||
if (_LIB_VERSION != _IEEE_)
|
||||
return __kernel_standard_l (x, x, 206);
|
||||
}
|
||||
else if (__builtin_expect (isless (x, u_threshold), 0))
|
||||
{
|
||||
if (_LIB_VERSION != _IEEE_)
|
||||
return __kernel_standard_l (x, x, 207);
|
||||
}
|
||||
long double z = __ieee754_expl (x);
|
||||
if (__builtin_expect (!__finitel (z) || z == 0, 0)
|
||||
&& __finitel (x) && _LIB_VERSION != _IEEE_)
|
||||
return __kernel_standard_l (x, x, 206 + !!__signbitl (x));
|
||||
|
||||
return __ieee754_expl (x);
|
||||
return z;
|
||||
}
|
||||
hidden_def (__expl)
|
||||
weak_alias (__expl, expl)
|
||||
|
@ -35,6 +35,10 @@ c0: .byte 0, 0, 0, 0, 0, 0, 0xaa, 0xb8, 0xff, 0x3f
|
||||
c1: .byte 0x20, 0xfa, 0xee, 0xc2, 0x5f, 0x70, 0xa5, 0xec, 0xed, 0x3f
|
||||
.byte 0, 0, 0, 0, 0, 0
|
||||
ASM_SIZE_DIRECTIVE(c1)
|
||||
ASM_TYPE_DIRECTIVE(csat,@object)
|
||||
csat: .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0e, 0x40
|
||||
.byte 0, 0, 0, 0, 0, 0
|
||||
ASM_SIZE_DIRECTIVE(csat)
|
||||
|
||||
#ifdef PIC
|
||||
# define MO(op) op##(%rip)
|
||||
@ -50,12 +54,25 @@ ENTRY(__ieee754_expl)
|
||||
For the i686 the code can be written better.
|
||||
-- drepper@cygnus.com. */
|
||||
fxam /* Is NaN or +-Inf? */
|
||||
movzwl 8+8(%rsp), %eax
|
||||
andl $0x7fff, %eax
|
||||
cmpl $0x400d, %eax
|
||||
jle 3f
|
||||
/* Overflow, underflow or infinity or NaN as argument. */
|
||||
fstsw %ax
|
||||
movb $0x45, %dh
|
||||
andb %ah, %dh
|
||||
cmpb $0x05, %dh
|
||||
je 1f /* Is +-Inf, jump. */
|
||||
fldl2e /* 1 log2(e) */
|
||||
cmpb $0x01, %dh
|
||||
je 2f /* Is +-NaN, jump. */
|
||||
/* Overflow or underflow; saturate. */
|
||||
fstp %st
|
||||
fldt MO(csat)
|
||||
andb $2, %ah
|
||||
jz 3f
|
||||
fchs
|
||||
3: fldl2e /* 1 log2(e) */
|
||||
fmul %st(1), %st /* 1 x log2(e) */
|
||||
frndint /* 1 i */
|
||||
fld %st(1) /* 2 x */
|
||||
|
Loading…
Reference in New Issue
Block a user