diff options
author | Joseph Myers <joseph@codesourcery.com> | 2015-05-15 22:07:57 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2015-05-15 22:07:57 +0000 |
commit | 8020a808870dc6199e584562b3b64f52054359e8 (patch) | |
tree | ce9400206b43fc1db091871c50d2e5e10c78c1fb /sysdeps/i386/fpu | |
parent | 5a608ccc2d676aa124f6b55a7b20d071e408ca31 (diff) | |
download | glibc-8020a808870dc6199e584562b3b64f52054359e8.tar.gz |
Fix atanhl missing underflows (bug 16352).
Similar to various other bugs in this area, some atanh implementations
do not raise the underflow exception for subnormal arguments, when the
result is tiny and inexact. This patch forces the exception in a
similar way to previous fixes. (No change in this regard is needed
for the i386 implementation; special handling to force underflows in
these cases will only be needed there when the spurious underflows,
bug 18049, get fixed.)
Tested for x86_64, x86, powerpc and mips64.
[BZ #16352]
* sysdeps/i386/fpu/e_atanh.S (dbl_min): New object.
(__ieee754_atanh): Force underflow exception for results with
small absolute value.
* sysdeps/i386/fpu/e_atanhf.S (flt_min): New object.
(__ieee754_atanhf): Force underflow exception for results with
small absolute value.
* sysdeps/ieee754/dbl-64/e_atanh.c: Include <float.h>.
(__ieee754_atanh): Force underflow exception for results with
small absolute value.
* sysdeps/ieee754/flt-32/e_atanhf.c: Include <float.h>.
(__ieee754_atanhf): Force underflow exception for results with
small absolute value.
* sysdeps/ieee754/ldbl-128/e_atanhl.c: Include <float.h>.
(__ieee754_atanhl): Force underflow exception for results with
small absolute value.
* sysdeps/ieee754/ldbl-128ibm/e_atanhl.c: Include <float.h>.
(__ieee754_atanhl): Force underflow exception for results with
small absolute value.
* sysdeps/ieee754/ldbl-96/e_atanhl.c: Include <float.h>.
(__ieee754_atanhl): Force underflow exception for results with
small absolute value.
* math/auto-libm-test-in: Do not allow missing underflow
exceptions from atanh.
* math/auto-libm-test-out: Regenerated.
Diffstat (limited to 'sysdeps/i386/fpu')
-rw-r--r-- | sysdeps/i386/fpu/e_atanh.S | 20 | ||||
-rw-r--r-- | sysdeps/i386/fpu/e_atanhf.S | 20 |
2 files changed, 38 insertions, 2 deletions
diff --git a/sysdeps/i386/fpu/e_atanh.S b/sysdeps/i386/fpu/e_atanh.S index 16e149b905..90d19bc9d6 100644 --- a/sysdeps/i386/fpu/e_atanh.S +++ b/sysdeps/i386/fpu/e_atanh.S @@ -35,6 +35,13 @@ limit: .double 0.29 ln2_2: .tfloat 0.3465735902799726547086160 ASM_SIZE_DIRECTIVE(ln2_2) + .section .rodata.cst8,"aM",@progbits,8 + + .p2align 3 + .type dbl_min,@object +dbl_min: .byte 0, 0, 0, 0, 0, 0, 0x10, 0 + ASM_SIZE_DIRECTIVE(dbl_min) + #ifdef PIC #define MO(op) op##@GOTOFF(%edx) #else @@ -81,7 +88,18 @@ ENTRY(__ieee754_atanh) sahf jae 4f fyl2xp1 // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|)) - jecxz 3f + fcoml MO(dbl_min) + fnstsw + sahf + jae 8f + subl $8, %esp + cfi_adjust_cfa_offset (8) + fld %st(0) + fmul %st(0) + fstpl (%esp) + addl $8, %esp + cfi_adjust_cfa_offset (-8) +8: jecxz 3f fchs // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x)) 3: ret diff --git a/sysdeps/i386/fpu/e_atanhf.S b/sysdeps/i386/fpu/e_atanhf.S index 0021d9c47d..1c8969e5ec 100644 --- a/sysdeps/i386/fpu/e_atanhf.S +++ b/sysdeps/i386/fpu/e_atanhf.S @@ -36,6 +36,13 @@ limit: .double 0.29 ln2_2: .tfloat 0.3465735902799726547086160 ASM_SIZE_DIRECTIVE(ln2_2) + .section .rodata.cst4,"aM",@progbits,4 + + .p2align 2 + .type flt_min,@object +flt_min: .byte 0, 0, 0x80, 0 + ASM_SIZE_DIRECTIVE(flt_min) + #ifdef PIC #define MO(op) op##@GOTOFF(%edx) #else @@ -77,7 +84,18 @@ ENTRY(__ieee754_atanhf) sahf jae 4f fyl2xp1 // 0.5*ln2*ld(1+2*|x|+(2*|x|^2)/(1-|x|)) - jecxz 3f + fcoms MO(flt_min) + fnstsw + sahf + jae 6f + subl $4, %esp + cfi_adjust_cfa_offset (4) + fld %st(0) + fmul %st(0) + fstps (%esp) + addl $4, %esp + cfi_adjust_cfa_offset (-4) +6: jecxz 3f fchs // 0.5*ln2*ld(1+2*x+(2*x^2)/(1-x)) 3: ret |