mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-24 22:10:13 +00:00
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.
This commit is contained in:
parent
a92f4e6299
commit
9620398097
1
NEWS
1
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:
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -1 +0,0 @@
|
||||
#include <sysdeps/x86_64/multiarch/test-multiarch.c>
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
ld {
|
||||
GLIBC_PRIVATE {
|
||||
__get_cpu_features;
|
||||
GLIBC_2.33 {
|
||||
__x86_get_cpu_features;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
183
sysdeps/x86/include/cpu-features.h
Normal file
183
sysdeps/x86/include/cpu-features.h
Normal file
@ -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 */
|
@ -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 */
|
250
sysdeps/x86/tst-cpu-features-cpuinfo.c
Normal file
250
sysdeps/x86/tst-cpu-features-cpuinfo.c
Normal file
@ -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"
|
192
sysdeps/x86/tst-cpu-features-supports.c
Normal file
192
sysdeps/x86/tst-cpu-features-supports.c
Normal file
@ -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"
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
ifeq ($(subdir),csu)
|
||||
tests += test-multiarch
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),string)
|
||||
|
||||
sysdep_routines += strncat-c stpncpy-c strncpy-c \
|
||||
|
@ -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"
|
Loading…
Reference in New Issue
Block a user