about summary refs log tree commit diff
path: root/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S
diff options
context:
space:
mode:
authorLuis Machado <luis@gargoyle.(none)>2010-07-13 16:39:26 -0300
committerLuis Machado <luis@gargoyle.(none)>2010-07-13 16:39:26 -0300
commit0eacdbad318c940ee4d45ed87155e73e990fe2bb (patch)
treeb999a88e4dff1face179697c1d4fc1c2ac34bfbf /sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S
parent052b16c76579af4519983e47c8d1d1f05d9a81a8 (diff)
downloadglibc-ibm/2.8/master.tar.gz
glibc-ibm/2.8/master.tar.xz
glibc-ibm/2.8/master.zip
powerpc: POWER7 optimizations ibm/2.8/master
    Add optimizations for classification functions (32-bit and 64-bit) and
    string functions (32-bit and 64-bit).

    powerpc: Re-work the Implies structure

    This patch tries to organize the implies files for ppc, since there are
    a number of processors and most of them are compatible with each other
    (backwards compatible).

    Having in mind that we start the search for processor-specific files in
    the sysdeps/unix/sysv/linux tree
    (sysdeps/unix/sysv/linux/powerpc/powerpc[32|64]/[processor]/fpu to be
    exact), we would like to grab any linux-specific code from that tree
    prior to going through the other tree (sysdeps/powerpc/...).

    For that, i removed the Implies files that were originally inside the
    fpu directories and placed then in the non-fpu directories (still inside
    the unix/sysv/linux tree). If no processor-specific/linux-specific files
    could be found, we "imply" the other tree's (sysdeps/powerpc/...) fpu
    directory for that specific processor AND also the non-fpu directory for
    that same tree.

    If, again, no processor-specific code is found, we read another Implies
    file that will point to the most compatible processor that we should
    grab code from, and so on, until we reach the power4 processor.

    So, in summary, the Implies files will live inside these directories
    now:

    * sysdeps/unix/sysv/linux/powerpc/powerpc[32|64]/[processor]
    * sysdeps/powerpc/powerpc[32|64]/[processor]

    Practical example of the order we will use to pick power6-specific code
    with the new structure.

    sysdeps/unix/sysv/linux/powerpc/powerpc[32|64]/power6/fpu ->
    sysdeps/unix/sysv/linux/powerpc/powerpc[32|64]/power6 ->
    sysdeps/powerpc/powerpc[32|64]/power6/fpu ->
    sysdeps/powerpc/powerpc[32|64]/power6 ->
    sysdeps/powerpc/powerpc[32|64]/power5+/fpu ->
    sysdeps/powerpc/powerpc[32|64]/power5+ ->
    sysdeps/powerpc/powerpc[32|64]/power5/fpu ->
    sysdeps/powerpc/powerpc[32|64]/power5 ->
    sysdeps/powerpc/powerpc[32|64]/power4/fpu ->
    sysdeps/powerpc/powerpc[32|64]/power4 (from here, it'll go to the
    generic path as usual)
Diffstat (limited to 'sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S')
-rw-r--r--sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S92
1 files changed, 92 insertions, 0 deletions
diff --git a/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S b/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S
new file mode 100644
index 0000000000..852539f24b
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S
@@ -0,0 +1,92 @@
+/* isnan().  PowerPC32/POWER7 version.
+   Copyright (C) 2010 Free Software Foundation, Inc.
+   Contributed by Luis Machado <luisgpm@br.ibm.com>.
+   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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* int __isnan(x)  */
+	.section    .rodata.cst8,"aM",@progbits,8
+	.align 3
+.LC0:   /* 1.0 */
+	.quad	    0x3ff0000000000000
+
+	.section    ".text"
+	.type	    __isnan, @function
+	.machine    power7
+ENTRY (__isnan)
+#ifdef SHARED
+	mflr	r11
+	cfi_register(lr,r11)
+
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	lfd	fp0,.LC0-1b@l(r9)
+
+	mtlr	r11
+	cfi_same_value (lr)
+#else
+	lis	r9,.LC0@ha
+	lfd	fp0,.LC0@l(r9)
+#endif
+	ftdiv	cr7,fp1,fp0
+	li	r3,0
+	bflr	30	      /* If not NaN or Inf, finish. */
+
+	/* We have -INF/+INF/NaN or a denormal.  */
+
+	stwu	r1,-16(r1)    /* Allocate stack space.  */
+	stfd	fp1,8(r1)     /* Transfer FP to GPR's.  */
+	ori	2,2,0	      /* Force a new dispatch group.  */
+	lwz     r4,8(r1)      /* Load the upper half of the FP value.  */
+	lwz     r5,12(r1)     /* Load the lower half of the FP value.  */
+	addi	r1,r1,16      /* Reset the stack pointer.  */
+	lis     r0,0x7ff0     /* Load the upper portion for an INF/NaN.  */
+	clrlwi  r4,r4,1	      /* r4 = abs(r4).  */
+	cmpw    cr7,r4,r0     /* if (abs(r4) <= inf).  */
+	cmpwi   cr6,r5,0      /* r5 == 0x00000000?  */
+	bltlr	cr7	      /* LT means we have a denormal.  */
+	bgt	cr7,L(NaN)    /* GT means we have a NaN.  */
+	beqlr	cr6	      /* EQ means we have +/-INF.  */
+L(NaN):
+	li      r3,1	      /* x == NaN?  */
+	blr
+	END (__isnan)
+
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
+
+/* It turns out that the 'double' version will also always work for
+   single-precision.  */
+strong_alias (__isnan, __isnanf)
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__isnan, __isnanl)
+weak_alias (__isnan, isnanl)
+#endif
+
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
+compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
+# endif
+#endif