arrfab / rpms / glibc

Forked from rpms/glibc 5 years ago
Clone

Blame SOURCES/glibc-rh1385004-21.patch

147e83
From 1ddf0e88cfea375eee1c7da2127a8520c02862b3 Mon Sep 17 00:00:00 2001
147e83
From: Anton Blanchard <anton@samba.org>
147e83
Date: Tue, 28 Jun 2016 21:59:40 +1000
147e83
Subject: [PATCH] powerpc: Add a POWER8-optimized version of sinf()
147e83
147e83
This uses the implementation of sinf() in sysdeps/x86_64/fpu/s_sinf.S
147e83
as inspiration.
147e83
147e83
(cherry picked from commit aa95fc13f5b02044eadc3af3d9e1c025f2e1edda)
147e83
---
147e83
 ChangeLog                                          |  10 +
147e83
 sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile   |   3 +-
147e83
 .../powerpc64/fpu/multiarch/s_sinf-power8.S        |  26 ++
147e83
 .../powerpc/powerpc64/fpu/multiarch/s_sinf-ppc64.c |  26 ++
147e83
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf.c   |  31 ++
147e83
 sysdeps/powerpc/powerpc64/power8/fpu/s_sinf.S      | 519 +++++++++++++++++++++
147e83
 6 files changed, 614 insertions(+), 1 deletion(-)
147e83
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-power8.S
147e83
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-ppc64.c
147e83
 create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf.c
147e83
 create mode 100644 sysdeps/powerpc/powerpc64/power8/fpu/s_sinf.S
147e83
147e83
diff --git a/ChangeLog b/ChangeLog
147e83
index 6cb2578..6d6aab3 100644
147e83
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
147e83
index 331763e..add1fb8 100644
147e83
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
147e83
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
147e83
@@ -25,7 +25,8 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
147e83
                        e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7 \
147e83
                        s_isnan-power8 s_isinf-power8 s_finite-power8 \
147e83
                        s_llrint-power8 s_llround-power8 \
147e83
-                       e_expf-power8 e_expf-ppc64
147e83
+                       e_expf-power8 e_expf-ppc64 \
147e83
+                       s_sinf-ppc64 s_sinf-power8
147e83
 
147e83
 CFLAGS-s_logbf-power7.c = -mcpu=power7
147e83
 CFLAGS-s_logbl-power7.c = -mcpu=power7
