b1dca6
commit 9620398097de3981c1adf5233e2b3478d36bc1b3
b1dca6
Author: H.J. Lu <hjl.tools@gmail.com>
b1dca6
Date:   Mon Jun 29 18:30:54 2020 -0700
b1dca6
b1dca6
    x86: Install <sys/platform/x86.h> [BZ #26124]
b1dca6
    
b1dca6
    Install <sys/platform/x86.h> so that programmers can do
b1dca6
    
b1dca6
     #if __has_include(<sys/platform/x86.h>)
b1dca6
     #include <sys/platform/x86.h>
b1dca6
     #endif
b1dca6
     ...
b1dca6
    
b1dca6
       if (CPU_FEATURE_USABLE (SSE2))
b1dca6
     ...
b1dca6
       if (CPU_FEATURE_USABLE (AVX2))
b1dca6
     ...
b1dca6
    
b1dca6
    <sys/platform/x86.h> exports only:
b1dca6
    
b1dca6
    enum
b1dca6
    {
b1dca6
      COMMON_CPUID_INDEX_1 = 0,
b1dca6
      COMMON_CPUID_INDEX_7,
b1dca6
      COMMON_CPUID_INDEX_80000001,
b1dca6
      COMMON_CPUID_INDEX_D_ECX_1,
b1dca6
      COMMON_CPUID_INDEX_80000007,
b1dca6
      COMMON_CPUID_INDEX_80000008,
b1dca6
      COMMON_CPUID_INDEX_7_ECX_1,
b1dca6
      /* Keep the following line at the end.  */
b1dca6
      COMMON_CPUID_INDEX_MAX
b1dca6
    };
b1dca6
    
b1dca6
    struct cpuid_features
b1dca6
    {
b1dca6
      struct cpuid_registers cpuid;
b1dca6
      struct cpuid_registers usable;
b1dca6
    };
b1dca6
    
b1dca6
    struct cpu_features
b1dca6
    {
b1dca6
      struct cpu_features_basic basic;
b1dca6
      struct cpuid_features features[COMMON_CPUID_INDEX_MAX];
b1dca6
    };
b1dca6
    
b1dca6
    /* Get a pointer to the CPU features structure.  */
b1dca6
    extern const struct cpu_features *__x86_get_cpu_features
b1dca6
      (unsigned int max) __attribute__ ((const));
b1dca6
    
b1dca6
    Since all feature checks are done through macros, programs compiled with
b1dca6
    a newer <sys/platform/x86.h> are compatible with the older glibc binaries
b1dca6
    as long as the layout of struct cpu_features is identical.  The features
b1dca6
    array can be expanded with backward binary compatibility for both .o and
b1dca6
    .so files.  When COMMON_CPUID_INDEX_MAX is increased to support new
b1dca6
    processor features, __x86_get_cpu_features in the older glibc binaries
b1dca6
    returns NULL and HAS_CPU_FEATURE/CPU_FEATURE_USABLE return false on the
b1dca6
    new processor feature.  No new symbol version is neeeded.
b1dca6
    
b1dca6
    Both CPU_FEATURE_USABLE and HAS_CPU_FEATURE are provided.  HAS_CPU_FEATURE
b1dca6
    can be used to identify processor features.
b1dca6
    
b1dca6
    Note: Although GCC has __builtin_cpu_supports, it only supports a subset
b1dca6
    of <sys/platform/x86.h> and it is equivalent to CPU_FEATURE_USABLE.  It
b1dca6
    doesn't support HAS_CPU_FEATURE.
b1dca6
b1dca6
Conflicts:
b1dca6
	sysdeps/x86/sys/platform/x86.h
b1dca6
	sysdeps/x86/tst-get-cpu-features.c
b1dca6
	sysdeps/x86_64/multiarch/test-multiarch.c
b1dca6
	  (Copyright year, URL differences.)
b1dca6
b1dca6
Downstream changes: Do not install <sys/platform/x86.h>,
b1dca6
and use a GLIBC_PRIVATE symbol for __x86_get_cpu_features.
b1dca6
b1dca6
diff --git a/manual/platform.texi b/manual/platform.texi
b1dca6
index 504addc956086820..2c145acdc3564cbb 100644
b1dca6
--- a/manual/platform.texi
b1dca6
+++ b/manual/platform.texi
b1dca6
@@ -7,6 +7,7 @@
b1dca6
 @menu
b1dca6
 * PowerPC::           Facilities Specific to the PowerPC Architecture
b1dca6
 * RISC-V::            Facilities Specific to the RISC-V Architecture
b1dca6
+* X86::               Facilities Specific to the X86 Architecture
b1dca6
 @end menu
b1dca6
 
b1dca6
 @node PowerPC
b1dca6
@@ -134,3 +135,519 @@ all threads in the current process.  Setting the
b1dca6
 ordering on only the current thread is necessary.  All other flag bits are
b1dca6
 reserved.
b1dca6
 @end deftypefun
b1dca6
+
b1dca6
+@node X86
b1dca6
+@appendixsec X86-specific Facilities
b1dca6
+
b1dca6
+Facilities specific to X86 that are not specific to a particular
b1dca6
+operating system are declared in @file{sys/platform/x86.h}.
b1dca6
+
b1dca6
+@deftypefun {const struct cpu_features *} __x86_get_cpu_features (unsigned int @var{max})
b1dca6
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
b1dca6
+Return a pointer to x86 CPU feature structure used by query macros for x86
b1dca6
+CPU features.  If @var{max} exceeds @code{COMMON_CPUID_INDEX_MAX} which
b1dca6
+is the limit of the CPUID leaves supported by @Theglibc{}, the function
b1dca6
+returns @code{NULL}, indicating that the queried processor feature is
b1dca6
+unsupported by @Theglibc{} run-time.
b1dca6
+@end deftypefun
b1dca6
+
b1dca6
+@deftypefn Macro int HAS_CPU_FEATURE (@var{name})
b1dca6
+This macro returns a nonzero value (true) if the processor has the feature
b1dca6
+@var{name}.
b1dca6
+@end deftypefn
b1dca6
+
b1dca6
+@deftypefn Macro int CPU_FEATURE_USABLE (@var{name})
b1dca6
+This macro returns a nonzero value (true) if the processor has the feature
b1dca6
+@var{name} and the feature is supported by the operating system.
b1dca6
+@end deftypefn
b1dca6
+
b1dca6
+The supported processor features are:
b1dca6
+
b1dca6
+@itemize @bullet
b1dca6
+
b1dca6
+@item
b1dca6
+@code{ACPI} -- Thermal Monitor and Software Controlled Clock Facilities.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{ADX} -- ADX instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{APIC} -- APIC On-Chip.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AES} -- The AES instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AMX_BF16} -- Tile computational operations on bfloat16 numbers.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AMX_INT8} -- Tile computational operations on 8-bit numbers.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AMX_TILE} -- Tile architecture.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{ARCH_CAPABILITIES} -- IA32_ARCH_CAPABILITIES MSR.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX} -- The AVX instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX2} -- The AVX2 instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512_4FMAPS} -- The AVX512_4FMAPS instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512_4VNNIW} -- The AVX512_4VNNIW instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512_BF16} -- The AVX512_BF16 instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512_BITALG} -- The AVX512_BITALG instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512_IFMA} -- The AVX512_IFMA instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512_VBMI} -- The AVX512_VBMI instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512_VBMI2} -- The AVX512_VBMI2 instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512_VNNI} -- The AVX512_VNNI instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512_VP2INTERSECT} -- The AVX512_VP2INTERSECT instruction
b1dca6
+extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512_VPOPCNTDQ} -- The AVX512_VPOPCNTDQ instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512BW} -- The AVX512BW instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512CD} -- The AVX512CD instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512ER} -- The AVX512ER instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512DQ} -- The AVX512DQ instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512F} -- The AVX512F instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512PF} -- The AVX512PF instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{AVX512VL} -- The AVX512VL instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{BMI1} -- BMI1 instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{BMI2} -- BMI2 instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{CLDEMOTE} -- CLDEMOTE instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{CLFLUSHOPT} -- CLFLUSHOPT instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{CLFSH} -- CLFLUSH instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{CLWB} -- CLWB instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{CMOV} -- Conditional Move instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{CMPXCHG16B} -- CMPXCHG16B instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{CNXT_ID} -- L1 Context ID.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{CORE_CAPABILITIES} -- IA32_CORE_CAPABILITIES MSR.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{CX8} -- CMPXCHG8B instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{DCA} -- Data prefetch from a memory mapped device.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{DE} -- Debugging Extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{DEPR_FPU_CS_DS} -- Deprecates FPU CS and FPU DS values.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{DS} -- Debug Store.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{DS_CPL} -- CPL Qualified Debug Store.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{DTES64} -- 64-bit DS Area.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{EIST} -- Enhanced Intel SpeedStep technology.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{ENQCMD} -- Enqueue Stores instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{ERMS} -- Enhanced REP MOVSB/STOSB.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{F16C} -- 16-bit floating-point conversion instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{FMA} -- FMA extensions using YMM state.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{FMA4} -- FMA4 instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{FPU} -- X87 Floating Point Unit On-Chip.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{FSGSBASE} -- RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{FSRM} -- Fast Short REP MOV.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{FXSR} -- FXSAVE and FXRSTOR instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{GFNI} -- GFNI instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{HLE} -- HLE instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{HTT} -- Max APIC IDs reserved field is Valid.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{HYBRID} -- Hybrid processor.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{IBRS_IBPB} -- Indirect branch restricted speculation (IBRS) and
b1dca6
+the indirect branch predictor barrier (IBPB).
b1dca6
+
b1dca6
+@item
b1dca6
+@code{IBT} -- Intel Indirect Branch Tracking instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{INVARIANT_TSC} -- Invariant TSC.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{INVPCID} -- INVPCID instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{L1D_FLUSH} -- IA32_FLUSH_CMD MSR.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{LAHF64_SAHF64} -- LAHF/SAHF available in 64-bit mode.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{LM} -- Long mode.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{LWP} -- Lightweight profiling.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{LZCNT} -- LZCNT instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{MCA} -- Machine Check Architecture.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{MCE} -- Machine Check Exception.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{MD_CLEAR} -- MD_CLEAR.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{MMX} -- Intel MMX Technology.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{MONITOR} --  MONITOR/MWAIT instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{MOVBE} -- MOVBE instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{MOVDIRI} -- MOVDIRI instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{MOVDIR64B} -- MOVDIR64B instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{MPX} -- Intel Memory Protection Extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{MSR} -- Model Specific Registers RDMSR and WRMSR instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{MTRR} -- Memory Type Range Registers.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{NX} -- No-execute page protection.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{OSPKE} -- OS has set CR4.PKE to enable protection keys.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{OSXSAVE} -- The OS has set CR4.OSXSAVE[bit 18] to enable
b1dca6
+XSETBV/XGETBV instructions to access XCR0 and to support processor
b1dca6
+extended state management using XSAVE/XRSTOR.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PAE} -- Physical Address Extension.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PAGE1GB} -- 1-GByte page.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PAT} -- Page Attribute Table.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PBE} -- Pending Break Enable.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PCID} -- Process-context identifiers.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PCLMULQDQ} -- PCLMULQDQ instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PCONFIG} -- PCONFIG instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PDCM} -- Perfmon and Debug Capability.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PGE} -- Page Global Bit.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PKS} -- Protection keys for supervisor-mode pages.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PKU} -- Protection keys for user-mode pages.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{POPCNT} -- POPCNT instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PREFETCHW} -- PREFETCHW instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PREFETCHWT1} -- PREFETCHWT1 instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PSE} -- Page Size Extension.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PSE_36} -- 36-Bit Page Size Extension.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{PSN} -- Processor Serial Number.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{RDPID} -- RDPID instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{RDRAND} -- RDRAND instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{RDSEED} -- RDSEED instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{RDT_A} -- Intel Resource Director Technology (Intel RDT) Allocation
b1dca6
+capability.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{RDT_M} -- Intel Resource Director Technology (Intel RDT) Monitoring
b1dca6
+capability.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{RDTSCP} -- RDTSCP instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{RTM} -- RTM instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SDBG} -- IA32_DEBUG_INTERFACE MSR for silicon debug.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SEP} -- SYSENTER and SYSEXIT instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SERIALIZE} -- SERIALIZE instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SGX} -- Intel Software Guard Extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SGX_LC} -- SGX Launch Configuration.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SHA} -- SHA instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SHSTK} -- Intel Shadow Stack instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SMAP} -- Supervisor-Mode Access Prevention.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SMEP} -- Supervisor-Mode Execution Prevention.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SMX} -- Safer Mode Extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SS} -- Self Snoop.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SSBD} -- Speculative Store Bypass Disable (SSBD).
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SSE} -- Streaming SIMD Extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SSE2} -- Streaming SIMD Extensions 2.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SSE3} -- Streaming SIMD Extensions 3.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SSE4_1} -- Streaming SIMD Extensions 4.1.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SSE4_2} -- Streaming SIMD Extensions 4.2.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SSE4A} -- SSE4A instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SSSE3} -- Supplemental Streaming SIMD Extensions 3.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{STIBP} -- Single thread indirect branch predictors (STIBP).
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SVM} -- Secure Virtual Machine.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{SYSCALL_SYSRET} -- SYSCALL/SYSRET instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{TBM} -- Trailing bit manipulation instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{TM} -- Thermal Monitor.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{TM2} -- Thermal Monitor 2.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{TRACE} -- Intel Processor Trace.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{TSC} -- Time Stamp Counter.  RDTSC instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{TSC_ADJUST} -- IA32_TSC_ADJUST MSR.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{TSC_DEADLINE} -- Local APIC timer supports one-shot operation
b1dca6
+using a TSC deadline value.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{TSXLDTRK} -- TSXLDTRK instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{UMIP} -- User-mode instruction prevention.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{VAES} -- VAES instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{VME} -- Virtual 8086 Mode Enhancements.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{VMX} -- Virtual Machine Extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{VPCLMULQDQ} -- VPCLMULQDQ instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{WAITPKG} -- WAITPKG instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{WBNOINVD} -- WBINVD/WBNOINVD instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{X2APIC} -- x2APIC.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{XFD} -- Extended Feature Disable (XFD).
b1dca6
+
b1dca6
+@item
b1dca6
+@code{XGETBV_ECX_1} -- XGETBV with ECX = 1.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{XOP} -- XOP instruction extensions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{XSAVE} -- The XSAVE/XRSTOR processor extended states feature, the
b1dca6
+XSETBV/XGETBV instructions, and XCR0.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{XSAVEC} -- XSAVEC instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{XSAVEOPT} -- XSAVEOPT instruction.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{XSAVES} -- XSAVES/XRSTORS instructions.
b1dca6
+
b1dca6
+@item
b1dca6
+@code{XTPRUPDCTRL} -- xTPR Update Control.
b1dca6
+
b1dca6
+@end itemize
b1dca6
+
b1dca6
+You could query if a processor supports @code{AVX} with:
b1dca6
+
b1dca6
+@smallexample
b1dca6
+#include <sys/platform/x86.h>
b1dca6
+
b1dca6
+int
b1dca6
+support_avx (void)
b1dca6
+@{
b1dca6
+  return HAS_CPU_FEATURE (AVX);
b1dca6
+@}
b1dca6
+@end smallexample
b1dca6
+
b1dca6
+and if @code{AVX} is usable with:
b1dca6
+
b1dca6
+@smallexample
b1dca6
+#include <sys/platform/x86.h>
b1dca6
+
b1dca6
+int
b1dca6
+usable_avx (void)
b1dca6
+@{
b1dca6
+  return CPU_FEATURE_USABLE (AVX);
b1dca6
+@}
b1dca6
+@end smallexample
b1dca6
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
b1dca6
index bf75a9947fe013a3..c4897922d710d37e 100644
b1dca6
--- a/sysdeps/i386/i686/multiarch/Makefile
b1dca6
+++ b/sysdeps/i386/i686/multiarch/Makefile
b1dca6
@@ -1,7 +1,3 @@
b1dca6
-ifeq ($(subdir),csu)
b1dca6
-tests += test-multiarch
b1dca6
-endif
b1dca6
-
b1dca6
 ifeq ($(subdir),string)
