From f6ef0657e493e1f84dfb5b0b1966cf34e371ae27 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Fri, 27 May 2016 17:47:54 +0000 Subject: [PATCH] Fix powerpc64 ceil, rint etc. on sNaN input (bug 20160). The powerpc64 versions of ceil, floor, round, trunc, rint, nearbyint and their float versions return sNaN for sNaN input when they should return qNaN. This patch fixes them to add a NaN argument to itself to quiet sNaNs before returning. Tested for powerpc64. [BZ #20160] * sysdeps/powerpc/powerpc64/fpu/s_ceil.S (__ceil): Add NaN argument to itself before returning the result. * sysdeps/powerpc/powerpc64/fpu/s_ceilf.S (__ceilf): Likewise. * sysdeps/powerpc/powerpc64/fpu/s_floor.S (__floor): Likewise. * sysdeps/powerpc/powerpc64/fpu/s_floorf.S (__floorf): Likewise. * sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S (__nearbyint): Likewise. * sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S (__nearbyintf): Likewise. * sysdeps/powerpc/powerpc64/fpu/s_rint.S (__rint): Likewise. * sysdeps/powerpc/powerpc64/fpu/s_rintf.S (__rintf): Likewise. * sysdeps/powerpc/powerpc64/fpu/s_round.S (__round): Likewise. * sysdeps/powerpc/powerpc64/fpu/s_roundf.S (__roundf): Likewise. * sysdeps/powerpc/powerpc64/fpu/s_trunc.S (__trunc): Likewise. * sysdeps/powerpc/powerpc64/fpu/s_truncf.S (__truncf): Likewise. --- ChangeLog | 17 +++++++++++++++++ sysdeps/powerpc/powerpc64/fpu/s_ceil.S | 8 +++++++- sysdeps/powerpc/powerpc64/fpu/s_ceilf.S | 8 +++++++- sysdeps/powerpc/powerpc64/fpu/s_floor.S | 8 +++++++- sysdeps/powerpc/powerpc64/fpu/s_floorf.S | 8 +++++++- sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S | 8 +++++++- sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S | 8 +++++++- sysdeps/powerpc/powerpc64/fpu/s_rint.S | 8 +++++++- sysdeps/powerpc/powerpc64/fpu/s_rintf.S | 8 +++++++- sysdeps/powerpc/powerpc64/fpu/s_round.S | 8 +++++++- sysdeps/powerpc/powerpc64/fpu/s_roundf.S | 8 +++++++- sysdeps/powerpc/powerpc64/fpu/s_trunc.S | 8 +++++++- sysdeps/powerpc/powerpc64/fpu/s_truncf.S | 8 +++++++- 13 files changed, 101 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index e652a0387c..776b7cab98 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,23 @@ 2016-05-27 Joseph Myers [BZ #20160] + * sysdeps/powerpc/powerpc64/fpu/s_ceil.S (__ceil): Add NaN + argument to itself before returning the result. + * sysdeps/powerpc/powerpc64/fpu/s_ceilf.S (__ceilf): Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_floor.S (__floor): Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_floorf.S (__floorf): Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S (__nearbyint): + Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S (__nearbyintf): + Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_rint.S (__rint): Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_rintf.S (__rintf): Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_round.S (__round): Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_roundf.S (__roundf): Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_trunc.S (__trunc): Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_truncf.S (__truncf): Likewise. + + [BZ #20160] * sysdeps/powerpc/powerpc32/fpu/s_ceil.S (__ceil): Add NaN argument to itself before returning the result. * sysdeps/powerpc/powerpc32/fpu/s_ceilf.S (__ceilf): Likewise. diff --git a/sysdeps/powerpc/powerpc64/fpu/s_ceil.S b/sysdeps/powerpc/powerpc64/fpu/s_ceil.S index d2f96bb628..9c2797784e 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_ceil.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_ceil.S @@ -33,7 +33,7 @@ EALIGN (__ceil, 4, 0) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,2 /* Set rounding mode toward +inf. */ ble- cr6,.L4 fadd fp1,fp1,fp13 /* x+= TWO52; */ @@ -53,6 +53,12 @@ EALIGN (__ceil, 4, 0) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr END (__ceil) weak_alias (__ceil, ceil) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S index ed944912a9..e16fb70df4 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S @@ -34,7 +34,7 @@ EALIGN (__ceilf, 4, 0) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,2 /* Set rounding mode toward +inf. */ ble- cr6,.L4 fadds fp1,fp1,fp13 /* x+= TWO23; */ @@ -54,6 +54,12 @@ EALIGN (__ceilf, 4, 0) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr END (__ceilf) weak_alias (__ceilf, ceilf) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_floor.S b/sysdeps/powerpc/powerpc64/fpu/s_floor.S index a304752423..aa7ae0b7e6 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_floor.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_floor.S @@ -33,7 +33,7 @@ EALIGN (__floor, 4, 0) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,3 /* Set rounding mode toward -inf. */ ble- cr6,.L4 fadd fp1,fp1,fp13 /* x+= TWO52; */ @@ -53,6 +53,12 @@ EALIGN (__floor, 4, 0) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr END (__floor) weak_alias (__floor, floor) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_floorf.S b/sysdeps/powerpc/powerpc64/fpu/s_floorf.S index 24e76b0568..c605c12d86 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_floorf.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_floorf.S @@ -34,7 +34,7 @@ EALIGN (__floorf, 4, 0) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,3 /* Set rounding mode toward -inf. */ ble- cr6,.L4 fadds fp1,fp1,fp13 /* x+= TWO23; */ @@ -54,6 +54,12 @@ EALIGN (__floorf, 4, 0) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr END (__floorf) weak_alias (__floorf, floorf) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S b/sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S index 93d24652e1..e709aea3a6 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S @@ -36,7 +36,7 @@ EALIGN (__nearbyint, 4, 0) fabs fp0,fp1 lfd fp13,.LC0@toc(2) fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ - bgelr cr7 + bge cr7,.L10 fsub fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp1,fp12 /* if (x > 0.0) */ ble cr7, L(lessthanzero) @@ -56,6 +56,12 @@ L(lessthanzero): fnabs fp1,fp1 /* if (x == 0.0) */ mtfsf 0xff,fp11 /* Restore FE_INEXACT state. */ blr /* x = -0.0; */ +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr END (__nearbyint) weak_alias (__nearbyint, nearbyint) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S b/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S index 3ba53784a4..c7a1db2187 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S @@ -37,7 +37,7 @@ EALIGN (__nearbyintf, 4, 0) fabs fp0,fp1 lfs fp13,.LC0@toc(2) fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ - bgelr cr7 + bge cr7,.L10 fsubs fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp1,fp12 /* if (x > 0.0) */ ble cr7, L(lessthanzero) @@ -57,6 +57,12 @@ L(lessthanzero): fnabs fp1,fp1 /* if (x == 0.0) */ mtfsf 0xff,fp11 /* Restore FE_INEXACT state. */ blr /* x = -0.0; */ +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr END (__nearbyintf) weak_alias (__nearbyintf, nearbyintf) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_rint.S b/sysdeps/powerpc/powerpc64/fpu/s_rint.S index 60c3deeb2e..4fee6b5a48 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_rint.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_rint.S @@ -34,7 +34,7 @@ EALIGN (__rint, 4, 0) fsub fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr cr7 + bnl cr7,.L10 bng cr6,.L4 fadd fp1,fp1,fp13 /* x+= TWO52; */ fsub fp1,fp1,fp13 /* x-= TWO52; */ @@ -46,6 +46,12 @@ EALIGN (__rint, 4, 0) fadd fp1,fp1,fp13 /* x+= TWO52; */ fnabs fp1,fp1 /* if (x == 0.0) */ blr /* x = -0.0; */ +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr END (__rint) weak_alias (__rint, rint) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_rintf.S b/sysdeps/powerpc/powerpc64/fpu/s_rintf.S index 0b274b008a..8c89b66bca 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_rintf.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_rintf.S @@ -32,7 +32,7 @@ EALIGN (__rintf, 4, 0) fsubs fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr cr7 + bnl cr7,.L10 bng cr6,.L4 fadds fp1,fp1,fp13 /* x+= TWO23; */ fsubs fp1,fp1,fp13 /* x-= TWO23; */ @@ -44,6 +44,12 @@ EALIGN (__rintf, 4, 0) fadds fp1,fp1,fp13 /* x+= TWO23; */ fnabs fp1,fp1 /* if (x == 0.0) */ blr /* x = -0.0; */ +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr END (__rintf) weak_alias (__rintf, rintf) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_round.S b/sysdeps/powerpc/powerpc64/fpu/s_round.S index 19713b37e2..5e68c67ed6 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_round.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_round.S @@ -45,7 +45,7 @@ EALIGN (__round, 4, 0) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,1 /* Set rounding mode toward 0. */ lfd fp10,.LC1@toc(2) ble- cr6,.L4 @@ -68,6 +68,12 @@ EALIGN (__round, 4, 0) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr END (__round) weak_alias (__round, round) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_roundf.S b/sysdeps/powerpc/powerpc64/fpu/s_roundf.S index 8841d83497..e47a9df3f9 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_roundf.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_roundf.S @@ -46,7 +46,7 @@ EALIGN (__roundf, 4, 0) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,1 /* Set rounding mode toward 0. */ lfs fp10,.LC1@toc(2) ble- cr6,.L4 @@ -69,6 +69,12 @@ EALIGN (__roundf, 4, 0) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr END (__roundf) weak_alias (__roundf, roundf) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_trunc.S b/sysdeps/powerpc/powerpc64/fpu/s_trunc.S index f310c317c3..05f3a0b66e 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_trunc.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_trunc.S @@ -40,7 +40,7 @@ EALIGN (__trunc, 4, 0) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,1 /* Set rounding toward 0 mode. */ ble- cr6,.L4 fadd fp1,fp1,fp13 /* x+= TWO52; */ @@ -60,6 +60,12 @@ EALIGN (__trunc, 4, 0) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr END (__trunc) weak_alias (__trunc, trunc) diff --git a/sysdeps/powerpc/powerpc64/fpu/s_truncf.S b/sysdeps/powerpc/powerpc64/fpu/s_truncf.S index b4fce645cd..021308ed81 100644 --- a/sysdeps/powerpc/powerpc64/fpu/s_truncf.S +++ b/sysdeps/powerpc/powerpc64/fpu/s_truncf.S @@ -41,7 +41,7 @@ EALIGN (__truncf, 4, 0) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,1 /* Set rounding toward 0 mode. */ ble- cr6,.L4 fadds fp1,fp1,fp13 /* x+= TWO23; */ @@ -61,6 +61,12 @@ EALIGN (__truncf, 4, 0) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr END (__truncf) weak_alias (__truncf, truncf) -- 2.11.4.GIT