diff options
Diffstat (limited to 'libc/sysdeps')
24 files changed, 172 insertions, 48 deletions
diff --git a/libc/sysdeps/generic/dl-procinfo.h b/libc/sysdeps/generic/dl-procinfo.h index 90c87d942..a184a5918 100644 --- a/libc/sysdeps/generic/dl-procinfo.h +++ b/libc/sysdeps/generic/dl-procinfo.h @@ -21,7 +21,7 @@ #define _DL_PROCINFO_H 1 /* We cannot provide a general printing function. */ -#define _dl_procinfo(word) -1 +#define _dl_procinfo(type, word) -1 /* There are no hardware capabilities defined. */ #define _dl_hwcap_string(idx) "" diff --git a/libc/sysdeps/generic/ldsodefs.h b/libc/sysdeps/generic/ldsodefs.h index 1d47f8819..2d0ed3ed0 100644 --- a/libc/sysdeps/generic/ldsodefs.h +++ b/libc/sysdeps/generic/ldsodefs.h @@ -562,6 +562,10 @@ struct rtld_global_ro EXTERN struct link_map *_dl_sysinfo_map; #endif + /* Mask for more hardware capabilities that are available on some + platforms. */ + EXTERN uint64_t _dl_hwcap2; + #ifdef SHARED /* We add a function table to _rtld_global which is then used to call the function instead of going through the PLT. The result diff --git a/libc/sysdeps/generic/libc-mmap.h b/libc/sysdeps/generic/libc-mmap.h new file mode 100644 index 000000000..0ddd20d42 --- /dev/null +++ b/libc/sysdeps/generic/libc-mmap.h @@ -0,0 +1,26 @@ +/* Internal logic for dealing with mmap quirks. + Copyright (C) 2013 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/>. */ + +#ifndef _LIBC_MMAP_H +#define _LIBC_MMAP_H 1 + +/* Using MAP_FIXED with mmap sometimes requires larger alignment. */ +#include <sys/shm.h> +#define MAP_FIXED_ALIGNMENT SHMLBA + +#endif diff --git a/libc/sysdeps/i386/dl-procinfo.h b/libc/sysdeps/i386/dl-procinfo.h index 883fa7f0a..233a3257e 100644 --- a/libc/sysdeps/i386/dl-procinfo.h +++ b/libc/sysdeps/i386/dl-procinfo.h @@ -61,7 +61,7 @@ enum }; /* We cannot provide a general printing function. */ -#define _dl_procinfo(word) -1 +#define _dl_procinfo(type, word) -1 static inline const char * __attribute__ ((unused)) diff --git a/libc/sysdeps/powerpc/Makefile b/libc/sysdeps/powerpc/Makefile index 7442b6709..f75e62523 100644 --- a/libc/sysdeps/powerpc/Makefile +++ b/libc/sysdeps/powerpc/Makefile @@ -17,7 +17,7 @@ endif endif ifeq ($(subdir),csu) -# get offset to rtld_global._dl_hwcap +# get offset to rtld_global._dl_hwcap and rtld_global._dl_hwcap2 gen-as-const-headers += rtld-global-offsets.sym # get offset to __locale_struct.__ctype_tolower gen-as-const-headers += locale-defines.sym diff --git a/libc/sysdeps/powerpc/bits/hwcap.h b/libc/sysdeps/powerpc/bits/hwcap.h index 783138a0e..0c02fc68e 100644 --- a/libc/sysdeps/powerpc/bits/hwcap.h +++ b/libc/sysdeps/powerpc/bits/hwcap.h @@ -1,4 +1,4 @@ -/* Defines for bits in AT_HWCAP. +/* Defines for bits in AT_HWCAP and AT_HWCAP2. Copyright (C) 2012-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -20,9 +20,9 @@ # error "Never include <bits/hwcap.h> directly; use <sys/auxv.h> instead." #endif -/* - * The following must match the kernels asm/cputable.h. - */ +/* The bit numbers must match those in the kernel's asm/cputable.h. */ + +/* Feature definitions in AT_HWCAP. */ #define PPC_FEATURE_32 0x80000000 /* 32-bit mode. */ #define PPC_FEATURE_64 0x40000000 /* 64-bit mode. */ #define PPC_FEATURE_601_INSTR 0x20000000 /* 601 chip, Old POWER ISA. */ @@ -39,8 +39,9 @@ #define PPC_FEATURE_POWER5 0x00040000 /* POWER5 ISA 2.02 */ #define PPC_FEATURE_POWER5_PLUS 0x00020000 /* POWER5+ ISA 2.03 */ #define PPC_FEATURE_CELL_BE 0x00010000 /* CELL Broadband Engine */ -#define PPC_FEATURE_BOOKE 0x00008000 -#define PPC_FEATURE_SMT 0x00004000 /* Simultaneous Multi-Threading */ +#define PPC_FEATURE_BOOKE 0x00008000 /* ISA Category Embedded */ +#define PPC_FEATURE_SMT 0x00004000 /* Simultaneous + Multi-Threading */ #define PPC_FEATURE_ICACHE_SNOOP 0x00002000 #define PPC_FEATURE_ARCH_2_05 0x00001000 /* ISA 2.05 */ #define PPC_FEATURE_PA6T 0x00000800 /* PA Semi 6T Core */ @@ -51,3 +52,13 @@ #define PPC_FEATURE_PSERIES_PERFMON_COMPAT 0x00000040 #define PPC_FEATURE_TRUE_LE 0x00000002 #define PPC_FEATURE_PPC_LE 0x00000001 + +/* Feature definitions in AT_HWCAP2. */ +#define PPC_FEATURE2_ARCH_2_07 0x80000000 /* ISA 2.07 */ +#define PPC_FEATURE2_HAS_HTM 0x40000000 /* Hardware Transactional + Memory */ +#define PPC_FEATURE2_HAS_DSCR 0x20000000 /* Data Stream Control + Register */ +#define PPC_FEATURE2_HAS_EBB 0x10000000 /* Event Base Branching */ +#define PPC_FEATURE2_HAS_ISEL 0x08000000 /* Integer Select */ +#define PPC_FEATURE2_HAS_TAR 0x04000000 /* Target Address Register */ diff --git a/libc/sysdeps/powerpc/dl-procinfo.c b/libc/sysdeps/powerpc/dl-procinfo.c index 0f5c2b3d6..2984af197 100644 --- a/libc/sysdeps/powerpc/dl-procinfo.c +++ b/libc/sysdeps/powerpc/dl-procinfo.c @@ -45,7 +45,7 @@ #if !defined PROCINFO_DECL && defined SHARED ._dl_powerpc_cap_flags #else -PROCINFO_CLASS const char _dl_powerpc_cap_flags[25][10] +PROCINFO_CLASS const char _dl_powerpc_cap_flags[57][10] #endif #ifndef PROCINFO_DECL = { @@ -56,6 +56,14 @@ PROCINFO_CLASS const char _dl_powerpc_cap_flags[25][10] "notb", "efpdouble", "efpsingle", "spe", "ucache", "4xxmac", "mmu", "fpu", "altivec", "ppc601", "ppc64", "ppc32", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "tar", "isel", + "ebb", "dscr", "htm", "arch_2_07", } #endif #if !defined SHARED || defined PROCINFO_DECL @@ -67,7 +75,7 @@ PROCINFO_CLASS const char _dl_powerpc_cap_flags[25][10] #if !defined PROCINFO_DECL && defined SHARED ._dl_powerpc_platforms #else -PROCINFO_CLASS const char _dl_powerpc_platforms[13][12] +PROCINFO_CLASS const char _dl_powerpc_platforms[14][12] #endif #ifndef PROCINFO_DECL = { @@ -83,7 +91,8 @@ PROCINFO_CLASS const char _dl_powerpc_platforms[13][12] [PPC_PLATFORM_PPC405] = "ppc405", [PPC_PLATFORM_PPC440] = "ppc440", [PPC_PLATFORM_PPC464] = "ppc464", - [PPC_PLATFORM_PPC476] = "ppc476" + [PPC_PLATFORM_PPC476] = "ppc476", + [PPC_PLATFORM_POWER8] = "power8", } #endif #if !defined SHARED || defined PROCINFO_DECL diff --git a/libc/sysdeps/powerpc/dl-procinfo.h b/libc/sysdeps/powerpc/dl-procinfo.h index 568fe19dd..e7eeed9d2 100644 --- a/libc/sysdeps/powerpc/dl-procinfo.h +++ b/libc/sysdeps/powerpc/dl-procinfo.h @@ -20,17 +20,27 @@ #define _DL_PROCINFO_H 1 #include <ldsodefs.h> -#include <sysdep.h> /* This defines the PPC_FEATURE_* macros. */ +#include <sysdep.h> /* This defines the PPC_FEATURE[2]_* macros. */ /* There are 25 bits used, but they are bits 7..31. */ #define _DL_HWCAP_FIRST 7 -#define _DL_HWCAP_COUNT 32 + +/* The total number of available bits (including those prior to + _DL_HWCAP_FIRST). Some of these bits might not be used. */ +#define _DL_HWCAP_COUNT 64 + +/* Features started at bit 31 and decremented as new features were added. */ +#define _DL_HWCAP_LAST 31 + +/* AT_HWCAP2 features started at bit 31 and decremented as new features were + added. HWCAP2 feature bits start at bit 0. */ +#define _DL_HWCAP2_LAST 31 /* These bits influence library search. */ #define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \ + PPC_FEATURE_HAS_DFP) -#define _DL_PLATFORMS_COUNT 13 +#define _DL_PLATFORMS_COUNT 14 #define _DL_FIRST_PLATFORM 32 /* Mask to filter out platforms. */ @@ -51,6 +61,7 @@ #define PPC_PLATFORM_PPC440 10 #define PPC_PLATFORM_PPC464 11 #define PPC_PLATFORM_PPC476 12 +#define PPC_PLATFORM_POWER8 13 static inline const char * __attribute__ ((unused)) @@ -111,6 +122,9 @@ _dl_string_platform (const char *str) case '7': ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER7; break; + case '8': + ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER8; + break; default: return -1; } @@ -155,16 +169,35 @@ _dl_string_platform (const char *str) #ifdef IS_IN_rtld static inline int __attribute__ ((unused)) -_dl_procinfo (int word) +_dl_procinfo (unsigned int type, unsigned long int word) { - _dl_printf ("AT_HWCAP: "); - - for (int i = _DL_HWCAP_FIRST; i < _DL_HWCAP_COUNT; ++i) - if (word & (1 << i)) - _dl_printf (" %s", _dl_hwcap_string (i)); - - _dl_printf ("\n"); - + switch(type) + { + case AT_HWCAP: + _dl_printf ("AT_HWCAP: "); + + for (int i = _DL_HWCAP_FIRST; i <= _DL_HWCAP_LAST; ++i) + if (word & (1 << i)) + _dl_printf (" %s", _dl_hwcap_string (i)); + break; + case AT_HWCAP2: + { + unsigned int offset = _DL_HWCAP_LAST + 1; + + _dl_printf ("AT_HWCAP2: "); + + /* We have to go through them all because the kernel added the + AT_HWCAP2 features starting with the high bits. */ + for (int i = 0; i <= _DL_HWCAP2_LAST; ++i) + if (word & (1 << i)) + _dl_printf (" %s", _dl_hwcap_string (offset + i)); + break; + } + default: + /* This should not happen. */ + return -1; + } + _dl_printf ("\n"); return 0; } #endif diff --git a/libc/sysdeps/powerpc/powerpc32/power8/Implies b/libc/sysdeps/powerpc/powerpc32/power8/Implies new file mode 100644 index 000000000..083f3e950 --- /dev/null +++ b/libc/sysdeps/powerpc/powerpc32/power8/Implies @@ -0,0 +1,2 @@ +powerpc/powerpc32/power7/fpu +powerpc/powerpc32/power7 diff --git a/libc/sysdeps/powerpc/powerpc64/power8/Implies b/libc/sysdeps/powerpc/powerpc64/power8/Implies new file mode 100644 index 000000000..9a5e3c727 --- /dev/null +++ b/libc/sysdeps/powerpc/powerpc64/power8/Implies @@ -0,0 +1,2 @@ +powerpc/powerpc64/power7/fpu +powerpc/powerpc64/power7 diff --git a/libc/sysdeps/powerpc/rtld-global-offsets.sym b/libc/sysdeps/powerpc/rtld-global-offsets.sym index ff4e97f2a..f5ea5a146 100644 --- a/libc/sysdeps/powerpc/rtld-global-offsets.sym +++ b/libc/sysdeps/powerpc/rtld-global-offsets.sym @@ -5,3 +5,4 @@ #define rtld_global_ro_offsetof(mem) offsetof (struct rtld_global_ro, mem) RTLD_GLOBAL_RO_DL_HWCAP_OFFSET rtld_global_ro_offsetof (_dl_hwcap) +RTLD_GLOBAL_RO_DL_HWCAP2_OFFSET rtld_global_ro_offsetof (_dl_hwcap2) diff --git a/libc/sysdeps/s390/dl-procinfo.h b/libc/sysdeps/s390/dl-procinfo.h index 717f6f9a5..45e27f102 100644 --- a/libc/sysdeps/s390/dl-procinfo.h +++ b/libc/sysdeps/s390/dl-procinfo.h @@ -56,7 +56,7 @@ enum | HWCAP_S390_EIMM | HWCAP_S390_DFP) /* We cannot provide a general printing function. */ -#define _dl_procinfo(word) -1 +#define _dl_procinfo(type, word) -1 static inline const char * __attribute__ ((unused)) diff --git a/libc/sysdeps/sparc/dl-procinfo.h b/libc/sysdeps/sparc/dl-procinfo.h index a18b09958..71b279acd 100644 --- a/libc/sysdeps/sparc/dl-procinfo.h +++ b/libc/sysdeps/sparc/dl-procinfo.h @@ -27,10 +27,14 @@ static inline int __attribute__ ((unused)) -_dl_procinfo (int word) +_dl_procinfo (unsigned int type, unsigned long int word) { int i; + /* Fallback to unknown output mechanism. */ + if (type == AT_HWCAP2) + return -1; + _dl_printf ("AT_HWCAP: "); for (i = 0; i < _DL_HWCAP_COUNT; ++i) diff --git a/libc/sysdeps/unix/sysv/linux/i386/dl-procinfo.h b/libc/sysdeps/unix/sysv/linux/i386/dl-procinfo.h index a82f8f5b8..10f1c00b7 100644 --- a/libc/sysdeps/unix/sysv/linux/i386/dl-procinfo.h +++ b/libc/sysdeps/unix/sysv/linux/i386/dl-procinfo.h @@ -24,12 +24,16 @@ #undef _dl_procinfo static inline int __attribute__ ((unused)) -_dl_procinfo (int word) +_dl_procinfo (unsigned int type, unsigned long int word) { /* This table should match the information from arch/i386/kernel/setup.c in the kernel sources. */ int i; + /* Fallback to unknown output mechanism. */ + if (type == AT_HWCAP2) + return -1; + _dl_printf ("AT_HWCAP: "); for (i = 0; i < _DL_HWCAP_COUNT; ++i) diff --git a/libc/sysdeps/unix/sysv/linux/mmap64.c b/libc/sysdeps/unix/sysv/linux/mmap64.c index 175e4abba..e2dcdc4d9 100644 --- a/libc/sysdeps/unix/sysv/linux/mmap64.c +++ b/libc/sysdeps/unix/sysv/linux/mmap64.c @@ -56,7 +56,7 @@ __mmap64 (void *addr, size_t len, int prot, int flags, int fd, off64_t offset) result = (void *) INLINE_SYSCALL (mmap2, 6, addr, len, prot, flags, fd, - (off_t) (offset >> MMAP2_PAGE_SHIFT)); + (off_t) (offset >> page_shift)); return result; } weak_alias (__mmap64, mmap64) diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/power8/Implies b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/power8/Implies new file mode 100644 index 000000000..066dea279 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/power8/Implies @@ -0,0 +1,2 @@ +powerpc/powerpc32/power8/fpu +powerpc/powerpc32/power8 diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/power8/Implies b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/power8/Implies new file mode 100644 index 000000000..fad2505ab --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/power8/Implies @@ -0,0 +1,2 @@ +powerpc/powerpc64/power8/fpu +powerpc/powerpc64/power8 diff --git a/libc/sysdeps/unix/sysv/linux/s390/dl-procinfo.h b/libc/sysdeps/unix/sysv/linux/s390/dl-procinfo.h index 5ca4b76ca..331230443 100644 --- a/libc/sysdeps/unix/sysv/linux/s390/dl-procinfo.h +++ b/libc/sysdeps/unix/sysv/linux/s390/dl-procinfo.h @@ -24,12 +24,16 @@ #undef _dl_procinfo static inline int __attribute__ ((unused)) -_dl_procinfo (int word) +_dl_procinfo (unsigned int type, unsigned long int word) { /* This table should match the information from arch/s390/kernel/setup.c in the kernel sources. */ int i; + /* Fallback to unknown output mechanism. */ + if (type == AT_HWCAP2) + return -1; + _dl_printf ("AT_HWCAP: "); for (i = 0; i < _DL_HWCAP_COUNT; ++i) diff --git a/libc/sysdeps/x86_64/multiarch/init-arch.c b/libc/sysdeps/x86_64/multiarch/init-arch.c index 9524aeea1..55839610e 100644 --- a/libc/sysdeps/x86_64/multiarch/init-arch.c +++ b/libc/sysdeps/x86_64/multiarch/init-arch.c @@ -81,8 +81,16 @@ __init_cpu_features (void) case 0x37: /* Unaligned load versions are faster than SSSE3 on Silvermont. */ +#if index_Fast_Unaligned_Load != index_Prefer_PMINUB_for_stringop +# error index_Fast_Unaligned_Load != index_Prefer_PMINUB_for_stringop +#endif +#if index_Fast_Unaligned_Load != index_Slow_SSE4_2 +# error index_Fast_Unaligned_Load != index_Slow_SSE4_2 +#endif __cpu_features.feature[index_Fast_Unaligned_Load] - |= bit_Fast_Unaligned_Load; + |= (bit_Fast_Unaligned_Load + | bit_Prefer_PMINUB_for_stringop + | bit_Slow_SSE4_2); break; default: diff --git a/libc/sysdeps/x86_64/multiarch/init-arch.h b/libc/sysdeps/x86_64/multiarch/init-arch.h index 28edbf7d0..0cb5f5bc3 100644 --- a/libc/sysdeps/x86_64/multiarch/init-arch.h +++ b/libc/sysdeps/x86_64/multiarch/init-arch.h @@ -23,6 +23,7 @@ #define bit_AVX_Usable (1 << 6) #define bit_FMA_Usable (1 << 7) #define bit_FMA4_Usable (1 << 8) +#define bit_Slow_SSE4_2 (1 << 9) /* CPUID Feature flags. */ @@ -62,6 +63,7 @@ # define index_AVX_Usable FEATURE_INDEX_1*FEATURE_SIZE # define index_FMA_Usable FEATURE_INDEX_1*FEATURE_SIZE # define index_FMA4_Usable FEATURE_INDEX_1*FEATURE_SIZE +# define index_Slow_SSE4_2 FEATURE_INDEX_1*FEATURE_SIZE #else /* __ASSEMBLER__ */ @@ -156,9 +158,11 @@ extern const struct cpu_features *__get_cpu_features (void) # define index_Fast_Copy_Backward FEATURE_INDEX_1 # define index_Slow_BSF FEATURE_INDEX_1 # define index_Fast_Unaligned_Load FEATURE_INDEX_1 +# define index_Prefer_PMINUB_for_stringop FEATURE_INDEX_1 # define index_AVX_Usable FEATURE_INDEX_1 # define index_FMA_Usable FEATURE_INDEX_1 # define index_FMA4_Usable FEATURE_INDEX_1 +# define index_Slow_SSE4_2 FEATURE_INDEX_1 # define HAS_ARCH_FEATURE(name) \ ((__get_cpu_features ()->feature[index_##name] & (bit_##name)) != 0) diff --git a/libc/sysdeps/x86_64/multiarch/memcmp-ssse3.S b/libc/sysdeps/x86_64/multiarch/memcmp-ssse3.S index bdd2ed213..e319df926 100644 --- a/libc/sysdeps/x86_64/multiarch/memcmp-ssse3.S +++ b/libc/sysdeps/x86_64/multiarch/memcmp-ssse3.S @@ -1463,10 +1463,8 @@ L(next_24_bytes): test $0x40, %dh jnz L(Byte22) - mov -9(%rdi), %eax - and $0xff, %eax - mov -9(%rsi), %edx - and $0xff, %edx + movzbl -9(%rdi), %eax + movzbl -9(%rsi), %edx sub %edx, %eax ret # else diff --git a/libc/sysdeps/x86_64/multiarch/strchr.S b/libc/sysdeps/x86_64/multiarch/strchr.S index 686032944..f170238b5 100644 --- a/libc/sysdeps/x86_64/multiarch/strchr.S +++ b/libc/sysdeps/x86_64/multiarch/strchr.S @@ -29,6 +29,8 @@ ENTRY(strchr) jne 1f call __init_cpu_features 1: leaq __strchr_sse2(%rip), %rax + testl $bit_Slow_SSE4_2, __cpu_features+CPUID_OFFSET+index_Slow_SSE4_2(%rip) + jnz 2f testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) jz 2f leaq __strchr_sse42(%rip), %rax diff --git a/libc/sysdeps/x86_64/multiarch/strcmp.S b/libc/sysdeps/x86_64/multiarch/strcmp.S index f69aaf42b..1d4d71183 100644 --- a/libc/sysdeps/x86_64/multiarch/strcmp.S +++ b/libc/sysdeps/x86_64/multiarch/strcmp.S @@ -88,14 +88,16 @@ ENTRY(STRCMP) jne 1f call __init_cpu_features 1: + testl $bit_Slow_SSE4_2, __cpu_features+CPUID_OFFSET+index_Slow_SSE4_2(%rip) + jnz 2f leaq STRCMP_SSE42(%rip), %rax testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) - jnz 2f - leaq STRCMP_SSSE3(%rip), %rax + jnz 3f +2: leaq STRCMP_SSSE3(%rip), %rax testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) - jnz 2f + jnz 3f leaq STRCMP_SSE2(%rip), %rax -2: ret +3: ret END(STRCMP) # ifdef USE_AS_STRCASECMP_L @@ -109,16 +111,18 @@ ENTRY(__strcasecmp) # ifdef HAVE_AVX_SUPPORT leaq __strcasecmp_avx(%rip), %rax testl $bit_AVX_Usable, __cpu_features+FEATURE_OFFSET+index_AVX_Usable(%rip) - jnz 2f + jnz 3f # endif + testl $bit_Slow_SSE4_2, __cpu_features+CPUID_OFFSET+index_Slow_SSE4_2(%rip) + jnz 2f leaq __strcasecmp_sse42(%rip), %rax testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) - jnz 2f - leaq __strcasecmp_ssse3(%rip), %rax + jnz 3f +2: leaq __strcasecmp_ssse3(%rip), %rax testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) - jnz 2f + jnz 3f leaq __strcasecmp_sse2(%rip), %rax -2: ret +3: ret END(__strcasecmp) weak_alias (__strcasecmp, strcasecmp) # endif @@ -133,16 +137,18 @@ ENTRY(__strncasecmp) # ifdef HAVE_AVX_SUPPORT leaq __strncasecmp_avx(%rip), %rax testl $bit_AVX_Usable, __cpu_features+FEATURE_OFFSET+index_AVX_Usable(%rip) - jnz 2f + jnz 3f # endif + testl $bit_Slow_SSE4_2, __cpu_features+CPUID_OFFSET+index_Slow_SSE4_2(%rip) + jnz 2f leaq __strncasecmp_sse42(%rip), %rax testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) - jnz 2f - leaq __strncasecmp_ssse3(%rip), %rax + jnz 3f +2: leaq __strncasecmp_ssse3(%rip), %rax testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) - jnz 2f + jnz 3f leaq __strncasecmp_sse2(%rip), %rax -2: ret +3: ret END(__strncasecmp) weak_alias (__strncasecmp, strncasecmp) # endif diff --git a/libc/sysdeps/x86_64/multiarch/strrchr.S b/libc/sysdeps/x86_64/multiarch/strrchr.S index ee6af6e9d..3f92a41ef 100644 --- a/libc/sysdeps/x86_64/multiarch/strrchr.S +++ b/libc/sysdeps/x86_64/multiarch/strrchr.S @@ -32,6 +32,8 @@ ENTRY(strrchr) jne 1f call __init_cpu_features 1: leaq __strrchr_sse2(%rip), %rax + testl $bit_Slow_SSE4_2, __cpu_features+CPUID_OFFSET+index_Slow_SSE4_2(%rip) + jnz 2f testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) jz 2f leaq __strrchr_sse42(%rip), %rax |