about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAdhemerval Zanella <azanella@linux.vnet.ibm.com>2013-04-08 15:22:43 -0500
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>2013-04-09 12:04:22 -0500
commite3fe5492234f7ad905e5f7dbd4fb3205d094d48b (patch)
tree401d67fecccf61097f42d4d1a0ab7818b95d7882
parent45f06f145fe4e1bd24ebaf38a4b8707a2e4c4b3b (diff)
downloadglibc-e3fe5492234f7ad905e5f7dbd4fb3205d094d48b.tar.gz
glibc-e3fe5492234f7ad905e5f7dbd4fb3205d094d48b.tar.xz
glibc-e3fe5492234f7ad905e5f7dbd4fb3205d094d48b.zip
PowerPC: wordcopy function ifunc for PowerPC32
-rw-r--r--string/wordcopy.c36
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/Makefile5
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/wordcopy-c.c5
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/wordcopy-power4.c (renamed from sysdeps/powerpc/powerpc32/power4/wordcopy.c)60
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/wordcopy-power5.c6
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/wordcopy-power6.c (renamed from sysdeps/powerpc/powerpc32/power6/wordcopy.c)69
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/wordcopy-power7.c6
-rw-r--r--sysdeps/powerpc/powerpc32/multiarch/wordcopy.c118
8 files changed, 244 insertions, 61 deletions
diff --git a/string/wordcopy.c b/string/wordcopy.c
index 726894b6e4..1bf271cf04 100644
--- a/string/wordcopy.c
+++ b/string/wordcopy.c
@@ -26,11 +26,12 @@
    block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
    Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
 
+#ifdef WORDCOPY_FWD_ALIGNED
+# define _wordcopy_fwd_aligned WORDCOPY_FWD_ALIGNED
+#endif
+
 void
