about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAdhemerval Zanella <azanella@linux.vnet.ibm.com>2013-03-07 14:37:13 -0300
committerTulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>2013-03-07 14:38:05 -0300
commitd929af5d898233d5115a35b1cb6048895645c8d0 (patch)
tree1895386c9e99b24997bed261669ef2b27c99b8da
parent642e52808d921b2205109ba3cd8dc713be38bc19 (diff)
downloadglibc-d929af5d898233d5115a35b1cb6048895645c8d0.tar.gz
glibc-d929af5d898233d5115a35b1cb6048895645c8d0.tar.xz
glibc-d929af5d898233d5115a35b1cb6048895645c8d0.zip
PowerPC: Add 32-bit multilib implementation of memcpy
Move and rename specialized memcpy implementation to multilib folder and
add IFUNC memcpy source.
-rw-r--r--ChangeLog17
-rw-r--r--sysdeps/powerpc/powerpc32/memcpy.S (renamed from sysdeps/powerpc/powerpc32/power4/memcpy.S)0
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/Makefile3
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c55
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/memcpy-a2.S (renamed from sysdeps/powerpc/powerpc32/a2/memcpy.S)5
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/memcpy-cell.S (renamed from sysdeps/powerpc/powerpc32/cell/memcpy.S)5
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/memcpy-power6.S (renamed from sysdeps/powerpc/powerpc32/power6/memcpy.S)8
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/memcpy-power7.S (renamed from sysdeps/powerpc/powerpc32/power7/memcpy.S)5
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/memcpy.S112
9 files changed, 196 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 4f08ec6286..7483f903a1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2013-03-07  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+	    Tulio Magno Quites Machado Filho  <tuliom@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc32/multiarch/Makefile: New file.
+	* sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c: Likewise.
+	* sysdeps/powerpc/powerpc32/multiarch/memcpy.S: Likewise.
+	* sysdeps/powerpc/powerpc32/a2/memcpy.S: Moved to...
+	* sysdeps/powerpc/powerpc32/multiarch/memcpy-a2.S: ... here.
+	* sysdeps/powerpc/powerpc32/cell/memcpy.S: Moved to...
+	* sysdeps/powerpc/powerpc32/multiarch/memcpy-cell.S: ... here.
+	* sysdeps/powerpc/powerpc32/power4/memcpy.S: Moved to...
+	* sysdeps/powerpc/powerpc32/memcpy.S: ... here.
+	* sysdeps/powerpc/powerpc32/power6/memcpy.S: Moved to...
+	* sysdeps/powerpc/powerpc32/multiarch/memcpy-power6.S: ... here.
+	* sysdeps/powerpc/powerpc32/power7/memcpy.S: Moved to...
+	* sysdeps/powerpc/powerpc32/multiarch/memcpy-power7.S: ... here.
+
 2013-03-07  Andreas Jaeger  <aj@suse.de>
 
 	* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
