This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 19/36] PowerPC: wordcopy multilib functions for PowerPC32


2013-08-19  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>

	* string/wordcopy.c (_wordcopy_fwd_aligned): Using macro to redefine
	symbol name.
	(_wordcopy_fwd_dest_aligned): Likewise.
	(_wordcopy_bwd_aligned): Likewise.
	(_wordcopy_bwd_dest_aligned): Likewise.
	* sysdeps/powerpc/powerpc32/power4/wordcopy.c: Move to ...
	* sysdeps/powerpc/power4/wordcopy.c: ... here.
	* sysdeps/powerpc/powerpc32/power6/wordcopy.c: Move to ...
	* sysdeps/powerpc/power6/wordcopy.c: ... here.
	* sysdeps/powerpc/powerpc32/multiarch/wordcopy-power4.c: New file:
	optimized POWER4 wordcopy functions for PPC32.
	* sysdeps/powerpc/powerpc32/multiarch/wordcopy-power5.c: New file:
	optimized POWER5 wordcopy functions for PPC32.
	* sysdeps/powerpc/powerpc32/multiarch/wordcopy-power6.c: New file:
	optimized POWER6 wordcopy functions for PPC32.
	* sysdeps/powerpc/powerpc32/multiarch/wordcopy-power7.c: New file:
	optimized POWER7 wordcopy functions for PPC32.
	* sysdeps/powerpc/powerpc32/multiarch/wordcopy-ppc32.c: New file:
	default wordcopy functions for PPC32.
	* sysdeps/powerpc/powerpc32/multiarch/wordcopy.c: New file:
	multiarch wordcopy functions for PPC32.
	* sysdeps/powerpc/powerpc32/multiarch/Makefile: Added wordcopy
	multiarch objects.
	* sysdeps/powerpc/powerpc32/multiarch/ifunc-impl-list
	(__libc_ifunc_impl_list): Likewise.

--

diff --git a/string/wordcopy.c b/string/wordcopy.c
index 726894b..51c1fad 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.  */
 
+#ifndef 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.  */
 
+#ifndef 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.  */
 
+#ifndef 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.  */
 
