From a2957f5a0b21f9588e8756228b11b86f886b0f4c Mon Sep 17 00:00:00 2001 From: Erich Elsen Date: Tue, 23 May 2017 12:29:24 -0700 Subject: [PATCH] add memcpy.c --- sysdeps/x86_64/multiarch/memcpy.c | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 sysdeps/x86_64/multiarch/memcpy.c diff --git a/sysdeps/x86_64/multiarch/memcpy.c b/sysdeps/x86_64/multiarch/memcpy.c new file mode 100644 index 0000000000..b0ff8c71fd --- /dev/null +++ b/sysdeps/x86_64/multiarch/memcpy.c @@ -0,0 +1,70 @@ +#include "cpu-features.h" +#include "init-arch.h" +#include "shlib-compat.h" +#include + +typedef void * (*memcpy_fn)(void *, const void *, size_t); + +extern void * __memcpy_erms(void *dest, const void *src, size_t n); +extern void * __memcpy_sse2_unaligned(void *dest, const void *src, size_t n); +extern void * __memcpy_sse2_unaligned_erms(void *dest, const void *src, size_t n); +extern void * __memcpy_ssse3(void *dest, const void *src, size_t n); +extern void * __memcpy_ssse3_back(void *dest, const void *src, size_t n); +extern void * __memcpy_avx_unaligned(void *dest, const void *src, size_t n); +extern void * __memcpy_avx_unaligned_erms(void *dest, const void *src, size_t n); +extern void * __memcpy_avx512_unaligned(void *dest, const void *src, size_t n); +extern void * __memcpy_avx512_unaligned_erms(void *dest, const void *src, size_t n); + +/* Defined in cacheinfo.c */ +extern long int __x86_shared_cache_size attribute_hidden; +extern long int __x86_shared_cache_size_half attribute_hidden; +extern long int __x86_data_cache_size attribute_hidden; +extern long int __x86_data_cache_size_half attribute_hidden; +extern long int __x86_shared_non_temporal_threshold attribute_hidden; + +static void * select_memcpy_impl(void) { + const struct cpu_features* cpu_features_struct_p = __get_cpu_features (); + + if (CPU_FEATURES_ARCH_P(cpu_features_struct_p, Prefer_ERMS)) { + return __memcpy_erms; + } + + if (CPU_FEATURES_ARCH_P(cpu_features_struct_p, AVX512F_Usable)) { + if (CPU_FEATURES_ARCH_P(cpu_features_struct_p, Prefer_No_VZEROUPPER)) + return __memcpy_avx512_unaligned_erms; + return __memcpy_avx512_unaligned; + } + + if (CPU_FEATURES_ARCH_P(cpu_features_struct_p, AVX_Fast_Unaligned_Load)) { + if (CPU_FEATURES_CPU_P(cpu_features_struct_p, ERMS)) { + return __memcpy_avx_unaligned_erms; + + } + return __memcpy_avx_unaligned; + } + else { + if (CPU_FEATURES_ARCH_P(cpu_features_struct_p, Fast_Unaligned_Copy)) { + if (CPU_FEATURES_CPU_P(cpu_features_struct_p, ERMS)) { + return __memcpy_sse2_unaligned_erms; + + } + return __memcpy_sse2_unaligned; + } + else { + if (!CPU_FEATURES_CPU_P(cpu_features_struct_p, SSSE3)) { + return __memcpy_sse2_unaligned; + + } + if (CPU_FEATURES_ARCH_P(cpu_features_struct_p, Fast_Copy_Backward)) { + return __memcpy_ssse3_back; + + } + return __memcpy_ssse3; + } + } +} + +void *__new_memcpy(void *dest, const void *src, size_t n) + __attribute__ ((ifunc ("select_memcpy_impl"))); + +versioned_symbol(libc, __new_memcpy, memcpy, GLIBC_2_14); -- 2.13.0.219.gdb65acc882-goog