diff --git a/sysdeps/powerpc/powerpc32/power4/memcpy.S b/sysdeps/powerpc/powerpc32/memcpy.S
index d9146631e3..d9146631e3 100644
--- a/sysdeps/powerpc/powerpc32/power4/memcpy.S
+++ b/sysdeps/powerpc/powerpc32/memcpy.S
diff --git a/sysdeps/powerpc/powerpc32/multiarch/Makefile b/sysdeps/powerpc/powerpc32/multiarch/Makefile
new file mode 100644
index 0000000000..9c2789015a
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),string)
+sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell
+endif
diff --git a/sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c
new file mode 100644
index 0000000000..2a23669f16
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list.c
@@ -0,0 +1,55 @@
+/* Enumerate available IFUNC implementations of a function.  PowerPC32 version.
+   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 <assert.h>
+#include <string.h>
+#include <wchar.h>
+#include <ldsodefs.h>
+#include <ifunc-impl-list.h>
+
+/* Maximum number of IFUNC implementations.  */
+#define MAX_IFUNC	5
+
+size_t
+__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+			size_t max)
+{
+  assert (max >= MAX_IFUNC);
+
+  size_t i = 0;
+
+  uint32_t hwcap;
+
+  hwcap = GLRO(dl_hwcap);
+
+#ifdef SHARED
+  IFUNC_IMPL (i, name, memcpy,
+	      IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_HAS_VSX,
+			      __memcpy_power7)
+	      IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_ARCH_2_06,
+			      __memcpy_a2)
+	      IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_ARCH_2_05,
+			      __memcpy_power6)
+	      IFUNC_IMPL_ADD (array, i, memcpy,
+			      hwcap & (PPC_FEATURE_CELL_BE >> 16),
+			      __memcpy_cell)
+	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ppc32))
+#endif
+
+  return i;
+}
diff --git a/sysdeps/powerpc/powerpc32/a2/memcpy.S b/sysdeps/powerpc/powerpc32/multiarch/memcpy-a2.S
index f2f63b1802..67e0f1b1aa 100644
--- a/sysdeps/powerpc/powerpc32/a2/memcpy.S
+++ b/sysdeps/powerpc/powerpc32/multiarch/memcpy-a2.S
@@ -23,7 +23,7 @@
 #define ZERO_AHEAD 2            /* no cache lines DST zeroing ahead  */
 
 	.machine  a2
-EALIGN (memcpy, 5, 0)
+EALIGN (__memcpy_a2, 5, 0)
 	CALL_MCOUNT
 
 	dcbt    0,r4            /* Prefetch ONE SRC cacheline  */
@@ -523,5 +523,4 @@ L(endloop2_128):
 	b       L(lessthancacheline)
 
 
-END (memcpy)
-libc_hidden_builtin_def (memcpy)
+END (__memcpy_a2)
diff --git a/sysdeps/powerpc/powerpc32/cell/memcpy.S b/sysdeps/powerpc/powerpc32/multiarch/memcpy-cell.S
index f3605d790f..8b0bf407ef 100644
--- a/sysdeps/powerpc/powerpc32/cell/memcpy.S
+++ b/sysdeps/powerpc/powerpc32/multiarch/memcpy-cell.S
@@ -39,7 +39,7 @@
 
 .align  7
 
-EALIGN (memcpy, 5, 0)
+EALIGN (__memcpy_cell, 5, 0)
 	CALL_MCOUNT
 
 	dcbt	0,r4		/* Prefetch ONE SRC cacheline  */
@@ -238,5 +238,4 @@ EALIGN (memcpy, 5, 0)
 	stb	r0,0(r6)
 1:	blr
 
-END (memcpy)
-libc_hidden_builtin_def (memcpy)
+END (__memcpy_cell)
diff --git a/sysdeps/powerpc/powerpc32/power6/memcpy.S b/sysdeps/powerpc/powerpc32/multiarch/memcpy-power6.S
index d900028cb6..4e39046e53 100644
--- a/sysdeps/powerpc/powerpc32/power6/memcpy.S
+++ b/sysdeps/powerpc/powerpc32/multiarch/memcpy-power6.S
@@ -21,7 +21,7 @@
 /* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
    Returns 'dst'.
 
-   Memcpy handles short copies (< 32-bytes) using a binary move blocks 
+   Memcpy handles short copies (< 32-bytes) using a binary move blocks
    (no loops) of lwz/stw.  The tail (remaining 1-3) bytes is handled
    with the appropriate combination of byte and halfword load/stores.
    There is minimal effort to optimize the alignment of short moves.
@@ -32,7 +32,7 @@
    Each case has an optimized unrolled loop.   */
 
 	.machine power6
-EALIGN (memcpy, 5, 0)
+EALIGN (__memcpy_power6, 5, 0)
 	CALL_MCOUNT
 
     stwu   1,-32(1)