+#ifndef 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/power4/wordcopy.c b/sysdeps/powerpc/power4/wordcopy.c
new file mode 100644
index 0000000..f4ba355
--- /dev/null
+++ b/sysdeps/powerpc/power4/wordcopy.c
@@ -0,0 +1,212 @@
+/* _memcopy.c -- subroutines for memory copy functions.
+   Copyright (C) 1991-2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   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/>.  */
+
+/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...!  */
+
+#include <stddef.h>
+#include <memcopy.h>
+
+/* _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.  */
+
+#ifndef WORDCOPY_FWD_ALIGNED
+# define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_aligned
+#endif
+
+void
+WORDCOPY_FWD_ALIGNED (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;
+    dstp += OPSIZ;
+    len -= 1;
+  }
+
+  do
+    {
+      a0 = ((op_t *) srcp)[0];
+      a1 = ((op_t *) srcp)[1];
+      ((op_t *) dstp)[0] = a0;
+      ((op_t *) dstp)[1] = a1;
+
+      srcp += 2 * OPSIZ;
+      dstp += 2 * OPSIZ;
+      len -= 2;
+    }
+  while (len != 0);
+}
+
+/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
+   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
+   DSTP should be aligned for memory operations on `op_t's, but SRCP must
+   *not* be aligned.  */
+
+#ifndef WORDCOPY_FWD_DEST_ALIGNED
+# define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned
+#endif
+
+void
+WORDCOPY_FWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len)
+{
+  op_t a0, a1, a2;
+  int sh_1, sh_2;
+
+  /* Calculate how to shift a word read at the memory operation
+     aligned srcp to make it aligned for copy.  */
+
+  sh_1 = 8 * (srcp % OPSIZ);
+  sh_2 = 8 * OPSIZ - sh_1;
+
+  /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
+     it points in the middle of.  */
+  srcp &= -OPSIZ;
+  a0 = ((op_t *) srcp)[0];
+
+  if (len & 1)
+  {
+    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;
+    len -= 1;
+  }
+
+  do
+    {
+      a1 = ((op_t *) srcp)[1];
+      a2 = ((op_t *) srcp)[2];
+      ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
+      ((op_t *) dstp)[1] = MERGE (a1, sh_1, a2, sh_2);
+      a0 = a2;
+
+      srcp += 2 * OPSIZ;
+      dstp += 2 * OPSIZ;
+      len -= 2;
+    }
+  while (len != 0);
+}
+
+/* _wordcopy_bwd_aligned -- Copy block finishing right before
+   SRCP to block finishing right before DSTP with LEN `op_t' words
+   (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
+   operations on `op_t's.  */
+
+#ifndef WORDCOPY_BWD_ALIGNED
+# define WORDCOPY_BWD_ALIGNED _wordcopy_bwd_aligned
+#endif
+
+void
+WORDCOPY_BWD_ALIGNED (long int dstp, long int srcp, size_t len)
+{
+  op_t a0, a1;
+
+  if (len & 1)
+  {
+    srcp -= OPSIZ;
+    dstp -= OPSIZ;
+    ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
+
+    if (len == 1)
+      return;
+    len -= 1;
+  }
+
+  do
+    {
+      srcp -= 2 * OPSIZ;
+      dstp -= 2 * OPSIZ;
+
+      a1 = ((op_t *) srcp)[1];
+      a0 = ((op_t *) srcp)[0];
+      ((op_t *) dstp)[1] = a1;
+      ((op_t *) dstp)[0] = a0;
+
+      len -= 2;
+    }
+  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.  */
+
+#ifndef WORDCOPY_BWD_DEST_ALIGNED
+# define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned
+#endif
+
+void
+WORDCOPY_BWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len)
+{
+  op_t a0, a1, a2;
+  int sh_1, sh_2;
+
+  /* Calculate how to shift a word read at the memory operation
+     aligned srcp to make it aligned for copy.  */
+
+  sh_1 = 8 * (srcp % OPSIZ);
+  sh_2 = 8 * OPSIZ - sh_1;
+
+  /* Make srcp aligned by rounding it down to the beginning of the op_t
+     it points in the middle of.  */
+  srcp &= -OPSIZ;
+  a2 = ((op_t *) srcp)[0];
+
+  if (len & 1)
+  {
+    srcp -= OPSIZ;
+    dstp -= OPSIZ;
+    a1 = ((op_t *) srcp)[0];
+    ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
+
+    if (len == 1)
+      return;
+
+    a2 = a1;
+    len -= 1;
+  }
+
+  do
+    {
+      srcp -= 2 * OPSIZ;
+      dstp -= 2 * OPSIZ;
+
+      a1 = ((op_t *) srcp)[1];
+      a0 = ((op_t *) srcp)[0];
+      ((op_t *) dstp)[1] = MERGE (a1, sh_1, a2, sh_2);
+      ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
+      a2 = a0;
+
+      len -= 2;
+    }
+  while (len != 0);
+}
diff --git a/sysdeps/powerpc/power6/wordcopy.c b/sysdeps/powerpc/power6/wordcopy.c
new file mode 100644
index 0000000..a6add27
--- /dev/null
+++ b/sysdeps/powerpc/power6/wordcopy.c
@@ -0,0 +1,222 @@
+/* _memcopy.c -- subroutines for memory copy functions.
+   Copyright (C) 1991-2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+   Updated for POWER6 by Steven Munroe (sjmunroe@us.ibm.com).
+
+   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/>.  */
+
+/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...!  */
+
+#include <stddef.h>
+#include <memcopy.h>
+
+/* _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.  */
+
+#ifndef WORDCOPY_FWD_ALIGNED
+# define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_aligned
+#endif
+
+void
+WORDCOPY_FWD_ALIGNED (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;
+    dstp += OPSIZ;
+    len -= 1;
+  }
+
+  do
+    {
+      a0 = ((op_t *) srcp)[0];
+      a1 = ((op_t *) srcp)[1];
+      ((op_t *) dstp)[0] = a0;
+      ((op_t *) dstp)[1] = a1;
+
+      srcp += 2 * OPSIZ;
+      dstp += 2 * OPSIZ;
+      len -= 2;
+    }
+  while (len != 0);
+}
+
+/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
+   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
+   DSTP should be aligned for memory operations on `op_t's, but SRCP must
+   *not* be aligned.  */
+
+#ifndef WORDCOPY_FWD_DEST_ALIGNED
+# define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned
+#endif
+
+#define fwd_align_merge(align)                                         \
+  do                                                                   \
+    {                                                                  \
+      a1 = ((op_t *) srcp)[1];                                         \
+      a2 = ((op_t *) srcp)[2];                                         \
+      ((op_t *) dstp)[0] = MERGE (a0, align*8, a1, (32-align*8));      \
+      ((op_t *) dstp)[1] = MERGE (a1, align*8, a2, (32-align*8));      \
+      a0 = a2;                                                         \
+      srcp += 2 * OPSIZ;                                               \
+      dstp += 2 * OPSIZ;                                               \
+      len -= 2;                                                                \
+    }                                                                  \
+  while (len != 0)
+
+void
+WORDCOPY_FWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len)
+{
+  op_t a0, a1, a2;
+  int sh_1, sh_2;
+  int align;
+
+  /* Calculate how to shift a word read at the memory operation
+     aligned srcp to make it aligned for copy.  */
+
+  align = srcp % OPSIZ;
+  sh_1 = 8 * (srcp % OPSIZ);
+  sh_2 = 8 * OPSIZ - sh_1;
+
+  /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
+     it points in the middle of.  */
+  srcp &= -OPSIZ;
+  a0 = ((op_t *) srcp)[0];
+
+  if (len & 1)
+  {
+    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;
+    len -= 1;
+  }
+
+  fwd_align_merge (align);
+
+}
+
+/* _wordcopy_bwd_aligned -- Copy block finishing right before
+   SRCP to block finishing right before DSTP with LEN `op_t' words
+   (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
+   operations on `op_t's.  */
+
+#ifndef WORDCOPY_BWD_ALIGNED
+# define WORDCOPY_BWD_ALIGNED _wordcopy_bwd_aligned
+#endif
+
+void
+WORDCOPY_BWD_ALIGNED (long int dstp, long int srcp, size_t len)
+{
+  op_t a0, a1;
+
+  if (len & 1)
+  {
+    srcp -= OPSIZ;
+    dstp -= OPSIZ;
+    ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
+
+    if (len == 1)
+      return;
+    len -= 1;
+  }
+
+  do
+    {
+      srcp -= 2 * OPSIZ;
+      dstp -= 2 * OPSIZ;
+
+      a1 = ((op_t *) srcp)[1];
+      a0 = ((op_t *) srcp)[0];
+      ((op_t *) dstp)[1] = a1;
+      ((op_t *) dstp)[0] = a0;
+
+      len -= 2;
+    }
+  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.  */
+
+#ifndef WORDCOPY_BWD_DEST_ALIGNED
+# define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned
+#endif
+
+#define bwd_align_merge(align)                                         \
+  do                                                                   \
+    {                                                                  \
+      srcp -= 2 * OPSIZ;                                               \
+      dstp -= 2 * OPSIZ;                                               \
+      a1 = ((op_t *) srcp)[1];                                         \
+      a0 = ((op_t *) srcp)[0];                                         \
+      ((op_t *) dstp)[1] = MERGE (a1, align*8, a2, (32-align*8));      \
+      ((op_t *) dstp)[0] = MERGE (a0, align*8, a1, (32-align*8));      \
+      a2 = a0;                                                         \
+      len -= 2;                                                                \
+    }                                                                  \
+  while (len != 0)
+
+void
+WORDCOPY_BWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len)
+{
+  op_t a0, a1, a2;
+  int sh_1, sh_2;
+  int align;
+
+  /* Calculate how to shift a word read at the memory operation
+     aligned srcp to make it aligned for copy.  */
+
+  align = srcp % OPSIZ;
+  sh_1 = 8 * (srcp % OPSIZ);
+  sh_2 = 8 * OPSIZ - sh_1;
+
+  /* Make srcp aligned by rounding it down to the beginning of the op_t
+     it points in the middle of.  */
+  srcp &= -OPSIZ;
+  a2 = ((op_t *) srcp)[0];
+
+  if (len & 1)
+  {
+    srcp -= OPSIZ;
+    dstp -= OPSIZ;
+    a1 = ((op_t *) srcp)[0];
+    ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
+
+    if (len == 1)
+      return;
+
+    a2 = a1;
+    len -= 1;
+  }
+
+  bwd_align_merge (align);
+}
diff --git a/sysdeps/powerpc/powerpc32/multiarch/Makefile b/sysdeps/powerpc/powerpc32/multiarch/Makefile
index 3c6d09e..57994be 100644
--- a/sysdeps/powerpc/powerpc32/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc32/multiarch/Makefile
@@ -10,7 +10,9 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
 		   strncase-power7 strncase_l-power7 strchrnul-power7 \
 		   strchrnul-ppc32 strchr-power7 strchr-ppc32 wcschr-power7 \
 		   wcschr-power6 wcschr-ppc32 wcsrchr-power7 wcsrchr-power6 \