b1dca6
 gen-as-const-headers += locale-defines.sym
b1dca6
 sysdep_routines += bzero-sse2 memset-sse2 memcpy-ssse3 mempcpy-ssse3 \
b1dca6
diff --git a/sysdeps/i386/i686/multiarch/test-multiarch.c b/sysdeps/i386/i686/multiarch/test-multiarch.c
b1dca6
deleted file mode 100644
b1dca6
index 593cfec2735fb5b0..0000000000000000
b1dca6
--- a/sysdeps/i386/i686/multiarch/test-multiarch.c
b1dca6
+++ /dev/null
b1dca6
@@ -1 +0,0 @@
b1dca6
-#include <sysdeps/x86_64/multiarch/test-multiarch.c>
b1dca6
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
b1dca6
index 962bbcb07eba1259..59e928e9d08d3229 100644
b1dca6
--- a/sysdeps/x86/Makefile
b1dca6
+++ b/sysdeps/x86/Makefile
b1dca6
@@ -5,7 +5,8 @@ endif
b1dca6
 ifeq ($(subdir),elf)
b1dca6
 sysdep-dl-routines += dl-get-cpu-features
b1dca6
 
b1dca6
-tests += tst-get-cpu-features tst-get-cpu-features-static
b1dca6
+tests += tst-get-cpu-features tst-get-cpu-features-static \
b1dca6
+	 tst-cpu-features-cpuinfo tst-cpu-features-supports
b1dca6
 tests-static += tst-get-cpu-features-static
b1dca6
 endif
b1dca6
 
b1dca6
diff --git a/sysdeps/x86/Versions b/sysdeps/x86/Versions
b1dca6
index e02923708e160881..df70e602192053c0 100644
b1dca6
--- a/sysdeps/x86/Versions
b1dca6
+++ b/sysdeps/x86/Versions
b1dca6
@@ -1,5 +1,5 @@
b1dca6
 ld {
b1dca6
   GLIBC_PRIVATE {
b1dca6
-    __get_cpu_features;
b1dca6
+    __x86_get_cpu_features;
b1dca6
   }
b1dca6
 }
b1dca6
diff --git a/sysdeps/x86/dl-get-cpu-features.c b/sysdeps/x86/dl-get-cpu-features.c
b1dca6
index 49593f19c64ad0bb..2aba0d167129b336 100644
b1dca6
--- a/sysdeps/x86/dl-get-cpu-features.c
b1dca6
+++ b/sysdeps/x86/dl-get-cpu-features.c
b1dca6
@@ -18,10 +18,12 @@
b1dca6
 
b1dca6
 #include <ldsodefs.h>
b1dca6
 
b1dca6
-#undef __get_cpu_features
b1dca6
+#undef __x86_get_cpu_features
b1dca6
 
b1dca6
 const struct cpu_features *
b1dca6
-__get_cpu_features (void)
b1dca6
+__x86_get_cpu_features (unsigned int max)
b1dca6
 {
b1dca6
+  if (max > COMMON_CPUID_INDEX_MAX)
b1dca6
+    return NULL;
b1dca6
   return &GLRO(dl_x86_cpu_features);
b1dca6
 }