@@ -835,6 +835,4 @@ L(wdus_0):
     lwz  31,24(1)
     addi 1,1,32
     blr
-END (memcpy)
-
-libc_hidden_builtin_def (memcpy)
+END (__memcpy_power6)
diff --git a/sysdeps/powerpc/powerpc32/power7/memcpy.S b/sysdeps/powerpc/powerpc32/multiarch/memcpy-power7.S
index 7f00778236..00e9fd729b 100644
--- a/sysdeps/powerpc/powerpc32/power7/memcpy.S
+++ b/sysdeps/powerpc/powerpc32/multiarch/memcpy-power7.S
@@ -23,7 +23,7 @@
    Returns 'dst'.  */
 
 	.machine  power7
-EALIGN (memcpy, 5, 0)
+EALIGN (__memcpy_power7, 5, 0)
 	CALL_MCOUNT
 
 	stwu    1,-32(1)
@@ -520,5 +520,4 @@ L(end_unaligned_loop):
 	addi    1,1,32
 	blr
 
-END (memcpy)
-libc_hidden_builtin_def (memcpy)
+END (__memcpy_power7)
diff --git a/sysdeps/powerpc/powerpc32/multiarch/memcpy.S b/sysdeps/powerpc/powerpc32/multiarch/memcpy.S
new file mode 100644
index 0000000000..7547520299
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/memcpy.S
@@ -0,0 +1,112 @@
+/* Optimized memcpy implementation for PowerPC32 on PowerPC64.
+   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(memcpy)
+	.type   memcpy, @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)
+	andi.	r7,r6,PPC_FEATURE_ARCH_2_06
+	bne-	L(powerA2)
+	andi.	r7,r6,PPC_FEATURE_ARCH_2_05
+	bne-	L(power6)
+	andis.	r7,r6,(PPC_FEATURE_CELL_BE >> 16)
+	bne-	L(powerCELL)
+# ifdef PIC
+	lwz	r3,__memcpy_ppc32@got(r5)
+# else
+	lis	r3,__memcpy_ppc32@ha
+	lwz	r3,__memcpy_ppc32@l(r3)
+# endif
+	blr
+L(power7):
+# ifdef PIC
+	lwz	r3,__memcpy_power7@got(r5)
+# else
+	lis	r3,__memcpy_power7@ha
+	lwz	r3,__memcpy_power7@l(r3)
+# endif
+	blr
+L(powerA2):
+# ifdef PIC
+	lwz	r3,__memcpy_a2@got(r5)
+# else
+	lis	r3,__memcpy_a2@ha
+	lwz	r3,__memcpy_a2@l(r3)
+# endif
+	blr
+L(power6):
+# ifdef PIC
+	lwz	r3,__memcpy_power6@got(r5)
+# else
+	lis	r3,__memcpy_power6@ha
+	lwz	r3,__memcpy_power6@l(r3)
+# endif
+	blr
+L(powerCELL):
+# ifdef PIC
+	lwz	r3,__memcpy_cell@got(r5)
+# else
+	lis	r3,__memcpy_cell@ha
+	lwz	r3,__memcpy_cell@l(r3)
+# endif
+	blr
+END(memcpy)
+
+# undef EALIGN
+# define EALIGN(name, alignt, words)                           \
+  .globl C_SYMBOL_NAME(__memcpy_ppc32);                        \
+  .type C_SYMBOL_NAME(__memcpy_ppc32),@function;               \
+  .align ALIGNARG(alignt);                                     \
+  EALIGN_W_##words;                                            \
+  C_LABEL(__memcpy_ppc32)                                      \
+  cfi_startproc;
+
+# undef END
+# define END(name)                                             \
+  cfi_endproc;                                                 \
+  ASM_SIZE_DIRECTIVE(__memcpy_ppc32)
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)                         \
+  .globl __GI_memcpy; __GI_memcpy = __memcpy_ppc32
+
+#endif
+
+#include "../memcpy.S"