* V8 [PATCH 1/2] x86: Clear some CPU usable feature bits @ 2020-08-05 23:01 H.J. Lu 2020-08-05 23:01 ` V8 [PATCH 2/2] x86: Install <sys/platform/x86.h> [BZ #26124] H.J. Lu 0 siblings, 1 reply; 7+ messages in thread From: H.J. Lu @ 2020-08-05 23:01 UTC (permalink / raw) To: libc-alpha Clear CPU usable feature bits which may require consulting processor manual to determine how to use them in user space. --- sysdeps/x86/cpu-features.c | 59 +++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c index 4c24ba7c31..5641a8293b 100644 --- a/sysdeps/x86/cpu-features.c +++ b/sysdeps/x86/cpu-features.c @@ -79,6 +79,64 @@ update_usable (struct cpu_features *cpu_features) CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_21); CPU_FEATURE_UNSET (cpu_features, INDEX_7_EDX_23); + /* Before COMMON_CPUID_INDEX_80000001, clear the usable bits which may + require consulting processor manual to determine how to use them in + user space. */ + CPU_FEATURE_UNSET (cpu_features, DTES64); + CPU_FEATURE_UNSET (cpu_features, DS_CPL); + CPU_FEATURE_UNSET (cpu_features, VMX); + CPU_FEATURE_UNSET (cpu_features, SMX); + CPU_FEATURE_UNSET (cpu_features, EIST); + CPU_FEATURE_UNSET (cpu_features, TM2); + CPU_FEATURE_UNSET (cpu_features, CNXT_ID); + CPU_FEATURE_UNSET (cpu_features, SDBG); + CPU_FEATURE_UNSET (cpu_features, XTPRUPDCTRL); + CPU_FEATURE_UNSET (cpu_features, PDCM); + CPU_FEATURE_UNSET (cpu_features, PCID); + CPU_FEATURE_UNSET (cpu_features, DCA); + CPU_FEATURE_UNSET (cpu_features, X2APIC); + CPU_FEATURE_UNSET (cpu_features, TSC_DEADLINE); + CPU_FEATURE_UNSET (cpu_features, VME); + CPU_FEATURE_UNSET (cpu_features, DE); + CPU_FEATURE_UNSET (cpu_features, PSE); + CPU_FEATURE_UNSET (cpu_features, PAE); + CPU_FEATURE_UNSET (cpu_features, MCE); + CPU_FEATURE_UNSET (cpu_features, APIC); + CPU_FEATURE_UNSET (cpu_features, MTRR); + CPU_FEATURE_UNSET (cpu_features, PGE); + CPU_FEATURE_UNSET (cpu_features, MCA); + CPU_FEATURE_UNSET (cpu_features, PAT); + CPU_FEATURE_UNSET (cpu_features, PSE_36); + CPU_FEATURE_UNSET (cpu_features, DS); + CPU_FEATURE_UNSET (cpu_features, ACPI); + CPU_FEATURE_UNSET (cpu_features, SS); + CPU_FEATURE_UNSET (cpu_features, TM); + CPU_FEATURE_UNSET (cpu_features, PBE); + CPU_FEATURE_UNSET (cpu_features, TSC_ADJUST); + CPU_FEATURE_UNSET (cpu_features, SGX); + CPU_FEATURE_UNSET (cpu_features, HLE); + CPU_FEATURE_UNSET (cpu_features, SMEP); + CPU_FEATURE_UNSET (cpu_features, RTM); + CPU_FEATURE_UNSET (cpu_features, RDT_M); + CPU_FEATURE_UNSET (cpu_features, DEPR_FPU_CS_DS); + CPU_FEATURE_UNSET (cpu_features, RDT_A); + CPU_FEATURE_UNSET (cpu_features, SMAP); + CPU_FEATURE_UNSET (cpu_features, TRACE); + CPU_FEATURE_UNSET (cpu_features, UMIP); + CPU_FEATURE_UNSET (cpu_features, SHSTK); + CPU_FEATURE_UNSET (cpu_features, SGX_LC); + CPU_FEATURE_UNSET (cpu_features, PKS); + CPU_FEATURE_UNSET (cpu_features, MD_CLEAR); + CPU_FEATURE_UNSET (cpu_features, HYBRID); + CPU_FEATURE_UNSET (cpu_features, PCONFIG); + CPU_FEATURE_UNSET (cpu_features, IBT); + CPU_FEATURE_UNSET (cpu_features, IBRS_IBPB); + CPU_FEATURE_UNSET (cpu_features, STIBP); + CPU_FEATURE_UNSET (cpu_features, L1D_FLUSH); + CPU_FEATURE_UNSET (cpu_features, ARCH_CAPABILITIES); + CPU_FEATURE_UNSET (cpu_features, CORE_CAPABILITIES); + CPU_FEATURE_UNSET (cpu_features, SSBD); + /* EAX/EBX from COMMON_CPUID_INDEX_1 and EAX from COMMON_CPUID_INDEX_7 aren't used for CPU feature detection. */ cpu_features->features[COMMON_CPUID_INDEX_1].usable.eax = 0; @@ -106,7 +164,6 @@ update_usable (struct cpu_features *cpu_features) CPU_FEATURE_SET_USABLE (cpu_features, XGETBV_ECX_1); CPU_FEATURE_SET_USABLE (cpu_features, XSAVES); CPU_FEATURE_SET_USABLE (cpu_features, XFD); - CPU_FEATURE_SET_USABLE (cpu_features, INVARIANT_TSC); CPU_FEATURE_SET_USABLE (cpu_features, WBNOINVD); CPU_FEATURE_SET_USABLE (cpu_features, AVX512_BF16); -- 2.26.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* V8 [PATCH 2/2] x86: Install <sys/platform/x86.h> [BZ #26124] 2020-08-05 23:01 V8 [PATCH 1/2] x86: Clear some CPU usable feature bits H.J. Lu @ 2020-08-05 23:01 ` H.J. Lu 2020-08-12 14:00 ` PING: " H.J. Lu 0 siblings, 1 reply; 7+ messages in thread From: H.J. Lu @ 2020-08-05 23:01 UTC (permalink / raw) To: libc-alpha Install <sys/platform/x86.h> so that programmers can do #if __has_include(<sys/platform/x86.h>) #include <sys/platform/x86.h> #endif ... if (CPU_FEATURE_USABLE (SSE2)) ... if (CPU_FEATURE_USABLE (AVX2)) ... <sys/platform/x86.h> exports only: enum { COMMON_CPUID_INDEX_1 = 0, COMMON_CPUID_INDEX_7, COMMON_CPUID_INDEX_80000001, COMMON_CPUID_INDEX_D_ECX_1, COMMON_CPUID_INDEX_80000007, COMMON_CPUID_INDEX_80000008, COMMON_CPUID_INDEX_7_ECX_1, /* Keep the following line at the end. */ COMMON_CPUID_INDEX_MAX }; struct cpuid_features { struct cpuid_registers cpuid; struct cpuid_registers usable; }; struct cpu_features { struct cpu_features_basic basic; struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; }; /* Get a pointer to the CPU features structure. */ extern const struct cpu_features *__x86_get_cpu_features (unsigned int max) __attribute__ ((const)); Since all feature checks are done through macros, programs compiled with a newer <sys/platform/x86.h> are compatible with the older glibc binaries as long as the layout of struct cpu_features is identical. The features array can be expanded with backward binary compatibility for both .o and .so files. When COMMON_CPUID_INDEX_MAX is increased to support new processor features, __x86_get_cpu_features in the older glibc binaries returns NULL and HAS_CPU_FEATURE/CPU_FEATURE_USABLE return false on the new processor feature. No new symbol version is neeeded. Both CPU_FEATURE_USABLE and HAS_CPU_FEATURE are provided. HAS_CPU_FEATURE can be used to identify processor features. Note: Although GCC has __builtin_cpu_supports, it only supports a subset of <sys/platform/x86.h> and it is equivalent to CPU_FEATURE_USABLE. It doesn't support HAS_CPU_FEATURE. --- NEWS | 2 +- manual/platform.texi | 517 ++++++++++++++++++ sysdeps/i386/i686/multiarch/Makefile | 4 - sysdeps/i386/i686/multiarch/test-multiarch.c | 1 - sysdeps/unix/sysv/linux/i386/ld.abilist | 1 + sysdeps/unix/sysv/linux/x86_64/64/ld.abilist | 1 + sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist | 1 + sysdeps/x86/Makefile | 4 +- sysdeps/x86/Versions | 4 +- sysdeps/x86/dl-get-cpu-features.c | 6 +- sysdeps/x86/include/cpu-features.h | 183 +++++++ .../{cpu-features.h => sys/platform/x86.h} | 150 +---- sysdeps/x86/tst-cpu-features-cpuinfo.c | 250 +++++++++ sysdeps/x86/tst-cpu-features-supports.c | 192 +++++++ sysdeps/x86/tst-get-cpu-features.c | 6 +- sysdeps/x86_64/fpu/math-tests-arch.h | 2 +- sysdeps/x86_64/multiarch/Makefile | 4 - sysdeps/x86_64/multiarch/test-multiarch.c | 96 ---- 18 files changed, 1176 insertions(+), 248 deletions(-) delete mode 100644 sysdeps/i386/i686/multiarch/test-multiarch.c create mode 100644 sysdeps/x86/include/cpu-features.h rename sysdeps/x86/{cpu-features.h => sys/platform/x86.h} (81%) create mode 100644 sysdeps/x86/tst-cpu-features-cpuinfo.c create mode 100644 sysdeps/x86/tst-cpu-features-supports.c delete mode 100644 sysdeps/x86_64/multiarch/test-multiarch.c diff --git a/NEWS b/NEWS index 2937adc3f3..d19551c132 100644 --- a/NEWS +++ b/NEWS @@ -9,7 +9,7 @@ Version 2.33 Major new features: - [Add new features here] +* Add <sys/platform/x86.h> to provide query macros for x86 CPU features. Deprecated and removed features, and other changes affecting compatibility: diff --git a/manual/platform.texi b/manual/platform.texi index 504addc956..2c145acdc3 100644 --- a/manual/platform.texi +++ b/manual/platform.texi @@ -7,6 +7,7 @@ @menu * PowerPC:: Facilities Specific to the PowerPC Architecture * RISC-V:: Facilities Specific to the RISC-V Architecture +* X86:: Facilities Specific to the X86 Architecture @end menu @node PowerPC @@ -134,3 +135,519 @@ all threads in the current process. Setting the ordering on only the current thread is necessary. All other flag bits are reserved. @end deftypefun + +@node X86 +@appendixsec X86-specific Facilities + +Facilities specific to X86 that are not specific to a particular +operating system are declared in @file{sys/platform/x86.h}. + +@deftypefun {const struct cpu_features *} __x86_get_cpu_features (unsigned int @var{max}) +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +Return a pointer to x86 CPU feature structure used by query macros for x86 +CPU features. If @var{max} exceeds @code{COMMON_CPUID_INDEX_MAX} which +is the limit of the CPUID leaves supported by @Theglibc{}, the function +returns @code{NULL}, indicating that the queried processor feature is +unsupported by @Theglibc{} run-time. +@end deftypefun + +@deftypefn Macro int HAS_CPU_FEATURE (@var{name}) +This macro returns a nonzero value (true) if the processor has the feature +@var{name}. +@end deftypefn + +@deftypefn Macro int CPU_FEATURE_USABLE (@var{name}) +This macro returns a nonzero value (true) if the processor has the feature +@var{name} and the feature is supported by the operating system. +@end deftypefn + +The supported processor features are: + +@itemize @bullet + +@item +@code{ACPI} -- Thermal Monitor and Software Controlled Clock Facilities. + +@item +@code{ADX} -- ADX instruction extensions. + +@item +@code{APIC} -- APIC On-Chip. + +@item +@code{AES} -- The AES instruction extensions. + +@item +@code{AMX_BF16} -- Tile computational operations on bfloat16 numbers. + +@item +@code{AMX_INT8} -- Tile computational operations on 8-bit numbers. + +@item +@code{AMX_TILE} -- Tile architecture. + +@item +@code{ARCH_CAPABILITIES} -- IA32_ARCH_CAPABILITIES MSR. + +@item +@code{AVX} -- The AVX instruction extensions. + +@item +@code{AVX2} -- The AVX2 instruction extensions. + +@item +@code{AVX512_4FMAPS} -- The AVX512_4FMAPS instruction extensions. + +@item +@code{AVX512_4VNNIW} -- The AVX512_4VNNIW instruction extensions. + +@item +@code{AVX512_BF16} -- The AVX512_BF16 instruction extensions. + +@item +@code{AVX512_BITALG} -- The AVX512_BITALG instruction extensions. + +@item +@code{AVX512_IFMA} -- The AVX512_IFMA instruction extensions. + +@item +@code{AVX512_VBMI} -- The AVX512_VBMI instruction extensions. + +@item +@code{AVX512_VBMI2} -- The AVX512_VBMI2 instruction extensions. + +@item +@code{AVX512_VNNI} -- The AVX512_VNNI instruction extensions. + +@item +@code{AVX512_VP2INTERSECT} -- The AVX512_VP2INTERSECT instruction +extensions. + +@item +@code{AVX512_VPOPCNTDQ} -- The AVX512_VPOPCNTDQ instruction extensions. + +@item +@code{AVX512BW} -- The AVX512BW instruction extensions. + +@item +@code{AVX512CD} -- The AVX512CD instruction extensions. + +@item +@code{AVX512ER} -- The AVX512ER instruction extensions. + +@item +@code{AVX512DQ} -- The AVX512DQ instruction extensions. + +@item +@code{AVX512F} -- The AVX512F instruction extensions. + +@item +@code{AVX512PF} -- The AVX512PF instruction extensions. + +@item +@code{AVX512VL} -- The AVX512VL instruction extensions. + +@item +@code{BMI1} -- BMI1 instructions. + +@item +@code{BMI2} -- BMI2 instructions. + +@item +@code{CLDEMOTE} -- CLDEMOTE instruction. + +@item +@code{CLFLUSHOPT} -- CLFLUSHOPT instruction. + +@item +@code{CLFSH} -- CLFLUSH instruction. + +@item +@code{CLWB} -- CLWB instruction. + +@item +@code{CMOV} -- Conditional Move instructions. + +@item +@code{CMPXCHG16B} -- CMPXCHG16B instruction. + +@item +@code{CNXT_ID} -- L1 Context ID. + +@item +@code{CORE_CAPABILITIES} -- IA32_CORE_CAPABILITIES MSR. + +@item +@code{CX8} -- CMPXCHG8B instruction. + +@item +@code{DCA} -- Data prefetch from a memory mapped device. + +@item +@code{DE} -- Debugging Extensions. + +@item +@code{DEPR_FPU_CS_DS} -- Deprecates FPU CS and FPU DS values. + +@item +@code{DS} -- Debug Store. + +@item +@code{DS_CPL} -- CPL Qualified Debug Store. + +@item +@code{DTES64} -- 64-bit DS Area. + +@item +@code{EIST} -- Enhanced Intel SpeedStep technology. + +@item +@code{ENQCMD} -- Enqueue Stores instructions. + +@item +@code{ERMS} -- Enhanced REP MOVSB/STOSB. + +@item +@code{F16C} -- 16-bit floating-point conversion instructions. + +@item +@code{FMA} -- FMA extensions using YMM state. + +@item +@code{FMA4} -- FMA4 instruction extensions. + +@item +@code{FPU} -- X87 Floating Point Unit On-Chip. + +@item +@code{FSGSBASE} -- RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE instructions. + +@item +@code{FSRM} -- Fast Short REP MOV. + +@item +@code{FXSR} -- FXSAVE and FXRSTOR instructions. + +@item +@code{GFNI} -- GFNI instruction extensions. + +@item +@code{HLE} -- HLE instruction extensions. + +@item +@code{HTT} -- Max APIC IDs reserved field is Valid. + +@item +@code{HYBRID} -- Hybrid processor. + +@item +@code{IBRS_IBPB} -- Indirect branch restricted speculation (IBRS) and +the indirect branch predictor barrier (IBPB). + +@item +@code{IBT} -- Intel Indirect Branch Tracking instruction extensions. + +@item +@code{INVARIANT_TSC} -- Invariant TSC. + +@item +@code{INVPCID} -- INVPCID instruction. + +@item +@code{L1D_FLUSH} -- IA32_FLUSH_CMD MSR. + +@item +@code{LAHF64_SAHF64} -- LAHF/SAHF available in 64-bit mode. + +@item +@code{LM} -- Long mode. + +@item +@code{LWP} -- Lightweight profiling. + +@item +@code{LZCNT} -- LZCNT instruction. + +@item +@code{MCA} -- Machine Check Architecture. + +@item +@code{MCE} -- Machine Check Exception. + +@item +@code{MD_CLEAR} -- MD_CLEAR. + +@item +@code{MMX} -- Intel MMX Technology. + +@item +@code{MONITOR} -- MONITOR/MWAIT instructions. + +@item +@code{MOVBE} -- MOVBE instruction. + +@item +@code{MOVDIRI} -- MOVDIRI instruction. + +@item +@code{MOVDIR64B} -- MOVDIR64B instruction. + +@item +@code{MPX} -- Intel Memory Protection Extensions. + +@item +@code{MSR} -- Model Specific Registers RDMSR and WRMSR instructions. + +@item +@code{MTRR} -- Memory Type Range Registers. + +@item +@code{NX} -- No-execute page protection. + +@item +@code{OSPKE} -- OS has set CR4.PKE to enable protection keys. + +@item +@code{OSXSAVE} -- The OS has set CR4.OSXSAVE[bit 18] to enable +XSETBV/XGETBV instructions to access XCR0 and to support processor +extended state management using XSAVE/XRSTOR. + +@item +@code{PAE} -- Physical Address Extension. + +@item +@code{PAGE1GB} -- 1-GByte page. + +@item +@code{PAT} -- Page Attribute Table. + +@item +@code{PBE} -- Pending Break Enable. + +@item +@code{PCID} -- Process-context identifiers. + +@item +@code{PCLMULQDQ} -- PCLMULQDQ instruction. + +@item +@code{PCONFIG} -- PCONFIG instruction. + +@item +@code{PDCM} -- Perfmon and Debug Capability. + +@item +@code{PGE} -- Page Global Bit. + +@item +@code{PKS} -- Protection keys for supervisor-mode pages. + +@item +@code{PKU} -- Protection keys for user-mode pages. + +@item +@code{POPCNT} -- POPCNT instruction. + +@item +@code{PREFETCHW} -- PREFETCHW instruction. + +@item +@code{PREFETCHWT1} -- PREFETCHWT1 instruction. + +@item +@code{PSE} -- Page Size Extension. + +@item +@code{PSE_36} -- 36-Bit Page Size Extension. + +@item +@code{PSN} -- Processor Serial Number. + +@item +@code{RDPID} -- RDPID instruction. + +@item +@code{RDRAND} -- RDRAND instruction. + +@item +@code{RDSEED} -- RDSEED instruction. + +@item +@code{RDT_A} -- Intel Resource Director Technology (Intel RDT) Allocation +capability. + +@item +@code{RDT_M} -- Intel Resource Director Technology (Intel RDT) Monitoring +capability. + +@item +@code{RDTSCP} -- RDTSCP instruction. + +@item +@code{RTM} -- RTM instruction extensions. + +@item +@code{SDBG} -- IA32_DEBUG_INTERFACE MSR for silicon debug. + +@item +@code{SEP} -- SYSENTER and SYSEXIT instructions. + +@item +@code{SERIALIZE} -- SERIALIZE instruction. + +@item +@code{SGX} -- Intel Software Guard Extensions. + +@item +@code{SGX_LC} -- SGX Launch Configuration. + +@item +@code{SHA} -- SHA instruction extensions. + +@item +@code{SHSTK} -- Intel Shadow Stack instruction extensions. + +@item +@code{SMAP} -- Supervisor-Mode Access Prevention. + +@item +@code{SMEP} -- Supervisor-Mode Execution Prevention. + +@item +@code{SMX} -- Safer Mode Extensions. + +@item +@code{SS} -- Self Snoop. + +@item +@code{SSBD} -- Speculative Store Bypass Disable (SSBD). + +@item +@code{SSE} -- Streaming SIMD Extensions. + +@item +@code{SSE2} -- Streaming SIMD Extensions 2. + +@item +@code{SSE3} -- Streaming SIMD Extensions 3. + +@item +@code{SSE4_1} -- Streaming SIMD Extensions 4.1. + +@item +@code{SSE4_2} -- Streaming SIMD Extensions 4.2. + +@item +@code{SSE4A} -- SSE4A instruction extensions. + +@item +@code{SSSE3} -- Supplemental Streaming SIMD Extensions 3. + +@item +@code{STIBP} -- Single thread indirect branch predictors (STIBP). + +@item +@code{SVM} -- Secure Virtual Machine. + +@item +@code{SYSCALL_SYSRET} -- SYSCALL/SYSRET instructions. + +@item +@code{TBM} -- Trailing bit manipulation instructions. + +@item +@code{TM} -- Thermal Monitor. + +@item +@code{TM2} -- Thermal Monitor 2. + +@item +@code{TRACE} -- Intel Processor Trace. + +@item +@code{TSC} -- Time Stamp Counter. RDTSC instruction. + +@item +@code{TSC_ADJUST} -- IA32_TSC_ADJUST MSR. + +@item +@code{TSC_DEADLINE} -- Local APIC timer supports one-shot operation +using a TSC deadline value. + +@item +@code{TSXLDTRK} -- TSXLDTRK instructions. + +@item +@code{UMIP} -- User-mode instruction prevention. + +@item +@code{VAES} -- VAES instruction extensions. + +@item +@code{VME} -- Virtual 8086 Mode Enhancements. + +@item +@code{VMX} -- Virtual Machine Extensions. + +@item +@code{VPCLMULQDQ} -- VPCLMULQDQ instruction. + +@item +@code{WAITPKG} -- WAITPKG instruction extensions. + +@item +@code{WBNOINVD} -- WBINVD/WBNOINVD instructions. + +@item +@code{X2APIC} -- x2APIC. + +@item +@code{XFD} -- Extended Feature Disable (XFD). + +@item +@code{XGETBV_ECX_1} -- XGETBV with ECX = 1. + +@item +@code{XOP} -- XOP instruction extensions. + +@item +@code{XSAVE} -- The XSAVE/XRSTOR processor extended states feature, the +XSETBV/XGETBV instructions, and XCR0. + +@item +@code{XSAVEC} -- XSAVEC instruction. + +@item +@code{XSAVEOPT} -- XSAVEOPT instruction. + +@item +@code{XSAVES} -- XSAVES/XRSTORS instructions. + +@item +@code{XTPRUPDCTRL} -- xTPR Update Control. + +@end itemize + +You could query if a processor supports @code{AVX} with: + +@smallexample +#include <sys/platform/x86.h> + +int +support_avx (void) +@{ + return HAS_CPU_FEATURE (AVX); +@} +@end smallexample + +and if @code{AVX} is usable with: + +@smallexample +#include <sys/platform/x86.h> + +int +usable_avx (void) +@{ + return CPU_FEATURE_USABLE (AVX); +@} +@end smallexample diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile index bf75a9947f..c4897922d7 100644 --- a/sysdeps/i386/i686/multiarch/Makefile +++ b/sysdeps/i386/i686/multiarch/Makefile @@ -1,7 +1,3 @@ -ifeq ($(subdir),csu) -tests += test-multiarch -endif - ifeq ($(subdir),string) gen-as-const-headers += locale-defines.sym sysdep_routines += bzero-sse2 memset-sse2 memcpy-ssse3 mempcpy-ssse3 \ diff --git a/sysdeps/i386/i686/multiarch/test-multiarch.c b/sysdeps/i386/i686/multiarch/test-multiarch.c deleted file mode 100644 index 593cfec273..0000000000 --- a/sysdeps/i386/i686/multiarch/test-multiarch.c +++ /dev/null @@ -1 +0,0 @@ -#include <sysdeps/x86_64/multiarch/test-multiarch.c> diff --git a/sysdeps/unix/sysv/linux/i386/ld.abilist b/sysdeps/unix/sysv/linux/i386/ld.abilist index 0478e22071..04655651b0 100644 --- a/sysdeps/unix/sysv/linux/i386/ld.abilist +++ b/sysdeps/unix/sysv/linux/i386/ld.abilist @@ -3,3 +3,4 @@ GLIBC_2.1 __libc_stack_end D 0x4 GLIBC_2.1 _dl_mcount F GLIBC_2.3 ___tls_get_addr F GLIBC_2.3 __tls_get_addr F +GLIBC_2.33 __x86_get_cpu_features F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist index d3cdf7611e..e632c6198e 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist @@ -2,3 +2,4 @@ GLIBC_2.2.5 __libc_stack_end D 0x8 GLIBC_2.2.5 _dl_mcount F GLIBC_2.2.5 _r_debug D 0x28 GLIBC_2.3 __tls_get_addr F +GLIBC_2.33 __x86_get_cpu_features F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist index c70bccf782..9d9d0befde 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist @@ -2,3 +2,4 @@ GLIBC_2.16 __libc_stack_end D 0x4 GLIBC_2.16 __tls_get_addr F GLIBC_2.16 _dl_mcount F GLIBC_2.16 _r_debug D 0x14 +GLIBC_2.33 __x86_get_cpu_features F diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile index a6736aef25..c369faf00d 100644 --- a/sysdeps/x86/Makefile +++ b/sysdeps/x86/Makefile @@ -4,8 +4,10 @@ endif ifeq ($(subdir),elf) sysdep-dl-routines += dl-get-cpu-features +sysdep_headers += sys/platform/x86.h -tests += tst-get-cpu-features tst-get-cpu-features-static +tests += tst-get-cpu-features tst-get-cpu-features-static \ + tst-cpu-features-cpuinfo tst-cpu-features-supports tests-static += tst-get-cpu-features-static endif diff --git a/sysdeps/x86/Versions b/sysdeps/x86/Versions index e02923708e..59db578a9d 100644 --- a/sysdeps/x86/Versions +++ b/sysdeps/x86/Versions @@ -1,5 +1,5 @@ ld { - GLIBC_PRIVATE { - __get_cpu_features; + GLIBC_2.33 { + __x86_get_cpu_features; } } diff --git a/sysdeps/x86/dl-get-cpu-features.c b/sysdeps/x86/dl-get-cpu-features.c index 9d61cd56be..5f9e46b0c6 100644 --- a/sysdeps/x86/dl-get-cpu-features.c +++ b/sysdeps/x86/dl-get-cpu-features.c @@ -18,10 +18,12 @@ #include <ldsodefs.h> -#undef __get_cpu_features +#undef __x86_get_cpu_features const struct cpu_features * -__get_cpu_features (void) +__x86_get_cpu_features (unsigned int max) { + if (max > COMMON_CPUID_INDEX_MAX) + return NULL; return &GLRO(dl_x86_cpu_features); } diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h new file mode 100644 index 0000000000..dcf29b6fe8 --- /dev/null +++ b/sysdeps/x86/include/cpu-features.h @@ -0,0 +1,183 @@ +/* Data structure for x86 CPU features. + Copyright (C) 2020 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 + <https://www.gnu.org/licenses/>. */ + +#ifndef _PRIVATE_CPU_FEATURES_H +#define _PRIVATE_CPU_FEATURES_H 1 + +#ifdef _CPU_FEATURES_H +# error this should be impossible +#endif + +#ifndef _ISOMAC +/* Get most of the contents from the public header, but we define a + different `struct cpu_features' type for private use. */ +# define cpu_features cpu_features_public +# define __x86_get_cpu_features __x86_get_cpu_features_public +#endif + +#include <sysdeps/x86/sys/platform/x86.h> + +#ifndef _ISOMAC + +# undef cpu_features +# undef __x86_get_cpu_features +# define __get_cpu_features() __x86_get_cpu_features (0) + +enum +{ + /* The integer bit array index for the first set of preferred feature + bits. */ + PREFERRED_FEATURE_INDEX_1 = 0, + /* The current maximum size of the feature integer bit array. */ + PREFERRED_FEATURE_INDEX_MAX +}; + +/* Only used directly in cpu-features.c. */ +# define CPU_FEATURE_SET(ptr, name) \ + ptr->features[index_cpu_##name].usable.reg_##name |= bit_cpu_##name; +# define CPU_FEATURE_UNSET(ptr, name) \ + ptr->features[index_cpu_##name].usable.reg_##name &= ~bit_cpu_##name; +# define CPU_FEATURE_SET_USABLE(ptr, name) \ + ptr->features[index_cpu_##name].usable.reg_##name \ + |= ptr->features[index_cpu_##name].cpuid.reg_##name & bit_cpu_##name; +# define CPU_FEATURE_PREFERRED_P(ptr, name) \ + ((ptr->preferred[index_arch_##name] & bit_arch_##name) != 0) +# define CPU_FEATURE_CPU_P(ptr, name) \ + CPU_FEATURE_CHECK_P (ptr, name, cpuid) + +/* HAS_CPU_FEATURE evaluates to true if CPU supports the feature. */ +# undef HAS_CPU_FEATURE +# define HAS_CPU_FEATURE(name) \ + CPU_FEATURE_CPU_P (__x86_get_cpu_features (0), name) +/* CPU_FEATURE_USABLE evaluates to true if the feature is usable. */ +# undef CPU_FEATURE_USABLE +# define CPU_FEATURE_USABLE(name) \ + CPU_FEATURE_USABLE_P (__x86_get_cpu_features (0), name) +/* CPU_FEATURE_PREFER evaluates to true if we prefer the feature at + runtime. */ +# define CPU_FEATURE_PREFERRED(name) \ + CPU_FEATURE_PREFERRED_P(__get_cpu_features (), name) + +# define CPU_FEATURES_CPU_P(ptr, name) \ + CPU_FEATURE_CPU_P (ptr, name) +# define CPU_FEATURES_ARCH_P(ptr, name) \ + CPU_FEATURE_PREFERRED_P (ptr, name) +# define HAS_ARCH_FEATURE(name) \ + CPU_FEATURE_PREFERRED (name) + +/* PREFERRED_FEATURE_INDEX_1. */ +# define bit_arch_I586 (1u << 0) +# define bit_arch_I686 (1u << 1) +# define bit_arch_Fast_Rep_String (1u << 2) +# define bit_arch_Fast_Copy_Backward (1u << 3) +# define bit_arch_Fast_Unaligned_Load (1u << 4) +# define bit_arch_Fast_Unaligned_Copy (1u << 5) +# define bit_arch_Slow_BSF (1u << 6) +# define bit_arch_Slow_SSE4_2 (1u << 7) +# define bit_arch_AVX_Fast_Unaligned_Load (1u << 8) +# define bit_arch_Prefer_MAP_32BIT_EXEC (1u << 9) +# define bit_arch_Prefer_PMINUB_for_stringop (1u << 10) +# define bit_arch_Prefer_No_VZEROUPPER (1u << 11) +# define bit_arch_Prefer_ERMS (1u << 12) +# define bit_arch_Prefer_FSRM (1u << 13) +# define bit_arch_Prefer_No_AVX512 (1u << 14) +# define bit_arch_MathVec_Prefer_No_AVX512 (1u << 15) + +# define index_arch_Fast_Rep_String PREFERRED_FEATURE_INDEX_1 +# define index_arch_Fast_Copy_Backward PREFERRED_FEATURE_INDEX_1 +# define index_arch_Slow_BSF PREFERRED_FEATURE_INDEX_1 +# define index_arch_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 +# define index_arch_Prefer_PMINUB_for_stringop PREFERRED_FEATURE_INDEX_1 +# define index_arch_Fast_Unaligned_Copy PREFERRED_FEATURE_INDEX_1 +# define index_arch_I586 PREFERRED_FEATURE_INDEX_1 +# define index_arch_I686 PREFERRED_FEATURE_INDEX_1 +# define index_arch_Slow_SSE4_2 PREFERRED_FEATURE_INDEX_1 +# define index_arch_AVX_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 +# define index_arch_Prefer_MAP_32BIT_EXEC PREFERRED_FEATURE_INDEX_1 +# define index_arch_Prefer_No_VZEROUPPER PREFERRED_FEATURE_INDEX_1 +# define index_arch_Prefer_ERMS PREFERRED_FEATURE_INDEX_1 +# define index_arch_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 +# define index_arch_MathVec_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 +# define index_arch_Prefer_FSRM PREFERRED_FEATURE_INDEX_1 + +/* XCR0 Feature flags. */ +# define bit_XMM_state (1u << 1) +# define bit_YMM_state (1u << 2) +# define bit_Opmask_state (1u << 5) +# define bit_ZMM0_15_state (1u << 6) +# define bit_ZMM16_31_state (1u << 7) +# define bit_XTILECFG_state (1u << 17) +# define bit_XTILEDATA_state (1u << 18) + +struct cpu_features +{ + struct cpu_features_basic basic; + struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; + unsigned int preferred[PREFERRED_FEATURE_INDEX_MAX]; + /* The state size for XSAVEC or XSAVE. The type must be unsigned long + int so that we use + + sub xsave_state_size_offset(%rip) %RSP_LP + + in _dl_runtime_resolve. */ + unsigned long int xsave_state_size; + /* The full state size for XSAVE when XSAVEC is disabled by + + GLIBC_TUNABLES=glibc.cpu.hwcaps=-XSAVEC + */ + unsigned int xsave_state_full_size; + /* Data cache size for use in memory and string routines, typically + L1 size. */ + unsigned long int data_cache_size; + /* Shared cache size for use in memory and string routines, typically + L2 or L3 size. */ + unsigned long int shared_cache_size; + /* Threshold to use non temporal store. */ + unsigned long int non_temporal_threshold; + /* Threshold to use "rep movsb". */ + unsigned long int rep_movsb_threshold; + /* Threshold to use "rep stosb". */ + unsigned long int rep_stosb_threshold; +}; + +# if defined (_LIBC) && !IS_IN (nonlib) +/* Unused for x86. */ +# define INIT_ARCH() +# define __x86_get_cpu_features(max) (&GLRO(dl_x86_cpu_features)) +# endif + +# ifdef __x86_64__ +# define HAS_CPUID 1 +# elif (defined __i586__ || defined __pentium__ \ + || defined __geode__ || defined __k6__) +# define HAS_CPUID 1 +# define HAS_I586 1 +# define HAS_I686 HAS_ARCH_FEATURE (I686) +# elif defined __i486__ +# define HAS_CPUID 0 +# define HAS_I586 HAS_ARCH_FEATURE (I586) +# define HAS_I686 HAS_ARCH_FEATURE (I686) +# else +# define HAS_CPUID 1 +# define HAS_I586 1 +# define HAS_I686 1 +# endif + +#endif /* !_ISOMAC */ + +#endif /* include/cpu-features.h */ diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/sys/platform/x86.h similarity index 81% rename from sysdeps/x86/cpu-features.h rename to sysdeps/x86/sys/platform/x86.h index 78fcec251e..bf3727ebc0 100644 --- a/sysdeps/x86/cpu-features.h +++ b/sysdeps/x86/sys/platform/x86.h @@ -1,4 +1,5 @@ -/* This file is part of the GNU C Library. +/* Data structure for x86 CPU features. + This file is part of the GNU C Library. Copyright (C) 2008-2020 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or @@ -15,17 +16,8 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ -#ifndef cpu_features_h -#define cpu_features_h - -enum -{ - /* The integer bit array index for the first set of preferred feature - bits. */ - PREFERRED_FEATURE_INDEX_1 = 0, - /* The current maximum size of the feature integer bit array. */ - PREFERRED_FEATURE_INDEX_MAX -}; +#ifndef _SYS_PLATFORM_X86_H +#define _SYS_PLATFORM_X86_H enum { @@ -76,73 +68,32 @@ struct cpu_features { struct cpu_features_basic basic; struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; - unsigned int preferred[PREFERRED_FEATURE_INDEX_MAX]; - /* The state size for XSAVEC or XSAVE. The type must be unsigned long - int so that we use - - sub xsave_state_size_offset(%rip) %RSP_LP - - in _dl_runtime_resolve. */ - unsigned long int xsave_state_size; - /* The full state size for XSAVE when XSAVEC is disabled by - - GLIBC_TUNABLES=glibc.cpu.hwcaps=-XSAVEC - */ - unsigned int xsave_state_full_size; - /* Data cache size for use in memory and string routines, typically - L1 size. */ - unsigned long int data_cache_size; - /* Shared cache size for use in memory and string routines, typically - L2 or L3 size. */ - unsigned long int shared_cache_size; - /* Threshold to use non temporal store. */ - unsigned long int non_temporal_threshold; - /* Threshold to use "rep movsb". */ - unsigned long int rep_movsb_threshold; - /* Threshold to use "rep stosb". */ - unsigned long int rep_stosb_threshold; }; -/* Used from outside of glibc to get access to the CPU features - structure. */ -extern const struct cpu_features *__get_cpu_features (void) +/* Get a pointer to the CPU features structure. */ +extern const struct cpu_features *__x86_get_cpu_features (unsigned int) __attribute__ ((const)); -/* Only used directly in cpu-features.c. */ #define CPU_FEATURE_CHECK_P(ptr, name, check) \ ((ptr->features[index_cpu_##name].check.reg_##name \ & bit_cpu_##name) != 0) -#define CPU_FEATURE_SET(ptr, name) \ - ptr->features[index_cpu_##name].usable.reg_##name |= bit_cpu_##name; -#define CPU_FEATURE_UNSET(ptr, name) \ - ptr->features[index_cpu_##name].usable.reg_##name &= ~bit_cpu_##name; -#define CPU_FEATURE_SET_USABLE(ptr, name) \ - ptr->features[index_cpu_##name].usable.reg_##name \ - |= ptr->features[index_cpu_##name].cpuid.reg_##name & bit_cpu_##name; -#define CPU_FEATURE_PREFERRED_P(ptr, name) \ - ((ptr->preferred[index_arch_##name] & bit_arch_##name) != 0) #define CPU_FEATURE_CPU_P(ptr, name) \ CPU_FEATURE_CHECK_P (ptr, name, cpuid) #define CPU_FEATURE_USABLE_P(ptr, name) \ CPU_FEATURE_CHECK_P (ptr, name, usable) /* HAS_CPU_FEATURE evaluates to true if CPU supports the feature. */ -#define HAS_CPU_FEATURE(name) \ - CPU_FEATURE_CPU_P (__get_cpu_features (), name) +#define HAS_CPU_FEATURE(name) \ + (__extension__ \ + ({ const struct cpu_features *__ptr = \ + __x86_get_cpu_features (COMMON_CPUID_INDEX_MAX); \ + __ptr && CPU_FEATURE_CPU_P (__ptr, name); })) /* CPU_FEATURE_USABLE evaluates to true if the feature is usable. */ -#define CPU_FEATURE_USABLE(name) \ - CPU_FEATURE_USABLE_P (__get_cpu_features (), name) -/* CPU_FEATURE_PREFER evaluates to true if we prefer the feature at - runtime. */ -#define CPU_FEATURE_PREFERRED(name) \ - CPU_FEATURE_PREFERRED_P(__get_cpu_features (), name) - -#define CPU_FEATURES_CPU_P(ptr, name) \ - CPU_FEATURE_CPU_P (ptr, name) -#define CPU_FEATURES_ARCH_P(ptr, name) \ - CPU_FEATURE_PREFERRED_P (ptr, name) -#define HAS_ARCH_FEATURE(name) \ - CPU_FEATURE_PREFERRED (name) +#define CPU_FEATURE_USABLE(name) \ + (__extension__ \ + ({ const struct cpu_features *__ptr = \ + __x86_get_cpu_features (COMMON_CPUID_INDEX_MAX); \ + __ptr && CPU_FEATURE_USABLE_P (__ptr, name); })) /* CPU features. */ @@ -787,71 +738,4 @@ extern const struct cpu_features *__get_cpu_features (void) /* EAX. */ #define reg_AVX512_BF16 eax -/* FEATURE_INDEX_2. */ -#define bit_arch_I586 (1u << 0) -#define bit_arch_I686 (1u << 1) -#define bit_arch_Fast_Rep_String (1u << 2) -#define bit_arch_Fast_Copy_Backward (1u << 3) -#define bit_arch_Fast_Unaligned_Load (1u << 4) -#define bit_arch_Fast_Unaligned_Copy (1u << 5) -#define bit_arch_Slow_BSF (1u << 6) -#define bit_arch_Slow_SSE4_2 (1u << 7) -#define bit_arch_AVX_Fast_Unaligned_Load (1u << 8) -#define bit_arch_Prefer_MAP_32BIT_EXEC (1u << 9) -#define bit_arch_Prefer_PMINUB_for_stringop (1u << 10) -#define bit_arch_Prefer_No_VZEROUPPER (1u << 11) -#define bit_arch_Prefer_ERMS (1u << 12) -#define bit_arch_Prefer_FSRM (1u << 13) -#define bit_arch_Prefer_No_AVX512 (1u << 14) -#define bit_arch_MathVec_Prefer_No_AVX512 (1u << 15) - -#define index_arch_Fast_Rep_String PREFERRED_FEATURE_INDEX_1 -#define index_arch_Fast_Copy_Backward PREFERRED_FEATURE_INDEX_1 -#define index_arch_Slow_BSF PREFERRED_FEATURE_INDEX_1 -#define index_arch_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 -#define index_arch_Prefer_PMINUB_for_stringop PREFERRED_FEATURE_INDEX_1 -#define index_arch_Fast_Unaligned_Copy PREFERRED_FEATURE_INDEX_1 -#define index_arch_I586 PREFERRED_FEATURE_INDEX_1 -#define index_arch_I686 PREFERRED_FEATURE_INDEX_1 -#define index_arch_Slow_SSE4_2 PREFERRED_FEATURE_INDEX_1 -#define index_arch_AVX_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 -#define index_arch_Prefer_MAP_32BIT_EXEC PREFERRED_FEATURE_INDEX_1 -#define index_arch_Prefer_No_VZEROUPPER PREFERRED_FEATURE_INDEX_1 -#define index_arch_Prefer_ERMS PREFERRED_FEATURE_INDEX_1 -#define index_arch_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 -#define index_arch_MathVec_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 -#define index_arch_Prefer_FSRM PREFERRED_FEATURE_INDEX_1 - -/* XCR0 Feature flags. */ -#define bit_XMM_state (1u << 1) -#define bit_YMM_state (1u << 2) -#define bit_Opmask_state (1u << 5) -#define bit_ZMM0_15_state (1u << 6) -#define bit_ZMM16_31_state (1u << 7) -#define bit_XTILECFG_state (1u << 17) -#define bit_XTILEDATA_state (1u << 18) - -# if defined (_LIBC) && !IS_IN (nonlib) -/* Unused for x86. */ -# define INIT_ARCH() -# define __get_cpu_features() (&GLRO(dl_x86_cpu_features)) -# endif - -#ifdef __x86_64__ -# define HAS_CPUID 1 -#elif (defined __i586__ || defined __pentium__ \ - || defined __geode__ || defined __k6__) -# define HAS_CPUID 1 -# define HAS_I586 1 -# define HAS_I686 HAS_ARCH_FEATURE (I686) -#elif defined __i486__ -# define HAS_CPUID 0 -# define HAS_I586 HAS_ARCH_FEATURE (I586) -# define HAS_I686 HAS_ARCH_FEATURE (I686) -#else -# define HAS_CPUID 1 -# define HAS_I586 1 -# define HAS_I686 1 -#endif - -#endif /* cpu_features_h */ +#endif /* _SYS_PLATFORM_X86_H */ diff --git a/sysdeps/x86/tst-cpu-features-cpuinfo.c b/sysdeps/x86/tst-cpu-features-cpuinfo.c new file mode 100644 index 0000000000..96277284d1 --- /dev/null +++ b/sysdeps/x86/tst-cpu-features-cpuinfo.c @@ -0,0 +1,250 @@ +/* Test CPU feature data against /proc/cpuinfo. + This file is part of the GNU C Library. + Copyright (C) 2012-2020 Free Software Foundation, Inc. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <sys/platform/x86.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +static char *cpu_flags; + +/* Search for flags in /proc/cpuinfo and store line + in cpu_flags. */ +void +get_cpuinfo (void) +{ + FILE *f; + char *line = NULL; + size_t len = 0; + ssize_t read; + + f = fopen ("/proc/cpuinfo", "r"); + if (f == NULL) + { + printf ("cannot open /proc/cpuinfo\n"); + exit (1); + } + + while ((read = getline (&line, &len, f)) != -1) + { + if (strncmp (line, "flags", 5) == 0) + { + cpu_flags = strdup (line); + break; + } + } + fclose (f); + free (line); +} + +int +check_proc (const char *proc_name, int flag, int usable, const char *name) +{ + int found = 0; + + printf ("Checking %s:\n", name); + if (!usable) + { + printf (" %s: insufficient usable info, skipped\n", name); + return 0; + } + printf (" %s: %d\n", name, flag); + if (strstr (cpu_flags, proc_name) != NULL) + found = 1; + printf (" cpuinfo (%s): %d\n", proc_name, found); + + if (found != flag) + printf (" *** failure ***\n"); + + return (found != flag); +} + +#define CHECK_PROC(str, name) \ + check_proc (#str, HAS_CPU_FEATURE (name), CPU_FEATURE_USABLE (name), \ + "HAS_CPU_FEATURE (" #name ")"); + +static int +do_test (int argc, char **argv) +{ + int fails = 0; + + get_cpuinfo (); + fails += CHECK_PROC (acpi, ACPI); + fails += CHECK_PROC (adx, ADX); + fails += CHECK_PROC (apic, APIC); + fails += CHECK_PROC (aes, AES); + fails += CHECK_PROC (amx_bf16, AMX_BF16); + fails += CHECK_PROC (amx_int8, AMX_INT8); + fails += CHECK_PROC (amx_tile, AMX_TILE); + fails += CHECK_PROC (arch_capabilities, ARCH_CAPABILITIES); + fails += CHECK_PROC (avx, AVX); + fails += CHECK_PROC (avx2, AVX2); + fails += CHECK_PROC (avx512_4fmaps, AVX512_4FMAPS); + fails += CHECK_PROC (avx512_4vnniw, AVX512_4VNNIW); + fails += CHECK_PROC (avx512_bf16, AVX512_BF16); + fails += CHECK_PROC (avx512_bitalg, AVX512_BITALG); + fails += CHECK_PROC (avx512ifma, AVX512_IFMA); + fails += CHECK_PROC (avx512_vbmi, AVX512_VBMI); + fails += CHECK_PROC (avx512_vbmi2, AVX512_VBMI2); + fails += CHECK_PROC (avx512_vnni, AVX512_VNNI); + fails += CHECK_PROC (avx512_vp2intersect, AVX512_VP2INTERSECT); + fails += CHECK_PROC (avx512_vpopcntdq, AVX512_VPOPCNTDQ); + fails += CHECK_PROC (avx512bw, AVX512BW); + fails += CHECK_PROC (avx512cd, AVX512CD); + fails += CHECK_PROC (avx512er, AVX512ER); + fails += CHECK_PROC (avx512dq, AVX512DQ); + fails += CHECK_PROC (avx512f, AVX512F); + fails += CHECK_PROC (avx512pf, AVX512PF); + fails += CHECK_PROC (avx512vl, AVX512VL); + fails += CHECK_PROC (bmi1, BMI1); + fails += CHECK_PROC (bmi2, BMI2); + fails += CHECK_PROC (cldemote, CLDEMOTE); + fails += CHECK_PROC (clflushopt, CLFLUSHOPT); + fails += CHECK_PROC (clflush, CLFSH); + fails += CHECK_PROC (clwb, CLWB); + fails += CHECK_PROC (cmov, CMOV); + fails += CHECK_PROC (cx16, CMPXCHG16B); + fails += CHECK_PROC (cnxt_id, CNXT_ID); + fails += CHECK_PROC (core_capabilities, CORE_CAPABILITIES); + fails += CHECK_PROC (cx8, CX8); + fails += CHECK_PROC (dca, DCA); + fails += CHECK_PROC (de, DE); + fails += CHECK_PROC (zero_fcs_fds, DEPR_FPU_CS_DS); + fails += CHECK_PROC (ds, DS); + fails += CHECK_PROC (ds_cpl, DS_CPL); + fails += CHECK_PROC (dtes64, DTES64); + fails += CHECK_PROC (est, EIST); + fails += CHECK_PROC (enqcmd, ENQCMD); + fails += CHECK_PROC (erms, ERMS); + fails += CHECK_PROC (f16c, F16C); + fails += CHECK_PROC (fma, FMA); + fails += CHECK_PROC (fma4, FMA4); + fails += CHECK_PROC (fpu, FPU); + fails += CHECK_PROC (fsgsbase, FSGSBASE); + fails += CHECK_PROC (fsrm, FSRM); + fails += CHECK_PROC (fxsr, FXSR); + fails += CHECK_PROC (gfni, GFNI); + fails += CHECK_PROC (hle, HLE); + fails += CHECK_PROC (ht, HTT); + fails += CHECK_PROC (hybrid, HYBRID); + fails += CHECK_PROC (ibrs, IBRS_IBPB); + fails += CHECK_PROC (ibt, IBT); + fails += CHECK_PROC (invariant_tsc, INVARIANT_TSC); + fails += CHECK_PROC (invpcid, INVPCID); + fails += CHECK_PROC (flush_l1d, L1D_FLUSH); + fails += CHECK_PROC (lahf_lm, LAHF64_SAHF64); + fails += CHECK_PROC (lm, LM); + fails += CHECK_PROC (lwp, LWP); + fails += CHECK_PROC (abm, LZCNT); + fails += CHECK_PROC (mca, MCA); + fails += CHECK_PROC (mce, MCE); + fails += CHECK_PROC (md_clear, MD_CLEAR); + fails += CHECK_PROC (mmx, MMX); + fails += CHECK_PROC (monitor, MONITOR); + fails += CHECK_PROC (movbe, MOVBE); + fails += CHECK_PROC (movdiri, MOVDIRI); + fails += CHECK_PROC (movdir64b, MOVDIR64B); + fails += CHECK_PROC (mpx, MPX); + fails += CHECK_PROC (msr, MSR); + fails += CHECK_PROC (mtrr, MTRR); + fails += CHECK_PROC (nx, NX); + fails += CHECK_PROC (ospke, OSPKE); +#if 0 + /* NB: /proc/cpuinfo doesn't report this feature. */ + fails += CHECK_PROC (osxsave, OSXSAVE); +#endif + fails += CHECK_PROC (pae, PAE); + fails += CHECK_PROC (pdpe1gb, PAGE1GB); + fails += CHECK_PROC (pat, PAT); + fails += CHECK_PROC (pbe, PBE); + fails += CHECK_PROC (pcid, PCID); + fails += CHECK_PROC (pclmulqdq, PCLMULQDQ); + fails += CHECK_PROC (pconfig, PCONFIG); + fails += CHECK_PROC (pdcm, PDCM); + fails += CHECK_PROC (pge, PGE); + fails += CHECK_PROC (pks, PKS); + fails += CHECK_PROC (pku, PKU); + fails += CHECK_PROC (popcnt, POPCNT); + fails += CHECK_PROC (3dnowprefetch, PREFETCHW); + fails += CHECK_PROC (prefetchwt1, PREFETCHWT1); + fails += CHECK_PROC (pse, PSE); + fails += CHECK_PROC (pse36, PSE_36); + fails += CHECK_PROC (psn, PSN); + fails += CHECK_PROC (rdpid, RDPID); + fails += CHECK_PROC (rdrand, RDRAND); + fails += CHECK_PROC (rdseed, RDSEED); + fails += CHECK_PROC (rdt_a, RDT_A); + fails += CHECK_PROC (cqm, RDT_M); + fails += CHECK_PROC (rdtscp, RDTSCP); + fails += CHECK_PROC (rtm, RTM); + fails += CHECK_PROC (sdbg, SDBG); + fails += CHECK_PROC (sep, SEP); + fails += CHECK_PROC (serialize, SERIALIZE); + fails += CHECK_PROC (sgx, SGX); + fails += CHECK_PROC (sgx_lc, SGX_LC); + fails += CHECK_PROC (sha_ni, SHA); + fails += CHECK_PROC (shstk, SHSTK); + fails += CHECK_PROC (smap, SMAP); + fails += CHECK_PROC (smep, SMEP); + fails += CHECK_PROC (smx, SMX); + fails += CHECK_PROC (ss, SS); + fails += CHECK_PROC (ssbd, SSBD); + fails += CHECK_PROC (sse, SSE); + fails += CHECK_PROC (sse2, SSE2); + fails += CHECK_PROC (sse3, SSE3); + fails += CHECK_PROC (sse4_1, SSE4_1); + fails += CHECK_PROC (sse4_2, SSE4_2); + fails += CHECK_PROC (sse4a, SSE4A); + fails += CHECK_PROC (ssse3, SSSE3); + fails += CHECK_PROC (stibp, STIBP); + fails += CHECK_PROC (svm, SVM); +#ifdef __x86_64__ + /* NB: SYSCALL_SYSRET is 64-bit only. */ + fails += CHECK_PROC (syscall, SYSCALL_SYSRET); +#endif + fails += CHECK_PROC (tbm, TBM); + fails += CHECK_PROC (tm, TM); + fails += CHECK_PROC (tm2, TM2); + fails += CHECK_PROC (intel_pt, TRACE); + fails += CHECK_PROC (tsc, TSC); + fails += CHECK_PROC (tsc_adjust, TSC_ADJUST); + fails += CHECK_PROC (tsc_deadline, TSC_DEADLINE); + fails += CHECK_PROC (tsxldtrk, TSXLDTRK); + fails += CHECK_PROC (umip, UMIP); + fails += CHECK_PROC (vaes, VAES); + fails += CHECK_PROC (vme, VME); + fails += CHECK_PROC (vmx, VMX); + fails += CHECK_PROC (vpclmulqdq, VPCLMULQDQ); + fails += CHECK_PROC (waitpkg, WAITPKG); + fails += CHECK_PROC (wbnoinvd, WBNOINVD); + fails += CHECK_PROC (x2apic, X2APIC); + fails += CHECK_PROC (xfd, XFD); + fails += CHECK_PROC (xgetbv1, XGETBV_ECX_1); + fails += CHECK_PROC (xop, XOP); + fails += CHECK_PROC (xsave, XSAVE); + fails += CHECK_PROC (xsavec, XSAVEC); + fails += CHECK_PROC (xsaveopt, XSAVEOPT); + fails += CHECK_PROC (xsaves, XSAVES); + fails += CHECK_PROC (xtpr, XTPRUPDCTRL); + + printf ("%d differences between /proc/cpuinfo and glibc code.\n", fails); + + return (fails != 0); +} + +#include "../../../test-skeleton.c" diff --git a/sysdeps/x86/tst-cpu-features-supports.c b/sysdeps/x86/tst-cpu-features-supports.c new file mode 100644 index 0000000000..bf881b531f --- /dev/null +++ b/sysdeps/x86/tst-cpu-features-supports.c @@ -0,0 +1,192 @@ +/* Test CPU feature data against __builtin_cpu_supports. + This file is part of the GNU C Library. + Copyright (C) 2020 Free Software Foundation, Inc. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <sys/platform/x86.h> +#include <stdio.h> + +int +check_supports (int supports, int usable, const char *supports_name, + const char *name) +{ + printf ("Checking %s:\n", name); + printf (" %s: %d\n", name, usable); + printf (" __builtin_cpu_supports (%s): %d\n", + supports_name, supports); + + if ((supports != 0) != (usable != 0)) + { + printf (" *** failure ***\n"); + return 1; + } + + return 0; +} + +#define CHECK_SUPPORTS(str, name) \ + check_supports (__builtin_cpu_supports (#str), \ + CPU_FEATURE_USABLE (name), \ + #str, "HAS_CPU_FEATURE (" #name ")"); + +static int +do_test (int argc, char **argv) +{ + int fails = 0; + +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (adx, ADX); +#endif +#if __GNUC_PREREQ (6, 0) + fails += CHECK_SUPPORTS (aes, AES); +#endif +#if __GNUC_PREREQ (11, 1) + fails += CHECK_SUPPORTS (amx_bf16, AMX_BF16); + fails += CHECK_SUPPORTS (amx_int8, AMX_INT8); + fails += CHECK_SUPPORTS (amx_tile, AMX_TILE); +#endif + fails += CHECK_SUPPORTS (avx, AVX); + fails += CHECK_SUPPORTS (avx2, AVX2); +#if __GNUC_PREREQ (7, 0) + fails += CHECK_SUPPORTS (avx5124fmaps, AVX512_4FMAPS); + fails += CHECK_SUPPORTS (avx5124vnniw, AVX512_4VNNIW); +#endif +#if __GNUC_PREREQ (10, 0) + fails += CHECK_SUPPORTS (avx512bf16, AVX512_BF16); +#endif +#if __GNUC_PREREQ (8, 0) + fails += CHECK_SUPPORTS (avx512bitalg, AVX512_BITALG); +#endif +#if __GNUC_PREREQ (6, 0) + fails += CHECK_SUPPORTS (avx512ifma, AVX512_IFMA); + fails += CHECK_SUPPORTS (avx512vbmi, AVX512_VBMI); +#endif +#if __GNUC_PREREQ (8, 0) + fails += CHECK_SUPPORTS (avx512vbmi2, AVX512_VBMI2); + fails += CHECK_SUPPORTS (avx512vnni, AVX512_VNNI); +#endif +#if __GNUC_PREREQ (10, 0) + fails += CHECK_SUPPORTS (avx512vp2intersect, AVX512_VP2INTERSECT); +#endif +#if __GNUC_PREREQ (7, 0) + fails += CHECK_SUPPORTS (avx512vpopcntdq, AVX512_VPOPCNTDQ); +#endif +#if __GNUC_PREREQ (6, 0) + fails += CHECK_SUPPORTS (avx512bw, AVX512BW); + fails += CHECK_SUPPORTS (avx512cd, AVX512CD); + fails += CHECK_SUPPORTS (avx512er, AVX512ER); + fails += CHECK_SUPPORTS (avx512dq, AVX512DQ); +#endif +#if __GNUC_PREREQ (5, 0) + fails += CHECK_SUPPORTS (avx512f, AVX512F); +#endif +#if __GNUC_PREREQ (6, 0) + fails += CHECK_SUPPORTS (avx512pf, AVX512PF); + fails += CHECK_SUPPORTS (avx512vl, AVX512VL); +#endif +#if __GNUC_PREREQ (5, 0) + fails += CHECK_SUPPORTS (bmi, BMI1); + fails += CHECK_SUPPORTS (bmi2, BMI2); +#endif +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (cldemote, CLDEMOTE); + fails += CHECK_SUPPORTS (clflushopt, CLFLUSHOPT); + fails += CHECK_SUPPORTS (clwb, CLWB); +#endif + fails += CHECK_SUPPORTS (cmov, CMOV); +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (cmpxchg16b, CMPXCHG16B); + fails += CHECK_SUPPORTS (cmpxchg8b, CX8); + fails += CHECK_SUPPORTS (enqcmd, ENQCMD); + fails += CHECK_SUPPORTS (f16c, F16C); +#endif +#if __GNUC_PREREQ (4, 9) + fails += CHECK_SUPPORTS (fma, FMA); + fails += CHECK_SUPPORTS (fma4, FMA4); +#endif +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (fsgsbase, FSGSBASE); + fails += CHECK_SUPPORTS (fxsave, FXSR); +#endif +#if __GNUC_PREREQ (8, 0) + fails += CHECK_SUPPORTS (gfni, GFNI); +#endif +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (hle, HLE); + fails += CHECK_SUPPORTS (ibt, IBT); + fails += CHECK_SUPPORTS (lahf_lm, LAHF64_SAHF64); + fails += CHECK_SUPPORTS (lm, LM); + fails += CHECK_SUPPORTS (lwp, LWP); + fails += CHECK_SUPPORTS (lzcnt, LZCNT); +#endif + fails += CHECK_SUPPORTS (mmx, MMX); +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (movbe, MOVBE); + fails += CHECK_SUPPORTS (movdiri, MOVDIRI); + fails += CHECK_SUPPORTS (movdir64b, MOVDIR64B); + fails += CHECK_SUPPORTS (osxsave, OSXSAVE); + fails += CHECK_SUPPORTS (pconfig, PCONFIG); + fails += CHECK_SUPPORTS (pku, PKU); +#endif + fails += CHECK_SUPPORTS (popcnt, POPCNT); +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (prefetchwt1, PREFETCHWT1); + fails += CHECK_SUPPORTS (rdpid, RDPID); + fails += CHECK_SUPPORTS (rdrnd, RDRAND); + fails += CHECK_SUPPORTS (rdseed, RDSEED); + fails += CHECK_SUPPORTS (rtm, RTM); + fails += CHECK_SUPPORTS (serialize, SERIALIZE); + fails += CHECK_SUPPORTS (sha, SHA); + fails += CHECK_SUPPORTS (shstk, SHSTK); +#endif + fails += CHECK_SUPPORTS (sse, SSE); + fails += CHECK_SUPPORTS (sse2, SSE2); + fails += CHECK_SUPPORTS (sse3, SSE3); + fails += CHECK_SUPPORTS (sse4.1, SSE4_1); + fails += CHECK_SUPPORTS (sse4.2, SSE4_2); +#if __GNUC_PREREQ (4, 9) + fails += CHECK_SUPPORTS (sse4a, SSE4A); +#endif + fails += CHECK_SUPPORTS (ssse3, SSSE3); +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (tbm, TBM); + fails += CHECK_SUPPORTS (tsxldtrk, TSXLDTRK); + fails += CHECK_SUPPORTS (vaes, VAES); +#endif +#if __GNUC_PREREQ (8, 0) + fails += CHECK_SUPPORTS (vpclmulqdq, VPCLMULQDQ); +#endif +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (waitpkg, WAITPKG); + fails += CHECK_SUPPORTS (wbnoinvd, WBNOINVD); +#endif +#if __GNUC_PREREQ (4, 9) + fails += CHECK_SUPPORTS (xop, XOP); +#endif +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (xsave, XSAVE); + fails += CHECK_SUPPORTS (xsavec, XSAVEC); + fails += CHECK_SUPPORTS (xsaveopt, XSAVEOPT); + fails += CHECK_SUPPORTS (xsaves, XSAVES); +#endif + + printf ("%d differences between __builtin_cpu_supports and glibc code.\n", + fails); + + return (fails != 0); +} + +#include "../../../test-skeleton.c" diff --git a/sysdeps/x86/tst-get-cpu-features.c b/sysdeps/x86/tst-get-cpu-features.c index 6bfdef0829..3447d17e23 100644 --- a/sysdeps/x86/tst-get-cpu-features.c +++ b/sysdeps/x86/tst-get-cpu-features.c @@ -1,4 +1,4 @@ -/* Test case for x86 __get_cpu_features interface +/* Test case for __x86_get_cpu_features interface Copyright (C) 2015-2020 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -18,7 +18,7 @@ #include <stdlib.h> #include <stdio.h> -#include <cpu-features.h> +#include <sys/platform/x86.h> #include <support/check.h> #define CHECK_CPU_FEATURE(name) \ @@ -45,7 +45,7 @@ static const char * const cpu_kinds[] = static int do_test (void) { - const struct cpu_features *cpu_features = __get_cpu_features (); + const struct cpu_features *cpu_features = __x86_get_cpu_features (0); switch (cpu_features->basic.kind) { diff --git a/sysdeps/x86_64/fpu/math-tests-arch.h b/sysdeps/x86_64/fpu/math-tests-arch.h index 33ea763de2..cc3c2b0c11 100644 --- a/sysdeps/x86_64/fpu/math-tests-arch.h +++ b/sysdeps/x86_64/fpu/math-tests-arch.h @@ -16,7 +16,7 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ -#include <cpu-features.h> +#include <sys/platform/x86.h> #if defined REQUIRE_AVX diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile index 395e432c09..9477538af4 100644 --- a/sysdeps/x86_64/multiarch/Makefile +++ b/sysdeps/x86_64/multiarch/Makefile @@ -1,7 +1,3 @@ -ifeq ($(subdir),csu) -tests += test-multiarch -endif - ifeq ($(subdir),string) sysdep_routines += strncat-c stpncpy-c strncpy-c \ diff --git a/sysdeps/x86_64/multiarch/test-multiarch.c b/sysdeps/x86_64/multiarch/test-multiarch.c deleted file mode 100644 index 2782803e73..0000000000 --- a/sysdeps/x86_64/multiarch/test-multiarch.c +++ /dev/null @@ -1,96 +0,0 @@ -/* Test CPU feature data. - This file is part of the GNU C Library. - Copyright (C) 2012-2020 Free Software Foundation, Inc. - - 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 - <https://www.gnu.org/licenses/>. */ - -#include <cpu-features.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -static char *cpu_flags; - -/* Search for flags in /proc/cpuinfo and store line - in cpu_flags. */ -void -get_cpuinfo (void) -{ - FILE *f; - char *line = NULL; - size_t len = 0; - ssize_t read; - - f = fopen ("/proc/cpuinfo", "r"); - if (f == NULL) - { - printf ("cannot open /proc/cpuinfo\n"); - exit (1); - } - - while ((read = getline (&line, &len, f)) != -1) - { - if (strncmp (line, "flags", 5) == 0) - { - cpu_flags = strdup (line); - break; - } - } - fclose (f); - free (line); -} - -int -check_proc (const char *proc_name, int flag, const char *name) -{ - int found = 0; - - printf ("Checking %s:\n", name); - printf (" init-arch %d\n", flag); - if (strstr (cpu_flags, proc_name) != NULL) - found = 1; - printf (" cpuinfo (%s) %d\n", proc_name, found); - - if (found != flag) - printf (" *** failure ***\n"); - - return (found != flag); -} - -static int -do_test (int argc, char **argv) -{ - int fails; - - get_cpuinfo (); - fails = check_proc ("avx", CPU_FEATURE_USABLE (AVX), - "CPU_FEATURE_USABLE (AVX)"); - fails += check_proc ("fma4", CPU_FEATURE_USABLE (FMA4), - "CPU_FEATURE_USABLE (FMA4)"); - fails += check_proc ("sse4_2", CPU_FEATURE_USABLE (SSE4_2), - "CPU_FEATURE_USABLE (SSE4_2)"); - fails += check_proc ("sse4_1", CPU_FEATURE_USABLE (SSE4_1) - , "CPU_FEATURE_USABLE (SSE4_1)"); - fails += check_proc ("ssse3", CPU_FEATURE_USABLE (SSSE3), - "CPU_FEATURE_USABLE (SSSE3)"); - fails += check_proc ("popcnt", CPU_FEATURE_USABLE (POPCNT), - "CPU_FEATURE_USABLE (POPCNT)"); - - printf ("%d differences between /proc/cpuinfo and glibc code.\n", fails); - - return (fails != 0); -} - -#include "../../../test-skeleton.c" -- 2.26.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* PING: V8 [PATCH 2/2] x86: Install <sys/platform/x86.h> [BZ #26124] 2020-08-05 23:01 ` V8 [PATCH 2/2] x86: Install <sys/platform/x86.h> [BZ #26124] H.J. Lu @ 2020-08-12 14:00 ` H.J. Lu 2020-08-19 12:52 ` PING^2: " H.J. Lu 0 siblings, 1 reply; 7+ messages in thread From: H.J. Lu @ 2020-08-12 14:00 UTC (permalink / raw) To: GNU C Library, Carlos O'Donell, Florian Weimer On Wed, Aug 5, 2020 at 4:01 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > Install <sys/platform/x86.h> so that programmers can do > > #if __has_include(<sys/platform/x86.h>) > #include <sys/platform/x86.h> > #endif > ... > > if (CPU_FEATURE_USABLE (SSE2)) > ... > if (CPU_FEATURE_USABLE (AVX2)) > ... > > <sys/platform/x86.h> exports only: > > enum > { > COMMON_CPUID_INDEX_1 = 0, > COMMON_CPUID_INDEX_7, > COMMON_CPUID_INDEX_80000001, > COMMON_CPUID_INDEX_D_ECX_1, > COMMON_CPUID_INDEX_80000007, > COMMON_CPUID_INDEX_80000008, > COMMON_CPUID_INDEX_7_ECX_1, > /* Keep the following line at the end. */ > COMMON_CPUID_INDEX_MAX > }; > > struct cpuid_features > { > struct cpuid_registers cpuid; > struct cpuid_registers usable; > }; > > struct cpu_features > { > struct cpu_features_basic basic; > struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; > }; > > /* Get a pointer to the CPU features structure. */ > extern const struct cpu_features *__x86_get_cpu_features > (unsigned int max) __attribute__ ((const)); > > Since all feature checks are done through macros, programs compiled with > a newer <sys/platform/x86.h> are compatible with the older glibc binaries > as long as the layout of struct cpu_features is identical. The features > array can be expanded with backward binary compatibility for both .o and > .so files. When COMMON_CPUID_INDEX_MAX is increased to support new > processor features, __x86_get_cpu_features in the older glibc binaries > returns NULL and HAS_CPU_FEATURE/CPU_FEATURE_USABLE return false on the > new processor feature. No new symbol version is neeeded. > > Both CPU_FEATURE_USABLE and HAS_CPU_FEATURE are provided. HAS_CPU_FEATURE > can be used to identify processor features. > > Note: Although GCC has __builtin_cpu_supports, it only supports a subset > of <sys/platform/x86.h> and it is equivalent to CPU_FEATURE_USABLE. It > doesn't support HAS_CPU_FEATURE. > --- > NEWS | 2 +- > manual/platform.texi | 517 ++++++++++++++++++ > sysdeps/i386/i686/multiarch/Makefile | 4 - > sysdeps/i386/i686/multiarch/test-multiarch.c | 1 - > sysdeps/unix/sysv/linux/i386/ld.abilist | 1 + > sysdeps/unix/sysv/linux/x86_64/64/ld.abilist | 1 + > sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist | 1 + > sysdeps/x86/Makefile | 4 +- > sysdeps/x86/Versions | 4 +- > sysdeps/x86/dl-get-cpu-features.c | 6 +- > sysdeps/x86/include/cpu-features.h | 183 +++++++ > .../{cpu-features.h => sys/platform/x86.h} | 150 +---- > sysdeps/x86/tst-cpu-features-cpuinfo.c | 250 +++++++++ > sysdeps/x86/tst-cpu-features-supports.c | 192 +++++++ > sysdeps/x86/tst-get-cpu-features.c | 6 +- > sysdeps/x86_64/fpu/math-tests-arch.h | 2 +- > sysdeps/x86_64/multiarch/Makefile | 4 - > sysdeps/x86_64/multiarch/test-multiarch.c | 96 ---- > 18 files changed, 1176 insertions(+), 248 deletions(-) > delete mode 100644 sysdeps/i386/i686/multiarch/test-multiarch.c > create mode 100644 sysdeps/x86/include/cpu-features.h > rename sysdeps/x86/{cpu-features.h => sys/platform/x86.h} (81%) > create mode 100644 sysdeps/x86/tst-cpu-features-cpuinfo.c > create mode 100644 sysdeps/x86/tst-cpu-features-supports.c > delete mode 100644 sysdeps/x86_64/multiarch/test-multiarch.c > > diff --git a/NEWS b/NEWS > index 2937adc3f3..d19551c132 100644 > --- a/NEWS > +++ b/NEWS > @@ -9,7 +9,7 @@ Version 2.33 > > Major new features: > > - [Add new features here] > +* Add <sys/platform/x86.h> to provide query macros for x86 CPU features. > > Deprecated and removed features, and other changes affecting compatibility: > > diff --git a/manual/platform.texi b/manual/platform.texi > index 504addc956..2c145acdc3 100644 > --- a/manual/platform.texi > +++ b/manual/platform.texi > @@ -7,6 +7,7 @@ > @menu > * PowerPC:: Facilities Specific to the PowerPC Architecture > * RISC-V:: Facilities Specific to the RISC-V Architecture > +* X86:: Facilities Specific to the X86 Architecture > @end menu > > @node PowerPC > @@ -134,3 +135,519 @@ all threads in the current process. Setting the > ordering on only the current thread is necessary. All other flag bits are > reserved. > @end deftypefun > + > +@node X86 > +@appendixsec X86-specific Facilities > + > +Facilities specific to X86 that are not specific to a particular > +operating system are declared in @file{sys/platform/x86.h}. > + > +@deftypefun {const struct cpu_features *} __x86_get_cpu_features (unsigned int @var{max}) > +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} > +Return a pointer to x86 CPU feature structure used by query macros for x86 > +CPU features. If @var{max} exceeds @code{COMMON_CPUID_INDEX_MAX} which > +is the limit of the CPUID leaves supported by @Theglibc{}, the function > +returns @code{NULL}, indicating that the queried processor feature is > +unsupported by @Theglibc{} run-time. > +@end deftypefun > + > +@deftypefn Macro int HAS_CPU_FEATURE (@var{name}) > +This macro returns a nonzero value (true) if the processor has the feature > +@var{name}. > +@end deftypefn > + > +@deftypefn Macro int CPU_FEATURE_USABLE (@var{name}) > +This macro returns a nonzero value (true) if the processor has the feature > +@var{name} and the feature is supported by the operating system. > +@end deftypefn > + > +The supported processor features are: > + > +@itemize @bullet > + > +@item > +@code{ACPI} -- Thermal Monitor and Software Controlled Clock Facilities. > + > +@item > +@code{ADX} -- ADX instruction extensions. > + > +@item > +@code{APIC} -- APIC On-Chip. > + > +@item > +@code{AES} -- The AES instruction extensions. > + > +@item > +@code{AMX_BF16} -- Tile computational operations on bfloat16 numbers. > + > +@item > +@code{AMX_INT8} -- Tile computational operations on 8-bit numbers. > + > +@item > +@code{AMX_TILE} -- Tile architecture. > + > +@item > +@code{ARCH_CAPABILITIES} -- IA32_ARCH_CAPABILITIES MSR. > + > +@item > +@code{AVX} -- The AVX instruction extensions. > + > +@item > +@code{AVX2} -- The AVX2 instruction extensions. > + > +@item > +@code{AVX512_4FMAPS} -- The AVX512_4FMAPS instruction extensions. > + > +@item > +@code{AVX512_4VNNIW} -- The AVX512_4VNNIW instruction extensions. > + > +@item > +@code{AVX512_BF16} -- The AVX512_BF16 instruction extensions. > + > +@item > +@code{AVX512_BITALG} -- The AVX512_BITALG instruction extensions. > + > +@item > +@code{AVX512_IFMA} -- The AVX512_IFMA instruction extensions. > + > +@item > +@code{AVX512_VBMI} -- The AVX512_VBMI instruction extensions. > + > +@item > +@code{AVX512_VBMI2} -- The AVX512_VBMI2 instruction extensions. > + > +@item > +@code{AVX512_VNNI} -- The AVX512_VNNI instruction extensions. > + > +@item > +@code{AVX512_VP2INTERSECT} -- The AVX512_VP2INTERSECT instruction > +extensions. > + > +@item > +@code{AVX512_VPOPCNTDQ} -- The AVX512_VPOPCNTDQ instruction extensions. > + > +@item > +@code{AVX512BW} -- The AVX512BW instruction extensions. > + > +@item > +@code{AVX512CD} -- The AVX512CD instruction extensions. > + > +@item > +@code{AVX512ER} -- The AVX512ER instruction extensions. > + > +@item > +@code{AVX512DQ} -- The AVX512DQ instruction extensions. > + > +@item > +@code{AVX512F} -- The AVX512F instruction extensions. > + > +@item > +@code{AVX512PF} -- The AVX512PF instruction extensions. > + > +@item > +@code{AVX512VL} -- The AVX512VL instruction extensions. > + > +@item > +@code{BMI1} -- BMI1 instructions. > + > +@item > +@code{BMI2} -- BMI2 instructions. > + > +@item > +@code{CLDEMOTE} -- CLDEMOTE instruction. > + > +@item > +@code{CLFLUSHOPT} -- CLFLUSHOPT instruction. > + > +@item > +@code{CLFSH} -- CLFLUSH instruction. > + > +@item > +@code{CLWB} -- CLWB instruction. > + > +@item > +@code{CMOV} -- Conditional Move instructions. > + > +@item > +@code{CMPXCHG16B} -- CMPXCHG16B instruction. > + > +@item > +@code{CNXT_ID} -- L1 Context ID. > + > +@item > +@code{CORE_CAPABILITIES} -- IA32_CORE_CAPABILITIES MSR. > + > +@item > +@code{CX8} -- CMPXCHG8B instruction. > + > +@item > +@code{DCA} -- Data prefetch from a memory mapped device. > + > +@item > +@code{DE} -- Debugging Extensions. > + > +@item > +@code{DEPR_FPU_CS_DS} -- Deprecates FPU CS and FPU DS values. > + > +@item > +@code{DS} -- Debug Store. > + > +@item > +@code{DS_CPL} -- CPL Qualified Debug Store. > + > +@item > +@code{DTES64} -- 64-bit DS Area. > + > +@item > +@code{EIST} -- Enhanced Intel SpeedStep technology. > + > +@item > +@code{ENQCMD} -- Enqueue Stores instructions. > + > +@item > +@code{ERMS} -- Enhanced REP MOVSB/STOSB. > + > +@item > +@code{F16C} -- 16-bit floating-point conversion instructions. > + > +@item > +@code{FMA} -- FMA extensions using YMM state. > + > +@item > +@code{FMA4} -- FMA4 instruction extensions. > + > +@item > +@code{FPU} -- X87 Floating Point Unit On-Chip. > + > +@item > +@code{FSGSBASE} -- RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE instructions. > + > +@item > +@code{FSRM} -- Fast Short REP MOV. > + > +@item > +@code{FXSR} -- FXSAVE and FXRSTOR instructions. > + > +@item > +@code{GFNI} -- GFNI instruction extensions. > + > +@item > +@code{HLE} -- HLE instruction extensions. > + > +@item > +@code{HTT} -- Max APIC IDs reserved field is Valid. > + > +@item > +@code{HYBRID} -- Hybrid processor. > + > +@item > +@code{IBRS_IBPB} -- Indirect branch restricted speculation (IBRS) and > +the indirect branch predictor barrier (IBPB). > + > +@item > +@code{IBT} -- Intel Indirect Branch Tracking instruction extensions. > + > +@item > +@code{INVARIANT_TSC} -- Invariant TSC. > + > +@item > +@code{INVPCID} -- INVPCID instruction. > + > +@item > +@code{L1D_FLUSH} -- IA32_FLUSH_CMD MSR. > + > +@item > +@code{LAHF64_SAHF64} -- LAHF/SAHF available in 64-bit mode. > + > +@item > +@code{LM} -- Long mode. > + > +@item > +@code{LWP} -- Lightweight profiling. > + > +@item > +@code{LZCNT} -- LZCNT instruction. > + > +@item > +@code{MCA} -- Machine Check Architecture. > + > +@item > +@code{MCE} -- Machine Check Exception. > + > +@item > +@code{MD_CLEAR} -- MD_CLEAR. > + > +@item > +@code{MMX} -- Intel MMX Technology. > + > +@item > +@code{MONITOR} -- MONITOR/MWAIT instructions. > + > +@item > +@code{MOVBE} -- MOVBE instruction. > + > +@item > +@code{MOVDIRI} -- MOVDIRI instruction. > + > +@item > +@code{MOVDIR64B} -- MOVDIR64B instruction. > + > +@item > +@code{MPX} -- Intel Memory Protection Extensions. > + > +@item > +@code{MSR} -- Model Specific Registers RDMSR and WRMSR instructions. > + > +@item > +@code{MTRR} -- Memory Type Range Registers. > + > +@item > +@code{NX} -- No-execute page protection. > + > +@item > +@code{OSPKE} -- OS has set CR4.PKE to enable protection keys. > + > +@item > +@code{OSXSAVE} -- The OS has set CR4.OSXSAVE[bit 18] to enable > +XSETBV/XGETBV instructions to access XCR0 and to support processor > +extended state management using XSAVE/XRSTOR. > + > +@item > +@code{PAE} -- Physical Address Extension. > + > +@item > +@code{PAGE1GB} -- 1-GByte page. > + > +@item > +@code{PAT} -- Page Attribute Table. > + > +@item > +@code{PBE} -- Pending Break Enable. > + > +@item > +@code{PCID} -- Process-context identifiers. > + > +@item > +@code{PCLMULQDQ} -- PCLMULQDQ instruction. > + > +@item > +@code{PCONFIG} -- PCONFIG instruction. > + > +@item > +@code{PDCM} -- Perfmon and Debug Capability. > + > +@item > +@code{PGE} -- Page Global Bit. > + > +@item > +@code{PKS} -- Protection keys for supervisor-mode pages. > + > +@item > +@code{PKU} -- Protection keys for user-mode pages. > + > +@item > +@code{POPCNT} -- POPCNT instruction. > + > +@item > +@code{PREFETCHW} -- PREFETCHW instruction. > + > +@item > +@code{PREFETCHWT1} -- PREFETCHWT1 instruction. > + > +@item > +@code{PSE} -- Page Size Extension. > + > +@item > +@code{PSE_36} -- 36-Bit Page Size Extension. > + > +@item > +@code{PSN} -- Processor Serial Number. > + > +@item > +@code{RDPID} -- RDPID instruction. > + > +@item > +@code{RDRAND} -- RDRAND instruction. > + > +@item > +@code{RDSEED} -- RDSEED instruction. > + > +@item > +@code{RDT_A} -- Intel Resource Director Technology (Intel RDT) Allocation > +capability. > + > +@item > +@code{RDT_M} -- Intel Resource Director Technology (Intel RDT) Monitoring > +capability. > + > +@item > +@code{RDTSCP} -- RDTSCP instruction. > + > +@item > +@code{RTM} -- RTM instruction extensions. > + > +@item > +@code{SDBG} -- IA32_DEBUG_INTERFACE MSR for silicon debug. > + > +@item > +@code{SEP} -- SYSENTER and SYSEXIT instructions. > + > +@item > +@code{SERIALIZE} -- SERIALIZE instruction. > + > +@item > +@code{SGX} -- Intel Software Guard Extensions. > + > +@item > +@code{SGX_LC} -- SGX Launch Configuration. > + > +@item > +@code{SHA} -- SHA instruction extensions. > + > +@item > +@code{SHSTK} -- Intel Shadow Stack instruction extensions. > + > +@item > +@code{SMAP} -- Supervisor-Mode Access Prevention. > + > +@item > +@code{SMEP} -- Supervisor-Mode Execution Prevention. > + > +@item > +@code{SMX} -- Safer Mode Extensions. > + > +@item > +@code{SS} -- Self Snoop. > + > +@item > +@code{SSBD} -- Speculative Store Bypass Disable (SSBD). > + > +@item > +@code{SSE} -- Streaming SIMD Extensions. > + > +@item > +@code{SSE2} -- Streaming SIMD Extensions 2. > + > +@item > +@code{SSE3} -- Streaming SIMD Extensions 3. > + > +@item > +@code{SSE4_1} -- Streaming SIMD Extensions 4.1. > + > +@item > +@code{SSE4_2} -- Streaming SIMD Extensions 4.2. > + > +@item > +@code{SSE4A} -- SSE4A instruction extensions. > + > +@item > +@code{SSSE3} -- Supplemental Streaming SIMD Extensions 3. > + > +@item > +@code{STIBP} -- Single thread indirect branch predictors (STIBP). > + > +@item > +@code{SVM} -- Secure Virtual Machine. > + > +@item > +@code{SYSCALL_SYSRET} -- SYSCALL/SYSRET instructions. > + > +@item > +@code{TBM} -- Trailing bit manipulation instructions. > + > +@item > +@code{TM} -- Thermal Monitor. > + > +@item > +@code{TM2} -- Thermal Monitor 2. > + > +@item > +@code{TRACE} -- Intel Processor Trace. > + > +@item > +@code{TSC} -- Time Stamp Counter. RDTSC instruction. > + > +@item > +@code{TSC_ADJUST} -- IA32_TSC_ADJUST MSR. > + > +@item > +@code{TSC_DEADLINE} -- Local APIC timer supports one-shot operation > +using a TSC deadline value. > + > +@item > +@code{TSXLDTRK} -- TSXLDTRK instructions. > + > +@item > +@code{UMIP} -- User-mode instruction prevention. > + > +@item > +@code{VAES} -- VAES instruction extensions. > + > +@item > +@code{VME} -- Virtual 8086 Mode Enhancements. > + > +@item > +@code{VMX} -- Virtual Machine Extensions. > + > +@item > +@code{VPCLMULQDQ} -- VPCLMULQDQ instruction. > + > +@item > +@code{WAITPKG} -- WAITPKG instruction extensions. > + > +@item > +@code{WBNOINVD} -- WBINVD/WBNOINVD instructions. > + > +@item > +@code{X2APIC} -- x2APIC. > + > +@item > +@code{XFD} -- Extended Feature Disable (XFD). > + > +@item > +@code{XGETBV_ECX_1} -- XGETBV with ECX = 1. > + > +@item > +@code{XOP} -- XOP instruction extensions. > + > +@item > +@code{XSAVE} -- The XSAVE/XRSTOR processor extended states feature, the > +XSETBV/XGETBV instructions, and XCR0. > + > +@item > +@code{XSAVEC} -- XSAVEC instruction. > + > +@item > +@code{XSAVEOPT} -- XSAVEOPT instruction. > + > +@item > +@code{XSAVES} -- XSAVES/XRSTORS instructions. > + > +@item > +@code{XTPRUPDCTRL} -- xTPR Update Control. > + > +@end itemize > + > +You could query if a processor supports @code{AVX} with: > + > +@smallexample > +#include <sys/platform/x86.h> > + > +int > +support_avx (void) > +@{ > + return HAS_CPU_FEATURE (AVX); > +@} > +@end smallexample > + > +and if @code{AVX} is usable with: > + > +@smallexample > +#include <sys/platform/x86.h> > + > +int > +usable_avx (void) > +@{ > + return CPU_FEATURE_USABLE (AVX); > +@} > +@end smallexample > diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile > index bf75a9947f..c4897922d7 100644 > --- a/sysdeps/i386/i686/multiarch/Makefile > +++ b/sysdeps/i386/i686/multiarch/Makefile > @@ -1,7 +1,3 @@ > -ifeq ($(subdir),csu) > -tests += test-multiarch > -endif > - > ifeq ($(subdir),string) > gen-as-const-headers += locale-defines.sym > sysdep_routines += bzero-sse2 memset-sse2 memcpy-ssse3 mempcpy-ssse3 \ > diff --git a/sysdeps/i386/i686/multiarch/test-multiarch.c b/sysdeps/i386/i686/multiarch/test-multiarch.c > deleted file mode 100644 > index 593cfec273..0000000000 > --- a/sysdeps/i386/i686/multiarch/test-multiarch.c > +++ /dev/null > @@ -1 +0,0 @@ > -#include <sysdeps/x86_64/multiarch/test-multiarch.c> > diff --git a/sysdeps/unix/sysv/linux/i386/ld.abilist b/sysdeps/unix/sysv/linux/i386/ld.abilist > index 0478e22071..04655651b0 100644 > --- a/sysdeps/unix/sysv/linux/i386/ld.abilist > +++ b/sysdeps/unix/sysv/linux/i386/ld.abilist > @@ -3,3 +3,4 @@ GLIBC_2.1 __libc_stack_end D 0x4 > GLIBC_2.1 _dl_mcount F > GLIBC_2.3 ___tls_get_addr F > GLIBC_2.3 __tls_get_addr F > +GLIBC_2.33 __x86_get_cpu_features F > diff --git a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist > index d3cdf7611e..e632c6198e 100644 > --- a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist > +++ b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist > @@ -2,3 +2,4 @@ GLIBC_2.2.5 __libc_stack_end D 0x8 > GLIBC_2.2.5 _dl_mcount F > GLIBC_2.2.5 _r_debug D 0x28 > GLIBC_2.3 __tls_get_addr F > +GLIBC_2.33 __x86_get_cpu_features F > diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist > index c70bccf782..9d9d0befde 100644 > --- a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist > +++ b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist > @@ -2,3 +2,4 @@ GLIBC_2.16 __libc_stack_end D 0x4 > GLIBC_2.16 __tls_get_addr F > GLIBC_2.16 _dl_mcount F > GLIBC_2.16 _r_debug D 0x14 > +GLIBC_2.33 __x86_get_cpu_features F > diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile > index a6736aef25..c369faf00d 100644 > --- a/sysdeps/x86/Makefile > +++ b/sysdeps/x86/Makefile > @@ -4,8 +4,10 @@ endif > > ifeq ($(subdir),elf) > sysdep-dl-routines += dl-get-cpu-features > +sysdep_headers += sys/platform/x86.h > > -tests += tst-get-cpu-features tst-get-cpu-features-static > +tests += tst-get-cpu-features tst-get-cpu-features-static \ > + tst-cpu-features-cpuinfo tst-cpu-features-supports > tests-static += tst-get-cpu-features-static > endif > > diff --git a/sysdeps/x86/Versions b/sysdeps/x86/Versions > index e02923708e..59db578a9d 100644 > --- a/sysdeps/x86/Versions > +++ b/sysdeps/x86/Versions > @@ -1,5 +1,5 @@ > ld { > - GLIBC_PRIVATE { > - __get_cpu_features; > + GLIBC_2.33 { > + __x86_get_cpu_features; > } > } > diff --git a/sysdeps/x86/dl-get-cpu-features.c b/sysdeps/x86/dl-get-cpu-features.c > index 9d61cd56be..5f9e46b0c6 100644 > --- a/sysdeps/x86/dl-get-cpu-features.c > +++ b/sysdeps/x86/dl-get-cpu-features.c > @@ -18,10 +18,12 @@ > > #include <ldsodefs.h> > > -#undef __get_cpu_features > +#undef __x86_get_cpu_features > > const struct cpu_features * > -__get_cpu_features (void) > +__x86_get_cpu_features (unsigned int max) > { > + if (max > COMMON_CPUID_INDEX_MAX) > + return NULL; > return &GLRO(dl_x86_cpu_features); > } > diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h > new file mode 100644 > index 0000000000..dcf29b6fe8 > --- /dev/null > +++ b/sysdeps/x86/include/cpu-features.h > @@ -0,0 +1,183 @@ > +/* Data structure for x86 CPU features. > + Copyright (C) 2020 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 > + <https://www.gnu.org/licenses/>. */ > + > +#ifndef _PRIVATE_CPU_FEATURES_H > +#define _PRIVATE_CPU_FEATURES_H 1 > + > +#ifdef _CPU_FEATURES_H > +# error this should be impossible > +#endif > + > +#ifndef _ISOMAC > +/* Get most of the contents from the public header, but we define a > + different `struct cpu_features' type for private use. */ > +# define cpu_features cpu_features_public > +# define __x86_get_cpu_features __x86_get_cpu_features_public > +#endif > + > +#include <sysdeps/x86/sys/platform/x86.h> > + > +#ifndef _ISOMAC > + > +# undef cpu_features > +# undef __x86_get_cpu_features > +# define __get_cpu_features() __x86_get_cpu_features (0) > + > +enum > +{ > + /* The integer bit array index for the first set of preferred feature > + bits. */ > + PREFERRED_FEATURE_INDEX_1 = 0, > + /* The current maximum size of the feature integer bit array. */ > + PREFERRED_FEATURE_INDEX_MAX > +}; > + > +/* Only used directly in cpu-features.c. */ > +# define CPU_FEATURE_SET(ptr, name) \ > + ptr->features[index_cpu_##name].usable.reg_##name |= bit_cpu_##name; > +# define CPU_FEATURE_UNSET(ptr, name) \ > + ptr->features[index_cpu_##name].usable.reg_##name &= ~bit_cpu_##name; > +# define CPU_FEATURE_SET_USABLE(ptr, name) \ > + ptr->features[index_cpu_##name].usable.reg_##name \ > + |= ptr->features[index_cpu_##name].cpuid.reg_##name & bit_cpu_##name; > +# define CPU_FEATURE_PREFERRED_P(ptr, name) \ > + ((ptr->preferred[index_arch_##name] & bit_arch_##name) != 0) > +# define CPU_FEATURE_CPU_P(ptr, name) \ > + CPU_FEATURE_CHECK_P (ptr, name, cpuid) > + > +/* HAS_CPU_FEATURE evaluates to true if CPU supports the feature. */ > +# undef HAS_CPU_FEATURE > +# define HAS_CPU_FEATURE(name) \ > + CPU_FEATURE_CPU_P (__x86_get_cpu_features (0), name) > +/* CPU_FEATURE_USABLE evaluates to true if the feature is usable. */ > +# undef CPU_FEATURE_USABLE > +# define CPU_FEATURE_USABLE(name) \ > + CPU_FEATURE_USABLE_P (__x86_get_cpu_features (0), name) > +/* CPU_FEATURE_PREFER evaluates to true if we prefer the feature at > + runtime. */ > +# define CPU_FEATURE_PREFERRED(name) \ > + CPU_FEATURE_PREFERRED_P(__get_cpu_features (), name) > + > +# define CPU_FEATURES_CPU_P(ptr, name) \ > + CPU_FEATURE_CPU_P (ptr, name) > +# define CPU_FEATURES_ARCH_P(ptr, name) \ > + CPU_FEATURE_PREFERRED_P (ptr, name) > +# define HAS_ARCH_FEATURE(name) \ > + CPU_FEATURE_PREFERRED (name) > + > +/* PREFERRED_FEATURE_INDEX_1. */ > +# define bit_arch_I586 (1u << 0) > +# define bit_arch_I686 (1u << 1) > +# define bit_arch_Fast_Rep_String (1u << 2) > +# define bit_arch_Fast_Copy_Backward (1u << 3) > +# define bit_arch_Fast_Unaligned_Load (1u << 4) > +# define bit_arch_Fast_Unaligned_Copy (1u << 5) > +# define bit_arch_Slow_BSF (1u << 6) > +# define bit_arch_Slow_SSE4_2 (1u << 7) > +# define bit_arch_AVX_Fast_Unaligned_Load (1u << 8) > +# define bit_arch_Prefer_MAP_32BIT_EXEC (1u << 9) > +# define bit_arch_Prefer_PMINUB_for_stringop (1u << 10) > +# define bit_arch_Prefer_No_VZEROUPPER (1u << 11) > +# define bit_arch_Prefer_ERMS (1u << 12) > +# define bit_arch_Prefer_FSRM (1u << 13) > +# define bit_arch_Prefer_No_AVX512 (1u << 14) > +# define bit_arch_MathVec_Prefer_No_AVX512 (1u << 15) > + > +# define index_arch_Fast_Rep_String PREFERRED_FEATURE_INDEX_1 > +# define index_arch_Fast_Copy_Backward PREFERRED_FEATURE_INDEX_1 > +# define index_arch_Slow_BSF PREFERRED_FEATURE_INDEX_1 > +# define index_arch_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 > +# define index_arch_Prefer_PMINUB_for_stringop PREFERRED_FEATURE_INDEX_1 > +# define index_arch_Fast_Unaligned_Copy PREFERRED_FEATURE_INDEX_1 > +# define index_arch_I586 PREFERRED_FEATURE_INDEX_1 > +# define index_arch_I686 PREFERRED_FEATURE_INDEX_1 > +# define index_arch_Slow_SSE4_2 PREFERRED_FEATURE_INDEX_1 > +# define index_arch_AVX_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 > +# define index_arch_Prefer_MAP_32BIT_EXEC PREFERRED_FEATURE_INDEX_1 > +# define index_arch_Prefer_No_VZEROUPPER PREFERRED_FEATURE_INDEX_1 > +# define index_arch_Prefer_ERMS PREFERRED_FEATURE_INDEX_1 > +# define index_arch_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 > +# define index_arch_MathVec_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 > +# define index_arch_Prefer_FSRM PREFERRED_FEATURE_INDEX_1 > + > +/* XCR0 Feature flags. */ > +# define bit_XMM_state (1u << 1) > +# define bit_YMM_state (1u << 2) > +# define bit_Opmask_state (1u << 5) > +# define bit_ZMM0_15_state (1u << 6) > +# define bit_ZMM16_31_state (1u << 7) > +# define bit_XTILECFG_state (1u << 17) > +# define bit_XTILEDATA_state (1u << 18) > + > +struct cpu_features > +{ > + struct cpu_features_basic basic; > + struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; > + unsigned int preferred[PREFERRED_FEATURE_INDEX_MAX]; > + /* The state size for XSAVEC or XSAVE. The type must be unsigned long > + int so that we use > + > + sub xsave_state_size_offset(%rip) %RSP_LP > + > + in _dl_runtime_resolve. */ > + unsigned long int xsave_state_size; > + /* The full state size for XSAVE when XSAVEC is disabled by > + > + GLIBC_TUNABLES=glibc.cpu.hwcaps=-XSAVEC > + */ > + unsigned int xsave_state_full_size; > + /* Data cache size for use in memory and string routines, typically > + L1 size. */ > + unsigned long int data_cache_size; > + /* Shared cache size for use in memory and string routines, typically > + L2 or L3 size. */ > + unsigned long int shared_cache_size; > + /* Threshold to use non temporal store. */ > + unsigned long int non_temporal_threshold; > + /* Threshold to use "rep movsb". */ > + unsigned long int rep_movsb_threshold; > + /* Threshold to use "rep stosb". */ > + unsigned long int rep_stosb_threshold; > +}; > + > +# if defined (_LIBC) && !IS_IN (nonlib) > +/* Unused for x86. */ > +# define INIT_ARCH() > +# define __x86_get_cpu_features(max) (&GLRO(dl_x86_cpu_features)) > +# endif > + > +# ifdef __x86_64__ > +# define HAS_CPUID 1 > +# elif (defined __i586__ || defined __pentium__ \ > + || defined __geode__ || defined __k6__) > +# define HAS_CPUID 1 > +# define HAS_I586 1 > +# define HAS_I686 HAS_ARCH_FEATURE (I686) > +# elif defined __i486__ > +# define HAS_CPUID 0 > +# define HAS_I586 HAS_ARCH_FEATURE (I586) > +# define HAS_I686 HAS_ARCH_FEATURE (I686) > +# else > +# define HAS_CPUID 1 > +# define HAS_I586 1 > +# define HAS_I686 1 > +# endif > + > +#endif /* !_ISOMAC */ > + > +#endif /* include/cpu-features.h */ > diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/sys/platform/x86.h > similarity index 81% > rename from sysdeps/x86/cpu-features.h > rename to sysdeps/x86/sys/platform/x86.h > index 78fcec251e..bf3727ebc0 100644 > --- a/sysdeps/x86/cpu-features.h > +++ b/sysdeps/x86/sys/platform/x86.h > @@ -1,4 +1,5 @@ > -/* This file is part of the GNU C Library. > +/* Data structure for x86 CPU features. > + This file is part of the GNU C Library. > Copyright (C) 2008-2020 Free Software Foundation, Inc. > > The GNU C Library is free software; you can redistribute it and/or > @@ -15,17 +16,8 @@ > License along with the GNU C Library; if not, see > <https://www.gnu.org/licenses/>. */ > > -#ifndef cpu_features_h > -#define cpu_features_h > - > -enum > -{ > - /* The integer bit array index for the first set of preferred feature > - bits. */ > - PREFERRED_FEATURE_INDEX_1 = 0, > - /* The current maximum size of the feature integer bit array. */ > - PREFERRED_FEATURE_INDEX_MAX > -}; > +#ifndef _SYS_PLATFORM_X86_H > +#define _SYS_PLATFORM_X86_H > > enum > { > @@ -76,73 +68,32 @@ struct cpu_features > { > struct cpu_features_basic basic; > struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; > - unsigned int preferred[PREFERRED_FEATURE_INDEX_MAX]; > - /* The state size for XSAVEC or XSAVE. The type must be unsigned long > - int so that we use > - > - sub xsave_state_size_offset(%rip) %RSP_LP > - > - in _dl_runtime_resolve. */ > - unsigned long int xsave_state_size; > - /* The full state size for XSAVE when XSAVEC is disabled by > - > - GLIBC_TUNABLES=glibc.cpu.hwcaps=-XSAVEC > - */ > - unsigned int xsave_state_full_size; > - /* Data cache size for use in memory and string routines, typically > - L1 size. */ > - unsigned long int data_cache_size; > - /* Shared cache size for use in memory and string routines, typically > - L2 or L3 size. */ > - unsigned long int shared_cache_size; > - /* Threshold to use non temporal store. */ > - unsigned long int non_temporal_threshold; > - /* Threshold to use "rep movsb". */ > - unsigned long int rep_movsb_threshold; > - /* Threshold to use "rep stosb". */ > - unsigned long int rep_stosb_threshold; > }; > > -/* Used from outside of glibc to get access to the CPU features > - structure. */ > -extern const struct cpu_features *__get_cpu_features (void) > +/* Get a pointer to the CPU features structure. */ > +extern const struct cpu_features *__x86_get_cpu_features (unsigned int) > __attribute__ ((const)); > > -/* Only used directly in cpu-features.c. */ > #define CPU_FEATURE_CHECK_P(ptr, name, check) \ > ((ptr->features[index_cpu_##name].check.reg_##name \ > & bit_cpu_##name) != 0) > -#define CPU_FEATURE_SET(ptr, name) \ > - ptr->features[index_cpu_##name].usable.reg_##name |= bit_cpu_##name; > -#define CPU_FEATURE_UNSET(ptr, name) \ > - ptr->features[index_cpu_##name].usable.reg_##name &= ~bit_cpu_##name; > -#define CPU_FEATURE_SET_USABLE(ptr, name) \ > - ptr->features[index_cpu_##name].usable.reg_##name \ > - |= ptr->features[index_cpu_##name].cpuid.reg_##name & bit_cpu_##name; > -#define CPU_FEATURE_PREFERRED_P(ptr, name) \ > - ((ptr->preferred[index_arch_##name] & bit_arch_##name) != 0) > #define CPU_FEATURE_CPU_P(ptr, name) \ > CPU_FEATURE_CHECK_P (ptr, name, cpuid) > #define CPU_FEATURE_USABLE_P(ptr, name) \ > CPU_FEATURE_CHECK_P (ptr, name, usable) > > /* HAS_CPU_FEATURE evaluates to true if CPU supports the feature. */ > -#define HAS_CPU_FEATURE(name) \ > - CPU_FEATURE_CPU_P (__get_cpu_features (), name) > +#define HAS_CPU_FEATURE(name) \ > + (__extension__ \ > + ({ const struct cpu_features *__ptr = \ > + __x86_get_cpu_features (COMMON_CPUID_INDEX_MAX); \ > + __ptr && CPU_FEATURE_CPU_P (__ptr, name); })) > /* CPU_FEATURE_USABLE evaluates to true if the feature is usable. */ > -#define CPU_FEATURE_USABLE(name) \ > - CPU_FEATURE_USABLE_P (__get_cpu_features (), name) > -/* CPU_FEATURE_PREFER evaluates to true if we prefer the feature at > - runtime. */ > -#define CPU_FEATURE_PREFERRED(name) \ > - CPU_FEATURE_PREFERRED_P(__get_cpu_features (), name) > - > -#define CPU_FEATURES_CPU_P(ptr, name) \ > - CPU_FEATURE_CPU_P (ptr, name) > -#define CPU_FEATURES_ARCH_P(ptr, name) \ > - CPU_FEATURE_PREFERRED_P (ptr, name) > -#define HAS_ARCH_FEATURE(name) \ > - CPU_FEATURE_PREFERRED (name) > +#define CPU_FEATURE_USABLE(name) \ > + (__extension__ \ > + ({ const struct cpu_features *__ptr = \ > + __x86_get_cpu_features (COMMON_CPUID_INDEX_MAX); \ > + __ptr && CPU_FEATURE_USABLE_P (__ptr, name); })) > > /* CPU features. */ > > @@ -787,71 +738,4 @@ extern const struct cpu_features *__get_cpu_features (void) > /* EAX. */ > #define reg_AVX512_BF16 eax > > -/* FEATURE_INDEX_2. */ > -#define bit_arch_I586 (1u << 0) > -#define bit_arch_I686 (1u << 1) > -#define bit_arch_Fast_Rep_String (1u << 2) > -#define bit_arch_Fast_Copy_Backward (1u << 3) > -#define bit_arch_Fast_Unaligned_Load (1u << 4) > -#define bit_arch_Fast_Unaligned_Copy (1u << 5) > -#define bit_arch_Slow_BSF (1u << 6) > -#define bit_arch_Slow_SSE4_2 (1u << 7) > -#define bit_arch_AVX_Fast_Unaligned_Load (1u << 8) > -#define bit_arch_Prefer_MAP_32BIT_EXEC (1u << 9) > -#define bit_arch_Prefer_PMINUB_for_stringop (1u << 10) > -#define bit_arch_Prefer_No_VZEROUPPER (1u << 11) > -#define bit_arch_Prefer_ERMS (1u << 12) > -#define bit_arch_Prefer_FSRM (1u << 13) > -#define bit_arch_Prefer_No_AVX512 (1u << 14) > -#define bit_arch_MathVec_Prefer_No_AVX512 (1u << 15) > - > -#define index_arch_Fast_Rep_String PREFERRED_FEATURE_INDEX_1 > -#define index_arch_Fast_Copy_Backward PREFERRED_FEATURE_INDEX_1 > -#define index_arch_Slow_BSF PREFERRED_FEATURE_INDEX_1 > -#define index_arch_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 > -#define index_arch_Prefer_PMINUB_for_stringop PREFERRED_FEATURE_INDEX_1 > -#define index_arch_Fast_Unaligned_Copy PREFERRED_FEATURE_INDEX_1 > -#define index_arch_I586 PREFERRED_FEATURE_INDEX_1 > -#define index_arch_I686 PREFERRED_FEATURE_INDEX_1 > -#define index_arch_Slow_SSE4_2 PREFERRED_FEATURE_INDEX_1 > -#define index_arch_AVX_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 > -#define index_arch_Prefer_MAP_32BIT_EXEC PREFERRED_FEATURE_INDEX_1 > -#define index_arch_Prefer_No_VZEROUPPER PREFERRED_FEATURE_INDEX_1 > -#define index_arch_Prefer_ERMS PREFERRED_FEATURE_INDEX_1 > -#define index_arch_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 > -#define index_arch_MathVec_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 > -#define index_arch_Prefer_FSRM PREFERRED_FEATURE_INDEX_1 > - > -/* XCR0 Feature flags. */ > -#define bit_XMM_state (1u << 1) > -#define bit_YMM_state (1u << 2) > -#define bit_Opmask_state (1u << 5) > -#define bit_ZMM0_15_state (1u << 6) > -#define bit_ZMM16_31_state (1u << 7) > -#define bit_XTILECFG_state (1u << 17) > -#define bit_XTILEDATA_state (1u << 18) > - > -# if defined (_LIBC) && !IS_IN (nonlib) > -/* Unused for x86. */ > -# define INIT_ARCH() > -# define __get_cpu_features() (&GLRO(dl_x86_cpu_features)) > -# endif > - > -#ifdef __x86_64__ > -# define HAS_CPUID 1 > -#elif (defined __i586__ || defined __pentium__ \ > - || defined __geode__ || defined __k6__) > -# define HAS_CPUID 1 > -# define HAS_I586 1 > -# define HAS_I686 HAS_ARCH_FEATURE (I686) > -#elif defined __i486__ > -# define HAS_CPUID 0 > -# define HAS_I586 HAS_ARCH_FEATURE (I586) > -# define HAS_I686 HAS_ARCH_FEATURE (I686) > -#else > -# define HAS_CPUID 1 > -# define HAS_I586 1 > -# define HAS_I686 1 > -#endif > - > -#endif /* cpu_features_h */ > +#endif /* _SYS_PLATFORM_X86_H */ > diff --git a/sysdeps/x86/tst-cpu-features-cpuinfo.c b/sysdeps/x86/tst-cpu-features-cpuinfo.c > new file mode 100644 > index 0000000000..96277284d1 > --- /dev/null > +++ b/sysdeps/x86/tst-cpu-features-cpuinfo.c > @@ -0,0 +1,250 @@ > +/* Test CPU feature data against /proc/cpuinfo. > + This file is part of the GNU C Library. > + Copyright (C) 2012-2020 Free Software Foundation, Inc. > + > + 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <sys/platform/x86.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > + > +static char *cpu_flags; > + > +/* Search for flags in /proc/cpuinfo and store line > + in cpu_flags. */ > +void > +get_cpuinfo (void) > +{ > + FILE *f; > + char *line = NULL; > + size_t len = 0; > + ssize_t read; > + > + f = fopen ("/proc/cpuinfo", "r"); > + if (f == NULL) > + { > + printf ("cannot open /proc/cpuinfo\n"); > + exit (1); > + } > + > + while ((read = getline (&line, &len, f)) != -1) > + { > + if (strncmp (line, "flags", 5) == 0) > + { > + cpu_flags = strdup (line); > + break; > + } > + } > + fclose (f); > + free (line); > +} > + > +int > +check_proc (const char *proc_name, int flag, int usable, const char *name) > +{ > + int found = 0; > + > + printf ("Checking %s:\n", name); > + if (!usable) > + { > + printf (" %s: insufficient usable info, skipped\n", name); > + return 0; > + } > + printf (" %s: %d\n", name, flag); > + if (strstr (cpu_flags, proc_name) != NULL) > + found = 1; > + printf (" cpuinfo (%s): %d\n", proc_name, found); > + > + if (found != flag) > + printf (" *** failure ***\n"); > + > + return (found != flag); > +} > + > +#define CHECK_PROC(str, name) \ > + check_proc (#str, HAS_CPU_FEATURE (name), CPU_FEATURE_USABLE (name), \ > + "HAS_CPU_FEATURE (" #name ")"); > + > +static int > +do_test (int argc, char **argv) > +{ > + int fails = 0; > + > + get_cpuinfo (); > + fails += CHECK_PROC (acpi, ACPI); > + fails += CHECK_PROC (adx, ADX); > + fails += CHECK_PROC (apic, APIC); > + fails += CHECK_PROC (aes, AES); > + fails += CHECK_PROC (amx_bf16, AMX_BF16); > + fails += CHECK_PROC (amx_int8, AMX_INT8); > + fails += CHECK_PROC (amx_tile, AMX_TILE); > + fails += CHECK_PROC (arch_capabilities, ARCH_CAPABILITIES); > + fails += CHECK_PROC (avx, AVX); > + fails += CHECK_PROC (avx2, AVX2); > + fails += CHECK_PROC (avx512_4fmaps, AVX512_4FMAPS); > + fails += CHECK_PROC (avx512_4vnniw, AVX512_4VNNIW); > + fails += CHECK_PROC (avx512_bf16, AVX512_BF16); > + fails += CHECK_PROC (avx512_bitalg, AVX512_BITALG); > + fails += CHECK_PROC (avx512ifma, AVX512_IFMA); > + fails += CHECK_PROC (avx512_vbmi, AVX512_VBMI); > + fails += CHECK_PROC (avx512_vbmi2, AVX512_VBMI2); > + fails += CHECK_PROC (avx512_vnni, AVX512_VNNI); > + fails += CHECK_PROC (avx512_vp2intersect, AVX512_VP2INTERSECT); > + fails += CHECK_PROC (avx512_vpopcntdq, AVX512_VPOPCNTDQ); > + fails += CHECK_PROC (avx512bw, AVX512BW); > + fails += CHECK_PROC (avx512cd, AVX512CD); > + fails += CHECK_PROC (avx512er, AVX512ER); > + fails += CHECK_PROC (avx512dq, AVX512DQ); > + fails += CHECK_PROC (avx512f, AVX512F); > + fails += CHECK_PROC (avx512pf, AVX512PF); > + fails += CHECK_PROC (avx512vl, AVX512VL); > + fails += CHECK_PROC (bmi1, BMI1); > + fails += CHECK_PROC (bmi2, BMI2); > + fails += CHECK_PROC (cldemote, CLDEMOTE); > + fails += CHECK_PROC (clflushopt, CLFLUSHOPT); > + fails += CHECK_PROC (clflush, CLFSH); > + fails += CHECK_PROC (clwb, CLWB); > + fails += CHECK_PROC (cmov, CMOV); > + fails += CHECK_PROC (cx16, CMPXCHG16B); > + fails += CHECK_PROC (cnxt_id, CNXT_ID); > + fails += CHECK_PROC (core_capabilities, CORE_CAPABILITIES); > + fails += CHECK_PROC (cx8, CX8); > + fails += CHECK_PROC (dca, DCA); > + fails += CHECK_PROC (de, DE); > + fails += CHECK_PROC (zero_fcs_fds, DEPR_FPU_CS_DS); > + fails += CHECK_PROC (ds, DS); > + fails += CHECK_PROC (ds_cpl, DS_CPL); > + fails += CHECK_PROC (dtes64, DTES64); > + fails += CHECK_PROC (est, EIST); > + fails += CHECK_PROC (enqcmd, ENQCMD); > + fails += CHECK_PROC (erms, ERMS); > + fails += CHECK_PROC (f16c, F16C); > + fails += CHECK_PROC (fma, FMA); > + fails += CHECK_PROC (fma4, FMA4); > + fails += CHECK_PROC (fpu, FPU); > + fails += CHECK_PROC (fsgsbase, FSGSBASE); > + fails += CHECK_PROC (fsrm, FSRM); > + fails += CHECK_PROC (fxsr, FXSR); > + fails += CHECK_PROC (gfni, GFNI); > + fails += CHECK_PROC (hle, HLE); > + fails += CHECK_PROC (ht, HTT); > + fails += CHECK_PROC (hybrid, HYBRID); > + fails += CHECK_PROC (ibrs, IBRS_IBPB); > + fails += CHECK_PROC (ibt, IBT); > + fails += CHECK_PROC (invariant_tsc, INVARIANT_TSC); > + fails += CHECK_PROC (invpcid, INVPCID); > + fails += CHECK_PROC (flush_l1d, L1D_FLUSH); > + fails += CHECK_PROC (lahf_lm, LAHF64_SAHF64); > + fails += CHECK_PROC (lm, LM); > + fails += CHECK_PROC (lwp, LWP); > + fails += CHECK_PROC (abm, LZCNT); > + fails += CHECK_PROC (mca, MCA); > + fails += CHECK_PROC (mce, MCE); > + fails += CHECK_PROC (md_clear, MD_CLEAR); > + fails += CHECK_PROC (mmx, MMX); > + fails += CHECK_PROC (monitor, MONITOR); > + fails += CHECK_PROC (movbe, MOVBE); > + fails += CHECK_PROC (movdiri, MOVDIRI); > + fails += CHECK_PROC (movdir64b, MOVDIR64B); > + fails += CHECK_PROC (mpx, MPX); > + fails += CHECK_PROC (msr, MSR); > + fails += CHECK_PROC (mtrr, MTRR); > + fails += CHECK_PROC (nx, NX); > + fails += CHECK_PROC (ospke, OSPKE); > +#if 0 > + /* NB: /proc/cpuinfo doesn't report this feature. */ > + fails += CHECK_PROC (osxsave, OSXSAVE); > +#endif > + fails += CHECK_PROC (pae, PAE); > + fails += CHECK_PROC (pdpe1gb, PAGE1GB); > + fails += CHECK_PROC (pat, PAT); > + fails += CHECK_PROC (pbe, PBE); > + fails += CHECK_PROC (pcid, PCID); > + fails += CHECK_PROC (pclmulqdq, PCLMULQDQ); > + fails += CHECK_PROC (pconfig, PCONFIG); > + fails += CHECK_PROC (pdcm, PDCM); > + fails += CHECK_PROC (pge, PGE); > + fails += CHECK_PROC (pks, PKS); > + fails += CHECK_PROC (pku, PKU); > + fails += CHECK_PROC (popcnt, POPCNT); > + fails += CHECK_PROC (3dnowprefetch, PREFETCHW); > + fails += CHECK_PROC (prefetchwt1, PREFETCHWT1); > + fails += CHECK_PROC (pse, PSE); > + fails += CHECK_PROC (pse36, PSE_36); > + fails += CHECK_PROC (psn, PSN); > + fails += CHECK_PROC (rdpid, RDPID); > + fails += CHECK_PROC (rdrand, RDRAND); > + fails += CHECK_PROC (rdseed, RDSEED); > + fails += CHECK_PROC (rdt_a, RDT_A); > + fails += CHECK_PROC (cqm, RDT_M); > + fails += CHECK_PROC (rdtscp, RDTSCP); > + fails += CHECK_PROC (rtm, RTM); > + fails += CHECK_PROC (sdbg, SDBG); > + fails += CHECK_PROC (sep, SEP); > + fails += CHECK_PROC (serialize, SERIALIZE); > + fails += CHECK_PROC (sgx, SGX); > + fails += CHECK_PROC (sgx_lc, SGX_LC); > + fails += CHECK_PROC (sha_ni, SHA); > + fails += CHECK_PROC (shstk, SHSTK); > + fails += CHECK_PROC (smap, SMAP); > + fails += CHECK_PROC (smep, SMEP); > + fails += CHECK_PROC (smx, SMX); > + fails += CHECK_PROC (ss, SS); > + fails += CHECK_PROC (ssbd, SSBD); > + fails += CHECK_PROC (sse, SSE); > + fails += CHECK_PROC (sse2, SSE2); > + fails += CHECK_PROC (sse3, SSE3); > + fails += CHECK_PROC (sse4_1, SSE4_1); > + fails += CHECK_PROC (sse4_2, SSE4_2); > + fails += CHECK_PROC (sse4a, SSE4A); > + fails += CHECK_PROC (ssse3, SSSE3); > + fails += CHECK_PROC (stibp, STIBP); > + fails += CHECK_PROC (svm, SVM); > +#ifdef __x86_64__ > + /* NB: SYSCALL_SYSRET is 64-bit only. */ > + fails += CHECK_PROC (syscall, SYSCALL_SYSRET); > +#endif > + fails += CHECK_PROC (tbm, TBM); > + fails += CHECK_PROC (tm, TM); > + fails += CHECK_PROC (tm2, TM2); > + fails += CHECK_PROC (intel_pt, TRACE); > + fails += CHECK_PROC (tsc, TSC); > + fails += CHECK_PROC (tsc_adjust, TSC_ADJUST); > + fails += CHECK_PROC (tsc_deadline, TSC_DEADLINE); > + fails += CHECK_PROC (tsxldtrk, TSXLDTRK); > + fails += CHECK_PROC (umip, UMIP); > + fails += CHECK_PROC (vaes, VAES); > + fails += CHECK_PROC (vme, VME); > + fails += CHECK_PROC (vmx, VMX); > + fails += CHECK_PROC (vpclmulqdq, VPCLMULQDQ); > + fails += CHECK_PROC (waitpkg, WAITPKG); > + fails += CHECK_PROC (wbnoinvd, WBNOINVD); > + fails += CHECK_PROC (x2apic, X2APIC); > + fails += CHECK_PROC (xfd, XFD); > + fails += CHECK_PROC (xgetbv1, XGETBV_ECX_1); > + fails += CHECK_PROC (xop, XOP); > + fails += CHECK_PROC (xsave, XSAVE); > + fails += CHECK_PROC (xsavec, XSAVEC); > + fails += CHECK_PROC (xsaveopt, XSAVEOPT); > + fails += CHECK_PROC (xsaves, XSAVES); > + fails += CHECK_PROC (xtpr, XTPRUPDCTRL); > + > + printf ("%d differences between /proc/cpuinfo and glibc code.\n", fails); > + > + return (fails != 0); > +} > + > +#include "../../../test-skeleton.c" > diff --git a/sysdeps/x86/tst-cpu-features-supports.c b/sysdeps/x86/tst-cpu-features-supports.c > new file mode 100644 > index 0000000000..bf881b531f > --- /dev/null > +++ b/sysdeps/x86/tst-cpu-features-supports.c > @@ -0,0 +1,192 @@ > +/* Test CPU feature data against __builtin_cpu_supports. > + This file is part of the GNU C Library. > + Copyright (C) 2020 Free Software Foundation, Inc. > + > + 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 > + <https://www.gnu.org/licenses/>. */ > + > +#include <sys/platform/x86.h> > +#include <stdio.h> > + > +int > +check_supports (int supports, int usable, const char *supports_name, > + const char *name) > +{ > + printf ("Checking %s:\n", name); > + printf (" %s: %d\n", name, usable); > + printf (" __builtin_cpu_supports (%s): %d\n", > + supports_name, supports); > + > + if ((supports != 0) != (usable != 0)) > + { > + printf (" *** failure ***\n"); > + return 1; > + } > + > + return 0; > +} > + > +#define CHECK_SUPPORTS(str, name) \ > + check_supports (__builtin_cpu_supports (#str), \ > + CPU_FEATURE_USABLE (name), \ > + #str, "HAS_CPU_FEATURE (" #name ")"); > + > +static int > +do_test (int argc, char **argv) > +{ > + int fails = 0; > + > +#if __GNUC_PREREQ (11, 0) > + fails += CHECK_SUPPORTS (adx, ADX); > +#endif > +#if __GNUC_PREREQ (6, 0) > + fails += CHECK_SUPPORTS (aes, AES); > +#endif > +#if __GNUC_PREREQ (11, 1) > + fails += CHECK_SUPPORTS (amx_bf16, AMX_BF16); > + fails += CHECK_SUPPORTS (amx_int8, AMX_INT8); > + fails += CHECK_SUPPORTS (amx_tile, AMX_TILE); > +#endif > + fails += CHECK_SUPPORTS (avx, AVX); > + fails += CHECK_SUPPORTS (avx2, AVX2); > +#if __GNUC_PREREQ (7, 0) > + fails += CHECK_SUPPORTS (avx5124fmaps, AVX512_4FMAPS); > + fails += CHECK_SUPPORTS (avx5124vnniw, AVX512_4VNNIW); > +#endif > +#if __GNUC_PREREQ (10, 0) > + fails += CHECK_SUPPORTS (avx512bf16, AVX512_BF16); > +#endif > +#if __GNUC_PREREQ (8, 0) > + fails += CHECK_SUPPORTS (avx512bitalg, AVX512_BITALG); > +#endif > +#if __GNUC_PREREQ (6, 0) > + fails += CHECK_SUPPORTS (avx512ifma, AVX512_IFMA); > + fails += CHECK_SUPPORTS (avx512vbmi, AVX512_VBMI); > +#endif > +#if __GNUC_PREREQ (8, 0) > + fails += CHECK_SUPPORTS (avx512vbmi2, AVX512_VBMI2); > + fails += CHECK_SUPPORTS (avx512vnni, AVX512_VNNI); > +#endif > +#if __GNUC_PREREQ (10, 0) > + fails += CHECK_SUPPORTS (avx512vp2intersect, AVX512_VP2INTERSECT); > +#endif > +#if __GNUC_PREREQ (7, 0) > + fails += CHECK_SUPPORTS (avx512vpopcntdq, AVX512_VPOPCNTDQ); > +#endif > +#if __GNUC_PREREQ (6, 0) > + fails += CHECK_SUPPORTS (avx512bw, AVX512BW); > + fails += CHECK_SUPPORTS (avx512cd, AVX512CD); > + fails += CHECK_SUPPORTS (avx512er, AVX512ER); > + fails += CHECK_SUPPORTS (avx512dq, AVX512DQ); > +#endif > +#if __GNUC_PREREQ (5, 0) > + fails += CHECK_SUPPORTS (avx512f, AVX512F); > +#endif > +#if __GNUC_PREREQ (6, 0) > + fails += CHECK_SUPPORTS (avx512pf, AVX512PF); > + fails += CHECK_SUPPORTS (avx512vl, AVX512VL); > +#endif > +#if __GNUC_PREREQ (5, 0) > + fails += CHECK_SUPPORTS (bmi, BMI1); > + fails += CHECK_SUPPORTS (bmi2, BMI2); > +#endif > +#if __GNUC_PREREQ (11, 0) > + fails += CHECK_SUPPORTS (cldemote, CLDEMOTE); > + fails += CHECK_SUPPORTS (clflushopt, CLFLUSHOPT); > + fails += CHECK_SUPPORTS (clwb, CLWB); > +#endif > + fails += CHECK_SUPPORTS (cmov, CMOV); > +#if __GNUC_PREREQ (11, 0) > + fails += CHECK_SUPPORTS (cmpxchg16b, CMPXCHG16B); > + fails += CHECK_SUPPORTS (cmpxchg8b, CX8); > + fails += CHECK_SUPPORTS (enqcmd, ENQCMD); > + fails += CHECK_SUPPORTS (f16c, F16C); > +#endif > +#if __GNUC_PREREQ (4, 9) > + fails += CHECK_SUPPORTS (fma, FMA); > + fails += CHECK_SUPPORTS (fma4, FMA4); > +#endif > +#if __GNUC_PREREQ (11, 0) > + fails += CHECK_SUPPORTS (fsgsbase, FSGSBASE); > + fails += CHECK_SUPPORTS (fxsave, FXSR); > +#endif > +#if __GNUC_PREREQ (8, 0) > + fails += CHECK_SUPPORTS (gfni, GFNI); > +#endif > +#if __GNUC_PREREQ (11, 0) > + fails += CHECK_SUPPORTS (hle, HLE); > + fails += CHECK_SUPPORTS (ibt, IBT); > + fails += CHECK_SUPPORTS (lahf_lm, LAHF64_SAHF64); > + fails += CHECK_SUPPORTS (lm, LM); > + fails += CHECK_SUPPORTS (lwp, LWP); > + fails += CHECK_SUPPORTS (lzcnt, LZCNT); > +#endif > + fails += CHECK_SUPPORTS (mmx, MMX); > +#if __GNUC_PREREQ (11, 0) > + fails += CHECK_SUPPORTS (movbe, MOVBE); > + fails += CHECK_SUPPORTS (movdiri, MOVDIRI); > + fails += CHECK_SUPPORTS (movdir64b, MOVDIR64B); > + fails += CHECK_SUPPORTS (osxsave, OSXSAVE); > + fails += CHECK_SUPPORTS (pconfig, PCONFIG); > + fails += CHECK_SUPPORTS (pku, PKU); > +#endif > + fails += CHECK_SUPPORTS (popcnt, POPCNT); > +#if __GNUC_PREREQ (11, 0) > + fails += CHECK_SUPPORTS (prefetchwt1, PREFETCHWT1); > + fails += CHECK_SUPPORTS (rdpid, RDPID); > + fails += CHECK_SUPPORTS (rdrnd, RDRAND); > + fails += CHECK_SUPPORTS (rdseed, RDSEED); > + fails += CHECK_SUPPORTS (rtm, RTM); > + fails += CHECK_SUPPORTS (serialize, SERIALIZE); > + fails += CHECK_SUPPORTS (sha, SHA); > + fails += CHECK_SUPPORTS (shstk, SHSTK); > +#endif > + fails += CHECK_SUPPORTS (sse, SSE); > + fails += CHECK_SUPPORTS (sse2, SSE2); > + fails += CHECK_SUPPORTS (sse3, SSE3); > + fails += CHECK_SUPPORTS (sse4.1, SSE4_1); > + fails += CHECK_SUPPORTS (sse4.2, SSE4_2); > +#if __GNUC_PREREQ (4, 9) > + fails += CHECK_SUPPORTS (sse4a, SSE4A); > +#endif > + fails += CHECK_SUPPORTS (ssse3, SSSE3); > +#if __GNUC_PREREQ (11, 0) > + fails += CHECK_SUPPORTS (tbm, TBM); > + fails += CHECK_SUPPORTS (tsxldtrk, TSXLDTRK); > + fails += CHECK_SUPPORTS (vaes, VAES); > +#endif > +#if __GNUC_PREREQ (8, 0) > + fails += CHECK_SUPPORTS (vpclmulqdq, VPCLMULQDQ); > +#endif > +#if __GNUC_PREREQ (11, 0) > + fails += CHECK_SUPPORTS (waitpkg, WAITPKG); > + fails += CHECK_SUPPORTS (wbnoinvd, WBNOINVD); > +#endif > +#if __GNUC_PREREQ (4, 9) > + fails += CHECK_SUPPORTS (xop, XOP); > +#endif > +#if __GNUC_PREREQ (11, 0) > + fails += CHECK_SUPPORTS (xsave, XSAVE); > + fails += CHECK_SUPPORTS (xsavec, XSAVEC); > + fails += CHECK_SUPPORTS (xsaveopt, XSAVEOPT); > + fails += CHECK_SUPPORTS (xsaves, XSAVES); > +#endif > + > + printf ("%d differences between __builtin_cpu_supports and glibc code.\n", > + fails); > + > + return (fails != 0); > +} > + > +#include "../../../test-skeleton.c" > diff --git a/sysdeps/x86/tst-get-cpu-features.c b/sysdeps/x86/tst-get-cpu-features.c > index 6bfdef0829..3447d17e23 100644 > --- a/sysdeps/x86/tst-get-cpu-features.c > +++ b/sysdeps/x86/tst-get-cpu-features.c > @@ -1,4 +1,4 @@ > -/* Test case for x86 __get_cpu_features interface > +/* Test case for __x86_get_cpu_features interface > Copyright (C) 2015-2020 Free Software Foundation, Inc. > This file is part of the GNU C Library. > > @@ -18,7 +18,7 @@ > > #include <stdlib.h> > #include <stdio.h> > -#include <cpu-features.h> > +#include <sys/platform/x86.h> > #include <support/check.h> > > #define CHECK_CPU_FEATURE(name) \ > @@ -45,7 +45,7 @@ static const char * const cpu_kinds[] = > static int > do_test (void) > { > - const struct cpu_features *cpu_features = __get_cpu_features (); > + const struct cpu_features *cpu_features = __x86_get_cpu_features (0); > > switch (cpu_features->basic.kind) > { > diff --git a/sysdeps/x86_64/fpu/math-tests-arch.h b/sysdeps/x86_64/fpu/math-tests-arch.h > index 33ea763de2..cc3c2b0c11 100644 > --- a/sysdeps/x86_64/fpu/math-tests-arch.h > +++ b/sysdeps/x86_64/fpu/math-tests-arch.h > @@ -16,7 +16,7 @@ > License along with the GNU C Library; if not, see > <https://www.gnu.org/licenses/>. */ > > -#include <cpu-features.h> > +#include <sys/platform/x86.h> > > #if defined REQUIRE_AVX > > diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile > index 395e432c09..9477538af4 100644 > --- a/sysdeps/x86_64/multiarch/Makefile > +++ b/sysdeps/x86_64/multiarch/Makefile > @@ -1,7 +1,3 @@ > -ifeq ($(subdir),csu) > -tests += test-multiarch > -endif > - > ifeq ($(subdir),string) > > sysdep_routines += strncat-c stpncpy-c strncpy-c \ > diff --git a/sysdeps/x86_64/multiarch/test-multiarch.c b/sysdeps/x86_64/multiarch/test-multiarch.c > deleted file mode 100644 > index 2782803e73..0000000000 > --- a/sysdeps/x86_64/multiarch/test-multiarch.c > +++ /dev/null > @@ -1,96 +0,0 @@ > -/* Test CPU feature data. > - This file is part of the GNU C Library. > - Copyright (C) 2012-2020 Free Software Foundation, Inc. > - > - 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 > - <https://www.gnu.org/licenses/>. */ > - > -#include <cpu-features.h> > -#include <stdio.h> > -#include <stdlib.h> > -#include <string.h> > - > -static char *cpu_flags; > - > -/* Search for flags in /proc/cpuinfo and store line > - in cpu_flags. */ > -void > -get_cpuinfo (void) > -{ > - FILE *f; > - char *line = NULL; > - size_t len = 0; > - ssize_t read; > - > - f = fopen ("/proc/cpuinfo", "r"); > - if (f == NULL) > - { > - printf ("cannot open /proc/cpuinfo\n"); > - exit (1); > - } > - > - while ((read = getline (&line, &len, f)) != -1) > - { > - if (strncmp (line, "flags", 5) == 0) > - { > - cpu_flags = strdup (line); > - break; > - } > - } > - fclose (f); > - free (line); > -} > - > -int > -check_proc (const char *proc_name, int flag, const char *name) > -{ > - int found = 0; > - > - printf ("Checking %s:\n", name); > - printf (" init-arch %d\n", flag); > - if (strstr (cpu_flags, proc_name) != NULL) > - found = 1; > - printf (" cpuinfo (%s) %d\n", proc_name, found); > - > - if (found != flag) > - printf (" *** failure ***\n"); > - > - return (found != flag); > -} > - > -static int > -do_test (int argc, char **argv) > -{ > - int fails; > - > - get_cpuinfo (); > - fails = check_proc ("avx", CPU_FEATURE_USABLE (AVX), > - "CPU_FEATURE_USABLE (AVX)"); > - fails += check_proc ("fma4", CPU_FEATURE_USABLE (FMA4), > - "CPU_FEATURE_USABLE (FMA4)"); > - fails += check_proc ("sse4_2", CPU_FEATURE_USABLE (SSE4_2), > - "CPU_FEATURE_USABLE (SSE4_2)"); > - fails += check_proc ("sse4_1", CPU_FEATURE_USABLE (SSE4_1) > - , "CPU_FEATURE_USABLE (SSE4_1)"); > - fails += check_proc ("ssse3", CPU_FEATURE_USABLE (SSSE3), > - "CPU_FEATURE_USABLE (SSSE3)"); > - fails += check_proc ("popcnt", CPU_FEATURE_USABLE (POPCNT), > - "CPU_FEATURE_USABLE (POPCNT)"); > - > - printf ("%d differences between /proc/cpuinfo and glibc code.\n", fails); > - > - return (fails != 0); > -} > - > -#include "../../../test-skeleton.c" > -- > 2.26.2 > -- H.J. ^ permalink raw reply [flat|nested] 7+ messages in thread
* PING^2: V8 [PATCH 2/2] x86: Install <sys/platform/x86.h> [BZ #26124] 2020-08-12 14:00 ` PING: " H.J. Lu @ 2020-08-19 12:52 ` H.J. Lu 2020-09-02 12:55 ` PING^3: " H.J. Lu 0 siblings, 1 reply; 7+ messages in thread From: H.J. Lu @ 2020-08-19 12:52 UTC (permalink / raw) To: GNU C Library, Carlos O'Donell, Florian Weimer On Wed, Aug 12, 2020 at 7:00 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > On Wed, Aug 5, 2020 at 4:01 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > Install <sys/platform/x86.h> so that programmers can do > > > > #if __has_include(<sys/platform/x86.h>) > > #include <sys/platform/x86.h> > > #endif > > ... > > > > if (CPU_FEATURE_USABLE (SSE2)) > > ... > > if (CPU_FEATURE_USABLE (AVX2)) > > ... > > > > <sys/platform/x86.h> exports only: > > > > enum > > { > > COMMON_CPUID_INDEX_1 = 0, > > COMMON_CPUID_INDEX_7, > > COMMON_CPUID_INDEX_80000001, > > COMMON_CPUID_INDEX_D_ECX_1, > > COMMON_CPUID_INDEX_80000007, > > COMMON_CPUID_INDEX_80000008, > > COMMON_CPUID_INDEX_7_ECX_1, > > /* Keep the following line at the end. */ > > COMMON_CPUID_INDEX_MAX > > }; > > > > struct cpuid_features > > { > > struct cpuid_registers cpuid; > > struct cpuid_registers usable; > > }; > > > > struct cpu_features > > { > > struct cpu_features_basic basic; > > struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; > > }; > > > > /* Get a pointer to the CPU features structure. */ > > extern const struct cpu_features *__x86_get_cpu_features > > (unsigned int max) __attribute__ ((const)); > > > > Since all feature checks are done through macros, programs compiled with > > a newer <sys/platform/x86.h> are compatible with the older glibc binaries > > as long as the layout of struct cpu_features is identical. The features > > array can be expanded with backward binary compatibility for both .o and > > .so files. When COMMON_CPUID_INDEX_MAX is increased to support new > > processor features, __x86_get_cpu_features in the older glibc binaries > > returns NULL and HAS_CPU_FEATURE/CPU_FEATURE_USABLE return false on the > > new processor feature. No new symbol version is neeeded. > > > > Both CPU_FEATURE_USABLE and HAS_CPU_FEATURE are provided. HAS_CPU_FEATURE > > can be used to identify processor features. > > > > Note: Although GCC has __builtin_cpu_supports, it only supports a subset > > of <sys/platform/x86.h> and it is equivalent to CPU_FEATURE_USABLE. It > > doesn't support HAS_CPU_FEATURE. PING: https://sourceware.org/pipermail/libc-alpha/2020-August/116865.html -- H.J. ^ permalink raw reply [flat|nested] 7+ messages in thread
* PING^3: V8 [PATCH 2/2] x86: Install <sys/platform/x86.h> [BZ #26124] 2020-08-19 12:52 ` PING^2: " H.J. Lu @ 2020-09-02 12:55 ` H.J. Lu 2020-09-07 18:21 ` H.J. Lu 0 siblings, 1 reply; 7+ messages in thread From: H.J. Lu @ 2020-09-02 12:55 UTC (permalink / raw) To: GNU C Library, Carlos O'Donell, Florian Weimer On Wed, Aug 19, 2020 at 5:52 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > On Wed, Aug 12, 2020 at 7:00 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > On Wed, Aug 5, 2020 at 4:01 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > > > Install <sys/platform/x86.h> so that programmers can do > > > > > > #if __has_include(<sys/platform/x86.h>) > > > #include <sys/platform/x86.h> > > > #endif > > > ... > > > > > > if (CPU_FEATURE_USABLE (SSE2)) > > > ... > > > if (CPU_FEATURE_USABLE (AVX2)) > > > ... > > > > > > <sys/platform/x86.h> exports only: > > > > > > enum > > > { > > > COMMON_CPUID_INDEX_1 = 0, > > > COMMON_CPUID_INDEX_7, > > > COMMON_CPUID_INDEX_80000001, > > > COMMON_CPUID_INDEX_D_ECX_1, > > > COMMON_CPUID_INDEX_80000007, > > > COMMON_CPUID_INDEX_80000008, > > > COMMON_CPUID_INDEX_7_ECX_1, > > > /* Keep the following line at the end. */ > > > COMMON_CPUID_INDEX_MAX > > > }; > > > > > > struct cpuid_features > > > { > > > struct cpuid_registers cpuid; > > > struct cpuid_registers usable; > > > }; > > > > > > struct cpu_features > > > { > > > struct cpu_features_basic basic; > > > struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; > > > }; > > > > > > /* Get a pointer to the CPU features structure. */ > > > extern const struct cpu_features *__x86_get_cpu_features > > > (unsigned int max) __attribute__ ((const)); > > > > > > Since all feature checks are done through macros, programs compiled with > > > a newer <sys/platform/x86.h> are compatible with the older glibc binaries > > > as long as the layout of struct cpu_features is identical. The features > > > array can be expanded with backward binary compatibility for both .o and > > > .so files. When COMMON_CPUID_INDEX_MAX is increased to support new > > > processor features, __x86_get_cpu_features in the older glibc binaries > > > returns NULL and HAS_CPU_FEATURE/CPU_FEATURE_USABLE return false on the > > > new processor feature. No new symbol version is neeeded. > > > > > > Both CPU_FEATURE_USABLE and HAS_CPU_FEATURE are provided. HAS_CPU_FEATURE > > > can be used to identify processor features. > > > > > > Note: Although GCC has __builtin_cpu_supports, it only supports a subset > > > of <sys/platform/x86.h> and it is equivalent to CPU_FEATURE_USABLE. It > > > doesn't support HAS_CPU_FEATURE. > > PING: > > https://sourceware.org/pipermail/libc-alpha/2020-August/116865.html > If there are no more comments, I will check it next Friday, Sept 11. -- H.J. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: PING^3: V8 [PATCH 2/2] x86: Install <sys/platform/x86.h> [BZ #26124] 2020-09-02 12:55 ` PING^3: " H.J. Lu @ 2020-09-07 18:21 ` H.J. Lu 2020-09-10 14:29 ` H.J. Lu 0 siblings, 1 reply; 7+ messages in thread From: H.J. Lu @ 2020-09-07 18:21 UTC (permalink / raw) To: GNU C Library, Carlos O'Donell, Florian Weimer [-- Attachment #1: Type: text/plain, Size: 2778 bytes --] On Wed, Sep 2, 2020 at 5:55 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > On Wed, Aug 19, 2020 at 5:52 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > On Wed, Aug 12, 2020 at 7:00 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > > > On Wed, Aug 5, 2020 at 4:01 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > > > > > Install <sys/platform/x86.h> so that programmers can do > > > > > > > > #if __has_include(<sys/platform/x86.h>) > > > > #include <sys/platform/x86.h> > > > > #endif > > > > ... > > > > > > > > if (CPU_FEATURE_USABLE (SSE2)) > > > > ... > > > > if (CPU_FEATURE_USABLE (AVX2)) > > > > ... > > > > > > > > <sys/platform/x86.h> exports only: > > > > > > > > enum > > > > { > > > > COMMON_CPUID_INDEX_1 = 0, > > > > COMMON_CPUID_INDEX_7, > > > > COMMON_CPUID_INDEX_80000001, > > > > COMMON_CPUID_INDEX_D_ECX_1, > > > > COMMON_CPUID_INDEX_80000007, > > > > COMMON_CPUID_INDEX_80000008, > > > > COMMON_CPUID_INDEX_7_ECX_1, > > > > /* Keep the following line at the end. */ > > > > COMMON_CPUID_INDEX_MAX > > > > }; > > > > > > > > struct cpuid_features > > > > { > > > > struct cpuid_registers cpuid; > > > > struct cpuid_registers usable; > > > > }; > > > > > > > > struct cpu_features > > > > { > > > > struct cpu_features_basic basic; > > > > struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; > > > > }; > > > > > > > > /* Get a pointer to the CPU features structure. */ > > > > extern const struct cpu_features *__x86_get_cpu_features > > > > (unsigned int max) __attribute__ ((const)); > > > > > > > > Since all feature checks are done through macros, programs compiled with > > > > a newer <sys/platform/x86.h> are compatible with the older glibc binaries > > > > as long as the layout of struct cpu_features is identical. The features > > > > array can be expanded with backward binary compatibility for both .o and > > > > .so files. When COMMON_CPUID_INDEX_MAX is increased to support new > > > > processor features, __x86_get_cpu_features in the older glibc binaries > > > > returns NULL and HAS_CPU_FEATURE/CPU_FEATURE_USABLE return false on the > > > > new processor feature. No new symbol version is neeeded. > > > > > > > > Both CPU_FEATURE_USABLE and HAS_CPU_FEATURE are provided. HAS_CPU_FEATURE > > > > can be used to identify processor features. > > > > > > > > Note: Although GCC has __builtin_cpu_supports, it only supports a subset > > > > of <sys/platform/x86.h> and it is equivalent to CPU_FEATURE_USABLE. It > > > > doesn't support HAS_CPU_FEATURE. > > > > PING: > > > > https://sourceware.org/pipermail/libc-alpha/2020-August/116865.html > > > > If there are no more comments, I will check it next Friday, > Sept 11. > I am enclosing the rebased patch I am checking in this Friday. -- H.J. [-- Attachment #2: 0001-x86-Install-sys-platform-x86.h-BZ-26124.patch --] [-- Type: text/x-patch, Size: 52609 bytes --] From 56b14744767e741b498036878d94c7a866a81b6d Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.tools@gmail.com> Date: Mon, 29 Jun 2020 18:30:54 -0700 Subject: [PATCH] x86: Install <sys/platform/x86.h> [BZ #26124] Install <sys/platform/x86.h> so that programmers can do #if __has_include(<sys/platform/x86.h>) #include <sys/platform/x86.h> #endif ... if (CPU_FEATURE_USABLE (SSE2)) ... if (CPU_FEATURE_USABLE (AVX2)) ... <sys/platform/x86.h> exports only: enum { COMMON_CPUID_INDEX_1 = 0, COMMON_CPUID_INDEX_7, COMMON_CPUID_INDEX_80000001, COMMON_CPUID_INDEX_D_ECX_1, COMMON_CPUID_INDEX_80000007, COMMON_CPUID_INDEX_80000008, COMMON_CPUID_INDEX_7_ECX_1, /* Keep the following line at the end. */ COMMON_CPUID_INDEX_MAX }; struct cpuid_features { struct cpuid_registers cpuid; struct cpuid_registers usable; }; struct cpu_features { struct cpu_features_basic basic; struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; }; /* Get a pointer to the CPU features structure. */ extern const struct cpu_features *__x86_get_cpu_features (unsigned int max) __attribute__ ((const)); Since all feature checks are done through macros, programs compiled with a newer <sys/platform/x86.h> are compatible with the older glibc binaries as long as the layout of struct cpu_features is identical. The features array can be expanded with backward binary compatibility for both .o and .so files. When COMMON_CPUID_INDEX_MAX is increased to support new processor features, __x86_get_cpu_features in the older glibc binaries returns NULL and HAS_CPU_FEATURE/CPU_FEATURE_USABLE return false on the new processor feature. No new symbol version is neeeded. Both CPU_FEATURE_USABLE and HAS_CPU_FEATURE are provided. HAS_CPU_FEATURE can be used to identify processor features. Note: Although GCC has __builtin_cpu_supports, it only supports a subset of <sys/platform/x86.h> and it is equivalent to CPU_FEATURE_USABLE. It doesn't support HAS_CPU_FEATURE. --- NEWS | 1 + manual/platform.texi | 517 ++++++++++++++++++ sysdeps/i386/i686/multiarch/Makefile | 4 - sysdeps/i386/i686/multiarch/test-multiarch.c | 1 - sysdeps/unix/sysv/linux/i386/ld.abilist | 1 + sysdeps/unix/sysv/linux/x86_64/64/ld.abilist | 1 + sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist | 1 + sysdeps/x86/Makefile | 4 +- sysdeps/x86/Versions | 4 +- sysdeps/x86/dl-get-cpu-features.c | 6 +- sysdeps/x86/include/cpu-features.h | 183 +++++++ .../{cpu-features.h => sys/platform/x86.h} | 150 +---- sysdeps/x86/tst-cpu-features-cpuinfo.c | 250 +++++++++ sysdeps/x86/tst-cpu-features-supports.c | 192 +++++++ sysdeps/x86/tst-get-cpu-features.c | 6 +- sysdeps/x86_64/fpu/math-tests-arch.h | 2 +- sysdeps/x86_64/multiarch/Makefile | 4 - sysdeps/x86_64/multiarch/test-multiarch.c | 96 ---- 18 files changed, 1176 insertions(+), 247 deletions(-) delete mode 100644 sysdeps/i386/i686/multiarch/test-multiarch.c create mode 100644 sysdeps/x86/include/cpu-features.h rename sysdeps/x86/{cpu-features.h => sys/platform/x86.h} (81%) create mode 100644 sysdeps/x86/tst-cpu-features-cpuinfo.c create mode 100644 sysdeps/x86/tst-cpu-features-supports.c delete mode 100644 sysdeps/x86_64/multiarch/test-multiarch.c diff --git a/NEWS b/NEWS index 06e43e0453..878221639b 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ Version 2.33 Major new features: +* Add <sys/platform/x86.h> to provide query macros for x86 CPU features. * Support for the RISC-V ISA running on Linux has been expanded to run on 32-bit hardware. This is supported for the following ISA and ABI pairs: diff --git a/manual/platform.texi b/manual/platform.texi index 504addc956..2c145acdc3 100644 --- a/manual/platform.texi +++ b/manual/platform.texi @@ -7,6 +7,7 @@ @menu * PowerPC:: Facilities Specific to the PowerPC Architecture * RISC-V:: Facilities Specific to the RISC-V Architecture +* X86:: Facilities Specific to the X86 Architecture @end menu @node PowerPC @@ -134,3 +135,519 @@ all threads in the current process. Setting the ordering on only the current thread is necessary. All other flag bits are reserved. @end deftypefun + +@node X86 +@appendixsec X86-specific Facilities + +Facilities specific to X86 that are not specific to a particular +operating system are declared in @file{sys/platform/x86.h}. + +@deftypefun {const struct cpu_features *} __x86_get_cpu_features (unsigned int @var{max}) +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +Return a pointer to x86 CPU feature structure used by query macros for x86 +CPU features. If @var{max} exceeds @code{COMMON_CPUID_INDEX_MAX} which +is the limit of the CPUID leaves supported by @Theglibc{}, the function +returns @code{NULL}, indicating that the queried processor feature is +unsupported by @Theglibc{} run-time. +@end deftypefun + +@deftypefn Macro int HAS_CPU_FEATURE (@var{name}) +This macro returns a nonzero value (true) if the processor has the feature +@var{name}. +@end deftypefn + +@deftypefn Macro int CPU_FEATURE_USABLE (@var{name}) +This macro returns a nonzero value (true) if the processor has the feature +@var{name} and the feature is supported by the operating system. +@end deftypefn + +The supported processor features are: + +@itemize @bullet + +@item +@code{ACPI} -- Thermal Monitor and Software Controlled Clock Facilities. + +@item +@code{ADX} -- ADX instruction extensions. + +@item +@code{APIC} -- APIC On-Chip. + +@item +@code{AES} -- The AES instruction extensions. + +@item +@code{AMX_BF16} -- Tile computational operations on bfloat16 numbers. + +@item +@code{AMX_INT8} -- Tile computational operations on 8-bit numbers. + +@item +@code{AMX_TILE} -- Tile architecture. + +@item +@code{ARCH_CAPABILITIES} -- IA32_ARCH_CAPABILITIES MSR. + +@item +@code{AVX} -- The AVX instruction extensions. + +@item +@code{AVX2} -- The AVX2 instruction extensions. + +@item +@code{AVX512_4FMAPS} -- The AVX512_4FMAPS instruction extensions. + +@item +@code{AVX512_4VNNIW} -- The AVX512_4VNNIW instruction extensions. + +@item +@code{AVX512_BF16} -- The AVX512_BF16 instruction extensions. + +@item +@code{AVX512_BITALG} -- The AVX512_BITALG instruction extensions. + +@item +@code{AVX512_IFMA} -- The AVX512_IFMA instruction extensions. + +@item +@code{AVX512_VBMI} -- The AVX512_VBMI instruction extensions. + +@item +@code{AVX512_VBMI2} -- The AVX512_VBMI2 instruction extensions. + +@item +@code{AVX512_VNNI} -- The AVX512_VNNI instruction extensions. + +@item +@code{AVX512_VP2INTERSECT} -- The AVX512_VP2INTERSECT instruction +extensions. + +@item +@code{AVX512_VPOPCNTDQ} -- The AVX512_VPOPCNTDQ instruction extensions. + +@item +@code{AVX512BW} -- The AVX512BW instruction extensions. + +@item +@code{AVX512CD} -- The AVX512CD instruction extensions. + +@item +@code{AVX512ER} -- The AVX512ER instruction extensions. + +@item +@code{AVX512DQ} -- The AVX512DQ instruction extensions. + +@item +@code{AVX512F} -- The AVX512F instruction extensions. + +@item +@code{AVX512PF} -- The AVX512PF instruction extensions. + +@item +@code{AVX512VL} -- The AVX512VL instruction extensions. + +@item +@code{BMI1} -- BMI1 instructions. + +@item +@code{BMI2} -- BMI2 instructions. + +@item +@code{CLDEMOTE} -- CLDEMOTE instruction. + +@item +@code{CLFLUSHOPT} -- CLFLUSHOPT instruction. + +@item +@code{CLFSH} -- CLFLUSH instruction. + +@item +@code{CLWB} -- CLWB instruction. + +@item +@code{CMOV} -- Conditional Move instructions. + +@item +@code{CMPXCHG16B} -- CMPXCHG16B instruction. + +@item +@code{CNXT_ID} -- L1 Context ID. + +@item +@code{CORE_CAPABILITIES} -- IA32_CORE_CAPABILITIES MSR. + +@item +@code{CX8} -- CMPXCHG8B instruction. + +@item +@code{DCA} -- Data prefetch from a memory mapped device. + +@item +@code{DE} -- Debugging Extensions. + +@item +@code{DEPR_FPU_CS_DS} -- Deprecates FPU CS and FPU DS values. + +@item +@code{DS} -- Debug Store. + +@item +@code{DS_CPL} -- CPL Qualified Debug Store. + +@item +@code{DTES64} -- 64-bit DS Area. + +@item +@code{EIST} -- Enhanced Intel SpeedStep technology. + +@item +@code{ENQCMD} -- Enqueue Stores instructions. + +@item +@code{ERMS} -- Enhanced REP MOVSB/STOSB. + +@item +@code{F16C} -- 16-bit floating-point conversion instructions. + +@item +@code{FMA} -- FMA extensions using YMM state. + +@item +@code{FMA4} -- FMA4 instruction extensions. + +@item +@code{FPU} -- X87 Floating Point Unit On-Chip. + +@item +@code{FSGSBASE} -- RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE instructions. + +@item +@code{FSRM} -- Fast Short REP MOV. + +@item +@code{FXSR} -- FXSAVE and FXRSTOR instructions. + +@item +@code{GFNI} -- GFNI instruction extensions. + +@item +@code{HLE} -- HLE instruction extensions. + +@item +@code{HTT} -- Max APIC IDs reserved field is Valid. + +@item +@code{HYBRID} -- Hybrid processor. + +@item +@code{IBRS_IBPB} -- Indirect branch restricted speculation (IBRS) and +the indirect branch predictor barrier (IBPB). + +@item +@code{IBT} -- Intel Indirect Branch Tracking instruction extensions. + +@item +@code{INVARIANT_TSC} -- Invariant TSC. + +@item +@code{INVPCID} -- INVPCID instruction. + +@item +@code{L1D_FLUSH} -- IA32_FLUSH_CMD MSR. + +@item +@code{LAHF64_SAHF64} -- LAHF/SAHF available in 64-bit mode. + +@item +@code{LM} -- Long mode. + +@item +@code{LWP} -- Lightweight profiling. + +@item +@code{LZCNT} -- LZCNT instruction. + +@item +@code{MCA} -- Machine Check Architecture. + +@item +@code{MCE} -- Machine Check Exception. + +@item +@code{MD_CLEAR} -- MD_CLEAR. + +@item +@code{MMX} -- Intel MMX Technology. + +@item +@code{MONITOR} -- MONITOR/MWAIT instructions. + +@item +@code{MOVBE} -- MOVBE instruction. + +@item +@code{MOVDIRI} -- MOVDIRI instruction. + +@item +@code{MOVDIR64B} -- MOVDIR64B instruction. + +@item +@code{MPX} -- Intel Memory Protection Extensions. + +@item +@code{MSR} -- Model Specific Registers RDMSR and WRMSR instructions. + +@item +@code{MTRR} -- Memory Type Range Registers. + +@item +@code{NX} -- No-execute page protection. + +@item +@code{OSPKE} -- OS has set CR4.PKE to enable protection keys. + +@item +@code{OSXSAVE} -- The OS has set CR4.OSXSAVE[bit 18] to enable +XSETBV/XGETBV instructions to access XCR0 and to support processor +extended state management using XSAVE/XRSTOR. + +@item +@code{PAE} -- Physical Address Extension. + +@item +@code{PAGE1GB} -- 1-GByte page. + +@item +@code{PAT} -- Page Attribute Table. + +@item +@code{PBE} -- Pending Break Enable. + +@item +@code{PCID} -- Process-context identifiers. + +@item +@code{PCLMULQDQ} -- PCLMULQDQ instruction. + +@item +@code{PCONFIG} -- PCONFIG instruction. + +@item +@code{PDCM} -- Perfmon and Debug Capability. + +@item +@code{PGE} -- Page Global Bit. + +@item +@code{PKS} -- Protection keys for supervisor-mode pages. + +@item +@code{PKU} -- Protection keys for user-mode pages. + +@item +@code{POPCNT} -- POPCNT instruction. + +@item +@code{PREFETCHW} -- PREFETCHW instruction. + +@item +@code{PREFETCHWT1} -- PREFETCHWT1 instruction. + +@item +@code{PSE} -- Page Size Extension. + +@item +@code{PSE_36} -- 36-Bit Page Size Extension. + +@item +@code{PSN} -- Processor Serial Number. + +@item +@code{RDPID} -- RDPID instruction. + +@item +@code{RDRAND} -- RDRAND instruction. + +@item +@code{RDSEED} -- RDSEED instruction. + +@item +@code{RDT_A} -- Intel Resource Director Technology (Intel RDT) Allocation +capability. + +@item +@code{RDT_M} -- Intel Resource Director Technology (Intel RDT) Monitoring +capability. + +@item +@code{RDTSCP} -- RDTSCP instruction. + +@item +@code{RTM} -- RTM instruction extensions. + +@item +@code{SDBG} -- IA32_DEBUG_INTERFACE MSR for silicon debug. + +@item +@code{SEP} -- SYSENTER and SYSEXIT instructions. + +@item +@code{SERIALIZE} -- SERIALIZE instruction. + +@item +@code{SGX} -- Intel Software Guard Extensions. + +@item +@code{SGX_LC} -- SGX Launch Configuration. + +@item +@code{SHA} -- SHA instruction extensions. + +@item +@code{SHSTK} -- Intel Shadow Stack instruction extensions. + +@item +@code{SMAP} -- Supervisor-Mode Access Prevention. + +@item +@code{SMEP} -- Supervisor-Mode Execution Prevention. + +@item +@code{SMX} -- Safer Mode Extensions. + +@item +@code{SS} -- Self Snoop. + +@item +@code{SSBD} -- Speculative Store Bypass Disable (SSBD). + +@item +@code{SSE} -- Streaming SIMD Extensions. + +@item +@code{SSE2} -- Streaming SIMD Extensions 2. + +@item +@code{SSE3} -- Streaming SIMD Extensions 3. + +@item +@code{SSE4_1} -- Streaming SIMD Extensions 4.1. + +@item +@code{SSE4_2} -- Streaming SIMD Extensions 4.2. + +@item +@code{SSE4A} -- SSE4A instruction extensions. + +@item +@code{SSSE3} -- Supplemental Streaming SIMD Extensions 3. + +@item +@code{STIBP} -- Single thread indirect branch predictors (STIBP). + +@item +@code{SVM} -- Secure Virtual Machine. + +@item +@code{SYSCALL_SYSRET} -- SYSCALL/SYSRET instructions. + +@item +@code{TBM} -- Trailing bit manipulation instructions. + +@item +@code{TM} -- Thermal Monitor. + +@item +@code{TM2} -- Thermal Monitor 2. + +@item +@code{TRACE} -- Intel Processor Trace. + +@item +@code{TSC} -- Time Stamp Counter. RDTSC instruction. + +@item +@code{TSC_ADJUST} -- IA32_TSC_ADJUST MSR. + +@item +@code{TSC_DEADLINE} -- Local APIC timer supports one-shot operation +using a TSC deadline value. + +@item +@code{TSXLDTRK} -- TSXLDTRK instructions. + +@item +@code{UMIP} -- User-mode instruction prevention. + +@item +@code{VAES} -- VAES instruction extensions. + +@item +@code{VME} -- Virtual 8086 Mode Enhancements. + +@item +@code{VMX} -- Virtual Machine Extensions. + +@item +@code{VPCLMULQDQ} -- VPCLMULQDQ instruction. + +@item +@code{WAITPKG} -- WAITPKG instruction extensions. + +@item +@code{WBNOINVD} -- WBINVD/WBNOINVD instructions. + +@item +@code{X2APIC} -- x2APIC. + +@item +@code{XFD} -- Extended Feature Disable (XFD). + +@item +@code{XGETBV_ECX_1} -- XGETBV with ECX = 1. + +@item +@code{XOP} -- XOP instruction extensions. + +@item +@code{XSAVE} -- The XSAVE/XRSTOR processor extended states feature, the +XSETBV/XGETBV instructions, and XCR0. + +@item +@code{XSAVEC} -- XSAVEC instruction. + +@item +@code{XSAVEOPT} -- XSAVEOPT instruction. + +@item +@code{XSAVES} -- XSAVES/XRSTORS instructions. + +@item +@code{XTPRUPDCTRL} -- xTPR Update Control. + +@end itemize + +You could query if a processor supports @code{AVX} with: + +@smallexample +#include <sys/platform/x86.h> + +int +support_avx (void) +@{ + return HAS_CPU_FEATURE (AVX); +@} +@end smallexample + +and if @code{AVX} is usable with: + +@smallexample +#include <sys/platform/x86.h> + +int +usable_avx (void) +@{ + return CPU_FEATURE_USABLE (AVX); +@} +@end smallexample diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile index bf75a9947f..c4897922d7 100644 --- a/sysdeps/i386/i686/multiarch/Makefile +++ b/sysdeps/i386/i686/multiarch/Makefile @@ -1,7 +1,3 @@ -ifeq ($(subdir),csu) -tests += test-multiarch -endif - ifeq ($(subdir),string) gen-as-const-headers += locale-defines.sym sysdep_routines += bzero-sse2 memset-sse2 memcpy-ssse3 mempcpy-ssse3 \ diff --git a/sysdeps/i386/i686/multiarch/test-multiarch.c b/sysdeps/i386/i686/multiarch/test-multiarch.c deleted file mode 100644 index 593cfec273..0000000000 --- a/sysdeps/i386/i686/multiarch/test-multiarch.c +++ /dev/null @@ -1 +0,0 @@ -#include <sysdeps/x86_64/multiarch/test-multiarch.c> diff --git a/sysdeps/unix/sysv/linux/i386/ld.abilist b/sysdeps/unix/sysv/linux/i386/ld.abilist index 0478e22071..04655651b0 100644 --- a/sysdeps/unix/sysv/linux/i386/ld.abilist +++ b/sysdeps/unix/sysv/linux/i386/ld.abilist @@ -3,3 +3,4 @@ GLIBC_2.1 __libc_stack_end D 0x4 GLIBC_2.1 _dl_mcount F GLIBC_2.3 ___tls_get_addr F GLIBC_2.3 __tls_get_addr F +GLIBC_2.33 __x86_get_cpu_features F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist index d3cdf7611e..e632c6198e 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/ld.abilist @@ -2,3 +2,4 @@ GLIBC_2.2.5 __libc_stack_end D 0x8 GLIBC_2.2.5 _dl_mcount F GLIBC_2.2.5 _r_debug D 0x28 GLIBC_2.3 __tls_get_addr F +GLIBC_2.33 __x86_get_cpu_features F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist index c70bccf782..9d9d0befde 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/ld.abilist @@ -2,3 +2,4 @@ GLIBC_2.16 __libc_stack_end D 0x4 GLIBC_2.16 __tls_get_addr F GLIBC_2.16 _dl_mcount F GLIBC_2.16 _r_debug D 0x14 +GLIBC_2.33 __x86_get_cpu_features F diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile index a6736aef25..c369faf00d 100644 --- a/sysdeps/x86/Makefile +++ b/sysdeps/x86/Makefile @@ -4,8 +4,10 @@ endif ifeq ($(subdir),elf) sysdep-dl-routines += dl-get-cpu-features +sysdep_headers += sys/platform/x86.h -tests += tst-get-cpu-features tst-get-cpu-features-static +tests += tst-get-cpu-features tst-get-cpu-features-static \ + tst-cpu-features-cpuinfo tst-cpu-features-supports tests-static += tst-get-cpu-features-static endif diff --git a/sysdeps/x86/Versions b/sysdeps/x86/Versions index e02923708e..59db578a9d 100644 --- a/sysdeps/x86/Versions +++ b/sysdeps/x86/Versions @@ -1,5 +1,5 @@ ld { - GLIBC_PRIVATE { - __get_cpu_features; + GLIBC_2.33 { + __x86_get_cpu_features; } } diff --git a/sysdeps/x86/dl-get-cpu-features.c b/sysdeps/x86/dl-get-cpu-features.c index 9d61cd56be..5f9e46b0c6 100644 --- a/sysdeps/x86/dl-get-cpu-features.c +++ b/sysdeps/x86/dl-get-cpu-features.c @@ -18,10 +18,12 @@ #include <ldsodefs.h> -#undef __get_cpu_features +#undef __x86_get_cpu_features const struct cpu_features * -__get_cpu_features (void) +__x86_get_cpu_features (unsigned int max) { + if (max > COMMON_CPUID_INDEX_MAX) + return NULL; return &GLRO(dl_x86_cpu_features); } diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h new file mode 100644 index 0000000000..dcf29b6fe8 --- /dev/null +++ b/sysdeps/x86/include/cpu-features.h @@ -0,0 +1,183 @@ +/* Data structure for x86 CPU features. + Copyright (C) 2020 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 + <https://www.gnu.org/licenses/>. */ + +#ifndef _PRIVATE_CPU_FEATURES_H +#define _PRIVATE_CPU_FEATURES_H 1 + +#ifdef _CPU_FEATURES_H +# error this should be impossible +#endif + +#ifndef _ISOMAC +/* Get most of the contents from the public header, but we define a + different `struct cpu_features' type for private use. */ +# define cpu_features cpu_features_public +# define __x86_get_cpu_features __x86_get_cpu_features_public +#endif + +#include <sysdeps/x86/sys/platform/x86.h> + +#ifndef _ISOMAC + +# undef cpu_features +# undef __x86_get_cpu_features +# define __get_cpu_features() __x86_get_cpu_features (0) + +enum +{ + /* The integer bit array index for the first set of preferred feature + bits. */ + PREFERRED_FEATURE_INDEX_1 = 0, + /* The current maximum size of the feature integer bit array. */ + PREFERRED_FEATURE_INDEX_MAX +}; + +/* Only used directly in cpu-features.c. */ +# define CPU_FEATURE_SET(ptr, name) \ + ptr->features[index_cpu_##name].usable.reg_##name |= bit_cpu_##name; +# define CPU_FEATURE_UNSET(ptr, name) \ + ptr->features[index_cpu_##name].usable.reg_##name &= ~bit_cpu_##name; +# define CPU_FEATURE_SET_USABLE(ptr, name) \ + ptr->features[index_cpu_##name].usable.reg_##name \ + |= ptr->features[index_cpu_##name].cpuid.reg_##name & bit_cpu_##name; +# define CPU_FEATURE_PREFERRED_P(ptr, name) \ + ((ptr->preferred[index_arch_##name] & bit_arch_##name) != 0) +# define CPU_FEATURE_CPU_P(ptr, name) \ + CPU_FEATURE_CHECK_P (ptr, name, cpuid) + +/* HAS_CPU_FEATURE evaluates to true if CPU supports the feature. */ +# undef HAS_CPU_FEATURE +# define HAS_CPU_FEATURE(name) \ + CPU_FEATURE_CPU_P (__x86_get_cpu_features (0), name) +/* CPU_FEATURE_USABLE evaluates to true if the feature is usable. */ +# undef CPU_FEATURE_USABLE +# define CPU_FEATURE_USABLE(name) \ + CPU_FEATURE_USABLE_P (__x86_get_cpu_features (0), name) +/* CPU_FEATURE_PREFER evaluates to true if we prefer the feature at + runtime. */ +# define CPU_FEATURE_PREFERRED(name) \ + CPU_FEATURE_PREFERRED_P(__get_cpu_features (), name) + +# define CPU_FEATURES_CPU_P(ptr, name) \ + CPU_FEATURE_CPU_P (ptr, name) +# define CPU_FEATURES_ARCH_P(ptr, name) \ + CPU_FEATURE_PREFERRED_P (ptr, name) +# define HAS_ARCH_FEATURE(name) \ + CPU_FEATURE_PREFERRED (name) + +/* PREFERRED_FEATURE_INDEX_1. */ +# define bit_arch_I586 (1u << 0) +# define bit_arch_I686 (1u << 1) +# define bit_arch_Fast_Rep_String (1u << 2) +# define bit_arch_Fast_Copy_Backward (1u << 3) +# define bit_arch_Fast_Unaligned_Load (1u << 4) +# define bit_arch_Fast_Unaligned_Copy (1u << 5) +# define bit_arch_Slow_BSF (1u << 6) +# define bit_arch_Slow_SSE4_2 (1u << 7) +# define bit_arch_AVX_Fast_Unaligned_Load (1u << 8) +# define bit_arch_Prefer_MAP_32BIT_EXEC (1u << 9) +# define bit_arch_Prefer_PMINUB_for_stringop (1u << 10) +# define bit_arch_Prefer_No_VZEROUPPER (1u << 11) +# define bit_arch_Prefer_ERMS (1u << 12) +# define bit_arch_Prefer_FSRM (1u << 13) +# define bit_arch_Prefer_No_AVX512 (1u << 14) +# define bit_arch_MathVec_Prefer_No_AVX512 (1u << 15) + +# define index_arch_Fast_Rep_String PREFERRED_FEATURE_INDEX_1 +# define index_arch_Fast_Copy_Backward PREFERRED_FEATURE_INDEX_1 +# define index_arch_Slow_BSF PREFERRED_FEATURE_INDEX_1 +# define index_arch_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 +# define index_arch_Prefer_PMINUB_for_stringop PREFERRED_FEATURE_INDEX_1 +# define index_arch_Fast_Unaligned_Copy PREFERRED_FEATURE_INDEX_1 +# define index_arch_I586 PREFERRED_FEATURE_INDEX_1 +# define index_arch_I686 PREFERRED_FEATURE_INDEX_1 +# define index_arch_Slow_SSE4_2 PREFERRED_FEATURE_INDEX_1 +# define index_arch_AVX_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 +# define index_arch_Prefer_MAP_32BIT_EXEC PREFERRED_FEATURE_INDEX_1 +# define index_arch_Prefer_No_VZEROUPPER PREFERRED_FEATURE_INDEX_1 +# define index_arch_Prefer_ERMS PREFERRED_FEATURE_INDEX_1 +# define index_arch_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 +# define index_arch_MathVec_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 +# define index_arch_Prefer_FSRM PREFERRED_FEATURE_INDEX_1 + +/* XCR0 Feature flags. */ +# define bit_XMM_state (1u << 1) +# define bit_YMM_state (1u << 2) +# define bit_Opmask_state (1u << 5) +# define bit_ZMM0_15_state (1u << 6) +# define bit_ZMM16_31_state (1u << 7) +# define bit_XTILECFG_state (1u << 17) +# define bit_XTILEDATA_state (1u << 18) + +struct cpu_features +{ + struct cpu_features_basic basic; + struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; + unsigned int preferred[PREFERRED_FEATURE_INDEX_MAX]; + /* The state size for XSAVEC or XSAVE. The type must be unsigned long + int so that we use + + sub xsave_state_size_offset(%rip) %RSP_LP + + in _dl_runtime_resolve. */ + unsigned long int xsave_state_size; + /* The full state size for XSAVE when XSAVEC is disabled by + + GLIBC_TUNABLES=glibc.cpu.hwcaps=-XSAVEC + */ + unsigned int xsave_state_full_size; + /* Data cache size for use in memory and string routines, typically + L1 size. */ + unsigned long int data_cache_size; + /* Shared cache size for use in memory and string routines, typically + L2 or L3 size. */ + unsigned long int shared_cache_size; + /* Threshold to use non temporal store. */ + unsigned long int non_temporal_threshold; + /* Threshold to use "rep movsb". */ + unsigned long int rep_movsb_threshold; + /* Threshold to use "rep stosb". */ + unsigned long int rep_stosb_threshold; +}; + +# if defined (_LIBC) && !IS_IN (nonlib) +/* Unused for x86. */ +# define INIT_ARCH() +# define __x86_get_cpu_features(max) (&GLRO(dl_x86_cpu_features)) +# endif + +# ifdef __x86_64__ +# define HAS_CPUID 1 +# elif (defined __i586__ || defined __pentium__ \ + || defined __geode__ || defined __k6__) +# define HAS_CPUID 1 +# define HAS_I586 1 +# define HAS_I686 HAS_ARCH_FEATURE (I686) +# elif defined __i486__ +# define HAS_CPUID 0 +# define HAS_I586 HAS_ARCH_FEATURE (I586) +# define HAS_I686 HAS_ARCH_FEATURE (I686) +# else +# define HAS_CPUID 1 +# define HAS_I586 1 +# define HAS_I686 1 +# endif + +#endif /* !_ISOMAC */ + +#endif /* include/cpu-features.h */ diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/sys/platform/x86.h similarity index 81% rename from sysdeps/x86/cpu-features.h rename to sysdeps/x86/sys/platform/x86.h index 78fcec251e..bf3727ebc0 100644 --- a/sysdeps/x86/cpu-features.h +++ b/sysdeps/x86/sys/platform/x86.h @@ -1,4 +1,5 @@ -/* This file is part of the GNU C Library. +/* Data structure for x86 CPU features. + This file is part of the GNU C Library. Copyright (C) 2008-2020 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or @@ -15,17 +16,8 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ -#ifndef cpu_features_h -#define cpu_features_h - -enum -{ - /* The integer bit array index for the first set of preferred feature - bits. */ - PREFERRED_FEATURE_INDEX_1 = 0, - /* The current maximum size of the feature integer bit array. */ - PREFERRED_FEATURE_INDEX_MAX -}; +#ifndef _SYS_PLATFORM_X86_H +#define _SYS_PLATFORM_X86_H enum { @@ -76,73 +68,32 @@ struct cpu_features { struct cpu_features_basic basic; struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; - unsigned int preferred[PREFERRED_FEATURE_INDEX_MAX]; - /* The state size for XSAVEC or XSAVE. The type must be unsigned long - int so that we use - - sub xsave_state_size_offset(%rip) %RSP_LP - - in _dl_runtime_resolve. */ - unsigned long int xsave_state_size; - /* The full state size for XSAVE when XSAVEC is disabled by - - GLIBC_TUNABLES=glibc.cpu.hwcaps=-XSAVEC - */ - unsigned int xsave_state_full_size; - /* Data cache size for use in memory and string routines, typically - L1 size. */ - unsigned long int data_cache_size; - /* Shared cache size for use in memory and string routines, typically - L2 or L3 size. */ - unsigned long int shared_cache_size; - /* Threshold to use non temporal store. */ - unsigned long int non_temporal_threshold; - /* Threshold to use "rep movsb". */ - unsigned long int rep_movsb_threshold; - /* Threshold to use "rep stosb". */ - unsigned long int rep_stosb_threshold; }; -/* Used from outside of glibc to get access to the CPU features - structure. */ -extern const struct cpu_features *__get_cpu_features (void) +/* Get a pointer to the CPU features structure. */ +extern const struct cpu_features *__x86_get_cpu_features (unsigned int) __attribute__ ((const)); -/* Only used directly in cpu-features.c. */ #define CPU_FEATURE_CHECK_P(ptr, name, check) \ ((ptr->features[index_cpu_##name].check.reg_##name \ & bit_cpu_##name) != 0) -#define CPU_FEATURE_SET(ptr, name) \ - ptr->features[index_cpu_##name].usable.reg_##name |= bit_cpu_##name; -#define CPU_FEATURE_UNSET(ptr, name) \ - ptr->features[index_cpu_##name].usable.reg_##name &= ~bit_cpu_##name; -#define CPU_FEATURE_SET_USABLE(ptr, name) \ - ptr->features[index_cpu_##name].usable.reg_##name \ - |= ptr->features[index_cpu_##name].cpuid.reg_##name & bit_cpu_##name; -#define CPU_FEATURE_PREFERRED_P(ptr, name) \ - ((ptr->preferred[index_arch_##name] & bit_arch_##name) != 0) #define CPU_FEATURE_CPU_P(ptr, name) \ CPU_FEATURE_CHECK_P (ptr, name, cpuid) #define CPU_FEATURE_USABLE_P(ptr, name) \ CPU_FEATURE_CHECK_P (ptr, name, usable) /* HAS_CPU_FEATURE evaluates to true if CPU supports the feature. */ -#define HAS_CPU_FEATURE(name) \ - CPU_FEATURE_CPU_P (__get_cpu_features (), name) +#define HAS_CPU_FEATURE(name) \ + (__extension__ \ + ({ const struct cpu_features *__ptr = \ + __x86_get_cpu_features (COMMON_CPUID_INDEX_MAX); \ + __ptr && CPU_FEATURE_CPU_P (__ptr, name); })) /* CPU_FEATURE_USABLE evaluates to true if the feature is usable. */ -#define CPU_FEATURE_USABLE(name) \ - CPU_FEATURE_USABLE_P (__get_cpu_features (), name) -/* CPU_FEATURE_PREFER evaluates to true if we prefer the feature at - runtime. */ -#define CPU_FEATURE_PREFERRED(name) \ - CPU_FEATURE_PREFERRED_P(__get_cpu_features (), name) - -#define CPU_FEATURES_CPU_P(ptr, name) \ - CPU_FEATURE_CPU_P (ptr, name) -#define CPU_FEATURES_ARCH_P(ptr, name) \ - CPU_FEATURE_PREFERRED_P (ptr, name) -#define HAS_ARCH_FEATURE(name) \ - CPU_FEATURE_PREFERRED (name) +#define CPU_FEATURE_USABLE(name) \ + (__extension__ \ + ({ const struct cpu_features *__ptr = \ + __x86_get_cpu_features (COMMON_CPUID_INDEX_MAX); \ + __ptr && CPU_FEATURE_USABLE_P (__ptr, name); })) /* CPU features. */ @@ -787,71 +738,4 @@ extern const struct cpu_features *__get_cpu_features (void) /* EAX. */ #define reg_AVX512_BF16 eax -/* FEATURE_INDEX_2. */ -#define bit_arch_I586 (1u << 0) -#define bit_arch_I686 (1u << 1) -#define bit_arch_Fast_Rep_String (1u << 2) -#define bit_arch_Fast_Copy_Backward (1u << 3) -#define bit_arch_Fast_Unaligned_Load (1u << 4) -#define bit_arch_Fast_Unaligned_Copy (1u << 5) -#define bit_arch_Slow_BSF (1u << 6) -#define bit_arch_Slow_SSE4_2 (1u << 7) -#define bit_arch_AVX_Fast_Unaligned_Load (1u << 8) -#define bit_arch_Prefer_MAP_32BIT_EXEC (1u << 9) -#define bit_arch_Prefer_PMINUB_for_stringop (1u << 10) -#define bit_arch_Prefer_No_VZEROUPPER (1u << 11) -#define bit_arch_Prefer_ERMS (1u << 12) -#define bit_arch_Prefer_FSRM (1u << 13) -#define bit_arch_Prefer_No_AVX512 (1u << 14) -#define bit_arch_MathVec_Prefer_No_AVX512 (1u << 15) - -#define index_arch_Fast_Rep_String PREFERRED_FEATURE_INDEX_1 -#define index_arch_Fast_Copy_Backward PREFERRED_FEATURE_INDEX_1 -#define index_arch_Slow_BSF PREFERRED_FEATURE_INDEX_1 -#define index_arch_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 -#define index_arch_Prefer_PMINUB_for_stringop PREFERRED_FEATURE_INDEX_1 -#define index_arch_Fast_Unaligned_Copy PREFERRED_FEATURE_INDEX_1 -#define index_arch_I586 PREFERRED_FEATURE_INDEX_1 -#define index_arch_I686 PREFERRED_FEATURE_INDEX_1 -#define index_arch_Slow_SSE4_2 PREFERRED_FEATURE_INDEX_1 -#define index_arch_AVX_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 -#define index_arch_Prefer_MAP_32BIT_EXEC PREFERRED_FEATURE_INDEX_1 -#define index_arch_Prefer_No_VZEROUPPER PREFERRED_FEATURE_INDEX_1 -#define index_arch_Prefer_ERMS PREFERRED_FEATURE_INDEX_1 -#define index_arch_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 -#define index_arch_MathVec_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 -#define index_arch_Prefer_FSRM PREFERRED_FEATURE_INDEX_1 - -/* XCR0 Feature flags. */ -#define bit_XMM_state (1u << 1) -#define bit_YMM_state (1u << 2) -#define bit_Opmask_state (1u << 5) -#define bit_ZMM0_15_state (1u << 6) -#define bit_ZMM16_31_state (1u << 7) -#define bit_XTILECFG_state (1u << 17) -#define bit_XTILEDATA_state (1u << 18) - -# if defined (_LIBC) && !IS_IN (nonlib) -/* Unused for x86. */ -# define INIT_ARCH() -# define __get_cpu_features() (&GLRO(dl_x86_cpu_features)) -# endif - -#ifdef __x86_64__ -# define HAS_CPUID 1 -#elif (defined __i586__ || defined __pentium__ \ - || defined __geode__ || defined __k6__) -# define HAS_CPUID 1 -# define HAS_I586 1 -# define HAS_I686 HAS_ARCH_FEATURE (I686) -#elif defined __i486__ -# define HAS_CPUID 0 -# define HAS_I586 HAS_ARCH_FEATURE (I586) -# define HAS_I686 HAS_ARCH_FEATURE (I686) -#else -# define HAS_CPUID 1 -# define HAS_I586 1 -# define HAS_I686 1 -#endif - -#endif /* cpu_features_h */ +#endif /* _SYS_PLATFORM_X86_H */ diff --git a/sysdeps/x86/tst-cpu-features-cpuinfo.c b/sysdeps/x86/tst-cpu-features-cpuinfo.c new file mode 100644 index 0000000000..96277284d1 --- /dev/null +++ b/sysdeps/x86/tst-cpu-features-cpuinfo.c @@ -0,0 +1,250 @@ +/* Test CPU feature data against /proc/cpuinfo. + This file is part of the GNU C Library. + Copyright (C) 2012-2020 Free Software Foundation, Inc. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <sys/platform/x86.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +static char *cpu_flags; + +/* Search for flags in /proc/cpuinfo and store line + in cpu_flags. */ +void +get_cpuinfo (void) +{ + FILE *f; + char *line = NULL; + size_t len = 0; + ssize_t read; + + f = fopen ("/proc/cpuinfo", "r"); + if (f == NULL) + { + printf ("cannot open /proc/cpuinfo\n"); + exit (1); + } + + while ((read = getline (&line, &len, f)) != -1) + { + if (strncmp (line, "flags", 5) == 0) + { + cpu_flags = strdup (line); + break; + } + } + fclose (f); + free (line); +} + +int +check_proc (const char *proc_name, int flag, int usable, const char *name) +{ + int found = 0; + + printf ("Checking %s:\n", name); + if (!usable) + { + printf (" %s: insufficient usable info, skipped\n", name); + return 0; + } + printf (" %s: %d\n", name, flag); + if (strstr (cpu_flags, proc_name) != NULL) + found = 1; + printf (" cpuinfo (%s): %d\n", proc_name, found); + + if (found != flag) + printf (" *** failure ***\n"); + + return (found != flag); +} + +#define CHECK_PROC(str, name) \ + check_proc (#str, HAS_CPU_FEATURE (name), CPU_FEATURE_USABLE (name), \ + "HAS_CPU_FEATURE (" #name ")"); + +static int +do_test (int argc, char **argv) +{ + int fails = 0; + + get_cpuinfo (); + fails += CHECK_PROC (acpi, ACPI); + fails += CHECK_PROC (adx, ADX); + fails += CHECK_PROC (apic, APIC); + fails += CHECK_PROC (aes, AES); + fails += CHECK_PROC (amx_bf16, AMX_BF16); + fails += CHECK_PROC (amx_int8, AMX_INT8); + fails += CHECK_PROC (amx_tile, AMX_TILE); + fails += CHECK_PROC (arch_capabilities, ARCH_CAPABILITIES); + fails += CHECK_PROC (avx, AVX); + fails += CHECK_PROC (avx2, AVX2); + fails += CHECK_PROC (avx512_4fmaps, AVX512_4FMAPS); + fails += CHECK_PROC (avx512_4vnniw, AVX512_4VNNIW); + fails += CHECK_PROC (avx512_bf16, AVX512_BF16); + fails += CHECK_PROC (avx512_bitalg, AVX512_BITALG); + fails += CHECK_PROC (avx512ifma, AVX512_IFMA); + fails += CHECK_PROC (avx512_vbmi, AVX512_VBMI); + fails += CHECK_PROC (avx512_vbmi2, AVX512_VBMI2); + fails += CHECK_PROC (avx512_vnni, AVX512_VNNI); + fails += CHECK_PROC (avx512_vp2intersect, AVX512_VP2INTERSECT); + fails += CHECK_PROC (avx512_vpopcntdq, AVX512_VPOPCNTDQ); + fails += CHECK_PROC (avx512bw, AVX512BW); + fails += CHECK_PROC (avx512cd, AVX512CD); + fails += CHECK_PROC (avx512er, AVX512ER); + fails += CHECK_PROC (avx512dq, AVX512DQ); + fails += CHECK_PROC (avx512f, AVX512F); + fails += CHECK_PROC (avx512pf, AVX512PF); + fails += CHECK_PROC (avx512vl, AVX512VL); + fails += CHECK_PROC (bmi1, BMI1); + fails += CHECK_PROC (bmi2, BMI2); + fails += CHECK_PROC (cldemote, CLDEMOTE); + fails += CHECK_PROC (clflushopt, CLFLUSHOPT); + fails += CHECK_PROC (clflush, CLFSH); + fails += CHECK_PROC (clwb, CLWB); + fails += CHECK_PROC (cmov, CMOV); + fails += CHECK_PROC (cx16, CMPXCHG16B); + fails += CHECK_PROC (cnxt_id, CNXT_ID); + fails += CHECK_PROC (core_capabilities, CORE_CAPABILITIES); + fails += CHECK_PROC (cx8, CX8); + fails += CHECK_PROC (dca, DCA); + fails += CHECK_PROC (de, DE); + fails += CHECK_PROC (zero_fcs_fds, DEPR_FPU_CS_DS); + fails += CHECK_PROC (ds, DS); + fails += CHECK_PROC (ds_cpl, DS_CPL); + fails += CHECK_PROC (dtes64, DTES64); + fails += CHECK_PROC (est, EIST); + fails += CHECK_PROC (enqcmd, ENQCMD); + fails += CHECK_PROC (erms, ERMS); + fails += CHECK_PROC (f16c, F16C); + fails += CHECK_PROC (fma, FMA); + fails += CHECK_PROC (fma4, FMA4); + fails += CHECK_PROC (fpu, FPU); + fails += CHECK_PROC (fsgsbase, FSGSBASE); + fails += CHECK_PROC (fsrm, FSRM); + fails += CHECK_PROC (fxsr, FXSR); + fails += CHECK_PROC (gfni, GFNI); + fails += CHECK_PROC (hle, HLE); + fails += CHECK_PROC (ht, HTT); + fails += CHECK_PROC (hybrid, HYBRID); + fails += CHECK_PROC (ibrs, IBRS_IBPB); + fails += CHECK_PROC (ibt, IBT); + fails += CHECK_PROC (invariant_tsc, INVARIANT_TSC); + fails += CHECK_PROC (invpcid, INVPCID); + fails += CHECK_PROC (flush_l1d, L1D_FLUSH); + fails += CHECK_PROC (lahf_lm, LAHF64_SAHF64); + fails += CHECK_PROC (lm, LM); + fails += CHECK_PROC (lwp, LWP); + fails += CHECK_PROC (abm, LZCNT); + fails += CHECK_PROC (mca, MCA); + fails += CHECK_PROC (mce, MCE); + fails += CHECK_PROC (md_clear, MD_CLEAR); + fails += CHECK_PROC (mmx, MMX); + fails += CHECK_PROC (monitor, MONITOR); + fails += CHECK_PROC (movbe, MOVBE); + fails += CHECK_PROC (movdiri, MOVDIRI); + fails += CHECK_PROC (movdir64b, MOVDIR64B); + fails += CHECK_PROC (mpx, MPX); + fails += CHECK_PROC (msr, MSR); + fails += CHECK_PROC (mtrr, MTRR); + fails += CHECK_PROC (nx, NX); + fails += CHECK_PROC (ospke, OSPKE); +#if 0 + /* NB: /proc/cpuinfo doesn't report this feature. */ + fails += CHECK_PROC (osxsave, OSXSAVE); +#endif + fails += CHECK_PROC (pae, PAE); + fails += CHECK_PROC (pdpe1gb, PAGE1GB); + fails += CHECK_PROC (pat, PAT); + fails += CHECK_PROC (pbe, PBE); + fails += CHECK_PROC (pcid, PCID); + fails += CHECK_PROC (pclmulqdq, PCLMULQDQ); + fails += CHECK_PROC (pconfig, PCONFIG); + fails += CHECK_PROC (pdcm, PDCM); + fails += CHECK_PROC (pge, PGE); + fails += CHECK_PROC (pks, PKS); + fails += CHECK_PROC (pku, PKU); + fails += CHECK_PROC (popcnt, POPCNT); + fails += CHECK_PROC (3dnowprefetch, PREFETCHW); + fails += CHECK_PROC (prefetchwt1, PREFETCHWT1); + fails += CHECK_PROC (pse, PSE); + fails += CHECK_PROC (pse36, PSE_36); + fails += CHECK_PROC (psn, PSN); + fails += CHECK_PROC (rdpid, RDPID); + fails += CHECK_PROC (rdrand, RDRAND); + fails += CHECK_PROC (rdseed, RDSEED); + fails += CHECK_PROC (rdt_a, RDT_A); + fails += CHECK_PROC (cqm, RDT_M); + fails += CHECK_PROC (rdtscp, RDTSCP); + fails += CHECK_PROC (rtm, RTM); + fails += CHECK_PROC (sdbg, SDBG); + fails += CHECK_PROC (sep, SEP); + fails += CHECK_PROC (serialize, SERIALIZE); + fails += CHECK_PROC (sgx, SGX); + fails += CHECK_PROC (sgx_lc, SGX_LC); + fails += CHECK_PROC (sha_ni, SHA); + fails += CHECK_PROC (shstk, SHSTK); + fails += CHECK_PROC (smap, SMAP); + fails += CHECK_PROC (smep, SMEP); + fails += CHECK_PROC (smx, SMX); + fails += CHECK_PROC (ss, SS); + fails += CHECK_PROC (ssbd, SSBD); + fails += CHECK_PROC (sse, SSE); + fails += CHECK_PROC (sse2, SSE2); + fails += CHECK_PROC (sse3, SSE3); + fails += CHECK_PROC (sse4_1, SSE4_1); + fails += CHECK_PROC (sse4_2, SSE4_2); + fails += CHECK_PROC (sse4a, SSE4A); + fails += CHECK_PROC (ssse3, SSSE3); + fails += CHECK_PROC (stibp, STIBP); + fails += CHECK_PROC (svm, SVM); +#ifdef __x86_64__ + /* NB: SYSCALL_SYSRET is 64-bit only. */ + fails += CHECK_PROC (syscall, SYSCALL_SYSRET); +#endif + fails += CHECK_PROC (tbm, TBM); + fails += CHECK_PROC (tm, TM); + fails += CHECK_PROC (tm2, TM2); + fails += CHECK_PROC (intel_pt, TRACE); + fails += CHECK_PROC (tsc, TSC); + fails += CHECK_PROC (tsc_adjust, TSC_ADJUST); + fails += CHECK_PROC (tsc_deadline, TSC_DEADLINE); + fails += CHECK_PROC (tsxldtrk, TSXLDTRK); + fails += CHECK_PROC (umip, UMIP); + fails += CHECK_PROC (vaes, VAES); + fails += CHECK_PROC (vme, VME); + fails += CHECK_PROC (vmx, VMX); + fails += CHECK_PROC (vpclmulqdq, VPCLMULQDQ); + fails += CHECK_PROC (waitpkg, WAITPKG); + fails += CHECK_PROC (wbnoinvd, WBNOINVD); + fails += CHECK_PROC (x2apic, X2APIC); + fails += CHECK_PROC (xfd, XFD); + fails += CHECK_PROC (xgetbv1, XGETBV_ECX_1); + fails += CHECK_PROC (xop, XOP); + fails += CHECK_PROC (xsave, XSAVE); + fails += CHECK_PROC (xsavec, XSAVEC); + fails += CHECK_PROC (xsaveopt, XSAVEOPT); + fails += CHECK_PROC (xsaves, XSAVES); + fails += CHECK_PROC (xtpr, XTPRUPDCTRL); + + printf ("%d differences between /proc/cpuinfo and glibc code.\n", fails); + + return (fails != 0); +} + +#include "../../../test-skeleton.c" diff --git a/sysdeps/x86/tst-cpu-features-supports.c b/sysdeps/x86/tst-cpu-features-supports.c new file mode 100644 index 0000000000..bf881b531f --- /dev/null +++ b/sysdeps/x86/tst-cpu-features-supports.c @@ -0,0 +1,192 @@ +/* Test CPU feature data against __builtin_cpu_supports. + This file is part of the GNU C Library. + Copyright (C) 2020 Free Software Foundation, Inc. + + 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 + <https://www.gnu.org/licenses/>. */ + +#include <sys/platform/x86.h> +#include <stdio.h> + +int +check_supports (int supports, int usable, const char *supports_name, + const char *name) +{ + printf ("Checking %s:\n", name); + printf (" %s: %d\n", name, usable); + printf (" __builtin_cpu_supports (%s): %d\n", + supports_name, supports); + + if ((supports != 0) != (usable != 0)) + { + printf (" *** failure ***\n"); + return 1; + } + + return 0; +} + +#define CHECK_SUPPORTS(str, name) \ + check_supports (__builtin_cpu_supports (#str), \ + CPU_FEATURE_USABLE (name), \ + #str, "HAS_CPU_FEATURE (" #name ")"); + +static int +do_test (int argc, char **argv) +{ + int fails = 0; + +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (adx, ADX); +#endif +#if __GNUC_PREREQ (6, 0) + fails += CHECK_SUPPORTS (aes, AES); +#endif +#if __GNUC_PREREQ (11, 1) + fails += CHECK_SUPPORTS (amx_bf16, AMX_BF16); + fails += CHECK_SUPPORTS (amx_int8, AMX_INT8); + fails += CHECK_SUPPORTS (amx_tile, AMX_TILE); +#endif + fails += CHECK_SUPPORTS (avx, AVX); + fails += CHECK_SUPPORTS (avx2, AVX2); +#if __GNUC_PREREQ (7, 0) + fails += CHECK_SUPPORTS (avx5124fmaps, AVX512_4FMAPS); + fails += CHECK_SUPPORTS (avx5124vnniw, AVX512_4VNNIW); +#endif +#if __GNUC_PREREQ (10, 0) + fails += CHECK_SUPPORTS (avx512bf16, AVX512_BF16); +#endif +#if __GNUC_PREREQ (8, 0) + fails += CHECK_SUPPORTS (avx512bitalg, AVX512_BITALG); +#endif +#if __GNUC_PREREQ (6, 0) + fails += CHECK_SUPPORTS (avx512ifma, AVX512_IFMA); + fails += CHECK_SUPPORTS (avx512vbmi, AVX512_VBMI); +#endif +#if __GNUC_PREREQ (8, 0) + fails += CHECK_SUPPORTS (avx512vbmi2, AVX512_VBMI2); + fails += CHECK_SUPPORTS (avx512vnni, AVX512_VNNI); +#endif +#if __GNUC_PREREQ (10, 0) + fails += CHECK_SUPPORTS (avx512vp2intersect, AVX512_VP2INTERSECT); +#endif +#if __GNUC_PREREQ (7, 0) + fails += CHECK_SUPPORTS (avx512vpopcntdq, AVX512_VPOPCNTDQ); +#endif +#if __GNUC_PREREQ (6, 0) + fails += CHECK_SUPPORTS (avx512bw, AVX512BW); + fails += CHECK_SUPPORTS (avx512cd, AVX512CD); + fails += CHECK_SUPPORTS (avx512er, AVX512ER); + fails += CHECK_SUPPORTS (avx512dq, AVX512DQ); +#endif +#if __GNUC_PREREQ (5, 0) + fails += CHECK_SUPPORTS (avx512f, AVX512F); +#endif +#if __GNUC_PREREQ (6, 0) + fails += CHECK_SUPPORTS (avx512pf, AVX512PF); + fails += CHECK_SUPPORTS (avx512vl, AVX512VL); +#endif +#if __GNUC_PREREQ (5, 0) + fails += CHECK_SUPPORTS (bmi, BMI1); + fails += CHECK_SUPPORTS (bmi2, BMI2); +#endif +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (cldemote, CLDEMOTE); + fails += CHECK_SUPPORTS (clflushopt, CLFLUSHOPT); + fails += CHECK_SUPPORTS (clwb, CLWB); +#endif + fails += CHECK_SUPPORTS (cmov, CMOV); +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (cmpxchg16b, CMPXCHG16B); + fails += CHECK_SUPPORTS (cmpxchg8b, CX8); + fails += CHECK_SUPPORTS (enqcmd, ENQCMD); + fails += CHECK_SUPPORTS (f16c, F16C); +#endif +#if __GNUC_PREREQ (4, 9) + fails += CHECK_SUPPORTS (fma, FMA); + fails += CHECK_SUPPORTS (fma4, FMA4); +#endif +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (fsgsbase, FSGSBASE); + fails += CHECK_SUPPORTS (fxsave, FXSR); +#endif +#if __GNUC_PREREQ (8, 0) + fails += CHECK_SUPPORTS (gfni, GFNI); +#endif +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (hle, HLE); + fails += CHECK_SUPPORTS (ibt, IBT); + fails += CHECK_SUPPORTS (lahf_lm, LAHF64_SAHF64); + fails += CHECK_SUPPORTS (lm, LM); + fails += CHECK_SUPPORTS (lwp, LWP); + fails += CHECK_SUPPORTS (lzcnt, LZCNT); +#endif + fails += CHECK_SUPPORTS (mmx, MMX); +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (movbe, MOVBE); + fails += CHECK_SUPPORTS (movdiri, MOVDIRI); + fails += CHECK_SUPPORTS (movdir64b, MOVDIR64B); + fails += CHECK_SUPPORTS (osxsave, OSXSAVE); + fails += CHECK_SUPPORTS (pconfig, PCONFIG); + fails += CHECK_SUPPORTS (pku, PKU); +#endif + fails += CHECK_SUPPORTS (popcnt, POPCNT); +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (prefetchwt1, PREFETCHWT1); + fails += CHECK_SUPPORTS (rdpid, RDPID); + fails += CHECK_SUPPORTS (rdrnd, RDRAND); + fails += CHECK_SUPPORTS (rdseed, RDSEED); + fails += CHECK_SUPPORTS (rtm, RTM); + fails += CHECK_SUPPORTS (serialize, SERIALIZE); + fails += CHECK_SUPPORTS (sha, SHA); + fails += CHECK_SUPPORTS (shstk, SHSTK); +#endif + fails += CHECK_SUPPORTS (sse, SSE); + fails += CHECK_SUPPORTS (sse2, SSE2); + fails += CHECK_SUPPORTS (sse3, SSE3); + fails += CHECK_SUPPORTS (sse4.1, SSE4_1); + fails += CHECK_SUPPORTS (sse4.2, SSE4_2); +#if __GNUC_PREREQ (4, 9) + fails += CHECK_SUPPORTS (sse4a, SSE4A); +#endif + fails += CHECK_SUPPORTS (ssse3, SSSE3); +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (tbm, TBM); + fails += CHECK_SUPPORTS (tsxldtrk, TSXLDTRK); + fails += CHECK_SUPPORTS (vaes, VAES); +#endif +#if __GNUC_PREREQ (8, 0) + fails += CHECK_SUPPORTS (vpclmulqdq, VPCLMULQDQ); +#endif +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (waitpkg, WAITPKG); + fails += CHECK_SUPPORTS (wbnoinvd, WBNOINVD); +#endif +#if __GNUC_PREREQ (4, 9) + fails += CHECK_SUPPORTS (xop, XOP); +#endif +#if __GNUC_PREREQ (11, 0) + fails += CHECK_SUPPORTS (xsave, XSAVE); + fails += CHECK_SUPPORTS (xsavec, XSAVEC); + fails += CHECK_SUPPORTS (xsaveopt, XSAVEOPT); + fails += CHECK_SUPPORTS (xsaves, XSAVES); +#endif + + printf ("%d differences between __builtin_cpu_supports and glibc code.\n", + fails); + + return (fails != 0); +} + +#include "../../../test-skeleton.c" diff --git a/sysdeps/x86/tst-get-cpu-features.c b/sysdeps/x86/tst-get-cpu-features.c index 6bfdef0829..3447d17e23 100644 --- a/sysdeps/x86/tst-get-cpu-features.c +++ b/sysdeps/x86/tst-get-cpu-features.c @@ -1,4 +1,4 @@ -/* Test case for x86 __get_cpu_features interface +/* Test case for __x86_get_cpu_features interface Copyright (C) 2015-2020 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -18,7 +18,7 @@ #include <stdlib.h> #include <stdio.h> -#include <cpu-features.h> +#include <sys/platform/x86.h> #include <support/check.h> #define CHECK_CPU_FEATURE(name) \ @@ -45,7 +45,7 @@ static const char * const cpu_kinds[] = static int do_test (void) { - const struct cpu_features *cpu_features = __get_cpu_features (); + const struct cpu_features *cpu_features = __x86_get_cpu_features (0); switch (cpu_features->basic.kind) { diff --git a/sysdeps/x86_64/fpu/math-tests-arch.h b/sysdeps/x86_64/fpu/math-tests-arch.h index 33ea763de2..cc3c2b0c11 100644 --- a/sysdeps/x86_64/fpu/math-tests-arch.h +++ b/sysdeps/x86_64/fpu/math-tests-arch.h @@ -16,7 +16,7 @@ License along with the GNU C Library; if not, see <https://www.gnu.org/licenses/>. */ -#include <cpu-features.h> +#include <sys/platform/x86.h> #if defined REQUIRE_AVX diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile index 395e432c09..9477538af4 100644 --- a/sysdeps/x86_64/multiarch/Makefile +++ b/sysdeps/x86_64/multiarch/Makefile @@ -1,7 +1,3 @@ -ifeq ($(subdir),csu) -tests += test-multiarch -endif - ifeq ($(subdir),string) sysdep_routines += strncat-c stpncpy-c strncpy-c \ diff --git a/sysdeps/x86_64/multiarch/test-multiarch.c b/sysdeps/x86_64/multiarch/test-multiarch.c deleted file mode 100644 index 2782803e73..0000000000 --- a/sysdeps/x86_64/multiarch/test-multiarch.c +++ /dev/null @@ -1,96 +0,0 @@ -/* Test CPU feature data. - This file is part of the GNU C Library. - Copyright (C) 2012-2020 Free Software Foundation, Inc. - - 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 - <https://www.gnu.org/licenses/>. */ - -#include <cpu-features.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -static char *cpu_flags; - -/* Search for flags in /proc/cpuinfo and store line - in cpu_flags. */ -void -get_cpuinfo (void) -{ - FILE *f; - char *line = NULL; - size_t len = 0; - ssize_t read; - - f = fopen ("/proc/cpuinfo", "r"); - if (f == NULL) - { - printf ("cannot open /proc/cpuinfo\n"); - exit (1); - } - - while ((read = getline (&line, &len, f)) != -1) - { - if (strncmp (line, "flags", 5) == 0) - { - cpu_flags = strdup (line); - break; - } - } - fclose (f); - free (line); -} - -int -check_proc (const char *proc_name, int flag, const char *name) -{ - int found = 0; - - printf ("Checking %s:\n", name); - printf (" init-arch %d\n", flag); - if (strstr (cpu_flags, proc_name) != NULL) - found = 1; - printf (" cpuinfo (%s) %d\n", proc_name, found); - - if (found != flag) - printf (" *** failure ***\n"); - - return (found != flag); -} - -static int -do_test (int argc, char **argv) -{ - int fails; - - get_cpuinfo (); - fails = check_proc ("avx", CPU_FEATURE_USABLE (AVX), - "CPU_FEATURE_USABLE (AVX)"); - fails += check_proc ("fma4", CPU_FEATURE_USABLE (FMA4), - "CPU_FEATURE_USABLE (FMA4)"); - fails += check_proc ("sse4_2", CPU_FEATURE_USABLE (SSE4_2), - "CPU_FEATURE_USABLE (SSE4_2)"); - fails += check_proc ("sse4_1", CPU_FEATURE_USABLE (SSE4_1) - , "CPU_FEATURE_USABLE (SSE4_1)"); - fails += check_proc ("ssse3", CPU_FEATURE_USABLE (SSSE3), - "CPU_FEATURE_USABLE (SSSE3)"); - fails += check_proc ("popcnt", CPU_FEATURE_USABLE (POPCNT), - "CPU_FEATURE_USABLE (POPCNT)"); - - printf ("%d differences between /proc/cpuinfo and glibc code.\n", fails); - - return (fails != 0); -} - -#include "../../../test-skeleton.c" -- 2.26.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: PING^3: V8 [PATCH 2/2] x86: Install <sys/platform/x86.h> [BZ #26124] 2020-09-07 18:21 ` H.J. Lu @ 2020-09-10 14:29 ` H.J. Lu 0 siblings, 0 replies; 7+ messages in thread From: H.J. Lu @ 2020-09-10 14:29 UTC (permalink / raw) To: GNU C Library, Carlos O'Donell, Florian Weimer On Mon, Sep 7, 2020 at 11:21 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > On Wed, Sep 2, 2020 at 5:55 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > On Wed, Aug 19, 2020 at 5:52 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > > > On Wed, Aug 12, 2020 at 7:00 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > > > > > On Wed, Aug 5, 2020 at 4:01 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > > > > > > > Install <sys/platform/x86.h> so that programmers can do > > > > > > > > > > #if __has_include(<sys/platform/x86.h>) > > > > > #include <sys/platform/x86.h> > > > > > #endif > > > > > ... > > > > > > > > > > if (CPU_FEATURE_USABLE (SSE2)) > > > > > ... > > > > > if (CPU_FEATURE_USABLE (AVX2)) > > > > > ... > > > > > > > > > > <sys/platform/x86.h> exports only: > > > > > > > > > > enum > > > > > { > > > > > COMMON_CPUID_INDEX_1 = 0, > > > > > COMMON_CPUID_INDEX_7, > > > > > COMMON_CPUID_INDEX_80000001, > > > > > COMMON_CPUID_INDEX_D_ECX_1, > > > > > COMMON_CPUID_INDEX_80000007, > > > > > COMMON_CPUID_INDEX_80000008, > > > > > COMMON_CPUID_INDEX_7_ECX_1, > > > > > /* Keep the following line at the end. */ > > > > > COMMON_CPUID_INDEX_MAX > > > > > }; > > > > > > > > > > struct cpuid_features > > > > > { > > > > > struct cpuid_registers cpuid; > > > > > struct cpuid_registers usable; > > > > > }; > > > > > > > > > > struct cpu_features > > > > > { > > > > > struct cpu_features_basic basic; > > > > > struct cpuid_features features[COMMON_CPUID_INDEX_MAX]; > > > > > }; > > > > > > > > > > /* Get a pointer to the CPU features structure. */ > > > > > extern const struct cpu_features *__x86_get_cpu_features > > > > > (unsigned int max) __attribute__ ((const)); > > > > > > > > > > Since all feature checks are done through macros, programs compiled with > > > > > a newer <sys/platform/x86.h> are compatible with the older glibc binaries > > > > > as long as the layout of struct cpu_features is identical. The features > > > > > array can be expanded with backward binary compatibility for both .o and > > > > > .so files. When COMMON_CPUID_INDEX_MAX is increased to support new > > > > > processor features, __x86_get_cpu_features in the older glibc binaries > > > > > returns NULL and HAS_CPU_FEATURE/CPU_FEATURE_USABLE return false on the > > > > > new processor feature. No new symbol version is neeeded. > > > > > > > > > > Both CPU_FEATURE_USABLE and HAS_CPU_FEATURE are provided. HAS_CPU_FEATURE > > > > > can be used to identify processor features. > > > > > > > > > > Note: Although GCC has __builtin_cpu_supports, it only supports a subset > > > > > of <sys/platform/x86.h> and it is equivalent to CPU_FEATURE_USABLE. It > > > > > doesn't support HAS_CPU_FEATURE. > > > > > > PING: > > > > > > https://sourceware.org/pipermail/libc-alpha/2020-August/116865.html > > > > > > > If there are no more comments, I will check it next Friday, > > Sept 11. > > > > I am enclosing the rebased patch I am checking in this Friday. > I will check this in tomorrow: https://sourceware.org/pipermail/libc-alpha/2020-September/117466.html -- H.J. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-09-10 14:30 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-08-05 23:01 V8 [PATCH 1/2] x86: Clear some CPU usable feature bits H.J. Lu 2020-08-05 23:01 ` V8 [PATCH 2/2] x86: Install <sys/platform/x86.h> [BZ #26124] H.J. Lu 2020-08-12 14:00 ` PING: " H.J. Lu 2020-08-19 12:52 ` PING^2: " H.J. Lu 2020-09-02 12:55 ` PING^3: " H.J. Lu 2020-09-07 18:21 ` H.J. Lu 2020-09-10 14:29 ` H.J. Lu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).