diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2015-08-19 14:10:40 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-08-20 16:25:21 -0700 |
commit | 33c174b4d5c292958e6a9dc2561b7301d34c4de7 (patch) | |
tree | c87c433a7f2332ef21247cf01c21f822c9becac2 | |
parent | c0271151b67be677bfb0a9afcfb780b4d3c48e43 (diff) | |
download | glibc-33c174b4d5c292958e6a9dc2561b7301d34c4de7.tar.gz glibc-33c174b4d5c292958e6a9dc2561b7301d34c4de7.tar.xz glibc-33c174b4d5c292958e6a9dc2561b7301d34c4de7.zip |
Add i386 memset family multiarch functions
18 files changed, 741 insertions, 0 deletions
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile new file mode 100644 index 0000000000..cb96d46e98 --- /dev/null +++ b/sysdeps/i386/multiarch/Makefile @@ -0,0 +1,12 @@ +ifeq ($(subdir),csu) +tests += test-multiarch +gen-as-const-headers += ifunc-defines.sym +endif + +ifeq ($(subdir),string) +gen-as-const-headers += locale-defines.sym +sysdep_routines += bzero-i386 bzero-i586 bzero-i686 \ + bzero-sse2 bzero-sse2-rep \ + memset-i386 memset-i586 memset-i686 \ + memset-sse2 memset-sse2-rep \ +endif diff --git a/sysdeps/i386/multiarch/bzero-i386.S b/sysdeps/i386/multiarch/bzero-i386.S new file mode 100644 index 0000000000..a59b2f1f1a --- /dev/null +++ b/sysdeps/i386/multiarch/bzero-i386.S @@ -0,0 +1,15 @@ +#include <init-arch.h> +#if !SUPPORT_I586 && !SUPPORT_I686 +# define __bzero __bzero_i386 +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(name) +# undef weak_alias +# define weak_alias(name, aliasname) +# include <sysdeps/i386/bzero.S> + +# ifdef SHARED + .globl __GI_bzero + .hidden __GI_bzero + __GI_bzero = __bzero_i386 +# endif +#endif diff --git a/sysdeps/i386/multiarch/bzero-i586.S b/sysdeps/i386/multiarch/bzero-i586.S new file mode 100644 index 0000000000..10321f68a5 --- /dev/null +++ b/sysdeps/i386/multiarch/bzero-i586.S @@ -0,0 +1,15 @@ +#include <init-arch.h> +#if !SUPPORT_I686 +# define __bzero __bzero_i586 +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(name) +# undef weak_alias +# define weak_alias(name, aliasname) +# include <sysdeps/i386/i586/bzero.S> + +# if defined SHARED && SUPPORT_I586 + .globl __GI_bzero + .hidden __GI_bzero + __GI_bzero = __bzero_i586 +# endif +#endif diff --git a/sysdeps/i386/multiarch/bzero-i686.S b/sysdeps/i386/multiarch/bzero-i686.S new file mode 100644 index 0000000000..b38bb63787 --- /dev/null +++ b/sysdeps/i386/multiarch/bzero-i686.S @@ -0,0 +1,13 @@ +#include <init-arch.h> +#define __bzero __bzero_i686 +#undef libc_hidden_builtin_def +#define libc_hidden_builtin_def(name) +#undef weak_alias +#define weak_alias(name, aliasname) +#include <sysdeps/i386/i686/bzero.S> + +#if defined SHARED && SUPPORT_I686 + .globl __GI_bzero + .hidden __GI_bzero + __GI_bzero = __bzero_i686 +#endif diff --git a/sysdeps/i386/i686/multiarch/bzero-sse2-rep.S b/sysdeps/i386/multiarch/bzero-sse2-rep.S index 507b288bb3..507b288bb3 100644 --- a/sysdeps/i386/i686/multiarch/bzero-sse2-rep.S +++ b/sysdeps/i386/multiarch/bzero-sse2-rep.S diff --git a/sysdeps/i386/i686/multiarch/bzero-sse2.S b/sysdeps/i386/multiarch/bzero-sse2.S index 8d04512e4e..8d04512e4e 100644 --- a/sysdeps/i386/i686/multiarch/bzero-sse2.S +++ b/sysdeps/i386/multiarch/bzero-sse2.S diff --git a/sysdeps/i386/multiarch/bzero.c b/sysdeps/i386/multiarch/bzero.c new file mode 100644 index 0000000000..8de71beb70 --- /dev/null +++ b/sysdeps/i386/multiarch/bzero.c @@ -0,0 +1,63 @@ +/* Multiple versions of bzero. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2015 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 multiple versions only for the definition in lib. */ +#if IS_IN (libc) +/* Redefine bzero so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef bzero +# define bzero __redirect_bzero +# include <string.h> +# undef bzero + +# include <init-arch.h> + +extern __typeof (__redirect_bzero) __bzero_i386 attribute_hidden; +extern __typeof (__redirect_bzero) __bzero_i586 attribute_hidden; +extern __typeof (__redirect_bzero) __bzero_i686 attribute_hidden; +extern __typeof (__redirect_bzero) __bzero_sse2 attribute_hidden; +extern __typeof (__redirect_bzero) __bzero_sse2_rep attribute_hidden; + +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ +extern __typeof (__redirect_bzero) __bzero; +extern void *bzero_ifunc (void) __asm__ ("__bzero"); + +void * +bzero_ifunc (void) +{ + if (HAS_CPU_FEATURE (SSE2)) + { + if (HAS_ARCH_FEATURE (Fast_Rep_String)) + return __bzero_sse2_rep; + else + return __bzero_sse2; + } + + if (HAS_I686) + return __bzero_i686; + else if (HAS_I586) + return __bzero_i586; + else + return __bzero_i386; +} +__asm__ (".type __bzero, %gnu_indirect_function"); + +weak_alias (__bzero, bzero) +#endif diff --git a/sysdeps/i386/i686/multiarch/ifunc-defines.sym b/sysdeps/i386/multiarch/ifunc-defines.sym index 96e9cfaf61..96e9cfaf61 100644 --- a/sysdeps/i386/i686/multiarch/ifunc-defines.sym +++ b/sysdeps/i386/multiarch/ifunc-defines.sym diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c new file mode 100644 index 0000000000..87d2080f7c --- /dev/null +++ b/sysdeps/i386/multiarch/ifunc-impl-list.c @@ -0,0 +1,407 @@ +/* Enumerate available IFUNC implementations of a function. i386 version. + Copyright (C) 2015 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 <ifunc-impl-list.h> +#include "init-arch.h" + +/* Maximum number of IFUNC implementations. */ +#define MAX_IFUNC 4 + +/* Fill ARRAY of MAX elements with IFUNC implementations for function + NAME and return the number of valid entries. */ + +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; + +#if 0 + /* Support sysdeps/i386/i686/multiarch/bcopy.S. */ + IFUNC_IMPL (i, name, bcopy, + IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSSE3), + __bcopy_ssse3_rep) + IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSSE3), + __bcopy_ssse3) + IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSE2), + __bcopy_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, bcopy, 1, __bcopy_ia32)) +#endif + + /* Support sysdeps/i386/i686/multiarch/bzero.S. */ + IFUNC_IMPL (i, name, bzero, + IFUNC_IMPL_ADD (array, i, bzero, HAS_CPU_FEATURE (SSE2), + __bzero_sse2_rep) + IFUNC_IMPL_ADD (array, i, bzero, HAS_CPU_FEATURE (SSE2), + __bzero_sse2) + IFUNC_IMPL_ADD (array, i, bzero, HAS_I686, __bzero_i686) +#if !SUPPORT_I686 + IFUNC_IMPL_ADD (array, i, bzero, HAS_I586, __bzero_i586) +# if !SUPPORT_I586 + IFUNC_IMPL_ADD (array, i, bzero, 1, __bzero_i386) +# endif +#endif + ) + +#if 0 + /* Support sysdeps/i386/i686/multiarch/memchr.S. */ + IFUNC_IMPL (i, name, memchr, + IFUNC_IMPL_ADD (array, i, memchr, HAS_CPU_FEATURE (SSE2), + __memchr_sse2_bsf) + IFUNC_IMPL_ADD (array, i, memchr, HAS_CPU_FEATURE (SSE2), + __memchr_sse2) + IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memcmp.S. */ + IFUNC_IMPL (i, name, memcmp, + IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSE4_2), + __memcmp_sse4_2) + IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSSE3), + __memcmp_ssse3) + IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memmove_chk.S. */ + IFUNC_IMPL (i, name, __memmove_chk, + IFUNC_IMPL_ADD (array, i, __memmove_chk, + HAS_CPU_FEATURE (SSSE3), + __memmove_chk_ssse3_rep) + IFUNC_IMPL_ADD (array, i, __memmove_chk, + HAS_CPU_FEATURE (SSSE3), + __memmove_chk_ssse3) + IFUNC_IMPL_ADD (array, i, __memmove_chk, + HAS_CPU_FEATURE (SSE2), + __memmove_chk_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, __memmove_chk, 1, + __memmove_chk_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memmove.S. */ + IFUNC_IMPL (i, name, memmove, + IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3), + __memmove_ssse3_rep) + IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3), + __memmove_ssse3) + IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSE2), + __memmove_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memrchr.S. */ + IFUNC_IMPL (i, name, memrchr, + IFUNC_IMPL_ADD (array, i, memrchr, HAS_CPU_FEATURE (SSE2), + __memrchr_sse2_bsf) + IFUNC_IMPL_ADD (array, i, memrchr, HAS_CPU_FEATURE (SSE2), + __memrchr_sse2) + IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_ia32)) +#endif + + /* Support sysdeps/i386/i686/multiarch/memset_chk.S. */ + IFUNC_IMPL (i, name, __memset_chk, + IFUNC_IMPL_ADD (array, i, __memset_chk, + HAS_CPU_FEATURE (SSE2), + __memset_chk_sse2_rep) + IFUNC_IMPL_ADD (array, i, __memset_chk, + HAS_CPU_FEATURE (SSE2), + __memset_chk_sse2) + IFUNC_IMPL_ADD (array, i, __memset_chk, + HAS_I686, __memset_chk_i686) +#if !SUPPORT_I686 + IFUNC_IMPL_ADD (array, i, __memset_chk, + HAS_I586, __memset_chk_i586) +# if !SUPPORT_I586 + IFUNC_IMPL_ADD (array, i, __memset_chk, 1, + __memset_chk_i386) +# endif +#endif + ) + + /* Support sysdeps/i386/i686/multiarch/memset.S. */ + IFUNC_IMPL (i, name, memset, + IFUNC_IMPL_ADD (array, i, memset, HAS_CPU_FEATURE (SSE2), + __memset_sse2_rep) + IFUNC_IMPL_ADD (array, i, memset, HAS_CPU_FEATURE (SSE2), + __memset_sse2) + IFUNC_IMPL_ADD (array, i, memset, HAS_I686, + __memset_i686) +#if !SUPPORT_I686 + IFUNC_IMPL_ADD (array, i, memset, HAS_I586, + __memset_i586) +# if !SUPPORT_I586 + IFUNC_IMPL_ADD (array, i, memset, 1, __memset_i386) +# endif +#endif + ) + +#if 0 + /* Support sysdeps/i386/i686/multiarch/rawmemchr.S. */ + IFUNC_IMPL (i, name, rawmemchr, + IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CPU_FEATURE (SSE2), + __rawmemchr_sse2_bsf) + IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CPU_FEATURE (SSE2), + __rawmemchr_sse2) + IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/stpncpy.S. */ + IFUNC_IMPL (i, name, stpncpy, + IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CPU_FEATURE (SSSE3), + __stpncpy_ssse3) + IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CPU_FEATURE (SSE2), + __stpncpy_sse2) + IFUNC_IMPL_ADD (array, i, stpncpy, 1, __stpncpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/stpcpy.S. */ + IFUNC_IMPL (i, name, stpcpy, + IFUNC_IMPL_ADD (array, i, stpcpy, HAS_CPU_FEATURE (SSSE3), + __stpcpy_ssse3) + IFUNC_IMPL_ADD (array, i, stpcpy, HAS_CPU_FEATURE (SSE2), + __stpcpy_sse2) + IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcasecmp.S. */ + IFUNC_IMPL (i, name, strcasecmp, + IFUNC_IMPL_ADD (array, i, strcasecmp, + HAS_CPU_FEATURE (SSE4_2), + __strcasecmp_sse4_2) + IFUNC_IMPL_ADD (array, i, strcasecmp, + HAS_CPU_FEATURE (SSSE3), + __strcasecmp_ssse3) + IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcasecmp_l.S. */ + IFUNC_IMPL (i, name, strcasecmp_l, + IFUNC_IMPL_ADD (array, i, strcasecmp_l, + HAS_CPU_FEATURE (SSE4_2), + __strcasecmp_l_sse4_2) + IFUNC_IMPL_ADD (array, i, strcasecmp_l, + HAS_CPU_FEATURE (SSSE3), + __strcasecmp_l_ssse3) + IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1, + __strcasecmp_l_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcat.S. */ + IFUNC_IMPL (i, name, strcat, + IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSSE3), + __strcat_ssse3) + IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSE2), + __strcat_sse2) + IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strchr.S. */ + IFUNC_IMPL (i, name, strchr, + IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2), + __strchr_sse2_bsf) + IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2), + __strchr_sse2) + IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcmp.S. */ + IFUNC_IMPL (i, name, strcmp, + IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSE4_2), + __strcmp_sse4_2) + IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSSE3), + __strcmp_ssse3) + IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcpy.S. */ + IFUNC_IMPL (i, name, strcpy, + IFUNC_IMPL_ADD (array, i, strcpy, HAS_CPU_FEATURE (SSSE3), + __strcpy_ssse3) + IFUNC_IMPL_ADD (array, i, strcpy, HAS_CPU_FEATURE (SSE2), + __strcpy_sse2) + IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcspn.S. */ + IFUNC_IMPL (i, name, strcspn, + IFUNC_IMPL_ADD (array, i, strcspn, HAS_CPU_FEATURE (SSE4_2), + __strcspn_sse42) + IFUNC_IMPL_ADD (array, i, strcspn, 1, __strcspn_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strncase.S. */ + IFUNC_IMPL (i, name, strncasecmp, + IFUNC_IMPL_ADD (array, i, strncasecmp, + HAS_CPU_FEATURE (SSE4_2), + __strncasecmp_sse4_2) + IFUNC_IMPL_ADD (array, i, strncasecmp, + HAS_CPU_FEATURE (SSSE3), + __strncasecmp_ssse3) + IFUNC_IMPL_ADD (array, i, strncasecmp, 1, + __strncasecmp_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strncase_l.S. */ + IFUNC_IMPL (i, name, strncasecmp_l, + IFUNC_IMPL_ADD (array, i, strncasecmp_l, + HAS_CPU_FEATURE (SSE4_2), + __strncasecmp_l_sse4_2) + IFUNC_IMPL_ADD (array, i, strncasecmp_l, + HAS_CPU_FEATURE (SSSE3), + __strncasecmp_l_ssse3) + IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1, + __strncasecmp_l_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strncat.S. */ + IFUNC_IMPL (i, name, strncat, + IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSSE3), + __strncat_ssse3) + IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSE2), + __strncat_sse2) + IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strncpy.S. */ + IFUNC_IMPL (i, name, strncpy, + IFUNC_IMPL_ADD (array, i, strncpy, HAS_CPU_FEATURE (SSSE3), + __strncpy_ssse3) + IFUNC_IMPL_ADD (array, i, strncpy, HAS_CPU_FEATURE (SSE2), + __strncpy_sse2) + IFUNC_IMPL_ADD (array, i, strncpy, 1, __strncpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strnlen.S. */ + IFUNC_IMPL (i, name, strnlen, + IFUNC_IMPL_ADD (array, i, strnlen, HAS_CPU_FEATURE (SSE2), + __strnlen_sse2) + IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strpbrk.S. */ + IFUNC_IMPL (i, name, strpbrk, + IFUNC_IMPL_ADD (array, i, strpbrk, HAS_CPU_FEATURE (SSE4_2), + __strpbrk_sse42) + IFUNC_IMPL_ADD (array, i, strpbrk, 1, __strpbrk_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strrchr.S. */ + IFUNC_IMPL (i, name, strrchr, + IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE2), + __strrchr_sse2_bsf) + IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE2), + __strrchr_sse2) + IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strspn.S. */ + IFUNC_IMPL (i, name, strspn, + IFUNC_IMPL_ADD (array, i, strspn, HAS_CPU_FEATURE (SSE4_2), + __strspn_sse42) + IFUNC_IMPL_ADD (array, i, strspn, 1, __strspn_ia32)) + + /* Support sysdeps/i386/i686/multiarch/wcschr.S. */ + IFUNC_IMPL (i, name, wcschr, + IFUNC_IMPL_ADD (array, i, wcschr, HAS_CPU_FEATURE (SSE2), + __wcschr_sse2) + IFUNC_IMPL_ADD (array, i, wcschr, 1, __wcschr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/wcscmp.S. */ + IFUNC_IMPL (i, name, wcscmp, + IFUNC_IMPL_ADD (array, i, wcscmp, HAS_CPU_FEATURE (SSE2), + __wcscmp_sse2) + IFUNC_IMPL_ADD (array, i, wcscmp, 1, __wcscmp_ia32)) + + /* Support sysdeps/i386/i686/multiarch/wcscpy.S. */ + IFUNC_IMPL (i, name, wcscpy, + IFUNC_IMPL_ADD (array, i, wcscpy, HAS_CPU_FEATURE (SSSE3), + __wcscpy_ssse3) + IFUNC_IMPL_ADD (array, i, wcscpy, 1, __wcscpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/wcslen.S. */ + IFUNC_IMPL (i, name, wcslen, + IFUNC_IMPL_ADD (array, i, wcslen, HAS_CPU_FEATURE (SSE2), + __wcslen_sse2) + IFUNC_IMPL_ADD (array, i, wcslen, 1, __wcslen_ia32)) + + /* Support sysdeps/i386/i686/multiarch/wcsrchr.S. */ + IFUNC_IMPL (i, name, wcsrchr, + IFUNC_IMPL_ADD (array, i, wcsrchr, HAS_CPU_FEATURE (SSE2), + __wcsrchr_sse2) + IFUNC_IMPL_ADD (array, i, wcsrchr, 1, __wcsrchr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/wmemcmp.S. */ + IFUNC_IMPL (i, name, wmemcmp, + IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSE4_2), + __wmemcmp_sse4_2) + IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSSE3), + __wmemcmp_ssse3) + IFUNC_IMPL_ADD (array, i, wmemcmp, 1, __wmemcmp_ia32)) + +#ifdef SHARED + /* Support sysdeps/i386/i686/multiarch/memcpy_chk.S. */ + IFUNC_IMPL (i, name, __memcpy_chk, + IFUNC_IMPL_ADD (array, i, __memcpy_chk, + HAS_CPU_FEATURE (SSSE3), + __memcpy_chk_ssse3_rep) + IFUNC_IMPL_ADD (array, i, __memcpy_chk, + HAS_CPU_FEATURE (SSSE3), + __memcpy_chk_ssse3) + IFUNC_IMPL_ADD (array, i, __memcpy_chk, + HAS_CPU_FEATURE (SSE2), + __memcpy_chk_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, __memcpy_chk, 1, + __memcpy_chk_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memcpy.S. */ + IFUNC_IMPL (i, name, memcpy, + IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3), + __memcpy_ssse3_rep) + IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3), + __memcpy_ssse3) + IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSE2), + __memcpy_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/mempcpy_chk.S. */ + IFUNC_IMPL (i, name, __mempcpy_chk, + IFUNC_IMPL_ADD (array, i, __mempcpy_chk, + HAS_CPU_FEATURE (SSSE3), + __mempcpy_chk_ssse3_rep) + IFUNC_IMPL_ADD (array, i, __mempcpy_chk, + HAS_CPU_FEATURE (SSSE3), + __mempcpy_chk_ssse3) + IFUNC_IMPL_ADD (array, i, __mempcpy_chk, + HAS_CPU_FEATURE (SSE2), + __mempcpy_chk_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, __mempcpy_chk, 1, + __mempcpy_chk_ia32)) + + /* Support sysdeps/i386/i686/multiarch/mempcpy.S. */ + IFUNC_IMPL (i, name, mempcpy, + IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3), + __mempcpy_ssse3_rep) + IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3), + __mempcpy_ssse3) + IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSE2), + __mempcpy_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, mempcpy, 1, __mempcpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strlen.S. */ + IFUNC_IMPL (i, name, strlen, + IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2), + __strlen_sse2_bsf) + IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2), + __strlen_sse2) + IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strncmp.S. */ + IFUNC_IMPL (i, name, strncmp, + IFUNC_IMPL_ADD (array, i, strncmp, HAS_CPU_FEATURE (SSE4_2), + __strncmp_sse4_2) + IFUNC_IMPL_ADD (array, i, strncmp, HAS_CPU_FEATURE (SSSE3), + __strncmp_ssse3) + IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_ia32)) +#endif +#endif + + return i; +} diff --git a/sysdeps/i386/i686/multiarch/locale-defines.sym b/sysdeps/i386/multiarch/locale-defines.sym index aebff9a4f9..aebff9a4f9 100644 --- a/sysdeps/i386/i686/multiarch/locale-defines.sym +++ b/sysdeps/i386/multiarch/locale-defines.sym diff --git a/sysdeps/i386/multiarch/memset-i386.S b/sysdeps/i386/multiarch/memset-i386.S new file mode 100644 index 0000000000..1790a4465a --- /dev/null +++ b/sysdeps/i386/multiarch/memset-i386.S @@ -0,0 +1,14 @@ +#include <init-arch.h> +#if !SUPPORT_I586 && !SUPPORT_I686 +# define memset __memset_i386 +# define __memset_chk __memset_chk_i386 +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(name) +# include <sysdeps/i386/memset.S> + +# ifdef SHARED + .globl __GI_memset + .hidden __GI_memset + __GI_memset = __memset_i386 +# endif +#endif diff --git a/sysdeps/i386/multiarch/memset-i586.S b/sysdeps/i386/multiarch/memset-i586.S new file mode 100644 index 0000000000..98f4dd13cd --- /dev/null +++ b/sysdeps/i386/multiarch/memset-i586.S @@ -0,0 +1,14 @@ +#include <init-arch.h> +#if !SUPPORT_I686 +# define memset __memset_i586 +# define __memset_chk __memset_chk_i586 +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(name) +# include <sysdeps/i386/i586/memset.S> + +# if defined SHARED && SUPPORT_I586 + .globl __GI_memset + .hidden __GI_memset + __GI_memset = __memset_i586 +# endif +#endif diff --git a/sysdeps/i386/multiarch/memset-i686.S b/sysdeps/i386/multiarch/memset-i686.S new file mode 100644 index 0000000000..83830f0a39 --- /dev/null +++ b/sysdeps/i386/multiarch/memset-i686.S @@ -0,0 +1,12 @@ +#include <init-arch.h> +#define memset __memset_i686 +#define __memset_chk __memset_chk_i686 +#undef libc_hidden_builtin_def +#define libc_hidden_builtin_def(name) +#include <sysdeps/i386/i686/memset.S> + +#if defined SHARED && SUPPORT_I686 + .globl __GI_memset + .hidden __GI_memset + __GI_memset = __memset_i686 +#endif diff --git a/sysdeps/i386/i686/multiarch/memset-sse2-rep.S b/sysdeps/i386/multiarch/memset-sse2-rep.S index 9c8f232c42..9c8f232c42 100644 --- a/sysdeps/i386/i686/multiarch/memset-sse2-rep.S +++ b/sysdeps/i386/multiarch/memset-sse2-rep.S diff --git a/sysdeps/i386/i686/multiarch/memset-sse2.S b/sysdeps/i386/multiarch/memset-sse2.S index d03e647a3f..d03e647a3f 100644 --- a/sysdeps/i386/i686/multiarch/memset-sse2.S +++ b/sysdeps/i386/multiarch/memset-sse2.S diff --git a/sysdeps/i386/multiarch/memset.c b/sysdeps/i386/multiarch/memset.c new file mode 100644 index 0000000000..d35f720a62 --- /dev/null +++ b/sysdeps/i386/multiarch/memset.c @@ -0,0 +1,63 @@ +/* Multiple versions of memset. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2015 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 multiple versions only for the definition in lib. */ +#if IS_IN (libc) +/* Redefine memset so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef memset +# define memset __redirect_memset +# include <string.h> +# undef memset + +# include <init-arch.h> + +extern __typeof (__redirect_memset) __memset_i386 attribute_hidden; +extern __typeof (__redirect_memset) __memset_i586 attribute_hidden; +extern __typeof (__redirect_memset) __memset_i686 attribute_hidden; +extern __typeof (__redirect_memset) __memset_sse2 attribute_hidden; +extern __typeof (__redirect_memset) __memset_sse2_rep attribute_hidden; + +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ +extern __typeof (__redirect_memset) __memset; +extern void *memset_ifunc (void) __asm__ ("__memset"); + +void * +memset_ifunc (void) +{ + if (HAS_CPU_FEATURE (SSE2)) + { + if (HAS_ARCH_FEATURE (Fast_Rep_String)) + return __memset_sse2_rep; + else + return __memset_sse2; + } + + if (HAS_I686) + return __memset_i686; + else if (HAS_I586) + return __memset_i586; + else + return __memset_i386; +} +__asm__ (".type __memset, %gnu_indirect_function"); + +strong_alias (__memset, memset) +#endif diff --git a/sysdeps/i386/multiarch/memset_chk.S b/sysdeps/i386/multiarch/memset_chk.S new file mode 100644 index 0000000000..350f0d17c6 --- /dev/null +++ b/sysdeps/i386/multiarch/memset_chk.S @@ -0,0 +1,113 @@ +/* Multiple versions of __memset_chk + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2010-2015 Free Software Foundation, Inc. + Contributed by Intel Corporation. + 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 multiple versions only for the definition in lib. */ +#if IS_IN (libc) +# include <sysdep.h> +# include <init-arch.h> + + .text +ENTRY(__memset_chk) + .type __memset_chk, @gnu_indirect_function + LOAD_GOT_AND_RTLD_GLOBAL_RO +# if !SUPPORT_I686 + LOAD_FUNC_GOT_EAX (__memset_chk_i386) + HAS_ARCH_FEATURE (I686) + jz 2f +# endif + LOAD_FUNC_GOT_EAX (__memset_chk_i686) + HAS_CPU_FEATURE (SSE2) + jz 2f + LOAD_FUNC_GOT_EAX (__memset_chk_sse2) + HAS_CPU_FEATURE (Fast_Rep_String) + jz 2f + LOAD_FUNC_GOT_EAX (__memset_chk_sse2_rep) +2: ret +END(__memset_chk) + +# ifdef SHARED +strong_alias (__memset_chk, __memset_zero_constant_len_parameter) + .section .gnu.warning.__memset_zero_constant_len_parameter + .string "memset used with constant zero length parameter; this could be due to transposed parameters" +# else + .text + .type __memset_chk_sse2, @function + .p2align 4; +__memset_chk_sse2: + cfi_startproc + CALL_MCOUNT + movl 12(%esp), %eax + cmpl %eax, 16(%esp) + jb __chk_fail + jmp __memset_sse2 + cfi_endproc + .size __memset_chk_sse2, .-__memset_chk_sse2 + + .type __memset_chk_sse2_rep, @function + .p2align 4; +__memset_chk_sse2_rep: + cfi_startproc + CALL_MCOUNT + movl 12(%esp), %eax + cmpl %eax, 16(%esp) + jb __chk_fail + jmp __memset_sse2_rep + cfi_endproc + .size __memset_chk_sse2_rep, .-__memset_chk_sse2_rep + + .type __memset_chk_i686, @function + .p2align 4; +__memset_chk_i686: + cfi_startproc + CALL_MCOUNT + movl 12(%esp), %eax + cmpl %eax, 16(%esp) + jb __chk_fail + jmp __memset_i686 + cfi_endproc + .size __memset_chk_i686, .-__memset_chk_i686 + + .type __memset_chk_i586, @function + .p2align 4; +__memset_chk_i586: + cfi_startproc + CALL_MCOUNT + movl 12(%esp), %eax + cmpl %eax, 16(%esp) + jb __chk_fail + jmp __memset_i586 + cfi_endproc + .size __memset_chk_i586, .-__memset_chk_i586 + +# if !SUPPORT_I686 + .type __memset_chk_i386, @function + .p2align 4; +__memset_chk_i386: + cfi_startproc + CALL_MCOUNT + movl 12(%esp), %eax + cmpl %eax, 16(%esp) + jb __chk_fail + jmp __memset_i386 + cfi_endproc + .size __memset_chk_i386, .-__memset_chk_i386 +# endif +# endif +#endif diff --git a/sysdeps/i386/i686/multiarch/test-multiarch.c b/sysdeps/i386/multiarch/test-multiarch.c index 593cfec273..593cfec273 100644 --- a/sysdeps/i386/i686/multiarch/test-multiarch.c +++ b/sysdeps/i386/multiarch/test-multiarch.c |