-_wordcopy_fwd_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
+_wordcopy_fwd_aligned (long int dstp, long int srcp, size_t len)
 {
   op_t a0, a1;
 
@@ -134,11 +135,12 @@ _wordcopy_fwd_aligned (dstp, srcp, len)
    DSTP should be aligned for memory operations on `op_t's, but SRCP must
    *not* be aligned.  */
 
+#ifdef WORDCOPY_FWD_DEST_ALIGNED
+# define _wordcopy_fwd_dest_aligned WORDCOPY_FWD_DEST_ALIGNED
+#endif
+
 void
-_wordcopy_fwd_dest_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
+_wordcopy_fwd_dest_aligned (long int dstp, long int srcp, size_t len)
 {
   op_t a0, a1, a2, a3;
   int sh_1, sh_2;
@@ -221,11 +223,12 @@ _wordcopy_fwd_dest_aligned (dstp, srcp, len)
    (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
    operations on `op_t's.  */
 
+#ifdef WORDCOPY_BWD_ALIGNED
+# define _wordcopy_bwd_aligned WORDCOPY_BWD_ALIGNED
+#endif
+
 void
-_wordcopy_bwd_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
+_wordcopy_bwd_aligned (long int dstp, long int srcp, size_t len)
 {
   op_t a0, a1;
 
@@ -329,11 +332,12 @@ _wordcopy_bwd_aligned (dstp, srcp, len)
    words (not LEN bytes!).  DSTP should be aligned for memory
    operations on `op_t', but SRCP must *not* be aligned.  */
 
+#ifdef WORDCOPY_BWD_DEST_ALIGNED
+# define _wordcopy_bwd_dest_aligned WORDCOPY_BWD_DEST_ALIGNED
+#endif
+
 void
-_wordcopy_bwd_dest_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
+_wordcopy_bwd_dest_aligned (long int dstp, long int srcp, size_t len)
 {
   op_t a0, a1, a2, a3;
   int sh_1, sh_2;
diff --git a/sysdeps/powerpc/powerpc32/multiarch/Makefile b/sysdeps/powerpc/powerpc32/multiarch/Makefile
index c3a3c58dde..4fe9bd04f3 100644
--- a/sysdeps/powerpc/powerpc32/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc32/multiarch/Makefile
@@ -10,5 +10,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
 		   memchr-power7 memchr-c \
 		   memrchr-power7 memrchr-c \
 		   rawmemchr-power7 rawmemchr-c \
-		   strchrnul-power7 strchrnul-c
+		   strchrnul-power7 strchrnul-c \
+		   wordcopy-power7 wordcopy-power6 wordcopy-power5 \
+		   wordcopy-power4 wordcopy-c \
+		   wcschr-power7 wcschr-power6 wcschr-c
 endif
diff --git a/sysdeps/powerpc/powerpc32/multiarch/wordcopy-c.c b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-c.c
new file mode 100644
index 0000000000..bf2456e51f
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-c.c
@@ -0,0 +1,5 @@
+#define WORDCOPY_FWD_ALIGNED      _wordcopy_fwd_aligned_ppc32
+#define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned_ppc32
+#define WORDCOPY_BWD_ALIGNED      _wordcopy_bwd_aligned_ppc32
+#define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned_ppc32
+#include <string/wordcopy.c>
diff --git a/sysdeps/powerpc/powerpc32/power4/wordcopy.c b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power4.c
index 6dd0fa3924..a9dfb0683c 100644
--- a/sysdeps/powerpc/powerpc32/power4/wordcopy.c
+++ b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power4.c
@@ -22,22 +22,30 @@
 #include <stddef.h>
 #include <memcopy.h>
 
+#ifndef WORDCOPY_ARCH
+# define WORDCOPY_ARCH "power4"
+#endif
+
 /* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
    block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
    Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
 
+#ifdef WORDCOPY_FWD_ALIGNED
+# define _wordcopy_fwd_aligned_power4 WORDCOPY_FWD_ALIGNED
+#endif
+
+__typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_power4
+  __attribute__ ((__target__ ("cpu=" WORDCOPY_ARCH)));
+
 void
-_wordcopy_fwd_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
+_wordcopy_fwd_aligned_power4 (long int dstp, long int srcp, size_t len)
 {
   op_t a0, a1;
 
   if (len & 1)
   {
     ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
-    
+
     if (len == 1)
       return;
     srcp += OPSIZ;
@@ -64,11 +72,15 @@ _wordcopy_fwd_aligned (dstp, srcp, len)
    DSTP should be aligned for memory operations on `op_t's, but SRCP must
    *not* be aligned.  */
 
+#ifdef WORDCOPY_FWD_DEST_ALIGNED
+# define _wordcopy_fwd_dest_aligned_power4 WORDCOPY_FWD_DEST_ALIGNED
+#endif
+
+__typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_power4
+  __attribute__ ((__target__ ("cpu=" WORDCOPY_ARCH)));
+
 void
-_wordcopy_fwd_dest_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
+_wordcopy_fwd_dest_aligned_power4 (long int dstp, long int srcp, size_t len)
 {
   op_t a0, a1, a2;
   int sh_1, sh_2;
@@ -88,10 +100,10 @@ _wordcopy_fwd_dest_aligned (dstp, srcp, len)
   {
     a1 = ((op_t *) srcp)[1];
     ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
-    
+
     if (len == 1)
       return;
-    
+
     a0 = a1;
     srcp += OPSIZ;
     dstp += OPSIZ;
@@ -118,11 +130,15 @@ _wordcopy_fwd_dest_aligned (dstp, srcp, len)
    (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
    operations on `op_t's.  */
 
+#ifdef WORDCOPY_BWD_ALIGNED
+# define _wordcopy_bwd_aligned_power4 WORDCOPY_BWD_ALIGNED
+#endif
+
+__typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_power4
+  __attribute__ ((__target__ ("cpu=" WORDCOPY_ARCH)));
+
 void
-_wordcopy_bwd_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
+_wordcopy_bwd_aligned_power4 (long int dstp, long int srcp, size_t len)
 {
   op_t a0, a1;
 
@@ -131,7 +147,7 @@ _wordcopy_bwd_aligned (dstp, srcp, len)
     srcp -= OPSIZ;
     dstp -= OPSIZ;
     ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
-    
+
     if (len == 1)
       return;
     len -= 1;
@@ -157,11 +173,15 @@ _wordcopy_bwd_aligned (dstp, srcp, len)
    words (not LEN bytes!).  DSTP should be aligned for memory
    operations on `op_t', but SRCP must *not* be aligned.  */
 
+#ifdef WORDCOPY_BWD_DEST_ALIGNED
+# define _wordcopy_bwd_dest_aligned_power4 WORDCOPY_BWD_DEST_ALIGNED
+#endif
+
+__typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_power4
+  __attribute__ ((__target__ ("cpu=" WORDCOPY_ARCH)));
+
 void
-_wordcopy_bwd_dest_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
+_wordcopy_bwd_dest_aligned_power4 (long int dstp, long int srcp, size_t len)
 {
   op_t a0, a1, a2;
   int sh_1, sh_2;
diff --git a/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power5.c b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power5.c
new file mode 100644
index 0000000000..1bf4ec40c6
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power5.c
@@ -0,0 +1,6 @@
+#define WORDCOPY_FWD_ALIGNED      _wordcopy_fwd_aligned_power5
+#define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned_power5
+#define WORDCOPY_BWD_ALIGNED      _wordcopy_bwd_aligned_power5
+#define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned_power5
+#define WORDCOPY_ARCH             "power5"
+#include <sysdeps/powerpc/powerpc32/multiarch/wordcopy-power4.c>
diff --git a/sysdeps/powerpc/powerpc32/power6/wordcopy.c b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power6.c
index bcb6176a37..2721d741cf 100644
--- a/sysdeps/powerpc/powerpc32/power6/wordcopy.c
+++ b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power6.c
@@ -23,22 +23,30 @@
 #include <stddef.h>
 #include <memcopy.h>
 
+#ifndef WORDCOPY_ARCH
+# define WORDCOPY_ARCH "power6"
+#endif
+
 /* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
    block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
    Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
 
+#ifdef WORDCOPY_FWD_ALIGNED
+# define _wordcopy_fwd_aligned_power6 WORDCOPY_FWD_ALIGNED
+#endif
+
+__typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_power6
+  __attribute__ ((__target__ ("cpu=" WORDCOPY_ARCH)));
+
 void
-_wordcopy_fwd_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
+_wordcopy_fwd_aligned_power6 (long int dstp, long int srcp, size_t len)
 {
   op_t a0, a1;
 
   if (len & 1)
   {
     ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
-    
+
     if (len == 1)
       return;
     srcp += OPSIZ;
@@ -65,6 +73,10 @@ _wordcopy_fwd_aligned (dstp, srcp, len)
    DSTP should be aligned for memory operations on `op_t's, but SRCP must
    *not* be aligned.  */
 
+#ifdef WORDCOPY_FWD_DEST_ALIGNED
+# define _wordcopy_fwd_dest_aligned_power6 WORDCOPY_FWD_DEST_ALIGNED
+#endif
+
 #define fwd_align_merge(align)                                         \
   do                                                                   \
     {                                                                  \
@@ -79,11 +91,11 @@ _wordcopy_fwd_aligned (dstp, srcp, len)
     }                                                                  \
   while (len != 0)
 
+__typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_power6
+  __attribute__ ((__target__ ("cpu=" WORDCOPY_ARCH)));
+
 void
-_wordcopy_fwd_dest_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
+_wordcopy_fwd_dest_aligned_power6 (long int dstp, long int srcp, size_t len)
 {
   op_t a0, a1, a2;
   int sh_1, sh_2;
@@ -105,10 +117,10 @@ _wordcopy_fwd_dest_aligned (dstp, srcp, len)
   {
     a1 = ((op_t *) srcp)[1];
     ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
-    
+
     if (len == 1)
       return;
-    
+
     a0 = a1;
     srcp += OPSIZ;
     dstp += OPSIZ;
@@ -124,11 +136,15 @@ _wordcopy_fwd_dest_aligned (dstp, srcp, len)
    (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
    operations on `op_t's.  */
 
+#ifdef WORDCOPY_BWD_ALIGNED
+# define _wordcopy_bwd_aligned_power6 WORDCOPY_BWD_ALIGNED
+#endif
+
+__typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_power6
+  __attribute__ ((__target__ ("cpu=" WORDCOPY_ARCH)));
+
 void
-_wordcopy_bwd_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
+_wordcopy_bwd_aligned_power6 (long int dstp, long int srcp, size_t len)
 {
   op_t a0, a1;
 
@@ -137,7 +153,7 @@ _wordcopy_bwd_aligned (dstp, srcp, len)
     srcp -= OPSIZ;
     dstp -= OPSIZ;
     ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
-    
+
     if (len == 1)
       return;
     len -= 1;
@@ -158,6 +174,16 @@ _wordcopy_bwd_aligned (dstp, srcp, len)
   while (len != 0);
 }
 
+
+/* _wordcopy_bwd_dest_aligned -- Copy block finishing right
+   before SRCP to block finishing right before DSTP with LEN `op_t'
+   words (not LEN bytes!).  DSTP should be aligned for memory
+   operations on `op_t', but SRCP must *not* be aligned.  */
+
+#ifdef WORDCOPY_BWD_DEST_ALIGNED
+# define _wordcopy_bwd_dest_aligned_power6 WORDCOPY_BWD_DEST_ALIGNED
+#endif
+
 #define bwd_align_merge(align)                                         \
   do                                                                   \
     {                                                                  \
@@ -172,16 +198,11 @@ _wordcopy_bwd_aligned (dstp, srcp, len)
     }                                                                  \
   while (len != 0)
 
-/* _wordcopy_bwd_dest_aligned -- Copy block finishing right
-   before SRCP to block finishing right before DSTP with LEN `op_t'
-   words (not LEN bytes!).  DSTP should be aligned for memory
-   operations on `op_t', but SRCP must *not* be aligned.  */
+__typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_power6
+  __attribute__ ((__target__ ("cpu=" WORDCOPY_ARCH)));
 
 void
-_wordcopy_bwd_dest_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
+_wordcopy_bwd_dest_aligned_power6 (long int dstp, long int srcp, size_t len)
 {
   op_t a0, a1, a2;
   int sh_1, sh_2;
diff --git a/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power7.c b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power7.c
new file mode 100644
index 0000000000..60fe8f8e51
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power7.c
@@ -0,0 +1,6 @@
+#define WORDCOPY_FWD_ALIGNED      _wordcopy_fwd_aligned_power7
+#define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned_power7
+#define WORDCOPY_BWD_ALIGNED      _wordcopy_bwd_aligned_power7
+#define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned_power7
+#define WORDCOPY_ARCH             "power7"
+#include <sysdeps/powerpc/powerpc32/multiarch/wordcopy-power6.c>
diff --git a/sysdeps/powerpc/powerpc32/multiarch/wordcopy.c b/sysdeps/powerpc/powerpc32/multiarch/wordcopy.c
new file mode 100644
index 0000000000..17e4e4ef17
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/wordcopy.c
@@ -0,0 +1,118 @@
+/* Multiple versions of memchr.
+   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 <stddef.h>
+# include <memcopy.h>
+# include <shlib-compat.h>
+# include "init-arch.h"
+
+extern __typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_ppc32
+attribute_hidden;
+extern __typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_power4
+attribute_hidden;
+extern __typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_power5
+attribute_hidden;
+extern __typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_power6
+attribute_hidden;
+extern __typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_power7
+attribute_hidden;
+
+libc_ifunc (_wordcopy_fwd_aligned,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? _wordcopy_fwd_aligned_power7 :
+	      (hwcap & PPC_FEATURE_ARCH_2_05)
+              ? _wordcopy_fwd_aligned_power6 :
+		(hwcap & PPC_FEATURE_POWER5)
+		? _wordcopy_fwd_aligned_power5 :
+		  (hwcap & PPC_FEATURE_POWER4)
+	          ? _wordcopy_fwd_aligned_power4
+            : _wordcopy_fwd_aligned_ppc32);
+
+
+extern __typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_ppc32
+attribute_hidden;
+extern __typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_power4
+attribute_hidden;
+extern __typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_power5
+attribute_hidden;
+extern __typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_power6
+attribute_hidden;
+extern __typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_power7
+attribute_hidden;
+
+libc_ifunc (_wordcopy_fwd_dest_aligned,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? _wordcopy_fwd_dest_aligned_power7 :
+	      (hwcap & PPC_FEATURE_ARCH_2_05)
+              ? _wordcopy_fwd_dest_aligned_power6 :
+		(hwcap & PPC_FEATURE_POWER5)
+		? _wordcopy_fwd_dest_aligned_power5 :
+		  (hwcap & PPC_FEATURE_POWER4)
+	          ? _wordcopy_fwd_dest_aligned_power4
+            : _wordcopy_fwd_dest_aligned_ppc32);
+
+
+extern __typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_ppc32
+attribute_hidden;
+extern __typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_power4
+attribute_hidden;
+extern __typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_power5
+attribute_hidden;
+extern __typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_power6
+attribute_hidden;
+extern __typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_power7
+attribute_hidden;
+
+libc_ifunc (_wordcopy_bwd_aligned,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? _wordcopy_bwd_aligned_power7 :
+	      (hwcap & PPC_FEATURE_ARCH_2_05)
+              ? _wordcopy_bwd_aligned_power6 :
+		(hwcap & PPC_FEATURE_POWER5)
+		? _wordcopy_bwd_aligned_power5 :
+		  (hwcap & PPC_FEATURE_POWER4)
+	          ? _wordcopy_bwd_aligned_power4
+            : _wordcopy_bwd_aligned_ppc32);
+
+
+extern __typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_ppc32
+attribute_hidden;
+extern __typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_power4
+attribute_hidden;
+extern __typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_power5
+attribute_hidden;
+extern __typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_power6
+attribute_hidden;
+extern __typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_power7
+attribute_hidden;
+
+libc_ifunc (_wordcopy_bwd_dest_aligned,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? _wordcopy_bwd_dest_aligned_power7 :
+	      (hwcap & PPC_FEATURE_ARCH_2_05)
+              ? _wordcopy_bwd_dest_aligned_power6 :
+		(hwcap & PPC_FEATURE_POWER5)
+		? _wordcopy_bwd_dest_aligned_power5 :
+		  (hwcap & PPC_FEATURE_POWER4)
+	          ? _wordcopy_bwd_dest_aligned_power4
+            : _wordcopy_bwd_dest_aligned_ppc32);
+
+#else
+#include "string/wordcopy.c"
+#endif