diff options
author | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2013-04-08 15:22:43 -0500 |
---|---|---|
committer | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2013-04-09 12:04:22 -0500 |
commit | e3fe5492234f7ad905e5f7dbd4fb3205d094d48b (patch) | |
tree | 401d67fecccf61097f42d4d1a0ab7818b95d7882 | |
parent | 45f06f145fe4e1bd24ebaf38a4b8707a2e4c4b3b (diff) | |
download | glibc-e3fe5492234f7ad905e5f7dbd4fb3205d094d48b.zip glibc-e3fe5492234f7ad905e5f7dbd4fb3205d094d48b.tar.gz glibc-e3fe5492234f7ad905e5f7dbd4fb3205d094d48b.tar.bz2 |
PowerPC: wordcopy function ifunc for PowerPC32
-rw-r--r-- | string/wordcopy.c | 36 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc32/multiarch/Makefile | 5 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc32/multiarch/wordcopy-c.c | 5 | ||||
-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.c | 6 | ||||
-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.c | 6 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc32/multiarch/wordcopy.c | 118 |
8 files changed, 244 insertions, 61 deletions
diff --git a/string/wordcopy.c b/string/wordcopy.c index 726894b..1bf271c 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 c3a3c58..4fe9bd0 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 0000000..bf2456e --- /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 6dd0fa3..a9dfb06 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 0000000..1bf4ec4 --- /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 bcb6176..2721d74 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 0000000..60fe8f8 --- /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 0000000..17e4e4e --- /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 |