diff options
author | Joseph Myers <joseph@codesourcery.com> | 2015-06-21 17:48:04 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2015-06-21 17:48:04 +0000 |
commit | 7540cfc5a8c39eca9ba7b631dd30b35f6530f54d (patch) | |
tree | c24b888cf113ef3ec9a6e55ad495a1917c6e57bb /sysdeps/i386 | |
parent | d6cc0b4feaacf7514167cde0b3935f0c9b2c2d88 (diff) | |
download | glibc-7540cfc5a8c39eca9ba7b631dd30b35f6530f54d.tar.gz |
Fix x86 / x86_64 expl, exp10l missing underflows (bug 16361).
Similar to various other bugs in this area, the x86 and x86_64
implementations of expl / exp10l can fail to produce underflow
exceptions when the unscaled result has trailing 0 bits so the scaling
down to subnormal precision is exact. This patch fixes this by
forcing the exception in the case of tiny results.
Tested for x86_64 and x86.
[BZ #16361]
* sysdeps/i386/fpu/e_expl.S [!USE_AS_EXPM1L] (cmin): New object.
[!USE_AS_EXPM1L] (IEEE754_EXPL): Force underflow exception for
tiny results.
* sysdeps/x86_64/fpu/e_expl.S [!USE_AS_EXPM1L] (cmin): New object.
[!USE_AS_EXPM1L] (IEEE754_EXPL): Force underflow exception for
tiny results.
* math/auto-libm-test-in: Add more tests of exp and exp10. Do not
mark underflow exceptions as possibly missing for bug 16361.
* math/auto-libm-test-out: Regenerated.
Diffstat (limited to 'sysdeps/i386')
-rw-r--r-- | sysdeps/i386/fpu/e_expl.S | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/sysdeps/i386/fpu/e_expl.S b/sysdeps/i386/fpu/e_expl.S index c7e43732dc..74968bbc2b 100644 --- a/sysdeps/i386/fpu/e_expl.S +++ b/sysdeps/i386/fpu/e_expl.S @@ -65,6 +65,10 @@ c1: .byte 0x20, 0xfa, 0xee, 0xc2, 0x5f, 0x70, 0xa5, 0xec, 0xed, 0x3f csat: .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x0e, 0x40 .byte 0, 0, 0, 0, 0, 0 ASM_SIZE_DIRECTIVE(csat) + .type cmin,@object +cmin: .byte 0, 0, 0, 0, 0, 0, 0, 0x80, 0x1, 0 + .byte 0, 0, 0, 0, 0, 0 + ASM_SIZE_DIRECTIVE(cmin) #endif #ifdef PIC @@ -189,8 +193,18 @@ ENTRY(IEEE754_EXPL) fstp %st(1) /* 2 */ fscale /* 2 scale factor is st(1); base^x */ fstp %st(1) /* 1 */ + /* Ensure underflow for tiny result. */ + fldt MO(cmin) /* 2 cmin */ + fld %st(1) /* 3 */ + fcompp /* 1 */ + fnstsw + sahf + jnc 6f + fld %st + fmul %st + fstp %st #endif - fstp %st(1) /* 0 */ +6: fstp %st(1) /* 0 */ jmp 2f 1: #ifdef USE_AS_EXPM1L |