b1dca6
diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h
b1dca6
new file mode 100644
b1dca6
index 0000000000000000..dcf29b6fe8578078
b1dca6
--- /dev/null
b1dca6
+++ b/sysdeps/x86/include/cpu-features.h
b1dca6
@@ -0,0 +1,183 @@
b1dca6
+/* Data structure for x86 CPU features.
b1dca6
+   Copyright (C) 2020 Free Software Foundation, Inc.
b1dca6
+   This file is part of the GNU C Library.
b1dca6
+
b1dca6
+   The GNU C Library is free software; you can redistribute it and/or
b1dca6
+   modify it under the terms of the GNU Lesser General Public
b1dca6
+   License as published by the Free Software Foundation; either
b1dca6
+   version 2.1 of the License, or (at your option) any later version.
b1dca6
+
b1dca6
+   The GNU C Library is distributed in the hope that it will be useful,
b1dca6
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
b1dca6
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
b1dca6
+   Lesser General Public License for more details.
b1dca6
+
b1dca6
+   You should have received a copy of the GNU Lesser General Public
b1dca6
+   License along with the GNU C Library; if not, see
b1dca6
+   <https://www.gnu.org/licenses/>.  */
b1dca6
+
b1dca6
+#ifndef	_PRIVATE_CPU_FEATURES_H
b1dca6
+#define	_PRIVATE_CPU_FEATURES_H	1
b1dca6
+
b1dca6
+#ifdef _CPU_FEATURES_H
b1dca6
+# error this should be impossible
b1dca6
+#endif
b1dca6
+
b1dca6
+#ifndef _ISOMAC
b1dca6
+/* Get most of the contents from the public header, but we define a
b1dca6
+   different `struct cpu_features' type for private use.  */
b1dca6
+# define cpu_features		cpu_features_public
b1dca6
+# define __x86_get_cpu_features	__x86_get_cpu_features_public
b1dca6
+#endif
b1dca6
+
b1dca6
+#include <sysdeps/x86/sys/platform/x86.h>
b1dca6
+
b1dca6
+#ifndef _ISOMAC
b1dca6
+
b1dca6
+# undef	cpu_features
b1dca6
+# undef __x86_get_cpu_features
b1dca6
+# define __get_cpu_features()	__x86_get_cpu_features (0)
b1dca6
+
b1dca6
+enum
b1dca6
+{
b1dca6
+  /* The integer bit array index for the first set of preferred feature
b1dca6
+     bits.  */
b1dca6
+  PREFERRED_FEATURE_INDEX_1 = 0,
b1dca6
+  /* The current maximum size of the feature integer bit array.  */
b1dca6
+  PREFERRED_FEATURE_INDEX_MAX
b1dca6
+};
b1dca6
+
b1dca6
+/* Only used directly in cpu-features.c.  */
b1dca6
+# define CPU_FEATURE_SET(ptr, name) \
b1dca6
+  ptr->features[index_cpu_##name].usable.reg_##name |= bit_cpu_##name;
b1dca6
+# define CPU_FEATURE_UNSET(ptr, name) \
b1dca6
+  ptr->features[index_cpu_##name].usable.reg_##name &= ~bit_cpu_##name;
b1dca6
+# define CPU_FEATURE_SET_USABLE(ptr, name) \
b1dca6
+  ptr->features[index_cpu_##name].usable.reg_##name \
b1dca6
+     |= ptr->features[index_cpu_##name].cpuid.reg_##name & bit_cpu_##name;
b1dca6
+# define CPU_FEATURE_PREFERRED_P(ptr, name) \
b1dca6
+  ((ptr->preferred[index_arch_##name] & bit_arch_##name) != 0)
b1dca6
+# define CPU_FEATURE_CPU_P(ptr, name) \
b1dca6
+  CPU_FEATURE_CHECK_P (ptr, name, cpuid)
b1dca6
+
b1dca6
+/* HAS_CPU_FEATURE evaluates to true if CPU supports the feature.  */
b1dca6
+# undef HAS_CPU_FEATURE
b1dca6
+# define HAS_CPU_FEATURE(name) \
b1dca6
+  CPU_FEATURE_CPU_P (__x86_get_cpu_features (0), name)
b1dca6
+/* CPU_FEATURE_USABLE evaluates to true if the feature is usable.  */
b1dca6
+# undef CPU_FEATURE_USABLE
b1dca6
+# define CPU_FEATURE_USABLE(name) \
b1dca6
+  CPU_FEATURE_USABLE_P (__x86_get_cpu_features (0), name)
b1dca6
+/* CPU_FEATURE_PREFER evaluates to true if we prefer the feature at
b1dca6
+   runtime.  */
b1dca6
+# define CPU_FEATURE_PREFERRED(name) \
b1dca6
+  CPU_FEATURE_PREFERRED_P(__get_cpu_features (), name)
b1dca6
+
b1dca6
+# define CPU_FEATURES_CPU_P(ptr, name) \
b1dca6
+  CPU_FEATURE_CPU_P (ptr, name)
b1dca6
+# define CPU_FEATURES_ARCH_P(ptr, name) \
b1dca6
+  CPU_FEATURE_PREFERRED_P (ptr, name)
b1dca6
+# define HAS_ARCH_FEATURE(name) \
b1dca6
+  CPU_FEATURE_PREFERRED (name)
b1dca6
+
b1dca6
+/* PREFERRED_FEATURE_INDEX_1.  */
b1dca6
+# define bit_arch_I586				(1u << 0)
b1dca6
+# define bit_arch_I686				(1u << 1)
b1dca6
+# define bit_arch_Fast_Rep_String		(1u << 2)
b1dca6
+# define bit_arch_Fast_Copy_Backward		(1u << 3)
b1dca6
+# define bit_arch_Fast_Unaligned_Load		(1u << 4)
b1dca6
+# define bit_arch_Fast_Unaligned_Copy		(1u << 5)
b1dca6
+# define bit_arch_Slow_BSF			(1u << 6)
b1dca6
+# define bit_arch_Slow_SSE4_2			(1u << 7)
b1dca6
+# define bit_arch_AVX_Fast_Unaligned_Load	(1u << 8)
b1dca6
+# define bit_arch_Prefer_MAP_32BIT_EXEC		(1u << 9)
b1dca6
+# define bit_arch_Prefer_PMINUB_for_stringop	(1u << 10)
b1dca6
+# define bit_arch_Prefer_No_VZEROUPPER		(1u << 11)
b1dca6
+# define bit_arch_Prefer_ERMS			(1u << 12)
b1dca6
+# define bit_arch_Prefer_FSRM			(1u << 13)
b1dca6
+# define bit_arch_Prefer_No_AVX512		(1u << 14)
b1dca6
+# define bit_arch_MathVec_Prefer_No_AVX512	(1u << 15)
b1dca6
+
b1dca6
+# define index_arch_Fast_Rep_String		PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_Fast_Copy_Backward		PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_Slow_BSF			PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_Fast_Unaligned_Load		PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_Prefer_PMINUB_for_stringop 	PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_Fast_Unaligned_Copy		PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_I586			PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_I686			PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_Slow_SSE4_2			PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_AVX_Fast_Unaligned_Load	PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_Prefer_MAP_32BIT_EXEC	PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_Prefer_No_VZEROUPPER	PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_Prefer_ERMS			PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_Prefer_No_AVX512		PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_MathVec_Prefer_No_AVX512	PREFERRED_FEATURE_INDEX_1
b1dca6
+# define index_arch_Prefer_FSRM			PREFERRED_FEATURE_INDEX_1
b1dca6
+
b1dca6
+/* XCR0 Feature flags.  */
b1dca6
+# define bit_XMM_state		(1u << 1)
b1dca6
+# define bit_YMM_state		(1u << 2)
b1dca6
+# define bit_Opmask_state	(1u << 5)
b1dca6
+# define bit_ZMM0_15_state	(1u << 6)
b1dca6
+# define bit_ZMM16_31_state	(1u << 7)
b1dca6
+# define bit_XTILECFG_state	(1u << 17)
b1dca6
+# define bit_XTILEDATA_state	(1u << 18)
b1dca6
+
b1dca6
+struct cpu_features
b1dca6
+{
b1dca6
+  struct cpu_features_basic basic;
b1dca6
+  struct cpuid_features features[COMMON_CPUID_INDEX_MAX];
b1dca6
+  unsigned int preferred[PREFERRED_FEATURE_INDEX_MAX];
b1dca6
+  /* The state size for XSAVEC or XSAVE.  The type must be unsigned long
b1dca6
+     int so that we use
b1dca6
+
b1dca6
+	sub xsave_state_size_offset(%rip) %RSP_LP
b1dca6
+
b1dca6
+     in _dl_runtime_resolve.  */
b1dca6
+  unsigned long int xsave_state_size;
b1dca6
+  /* The full state size for XSAVE when XSAVEC is disabled by
b1dca6
+
b1dca6
+     GLIBC_TUNABLES=glibc.cpu.hwcaps=-XSAVEC
b1dca6
+   */
b1dca6
+  unsigned int xsave_state_full_size;
b1dca6
+  /* Data cache size for use in memory and string routines, typically
b1dca6
+     L1 size.  */
b1dca6
+  unsigned long int data_cache_size;
b1dca6
+  /* Shared cache size for use in memory and string routines, typically
b1dca6
+     L2 or L3 size.  */
b1dca6
+  unsigned long int shared_cache_size;
b1dca6
+  /* Threshold to use non temporal store.  */
b1dca6
+  unsigned long int non_temporal_threshold;
b1dca6
+  /* Threshold to use "rep movsb".  */
b1dca6
+  unsigned long int rep_movsb_threshold;
b1dca6
+  /* Threshold to use "rep stosb".  */
b1dca6
+  unsigned long int rep_stosb_threshold;
b1dca6
+};
b1dca6
+
b1dca6
+# if defined (_LIBC) && !IS_IN (nonlib)
b1dca6
+/* Unused for x86.  */
b1dca6
+#  define INIT_ARCH()
b1dca6
+#  define __x86_get_cpu_features(max) (&GLRO(dl_x86_cpu_features))
b1dca6
+# endif
b1dca6
+
b1dca6
+# ifdef __x86_64__
b1dca6
+#  define HAS_CPUID 1
b1dca6
+# elif (defined __i586__ || defined __pentium__	\
b1dca6
+	|| defined __geode__ || defined __k6__)
b1dca6
+#  define HAS_CPUID 1
b1dca6
+#  define HAS_I586 1
b1dca6
+#  define HAS_I686 HAS_ARCH_FEATURE (I686)
b1dca6
+# elif defined __i486__
b1dca6
+#  define HAS_CPUID 0
b1dca6
+#  define HAS_I586 HAS_ARCH_FEATURE (I586)
b1dca6
+#  define HAS_I686 HAS_ARCH_FEATURE (I686)
b1dca6
+# else
b1dca6
+#  define HAS_CPUID 1
b1dca6
+#  define HAS_I586 1
b1dca6
+#  define HAS_I686 1
b1dca6
+# endif
b1dca6
+
b1dca6
+#endif /* !_ISOMAC */
b1dca6
+
b1dca6
+#endif /* include/cpu-features.h */
b1dca6
diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/sys/platform/x86.h
b1dca6
similarity index 81%
b1dca6
rename from sysdeps/x86/cpu-features.h
b1dca6
rename to sysdeps/x86/sys/platform/x86.h
b1dca6
index 3b401d441b8d370a..ebc5f6fc16cb8104 100644
b1dca6
--- a/sysdeps/x86/cpu-features.h
b1dca6
+++ b/sysdeps/x86/sys/platform/x86.h
b1dca6
@@ -1,5 +1,6 @@
b1dca6
-/* This file is part of the GNU C Library.
b1dca6
-   Copyright (C) 2008-2018 Free Software Foundation, Inc.
b1dca6
+/* Data structure for x86 CPU features.
b1dca6
+   This file is part of the GNU C Library.
b1dca6
+   Copyright (C) 2008-2020 Free Software Foundation, Inc.
b1dca6
 
b1dca6
    The GNU C Library is free software; you can redistribute it and/or
b1dca6
    modify it under the terms of the GNU Lesser General Public
b1dca6
@@ -15,17 +16,8 @@
b1dca6
    License along with the GNU C Library; if not, see
b1dca6
    <http://www.gnu.org/licenses/>.  */
b1dca6
 
b1dca6
-#ifndef cpu_features_h
b1dca6
-#define cpu_features_h
b1dca6
-
b1dca6
-enum
b1dca6
-{
b1dca6
-  /* The integer bit array index for the first set of preferred feature
b1dca6
-     bits.  */
b1dca6
-  PREFERRED_FEATURE_INDEX_1 = 0,
b1dca6
-  /* The current maximum size of the feature integer bit array.  */
b1dca6
-  PREFERRED_FEATURE_INDEX_MAX
b1dca6
-};
b1dca6
+#ifndef _SYS_PLATFORM_X86_H
b1dca6
+#define _SYS_PLATFORM_X86_H
b1dca6
 
b1dca6
 enum
b1dca6
 {
b1dca6
@@ -76,73 +68,32 @@ struct cpu_features
b1dca6
 {
b1dca6
   struct cpu_features_basic basic;
b1dca6
   struct cpuid_features features[COMMON_CPUID_INDEX_MAX];
b1dca6
-  unsigned int preferred[PREFERRED_FEATURE_INDEX_MAX];
b1dca6
-  /* The state size for XSAVEC or XSAVE.  The type must be unsigned long
b1dca6
-     int so that we use
b1dca6
-
b1dca6
-	sub xsave_state_size_offset(%rip) %RSP_LP
b1dca6
-
b1dca6
-     in _dl_runtime_resolve.  */
b1dca6
-  unsigned long int xsave_state_size;
b1dca6
-  /* The full state size for XSAVE when XSAVEC is disabled by
b1dca6
-
b1dca6
-     GLIBC_TUNABLES=glibc.cpu.hwcaps=-XSAVEC
b1dca6
-   */
b1dca6
-  unsigned int xsave_state_full_size;
b1dca6
-  /* Data cache size for use in memory and string routines, typically
b1dca6
-     L1 size.  */
b1dca6
-  unsigned long int data_cache_size;
b1dca6
-  /* Shared cache size for use in memory and string routines, typically
b1dca6
-     L2 or L3 size.  */
b1dca6
-  unsigned long int shared_cache_size;
b1dca6
-  /* Threshold to use non temporal store.  */
b1dca6
-  unsigned long int non_temporal_threshold;
b1dca6
-  /* Threshold to use "rep movsb".  */
b1dca6
-  unsigned long int rep_movsb_threshold;
b1dca6
-  /* Threshold to use "rep stosb".  */
b1dca6
-  unsigned long int rep_stosb_threshold;
b1dca6
 };
b1dca6
 
b1dca6
-/* Used from outside of glibc to get access to the CPU features
b1dca6
-   structure.  */
b1dca6
-extern const struct cpu_features *__get_cpu_features (void)
b1dca6
+/* Get a pointer to the CPU features structure.  */
b1dca6
+extern const struct cpu_features *__x86_get_cpu_features (unsigned int)
b1dca6
      __attribute__ ((const));
b1dca6
 
b1dca6
-/* Only used directly in cpu-features.c.  */
b1dca6
 #define CPU_FEATURE_CHECK_P(ptr, name, check) \
b1dca6
   ((ptr->features[index_cpu_##name].check.reg_##name \
b1dca6
     & bit_cpu_##name) != 0)
b1dca6
-#define CPU_FEATURE_SET(ptr, name) \
b1dca6
-  ptr->features[index_cpu_##name].usable.reg_##name |= bit_cpu_##name;
b1dca6
-#define CPU_FEATURE_UNSET(ptr, name) \
b1dca6
-  ptr->features[index_cpu_##name].usable.reg_##name &= ~bit_cpu_##name;
b1dca6
-#define CPU_FEATURE_SET_USABLE(ptr, name) \
b1dca6
-  ptr->features[index_cpu_##name].usable.reg_##name \
b1dca6
-     |= ptr->features[index_cpu_##name].cpuid.reg_##name & bit_cpu_##name;
b1dca6
-#define CPU_FEATURE_PREFERRED_P(ptr, name) \
b1dca6
-  ((ptr->preferred[index_arch_##name] & bit_arch_##name) != 0)
b1dca6
 #define CPU_FEATURE_CPU_P(ptr, name) \
b1dca6
   CPU_FEATURE_CHECK_P (ptr, name, cpuid)
b1dca6
 #define CPU_FEATURE_USABLE_P(ptr, name) \
b1dca6
   CPU_FEATURE_CHECK_P (ptr, name, usable)
b1dca6
 
b1dca6
 /* HAS_CPU_FEATURE evaluates to true if CPU supports the feature.  */
b1dca6
-#define HAS_CPU_FEATURE(name) \
b1dca6
-  CPU_FEATURE_CPU_P (__get_cpu_features (), name)
b1dca6
+#define HAS_CPU_FEATURE(name)					\
b1dca6
+  (__extension__						\
b1dca6
+   ({ const struct cpu_features *__ptr =			\
b1dca6
+	__x86_get_cpu_features (COMMON_CPUID_INDEX_MAX);	\
b1dca6
+      __ptr && CPU_FEATURE_CPU_P (__ptr, name); }))
b1dca6
 /* CPU_FEATURE_USABLE evaluates to true if the feature is usable.  */
b1dca6
-#define CPU_FEATURE_USABLE(name) \
b1dca6
-  CPU_FEATURE_USABLE_P (__get_cpu_features (), name)
b1dca6
-/* CPU_FEATURE_PREFER evaluates to true if we prefer the feature at
b1dca6
-   runtime.  */
b1dca6
-#define CPU_FEATURE_PREFERRED(name) \
b1dca6
-  CPU_FEATURE_PREFERRED_P(__get_cpu_features (), name)
b1dca6
-
b1dca6
-#define CPU_FEATURES_CPU_P(ptr, name) \
b1dca6
-  CPU_FEATURE_CPU_P (ptr, name)
b1dca6
-#define CPU_FEATURES_ARCH_P(ptr, name) \
b1dca6
-  CPU_FEATURE_PREFERRED_P (ptr, name)
b1dca6
-#define HAS_ARCH_FEATURE(name) \
b1dca6
-  CPU_FEATURE_PREFERRED (name)
b1dca6
+#define CPU_FEATURE_USABLE(name)				\
b1dca6
+  (__extension__						\
b1dca6
+   ({ const struct cpu_features *__ptr =			\
b1dca6
+	__x86_get_cpu_features (COMMON_CPUID_INDEX_MAX);	\
b1dca6
+      __ptr && CPU_FEATURE_USABLE_P (__ptr, name); }))
b1dca6
 
b1dca6
 /* CPU features.  */
b1dca6
 
b1dca6
@@ -787,71 +738,4 @@ extern const struct cpu_features *__get_cpu_features (void)
b1dca6
 /* EAX.  */
b1dca6
 #define reg_AVX512_BF16		eax
b1dca6
 
b1dca6
-/* FEATURE_INDEX_2.  */
b1dca6
-#define bit_arch_I586				(1u << 0)
b1dca6
-#define bit_arch_I686				(1u << 1)
b1dca6
-#define bit_arch_Fast_Rep_String		(1u << 2)
b1dca6
-#define bit_arch_Fast_Copy_Backward		(1u << 3)
b1dca6
-#define bit_arch_Fast_Unaligned_Load		(1u << 4)
b1dca6
-#define bit_arch_Fast_Unaligned_Copy		(1u << 5)
b1dca6
-#define bit_arch_Slow_BSF			(1u << 6)
b1dca6
-#define bit_arch_Slow_SSE4_2			(1u << 7)
b1dca6
-#define bit_arch_AVX_Fast_Unaligned_Load	(1u << 8)
b1dca6
-#define bit_arch_Prefer_MAP_32BIT_EXEC		(1u << 9)
b1dca6
-#define bit_arch_Prefer_PMINUB_for_stringop	(1u << 10)
b1dca6
-#define bit_arch_Prefer_No_VZEROUPPER		(1u << 11)
b1dca6
-#define bit_arch_Prefer_ERMS			(1u << 12)
b1dca6
-#define bit_arch_Prefer_FSRM			(1u << 13)
b1dca6
-#define bit_arch_Prefer_No_AVX512		(1u << 14)
b1dca6
-#define bit_arch_MathVec_Prefer_No_AVX512	(1u << 15)
b1dca6
-
b1dca6
-#define index_arch_Fast_Rep_String		PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_Fast_Copy_Backward		PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_Slow_BSF			PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_Fast_Unaligned_Load		PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_Prefer_PMINUB_for_stringop 	PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_Fast_Unaligned_Copy		PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_I586				PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_I686				PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_Slow_SSE4_2			PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_AVX_Fast_Unaligned_Load	PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_Prefer_MAP_32BIT_EXEC	PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_Prefer_No_VZEROUPPER		PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_Prefer_ERMS			PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_Prefer_No_AVX512		PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_MathVec_Prefer_No_AVX512	PREFERRED_FEATURE_INDEX_1
b1dca6
-#define index_arch_Prefer_FSRM			PREFERRED_FEATURE_INDEX_1
b1dca6
-
b1dca6
-/* XCR0 Feature flags.  */
b1dca6
-#define bit_XMM_state		(1u << 1)
b1dca6
-#define bit_YMM_state		(1u << 2)
b1dca6
-#define bit_Opmask_state	(1u << 5)
b1dca6
-#define bit_ZMM0_15_state	(1u << 6)
b1dca6
-#define bit_ZMM16_31_state	(1u << 7)
b1dca6
-#define bit_XTILECFG_state	(1u << 17)
b1dca6
-#define bit_XTILEDATA_state	(1u << 18)
b1dca6
-
b1dca6
-# if defined (_LIBC) && !IS_IN (nonlib)
b1dca6
-/* Unused for x86.  */
b1dca6
-#  define INIT_ARCH()
b1dca6
-#  define __get_cpu_features()	(&GLRO(dl_x86_cpu_features))
b1dca6
-# endif
b1dca6
-
b1dca6
-#ifdef __x86_64__
b1dca6
-# define HAS_CPUID 1
b1dca6
-#elif (defined __i586__ || defined __pentium__	\
b1dca6
-       || defined __geode__ || defined __k6__)
b1dca6
-# define HAS_CPUID 1
b1dca6
-# define HAS_I586 1
b1dca6
-# define HAS_I686 HAS_ARCH_FEATURE (I686)
b1dca6
-#elif defined __i486__
b1dca6
-# define HAS_CPUID 0
b1dca6
-# define HAS_I586 HAS_ARCH_FEATURE (I586)
b1dca6
-# define HAS_I686 HAS_ARCH_FEATURE (I686)
b1dca6
-#else
b1dca6
-# define HAS_CPUID 1
b1dca6
-# define HAS_I586 1
b1dca6
-# define HAS_I686 1
b1dca6
-#endif
b1dca6
-
b1dca6
-#endif  /* cpu_features_h */
b1dca6
+#endif  /* _SYS_PLATFORM_X86_H */
b1dca6
diff --git a/sysdeps/x86/tst-cpu-features-cpuinfo.c b/sysdeps/x86/tst-cpu-features-cpuinfo.c
b1dca6
new file mode 100644
b1dca6
index 0000000000000000..96277284d15a0690
b1dca6
--- /dev/null
b1dca6
+++ b/sysdeps/x86/tst-cpu-features-cpuinfo.c
b1dca6
@@ -0,0 +1,250 @@
b1dca6
+/* Test CPU feature data against /proc/cpuinfo.
b1dca6
+   This file is part of the GNU C Library.
b1dca6
+   Copyright (C) 2012-2020 Free Software Foundation, Inc.
b1dca6
+
b1dca6
+   The GNU C Library is free software; you can redistribute it and/or
b1dca6
+   modify it under the terms of the GNU Lesser General Public
b1dca6
+   License as published by the Free Software Foundation; either
b1dca6
+   version 2.1 of the License, or (at your option) any later version.
b1dca6
+
b1dca6
+   The GNU C Library is distributed in the hope that it will be useful,
b1dca6
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
b1dca6
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
b1dca6
+   Lesser General Public License for more details.
b1dca6
+
b1dca6
+   You should have received a copy of the GNU Lesser General Public
b1dca6
+   License along with the GNU C Library; if not, see
b1dca6
+   <https://www.gnu.org/licenses/>.  */
b1dca6
+
b1dca6
+#include <sys/platform/x86.h>
b1dca6
+#include <stdio.h>
b1dca6
+#include <stdlib.h>
b1dca6
+#include <string.h>
b1dca6
+
b1dca6
+static char *cpu_flags;
b1dca6
+
b1dca6
+/* Search for flags in /proc/cpuinfo and store line
b1dca6
+   in cpu_flags.  */
b1dca6
+void
b1dca6
+get_cpuinfo (void)
b1dca6
+{
b1dca6
+  FILE *f;
b1dca6
+  char *line = NULL;
b1dca6
+  size_t len = 0;
b1dca6
+  ssize_t read;
b1dca6
+
b1dca6
+  f = fopen ("/proc/cpuinfo", "r");
b1dca6
+  if (f == NULL)
b1dca6
+    {
b1dca6
+      printf ("cannot open /proc/cpuinfo\n");
b1dca6
+      exit (1);
b1dca6
+    }
b1dca6
+
b1dca6
+  while ((read = getline (&line, &len, f)) != -1)
b1dca6
+    {
b1dca6
+      if (strncmp (line, "flags", 5) == 0)
b1dca6
+       {
b1dca6
+         cpu_flags = strdup (line);
b1dca6
+         break;
b1dca6
+       }
b1dca6
+    }
b1dca6
+  fclose (f);
b1dca6
+  free (line);
b1dca6
+}
b1dca6
+
b1dca6
+int
b1dca6
+check_proc (const char *proc_name, int flag, int usable, const char *name)
b1dca6
+{
b1dca6
+  int found = 0;
b1dca6
+
b1dca6
+  printf ("Checking %s:\n", name);
b1dca6
+  if (!usable)
b1dca6
+    {
b1dca6
+      printf ("  %s: insufficient usable info, skipped\n", name);
b1dca6
+      return 0;
b1dca6
+    }
b1dca6
+  printf ("  %s: %d\n", name, flag);
b1dca6
+  if (strstr (cpu_flags, proc_name) != NULL)
b1dca6
+    found = 1;
b1dca6
+  printf ("  cpuinfo (%s): %d\n", proc_name, found);
b1dca6
+
b1dca6
+  if (found != flag)
b1dca6
+    printf (" *** failure ***\n");
b1dca6
+
b1dca6
+  return (found != flag);
b1dca6
+}
b1dca6
+
b1dca6
+#define CHECK_PROC(str, name) \
b1dca6
+  check_proc (#str, HAS_CPU_FEATURE (name), CPU_FEATURE_USABLE (name), \
b1dca6
+	      "HAS_CPU_FEATURE (" #name ")");
b1dca6
+
b1dca6
+static int
b1dca6
+do_test (int argc, char **argv)
b1dca6
+{
b1dca6
+  int fails = 0;
b1dca6
+
b1dca6
+  get_cpuinfo ();
b1dca6
+  fails += CHECK_PROC (acpi, ACPI);
b1dca6
+  fails += CHECK_PROC (adx, ADX);
b1dca6
+  fails += CHECK_PROC (apic, APIC);
b1dca6
+  fails += CHECK_PROC (aes, AES);
b1dca6
+  fails += CHECK_PROC (amx_bf16, AMX_BF16);
b1dca6
+  fails += CHECK_PROC (amx_int8, AMX_INT8);
b1dca6
+  fails += CHECK_PROC (amx_tile, AMX_TILE);
b1dca6
+  fails += CHECK_PROC (arch_capabilities, ARCH_CAPABILITIES);
b1dca6
+  fails += CHECK_PROC (avx, AVX);
b1dca6
+  fails += CHECK_PROC (avx2, AVX2);
b1dca6
+  fails += CHECK_PROC (avx512_4fmaps, AVX512_4FMAPS);
b1dca6
+  fails += CHECK_PROC (avx512_4vnniw, AVX512_4VNNIW);
b1dca6
+  fails += CHECK_PROC (avx512_bf16, AVX512_BF16);
b1dca6
+  fails += CHECK_PROC (avx512_bitalg, AVX512_BITALG);
b1dca6
+  fails += CHECK_PROC (avx512ifma, AVX512_IFMA);
b1dca6
+  fails += CHECK_PROC (avx512_vbmi, AVX512_VBMI);
b1dca6
+  fails += CHECK_PROC (avx512_vbmi2, AVX512_VBMI2);
b1dca6
+  fails += CHECK_PROC (avx512_vnni, AVX512_VNNI);
b1dca6
+  fails += CHECK_PROC (avx512_vp2intersect, AVX512_VP2INTERSECT);
b1dca6
+  fails += CHECK_PROC (avx512_vpopcntdq, AVX512_VPOPCNTDQ);
b1dca6
+  fails += CHECK_PROC (avx512bw, AVX512BW);
b1dca6
+  fails += CHECK_PROC (avx512cd, AVX512CD);
b1dca6
+  fails += CHECK_PROC (avx512er, AVX512ER);
b1dca6
+  fails += CHECK_PROC (avx512dq, AVX512DQ);
b1dca6
+  fails += CHECK_PROC (avx512f, AVX512F);
b1dca6
+  fails += CHECK_PROC (avx512pf, AVX512PF);
b1dca6
+  fails += CHECK_PROC (avx512vl, AVX512VL);
b1dca6
+  fails += CHECK_PROC (bmi1, BMI1);
b1dca6
+  fails += CHECK_PROC (bmi2, BMI2);
b1dca6
+  fails += CHECK_PROC (cldemote, CLDEMOTE);
b1dca6
+  fails += CHECK_PROC (clflushopt, CLFLUSHOPT);
b1dca6
+  fails += CHECK_PROC (clflush, CLFSH);
b1dca6
+  fails += CHECK_PROC (clwb, CLWB);
b1dca6
+  fails += CHECK_PROC (cmov, CMOV);
b1dca6
+  fails += CHECK_PROC (cx16, CMPXCHG16B);
b1dca6
+  fails += CHECK_PROC (cnxt_id, CNXT_ID);
b1dca6
+  fails += CHECK_PROC (core_capabilities, CORE_CAPABILITIES);
b1dca6
+  fails += CHECK_PROC (cx8, CX8);
b1dca6
+  fails += CHECK_PROC (dca, DCA);
b1dca6
+  fails += CHECK_PROC (de, DE);
b1dca6
+  fails += CHECK_PROC (zero_fcs_fds, DEPR_FPU_CS_DS);
b1dca6
+  fails += CHECK_PROC (ds, DS);
b1dca6
+  fails += CHECK_PROC (ds_cpl, DS_CPL);
b1dca6
+  fails += CHECK_PROC (dtes64, DTES64);
b1dca6
+  fails += CHECK_PROC (est, EIST);
b1dca6
+  fails += CHECK_PROC (enqcmd, ENQCMD);
b1dca6
+  fails += CHECK_PROC (erms, ERMS);
b1dca6
+  fails += CHECK_PROC (f16c, F16C);
b1dca6
+  fails += CHECK_PROC (fma, FMA);
b1dca6
+  fails += CHECK_PROC (fma4, FMA4);
b1dca6
+  fails += CHECK_PROC (fpu, FPU);
b1dca6
+  fails += CHECK_PROC (fsgsbase, FSGSBASE);
b1dca6
+  fails += CHECK_PROC (fsrm, FSRM);
b1dca6
+  fails += CHECK_PROC (fxsr, FXSR);
b1dca6
+  fails += CHECK_PROC (gfni, GFNI);
b1dca6
+  fails += CHECK_PROC (hle, HLE);
b1dca6
+  fails += CHECK_PROC (ht, HTT);
b1dca6
+  fails += CHECK_PROC (hybrid, HYBRID);
b1dca6
+  fails += CHECK_PROC (ibrs, IBRS_IBPB);
b1dca6
+  fails += CHECK_PROC (ibt, IBT);
b1dca6
+  fails += CHECK_PROC (invariant_tsc, INVARIANT_TSC);
b1dca6
+  fails += CHECK_PROC (invpcid, INVPCID);
b1dca6
+  fails += CHECK_PROC (flush_l1d, L1D_FLUSH);
b1dca6
+  fails += CHECK_PROC (lahf_lm, LAHF64_SAHF64);
b1dca6
+  fails += CHECK_PROC (lm, LM);
b1dca6
+  fails += CHECK_PROC (lwp, LWP);
b1dca6
+  fails += CHECK_PROC (abm, LZCNT);
b1dca6
+  fails += CHECK_PROC (mca, MCA);
b1dca6
+  fails += CHECK_PROC (mce, MCE);
b1dca6
+  fails += CHECK_PROC (md_clear, MD_CLEAR);
b1dca6
+  fails += CHECK_PROC (mmx, MMX);
b1dca6
+  fails += CHECK_PROC (monitor, MONITOR);
b1dca6
+  fails += CHECK_PROC (movbe, MOVBE);
b1dca6
+  fails += CHECK_PROC (movdiri, MOVDIRI);
b1dca6
+  fails += CHECK_PROC (movdir64b, MOVDIR64B);
b1dca6
+  fails += CHECK_PROC (mpx, MPX);
b1dca6
+  fails += CHECK_PROC (msr, MSR);
b1dca6
+  fails += CHECK_PROC (mtrr, MTRR);
b1dca6
+  fails += CHECK_PROC (nx, NX);
b1dca6
+  fails += CHECK_PROC (ospke, OSPKE);
b1dca6
+#if 0
b1dca6
+  /* NB: /proc/cpuinfo doesn't report this feature.  */
b1dca6
+  fails += CHECK_PROC (osxsave, OSXSAVE);
b1dca6
+#endif
b1dca6
+  fails += CHECK_PROC (pae, PAE);
b1dca6
+  fails += CHECK_PROC (pdpe1gb, PAGE1GB);
b1dca6
+  fails += CHECK_PROC (pat, PAT);
b1dca6
+  fails += CHECK_PROC (pbe, PBE);
b1dca6
+  fails += CHECK_PROC (pcid, PCID);
b1dca6
+  fails += CHECK_PROC (pclmulqdq, PCLMULQDQ);
b1dca6
+  fails += CHECK_PROC (pconfig, PCONFIG);
b1dca6
+  fails += CHECK_PROC (pdcm, PDCM);
b1dca6
+  fails += CHECK_PROC (pge, PGE);
b1dca6
+  fails += CHECK_PROC (pks, PKS);
b1dca6
+  fails += CHECK_PROC (pku, PKU);
b1dca6
+  fails += CHECK_PROC (popcnt, POPCNT);
b1dca6
+  fails += CHECK_PROC (3dnowprefetch, PREFETCHW);
b1dca6
+  fails += CHECK_PROC (prefetchwt1, PREFETCHWT1);
b1dca6
+  fails += CHECK_PROC (pse, PSE);
b1dca6
+  fails += CHECK_PROC (pse36, PSE_36);
b1dca6
+  fails += CHECK_PROC (psn, PSN);
b1dca6
+  fails += CHECK_PROC (rdpid, RDPID);
b1dca6
+  fails += CHECK_PROC (rdrand, RDRAND);
b1dca6
+  fails += CHECK_PROC (rdseed, RDSEED);
b1dca6
+  fails += CHECK_PROC (rdt_a, RDT_A);
b1dca6
+  fails += CHECK_PROC (cqm, RDT_M);
b1dca6
+  fails += CHECK_PROC (rdtscp, RDTSCP);
b1dca6
+  fails += CHECK_PROC (rtm, RTM);
b1dca6
+  fails += CHECK_PROC (sdbg, SDBG);
b1dca6
+  fails += CHECK_PROC (sep, SEP);
b1dca6
+  fails += CHECK_PROC (serialize, SERIALIZE);
b1dca6
+  fails += CHECK_PROC (sgx, SGX);
b1dca6
+  fails += CHECK_PROC (sgx_lc, SGX_LC);
b1dca6
+  fails += CHECK_PROC (sha_ni, SHA);
b1dca6
+  fails += CHECK_PROC (shstk, SHSTK);
b1dca6
+  fails += CHECK_PROC (smap, SMAP);
b1dca6
+  fails += CHECK_PROC (smep, SMEP);
b1dca6
+  fails += CHECK_PROC (smx, SMX);
b1dca6
+  fails += CHECK_PROC (ss, SS);
b1dca6
+  fails += CHECK_PROC (ssbd, SSBD);
b1dca6
+  fails += CHECK_PROC (sse, SSE);
b1dca6
+  fails += CHECK_PROC (sse2, SSE2);
b1dca6
+  fails += CHECK_PROC (sse3, SSE3);
b1dca6
+  fails += CHECK_PROC (sse4_1, SSE4_1);
b1dca6
+  fails += CHECK_PROC (sse4_2, SSE4_2);
b1dca6
+  fails += CHECK_PROC (sse4a, SSE4A);
b1dca6
+  fails += CHECK_PROC (ssse3, SSSE3);
b1dca6
+  fails += CHECK_PROC (stibp, STIBP);
b1dca6
+  fails += CHECK_PROC (svm, SVM);
b1dca6
+#ifdef __x86_64__
b1dca6
+  /* NB: SYSCALL_SYSRET is 64-bit only.  */
b1dca6
+  fails += CHECK_PROC (syscall, SYSCALL_SYSRET);
b1dca6
+#endif
b1dca6
+  fails += CHECK_PROC (tbm, TBM);
b1dca6
+  fails += CHECK_PROC (tm, TM);
b1dca6
+  fails += CHECK_PROC (tm2, TM2);
b1dca6
+  fails += CHECK_PROC (intel_pt, TRACE);
b1dca6
+  fails += CHECK_PROC (tsc, TSC);
b1dca6
+  fails += CHECK_PROC (tsc_adjust, TSC_ADJUST);
b1dca6
+  fails += CHECK_PROC (tsc_deadline, TSC_DEADLINE);
b1dca6
+  fails += CHECK_PROC (tsxldtrk, TSXLDTRK);
b1dca6
+  fails += CHECK_PROC (umip, UMIP);
b1dca6
+  fails += CHECK_PROC (vaes, VAES);
b1dca6
+  fails += CHECK_PROC (vme, VME);
b1dca6
+  fails += CHECK_PROC (vmx, VMX);
b1dca6
+  fails += CHECK_PROC (vpclmulqdq, VPCLMULQDQ);
b1dca6
+  fails += CHECK_PROC (waitpkg, WAITPKG);
b1dca6
+  fails += CHECK_PROC (wbnoinvd, WBNOINVD);
b1dca6
+  fails += CHECK_PROC (x2apic, X2APIC);
b1dca6
+  fails += CHECK_PROC (xfd, XFD);
b1dca6
+  fails += CHECK_PROC (xgetbv1, XGETBV_ECX_1);
b1dca6
+  fails += CHECK_PROC (xop, XOP);
b1dca6
+  fails += CHECK_PROC (xsave, XSAVE);
b1dca6
+  fails += CHECK_PROC (xsavec, XSAVEC);
b1dca6
+  fails += CHECK_PROC (xsaveopt, XSAVEOPT);
b1dca6
+  fails += CHECK_PROC (xsaves, XSAVES);
b1dca6
+  fails += CHECK_PROC (xtpr, XTPRUPDCTRL);
b1dca6
+
b1dca6
+  printf ("%d differences between /proc/cpuinfo and glibc code.\n", fails);
b1dca6
+
b1dca6
+  return (fails != 0);
b1dca6
+}
b1dca6
+
b1dca6
+#include "../../../test-skeleton.c"
b1dca6
diff --git a/sysdeps/x86/tst-cpu-features-supports.c b/sysdeps/x86/tst-cpu-features-supports.c
b1dca6
new file mode 100644
b1dca6
index 0000000000000000..bf881b531f4bc2ed
b1dca6
--- /dev/null
b1dca6
+++ b/sysdeps/x86/tst-cpu-features-supports.c
b1dca6
@@ -0,0 +1,192 @@
b1dca6
+/* Test CPU feature data against __builtin_cpu_supports.
b1dca6
+   This file is part of the GNU C Library.
b1dca6
+   Copyright (C) 2020 Free Software Foundation, Inc.
b1dca6
+
b1dca6
+   The GNU C Library is free software; you can redistribute it and/or
b1dca6
+   modify it under the terms of the GNU Lesser General Public
b1dca6
+   License as published by the Free Software Foundation; either
b1dca6
+   version 2.1 of the License, or (at your option) any later version.
b1dca6
+
b1dca6
+   The GNU C Library is distributed in the hope that it will be useful,
b1dca6
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
b1dca6
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
b1dca6
+   Lesser General Public License for more details.
b1dca6
+
b1dca6
+   You should have received a copy of the GNU Lesser General Public
b1dca6
+   License along with the GNU C Library; if not, see
b1dca6
+   <https://www.gnu.org/licenses/>.  */
b1dca6
+
b1dca6
+#include <sys/platform/x86.h>
b1dca6
+#include <stdio.h>
b1dca6
+
b1dca6
+int
b1dca6
+check_supports (int supports, int usable, const char *supports_name,
b1dca6
+		const char *name)
b1dca6
+{
b1dca6
+  printf ("Checking %s:\n", name);
b1dca6
+  printf ("  %s: %d\n", name, usable);
b1dca6
+  printf ("  __builtin_cpu_supports (%s): %d\n",
b1dca6
+	  supports_name, supports);
b1dca6
+
b1dca6
+  if ((supports != 0) != (usable != 0))
b1dca6
+    {
b1dca6
+      printf (" *** failure ***\n");
b1dca6
+      return 1;
b1dca6
+    }
b1dca6
+
b1dca6
+  return 0;
b1dca6
+}
b1dca6
+
b1dca6
+#define CHECK_SUPPORTS(str, name) \
b1dca6
+  check_supports (__builtin_cpu_supports (#str), \
b1dca6
+		  CPU_FEATURE_USABLE (name), \
b1dca6
+		  #str, "HAS_CPU_FEATURE (" #name ")");
b1dca6
+
b1dca6
+static int
b1dca6
+do_test (int argc, char **argv)
b1dca6
+{
b1dca6
+  int fails = 0;
b1dca6
+
b1dca6
+#if __GNUC_PREREQ (11, 0)
b1dca6
+  fails += CHECK_SUPPORTS (adx, ADX);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (6, 0)
b1dca6
+  fails += CHECK_SUPPORTS (aes, AES);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (11, 1)
b1dca6
+  fails += CHECK_SUPPORTS (amx_bf16, AMX_BF16);
b1dca6
+  fails += CHECK_SUPPORTS (amx_int8, AMX_INT8);
b1dca6
+  fails += CHECK_SUPPORTS (amx_tile, AMX_TILE);
b1dca6
+#endif
b1dca6
+  fails += CHECK_SUPPORTS (avx, AVX);
b1dca6
+  fails += CHECK_SUPPORTS (avx2, AVX2);
b1dca6
+#if __GNUC_PREREQ (7, 0)
b1dca6
+  fails += CHECK_SUPPORTS (avx5124fmaps, AVX512_4FMAPS);
b1dca6
+  fails += CHECK_SUPPORTS (avx5124vnniw, AVX512_4VNNIW);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (10, 0)
b1dca6
+  fails += CHECK_SUPPORTS (avx512bf16, AVX512_BF16);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (8, 0)
b1dca6
+  fails += CHECK_SUPPORTS (avx512bitalg, AVX512_BITALG);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (6, 0)
b1dca6
+  fails += CHECK_SUPPORTS (avx512ifma, AVX512_IFMA);
b1dca6
+  fails += CHECK_SUPPORTS (avx512vbmi, AVX512_VBMI);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (8, 0)
b1dca6
+  fails += CHECK_SUPPORTS (avx512vbmi2, AVX512_VBMI2);
b1dca6
+  fails += CHECK_SUPPORTS (avx512vnni, AVX512_VNNI);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (10, 0)
b1dca6
+  fails += CHECK_SUPPORTS (avx512vp2intersect, AVX512_VP2INTERSECT);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (7, 0)
b1dca6
+  fails += CHECK_SUPPORTS (avx512vpopcntdq, AVX512_VPOPCNTDQ);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (6, 0)
b1dca6
+  fails += CHECK_SUPPORTS (avx512bw, AVX512BW);
b1dca6
+  fails += CHECK_SUPPORTS (avx512cd, AVX512CD);
b1dca6
+  fails += CHECK_SUPPORTS (avx512er, AVX512ER);
b1dca6
+  fails += CHECK_SUPPORTS (avx512dq, AVX512DQ);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (5, 0)
b1dca6
+  fails += CHECK_SUPPORTS (avx512f, AVX512F);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (6, 0)
b1dca6
+  fails += CHECK_SUPPORTS (avx512pf, AVX512PF);
b1dca6
+  fails += CHECK_SUPPORTS (avx512vl, AVX512VL);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (5, 0)
b1dca6
+  fails += CHECK_SUPPORTS (bmi, BMI1);
b1dca6
+  fails += CHECK_SUPPORTS (bmi2, BMI2);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (11, 0)
b1dca6
+  fails += CHECK_SUPPORTS (cldemote, CLDEMOTE);
b1dca6
+  fails += CHECK_SUPPORTS (clflushopt, CLFLUSHOPT);
b1dca6
+  fails += CHECK_SUPPORTS (clwb, CLWB);
b1dca6
+#endif
b1dca6
+  fails += CHECK_SUPPORTS (cmov, CMOV);
b1dca6
+#if __GNUC_PREREQ (11, 0)
b1dca6
+  fails += CHECK_SUPPORTS (cmpxchg16b, CMPXCHG16B);
b1dca6
+  fails += CHECK_SUPPORTS (cmpxchg8b, CX8);
b1dca6
+  fails += CHECK_SUPPORTS (enqcmd, ENQCMD);
b1dca6
+  fails += CHECK_SUPPORTS (f16c, F16C);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (4, 9)
b1dca6
+  fails += CHECK_SUPPORTS (fma, FMA);
b1dca6
+  fails += CHECK_SUPPORTS (fma4, FMA4);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (11, 0)
b1dca6
+  fails += CHECK_SUPPORTS (fsgsbase, FSGSBASE);
b1dca6
+  fails += CHECK_SUPPORTS (fxsave, FXSR);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (8, 0)
b1dca6
+  fails += CHECK_SUPPORTS (gfni, GFNI);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (11, 0)
b1dca6
+  fails += CHECK_SUPPORTS (hle, HLE);
b1dca6
+  fails += CHECK_SUPPORTS (ibt, IBT);
b1dca6
+  fails += CHECK_SUPPORTS (lahf_lm, LAHF64_SAHF64);
b1dca6
+  fails += CHECK_SUPPORTS (lm, LM);
b1dca6
+  fails += CHECK_SUPPORTS (lwp, LWP);
b1dca6
+  fails += CHECK_SUPPORTS (lzcnt, LZCNT);
b1dca6
+#endif
b1dca6
+  fails += CHECK_SUPPORTS (mmx, MMX);
b1dca6
+#if __GNUC_PREREQ (11, 0)
b1dca6
+  fails += CHECK_SUPPORTS (movbe, MOVBE);
b1dca6
+  fails += CHECK_SUPPORTS (movdiri, MOVDIRI);
b1dca6
+  fails += CHECK_SUPPORTS (movdir64b, MOVDIR64B);
b1dca6
+  fails += CHECK_SUPPORTS (osxsave, OSXSAVE);
b1dca6
+  fails += CHECK_SUPPORTS (pconfig, PCONFIG);
b1dca6
+  fails += CHECK_SUPPORTS (pku, PKU);
b1dca6
+#endif
b1dca6
+  fails += CHECK_SUPPORTS (popcnt, POPCNT);
b1dca6
+#if __GNUC_PREREQ (11, 0)
b1dca6
+  fails += CHECK_SUPPORTS (prefetchwt1, PREFETCHWT1);
b1dca6
+  fails += CHECK_SUPPORTS (rdpid, RDPID);
b1dca6
+  fails += CHECK_SUPPORTS (rdrnd, RDRAND);
b1dca6
+  fails += CHECK_SUPPORTS (rdseed, RDSEED);
b1dca6
+  fails += CHECK_SUPPORTS (rtm, RTM);
b1dca6
+  fails += CHECK_SUPPORTS (serialize, SERIALIZE);
b1dca6
+  fails += CHECK_SUPPORTS (sha, SHA);
b1dca6
+  fails += CHECK_SUPPORTS (shstk, SHSTK);
b1dca6
+#endif
b1dca6
+  fails += CHECK_SUPPORTS (sse, SSE);
b1dca6
+  fails += CHECK_SUPPORTS (sse2, SSE2);
b1dca6
+  fails += CHECK_SUPPORTS (sse3, SSE3);
b1dca6
+  fails += CHECK_SUPPORTS (sse4.1, SSE4_1);
b1dca6
+  fails += CHECK_SUPPORTS (sse4.2, SSE4_2);
b1dca6
+#if __GNUC_PREREQ (4, 9)
b1dca6
+  fails += CHECK_SUPPORTS (sse4a, SSE4A);
b1dca6
+#endif
b1dca6
+  fails += CHECK_SUPPORTS (ssse3, SSSE3);
b1dca6
+#if __GNUC_PREREQ (11, 0)
b1dca6
+  fails += CHECK_SUPPORTS (tbm, TBM);
b1dca6
+  fails += CHECK_SUPPORTS (tsxldtrk, TSXLDTRK);
b1dca6
+  fails += CHECK_SUPPORTS (vaes, VAES);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (8, 0)
b1dca6
+  fails += CHECK_SUPPORTS (vpclmulqdq, VPCLMULQDQ);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (11, 0)
b1dca6
+  fails += CHECK_SUPPORTS (waitpkg, WAITPKG);
b1dca6
+  fails += CHECK_SUPPORTS (wbnoinvd, WBNOINVD);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (4, 9)
b1dca6
+  fails += CHECK_SUPPORTS (xop, XOP);
b1dca6
+#endif
b1dca6
+#if __GNUC_PREREQ (11, 0)
b1dca6
+  fails += CHECK_SUPPORTS (xsave, XSAVE);
b1dca6
+  fails += CHECK_SUPPORTS (xsavec, XSAVEC);
b1dca6
+  fails += CHECK_SUPPORTS (xsaveopt, XSAVEOPT);
b1dca6
+  fails += CHECK_SUPPORTS (xsaves, XSAVES);
b1dca6
+#endif
b1dca6
+
b1dca6
+  printf ("%d differences between __builtin_cpu_supports and glibc code.\n",
b1dca6
+	  fails);
b1dca6
+
b1dca6
+  return (fails != 0);
b1dca6
+}
b1dca6
+
b1dca6
+#include "../../../test-skeleton.c"
b1dca6
diff --git a/sysdeps/x86/tst-get-cpu-features.c b/sysdeps/x86/tst-get-cpu-features.c
b1dca6
index 582b125a2dad3f21..95e0d33f6c7eeace 100644
b1dca6
--- a/sysdeps/x86/tst-get-cpu-features.c
b1dca6
+++ b/sysdeps/x86/tst-get-cpu-features.c
b1dca6
@@ -1,5 +1,5 @@
b1dca6
-/* Test case for x86 __get_cpu_features interface
b1dca6
-   Copyright (C) 2015-2018 Free Software Foundation, Inc.
b1dca6
+/* Test case for __x86_get_cpu_features interface
b1dca6
+   Copyright (C) 2015-2020 Free Software Foundation, Inc.
b1dca6
    This file is part of the GNU C Library.
b1dca6
 
b1dca6
    The GNU C Library is free software; you can redistribute it and/or
b1dca6
@@ -18,7 +18,7 @@
b1dca6
 
b1dca6
 #include <stdlib.h>
b1dca6
 #include <stdio.h>
b1dca6
-#include <cpu-features.h>
b1dca6
+#include <sys/platform/x86.h>
b1dca6
 #include <support/check.h>
b1dca6
 
b1dca6
 #define CHECK_CPU_FEATURE(name)		\
b1dca6
@@ -44,7 +44,7 @@ static const char * const cpu_kinds[] =
b1dca6
 static int
b1dca6
 do_test (void)
b1dca6
 {
b1dca6
-  const struct cpu_features *cpu_features = __get_cpu_features ();
b1dca6
+  const struct cpu_features *cpu_features = __x86_get_cpu_features (0);
b1dca6
 
b1dca6
   switch (cpu_features->basic.kind)
b1dca6
     {
b1dca6
diff --git a/sysdeps/x86_64/fpu/math-tests-arch.h b/sysdeps/x86_64/fpu/math-tests-arch.h
b1dca6
index 61955d70863321fd..c908eac6b4fff16d 100644
b1dca6
--- a/sysdeps/x86_64/fpu/math-tests-arch.h
b1dca6
+++ b/sysdeps/x86_64/fpu/math-tests-arch.h
b1dca6
@@ -16,7 +16,7 @@
b1dca6
    License along with the GNU C Library; if not, see
b1dca6
    <http://www.gnu.org/licenses/>.  */
b1dca6
 
b1dca6
-#include <cpu-features.h>
b1dca6
+#include <sys/platform/x86.h>
b1dca6
 
b1dca6
 #if defined REQUIRE_AVX
b1dca6
 
b1dca6
diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile
b1dca6
index 395e432c092ca17c..9477538af46787a5 100644
b1dca6
--- a/sysdeps/x86_64/multiarch/Makefile
b1dca6
+++ b/sysdeps/x86_64/multiarch/Makefile
b1dca6
@@ -1,7 +1,3 @@
b1dca6
-ifeq ($(subdir),csu)
b1dca6
-tests += test-multiarch
b1dca6
-endif
b1dca6
-
b1dca6
 ifeq ($(subdir),string)
b1dca6
 
b1dca6
 sysdep_routines += strncat-c stpncpy-c strncpy-c \
b1dca6
diff --git a/sysdeps/x86_64/multiarch/test-multiarch.c b/sysdeps/x86_64/multiarch/test-multiarch.c
b1dca6
deleted file mode 100644
b1dca6
index cc2ea56a6753402d..0000000000000000
b1dca6
--- a/sysdeps/x86_64/multiarch/test-multiarch.c
b1dca6
+++ /dev/null
b1dca6
@@ -1,96 +0,0 @@
b1dca6
-/* Test CPU feature data.
b1dca6
-   This file is part of the GNU C Library.
b1dca6
-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
b1dca6
-
b1dca6
-   The GNU C Library is free software; you can redistribute it and/or
b1dca6
-   modify it under the terms of the GNU Lesser General Public
b1dca6
-   License as published by the Free Software Foundation; either
b1dca6
-   version 2.1 of the License, or (at your option) any later version.
b1dca6
-
b1dca6
-   The GNU C Library is distributed in the hope that it will be useful,
b1dca6
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
b1dca6
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
b1dca6
-   Lesser General Public License for more details.
b1dca6
-
b1dca6
-   You should have received a copy of the GNU Lesser General Public
b1dca6
-   License along with the GNU C Library; if not, see
b1dca6
-   <http://www.gnu.org/licenses/>.  */
b1dca6
-
b1dca6
-#include <cpu-features.h>
b1dca6
-#include <stdio.h>
b1dca6
-#include <stdlib.h>
b1dca6
-#include <string.h>
b1dca6
-
b1dca6
-static char *cpu_flags;
b1dca6
-
b1dca6
-/* Search for flags in /proc/cpuinfo and store line
b1dca6
-   in cpu_flags.  */
b1dca6
-void
b1dca6
-get_cpuinfo (void)
b1dca6
-{
b1dca6
-  FILE *f;
b1dca6
-  char *line = NULL;
b1dca6
-  size_t len = 0;
b1dca6
-  ssize_t read;
b1dca6
-
b1dca6
-  f = fopen ("/proc/cpuinfo", "r");
b1dca6
-  if (f == NULL)
b1dca6
-    {
b1dca6
-      printf ("cannot open /proc/cpuinfo\n");
b1dca6
-      exit (1);
b1dca6
-    }
b1dca6
-
b1dca6
-  while ((read = getline (&line, &len, f)) != -1)
b1dca6
-    {
b1dca6
-      if (strncmp (line, "flags", 5) == 0)
b1dca6
-       {
b1dca6
-         cpu_flags = strdup (line);
b1dca6
-         break;
b1dca6
-       }
b1dca6
-    }
b1dca6
-  fclose (f);
b1dca6
-  free (line);
b1dca6
-}
b1dca6
-
b1dca6
-int
b1dca6
-check_proc (const char *proc_name, int flag, const char *name)
b1dca6
-{
b1dca6
-  int found = 0;
b1dca6
-
b1dca6
-  printf ("Checking %s:\n", name);
b1dca6
-  printf ("  init-arch %d\n", flag);
b1dca6
-  if (strstr (cpu_flags, proc_name) != NULL)
b1dca6
-    found = 1;
b1dca6
-  printf ("  cpuinfo (%s) %d\n", proc_name, found);
b1dca6
-
b1dca6
-  if (found != flag)
b1dca6
-    printf (" *** failure ***\n");
b1dca6
-
b1dca6
-  return (found != flag);
b1dca6
-}
b1dca6
-
b1dca6
-static int
b1dca6
-do_test (int argc, char **argv)
b1dca6
-{
b1dca6
-  int fails;
b1dca6
-
b1dca6
-  get_cpuinfo ();
b1dca6
-  fails = check_proc ("avx", CPU_FEATURE_USABLE (AVX),
b1dca6
-		      "CPU_FEATURE_USABLE (AVX)");
b1dca6
-  fails += check_proc ("fma4", CPU_FEATURE_USABLE (FMA4),
b1dca6
-		       "CPU_FEATURE_USABLE (FMA4)");
b1dca6
-  fails += check_proc ("sse4_2", CPU_FEATURE_USABLE (SSE4_2),
b1dca6
-		       "CPU_FEATURE_USABLE (SSE4_2)");
b1dca6
-  fails += check_proc ("sse4_1", CPU_FEATURE_USABLE (SSE4_1)
b1dca6
-		       , "CPU_FEATURE_USABLE (SSE4_1)");
b1dca6
-  fails += check_proc ("ssse3", CPU_FEATURE_USABLE (SSSE3),
b1dca6
-		       "CPU_FEATURE_USABLE (SSSE3)");
b1dca6
-  fails += check_proc ("popcnt", CPU_FEATURE_USABLE (POPCNT),
b1dca6
-		       "CPU_FEATURE_USABLE (POPCNT)");
b1dca6
-
b1dca6
-  printf ("%d differences between /proc/cpuinfo and glibc code.\n", fails);
b1dca6
-
b1dca6
-  return (fails != 0);
b1dca6
-}
b1dca6
-
b1dca6
-#include "../../../test-skeleton.c"