From 636af2a799bc3256c0cd2d0978c23e480a58c4d2 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 28 Sep 2012 07:03:20 -0700 Subject: [PATCH 3/6] Add x86_64 multiarch __libc_func --- ChangeLog.test-ifunc | 21 + sysdeps/x86_64/multiarch/libc-func.c | 855 ++++++++++++++++++++++++++++++++ sysdeps/x86_64/multiarch/memcmp.S | 2 + sysdeps/x86_64/multiarch/memcpy.S | 2 + sysdeps/x86_64/multiarch/mempcpy.S | 2 + sysdeps/x86_64/multiarch/rawmemchr.S | 4 + sysdeps/x86_64/multiarch/strcat.S | 2 + sysdeps/x86_64/multiarch/strchr.S | 4 + sysdeps/x86_64/multiarch/strcmp-sse42.S | 2 + sysdeps/x86_64/multiarch/strcmp.S | 6 + sysdeps/x86_64/multiarch/strcpy.S | 2 + sysdeps/x86_64/multiarch/strlen.S | 2 + sysdeps/x86_64/multiarch/strnlen.S | 2 + sysdeps/x86_64/multiarch/strrchr.S | 4 + 14 files changed, 910 insertions(+) create mode 100644 sysdeps/x86_64/multiarch/libc-func.c diff --git a/ChangeLog.test-ifunc b/ChangeLog.test-ifunc index 7867b0e..f64d40e 100644 --- a/ChangeLog.test-ifunc +++ b/ChangeLog.test-ifunc @@ -1,5 +1,26 @@ 2012-09-26 H.J. Lu + * sysdeps/x86_64/multiarch/libc-func.c: New file. + * sysdeps/x86_64/multiarch/memcmp.S (__memcmp_sse2): Make it + global and hidden. + * sysdeps/x86_64/multiarch/memcpy.S (__memcpy_sse2): Likewise. + * sysdeps/x86_64/multiarch/mempcpy.S (__mempcpy_sse2): Likewise. + * sysdeps/x86_64/multiarch/rawmemchr.S (__rawmemchr_sse42): + Likewise. + (__rawmemchr_sse2): Likewise. + * sysdeps/x86_64/multiarch/strcat.S (STRCAT_SSE2): Likewise. + * sysdeps/x86_64/multiarch/strchr.S (__strchr_sse42): Likewise. + (__strchr_sse2): Likewise. + * sysdeps/x86_64/multiarch/strcmp-sse42.S (STRCMP_SSE42): Likewise. + * sysdeps/x86_64/multiarch/strcmp.S (STRCMP_SSE2): Likewise. + (__strcasecmp_sse2): Likewise. + (__strncasecmp_sse2): Likewise. + * sysdeps/x86_64/multiarch/strcpy.S (STRCPY_SSE2): Likewise. + * sysdeps/x86_64/multiarch/strlen.S (__strlen_sse2): Likewise. + * sysdeps/x86_64/multiarch/strnlen.S (__strnlen_sse2): Likewise. + * sysdeps/x86_64/multiarch/strrchr.S (__strrchr_sse42): Likewise. + (__strrchr_sse2): Likewise. + * sysdeps/i386/i686/multiarch/bcopy.S (__bcopy_ia32): Make it global and hidden. * sysdeps/i386/i686/multiarch/bzero.S (__bzero_ia32): Likewise. diff --git a/sysdeps/x86_64/multiarch/libc-func.c b/sysdeps/x86_64/multiarch/libc-func.c new file mode 100644 index 0000000..44d8b55 --- /dev/null +++ b/sysdeps/x86_64/multiarch/libc-func.c @@ -0,0 +1,855 @@ +/* Copyright (C) 2012 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 + . */ + +#include +#include +#include +#include +#include +#include "init-arch.h" + +#define find_memcmp(array, max) 0 +#define find_memcpy(array, max) 0 +#define find_memmove(array, max) 0 +#define find_mempcpy(array, max) 0 +#define find___memcpy_chk(array, max) 0 +#define find___memmove_chk(array, max) 0 +#define find___mempcpy_chk(array, max) 0 +#define find_memset(array, max) 0 +#define find_rawmemchr(array, max) 0 +#define find_stpcpy(array, max) 0 +#define find_stpncpy(array, max) 0 +#define find_strcpy(array, max) 0 +#define find_strncpy(array, max) 0 +#define find_strcasecmp(array, max) 0 +#define find_strcasecmp_l(array, max) 0 +#define find_strcat(array, max) 0 +#define find_strncat(array, max) 0 +#define find_strcmp(array, max) 0 +#define find_strncasecmp(array, max) 0 +#define find_strncasecmp_l(array, max) 0 +#define find_strncmp(array, max) 0 +#define find_strnlen(array, max) 0 +#define find_strcasestr(array, max) 0 +#define find_strchr(array, max) 0 +#define find_strcspn(array, max) 0 +#define find_strlen(array, max) 0 +#define find_strpbrk(array, max) 0 +#define find_strrchr(array, max) 0 +#define find_strspn(array, max) 0 +#define find_strstr(array, max) 0 +#define find_wcscpy(array, max) 0 +#define find_wmemcmp(array, max) 0 + +#ifndef NOT_IN_libc + +extern __typeof (memmove) __memmove_sse2 attribute_hidden; +extern __typeof (memmove) __memmove_ssse3 attribute_hidden; +extern __typeof (memmove) __memmove_ssse3_back attribute_hidden; + +# undef find_memmove + +static int +find_memmove (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__memmove_ssse3_back); + array[i + 1] = LIBC_FUNC_INIT (__memmove_ssse3); + i += 2; + } + array[i] = LIBC_FUNC_INIT (__memmove_sse2); + return i + 1; +} + +extern void *__memmove_chk (void *, const void *, size_t, size_t); +extern __typeof (__memmove_chk) __memmove_chk_sse2 attribute_hidden; +extern __typeof (__memmove_chk) __memmove_chk_ssse3 attribute_hidden; +extern __typeof (__memmove_chk) __memmove_chk_ssse3_back attribute_hidden; + +# undef find___memmove_chk + +static int +find___memmove_chk (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__memmove_chk_ssse3_back); + array[i + 1] = LIBC_FUNC_INIT (__memmove_chk_ssse3); + i += 2; + } + array[i] = LIBC_FUNC_INIT (__memmove_chk_sse2); + return i + 1; +} + +extern __typeof (memset) __memset_x86_64 attribute_hidden; +extern __typeof (memset) __memset_sse2 attribute_hidden; + +# undef find_memset + +static int +find_memset (struct libc_func_test *array, int max) +{ + array[0] = LIBC_FUNC_INIT (__memset_sse2); + array[1] = LIBC_FUNC_INIT (__memset_x86_64); + return 2; +} + +extern __typeof (rawmemchr) __rawmemchr_sse2 attribute_hidden; +extern __typeof (rawmemchr) __rawmemchr_sse42 attribute_hidden; + +# undef find_rawmemchr + +static int +find_rawmemchr (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__rawmemchr_sse42); + i++; + } + array[i] = LIBC_FUNC_INIT (__rawmemchr_sse2); + return i + 1; +} + +extern __typeof (stpcpy) __stpcpy_sse2 attribute_hidden; +extern __typeof (stpcpy) __stpcpy_sse2_unaligned attribute_hidden; +extern __typeof (stpcpy) __stpcpy_ssse3 attribute_hidden; + +# undef find_stpcpy + +static int +find_stpcpy (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__stpcpy_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__stpcpy_sse2); + i++; + array[i] = LIBC_FUNC_INIT (__stpcpy_sse2_unaligned); + return i + 1; +} + +extern __typeof (stpncpy) __stpncpy_sse2 attribute_hidden; +extern __typeof (stpncpy) __stpncpy_sse2_unaligned attribute_hidden; +extern __typeof (stpncpy) __stpncpy_ssse3 attribute_hidden; + +# undef find_stpncpy + +static int +find_stpncpy (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__stpncpy_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__stpncpy_sse2); + i++; + array[i] = LIBC_FUNC_INIT (__stpncpy_sse2_unaligned); + return i + 1; +} + +extern __typeof (strcpy) __strcpy_sse2 attribute_hidden; +extern __typeof (strcpy) __strcpy_sse2_unaligned attribute_hidden; +extern __typeof (strcpy) __strcpy_ssse3 attribute_hidden; + +# undef find_strcpy + +static int +find_strcpy (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__strcpy_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__strcpy_sse2); + i++; + array[i] = LIBC_FUNC_INIT (__strcpy_sse2_unaligned); + return i + 1; +} + +extern __typeof (strncpy) __strncpy_sse2 attribute_hidden; +extern __typeof (strncpy) __strncpy_sse2_unaligned attribute_hidden; +extern __typeof (strncpy) __strncpy_ssse3 attribute_hidden; + +# undef find_strncpy + +static int +find_strncpy (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__strncpy_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__strncpy_sse2); + i++; + array[i] = LIBC_FUNC_INIT (__strncpy_sse2_unaligned); + return i + 1; +} + +extern __typeof (strcasecmp) __strcasecmp_sse2 attribute_hidden; +extern __typeof (strcasecmp) __strcasecmp_ssse3 attribute_hidden; +extern __typeof (strcasecmp) __strcasecmp_sse42 attribute_hidden; +extern __typeof (strcasecmp) __strcasecmp_avx attribute_hidden; + +# undef find_strcasecmp + +static int +find_strcasecmp (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_AVX) + { + array[i] = LIBC_FUNC_INIT (__strcasecmp_avx); + i++; + } + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strcasecmp_sse42); + i++; + } + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__strcasecmp_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__strcasecmp_sse2); + return i + 1; +} + +extern __typeof (strcasecmp_l) __strcasecmp_l_sse2 attribute_hidden; +extern __typeof (strcasecmp_l) __strcasecmp_l_ssse3 attribute_hidden; +extern __typeof (strcasecmp_l) __strcasecmp_l_sse42 attribute_hidden; +extern __typeof (strcasecmp_l) __strcasecmp_l_avx attribute_hidden; + +# undef find_strcasecmp_l + +static int +find_strcasecmp_l (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_AVX) + { + array[i] = LIBC_FUNC_INIT (__strcasecmp_l_avx); + i++; + } + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strcasecmp_l_sse42); + i++; + } + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__strcasecmp_l_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__strcasecmp_l_sse2); + return i + 1; +} + +extern __typeof (strcat) __strcat_sse2 attribute_hidden; +extern __typeof (strcat) __strcat_sse2_unaligned attribute_hidden; +extern __typeof (strcat) __strcat_ssse3 attribute_hidden; + +# undef find_strcat + +static int +find_strcat (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__strcat_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__strcat_sse2); + i++; + array[i] = LIBC_FUNC_INIT (__strcat_sse2_unaligned); + return i + 1; +} + +extern __typeof (strncat) __strncat_sse2 attribute_hidden; +extern __typeof (strncat) __strncat_sse2_unaligned attribute_hidden; +extern __typeof (strncat) __strncat_ssse3 attribute_hidden; + +# undef find_strncat + +static int +find_strncat (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__strncat_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__strncat_sse2); + i++; + array[i] = LIBC_FUNC_INIT (__strncat_sse2_unaligned); + return i + 1; +} + +extern __typeof (strcmp) __strcmp_sse2 attribute_hidden; +extern __typeof (strcmp) __strcmp_ssse3 attribute_hidden; +extern __typeof (strcmp) __strcmp_sse42 attribute_hidden; + +# undef find_strcmp + +static int +find_strcmp (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strcmp_sse42); + i++; + } + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__strcmp_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__strcmp_sse2); + return i + 1; +} + +extern __typeof (strncasecmp) __strncasecmp_sse2 attribute_hidden; +extern __typeof (strncasecmp) __strncasecmp_ssse3 attribute_hidden; +extern __typeof (strncasecmp) __strncasecmp_sse42 attribute_hidden; +extern __typeof (strncasecmp) __strncasecmp_avx attribute_hidden; + +# undef find_strncasecmp + +static int +find_strncasecmp (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_AVX) + { + array[i] = LIBC_FUNC_INIT (__strncasecmp_avx); + i++; + } + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strncasecmp_sse42); + i++; + } + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__strncasecmp_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__strncasecmp_sse2); + return i + 1; +} + +extern __typeof (strncasecmp_l) __strncasecmp_l_sse2 attribute_hidden; +extern __typeof (strncasecmp_l) __strncasecmp_l_ssse3 attribute_hidden; +extern __typeof (strncasecmp_l) __strncasecmp_l_sse42 attribute_hidden; +extern __typeof (strncasecmp_l) __strncasecmp_l_avx attribute_hidden; + +# undef find_strncasecmp_l + +static int +find_strncasecmp_l (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_AVX) + { + array[i] = LIBC_FUNC_INIT (__strncasecmp_l_avx); + i++; + } + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strncasecmp_l_sse42); + i++; + } + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__strncasecmp_l_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__strncasecmp_l_sse2); + return i + 1; +} + +extern __typeof (strcasestr) __strcasestr_sse2 attribute_hidden; +extern __typeof (strcasestr) __strcasestr_sse42 attribute_hidden; + +# undef find_strcasestr + +static int +find_strcasestr (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strcasestr_sse42); + i++; + } + array[i] = LIBC_FUNC_INIT (__strcasestr_sse2); + return i + 1; +} + +extern __typeof (strchr) __strchr_sse2 attribute_hidden; +extern __typeof (strchr) __strchr_sse2_no_bsf attribute_hidden; +extern __typeof (strchr) __strchr_sse42 attribute_hidden; + +# undef find_strchr + +static int +find_strchr (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strchr_sse42); + i++; + } + array[i] = LIBC_FUNC_INIT (__strchr_sse2); + i++; + array[i] = LIBC_FUNC_INIT (__strchr_sse2_no_bsf); + return i + 1; +} + +extern __typeof (strcspn) __strcspn_sse2 attribute_hidden; +extern __typeof (strcspn) __strcspn_sse42 attribute_hidden; + +# undef find_strcspn + +static int +find_strcspn (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strcspn_sse42); + i++; + } + array[i] = LIBC_FUNC_INIT (__strcspn_sse2); + return i + 1; +} + +extern __typeof (strnlen) __strnlen_sse2 attribute_hidden; +extern __typeof (strnlen) __strnlen_sse2_no_bsf attribute_hidden; + +# undef find_strnlen + +static int +find_strnlen (struct libc_func_test *array, int max) +{ + array[0] = LIBC_FUNC_INIT (__strnlen_sse2); + array[1] = LIBC_FUNC_INIT (__strnlen_sse2_no_bsf); + return 2; +} + +extern __typeof (strpbrk) __strpbrk_sse2 attribute_hidden; +extern __typeof (strpbrk) __strpbrk_sse42 attribute_hidden; + +# undef find_strpbrk + +static int +find_strpbrk (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strpbrk_sse42); + i++; + } + array[i] = LIBC_FUNC_INIT (__strpbrk_sse2); + return i + 1; +} + +extern __typeof (strrchr) __strrchr_sse2 attribute_hidden; +extern __typeof (strrchr) __strrchr_sse2_no_bsf attribute_hidden; +extern __typeof (strrchr) __strrchr_sse42 attribute_hidden; + +# undef find_strrchr + +static int +find_strrchr (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strrchr_sse42); + i++; + } + array[i] = LIBC_FUNC_INIT (__strrchr_sse2); + i++; + array[i] = LIBC_FUNC_INIT (__strrchr_sse2_no_bsf); + return i + 1; +} + +extern __typeof (strspn) __strspn_sse2 attribute_hidden; +extern __typeof (strspn) __strspn_sse42 attribute_hidden; + +# undef find_strspn + +static int +find_strspn (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strspn_sse42); + i++; + } + array[i] = LIBC_FUNC_INIT (__strspn_sse2); + return i + 1; +} + +extern __typeof (strstr) __strstr_sse2 attribute_hidden; +extern __typeof (strstr) __strstr_sse42 attribute_hidden; + +# undef find_strstr + +static int +find_strstr (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strstr_sse42); + i++; + } + array[i] = LIBC_FUNC_INIT (__strstr_sse2); + return i + 1; +} + +extern __typeof (wcscpy) __wcscpy_sse2 attribute_hidden; +extern __typeof (wcscpy) __wcscpy_ssse3 attribute_hidden; + +# undef find_wcscpy + +static int +find_wcscpy (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__wcscpy_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__wcscpy_sse2); + return i + 1; +} + +extern __typeof (wmemcmp) __wmemcmp_sse2 attribute_hidden; +extern __typeof (wmemcmp) __wmemcmp_ssse3 attribute_hidden; +extern __typeof (wmemcmp) __wmemcmp_sse4_1 attribute_hidden; + +# undef find_wmemcmp + +static int +find_wmemcmp (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_1) + { + array[i] = LIBC_FUNC_INIT (__wmemcmp_sse4_1); + i++; + } + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__wmemcmp_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__wmemcmp_sse2); + return i + 1; +} + +# ifdef SHARED +extern __typeof (memcmp) __memcmp_sse2 attribute_hidden; +extern __typeof (memcmp) __memcmp_ssse3 attribute_hidden; +extern __typeof (memcmp) __memcmp_sse4_1 attribute_hidden; + +# undef find_memcmp + +static int +find_memcmp (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_1) + { + array[i] = LIBC_FUNC_INIT (__memcmp_sse4_1); + i++; + } + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__memcmp_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__memcmp_sse2); + return i + 1; +} + +extern __typeof (memcpy) __memcpy_sse2 attribute_hidden; +extern __typeof (memcpy) __memcpy_ssse3 attribute_hidden; +extern __typeof (memcpy) __memcpy_ssse3_back attribute_hidden; + +# undef find_memcpy + +static int +find_memcpy (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__memcpy_ssse3_back); + array[i + 1] = LIBC_FUNC_INIT (__memcpy_ssse3); + i += 2; + } + array[i] = LIBC_FUNC_INIT (__memcpy_sse2); + return i + 1; +} + +extern __typeof (mempcpy) __mempcpy_sse2 attribute_hidden; +extern __typeof (mempcpy) __mempcpy_ssse3 attribute_hidden; +extern __typeof (mempcpy) __mempcpy_ssse3_back attribute_hidden; + +# undef find_mempcpy + +static int +find_mempcpy (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__mempcpy_ssse3_back); + array[i + 1] = LIBC_FUNC_INIT (__mempcpy_ssse3); + i += 2; + } + array[i] = LIBC_FUNC_INIT (__mempcpy_sse2); + return i + 1; +} + +extern void *__memcpy_chk (void *, const void *, size_t, size_t); +extern __typeof (__memcpy_chk) __memcpy_chk_sse2 attribute_hidden; +extern __typeof (__memcpy_chk) __memcpy_chk_ssse3 attribute_hidden; +extern __typeof (__memcpy_chk) __memcpy_chk_ssse3_back attribute_hidden; + +# undef find___memcpy_chk + +static int +find___memcpy_chk (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__memcpy_chk_ssse3_back); + array[i + 1] = LIBC_FUNC_INIT (__memcpy_chk_ssse3); + i += 2; + } + array[i] = LIBC_FUNC_INIT (__memcpy_chk_sse2); + return i + 1; +} + +extern void *__mempcpy_chk (void *, const void *, size_t, size_t); +extern __typeof (__mempcpy_chk) __mempcpy_chk_sse2 attribute_hidden; +extern __typeof (__mempcpy_chk) __mempcpy_chk_ssse3 attribute_hidden; +extern __typeof (__mempcpy_chk) __mempcpy_chk_ssse3_back attribute_hidden; + +# undef find___mempcpy_chk + +static int +find___mempcpy_chk (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__mempcpy_chk_ssse3_back); + array[i + 1] = LIBC_FUNC_INIT (__mempcpy_chk_ssse3); + i += 2; + } + array[i] = LIBC_FUNC_INIT (__mempcpy_chk_sse2); + return i + 1; +} + +extern __typeof (strlen) __strlen_sse2 attribute_hidden; +extern __typeof (strlen) __strlen_sse2_no_bsf attribute_hidden; +extern __typeof (strlen) __strlen_sse2_pminub attribute_hidden; +extern __typeof (strlen) __strlen_sse42 attribute_hidden; + +# undef find_strlen + +static int +find_strlen (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strlen_sse42); + i++; + } + array[i] = LIBC_FUNC_INIT (__strlen_sse2); + i++; + array[i] = LIBC_FUNC_INIT (__strlen_sse2_no_bsf); + i++; + array[i] = LIBC_FUNC_INIT (__strlen_sse2_pminub); + return i + 1; +} + +extern __typeof (strncmp) __strncmp_sse2 attribute_hidden; +extern __typeof (strncmp) __strncmp_ssse3 attribute_hidden; +extern __typeof (strncmp) __strncmp_sse42 attribute_hidden; + +# undef find_strncmp + +static int +find_strncmp (struct libc_func_test *array, int max) +{ + size_t i = 0; + if (HAS_SSE4_2) + { + array[i] = LIBC_FUNC_INIT (__strncmp_sse42); + i++; + } + if (HAS_SSSE3) + { + array[i] = LIBC_FUNC_INIT (__strncmp_ssse3); + i++; + } + array[i] = LIBC_FUNC_INIT (__strncmp_sse2); + return i + 1; +} +# endif /* SHARED */ +#endif /* NOT_IN_libc */ + +/* Maximum number of IFUNC implementations. */ +#define MAX_IFUNC 4 + +/* Fill ARRAY of MAX elements with IFUNC implementations for function + NAME supported on target machine and return the number of valid + entries. */ + +int +__libc_func (const char *name, struct libc_func_test *array, int max) +{ + assert (max >= MAX_IFUNC); + + if (strcmp (name, "memcmp") == 0) + return find_memcmp (array, max); + + if (strcmp (name, "memcpy") == 0) + return find_memcpy (array, max); + + if (strcmp (name, "memmove") == 0) + return find_memmove (array, max); + + if (strcmp (name, "mempcpy") == 0) + return find_mempcpy (array, max); + + if (strcmp (name, "__memcpy_chk") == 0) + return find___memcpy_chk (array, max); + + if (strcmp (name, "__memmove_chk") == 0) + return find___memmove_chk (array, max); + + if (strcmp (name, "__mempcpy_chk") == 0) + return find___mempcpy_chk (array, max); + + if (strcmp (name, "memset") == 0) + return find_memset (array, max); + + if (strcmp (name, "rawmemchr") == 0) + return find_rawmemchr (array, max); + + if (strcmp (name, "stpcpy") == 0) + return find_stpcpy (array, max); + + if (strcmp (name, "stpncpy") == 0) + return find_stpncpy (array, max); + + if (strcmp (name, "strcpy") == 0) + return find_strcpy (array, max); + + if (strcmp (name, "strncpy") == 0) + return find_strncpy (array, max); + + if (strcmp (name, "strcasecmp") == 0) + return find_strcasecmp (array, max); + + if (strcmp (name, "strcasecmp_l") == 0) + return find_strcasecmp_l (array, max); + + if (strcmp (name, "strcat") == 0) + return find_strcat (array, max); + + if (strcmp (name, "strcmp") == 0) + return find_strcmp (array, max); + + if (strcmp (name, "strncasecmp") == 0) + return find_strncasecmp (array, max); + + if (strcmp (name, "strncasecmp_l") == 0) + return find_strncasecmp_l (array, max); + + if (strcmp (name, "strncat") == 0) + return find_strncat (array, max); + + if (strcmp (name, "strncmp") == 0) + return find_strncmp (array, max); + + if (strcmp (name, "strnlen") == 0) + return find_strnlen (array, max); + + if (strcmp (name, "strcasestr") == 0) + return find_strcasestr (array, max); + + if (strcmp (name, "strchr") == 0) + return find_strchr (array, max); + + if (strcmp (name, "strcspn") == 0) + return find_strcspn (array, max); + + if (strcmp (name, "strlen") == 0) + return find_strlen (array, max); + + if (strcmp (name, "strpbrk") == 0) + return find_strpbrk (array, max); + + if (strcmp (name, "strrchr") == 0) + return find_strrchr (array, max); + + if (strcmp (name, "strspn") == 0) + return find_strspn (array, max); + + if (strcmp (name, "strstr") == 0) + return find_strstr (array, max); + + if (strcmp (name, "wcscpy") == 0) + return find_wcscpy (array, max); + + if (strcmp (name, "wmemcmp") == 0) + return find_wmemcmp (array, max); + + return 0; +} diff --git a/sysdeps/x86_64/multiarch/memcmp.S b/sysdeps/x86_64/multiarch/memcmp.S index b2bc4d7..f2c9b30 100644 --- a/sysdeps/x86_64/multiarch/memcmp.S +++ b/sysdeps/x86_64/multiarch/memcmp.S @@ -48,6 +48,8 @@ END(memcmp) # define ENTRY(name) \ .type __memcmp_sse2, @function; \ .p2align 4; \ + .globl __memcmp_sse2; \ + .hidden __memcmp_sse2; \ __memcmp_sse2: cfi_startproc; \ CALL_MCOUNT # undef END diff --git a/sysdeps/x86_64/multiarch/memcpy.S b/sysdeps/x86_64/multiarch/memcpy.S index a77cdfb..0c1c1e6 100644 --- a/sysdeps/x86_64/multiarch/memcpy.S +++ b/sysdeps/x86_64/multiarch/memcpy.S @@ -45,6 +45,8 @@ END(__new_memcpy) # undef ENTRY # define ENTRY(name) \ .type __memcpy_sse2, @function; \ + .globl __memcpy_sse2; \ + .hidden __memcpy_sse2; \ .p2align 4; \ __memcpy_sse2: cfi_startproc; \ CALL_MCOUNT diff --git a/sysdeps/x86_64/multiarch/mempcpy.S b/sysdeps/x86_64/multiarch/mempcpy.S index caa435b..2fac9d7 100644 --- a/sysdeps/x86_64/multiarch/mempcpy.S +++ b/sysdeps/x86_64/multiarch/mempcpy.S @@ -43,6 +43,8 @@ END(__mempcpy) # define ENTRY(name) \ .type __mempcpy_sse2, @function; \ .p2align 4; \ + .globl __mempcpy_sse2; \ + .hidden __mempcpy_sse2; \ __mempcpy_sse2: cfi_startproc; \ CALL_MCOUNT # undef END diff --git a/sysdeps/x86_64/multiarch/rawmemchr.S b/sysdeps/x86_64/multiarch/rawmemchr.S index c4157ad..ebcc17e 100644 --- a/sysdeps/x86_64/multiarch/rawmemchr.S +++ b/sysdeps/x86_64/multiarch/rawmemchr.S @@ -44,6 +44,8 @@ strong_alias (rawmemchr, __rawmemchr) .section .text.sse4.2,"ax",@progbits .align 16 .type __rawmemchr_sse42, @function + .globl __rawmemchr_sse42 + .hidden __rawmemchr_sse42 __rawmemchr_sse42: cfi_startproc CALL_MCOUNT @@ -81,6 +83,8 @@ __rawmemchr_sse42: # define ENTRY(name) \ .type __rawmemchr_sse2, @function; \ .align 16; \ + .globl __rawmemchr_sse2; \ + .hidden __rawmemchr_sse2; \ __rawmemchr_sse2: cfi_startproc; \ CALL_MCOUNT # undef END diff --git a/sysdeps/x86_64/multiarch/strcat.S b/sysdeps/x86_64/multiarch/strcat.S index 0c256de..1ba69b6 100644 --- a/sysdeps/x86_64/multiarch/strcat.S +++ b/sysdeps/x86_64/multiarch/strcat.S @@ -63,6 +63,8 @@ END(STRCAT) # define ENTRY(name) \ .type STRCAT_SSE2, @function; \ .align 16; \ + .globl STRCAT_SSE2; \ + .hidden STRCAT_SSE2; \ STRCAT_SSE2: cfi_startproc; \ CALL_MCOUNT # undef END diff --git a/sysdeps/x86_64/multiarch/strchr.S b/sysdeps/x86_64/multiarch/strchr.S index b9f88e4..5c8aa7c 100644 --- a/sysdeps/x86_64/multiarch/strchr.S +++ b/sysdeps/x86_64/multiarch/strchr.S @@ -82,6 +82,8 @@ END(strchr) .section .text.sse4.2,"ax",@progbits .align 16 .type __strchr_sse42, @function + .globl __strchr_sse42 + .hidden __strchr_sse42 __strchr_sse42: cfi_startproc CALL_MCOUNT @@ -164,6 +166,8 @@ L(loop_exit): # define ENTRY(name) \ .type __strchr_sse2, @function; \ .align 16; \ + .globl __strchr_sse2; \ + .hidden __strchr_sse2; \ __strchr_sse2: cfi_startproc; \ CALL_MCOUNT # undef END diff --git a/sysdeps/x86_64/multiarch/strcmp-sse42.S b/sysdeps/x86_64/multiarch/strcmp-sse42.S index 9d00bbc..4fadfcb 100644 --- a/sysdeps/x86_64/multiarch/strcmp-sse42.S +++ b/sysdeps/x86_64/multiarch/strcmp-sse42.S @@ -48,6 +48,8 @@ .section .text.SECTION,"ax",@progbits .align 16 .type STRCMP_SSE42, @function + .globl STRCMP_SSE42 + .hidden STRCMP_SSE42 #ifdef USE_AS_STRCASECMP_L ENTRY (GLABEL(__strcasecmp)) movq __libc_tsd_LOCALE@gottpoff(%rip),%rax diff --git a/sysdeps/x86_64/multiarch/strcmp.S b/sysdeps/x86_64/multiarch/strcmp.S index d366d09..fb9b0fb 100644 --- a/sysdeps/x86_64/multiarch/strcmp.S +++ b/sysdeps/x86_64/multiarch/strcmp.S @@ -171,6 +171,8 @@ weak_alias (__strncasecmp, strncasecmp) # define ENTRY(name) \ .type STRCMP_SSE2, @function; \ .align 16; \ + .globl STRCMP_SSE2; \ + .hidden STRCMP_SSE2; \ STRCMP_SSE2: cfi_startproc; \ CALL_MCOUNT # undef END @@ -181,6 +183,8 @@ weak_alias (__strncasecmp, strncasecmp) # define ENTRY2(name) \ .type __strcasecmp_sse2, @function; \ .align 16; \ + .globl __strcasecmp_sse2; \ + .hidden __strcasecmp_sse2; \ __strcasecmp_sse2: cfi_startproc; \ CALL_MCOUNT # define END2(name) \ @@ -191,6 +195,8 @@ weak_alias (__strncasecmp, strncasecmp) # define ENTRY2(name) \ .type __strncasecmp_sse2, @function; \ .align 16; \ + .globl __strncasecmp_sse2; \ + .hidden __strncasecmp_sse2; \ __strncasecmp_sse2: cfi_startproc; \ CALL_MCOUNT # define END2(name) \ diff --git a/sysdeps/x86_64/multiarch/strcpy.S b/sysdeps/x86_64/multiarch/strcpy.S index 7be1b8b..b97215e 100644 --- a/sysdeps/x86_64/multiarch/strcpy.S +++ b/sysdeps/x86_64/multiarch/strcpy.S @@ -77,6 +77,8 @@ END(STRCPY) # define ENTRY(name) \ .type STRCPY_SSE2, @function; \ .align 16; \ + .globl STRCPY_SSE2; \ + .hidden STRCPY_SSE2; \ STRCPY_SSE2: cfi_startproc; \ CALL_MCOUNT # undef END diff --git a/sysdeps/x86_64/multiarch/strlen.S b/sysdeps/x86_64/multiarch/strlen.S index 0c46b4f..bab0ac3 100644 --- a/sysdeps/x86_64/multiarch/strlen.S +++ b/sysdeps/x86_64/multiarch/strlen.S @@ -49,6 +49,8 @@ END(strlen) # define ENTRY(name) \ .type __strlen_sse2, @function; \ .align 16; \ + .globl __strlen_sse2; \ + .hidden __strlen_sse2; \ __strlen_sse2: cfi_startproc; \ CALL_MCOUNT # undef END diff --git a/sysdeps/x86_64/multiarch/strnlen.S b/sysdeps/x86_64/multiarch/strnlen.S index 044b910..86b32d8 100644 --- a/sysdeps/x86_64/multiarch/strnlen.S +++ b/sysdeps/x86_64/multiarch/strnlen.S @@ -40,6 +40,8 @@ END(__strnlen) # define ENTRY(name) \ .type __strnlen_sse2, @function; \ .align 16; \ + .globl __strnlen_sse2; \ + .hidden __strnlen_sse2; \ __strnlen_sse2: cfi_startproc; \ CALL_MCOUNT # undef END diff --git a/sysdeps/x86_64/multiarch/strrchr.S b/sysdeps/x86_64/multiarch/strrchr.S index c87d8fa..1ccaf4a 100644 --- a/sysdeps/x86_64/multiarch/strrchr.S +++ b/sysdeps/x86_64/multiarch/strrchr.S @@ -87,6 +87,8 @@ END(strrchr) .section .text.sse4.2,"ax",@progbits .align 16 .type __strrchr_sse42, @function + .globl __strrchr_sse42 + .hidden __strrchr_sse42 __strrchr_sse42: cfi_startproc CALL_MCOUNT @@ -265,6 +267,8 @@ L(psrldq_table): # define ENTRY(name) \ .type __strrchr_sse2, @function; \ .align 16; \ + .globl __strrchr_sse2; \ + .hidden __strrchr_sse2; \ __strrchr_sse2: cfi_startproc; \ CALL_MCOUNT # undef END -- 1.7.11.4