From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-io1-xd2b.google.com (mail-io1-xd2b.google.com [IPv6:2607:f8b0:4864:20::d2b]) by sourceware.org (Postfix) with ESMTPS id 524043857C40 for ; Wed, 12 Aug 2020 14:01:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 524043857C40 Received: by mail-io1-xd2b.google.com with SMTP id q75so2702974iod.1 for ; Wed, 12 Aug 2020 07:01:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=sGg+/Issktza1vgQ8p2uvdzAsvZHGt2mv9G4HjhffNA=; b=kTxSc73dV0WIhrrDpzWt0A6e0qN2zzZ16DDg5sRdunZTHROudY1m60FtAUWJK4SPlB qULmgtPtPw2iWSzOOoqikq5YQ2BiR4XTDkYH1tr6yselOZ4hjgUFmnUImVfBTYTXCzLD CDztN6JxRo2PQG7oAgv0AlOm3bwXBo+j98AAuf1ru82Q8txXMY6+VxieUFFPoQFXzczj Q0vbdgFfbwNyyBxiNjHlQ98+iIgsGVoffNSdqo69VPltNg2V1dCyJlSQj1nOinXu+hUH ZM/LJNZ/ylY2ztY+9aklLWJU5t5rkAMt4SqG7HaWnRc/nzgSeR7cgZMvg6a0ig8DIKyG VtYA== X-Gm-Message-State: AOAM531Sp79/KMm+s41ttVeIhrKKUMINCYmfG919uYzRkPA4whUQFJWm sIqSYddZ6kfv8NAPF2zA58kRKxoTNAOcZmSiJ2xC7MIV X-Google-Smtp-Source: ABdhPJyuHLt/S37zhHrry/35BNXSxxMeNENCQw8u0codb728tD6d4MiNE9aJ9bHZ6si3MBhkpHtrEHa41Am1JYwVIiY= X-Received: by 2002:a02:8806:: with SMTP id r6mr30971917jai.88.1597240883142; Wed, 12 Aug 2020 07:01:23 -0700 (PDT) MIME-Version: 1.0 References: <20200805230137.3572872-1-hjl.tools@gmail.com> <20200805230137.3572872-2-hjl.tools@gmail.com> In-Reply-To: <20200805230137.3572872-2-hjl.tools@gmail.com> From: "H.J. Lu" Date: Wed, 12 Aug 2020 07:00:47 -0700 Message-ID: Subject: PING: V8 [PATCH 2/2] x86: Install [BZ #26124] To: GNU C Library , "Carlos O'Donell" , Florian Weimer Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Aug 2020 14:01:31 -0000 On Wed, Aug 5, 2020 at 4:01 PM H.J. Lu wrote: > > Install so that programmers can do > > #if __has_include() > #include > #endif > ... > > if (CPU_FEATURE_USABLE (SSE2)) > ... > if (CPU_FEATURE_USABLE (AVX2)) > ... > > 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 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 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 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 > + > +int > +support_avx (void) > +@{ > + return HAS_CPU_FEATURE (AVX); > +@} > +@end smallexample > + > +and if @code{AVX} is usable with: > + > +@smallexample > +#include > + > +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 > 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 > > -#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 > + . */ > + > +#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 > + > +#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 > . */ > > -#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 > + . */ > + > +#include > +#include > +#include > +#include > + > +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 > + . */ > + > +#include > +#include > + > +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 > #include > -#include > +#include > #include > > #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 > . */ > > -#include > +#include > > #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 > - . */ > - > -#include > -#include > -#include > -#include > - > -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.