diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2015-08-20 13:57:22 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-08-27 09:35:11 -0700 |
commit | f737f66b63911549f2dc82a5b940cb219b6e661e (patch) | |
tree | 33335e81d9ec67a491f75a7055affdf035aa445e | |
parent | 4fadad5ce5208d12fd65538ecbec1b97ae83b440 (diff) | |
download | glibc-f737f66b63911549f2dc82a5b940cb219b6e661e.tar.gz glibc-f737f66b63911549f2dc82a5b940cb219b6e661e.tar.xz glibc-f737f66b63911549f2dc82a5b940cb219b6e661e.zip |
Add i386 strcmp family multiarch functions
35 files changed, 389 insertions, 198 deletions
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile index 2a14fe8983..d38a051305 100644 --- a/sysdeps/i386/i686/multiarch/Makefile +++ b/sysdeps/i386/i686/multiarch/Makefile @@ -1,15 +1,10 @@ ifeq ($(subdir),string) -sysdep_routines += strcmp-ssse3 \ - strcmp-sse4 strncmp-c strncmp-ssse3 strncmp-sse4 \ - varshift \ +sysdep_routines += varshift \ strlen-sse2 strlen-sse2-bsf \ strcat-ssse3 \ strcat-sse2 strncat-ssse3 strncat-sse2 strncat-c \ strchr-sse2 strrchr-sse2 strchr-sse2-bsf strrchr-sse2-bsf \ - strnlen-sse2 strnlen-c \ - strcasecmp_l-c strcasecmp-c strcasecmp_l-ssse3 \ - strncase_l-c strncase-c strncase_l-ssse3 \ - strcasecmp_l-sse4 strncase_l-sse4 + strnlen-sse2 strnlen-c ifeq (yes,$(config-cflags-sse4)) sysdep_routines += strcspn-c strpbrk-c strspn-c CFLAGS-varshift.c += -msse4 diff --git a/sysdeps/i386/i686/multiarch/strcasecmp.S b/sysdeps/i386/i686/multiarch/rtld-strcmp.S index e4b3cf5b46..103ab899eb 100644 --- a/sysdeps/i386/i686/multiarch/strcasecmp.S +++ b/sysdeps/i386/i686/multiarch/rtld-strcmp.S @@ -1,6 +1,5 @@ -/* Entry point for multi-version x86 strcasecmp. - All versions must be listed in ifunc-impl-list.c. - Copyright (C) 2011-2015 Free Software Foundation, Inc. +/* strcmp for ld.so + 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 @@ -17,23 +16,4 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <sysdep.h> -#include <init-arch.h> - - .text -ENTRY(__strcasecmp) - .type __strcasecmp, @gnu_indirect_function - LOAD_GOT_AND_RTLD_GLOBAL_RO - LOAD_FUNC_GOT_EAX (__strcasecmp_ia32) - HAS_CPU_FEATURE (SSSE3) - jz 2f - LOAD_FUNC_GOT_EAX (__strcasecmp_ssse3) - HAS_CPU_FEATURE (SSE4_2) - jz 2f - HAS_ARCH_FEATURE (Slow_SSE4_2) - jnz 2f - LOAD_FUNC_GOT_EAX (__strcasecmp_sse4_2) -2: ret -END(__strcasecmp) - -weak_alias (__strcasecmp, strcasecmp) +#include <sysdeps/i386/i686/strcmp.S> diff --git a/sysdeps/i386/i686/multiarch/strcasecmp_l.S b/sysdeps/i386/i686/multiarch/strcasecmp_l.S deleted file mode 100644 index 711c09b0dc..0000000000 --- a/sysdeps/i386/i686/multiarch/strcasecmp_l.S +++ /dev/null @@ -1,7 +0,0 @@ -/* Multiple versions of strcasecmp_l - All versions must be listed in ifunc-impl-list.c. */ -#define STRCMP __strcasecmp_l -#define USE_AS_STRCASECMP_L -#include "strcmp.S" - -weak_alias (__strcasecmp_l, strcasecmp_l) diff --git a/sysdeps/i386/i686/multiarch/strcmp-i386.c b/sysdeps/i386/i686/multiarch/strcmp-i386.c new file mode 100644 index 0000000000..9d841c9fd1 --- /dev/null +++ b/sysdeps/i386/i686/multiarch/strcmp-i386.c @@ -0,0 +1 @@ +/* Dummy file. */ diff --git a/sysdeps/i386/i686/multiarch/strcmp-i686.S b/sysdeps/i386/i686/multiarch/strcmp-i686.S new file mode 100644 index 0000000000..e4616f8e0a --- /dev/null +++ b/sysdeps/i386/i686/multiarch/strcmp-i686.S @@ -0,0 +1,14 @@ +#ifdef SHARED +# include <init-arch.h> +# define strcmp __strcmp_i686 +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(name) +#endif + +#include <sysdeps/i386/i686/strcmp.S> + +#ifdef SHARED + .globl __GI_strcmp + .hidden __GI_strcmp + __GI_strcmp = __strcmp_i686 +#endif diff --git a/sysdeps/i386/i686/multiarch/strcmp.S b/sysdeps/i386/i686/multiarch/strcmp.S deleted file mode 100644 index cad179d8f2..0000000000 --- a/sysdeps/i386/i686/multiarch/strcmp.S +++ /dev/null @@ -1,95 +0,0 @@ -/* Multiple versions of strcmp - 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/>. */ - -#include <sysdep.h> -#include <init-arch.h> - -#ifdef USE_AS_STRNCMP -# define STRCMP strncmp -# define __GI_STRCMP __GI_strncmp -# define __STRCMP_IA32 __strncmp_ia32 -# define __STRCMP_SSSE3 __strncmp_ssse3 -# define __STRCMP_SSE4_2 __strncmp_sse4_2 -#elif defined USE_AS_STRCASECMP_L -# define STRCMP __strcasecmp_l -# define __GI_STRCMP __GI_strcasecmp_l -# define __STRCMP_IA32 __strcasecmp_l_ia32 -# define __STRCMP_SSSE3 __strcasecmp_l_ssse3 -# define __STRCMP_SSE4_2 __strcasecmp_l_sse4_2 -#elif defined USE_AS_STRNCASECMP_L -# define STRCMP __strncasecmp_l -# define __GI_STRCMP __GI_strncasecmp_l -# define __STRCMP_IA32 __strncasecmp_l_ia32 -# define __STRCMP_SSSE3 __strncasecmp_l_ssse3 -# define __STRCMP_SSE4_2 __strncasecmp_l_sse4_2 -#else -# define STRCMP strcmp -# define __GI_STRCMP __GI_strcmp -# define __STRCMP_IA32 __strcmp_ia32 -# define __STRCMP_SSSE3 __strcmp_ssse3 -# define __STRCMP_SSE4_2 __strcmp_sse4_2 -#endif - -/* Define multiple versions only for the definition in libc. Don't - define multiple versions for strncmp in static library since we - need strncmp before the initialization happened. */ -#if (defined SHARED || !defined USE_AS_STRNCMP) && IS_IN (libc) - .text -ENTRY(STRCMP) - .type STRCMP, @gnu_indirect_function - LOAD_GOT_AND_RTLD_GLOBAL_RO - LOAD_FUNC_GOT_EAX (__STRCMP_IA32) - HAS_CPU_FEATURE (SSSE3) - jz 2f - LOAD_FUNC_GOT_EAX (__STRCMP_SSSE3) - HAS_CPU_FEATURE (SSE4_2) - jz 2f - HAS_ARCH_FEATURE (Slow_SSE4_2) - jnz 2f - LOAD_FUNC_GOT_EAX (__STRCMP_SSE4_2) -2: ret -END(STRCMP) - -# undef ENTRY -# define ENTRY(name) \ - .type __STRCMP_IA32, @function; \ - .p2align 4; \ - .globl __STRCMP_IA32; \ - .hidden __STRCMP_IA32; \ - __STRCMP_IA32: cfi_startproc; \ - CALL_MCOUNT -# undef END -# define END(name) \ - cfi_endproc; .size __STRCMP_IA32, .-__STRCMP_IA32 - -# ifdef SHARED -# undef libc_hidden_builtin_def -/* IFUNC doesn't work with the hidden functions in shared library since - they will be called without setting up EBX needed for PLT which is - used by IFUNC. */ -# define libc_hidden_builtin_def(name) \ - .globl __GI_STRCMP; __GI_STRCMP = __STRCMP_IA32 -# endif -#endif - -#if !defined USE_AS_STRNCMP && !defined USE_AS_STRCASECMP_L \ - && !defined USE_AS_STRNCASECMP_L -# include "../strcmp.S" -#endif diff --git a/sysdeps/i386/i686/multiarch/strcmp.c b/sysdeps/i386/i686/multiarch/strcmp.c new file mode 100644 index 0000000000..e69369900d --- /dev/null +++ b/sysdeps/i386/i686/multiarch/strcmp.c @@ -0,0 +1 @@ +#include <sysdeps/i386/multiarch/strcmp.c> diff --git a/sysdeps/i386/i686/multiarch/strncase.S b/sysdeps/i386/i686/multiarch/strncase.S deleted file mode 100644 index 0cdbeff42a..0000000000 --- a/sysdeps/i386/i686/multiarch/strncase.S +++ /dev/null @@ -1,39 +0,0 @@ -/* Entry point for multi-version x86 strncasecmp. - All versions must be listed in ifunc-impl-list.c. - Copyright (C) 2011-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 <sysdep.h> -#include <init-arch.h> - - .text -ENTRY(__strncasecmp) - .type __strncasecmp, @gnu_indirect_function - LOAD_GOT_AND_RTLD_GLOBAL_RO - LOAD_FUNC_GOT_EAX (__strncasecmp_ia32) - HAS_CPU_FEATURE (SSSE3) - jz 2f - LOAD_FUNC_GOT_EAX (__strncasecmp_ssse3) - HAS_CPU_FEATURE (SSE4_2) - jz 2f - HAS_ARCH_FEATURE (Slow_SSE4_2) - jnz 2f - LOAD_FUNC_GOT_EAX (__strncasecmp_sse4_2) -2: ret -END(__strncasecmp) - -weak_alias (__strncasecmp, strncasecmp) diff --git a/sysdeps/i386/i686/multiarch/strncase_l.S b/sysdeps/i386/i686/multiarch/strncase_l.S deleted file mode 100644 index 8a74ee8574..0000000000 --- a/sysdeps/i386/i686/multiarch/strncase_l.S +++ /dev/null @@ -1,7 +0,0 @@ -/* Multiple versions of strncasecmp_l - All versions must be listed in ifunc-impl-list.c. */ -#define STRCMP __strncasecmp_l -#define USE_AS_STRNCASECMP_L -#include "strcmp.S" - -weak_alias (__strncasecmp_l, strncasecmp_l) diff --git a/sysdeps/i386/i686/multiarch/strncmp.S b/sysdeps/i386/i686/multiarch/strncmp.S deleted file mode 100644 index 150d4786d2..0000000000 --- a/sysdeps/i386/i686/multiarch/strncmp.S +++ /dev/null @@ -1,5 +0,0 @@ -/* Multiple versions of strncmp - All versions must be listed in ifunc-impl-list.c. */ -#define USE_AS_STRNCMP -#define STRCMP strncmp -#include "strcmp.S" diff --git a/sysdeps/i386/i686/rtld-strcmp.S b/sysdeps/i386/i686/rtld-strcmp.S new file mode 100644 index 0000000000..01f31f4ef8 --- /dev/null +++ b/sysdeps/i386/i686/rtld-strcmp.S @@ -0,0 +1 @@ +#include <sysdeps/i386/i686/strcmp.S> diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile index 1518caed7d..78a99a7bbe 100644 --- a/sysdeps/i386/multiarch/Makefile +++ b/sysdeps/i386/multiarch/Makefile @@ -25,7 +25,13 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \ stpcpy-i386 stpcpy-i586 stpcpy-sse2 stpcpy-ssse3 \ stpncpy-i386 stpncpy-sse2 stpncpy-ssse3 \ strcpy-i386 strcpy-i586 strcpy-sse2 strcpy-ssse3 \ - strncpy-i386 strncpy-sse2 strncpy-ssse3 + strncpy-i386 strncpy-sse2 strncpy-ssse3 \ + strcmp-i386 strcmp-i686 strcmp-sse4 strcmp-ssse3 \ + strcasecmp-i386 strcasecmp_l-i386 strcasecmp_l-sse4 \ + strcasecmp_l-ssse3 \ + strncase-i386 strncase_l-i386 strncase_l-sse4 \ + strncase_l-ssse3 \ + strncmp-i386 strncmp-ssse3 strncmp-sse4 endif ifeq (mathyes,$(subdir)$(config-cflags-avx)) diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c index 412f227457..bddc9e75da 100644 --- a/sysdeps/i386/multiarch/ifunc-impl-list.c +++ b/sysdeps/i386/multiarch/ifunc-impl-list.c @@ -185,7 +185,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, #endif ) -#if 0 /* Support sysdeps/i386/i686/multiarch/strcasecmp.S. */ IFUNC_IMPL (i, name, strcasecmp, IFUNC_IMPL_ADD (array, i, strcasecmp, @@ -194,7 +193,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, IFUNC_IMPL_ADD (array, i, strcasecmp, HAS_CPU_FEATURE (SSSE3), __strcasecmp_ssse3) - IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_ia32)) + IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_i386)) /* Support sysdeps/i386/i686/multiarch/strcasecmp_l.S. */ IFUNC_IMPL (i, name, strcasecmp_l, @@ -205,8 +204,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, HAS_CPU_FEATURE (SSSE3), __strcasecmp_l_ssse3) IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1, - __strcasecmp_l_ia32)) + __strcasecmp_l_i386)) +#if 0 /* Support sysdeps/i386/i686/multiarch/strcat.S. */ IFUNC_IMPL (i, name, strcat, IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSSE3), @@ -222,6 +222,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2), __strchr_sse2) IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_ia32)) +#endif /* Support sysdeps/i386/i686/multiarch/strcmp.S. */ IFUNC_IMPL (i, name, strcmp, @@ -229,8 +230,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, __strcmp_sse4_2) IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSSE3), __strcmp_ssse3) - IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_ia32)) + IFUNC_IMPL_ADD (array, i, strcmp, HAS_I686, __strcmp_i686) +#if MINIMUM_ISA < 686 + IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_i386) #endif + ) /* Support sysdeps/i386/i686/multiarch/strcpy.S. */ IFUNC_IMPL (i, name, strcpy, @@ -250,6 +254,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, IFUNC_IMPL_ADD (array, i, strcspn, HAS_CPU_FEATURE (SSE4_2), __strcspn_sse42) IFUNC_IMPL_ADD (array, i, strcspn, 1, __strcspn_ia32)) +#endif /* Support sysdeps/i386/i686/multiarch/strncase.S. */ IFUNC_IMPL (i, name, strncasecmp, @@ -260,7 +265,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, HAS_CPU_FEATURE (SSSE3), __strncasecmp_ssse3) IFUNC_IMPL_ADD (array, i, strncasecmp, 1, - __strncasecmp_ia32)) + __strncasecmp_i386)) /* Support sysdeps/i386/i686/multiarch/strncase_l.S. */ IFUNC_IMPL (i, name, strncasecmp_l, @@ -271,8 +276,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, HAS_CPU_FEATURE (SSSE3), __strncasecmp_l_ssse3) IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1, - __strncasecmp_l_ia32)) + __strncasecmp_l_i386)) +#if 0 /* Support sysdeps/i386/i686/multiarch/strncat.S. */ IFUNC_IMPL (i, name, strncat, IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSSE3), @@ -437,6 +443,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2), __strlen_sse2) IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_ia32)) +#endif /* Support sysdeps/i386/i686/multiarch/strncmp.S. */ IFUNC_IMPL (i, name, strncmp, @@ -444,8 +451,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, __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 + IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_i386)) #endif return i; diff --git a/sysdeps/i386/multiarch/rtld-strcmp.c b/sysdeps/i386/multiarch/rtld-strcmp.c new file mode 100644 index 0000000000..78448ae52b --- /dev/null +++ b/sysdeps/i386/multiarch/rtld-strcmp.c @@ -0,0 +1 @@ +#include "string/strcmp.c" diff --git a/sysdeps/i386/i686/multiarch/strcasecmp-c.c b/sysdeps/i386/multiarch/strcasecmp-i386.c index 753c6ec84a..eb5d602dc1 100644 --- a/sysdeps/i386/i686/multiarch/strcasecmp-c.c +++ b/sysdeps/i386/multiarch/strcasecmp-i386.c @@ -5,7 +5,7 @@ extern __typeof (strcasecmp) __strcasecmp_nonascii; #define __strcasecmp __strcasecmp_nonascii #include <string/strcasecmp.c> -strong_alias (__strcasecmp_nonascii, __strcasecmp_ia32) +strong_alias (__strcasecmp_nonascii, __strcasecmp_i386) /* The needs of strcasecmp in libc are minimal, no need to go through the IFUNC. */ diff --git a/sysdeps/i386/multiarch/strcasecmp.c b/sysdeps/i386/multiarch/strcasecmp.c new file mode 100644 index 0000000000..261bd7a893 --- /dev/null +++ b/sysdeps/i386/multiarch/strcasecmp.c @@ -0,0 +1,53 @@ +/* Multiple versions of strcasecmp. + 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 strcasecmp so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strcasecmp +# define strcasecmp __redirect_strcasecmp +# include <string.h> +# undef strcasecmp + +# include <init-arch.h> + +extern __typeof (__redirect_strcasecmp) __strcasecmp_i386 attribute_hidden; +extern __typeof (__redirect_strcasecmp) __strcasecmp_ssse3 attribute_hidden; +extern __typeof (__redirect_strcasecmp) __strcasecmp_sse4_2 attribute_hidden; + +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ +extern __typeof (__redirect_strcasecmp) __strcasecmp; +extern void *strcasecmp_ifunc (void) __asm__ ("__strcasecmp"); + +void * +strcasecmp_ifunc (void) +{ + if (HAS_CPU_FEATURE (SSE4_2)) + return __strcasecmp_sse4_2; + else if (HAS_CPU_FEATURE (SSSE3)) + return __strcasecmp_ssse3; + + return __strcasecmp_i386; +} +__asm__ (".type __strcasecmp, %gnu_indirect_function"); + +weak_alias (__strcasecmp, strcasecmp) +#endif diff --git a/sysdeps/i386/i686/multiarch/strcasecmp_l-c.c b/sysdeps/i386/multiarch/strcasecmp_l-i386.c index d4fcd2b4a1..b5b38d3f7a 100644 --- a/sysdeps/i386/i686/multiarch/strcasecmp_l-c.c +++ b/sysdeps/i386/multiarch/strcasecmp_l-i386.c @@ -6,7 +6,7 @@ extern __typeof (strcasecmp_l) __strcasecmp_l_nonascii; #define USE_IN_EXTENDED_LOCALE_MODEL 1 #include <string/strcasecmp.c> -strong_alias (__strcasecmp_l_nonascii, __strcasecmp_l_ia32) +strong_alias (__strcasecmp_l_nonascii, __strcasecmp_l_i386) /* The needs of strcasecmp in libc are minimal, no need to go through the IFUNC. */ diff --git a/sysdeps/i386/i686/multiarch/strcasecmp_l-sse4.S b/sysdeps/i386/multiarch/strcasecmp_l-sse4.S index 411d4153f2..411d4153f2 100644 --- a/sysdeps/i386/i686/multiarch/strcasecmp_l-sse4.S +++ b/sysdeps/i386/multiarch/strcasecmp_l-sse4.S diff --git a/sysdeps/i386/i686/multiarch/strcasecmp_l-ssse3.S b/sysdeps/i386/multiarch/strcasecmp_l-ssse3.S index a22b93c518..a22b93c518 100644 --- a/sysdeps/i386/i686/multiarch/strcasecmp_l-ssse3.S +++ b/sysdeps/i386/multiarch/strcasecmp_l-ssse3.S diff --git a/sysdeps/i386/multiarch/strcasecmp_l.c b/sysdeps/i386/multiarch/strcasecmp_l.c new file mode 100644 index 0000000000..7bdc760a3f --- /dev/null +++ b/sysdeps/i386/multiarch/strcasecmp_l.c @@ -0,0 +1,53 @@ +/* Multiple versions of strcasecmp_l. + 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 strcasecmp_l so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strcasecmp_l +# define strcasecmp_l __redirect_strcasecmp_l +# include <string.h> +# undef strcasecmp_l + +# include <init-arch.h> + +extern __typeof (__redirect_strcasecmp_l) __strcasecmp_l_i386 attribute_hidden; +extern __typeof (__redirect_strcasecmp_l) __strcasecmp_l_ssse3 attribute_hidden; +extern __typeof (__redirect_strcasecmp_l) __strcasecmp_l_sse4_2 attribute_hidden; + +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ +extern __typeof (__redirect_strcasecmp_l) __strcasecmp_l; +extern void *strcasecmp_l_ifunc (void) __asm__ ("__strcasecmp_l"); + +void * +strcasecmp_l_ifunc (void) +{ + if (HAS_CPU_FEATURE (SSE4_2)) + return __strcasecmp_l_sse4_2; + else if (HAS_CPU_FEATURE (SSSE3)) + return __strcasecmp_l_ssse3; + + return __strcasecmp_l_i386; +} +__asm__ (".type __strcasecmp_l, %gnu_indirect_function"); + +weak_alias (__strcasecmp_l, strcasecmp_l) +#endif diff --git a/sysdeps/i386/multiarch/strcmp-i386.c b/sysdeps/i386/multiarch/strcmp-i386.c new file mode 100644 index 0000000000..f3b045a477 --- /dev/null +++ b/sysdeps/i386/multiarch/strcmp-i386.c @@ -0,0 +1,9 @@ +#ifdef SHARED +# include <init-arch.h> +# define STRCMP __strcmp_i386 +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(name) \ + __hidden_ver1 (__strcmp_i386, __GI_strcmp, __strcmp_i386); +#endif + +#include "string/strcmp.c" diff --git a/sysdeps/i386/multiarch/strcmp-i686.S b/sysdeps/i386/multiarch/strcmp-i686.S new file mode 100644 index 0000000000..0265d49d5f --- /dev/null +++ b/sysdeps/i386/multiarch/strcmp-i686.S @@ -0,0 +1,6 @@ +#ifdef SHARED +# define strcmp __strcmp_i686 +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(name) +# include <sysdeps/i386/i686/strcmp.S> +#endif diff --git a/sysdeps/i386/i686/multiarch/strcmp-sse4.S b/sysdeps/i386/multiarch/strcmp-sse4.S index 38c2317c26..38c2317c26 100644 --- a/sysdeps/i386/i686/multiarch/strcmp-sse4.S +++ b/sysdeps/i386/multiarch/strcmp-sse4.S diff --git a/sysdeps/i386/i686/multiarch/strcmp-ssse3.S b/sysdeps/i386/multiarch/strcmp-ssse3.S index fb21288c7d..fb21288c7d 100644 --- a/sysdeps/i386/i686/multiarch/strcmp-ssse3.S +++ b/sysdeps/i386/multiarch/strcmp-ssse3.S diff --git a/sysdeps/i386/multiarch/strcmp.c b/sysdeps/i386/multiarch/strcmp.c new file mode 100644 index 0000000000..5073c69a7f --- /dev/null +++ b/sysdeps/i386/multiarch/strcmp.c @@ -0,0 +1,58 @@ +/* Multiple versions of strcmp. + 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 libc. Don't + define multiple versions for strcmp in static library since we + need strcmp before the initialization happened. */ +#if defined SHARED && IS_IN (libc) +# define _HAVE_STRING_ARCH_strcmp +/* Redefine strcmp so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strcmp +# define strcmp __redirect_strcmp +# include <string.h> +# undef strcmp + +# include <init-arch.h> + +extern __typeof (__redirect_strcmp) __strcmp_i386 attribute_hidden; +extern __typeof (__redirect_strcmp) __strcmp_i686 attribute_hidden; +extern __typeof (__redirect_strcmp) __strcmp_ssse3 attribute_hidden; +extern __typeof (__redirect_strcmp) __strcmp_sse4_2 attribute_hidden; + +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ +extern __typeof (__redirect_strcmp) strcmp; +extern void *strcmp_ifunc (void) __asm__ ("strcmp"); + +void * +strcmp_ifunc (void) +{ + if (HAS_CPU_FEATURE (SSE4_2)) + return __strcmp_sse4_2; + else if (HAS_CPU_FEATURE (SSSE3)) + return __strcmp_ssse3; + + if (USE_I686) + return __strcmp_i686; + else + return __strcmp_i386; +} +__asm__ (".type strcmp, %gnu_indirect_function"); +#endif diff --git a/sysdeps/i386/i686/multiarch/strncase-c.c b/sysdeps/i386/multiarch/strncase-i386.c index 76581eb62b..7053e553cf 100644 --- a/sysdeps/i386/i686/multiarch/strncase-c.c +++ b/sysdeps/i386/multiarch/strncase-i386.c @@ -5,4 +5,4 @@ extern __typeof (strncasecmp) __strncasecmp_nonascii; #define __strncasecmp __strncasecmp_nonascii #include <string/strncase.c> -strong_alias (__strncasecmp_nonascii, __strncasecmp_ia32) +strong_alias (__strncasecmp_nonascii, __strncasecmp_i386) diff --git a/sysdeps/i386/multiarch/strncase.c b/sysdeps/i386/multiarch/strncase.c new file mode 100644 index 0000000000..9e5dcabfca --- /dev/null +++ b/sysdeps/i386/multiarch/strncase.c @@ -0,0 +1,53 @@ +/* Multiple versions of strncasecmp. + 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 strncasecmp so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strncasecmp +# define strncasecmp __redirect_strncasecmp +# include <string.h> +# undef strncasecmp + +# include <init-arch.h> + +extern __typeof (__redirect_strncasecmp) __strncasecmp_i386 attribute_hidden; +extern __typeof (__redirect_strncasecmp) __strncasecmp_ssse3 attribute_hidden; +extern __typeof (__redirect_strncasecmp) __strncasecmp_sse4_2 attribute_hidden; + +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ +extern __typeof (__redirect_strncasecmp) __strncasecmp; +extern void *strncasecmp_ifunc (void) __asm__ ("__strncasecmp"); + +void * +strncasecmp_ifunc (void) +{ + if (HAS_CPU_FEATURE (SSE4_2)) + return __strncasecmp_sse4_2; + else if (HAS_CPU_FEATURE (SSSE3)) + return __strncasecmp_ssse3; + + return __strncasecmp_i386; +} +__asm__ (".type __strncasecmp, %gnu_indirect_function"); + +weak_alias (__strncasecmp, strncasecmp) +#endif diff --git a/sysdeps/i386/i686/multiarch/strncase_l-c.c b/sysdeps/i386/multiarch/strncase_l-i386.c index 7e601af271..efee0bf991 100644 --- a/sysdeps/i386/i686/multiarch/strncase_l-c.c +++ b/sysdeps/i386/multiarch/strncase_l-i386.c @@ -6,7 +6,7 @@ extern __typeof (strncasecmp_l) __strncasecmp_l_nonascii; #define USE_IN_EXTENDED_LOCALE_MODEL 1 #include <string/strncase.c> -strong_alias (__strncasecmp_l_nonascii, __strncasecmp_l_ia32) +strong_alias (__strncasecmp_l_nonascii, __strncasecmp_l_i386) /* The needs of strcasecmp in libc are minimal, no need to go through the IFUNC. */ diff --git a/sysdeps/i386/i686/multiarch/strncase_l-sse4.S b/sysdeps/i386/multiarch/strncase_l-sse4.S index 557210832e..557210832e 100644 --- a/sysdeps/i386/i686/multiarch/strncase_l-sse4.S +++ b/sysdeps/i386/multiarch/strncase_l-sse4.S diff --git a/sysdeps/i386/i686/multiarch/strncase_l-ssse3.S b/sysdeps/i386/multiarch/strncase_l-ssse3.S index d438a1ae35..d438a1ae35 100644 --- a/sysdeps/i386/i686/multiarch/strncase_l-ssse3.S +++ b/sysdeps/i386/multiarch/strncase_l-ssse3.S diff --git a/sysdeps/i386/multiarch/strncase_l.c b/sysdeps/i386/multiarch/strncase_l.c new file mode 100644 index 0000000000..279b3ce007 --- /dev/null +++ b/sysdeps/i386/multiarch/strncase_l.c @@ -0,0 +1,53 @@ +/* Multiple versions of strncasecmp_l. + 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 strncasecmp_l so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strncasecmp_l +# define strncasecmp_l __redirect_strncasecmp_l +# include <string.h> +# undef strncasecmp_l + +# include <init-arch.h> + +extern __typeof (__redirect_strncasecmp_l) __strncasecmp_l_i386 attribute_hidden; +extern __typeof (__redirect_strncasecmp_l) __strncasecmp_l_ssse3 attribute_hidden; +extern __typeof (__redirect_strncasecmp_l) __strncasecmp_l_sse4_2 attribute_hidden; + +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ +extern __typeof (__redirect_strncasecmp_l) __strncasecmp_l; +extern void *strncasecmp_l_ifunc (void) __asm__ ("__strncasecmp_l"); + +void * +strncasecmp_l_ifunc (void) +{ + if (HAS_CPU_FEATURE (SSE4_2)) + return __strncasecmp_l_sse4_2; + else if (HAS_CPU_FEATURE (SSSE3)) + return __strncasecmp_l_ssse3; + + return __strncasecmp_l_i386; +} +__asm__ (".type __strncasecmp_l, %gnu_indirect_function"); + +weak_alias (__strncasecmp_l, strncasecmp_l) +#endif diff --git a/sysdeps/i386/i686/multiarch/strncmp-c.c b/sysdeps/i386/multiarch/strncmp-i386.c index cc059da494..8e4138894f 100644 --- a/sysdeps/i386/i686/multiarch/strncmp-c.c +++ b/sysdeps/i386/multiarch/strncmp-i386.c @@ -1,8 +1,8 @@ #ifdef SHARED -# define STRNCMP __strncmp_ia32 +# define STRNCMP __strncmp_i386 # undef libc_hidden_builtin_def # define libc_hidden_builtin_def(name) \ - __hidden_ver1 (__strncmp_ia32, __GI_strncmp, __strncmp_ia32); + __hidden_ver1 (__strncmp_i386, __GI_strncmp, __strncmp_i386); #endif #include "string/strncmp.c" diff --git a/sysdeps/i386/i686/multiarch/strncmp-sse4.S b/sysdeps/i386/multiarch/strncmp-sse4.S index cf14dfaf6c..cf14dfaf6c 100644 --- a/sysdeps/i386/i686/multiarch/strncmp-sse4.S +++ b/sysdeps/i386/multiarch/strncmp-sse4.S diff --git a/sysdeps/i386/i686/multiarch/strncmp-ssse3.S b/sysdeps/i386/multiarch/strncmp-ssse3.S index 536c8685f2..536c8685f2 100644 --- a/sysdeps/i386/i686/multiarch/strncmp-ssse3.S +++ b/sysdeps/i386/multiarch/strncmp-ssse3.S diff --git a/sysdeps/i386/multiarch/strncmp.c b/sysdeps/i386/multiarch/strncmp.c new file mode 100644 index 0000000000..180f87062e --- /dev/null +++ b/sysdeps/i386/multiarch/strncmp.c @@ -0,0 +1,54 @@ +/* Multiple versions of strncmp. + 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 libc. Don't + define multiple versions for strncmp in static library since we + need strncmp before the initialization happened. */ +#if defined SHARED && IS_IN (libc) +# define _HAVE_STRING_ARCH_strncmp +/* Redefine strncmp so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strncmp +# define strncmp __redirect_strncmp +# include <string.h> +# undef strncmp + +# include <init-arch.h> + +extern __typeof (__redirect_strncmp) __strncmp_i386 attribute_hidden; +extern __typeof (__redirect_strncmp) __strncmp_ssse3 attribute_hidden; +extern __typeof (__redirect_strncmp) __strncmp_sse4_2 attribute_hidden; + +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ +extern __typeof (__redirect_strncmp) strncmp; +extern void *strncmp_ifunc (void) __asm__ ("strncmp"); + +void * +strncmp_ifunc (void) +{ + if (HAS_CPU_FEATURE (SSE4_2)) + return __strncmp_sse4_2; + else if (HAS_CPU_FEATURE (SSSE3)) + return __strncmp_ssse3; + + return __strncmp_i386; +} +__asm__ (".type strncmp, %gnu_indirect_function"); +#endif |