147e83
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-power8.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-power8.S
147e83
new file mode 100644
147e83
index 0000000..579019c
147e83
--- /dev/null
147e83
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-power8.S
147e83
@@ -0,0 +1,26 @@
147e83
+/* sinf().  PowerPC64/POWER8 version.
147e83
+   Copyright (C) 2016 Free Software Foundation, Inc.
147e83
+   This file is part of the GNU C Library.
147e83
+
147e83
+   The GNU C Library is free software; you can redistribute it and/or
147e83
+   modify it under the terms of the GNU Lesser General Public
147e83
+   License as published by the Free Software Foundation; either
147e83
+   version 2.1 of the License, or (at your option) any later version.
147e83
+
147e83
+   The GNU C Library is distributed in the hope that it will be useful,
147e83
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
147e83
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
147e83
+   Lesser General Public License for more details.
147e83
+
147e83
+   You should have received a copy of the GNU Lesser General Public
147e83
+   License along with the GNU C Library; if not, see
147e83
+   <http://www.gnu.org/licenses/>.  */
147e83
+
147e83
+#include <sysdep.h>
147e83
+
147e83
+#undef weak_alias
147e83
+#define weak_alias(a, b)
147e83
+
147e83
+#define __sinf __sinf_power8
147e83
+
147e83
+#include <sysdeps/powerpc/powerpc64/power8/fpu/s_sinf.S>
147e83
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-ppc64.c
147e83
new file mode 100644
147e83
index 0000000..eaf83fa
147e83
--- /dev/null
147e83
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-ppc64.c
147e83
@@ -0,0 +1,26 @@
147e83
+/* sinf().  PowerPC64 default version.
147e83
+   Copyright (C) 2016 Free Software Foundation, Inc.
147e83
+   This file is part of the GNU C Library.
147e83
+
147e83
+   The GNU C Library is free software; you can redistribute it and/or
147e83
+   modify it under the terms of the GNU Lesser General Public
147e83
+   License as published by the Free Software Foundation; either
147e83
+   version 2.1 of the License, or (at your option) any later version.
147e83
+
147e83
+   The GNU C Library is distributed in the hope that it will be useful,
147e83
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
147e83
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
147e83
+   Lesser General Public License for more details.
147e83
+
147e83
+   You should have received a copy of the GNU Lesser General Public
147e83
+   License along with the GNU C Library; if not, see
147e83
+   <http://www.gnu.org/licenses/>.  */
147e83
+
147e83
+#include <sysdep.h>
147e83
+
147e83
+#undef weak_alias
147e83
+#define weak_alias(a, b)
147e83
+
147e83
+#define __sinf __sinf_ppc64
147e83
+
147e83
+#include <sysdeps/ieee754/flt-32/s_sinf.c>
147e83
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf.c
147e83
new file mode 100644
147e83
index 0000000..4269d58
147e83
--- /dev/null
147e83
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf.c
147e83
@@ -0,0 +1,31 @@
147e83
+/* Multiple versions of sinf.
147e83
+   Copyright (C) 2016 Free Software Foundation, Inc.
147e83
+   This file is part of the GNU C Library.
147e83
+
147e83
+   The GNU C Library is free software; you can redistribute it and/or
147e83
+   modify it under the terms of the GNU Lesser General Public
147e83
+   License as published by the Free Software Foundation; either
147e83
+   version 2.1 of the License, or (at your option) any later version.
147e83
+
147e83
+   The GNU C Library is distributed in the hope that it will be useful,
147e83
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
147e83
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
147e83
+   Lesser General Public License for more details.
147e83
+
147e83
+   You should have received a copy of the GNU Lesser General Public
147e83
+   License along with the GNU C Library; if not, see
147e83
+   <http://www.gnu.org/licenses/>.  */
147e83
+
147e83
+#include <math.h>
147e83
+#include <shlib-compat.h>
147e83
+#include "init-arch.h"
147e83
+
147e83
+extern __typeof (__sinf) __sinf_ppc64 attribute_hidden;
147e83
+extern __typeof (__sinf) __sinf_power8 attribute_hidden;
147e83
+
147e83
+libc_ifunc (__sinf,
147e83
+            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
147e83
+            ? __sinf_power8
147e83
+            : __sinf_ppc64);
147e83
+
147e83
+weak_alias (__sinf, sinf)
147e83
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_sinf.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_sinf.S
147e83
new file mode 100644
147e83
index 0000000..3b8f5af
147e83
--- /dev/null
147e83
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_sinf.S
147e83
@@ -0,0 +1,519 @@
147e83
+/* Optimized sinf().  PowerPC64/POWER8 version.
147e83
+   Copyright (C) 2016 Free Software Foundation, Inc.
147e83
+   This file is part of the GNU C Library.
147e83
+
147e83
+   The GNU C Library is free software; you can redistribute it and/or
147e83
+   modify it under the terms of the GNU Lesser General Public
147e83
+   License as published by the Free Software Foundation; either
147e83
+   version 2.1 of the License, or (at your option) any later version.
147e83
+
147e83
+   The GNU C Library is distributed in the hope that it will be useful,
147e83
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
147e83
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
147e83
+   Lesser General Public License for more details.
147e83
+
147e83
+   You should have received a copy of the GNU Lesser General Public
147e83
+   License along with the GNU C Library; if not, see
147e83
+   <http://www.gnu.org/licenses/>.  */
147e83
+
147e83
+#include <sysdep.h>
147e83
+#define _ERRNO_H	1
147e83
+#include <bits/errno.h>
147e83
+
147e83
+#define FRAMESIZE (FRAME_MIN_SIZE+16)
147e83
+
147e83
+#define FLOAT_EXPONENT_SHIFT	23
147e83
+#define FLOAT_EXPONENT_BIAS	127
147e83
+#define INTEGER_BITS		3
147e83
+
147e83
+#define PI_4		0x3f490fdb	/* PI/4 */
147e83
+#define NINEPI_4	0x40e231d6	/* 9 * PI/4 */
147e83
+#define TWO_PN5		0x3d000000	/* 2^-5 */
147e83
+#define TWO_PN27	0x32000000	/* 2^-27 */
147e83
+#define INFINITY	0x7f800000
147e83
+#define TWO_P23		0x4b000000	/* 2^27 */
147e83
+#define FX_FRACTION_1_28 0x9249250	/* 0x100000000 / 28 + 1 */
147e83
+
147e83
+	/* Implements the function
147e83
+
147e83
+	   float [fp1] sinf (float [fp1] x)  */
147e83
+
147e83
+	.machine power8
147e83
+EALIGN(__sinf, 4, 0)
147e83
+	addis	r9,r2,L(anchor)@toc@ha
147e83
+	addi	r9,r9,L(anchor)@toc@l
147e83
+
147e83
+	lis	r4,PI_4@h
147e83
+	ori	r4,r4,PI_4@l
147e83
+
147e83
+	xscvdpspn v0,v1
147e83
+	mfvsrd	r8,v0
147e83
+	rldicl	r3,r8,32,33		/* Remove sign bit.  */
147e83
+
147e83
+	cmpw	r3,r4
147e83
+	bge	L(greater_or_equal_pio4)
147e83
+
147e83
+	lis	r4,TWO_PN5@h
147e83
+	ori	r4,r4,TWO_PN5@l
147e83
+
147e83
+	cmpw	r3,r4
147e83
+	blt	L(less_2pn5)
147e83
+
147e83
+	/* Chebyshev polynomial of the form:
147e83
+	 * x+x^3*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))).  */
147e83
+
147e83
+	lfd	fp9,(L(S0)-L(anchor))(r9)
147e83
+	lfd	fp10,(L(S1)-L(anchor))(r9)
147e83
+	lfd	fp11,(L(S2)-L(anchor))(r9)
147e83
+	lfd	fp12,(L(S3)-L(anchor))(r9)
147e83
+	lfd	fp13,(L(S4)-L(anchor))(r9)
147e83
+
147e83
+	fmul	fp2,fp1,fp1		/* x^2 */
147e83
+	fmul	fp3,fp2,fp1		/* x^3 */
147e83
+
147e83
+	fmadd	fp4,fp2,fp13,fp12	/* S3+x^2*S4 */
147e83
+	fmadd	fp4,fp2,fp4,fp11	/* S2+x^2*(S3+x^2*S4) */
147e83
+	fmadd	fp4,fp2,fp4,fp10	/* S1+x^2*(S2+x^2*(S3+x^2*S4)) */
147e83
+	fmadd	fp4,fp2,fp4,fp9		/* S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4))) */
147e83
+	fmadd	fp1,fp3,fp4,fp1		/* x+x^3*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))) */
147e83
+	frsp	fp1,fp1			/* Round to single precision.  */
147e83
+
147e83
+	blr
147e83
+
147e83
+	.balign 16
147e83
+L(greater_or_equal_pio4):
147e83
+	lis	r4,NINEPI_4@h
147e83
+	ori	r4,r4,NINEPI_4@l
147e83
+	cmpw	r3,r4
147e83
+	bge	L(greater_or_equal_9pio4)
147e83
+
147e83
+	/* Calculate quotient of |x|/(PI/4).  */
147e83
+	lfd	fp2,(L(invpio4)-L(anchor))(r9)
147e83
+	fabs	fp1,fp1			/* |x| */
147e83
+	fmul	fp2,fp1,fp2		/* |x|/(PI/4) */
147e83
+	fctiduz	fp2,fp2
147e83
+	mfvsrd	r3,v2			/* n = |x| mod PI/4 */
147e83
+
147e83
+	/* Now use that quotient to find |x| mod (PI/2).  */
147e83
+	addi	r7,r3,1
147e83
+	rldicr	r5,r7,2,60		/* ((n+1) >> 1) << 3 */
147e83
+	addi	r6,r9,(L(pio2_table)-L(anchor))
147e83
+	lfdx	fp4,r5,r6
147e83
+	fsub	fp1,fp1,fp4
147e83
+
147e83
+	.balign 16
147e83
+L(reduced):
147e83
+	/* Now we are in the range -PI/4 to PI/4.  */
147e83
+
147e83
+	/* Work out if we are in a positive or negative primary interval.  */
147e83
+	rldicl	r4,r7,62,63		/* ((n+1) >> 2) & 1 */
147e83
+
147e83
+	/* We are operating on |x|, so we need to add back the original
147e83
+	   sign.  */
147e83
+	rldicl	r8,r8,33,63		/* (x >> 31) & 1, ie the sign bit.  */
147e83
+	xor	r4,r4,r8		/* 0 if result should be positive,
147e83
+					   1 if negative.  */
147e83
+
147e83
+	/* Load a 1.0 or -1.0.  */
147e83
+	addi	r5,r9,(L(ones)-L(anchor))
147e83
+	sldi	r4,r4,3
147e83
+	lfdx	fp0,r4,r5
147e83
+
147e83
+	/* Are we in the primary interval of sin or cos?  */
147e83
+	andi.	r4,r7,0x2
147e83
+	bne	L(cos)
147e83
+
147e83
+	/* Chebyshev polynomial of the form:
147e83
+	   x+x^3*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))).  */
147e83
+
147e83
+	lfd	fp9,(L(S0)-L(anchor))(r9)
147e83
+	lfd	fp10,(L(S1)-L(anchor))(r9)
147e83
+	lfd	fp11,(L(S2)-L(anchor))(r9)
147e83
+	lfd	fp12,(L(S3)-L(anchor))(r9)
147e83
+	lfd	fp13,(L(S4)-L(anchor))(r9)
147e83
+
147e83
+	fmul	fp2,fp1,fp1		/* x^2 */
147e83
+	fmul	fp3,fp2,fp1		/* x^3 */
147e83
+
147e83
+	fmadd	fp4,fp2,fp13,fp12	/* S3+x^2*S4 */
147e83
+	fmadd	fp4,fp2,fp4,fp11	/* S2+x^2*(S3+x^2*S4) */
147e83
+	fmadd	fp4,fp2,fp4,fp10	/* S1+x^2*(S2+x^2*(S3+x^2*S4)) */
147e83
+	fmadd	fp4,fp2,fp4,fp9		/* S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4))) */
147e83
+	fmadd	fp4,fp3,fp4,fp1		/* x+x^3*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))) */
147e83
+	fmul	fp4,fp4,fp0		/* Add in the sign.  */
147e83
+	frsp	fp1,fp4			/* Round to single precision.  */
147e83
+
147e83
+	blr
147e83
+
147e83
+	.balign 16
147e83
+L(cos):
147e83
+	/* Chebyshev polynomial of the form:
147e83
+	   1.0+x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))).  */
147e83
+
147e83
+	lfd	fp9,(L(C0)-L(anchor))(r9)
147e83
+	lfd	fp10,(L(C1)-L(anchor))(r9)
147e83
+	lfd	fp11,(L(C2)-L(anchor))(r9)
147e83
+	lfd	fp12,(L(C3)-L(anchor))(r9)
147e83
+	lfd	fp13,(L(C4)-L(anchor))(r9)
147e83
+
147e83
+	fmul	fp2,fp1,fp1		/* x^2 */
147e83
+	lfd	fp3,(L(DPone)-L(anchor))(r9)
147e83
+
147e83
+	fmadd	fp4,fp2,fp13,fp12	/* C3+x^2*C4 */
147e83
+	fmadd	fp4,fp2,fp4,fp11	/* C2+x^2*(C3+x^2*C4) */
147e83
+	fmadd	fp4,fp2,fp4,fp10	/* C1+x^2*(C2+x^2*(C3+x^2*C4)) */
147e83
+	fmadd	fp4,fp2,fp4,fp9		/* C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4))) */
147e83
+	fmadd	fp4,fp2,fp4,fp3		/* 1.0 + x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))) */
147e83
+	fmul	fp4,fp4,fp0		/* Add in the sign.  */
147e83
+	frsp	fp1,fp4			/* Round to single precision.  */
147e83
+
147e83
+	blr
147e83
+
147e83
+	.balign 16
147e83
+L(greater_or_equal_9pio4):
147e83
+	lis	r4,INFINITY@h
147e83
+	ori	r4,r4,INFINITY@l
147e83
+	cmpw	r3,r4
147e83
+	bge	L(inf_or_nan)
147e83
+
147e83
+	lis	r4,TWO_P23@h
147e83
+	ori	r4,r4,TWO_P23@l
147e83
+	cmpw	r3,r4
147e83
+	bge	L(greater_or_equal_2p23)
147e83
+
147e83
+	fabs	fp1,fp1			/* |x| */
147e83
+
147e83
+	/* Calculate quotient of |x|/(PI/4).  */
147e83
+	lfd	fp2,(L(invpio4)-L(anchor))(r9)
147e83
+
147e83
+	lfd	fp3,(L(DPone)-L(anchor))(r9)
147e83
+	lfd	fp4,(L(DPhalf)-L(anchor))(r9)
147e83
+	fmul	fp2,fp1,fp2		/* |x|/(PI/4) */
147e83
+	friz	fp2,fp2			/* n = floor(|x|/(PI/4)) */
147e83
+
147e83
+	/* Calculate (n + 1) / 2.  */
147e83
+	fadd	fp2,fp2,fp3		/* n + 1 */
147e83
+	fmul	fp3,fp2,fp4		/* (n + 1) / 2 */
147e83
+	friz	fp3,fp3
147e83
+
147e83
+	lfd	fp4,(L(pio2hi)-L(anchor))(r9)
147e83
+	lfd	fp5,(L(pio2lo)-L(anchor))(r9)
147e83
+
147e83
+	fmul	fp6,fp4,fp3
147e83
+	fadd	fp6,fp6,fp1
147e83
+	fmadd	fp1,fp5,fp3,fp6
147e83
+
147e83
+	fctiduz	fp2,fp2
147e83
+	mfvsrd	r7,v2			/* n + 1 */
147e83
+
147e83
+	b	L(reduced)
147e83
+
147e83
+	.balign 16
147e83
+L(inf_or_nan):
147e83
+	bne	L(skip_errno_setting)	/* Is a NAN?  */
147e83
+
147e83
+	/* We delayed the creation of the stack frame, as well as the saving of
147e83
+	   the link register, because only at this point, we are sure that
147e83
+	   doing so is actually needed.  */
147e83
+
147e83
+	stfd	fp1,-8(r1)
147e83
+
147e83
+	/* Save the link register.  */
147e83
+	mflr	r0
147e83
+	std	r0,16(r1)
147e83
+	cfi_offset(lr, 16)
147e83
+
147e83
+	/* Create the stack frame.  */
147e83
+	stdu	r1,-FRAMESIZE(r1)
147e83
+	cfi_adjust_cfa_offset(FRAMESIZE)
147e83
+
147e83
+	bl	JUMPTARGET(__errno_location)
147e83
+	nop
147e83
+
147e83
+	/* Restore the stack frame.  */
147e83
+	addi	r1,r1,FRAMESIZE
147e83
+	cfi_adjust_cfa_offset(-FRAMESIZE)
147e83
+	/* Restore the link register.  */
147e83
+	ld	r0,16(r1)
147e83
+	mtlr	r0
147e83
+
147e83
+	lfd	fp1,-8(r1)
147e83
+
147e83
+	/* errno = EDOM */
147e83
+	li	r4,EDOM
147e83
+	stw	r4,0(r3)
147e83
+
147e83
+L(skip_errno_setting):
147e83
+	fsub	fp1,fp1,fp1		/* x - x */
147e83
+	blr
147e83
+
147e83
+	.balign 16
147e83
+L(greater_or_equal_2p23):
147e83
+	fabs	fp1,fp1
147e83
+
147e83
+	srwi	r4,r3,FLOAT_EXPONENT_SHIFT
147e83
+	subi	r4,r4,FLOAT_EXPONENT_BIAS
147e83
+
147e83
+	/* We reduce the input modulo pi/4, so we need 3 bits of integer
147e83
+	   to determine where in 2*pi we are. Index into our array
147e83
+	   accordingly.  */
147e83
+	addi r4,r4,INTEGER_BITS
147e83
+
147e83
+	/* To avoid an expensive divide, for the range we care about (0 - 127)
147e83
+	   we can transform x/28 into:
147e83
+
147e83
+	   x/28 = (x * ((0x100000000 / 28) + 1)) >> 32
147e83
+
147e83
+	   mulhwu returns the top 32 bits of the 64 bit result, doing the
147e83
+	   shift for us in the same instruction. The top 32 bits are undefined,
147e83
+	   so we have to mask them.  */
147e83
+
147e83
+	lis	r6,FX_FRACTION_1_28@h
147e83
+	ori	r6,r6,FX_FRACTION_1_28@l
147e83
+	mulhwu	r5,r4,r6
147e83
+	clrldi	r5,r5,32
147e83
+
147e83
+	/* Get our pointer into the invpio4_table array.  */
147e83
+	sldi	r4,r5,3
147e83
+	addi	r6,r9,(L(invpio4_table)-L(anchor))
147e83
+	add	r4,r4,r6
147e83
+
147e83
+	lfd	fp2,0(r4)
147e83
+	lfd	fp3,8(r4)
147e83
+	lfd	fp4,16(r4)
147e83
+	lfd	fp5,24(r4)
147e83
+
147e83
+	fmul	fp6,fp2,fp1
147e83
+	fmul	fp7,fp3,fp1
147e83
+	fmul	fp8,fp4,fp1
147e83
+	fmul	fp9,fp5,fp1
147e83
+
147e83
+	/* Mask off larger integer bits in highest double word that we don't
147e83
+	   care about to avoid losing precision when combining with smaller
147e83
+	   values.  */
147e83
+	fctiduz	fp10,fp6
147e83
+	mfvsrd	r7,v10
147e83
+	rldicr	r7,r7,0,(63-INTEGER_BITS)
147e83
+	mtvsrd	v10,r7
147e83
+	fcfidu	fp10,fp10		/* Integer bits.  */
147e83
+
147e83
+	fsub	fp6,fp6,fp10		/* highest -= integer bits */
147e83
+
147e83
+	/* Work out the integer component, rounded down. Use the top two
147e83
+	   limbs for this.  */
147e83
+	fadd	fp10,fp6,fp7		/* highest + higher */
147e83
+
147e83
+	fctiduz	fp10,fp10
147e83
+	mfvsrd	r7,v10
147e83
+	andi.	r0,r7,1
147e83
+	fcfidu	fp10,fp10
147e83
+
147e83
+	/* Subtract integer component from highest limb.  */
147e83
+	fsub	fp12,fp6,fp10
147e83
+
147e83
+	beq	L(even_integer)
147e83
+
147e83
+	/* Our integer component is odd, so we are in the -PI/4 to 0 primary
147e83
+	   region. We need to shift our result down by PI/4, and to do this
147e83
+	   in the mod (4/PI) space we simply subtract 1.  */
147e83
+	lfd	fp11,(L(DPone)-L(anchor))(r9)
147e83
+	fsub	fp12,fp12,fp11
147e83
+
147e83
+	/* Now add up all the limbs in order.  */
147e83
+	fadd	fp12,fp12,fp7
147e83
+	fadd	fp12,fp12,fp8
147e83
+	fadd	fp12,fp12,fp9
147e83
+
147e83
+	/* And finally multiply by pi/4.  */
147e83
+	lfd	fp13,(L(pio4)-L(anchor))(r9)
147e83
+	fmul	fp1,fp12,fp13
147e83
+
147e83
+	addi	r7,r7,1
147e83
+	b	L(reduced)
147e83
+
147e83
+L(even_integer):
147e83
+	lfd	fp11,(L(DPone)-L(anchor))(r9)
147e83
+
147e83
+	/* Now add up all the limbs in order.  */
147e83
+	fadd	fp12,fp12,fp7
147e83
+	fadd	fp12,r12,fp8
147e83
+	fadd	fp12,r12,fp9
147e83
+
147e83
+	/* We need to check if the addition of all the limbs resulted in us
147e83
+	   overflowing 1.0.  */
147e83
+	fcmpu	0,fp12,fp11
147e83
+	bgt	L(greater_than_one)
147e83
+
147e83
+	/* And finally multiply by pi/4.  */
147e83
+	lfd	fp13,(L(pio4)-L(anchor))(r9)
147e83
+	fmul	fp1,fp12,fp13
147e83
+
147e83
+	addi	r7,r7,1
147e83
+	b	L(reduced)
147e83
+
147e83
+L(greater_than_one):
147e83
+	/* We did overflow 1.0 when adding up all the limbs. Add 1.0 to our
147e83
+	   integer, and subtract 1.0 from our result. Since that makes the
147e83
+	   integer component odd, we need to subtract another 1.0 as
147e83
+	   explained above.  */
147e83
+	addi	r7,r7,1
147e83
+
147e83
+	lfd	fp11,(L(DPtwo)-L(anchor))(r9)
147e83
+	fsub	fp12,fp12,fp11
147e83
+
147e83
+	/* And finally multiply by pi/4.  */
147e83
+	lfd	fp13,(L(pio4)-L(anchor))(r9)
147e83
+	fmul	fp1,fp12,fp13
147e83
+
147e83
+	addi	r7,r7,1
147e83
+	b	L(reduced)
147e83
+
147e83
+	.balign 16
147e83
+L(less_2pn5):
147e83
+	lis	r4,TWO_PN27@h
147e83
+	ori	r4,r4,TWO_PN27@l
147e83
+
147e83
+	cmpw	r3,r4
147e83
+	blt	L(less_2pn27)
147e83
+
147e83
+	/* A simpler Chebyshev approximation is close enough for this range:
147e83
+	   x+x^3*(SS0+x^2*SS1).  */
147e83
+
147e83
+	lfd	fp10,(L(SS0)-L(anchor))(r9)
147e83
+	lfd	fp11,(L(SS1)-L(anchor))(r9)
147e83
+
147e83
+	fmul	fp2,fp1,fp1		/* x^2 */
147e83
+	fmul	fp3,fp2,fp1		/* x^3 */
147e83
+
147e83
+	fmadd	fp4,fp2,fp11,fp10	/* SS0+x^2*SS1 */
147e83
+	fmadd	fp1,fp3,fp4,fp1		/* x+x^3*(SS0+x^2*SS1) */
147e83
+
147e83
+	frsp	fp1,fp1			/* Round to single precision.  */
147e83
+
147e83
+	blr
147e83
+
147e83
+	.balign 16
147e83
+L(less_2pn27):
147e83
+	cmpwi	r3,0
147e83
+	beq	L(zero)
147e83
+
147e83
+	/* Handle some special cases:
147e83
+
147e83
+	   sinf(subnormal) raises inexact/underflow
147e83
+	   sinf(min_normalized) raises inexact/underflow
147e83
+	   sinf(normalized) raises inexact.  */
147e83
+
147e83
+	lfd	fp2,(L(small)-L(anchor))(r9)
147e83
+
147e83
+	fmul	fp2,fp1,fp2		/* x * small */
147e83
+	fsub	fp1,fp1,fp2		/* x - x * small */
147e83
+
147e83
+	frsp	fp1,fp1
147e83
+
147e83
+	blr
147e83
+
147e83
+	.balign 16
147e83
+L(zero):
147e83
+	blr
147e83
+
147e83
+END (__sinf)
147e83
+
147e83
+	.section .rodata, "a"
147e83
+
147e83
+	.balign 8
147e83
+
147e83
+L(anchor):
147e83
+
147e83
+	/* Chebyshev constants for sin, range -PI/4 - PI/4.  */
147e83
+L(S0):	.8byte	0xbfc5555555551cd9
147e83
+L(S1):	.8byte	0x3f81111110c2688b
147e83
+L(S2):	.8byte	0xbf2a019f8b4bd1f9
147e83
+L(S3):	.8byte	0x3ec71d7264e6b5b4
147e83
+L(S4):	.8byte	0xbe5a947e1674b58a
147e83
+
147e83
+	/* Chebyshev constants for sin, range 2^-27 - 2^-5.  */
147e83
+L(SS0):	.8byte	0xbfc555555543d49d
147e83
+L(SS1):	.8byte	0x3f8110f475cec8c5
147e83
+
147e83
+	/* Chebyshev constants for cos, range -PI/4 - PI/4.  */
147e83
+L(C0):	.8byte	0xbfdffffffffe98ae
147e83
+L(C1):	.8byte	0x3fa55555545c50c7
147e83
+L(C2):	.8byte	0xbf56c16b348b6874
147e83
+L(C3):	.8byte	0x3efa00eb9ac43cc0
147e83
+L(C4):	.8byte	0xbe923c97dd8844d7
147e83
+
147e83
+L(invpio2):
147e83
+	.8byte	0x3fe45f306dc9c883	/* 2/PI */
147e83
+
147e83
+L(invpio4):
147e83
+	.8byte	0x3ff45f306dc9c883	/* 4/PI */
147e83
+
147e83
+L(invpio4_table):
147e83
+	.8byte	0x0000000000000000
147e83
+	.8byte	0x3ff45f306c000000
147e83
+	.8byte	0x3e3c9c882a000000
147e83
+	.8byte	0x3c54fe13a8000000
147e83
+	.8byte	0x3aaf47d4d0000000
147e83
+	.8byte	0x38fbb81b6c000000
147e83
+	.8byte	0x3714acc9e0000000
147e83
+	.8byte	0x3560e4107c000000
147e83
+	.8byte	0x33bca2c756000000
147e83
+	.8byte	0x31fbd778ac000000
147e83
+	.8byte	0x300b7246e0000000
147e83
+	.8byte	0x2e5d2126e8000000
147e83
+	.8byte	0x2c97003248000000
147e83
+	.8byte	0x2ad77504e8000000
147e83
+	.8byte	0x290921cfe0000000
147e83
+	.8byte	0x274deb1cb0000000
147e83
+	.8byte	0x25829a73e0000000
147e83
+	.8byte	0x23fd1046be000000
147e83
+	.8byte	0x2224baed10000000
147e83
+	.8byte	0x20709d338e000000
147e83
+	.8byte	0x1e535a2f80000000
147e83
+	.8byte	0x1cef904e64000000
147e83
+	.8byte	0x1b0d639830000000
147e83
+	.8byte	0x1964ce7d24000000
147e83
+	.8byte	0x17b908bf16000000
147e83
+
147e83
+L(pio4):
147e83
+	.8byte	0x3fe921fb54442d18	/* PI/4 */
147e83
+
147e83
+/* PI/2 as a sum of two doubles. We only use 32 bits of the upper limb
147e83
+   to avoid losing significant bits when multiplying with up to
147e83
+   (2^22)/(pi/2).  */
147e83
+L(pio2hi):
147e83
+	.8byte	0xbff921fb54400000
147e83
+
147e83
+L(pio2lo):
147e83
+	.8byte	0xbdd0b4611a626332
147e83
+
147e83
+L(pio2_table):
147e83
+	.8byte	0
147e83
+	.8byte	0x3ff921fb54442d18	/* 1 * PI/2 */
147e83
+	.8byte	0x400921fb54442d18	/* 2 * PI/2 */
147e83
+	.8byte	0x4012d97c7f3321d2	/* 3 * PI/2 */
147e83
+	.8byte	0x401921fb54442d18	/* 4 * PI/2 */
147e83
+	.8byte	0x401f6a7a2955385e	/* 5 * PI/2 */
147e83
+	.8byte	0x4022d97c7f3321d2	/* 6 * PI/2 */
147e83
+	.8byte	0x4025fdbbe9bba775	/* 7 * PI/2 */
147e83
+	.8byte	0x402921fb54442d18	/* 8 * PI/2 */
147e83
+	.8byte	0x402c463abeccb2bb	/* 9 * PI/2 */
147e83
+	.8byte	0x402f6a7a2955385e	/* 10 * PI/2 */
147e83
+
147e83
+L(small):
147e83
+	.8byte	0x3cd0000000000000	/* 2^-50 */
147e83
+
147e83
+L(ones):
147e83
+	.8byte	0x3ff0000000000000	/* +1.0 */
147e83
+	.8byte	0xbff0000000000000	/* -1.0 */
147e83
+
147e83
+L(DPhalf):
147e83
+	.8byte	0x3fe0000000000000	/* 0.5 */
147e83
+
147e83
+L(DPone):
147e83
+	.8byte	0x3ff0000000000000	/* 1.0 */
147e83
+
147e83
+L(DPtwo):
147e83
+	.8byte	0x4000000000000000	/* 2.0 */
147e83
+
147e83
+weak_alias(__sinf, sinf)
147e83
-- 
147e83
2.1.0
147e83