about summary refs log tree commit diff
path: root/sysdeps/powerpc/powerpc32/fpu/s_lround.S
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/powerpc/powerpc32/fpu/s_lround.S')
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_lround.S43
1 files changed, 41 insertions, 2 deletions
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_lround.S b/sysdeps/powerpc/powerpc32/fpu/s_lround.S
index 231d5e4f45..5dd3618524 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_lround.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_lround.S
@@ -23,6 +23,16 @@
 	.align	2
 .LC0:	/* 0.5 */
 	.long 0x3f000000
+.LC1:	/* 2^52.  */
+	.long 0x59800000
+	.section	.rodata.cst8,"aM",@progbits,8
+	.align	3
+.LC2:	/* 0x7fffffff.8p0.  */
+	.long 0x41dfffff
+	.long 0xffe00000
+.LC3:	/* -0x80000000.8p0.  */
+	.long 0xc1e00000
+	.long 0x00100000
 	.section	".text"
 
 /* long [r3] lround (float x [fp1])
@@ -45,19 +55,40 @@ ENTRY (__lround)
 	mflr	r11
 	cfi_register(lr,r11)
 	SETUP_GOT_ACCESS(r9,got_label)
-	addis	r9,r9,.LC0-got_label@ha
-	lfs	fp10,.LC0-got_label@l(r9)
+	addis	r10,r9,.LC0-got_label@ha
+	lfs	fp10,.LC0-got_label@l(r10)
+	addis	r10,r9,.LC1-got_label@ha
+	lfs	fp11,.LC1-got_label@l(r10)
+	addis	r10,r9,.LC2-got_label@ha
+	lfd	fp9,.LC2-got_label@l(r10)
+	addis	r10,r9,.LC3-got_label@ha
+	lfd	fp8,.LC3-got_label@l(r10)
 	mtlr	r11
 	cfi_same_value (lr)
 #else
 	lis	r9,.LC0@ha
 	lfs	fp10,.LC0@l(r9)
+	lis	r9,.LC1@ha
+	lfs	fp11,.LC1@l(r9)
+	lis	r9,.LC2@ha
+	lfd	fp9,.LC2@l(r9)
+	lis	r9,.LC3@ha
+	lfd	fp8,.LC3@l(r9)
 #endif
 	fabs	fp2, fp1	/* Get the absolute value of x.  */
 	fsub	fp12,fp10,fp10	/* Compute 0.0.  */
 	fcmpu	cr6, fp2, fp10	/* if |x| < 0.5  */
+	fcmpu	cr5, fp1, fp9	/* if x >= 0x7fffffff.8p0  */
+	fcmpu	cr1, fp1, fp8	/* if x <= -0x80000000.8p0  */
 	fcmpu	cr7, fp1, fp12	/* x is negative? x < 0.0  */
 	blt-	cr6,.Lretzero
+	bge-	cr5,.Loflow
+	ble-	cr1,.Loflow
+	/* Test whether an integer to avoid spurious "inexact".  */
+	fadd	fp3,fp2,fp11
+	fsub	fp3,fp3,fp11
+	fcmpu	cr5, fp2, fp3
+	beq	cr5,.Lnobias
 	fadd	fp3,fp2,fp10	/* |x|+=0.5 bias to prepare to round.  */
 	bge	cr7,.Lconvert	/* x is positive so don't negate x.  */
 	fnabs	fp3,fp3		/* -(|x|+=0.5)  */
@@ -74,6 +105,14 @@ ENTRY (__lround)
 .Lretzero:			/* when 0.5 > x > -0.5  */
 	li	r3,0		/* return 0.  */
 	b	.Lout
+.Lnobias:
+	fmr	fp3,fp1
+	b	.Lconvert
+.Loflow:
+	fmr	fp3,fp11
+	bge	cr7,.Lconvert
+	fnabs	fp3,fp3
+	b	.Lconvert
 	END (__lround)
 
 weak_alias (__lround, lround)