diff options
author | Joseph Myers <joseph@codesourcery.com> | 2015-02-24 17:30:02 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2015-02-24 17:30:02 +0000 |
commit | 9438b237abca11de201dd10483717299eafb1f0b (patch) | |
tree | eb70d51aaa288f93cb7f365c2221dc1c08343ad7 /sysdeps | |
parent | 6909d2767580b680138a6aa49aabf4976770e9f6 (diff) | |
download | glibc-9438b237abca11de201dd10483717299eafb1f0b.zip glibc-9438b237abca11de201dd10483717299eafb1f0b.tar.gz glibc-9438b237abca11de201dd10483717299eafb1f0b.tar.bz2 |
Fix x86/x86_64 scalb (qNaN, -Inf) (bug 16783).
Various x86 / x86_64 versions of scalb / scalbf / scalbl produce
spurious "invalid" exceptions for (qNaN, -Inf) arguments, because this
is wrongly handled like (+/-Inf, -Inf) which *should* raise such an
exception. (In fact the NaN case of the code determining whether to
quietly return a zero or a NaN for second argument -Inf was
accidentally dead since the code had been made to return a NaN with
exception.) This patch fixes the code to do the proper test for an
infinity as distinct from a NaN.
(Since the existing code does nothing to distinguish qNaNs and sNaNs
here, this patch doesn't either. If in future we systematically
implement proper sNaN semantics following TS 18661-1:2014, there will
be lots of bugs to address - Thomas found lots of issues with his
patch <https://sourceware.org/ml/libc-ports/2013-04/msg00008.html> to
add SNaN tests (which never went in and would now require significant
reworking).)
Tested for x86_64 and x86. Committed.
[BZ #16783]
* sysdeps/i386/fpu/e_scalb.S (__ieee754_scalb): Do not handle
arguments (NaN, -Inf) the same as (+/-Inf, -Inf).
* sysdeps/i386/fpu/e_scalbf.S (__ieee754_scalbf): Likewise.
* sysdeps/i386/fpu/e_scalbl.S (__ieee754_scalbl): Likewise.
* sysdeps/x86_64/fpu/e_scalbl.S (__ieee754_scalbl): Likewise.
* math/libm-test.inc (scalb_test_data): Add more tests.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/i386/fpu/e_scalb.S | 4 | ||||
-rw-r--r-- | sysdeps/i386/fpu/e_scalbf.S | 4 | ||||
-rw-r--r-- | sysdeps/i386/fpu/e_scalbl.S | 4 | ||||
-rw-r--r-- | sysdeps/x86_64/fpu/e_scalbl.S | 4 |
4 files changed, 12 insertions, 4 deletions
diff --git a/sysdeps/i386/fpu/e_scalb.S b/sysdeps/i386/fpu/e_scalb.S index 20d489e..6a01aa6 100644 --- a/sysdeps/i386/fpu/e_scalb.S +++ b/sysdeps/i386/fpu/e_scalb.S @@ -65,8 +65,10 @@ ENTRY(__ieee754_scalb) fstp %st fstp %st andl $0x80000000, %edx + andl $0x0228, %eax + cmpl $0x0028, %eax + je 4f andl $8, %eax - jnz 4f shrl $27, %edx addl %edx, %eax fldl MOX(zero_nan, %eax, 1) diff --git a/sysdeps/i386/fpu/e_scalbf.S b/sysdeps/i386/fpu/e_scalbf.S index b6dd021..12b2515 100644 --- a/sysdeps/i386/fpu/e_scalbf.S +++ b/sysdeps/i386/fpu/e_scalbf.S @@ -67,8 +67,10 @@ ENTRY(__ieee754_scalbf) fstp %st fstp %st andl $0x80000000, %edx + andl $0x0228, %eax + cmpl $0x0028, %eax + je 4f andl $8, %eax - jnz 4f shrl $27, %edx addl %edx, %eax fldl MOX(zero_nan, %eax, 1) diff --git a/sysdeps/i386/fpu/e_scalbl.S b/sysdeps/i386/fpu/e_scalbl.S index 83f17b2..d10b22e 100644 --- a/sysdeps/i386/fpu/e_scalbl.S +++ b/sysdeps/i386/fpu/e_scalbl.S @@ -67,8 +67,10 @@ ENTRY(__ieee754_scalbl) fstp %st fstp %st andl $0x8000, %edx + andl $0x0228, %eax + cmpl $0x0028, %eax + je 4f andl $8, %eax - jnz 4f shrl $11, %edx addl %edx, %eax fldl MOX(zero_nan, %eax, 1) diff --git a/sysdeps/x86_64/fpu/e_scalbl.S b/sysdeps/x86_64/fpu/e_scalbl.S index c422d53..331bee5 100644 --- a/sysdeps/x86_64/fpu/e_scalbl.S +++ b/sysdeps/x86_64/fpu/e_scalbl.S @@ -61,8 +61,10 @@ ENTRY(__ieee754_scalbl) fstp %st fstp %st andl $0x8000, %edx + andl $0x0228, %eax + cmpl $0x0028, %eax + je 4f andl $8, %eax - jnz 4f shrl $11, %edx addl %edx, %eax #ifdef PIC |