/* Enumerate available IFUNC implementations of a function. s390/s390x version. Copyright (C) 2015-2018 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 #include #include #include /* Maximum number of IFUNC implementations. */ #define MAX_IFUNC 3 /* Fill ARRAY of MAX elements with IFUNC implementations for function NAME supported on target machine 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; /* Get hardware information. */ unsigned long int dl_hwcap = GLRO (dl_hwcap); unsigned long long stfle_bits = 0ULL; if ((dl_hwcap & HWCAP_S390_STFLE) && (dl_hwcap & HWCAP_S390_ZARCH) && (dl_hwcap & HWCAP_S390_HIGH_GPRS)) { S390_STORE_STFLE (stfle_bits); } #if HAVE_MEMSET_IFUNC IFUNC_IMPL (i, name, memset, # if HAVE_MEMSET_Z196 IFUNC_IMPL_ADD (array, i, memset, S390_IS_Z196 (stfle_bits), MEMSET_Z196) # endif # if HAVE_MEMSET_Z10 IFUNC_IMPL_ADD (array, i, memset, S390_IS_Z10 (stfle_bits), MEMSET_Z10) # endif # if HAVE_MEMSET_Z900_G5 IFUNC_IMPL_ADD (array, i, memset, 1, MEMSET_Z900_G5) # endif ) /* Note: bzero is implemented in memset. */ IFUNC_IMPL (i, name, bzero, # if HAVE_MEMSET_Z196 IFUNC_IMPL_ADD (array, i, bzero, S390_IS_Z196 (stfle_bits), BZERO_Z196) # endif # if HAVE_MEMSET_Z10 IFUNC_IMPL_ADD (array, i, bzero, S390_IS_Z10 (stfle_bits), BZERO_Z10) # endif # if HAVE_MEMSET_Z900_G5 IFUNC_IMPL_ADD (array, i, bzero, 1, BZERO_Z900_G5) # endif ) #endif /* HAVE_MEMSET_IFUNC */ #if HAVE_MEMCMP_IFUNC IFUNC_IMPL (i, name, memcmp, # if HAVE_MEMCMP_Z196 IFUNC_IMPL_ADD (array, i, memcmp, S390_IS_Z196 (stfle_bits), MEMCMP_Z196) # endif # if HAVE_MEMCMP_Z10 IFUNC_IMPL_ADD (array, i, memcmp, S390_IS_Z10 (stfle_bits), MEMCMP_Z10) # endif # if HAVE_MEMCMP_Z900_G5 IFUNC_IMPL_ADD (array, i, memcmp, 1, MEMCMP_Z900_G5) # endif ) #endif /* HAVE_MEMCMP_IFUNC */ #if HAVE_MEMCPY_IFUNC IFUNC_IMPL (i, name, memcpy, # if HAVE_MEMCPY_Z196 IFUNC_IMPL_ADD (array, i, memcpy, S390_IS_Z196 (stfle_bits), MEMCPY_Z196) # endif # if HAVE_MEMCPY_Z10 IFUNC_IMPL_ADD (array, i, memcpy, S390_IS_Z10 (stfle_bits), MEMCPY_Z10) # endif # if HAVE_MEMCPY_Z900_G5 IFUNC_IMPL_ADD (array, i, memcpy, 1, MEMCPY_Z900_G5) # endif ) IFUNC_IMPL (i, name, mempcpy, # if HAVE_MEMCPY_Z196 IFUNC_IMPL_ADD (array, i, mempcpy, S390_IS_Z196 (stfle_bits), MEMPCPY_Z196) # endif # if HAVE_MEMCPY_Z10 IFUNC_IMPL_ADD (array, i, mempcpy, S390_IS_Z10 (stfle_bits), MEMPCPY_Z10) # endif # if HAVE_MEMCPY_Z900_G5 IFUNC_IMPL_ADD (array, i, mempcpy, 1, MEMPCPY_Z900_G5) # endif ) #endif /* HAVE_MEMCPY_IFUNC */ #if HAVE_MEMMOVE_IFUNC IFUNC_IMPL (i, name, memmove, # if HAVE_MEMMOVE_Z13 IFUNC_IMPL_ADD (array, i, memmove, dl_hwcap & HWCAP_S390_VX, MEMMOVE_Z13) # endif # if HAVE_MEMMOVE_C IFUNC_IMPL_ADD (array, i, memmove, 1, MEMMOVE_C) # endif ) #endif /* HAVE_MEMMOVE_IFUNC */ #if HAVE_STRSTR_IFUNC IFUNC_IMPL (i, name, strstr, # if HAVE_STRSTR_Z13 IFUNC_IMPL_ADD (array, i, strstr, dl_hwcap & HWCAP_S390_VX, STRSTR_Z13) # endif # if HAVE_STRSTR_C IFUNC_IMPL_ADD (array, i, strstr, 1, STRSTR_C) # endif ) #endif /* HAVE_STRSTR_IFUNC */ #ifdef HAVE_S390_VX_ASM_SUPPORT # define IFUNC_VX_IMPL(FUNC) \ IFUNC_IMPL (i, name, FUNC, \ IFUNC_IMPL_ADD (array, i, FUNC, dl_hwcap & HWCAP_S390_VX, \ __##FUNC##_vx) \ IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) IFUNC_VX_IMPL (strlen); IFUNC_VX_IMPL (wcslen); IFUNC_VX_IMPL (strnlen); IFUNC_VX_IMPL (wcsnlen); IFUNC_VX_IMPL (strcpy); IFUNC_VX_IMPL (wcscpy); IFUNC_VX_IMPL (stpcpy); IFUNC_VX_IMPL (wcpcpy); IFUNC_VX_IMPL (strncpy); IFUNC_VX_IMPL (wcsncpy); IFUNC_VX_IMPL (stpncpy); IFUNC_VX_IMPL (wcpncpy); IFUNC_VX_IMPL (strcat); IFUNC_VX_IMPL (wcscat); IFUNC_VX_IMPL (strncat); IFUNC_VX_IMPL (wcsncat); IFUNC_VX_IMPL (strcmp); IFUNC_VX_IMPL (wcscmp); IFUNC_VX_IMPL (strncmp); IFUNC_VX_IMPL (wcsncmp); IFUNC_VX_IMPL (strchr); IFUNC_VX_IMPL (wcschr); IFUNC_VX_IMPL (strchrnul); IFUNC_VX_IMPL (wcschrnul); IFUNC_VX_IMPL (strrchr); IFUNC_VX_IMPL (wcsrchr); IFUNC_VX_IMPL (strspn); IFUNC_VX_IMPL (wcsspn); IFUNC_VX_IMPL (strpbrk); IFUNC_VX_IMPL (wcspbrk); IFUNC_VX_IMPL (strcspn); IFUNC_VX_IMPL (wcscspn); IFUNC_VX_IMPL (memchr); IFUNC_VX_IMPL (wmemchr); IFUNC_VX_IMPL (rawmemchr); IFUNC_VX_IMPL (memccpy); IFUNC_VX_IMPL (wmemset); IFUNC_VX_IMPL (wmemcmp); IFUNC_VX_IMPL (memrchr); #endif /* HAVE_S390_VX_ASM_SUPPORT */ return i; }