about summary refs log tree commit diff
path: root/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S
diff options
context:
space:
mode:
authorAdhemerval Zanella <azanella@linux.vnet.ibm.com>2014-02-27 09:45:41 -0600
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>2014-02-27 12:58:33 -0600
commit4393fc119c34e97519b9b7a4fc94066b283be452 (patch)
treedffac0629930499b0f88886fca4f1b094ef74fa5 /sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S
parent487972aea52004f604c2878c8c9d3e77670f2c32 (diff)
downloadglibc-4393fc119c34e97519b9b7a4fc94066b283be452.tar.gz
glibc-4393fc119c34e97519b9b7a4fc94066b283be452.tar.xz
glibc-4393fc119c34e97519b9b7a4fc94066b283be452.zip
PowerPC: Optimized isinf/isinff for POWER8
This patch add a optimized isinf/isinff implementation for POWER8
using the new Move From VSR Doubleword instruction to gains some
cycles from FP to GRP register move.
Diffstat (limited to 'sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S')
-rw-r--r--sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S61
1 files changed, 61 insertions, 0 deletions
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S
new file mode 100644
index 0000000000..0e92af8d9f
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S
@@ -0,0 +1,61 @@
+/* isinf().  PowerPC64/POWER8 version.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+#define MFVSRD_R3_V1  .byte 0x7c,0x23,0x00,0x66     /* mfvsrd  r3,vs1  */
+
+/* int [r3] __isinf([fp1] x)  */
+
+EALIGN (__isinf, 4, 0)
+	CALL_MCOUNT 0
+	MFVSRD_R3_V1
+	lis     r9,0x7ff0     /* r9 = 0x7ff0  */
+	rldicl  r10,r3,0,1    /* r10 = r3 & (0x8000000000000000)  */
+	sldi    r9,r9,32      /* r9 = r9 << 52  */
+	cmpd    cr7,r10,r9    /* fp1 & 0x7ff0000000000000 ?  */
+	beq     cr7,L(inf)
+	li      r3,0          /* Not inf  */
+	blr
+L(inf):
+	sradi   r3,r3,63      /* r3 = r3 >> 63  */
+	ori     r3,r3,1       /* r3 = r3 | 0x1  */
+	blr
+END (__isinf)
+
+hidden_def (__isinf)
+weak_alias (__isinf, isinf)
+
+/* It turns out that the 'double' version will also always work for
+   single-precision.  */
+strong_alias (__isinf, __isinff)
+hidden_def (__isinff)
+weak_alias (__isinff, isinff)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__isinf, __isinfl)
+weak_alias (__isinf, isinfl)
+#endif
+
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isinf, __isinfl, GLIBC_2_0);
+compat_symbol (libc, isinf, isinfl, GLIBC_2_0);
+# endif
+#endif