summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--math/libm-test.inc36
-rw-r--r--sysdeps/i386/fpu/e_scalbl.S16
-rw-r--r--sysdeps/x86_64/fpu/e_scalbl.S13
4 files changed, 48 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index e654c95043..3d6dad2167 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2016-06-23 Joseph Myers <joseph@codesourcery.com>
+ [BZ #20296]
+ * sysdeps/i386/fpu/e_scalbl.S (__ieee754_scalbl): Add arguments
+ when either argument is a NaN.
+ * sysdeps/x86_64/fpu/e_scalbl.S (__ieee754_scalbl): Likewise.
+ * math/libm-test.inc (scalb_test_data): Add sNaN tests.
+
* math/libm-test.inc (snan_value_ld): New macro.
(isgreater_test_data): Add sNaN tests.
(isgreaterequal_test_data): Likewise.
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 3e4ef187c3..7334a48577 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -11598,6 +11598,10 @@ static const struct test_ff_f_data scalb_test_data[] =
TEST_ff_f (scalb, 0, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, 1, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, 1, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (scalb, 0, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, 0, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, 1, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, 1, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
TEST_ff_f (scalb, 1, 0, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, -1, 0, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -11634,28 +11638,60 @@ static const struct test_ff_f_data scalb_test_data[] =
TEST_ff_f (scalb, qnan_value, 1, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, -qnan_value, 1, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (scalb, snan_value, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, -snan_value, 1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
TEST_ff_f (scalb, 1, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, 1, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (scalb, 1, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, 1, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
TEST_ff_f (scalb, qnan_value, 0.5, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, -qnan_value, 0.5, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (scalb, snan_value, 0.5, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, -snan_value, 0.5, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
TEST_ff_f (scalb, 0.5, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, 0.5, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (scalb, 0.5, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, 0.5, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
TEST_ff_f (scalb, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, -qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (scalb, snan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, -snan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
TEST_ff_f (scalb, 0, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, 0, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (scalb, 0, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, 0, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
TEST_ff_f (scalb, qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, -qnan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (scalb, snan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, -snan_value, plus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
TEST_ff_f (scalb, plus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, plus_infty, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (scalb, plus_infty, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, plus_infty, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
TEST_ff_f (scalb, qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, -qnan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (scalb, snan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, -snan_value, minus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
TEST_ff_f (scalb, minus_infty, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, minus_infty, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (scalb, minus_infty, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, minus_infty, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
TEST_ff_f (scalb, qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, qnan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, -qnan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (scalb, -qnan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (scalb, snan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, snan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, -snan_value, qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, -snan_value, -qnan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, qnan_value, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, qnan_value, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, -qnan_value, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, -qnan_value, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, snan_value, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, snan_value, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, -snan_value, snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+ TEST_ff_f (scalb, -snan_value, -snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
TEST_ff_f (scalb, max_value, max_value, plus_oflow, INEXACT_EXCEPTION|OVERFLOW_EXCEPTION|ERRNO_PLUS_OFLOW),
TEST_ff_f (scalb, max_value, -max_value, plus_uflow, INEXACT_EXCEPTION|UNDERFLOW_EXCEPTION|ERRNO_PLUS_UFLOW),
diff --git a/sysdeps/i386/fpu/e_scalbl.S b/sysdeps/i386/fpu/e_scalbl.S
index d10b22ea83..896f599cb0 100644
--- a/sysdeps/i386/fpu/e_scalbl.S
+++ b/sysdeps/i386/fpu/e_scalbl.S
@@ -45,7 +45,7 @@ ENTRY(__ieee754_scalbl)
fnstsw
andl $0x4500, %eax
cmpl $0x0100, %eax
- je 3f
+ je 2f
fld %st(1)
frndint
fcomp %st(2)
@@ -76,18 +76,8 @@ ENTRY(__ieee754_scalbl)
fldl MOX(zero_nan, %eax, 1)
ret
- /* The result is NaN, but we must not raise an exception.
- So use a variable. */
-2: fstp %st
- fstp %st
-#ifdef PIC
- LOAD_PIC_REG (cx)
-#endif
- fldl MO(nan)
- ret
-
- /* The first parameter is a NaN. Return it. */
-3: fstp %st(1)
+ /* The result is NaN; raise an exception for sNaN arguments. */
+2: faddp
ret
/* Return NaN and raise the invalid exception. */
diff --git a/sysdeps/x86_64/fpu/e_scalbl.S b/sysdeps/x86_64/fpu/e_scalbl.S
index 331bee580c..2982dc3b9e 100644
--- a/sysdeps/x86_64/fpu/e_scalbl.S
+++ b/sysdeps/x86_64/fpu/e_scalbl.S
@@ -44,7 +44,7 @@ ENTRY(__ieee754_scalbl)
fnstsw
andl $0x4500, %eax
cmpl $0x0100, %eax
- je 3f
+ je 2f
fld %st(1)
frndint
fcomip %st(2), %st
@@ -75,15 +75,8 @@ ENTRY(__ieee754_scalbl)
#endif
ret
- /* The result is NaN, but we must not raise an exception.
- So use a variable. */
-2: fstp %st
- fstp %st
- fldl MO(nan)
- ret
-
- /* The first parameter is a NaN. Return it. */
-3: fstp %st(1)
+ /* The result is NaN; raise an exception for sNaN arguments. */
+2: faddp
ret
/* Return NaN and raise the invalid exception. */