-		   wcsrchr-ppc32
+		   wcsrchr-ppc32 wcscpy-power7 wcscpy-power6 wcscpy-ppc32 \
+		   wordcopy-power7 wordcopy-power6 wordcopy-power5 \
+		   wordcopy-power4 wordcopy-ppc32
 
 CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
 CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
@@ -18,4 +20,6 @@ CFLAGS-wcschr-power7.c += -mcpu=power7
 CFLAGS-wcschr-power6.c += -mcpu=power6
 CFLAGS-wcsrchr-power7.c += -mcpu=power7
 CFLAGS-wcsrchr-power6.c += -mcpu=power6
+CFLAGS-wcscpy-power7.c += -mcpu=power7
+CFLAGS-wcscpy-power6.c += -mcpu=power6
 endif
diff --git a/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power4.c b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power4.c
new file mode 100644
index 0000000..866f549
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power4.c
@@ -0,0 +1,23 @@
+/* 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/>.  */
+
+#define WORDCOPY_FWD_ALIGNED      _wordcopy_fwd_aligned_power4
+#define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned_power4
+#define WORDCOPY_BWD_ALIGNED      _wordcopy_bwd_aligned_power4
+#define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned_power4
+
+#include <sysdeps/powerpc/power4/wordcopy.c>
diff --git a/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power5.c b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power5.c
new file mode 100644
index 0000000..7652180
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power5.c
@@ -0,0 +1,23 @@
+/* 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/>.  */
+
+#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
+
+#include <sysdeps/powerpc/power4/wordcopy.c>
diff --git a/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power6.c b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power6.c
new file mode 100644
index 0000000..b8edd10
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power6.c
@@ -0,0 +1,23 @@
+/* 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/>.  */
+
+#define WORDCOPY_FWD_ALIGNED      _wordcopy_fwd_aligned_power6
+#define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned_power6
+#define WORDCOPY_BWD_ALIGNED      _wordcopy_bwd_aligned_power6
+#define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned_power6
+
+#include <sysdeps/powerpc/power6/wordcopy.c>
diff --git a/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power7.c b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power7.c
new file mode 100644
index 0000000..e7999c3
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-power7.c
@@ -0,0 +1,23 @@
+/* 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/>.  */
+
+#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
+
+#include <sysdeps/powerpc/power6/wordcopy.c>
diff --git a/sysdeps/powerpc/powerpc32/multiarch/wordcopy-ppc32.c b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-ppc32.c
new file mode 100644
index 0000000..3e8c471
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/wordcopy-ppc32.c
@@ -0,0 +1,23 @@
+/* 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/>.  */
+
+#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/multiarch/wordcopy.c b/sysdeps/powerpc/powerpc32/multiarch/wordcopy.c
new file mode 100644
index 0000000..5723766
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/multiarch/wordcopy.c
@@ -0,0 +1,118 @@
+/* Multiple versions of wordcopy functions.
+   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
diff --git a/sysdeps/powerpc/powerpc32/power4/wordcopy.c b/sysdeps/powerpc/powerpc32/power4/wordcopy.c
deleted file mode 100644
index 5d857f6..0000000
--- a/sysdeps/powerpc/powerpc32/power4/wordcopy.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* _memcopy.c -- subroutines for memory copy functions.
-   Copyright (C) 1991-2013 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Torbjorn Granlund (tege@sics.se).
-
-   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/>.  */
-
-/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...!  */
-
-#include <stddef.h>
-#include <memcopy.h>
-
-/* _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.  */
-
-void
-_wordcopy_fwd_aligned (dstp, srcp, len)
-     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;
-    dstp += OPSIZ;
-    len -= 1;
-  }
-
-  do
-    {
-      a0 = ((op_t *) srcp)[0];
-      a1 = ((op_t *) srcp)[1];
-      ((op_t *) dstp)[0] = a0;
-      ((op_t *) dstp)[1] = a1;
-
-      srcp += 2 * OPSIZ;
-      dstp += 2 * OPSIZ;
-      len -= 2;
-    }
-  while (len != 0);
-}
-
-/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
-   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
-   DSTP should be aligned for memory operations on `op_t's, but SRCP must
-   *not* be aligned.  */
-
-void
-_wordcopy_fwd_dest_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
-{
-  op_t a0, a1, a2;
-  int sh_1, sh_2;
-
-  /* Calculate how to shift a word read at the memory operation
-     aligned srcp to make it aligned for copy.  */
-
-  sh_1 = 8 * (srcp % OPSIZ);
-  sh_2 = 8 * OPSIZ - sh_1;
-
-  /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
-     it points in the middle of.  */
-  srcp &= -OPSIZ;
-  a0 = ((op_t *) srcp)[0];
-
-  if (len & 1)
-  {
-    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;
-    len -= 1;
-  }
-
-  do
-    {
-      a1 = ((op_t *) srcp)[1];
-      a2 = ((op_t *) srcp)[2];
-      ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
-      ((op_t *) dstp)[1] = MERGE (a1, sh_1, a2, sh_2);
-      a0 = a2;
-
-      srcp += 2 * OPSIZ;
-      dstp += 2 * OPSIZ;
-      len -= 2;
-    }
-  while (len != 0);
-}
-
-/* _wordcopy_bwd_aligned -- Copy block finishing right before
-   SRCP to block finishing right before DSTP with LEN `op_t' words
-   (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
-   operations on `op_t's.  */
-
-void
-_wordcopy_bwd_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
-{
-  op_t a0, a1;
-
-  if (len & 1)
-  {
-    srcp -= OPSIZ;
-    dstp -= OPSIZ;
-    ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
-
-    if (len == 1)
-      return;
-    len -= 1;
-  }
-
-  do
-    {
-      srcp -= 2 * OPSIZ;
-      dstp -= 2 * OPSIZ;
-
-      a1 = ((op_t *) srcp)[1];
-      a0 = ((op_t *) srcp)[0];
-      ((op_t *) dstp)[1] = a1;
-      ((op_t *) dstp)[0] = a0;
-
-      len -= 2;
-    }
-  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.  */
-
-void
-_wordcopy_bwd_dest_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
-{
-  op_t a0, a1, a2;
-  int sh_1, sh_2;
-
-  /* Calculate how to shift a word read at the memory operation
-     aligned srcp to make it aligned for copy.  */
-
-  sh_1 = 8 * (srcp % OPSIZ);
-  sh_2 = 8 * OPSIZ - sh_1;
-
-  /* Make srcp aligned by rounding it down to the beginning of the op_t
-     it points in the middle of.  */
-  srcp &= -OPSIZ;
-  a2 = ((op_t *) srcp)[0];
-
-  if (len & 1)
-  {
-    srcp -= OPSIZ;
-    dstp -= OPSIZ;
-    a1 = ((op_t *) srcp)[0];
-    ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
-
-    if (len == 1)
-      return;
-
-    a2 = a1;
-    len -= 1;
-  }
-
-  do
-    {
-      srcp -= 2 * OPSIZ;
-      dstp -= 2 * OPSIZ;
-
-      a1 = ((op_t *) srcp)[1];
-      a0 = ((op_t *) srcp)[0];
-      ((op_t *) dstp)[1] = MERGE (a1, sh_1, a2, sh_2);
-      ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
-      a2 = a0;
-
-      len -= 2;
-    }
-  while (len != 0);
-}
diff --git a/sysdeps/powerpc/powerpc32/power6/wordcopy.c b/sysdeps/powerpc/powerpc32/power6/wordcopy.c
deleted file mode 100644
index 4106e5c..0000000
--- a/sysdeps/powerpc/powerpc32/power6/wordcopy.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/* _memcopy.c -- subroutines for memory copy functions.
-   Copyright (C) 1991-2013 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Torbjorn Granlund (tege@sics.se).
-   Updated for POWER6 by Steven Munroe (sjmunroe@us.ibm.com).
-
-   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/>.  */
-
-/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...!  */
-
-#include <stddef.h>
-#include <memcopy.h>
-
-/* _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.  */
-
-void
-_wordcopy_fwd_aligned (dstp, srcp, len)
-     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;
-    dstp += OPSIZ;
-    len -= 1;
-  }
-
-  do
-    {
-      a0 = ((op_t *) srcp)[0];
-      a1 = ((op_t *) srcp)[1];
-      ((op_t *) dstp)[0] = a0;
-      ((op_t *) dstp)[1] = a1;
-
-      srcp += 2 * OPSIZ;
-      dstp += 2 * OPSIZ;
-      len -= 2;
-    }
-  while (len != 0);
-}
-
-/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
-   block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
-   DSTP should be aligned for memory operations on `op_t's, but SRCP must
-   *not* be aligned.  */
-
-#define fwd_align_merge(align)                                         \
-  do                                                                   \
-    {                                                                  \
-      a1 = ((op_t *) srcp)[1];                                         \
-      a2 = ((op_t *) srcp)[2];                                         \
-      ((op_t *) dstp)[0] = MERGE (a0, align*8, a1, (32-align*8));      \
-      ((op_t *) dstp)[1] = MERGE (a1, align*8, a2, (32-align*8));      \
-      a0 = a2;                                                         \
-      srcp += 2 * OPSIZ;                                               \
-      dstp += 2 * OPSIZ;                                               \
-      len -= 2;                                                                \
-    }                                                                  \
-  while (len != 0)
-
-void
-_wordcopy_fwd_dest_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
-{
-  op_t a0, a1, a2;
-  int sh_1, sh_2;
-  int align;
-
-  /* Calculate how to shift a word read at the memory operation
-     aligned srcp to make it aligned for copy.  */
-
-  align = srcp % OPSIZ;
-  sh_1 = 8 * (srcp % OPSIZ);
-  sh_2 = 8 * OPSIZ - sh_1;
-
-  /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
-     it points in the middle of.  */
-  srcp &= -OPSIZ;
-  a0 = ((op_t *) srcp)[0];
-
-  if (len & 1)
-  {
-    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;
-    len -= 1;
-  }
-
-  fwd_align_merge (align);
-
-}
-
-/* _wordcopy_bwd_aligned -- Copy block finishing right before
-   SRCP to block finishing right before DSTP with LEN `op_t' words
-   (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
-   operations on `op_t's.  */
-
-void
-_wordcopy_bwd_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
-{
-  op_t a0, a1;
-
-  if (len & 1)
-  {
-    srcp -= OPSIZ;
-    dstp -= OPSIZ;
-    ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
-
-    if (len == 1)
-      return;
-    len -= 1;
-  }
-
-  do
-    {
-      srcp -= 2 * OPSIZ;
-      dstp -= 2 * OPSIZ;
-
-      a1 = ((op_t *) srcp)[1];
-      a0 = ((op_t *) srcp)[0];
-      ((op_t *) dstp)[1] = a1;
-      ((op_t *) dstp)[0] = a0;
-
-      len -= 2;
-    }
-  while (len != 0);
-}
-
-#define bwd_align_merge(align)                                         \
-  do                                                                   \
-    {                                                                  \
-      srcp -= 2 * OPSIZ;                                               \
-      dstp -= 2 * OPSIZ;                                               \
-      a1 = ((op_t *) srcp)[1];                                         \
-      a0 = ((op_t *) srcp)[0];                                         \
-      ((op_t *) dstp)[1] = MERGE (a1, align*8, a2, (32-align*8));      \
-      ((op_t *) dstp)[0] = MERGE (a0, align*8, a1, (32-align*8));      \
-      a2 = a0;                                                         \
-      len -= 2;                                                                \
-    }                                                                  \
-  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.  */
-
-void
-_wordcopy_bwd_dest_aligned (dstp, srcp, len)
-     long int dstp;
-     long int srcp;
-     size_t len;
-{
-  op_t a0, a1, a2;
-  int sh_1, sh_2;
-  int align;
-
-  /* Calculate how to shift a word read at the memory operation
-     aligned srcp to make it aligned for copy.  */
-
-  align = srcp % OPSIZ;
-  sh_1 = 8 * (srcp % OPSIZ);
-  sh_2 = 8 * OPSIZ - sh_1;
-
-  /* Make srcp aligned by rounding it down to the beginning of the op_t
-     it points in the middle of.  */
-  srcp &= -OPSIZ;
-  a2 = ((op_t *) srcp)[0];
-
-  if (len & 1)
-  {
-    srcp -= OPSIZ;
-    dstp -= OPSIZ;
-    a1 = ((op_t *) srcp)[0];
-    ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
-
-    if (len == 1)
-      return;
-
-    a2 = a1;
-    len -= 1;
-  }
-
-  bwd_align_merge (align);
-}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]