diff options
author | Joseph Myers <joseph@codesourcery.com> | 2012-07-06 11:17:41 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2012-07-06 11:17:41 +0000 |
commit | f17ac40d7cb8e8c462476b6ab703262f6b8f6da8 (patch) | |
tree | b06be367df1701da97deb44092ddf8707d2e8db2 /sysdeps/x86_64 | |
parent | fb21f89b75d0152aa42efb6b620843799a4cd76b (diff) | |
download | glibc-f17ac40d7cb8e8c462476b6ab703262f6b8f6da8.tar.gz glibc-f17ac40d7cb8e8c462476b6ab703262f6b8f6da8.tar.xz glibc-f17ac40d7cb8e8c462476b6ab703262f6b8f6da8.zip |
Fix expm1 spurious underflow exceptions (bug 6778).
Diffstat (limited to 'sysdeps/x86_64')
-rw-r--r-- | sysdeps/x86_64/fpu/e_expl.S | 42 | ||||
-rw-r--r-- | sysdeps/x86_64/fpu/libm-test-ulps | 3 |
2 files changed, 31 insertions, 14 deletions
diff --git a/sysdeps/x86_64/fpu/e_expl.S b/sysdeps/x86_64/fpu/e_expl.S index e6b842bf26..1c37c86f7f 100644 --- a/sysdeps/x86_64/fpu/e_expl.S +++ b/sysdeps/x86_64/fpu/e_expl.S @@ -60,10 +60,12 @@ c1: .byte 0x20, 0xfa, 0xee, 0xc2, 0x5f, 0x70, 0xa5, 0xec, 0xed, 0x3f .byte 0, 0, 0, 0, 0, 0 ASM_SIZE_DIRECTIVE(c1) #endif +#ifndef USE_AS_EXPM1L 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) +#endif #ifdef PIC # define MO(op) op##(%rip) @@ -85,9 +87,26 @@ ENTRY(IEEE754_EXPL) For the i686 the code can be written better. -- drepper@cygnus.com. */ fxam /* Is NaN or +-Inf? */ -#ifndef USE_AS_EXPM1L +#ifdef USE_AS_EXPM1L + xorb $0x80, %ah + cmpl $0xc006, %eax + fstsw %ax + movb $0x45, %dh + jb 4f + + /* Below -64.0 (may be -NaN or -Inf). */ + andb %ah, %dh + cmpb $0x01, %dh + je 2f /* Is +-NaN, jump. */ + jmp 1f /* -large, possibly -Inf. */ + +4: /* In range -64.0 to 64.0 (may be +-0 but not NaN or +-Inf). */ + /* Test for +-0 as argument. */ + andb %ah, %dh + cmpb $0x40, %dh + je 2f +#else movzwl 8+8(%rsp), %eax -#endif andl $0x7fff, %eax cmpl $0x400d, %eax jle 3f @@ -105,16 +124,8 @@ ENTRY(IEEE754_EXPL) andb $2, %ah jz 3f fchs -3: -#ifdef USE_AS_EXPM1L - /* Test for +-0 as argument. */ - fstsw %ax - movb $0x45, %dh - andb %ah, %dh - cmpb $0x40, %dh - je 2f #endif - FLDLOG /* 1 log2(base) */ +3: FLDLOG /* 1 log2(base) */ fmul %st(1), %st /* 1 x log2(base) */ frndint /* 1 i */ fld %st(1) /* 2 x */ @@ -151,13 +162,16 @@ ENTRY(IEEE754_EXPL) #endif fstp %st(1) /* 0 */ jmp 2f -1: testl $0x200, %eax /* Test sign. */ - jz 2f /* If positive, jump. */ - fstp %st +1: #ifdef USE_AS_EXPM1L + /* For expm1l, only negative sign gets here. */ + fstp %st fld1 fchs #else + testl $0x200, %eax /* Test sign. */ + jz 2f /* If positive, jump. */ + fstp %st fldz /* Set result to 0. */ #endif 2: ret diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps index b64e52d7d8..be28024b51 100644 --- a/sysdeps/x86_64/fpu/libm-test-ulps +++ b/sysdeps/x86_64/fpu/libm-test-ulps @@ -1657,6 +1657,9 @@ float: 1 ifloat: 1 # expm1 +Test "expm1 (-45.0) == -0.9999999999999999999713748141945060635553": +ildouble: 1 +ldouble: 1 Test "expm1 (0.75) == 1.11700001661267466854536981983709561": double: 1 idouble: 1 |