unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: "H.J. Lu via Libc-alpha" <libc-alpha@sourceware.org>
To: GNU C Library <libc-alpha@sourceware.org>,
	"Carlos O'Donell" <carlos@redhat.com>,
	Florian Weimer <fweimer@redhat.com>
Subject: PING: V8 [PATCH 2/2] x86: Install <sys/platform/x86.h> [BZ #26124]
Date: Wed, 12 Aug 2020 07:00:47 -0700	[thread overview]
Message-ID: <CAMe9rOqAKbfV9BFaqF6Rnvko9VveELT9ZJ7bWMJ8Q-x+xsoHBg@mail.gmail.com> (raw)
In-Reply-To: <20200805230137.3572872-2-hjl.tools@gmail.com>

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.

  reply	other threads:[~2020-08-12 14:01 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-05 23:01 V8 [PATCH 1/2] x86: Clear some CPU usable feature bits H.J. Lu via Libc-alpha
2020-08-05 23:01 ` V8 [PATCH 2/2] x86: Install <sys/platform/x86.h> [BZ #26124] H.J. Lu via Libc-alpha
2020-08-12 14:00   ` H.J. Lu via Libc-alpha [this message]
2020-08-19 12:52     ` PING^2: " H.J. Lu via Libc-alpha
2020-09-02 12:55       ` PING^3: " H.J. Lu via Libc-alpha
2020-09-07 18:21         ` H.J. Lu via Libc-alpha
2020-09-10 14:29           ` H.J. Lu via Libc-alpha

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/libc/involved.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAMe9rOqAKbfV9BFaqF6Rnvko9VveELT9ZJ7bWMJ8Q-x+xsoHBg@mail.gmail.com \
    --to=libc-alpha@sourceware.org \
    --cc=carlos@redhat.com \
    --cc=fweimer@redhat.com \
    --cc=hjl.tools@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).