aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdhemerval Zanella <azanella@linux.vnet.ibm.com>2013-03-31 08:51:41 -0500
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>2013-03-31 08:51:41 -0500
commit2d753391bc0e5b57db029ccda01e83aa6a1844b1 (patch)
tree487b1193d0f90c4acbf20c0a8ecd88ce959fa428
parentaec101aa9897a41f894f4cd9caa14e39fc73d091 (diff)
downloadglibc-2d753391bc0e5b57db029ccda01e83aa6a1844b1.tar
glibc-2d753391bc0e5b57db029ccda01e83aa6a1844b1.tar.gz
glibc-2d753391bc0e5b57db029ccda01e83aa6a1844b1.tar.bz2
glibc-2d753391bc0e5b57db029ccda01e83aa6a1844b1.zip
PowerPC: strchr ifunc for PPC32
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/Makefile1
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c7
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/rtld-strchr.S1
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/strchr-power7.S (renamed from sysdeps/powerpc/powerpc32/power7/strchr.S)6
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/strchr.S82
5 files changed, 93 insertions, 4 deletions
diff --git a/sysdeps/powerpc/powerpc32/multiarch/Makefile b/sysdeps/powerpc/powerpc32/multiarch/Makefile
index fbf298af0f..c3a3c58dde 100644
--- a/sysdeps/powerpc/powerpc32/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc32/multiarch/Makefile
@@ -5,6 +5,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
strncmp-power7 strncmp-power4 strlen-power7 \
strcasecmp-power7 strcasecmp_l-power7 \
strnlen-power7 strnlen-c \
+ strchr-power7 \
mempcpy-power7 mempcpy-c \
memchr-power7 memchr-c \
memrchr-power7 memrchr-c \
diff --git a/sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c
index 1399548b67..faeef4a91c 100644
--- a/sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c
@@ -142,6 +142,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL_ADD (array, i, strnlen, 1,
__strnlen_ppc32))
+ IFUNC_IMPL (i, name, strchr,
+ IFUNC_IMPL_ADD (array, i, strchr,
+ hwcap & PPC_FEATURE_HAS_VSX,
+ __strchr_power7)
+ IFUNC_IMPL_ADD (array, i, strchr, 1,
+ __strchr_ppc32))
+
IFUNC_IMPL (i, name, strchrnul,
IFUNC_IMPL_ADD (array, i, strchrnul,
hwcap & PPC_FEATURE_HAS_VSX,
diff --git a/sysdeps/powerpc/powerpc32/multiarch/rtld-strchr.S b/sysdeps/powerpc/powerpc32/multiarch/rtld-strchr.S
new file mode 100644
index 0000000000..d969c0ab57
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/rtld-strchr.S
@@ -0,0 +1 @@
+#include "../strchr.S"
diff --git a/sysdeps/powerpc/powerpc32/power7/strchr.S b/sysdeps/powerpc/powerpc32/multiarch/strchr-power7.S
index 0ecadb271a..32bc5bb746 100644
--- a/sysdeps/powerpc/powerpc32/power7/strchr.S
+++ b/sysdeps/powerpc/powerpc32/multiarch/strchr-power7.S
@@ -21,7 +21,7 @@
/* int [r3] strchr (char *s [r3], int c [r4]) */
.machine power7
-ENTRY (strchr)
+ENTRY (__strchr_power7)
CALL_MCOUNT
dcbt 0,r3
clrrwi r8,r3,2 /* Align the address to word boundary. */
@@ -195,6 +195,4 @@ L(done_null):
srwi r0,r0,3 /* Convert leading zeros to bytes. */
add r3,r8,r0 /* Return address of the matching null byte. */
blr
-END (strchr)
-weak_alias (strchr, index)
-libc_hidden_builtin_def (strchr)
+END (__strchr_power7)
diff --git a/sysdeps/powerpc/powerpc32/multiarch/strchr.S b/sysdeps/powerpc/powerpc32/multiarch/strchr.S
new file mode 100644
index 0000000000..08f0d90440
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/strchr.S
@@ -0,0 +1,82 @@
+/* Optimized strchr implementation for PowerPC32.
+ Copyright (C) 2013 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 <rtld-global-offsets.h>
+
+/* Define multiple versions only for the definition in libc. */
+#if defined SHARED && !defined NOT_IN_libc
+ .text
+ENTRY(strchr)
+ .type strchr, @gnu_indirect_function
+# ifdef PIC
+ mflr r11
+ cfi_register (lr,r11)
+ bcl 20,31,1f
+1: mflr r5
+ addis r5,r5,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r5,r5,_GLOBAL_OFFSET_TABLE_-1b@l
+ lwz r6,_rtld_global_ro@got(r5)
+ mtlr r11
+ cfi_same_value (lr)
+ lwz r6,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r6)
+# else
+ lis r6,(_dl_hwcap+4)@ha
+ lwz r6,(_dl_hwcap+4)@l(r6)
+# endif
+ /* r5 - got pointer | r6 - _dl_hwcap */
+ andi. r7,r6,PPC_FEATURE_HAS_VSX
+ bne- L(power7)
+# ifdef PIC
+ lwz r3,__strchr_ppc32@got(r5)
+# else
+ lis r3,__strchr_ppc32@ha
+ lwz r3,__strchr_ppc32@l(r3)
+# endif
+ blr
+L(power7):
+# ifdef PIC
+ lwz r3,__strchr_power7@got(r5)
+# else
+ lis r3,__strchr_power7@ha
+ lwz r3,__strchr_power7@l(r3)
+# endif
+ blr
+END(strchr)
+
+# undef ENTRY
+# define ENTRY(name) \
+ .globl C_SYMBOL_NAME(__strchr_ppc32); \
+ .type C_SYMBOL_NAME(__strchr_ppc32),@function; \
+ .align ALIGNARG(2); \
+ C_LABEL(__strchr_ppc32) \
+ cfi_startproc; \
+ CALL_MCOUNT
+
+# undef END
+# define END(name) \
+ cfi_endproc; \
+ ASM_SIZE_DIRECTIVE(__strchr_ppc32) \
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ .globl __GI_strchr; __GI_strchr = __strchr_ppc32
+
+#endif
+
+#include "../strchr.S"