+2013-03-07 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
+ Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
+
+ * sysdeps/powerpc/powerpc64/a2/memcpy.S: Moved to multiarch folder.
+ * sysdeps/powerpc/powerpc64/cell/memcpy.S: Moved to multiarch folder.
+ * sysdeps/powerpc/powerpc64/power4/memcpy.S: Moved to multiarch folder.
+ * sysdeps/powerpc/powerpc64/power6/memcpy.S: Moved to multiarch folder.
+ * sysdeps/powerpc/powerpc64/power7/memcpy.S: Moved to multiarch folder.
+ * sysdeps/powerpc/powerpc64/multiarch/Makefile: Multiarch makefile.
+ * sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S: Moved from a2 folder.
+ * sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S: Moved from cell
+ folder.
+ * sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S: Moved from power4
+ folder.
+ * sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S: Moved from power6
+ folder.
+ * sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S: Moved from power7
+ folder.
+ * sysdeps/powerpc/powerpc64/multiarch/memcpy.S: Multiarch implementation
+ using IFUNC extension.
+
2013-03-07 Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
* sysdeps/powerpc/powerpc32/multiarch/Makefile (sysdep_routines):
--- /dev/null
+ifeq ($(subdir),string)
+sysdep_routines += memcpy-a2 memcpy-cell memcpy-power4 memcpy-power6 \
+ memcpy-power7
+endif
--- /dev/null
+/* 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
+
+/* Some of the . */
+#define PPC_POWER4 (PPC_FEATURE_POWER4|PPC_FEATURE_ARCH_2_05| \
+ PPC_FEATURE_ARCH_2_06)
+#define PPC_POWER6 (PPC_FEATURE_ARCH_2_05|PPC_FEATURE_ARCH_2_06)
+
+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_power_a2)
+ IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_POWER6,
+ __memcpy_power6)
+ IFUNC_IMPL_ADD (array, i, memcpy,
+ hwcap & (PPC_FEATURE_CELL_BE >> 16),
+ __memcpy_cell)
+ IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_POWER4,
+ __memcpy_power4)
+ IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ppc64))
+#endif
+
+ return i;
+}
.machine a2
-EALIGN (memcpy, 5, 0)
+EALIGN (__memcpy_power_a2, 5, 0)
CALL_MCOUNT 3
dcbt 0,r4 /* Prefetch ONE SRC cacheline */
b L(lessthancacheline)
-END_GEN_TB (memcpy,TB_TOCLESS)
-libc_hidden_builtin_def (memcpy)
+END_GEN_TB (__memcpy_power_a2,TB_TOCLESS)
.align 7
-EALIGN (memcpy, 5, 0)
+EALIGN (__memcpy_cell, 5, 0)
CALL_MCOUNT 3
dcbt 0,r4 /* Prefetch ONE SRC cacheline */
stb r0,0(r6)
1: blr
-END_GEN_TB (memcpy,TB_TOCLESS)
-libc_hidden_builtin_def (memcpy)
+END_GEN_TB (__memcpy_cell,TB_TOCLESS)
Each case has a optimized unrolled loop. */
.machine power4
-EALIGN (memcpy, 5, 0)
+EALIGN (__memcpy_power4, 5, 0)
CALL_MCOUNT 3
cmpldi cr1,5,31
/* Move doublewords where destination and source are DW aligned.
Use a unrolled loop to copy 4 doubleword (32-bytes) per iteration.
- If the copy is not an exact multiple of 32 bytes, 1-3
+ If the copy is not an exact multiple of 32 bytes, 1-3
doublewords are copied as needed to set up the main loop. After
the main loop exits there may be a tail of 1-7 bytes. These byte are
copied a word/halfword/byte at a time as needed to preserve alignment. */
ld 31,-8(1)
ld 3,-16(1)
blr
-END_GEN_TB (memcpy,TB_TOCLESS)
-libc_hidden_builtin_def (memcpy)
+END_GEN_TB (__memcpy_power4,TB_TOCLESS)
for the destination. */
.machine "power6"
-EALIGN (memcpy, 7, 0)
+EALIGN (__memcpy_power6, 7, 0)
CALL_MCOUNT 3
cmpldi cr1,5,31
ld 31,-8(1)
ld 3,-16(1)
blr
-END_GEN_TB (memcpy,TB_TOCLESS)
-libc_hidden_builtin_def (memcpy)
+END_GEN_TB (__memcpy_power6,TB_TOCLESS)
Returns 'dst'. */
.machine power7
-EALIGN (memcpy, 5, 0)
+EALIGN (__memcpy_power7, 5, 0)
CALL_MCOUNT 3
cmpldi cr1,5,31
ld 3,-16(1)
blr
-END_GEN_TB (memcpy,TB_TOCLESS)
-libc_hidden_builtin_def (memcpy)
+END_GEN_TB (__memcpy_power7,TB_TOCLESS)
--- /dev/null
+/* Multiple versions of memcpy PowerPC64.
+ Copyright (C) 2012-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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <rtld-global-offsets.h>
+
+/* Define multiple versions only for the definition in lib and for
+ DSO. In static binaries we need memcpy before the initialization
+ happened. */
+#if defined SHARED && !defined NOT_IN_libc
+ .section ".toc","aw"
+.LC__dl_hwcap:
+# ifdef SHARED
+ .tc _rtld_global_ro[TC],_rtld_global_ro
+# else
+ .tc _dl_hwcap[TC],_dl_hwcap
+# endif
+ .section ".text"
+
+ENTRY(memcpy)
+ .type memcpy, @gnu_indirect_function
+ ld r5,.LC__dl_hwcap@toc(r2)
+# ifdef SHARED
+ /* Load _rtld-global._dl_hwcap. */
+ ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
+# else
+ ld r5,0(r5) /* Load extern _dl_hwcap. */
+# endif
+ rldicl. r0,r5,57,63
+ bne- L(power7)
+ rldicl. r0,r5,56,63
+ bne- L(powerA2)
+ rldicl. r0,r5,52,63
+ bne- L(power6)
+ rldicl. r0,r5,48,63
+ bne- L(powercell)
+ rldicl. r0,r5,45,63
+ bne- L(power4)
+ ld r3,__memcpy_ppc64@got(r2)
+ blr
+L(power7):
+ ld r3,__memcpy_power7@got(r2)
+ blr
+L(powerA2):
+ ld r3,__memcpy_power_a2@got(r2)
+ blr
+L(power6):
+ ld r3,__memcpy_power6@got(r2)
+ blr
+L(powercell):
+ ld r3,__memcpy_cell@got(r2)
+ blr
+L(power4):
+ ld r3,__memcpy_power4@got(r2)
+ blr
+END(memcpy)
+
+# undef EALIGN
+# define EALIGN(name, alignt, words) \
+ ENTRY_2(__memcpy_ppc64) \
+BODY_LABEL(__memcpy_ppc64): \
+ cfi_startproc;
+
+# undef END_GEN_TB
+# define END_GEN_TB(name, mask) \
+ cfi_endproc; \
+ TRACEBACK_MASK(__memcpy_ppc64,mask) \
+ END_2(__memcpy_ppc64)
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ .globl __GI_memcpy; __GI_memcpy = __memcpy_ppc64
+
+#endif
+
+#include "../memcpy.S"