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-20 16:25:22 -0700 |
commit | 6458faf199de42a3bba3dc7cad9fb38d66bf0b4d (patch) | |
tree | ab91cebf0633a9f9dad6263cb75ff16c3cf01a9c /sysdeps | |
parent | 507abbad59c5777be75a6bac5f887d919af44e6d (diff) | |
download | glibc-6458faf199de42a3bba3dc7cad9fb38d66bf0b4d.tar.gz |
Add i386 strcmp family multiarch functions
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/i386/i686/rtld-strcmp.S | 1 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/Makefile | 8 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/ifunc-impl-list.c | 22 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/rtld-strcmp.c | 1 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcasecmp-i386.c (renamed from sysdeps/i386/i686/multiarch/strcasecmp-c.c) | 2 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcasecmp.c | 53 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcasecmp_l-i386.c (renamed from sysdeps/i386/i686/multiarch/strcasecmp_l-c.c) | 2 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcasecmp_l-sse4.S (renamed from sysdeps/i386/i686/multiarch/strcasecmp_l-sse4.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcasecmp_l-ssse3.S (renamed from sysdeps/i386/i686/multiarch/strcasecmp_l-ssse3.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcasecmp_l.c | 53 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcmp-i386.c | 10 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcmp-i686.S | 16 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcmp-sse4.S (renamed from sysdeps/i386/i686/multiarch/strcmp-sse4.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcmp-ssse3.S (renamed from sysdeps/i386/i686/multiarch/strcmp-ssse3.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcmp.c | 58 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncase-i386.c (renamed from sysdeps/i386/i686/multiarch/strncase-c.c) | 2 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncase.c | 53 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncase_l-i386.c (renamed from sysdeps/i386/i686/multiarch/strncase_l-c.c) | 2 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncase_l-sse4.S (renamed from sysdeps/i386/i686/multiarch/strncase_l-sse4.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncase_l-ssse3.S (renamed from sysdeps/i386/i686/multiarch/strncase_l-ssse3.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncase_l.c | 53 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncmp-i386.c (renamed from sysdeps/i386/i686/multiarch/strncmp-c.c) | 4 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncmp-sse4.S (renamed from sysdeps/i386/i686/multiarch/strncmp-sse4.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncmp-ssse3.S (renamed from sysdeps/i386/i686/multiarch/strncmp-ssse3.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncmp.c | 54 |
25 files changed, 379 insertions, 15 deletions
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 147258cbe9..ba6a489303 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 73cd46d15c..015ad3c6dd 100644 --- a/sysdeps/i386/multiarch/ifunc-impl-list.c +++ b/sysdeps/i386/multiarch/ifunc-impl-list.c @@ -191,7 +191,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, @@ -200,7 +199,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, @@ -211,8 +210,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), @@ -228,6 +228,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, @@ -235,8 +236,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 !SUPPORT_I686 + IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_i386) #endif + ) /* Support sysdeps/i386/i686/multiarch/strcpy.S. */ IFUNC_IMPL (i, name, strcpy, @@ -256,6 +260,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, @@ -266,7 +271,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, @@ -277,8 +282,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), @@ -451,6 +457,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, @@ -458,8 +465,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..f5931bf5aa --- /dev/null +++ b/sysdeps/i386/multiarch/strcmp-i386.c @@ -0,0 +1,10 @@ +#include <init-arch.h> +#if !SUPPORT_I686 +# ifdef SHARED +# 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" +#endif diff --git a/sysdeps/i386/multiarch/strcmp-i686.S b/sysdeps/i386/multiarch/strcmp-i686.S new file mode 100644 index 0000000000..ce07410733 --- /dev/null +++ b/sysdeps/i386/multiarch/strcmp-i686.S @@ -0,0 +1,16 @@ +#include <init-arch.h> +#ifdef SHARED +# define strcmp __strcmp_i686 +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(name) +#endif + +#if SUPPORT_I686 || defined SHARED +#include <sysdeps/i386/i686/strcmp.S> +#endif + +#if defined SHARED && SUPPORT_I686 + .globl __GI_strcmp + .hidden __GI_strcmp + __GI_strcmp = __strcmp_i686 +#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..58049e8051 --- /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 (HAS_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 |