This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 08/36] PowerPC: rawmemchr multilib for PowerPC32
- From: Adhemerval Zanella <azanella at linux dot vnet dot ibm dot com>
- To: "GNU C. Library" <libc-alpha at sourceware dot org>
- Date: Mon, 19 Aug 2013 18:28:06 -0300
- Subject: [PATCH 08/36] PowerPC: rawmemchr multilib for PowerPC32
- References: <52127ABC dot 40008 at linux dot vnet dot ibm dot com>
2013-08-19 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
* string/rawmemchr.c (__rawmemchr): Using macro to redefine symbol
name.
* sysdeps/powerpc/powerpc32/power7/rawmemchr.S: Move to ...
* sysdeps/powerpc/powerpc32/multiarch/rawmemchr-power7.S: ... here.
(__memrchr): Rename symbol name to __memrchr_power7 and remove the
libc_hidden_builtin_def and weak_alias.
* sysdeps/powerpc/powerpc32/multiarch/rawmemchr-ppc32.c: New file:
default memrchr PPC32 implementation.
* sysdeps/powerpc/powerpc32/multiarch/rawmemchr.c: New file:
multiarch rawmemrchr for PPC32.
* sysdeps/powerpc/powerpc32/multiarch/Makefile: Added rawmemrchr
multiarch objects.
* sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list
(__libc_ifunc_impl_list): Likewise.
--
diff --git a/string/rawmemchr.c b/string/rawmemchr.c
index 30fbe87..3b6e19b 100644
--- a/string/rawmemchr.c
+++ b/string/rawmemchr.c
@@ -46,11 +46,13 @@
#include <sys/types.h>
#undef memchr
-
+#ifndef RAWMEMCHR
+# define RAWMEMCHR __rawmemchr
+#endif
/* Find the first occurrence of C in S. */
__ptr_t
-__rawmemchr (s, c_in)
+RAWMEMCHR (s, c_in)
const __ptr_t s;
int c_in;
{
diff --git a/sysdeps/powerpc/powerpc32/multiarch/Makefile b/sysdeps/powerpc/powerpc32/multiarch/Makefile
index fde4fbf..ab482ba 100644
--- a/sysdeps/powerpc/powerpc32/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc32/multiarch/Makefile
@@ -3,5 +3,6 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
memcpy-power4 memcpy-ppc32 memcmp-power7 memcmp-power4 \
memcmp-ppc32 memset-power7 memset-power6 memset-power4 \
memset-ppc32 mempcpy-power7 mempcpy-ppc32 memchr-power7 \
- memchr-ppc32 memrchr-power7 memrchr-ppc32
+ memchr-ppc32 memrchr-power7 memrchr-ppc32 rawmemchr-power7 \
+ rawmemchr-ppc32
endif
diff --git a/sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c
index 4b3dd75..7d65f52 100644
--- a/sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c
@@ -71,6 +71,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL_ADD (array, i, memrchr, 1,
__memrchr_ppc32))
+ /* Support sysdeps/powerpc/powerpc32/multiarch/rawmemchr.c. */
+ IFUNC_IMPL (i, name, rawmemchr,
+ IFUNC_IMPL_ADD (array, i, rawmemchr,
+ hwcap & PPC_FEATURE_HAS_VSX,
+ __rawmemchr_power7)
+ IFUNC_IMPL_ADD (array, i, rawmemchr, 1,
+ __rawmemchr_ppc32))
+
#ifdef SHARED
/* Support sysdeps/powerpc/powerpc32/multiarch/memset.c. */
IFUNC_IMPL (i, name, memset,
diff --git a/sysdeps/powerpc/powerpc32/multiarch/rawmemchr-power7.S b/sysdeps/powerpc/powerpc32/multiarch/rawmemchr-power7.S
new file mode 100644
index 0000000..b495393
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/rawmemchr-power7.S
@@ -0,0 +1,97 @@
+/* Optimized rawmemchr implementation for PowerPC32/POWER7 using cmpb insn.
+ Copyright (C) 2010-2013 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+/* int [r3] rawmemchr (void *s [r3], int c [r4]) */
+ .machine power7
+ENTRY (__rawmemchr_power7)
+ CALL_MCOUNT
+ dcbt 0,r3
+ clrrwi r8,r3,2 /* Align the address to word boundary. */
+
+ /* Replicate byte to word. */
+ rlwimi r4,r4,8,16,23
+ rlwimi r4,r4,16,0,15
+
+ /* Now r4 has a word of c bytes. */
+
+ rlwinm r6,r3,3,27,28 /* Calculate padding. */
+ lwz r12,0(r8) /* Load word from memory. */
+ cmpb r5,r12,r4 /* Compare each byte against c byte. */
+ slw r5,r5,r6 /* Move left to discard ignored bits. */
+ srw r5,r5,r6 /* Bring the bits back as zeros. */
+ cmpwi cr7,r5,0 /* If r5 == 0, no c bytes have been found. */
+ bne cr7,L(done)
+
+ mtcrf 0x01,r8
+
+ /* Are we now aligned to a doubleword boundary? If so, skip to
+ the main loop. Otherwise, go through the alignment code. */
+
+ bt 29,L(loop)
+
+ /* Handle WORD2 of pair. */
+ lwzu r12,4(r8)
+ cmpb r5,r12,r4
+ cmpwi cr7,r5,0
+ bne cr7,L(done)
+ b L(loop) /* We branch here (rather than falling through)
+ to skip the nops due to heavy alignment
+ of the loop below. */
+
+ /* Main loop to look for the end of the string. Since it's a
+ small loop (< 8 instructions), align it to 32-bytes. */
+ .p2align 5
+L(loop):
+ /* Load two words, compare and merge in a
+ single register for speed. This is an attempt
+ to speed up the byte-checking process for bigger strings. */
+ lwz r12,4(r8)
+ lwzu r11,8(r8)
+ cmpb r5,r12,r4
+ cmpb r6,r11,r4
+ or r7,r5,r6
+ cmpwi cr7,r7,0
+ beq cr7,L(loop)
+
+ /* OK, one (or both) of the words contains a 'c' byte. Check
+ the first word and decrement the address in case the first
+ word really contains a c byte. */
+
+ cmpwi cr6,r5,0
+ addi r8,r8,-4
+ bne cr6,L(done)
+
+ /* The 'c' byte must be in the second word. Adjust the address
+ again and move the result of cmpb to r10 so we can calculate the
+ pointer. */
+ mr r5,r6
+ addi r8,r8,4
+
+ /* r5 has the output of the cmpb instruction, that is, it contains
+ 0xff in the same position as the 'c' byte in the original
+ word from the string. Use that fact to find out what is
+ the position of the byte inside the string. */
+L(done):
+ cntlzw r0,r5 /* Count leading zeros before the match. */
+ srwi r0,r0,3 /* Convert leading zeroes to bytes. */
+ add r3,r8,r0 /* Return address of the matching char. */
+ blr
+END (__rawmemchr_power7)
diff --git a/sysdeps/powerpc/powerpc32/multiarch/rawmemchr-ppc32.c b/sysdeps/powerpc/powerpc32/multiarch/rawmemchr-ppc32.c
new file mode 100644
index 0000000..a0a9504
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/rawmemchr-ppc32.c
@@ -0,0 +1,32 @@
+/* PowerPC32 default implementation of rawmemchr.
+ 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 <string.h>
+
+#define RAWMEMCHR __rawmemchr_ppc32
+#undef weak_alias
+#define weak_alias(a, b)
+#ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__rawmemchr_ppc32, __GI___rawmemchr, __rawmemchr_ppc32);
+#endif
+
+extern __typeof (rawmemchr) __rawmemchr_ppc32 attribute_hidden;
+
+#include <string/rawmemchr.c>
diff --git a/sysdeps/powerpc/powerpc32/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc32/multiarch/rawmemchr.c
new file mode 100644
index 0000000..b033f47
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/rawmemchr.c
@@ -0,0 +1,37 @@
+/* Multiple versions of rawmemchr.
+ 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/>. */
+
+#ifndef NOT_IN_libc
+# include <string.h>
+# include <shlib-compat.h>
+# include "init-arch.h"
+
+extern __typeof (__rawmemchr) __rawmemchr_ppc32 attribute_hidden;
+extern __typeof (__rawmemchr) __rawmemchr_power7 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+ ifunc symbol properly. */
+libc_ifunc (__rawmemchr,
+ (hwcap & PPC_FEATURE_HAS_VSX)
+ ? __rawmemchr_power7
+ : __rawmemchr_ppc32);
+
+weak_alias (__rawmemchr, rawmemchr)
+#else
+#include <string/rawmemchr.c>
+#endif
diff --git a/sysdeps/powerpc/powerpc32/power7/rawmemchr.S b/sysdeps/powerpc/powerpc32/power7/rawmemchr.S
deleted file mode 100644
index a80c74a..0000000
--- a/sysdeps/powerpc/powerpc32/power7/rawmemchr.S
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Optimized rawmemchr implementation for PowerPC32/POWER7 using cmpb insn.
- Copyright (C) 2010-2013 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, see
- <http://www.gnu.org/licenses/>. */
-
-#include <sysdep.h>
-
-/* int [r3] rawmemchr (void *s [r3], int c [r4]) */
- .machine power7
-ENTRY (__rawmemchr)
- CALL_MCOUNT
- dcbt 0,r3
- clrrwi r8,r3,2 /* Align the address to word boundary. */
-
- /* Replicate byte to word. */
- rlwimi r4,r4,8,16,23
- rlwimi r4,r4,16,0,15
-
- /* Now r4 has a word of c bytes. */
-
- rlwinm r6,r3,3,27,28 /* Calculate padding. */
- lwz r12,0(r8) /* Load word from memory. */
- cmpb r5,r12,r4 /* Compare each byte against c byte. */
- slw r5,r5,r6 /* Move left to discard ignored bits. */
- srw r5,r5,r6 /* Bring the bits back as zeros. */
- cmpwi cr7,r5,0 /* If r5 == 0, no c bytes have been found. */
- bne cr7,L(done)
-
- mtcrf 0x01,r8
-
- /* Are we now aligned to a doubleword boundary? If so, skip to
- the main loop. Otherwise, go through the alignment code. */
-
- bt 29,L(loop)
-
- /* Handle WORD2 of pair. */
- lwzu r12,4(r8)
- cmpb r5,r12,r4
- cmpwi cr7,r5,0
- bne cr7,L(done)
- b L(loop) /* We branch here (rather than falling through)
- to skip the nops due to heavy alignment
- of the loop below. */
-
- /* Main loop to look for the end of the string. Since it's a
- small loop (< 8 instructions), align it to 32-bytes. */
- .p2align 5
-L(loop):
- /* Load two words, compare and merge in a
- single register for speed. This is an attempt
- to speed up the byte-checking process for bigger strings. */
- lwz r12,4(r8)
- lwzu r11,8(r8)
- cmpb r5,r12,r4
- cmpb r6,r11,r4
- or r7,r5,r6
- cmpwi cr7,r7,0
- beq cr7,L(loop)
-
- /* OK, one (or both) of the words contains a 'c' byte. Check
- the first word and decrement the address in case the first
- word really contains a c byte. */
-
- cmpwi cr6,r5,0
- addi r8,r8,-4
- bne cr6,L(done)
-
- /* The 'c' byte must be in the second word. Adjust the address
- again and move the result of cmpb to r10 so we can calculate the
- pointer. */
- mr r5,r6
- addi r8,r8,4
-
- /* r5 has the output of the cmpb instruction, that is, it contains
- 0xff in the same position as the 'c' byte in the original
- word from the string. Use that fact to find out what is
- the position of the byte inside the string. */
-L(done):
- cntlzw r0,r5 /* Count leading zeros before the match. */
- srwi r0,r0,3 /* Convert leading zeroes to bytes. */
- add r3,r8,r0 /* Return address of the matching char. */
- blr
-END (__rawmemchr)
-weak_alias (__rawmemchr,rawmemchr)
-libc_hidden_builtin_def (__rawmemchr)