public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* Fix powerpc64 ceil, rint etc. on sNaN input (bug 20160) [committed]
@ 2016-05-27 18:08 Joseph Myers
  0 siblings, 0 replies; only message in thread
From: Joseph Myers @ 2016-05-27 18:08 UTC (permalink / raw)
  To: libc-alpha

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.  Committed.

2016-05-27  Joseph Myers  <joseph@codesourcery.com>

	[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.

diff --git a/sysdeps/powerpc/powerpc64/fpu/s_ceil.S b/sysdeps/powerpc/powerpc64/fpu/s_ceil.S
index d2f96bb..9c27977 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 ed94491..e16fb70 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 a304752..aa7ae0b 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 24e76b0..c605c12 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 93d2465..e709aea 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 3ba5378..c7a1db2 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 60c3dee..4fee6b5 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 0b274b0..8c89b66 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 19713b3..5e68c67 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 8841d83..e47a9df 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 f310c31..05f3a0b 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 b4fce64..021308e 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)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2016-05-27 17:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-27 18:08 Fix powerpc64 ceil, rint etc. on sNaN input (bug 20160) [committed] Joseph Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).