From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11348 invoked by alias); 29 Jul 2018 16:16:29 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Received: (qmail 11333 invoked by uid 89); 29 Jul 2018 16:16:29 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-8.3 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,GIT_PATCH_1,KAM_NUMSUBJECT,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=nanoseconds, HX-Received:ce0b, evaluates, popcount X-HELO: mail-pg1-f178.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:subject:message-id:mime-version:content-disposition :user-agent; bh=qfvVlh/0UJDTcaqtjsbBXNG2WW4EnYuvETAfQ9HZ8kg=; b=btXVMAEe9XRrVkPW838Lg9Il16RXrmFa82HRULU8b3einMvCwERo3ZGo0H6MgcnJN3 8B4aMajo4FH7Z2LvCKwb9Z1EwwSd0ZpvFV52bGY9RAkQmqsWIx1DzeDMDtyjLAcyY6Pi 1GbZTEtH5XvWttWrcgX23TPkuW+DftQf7baP49ciEjuP+vom90CIJQvfpvP9KbY3JeYc zM2kJkUGDXUYtQv5hEEZ89xuY2ORVRU9zgZhL+/NWNq1fvVZYfFJzV9BxZHFMe1fzD/y hiVPQr4zxdI69h3rWiUOPvhKr2aWsDBEyjFhxzg31DGt+Gcx4bHtwaGMetKT92VzbnbP MjgQ== Return-Path: Date: Sun, 29 Jul 2018 16:16:00 -0000 From: "H.J. Lu" To: GNU C Library Subject: RFC: Add to glibc 2.29 Message-ID: <20180729161623.GA17944@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.10.0 (2018-05-17) X-SW-Source: 2018-07/txt/msg01022.txt.bz2 I am proposing to add to glibc 2.29 to provide an API to access x86 specific platform features: enum { /* The integer bit array index of architecture feature bits. */ FEATURE_INDEX_1 = 0, FEATURE_INDEX_2, /* The current maximum size of the feature integer bit array. */ FEATURE_INDEX_MAX }; 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, /* Keep the following line at the end. */ COMMON_CPUID_INDEX_MAX }; enum cpu_features_kind { arch_kind_unknown = 0, arch_kind_intel, arch_kind_amd, arch_kind_other }; struct cpuid_registers { unsigned int eax; unsigned int ebx; unsigned int ecx; unsigned int edx; }; extern enum cpu_features_kind __x86_get_cpu_kind (void) __attribute__ ((const)); extern const struct cpuid_registers *__x86_get_cpuid_registers (unsigned int) __attribute__ ((const)); extern unsigned int __x86_get_arch_feature (unsigned int) __attribute__ ((const)); extern unsigned long long __x86_tsc_to_ns (unsigned long long); extern unsigned long long __x86_ns_to_tsc (unsigned long long); /* HAS_* evaluates to true if we may use the feature at runtime. */ #define HAS_CPU_FEATURE(name) \ ((__x86_get_cpuid_registers (index_cpu_##name)->reg_##name \ & (bit_cpu_##name)) != 0) #define HAS_ARCH_FEATURE(name) \ ((__x86_get_arch_feature (index_arch_##name) & (bit_arch_##name)) != 0) Users can use to detect if a CPU feature is supported at run-time with HAS_CPU_FEATURE (AVX) which returns true if glibc detects that AVX is available. Before AVX can be used, he/she should check HAS_ARCH_FEATURE (AVX_Usable) which returns true if glibc detects that AVX is available and usable. extern unsigned long long __x86_tsc_to_ns (unsigned long long); extern unsigned long long __x86_ns_to_tsc (unsigned long long); can be used to convert between TSCs and nanoseconds if HAS_ARCH_FEATURE (TSC_To_NS_Usable) returns true. Backward binary compatibility is provided by: 1. __x86_get_cpu_kind will get a new version if a new CPU kind is added to cpu_features_kind. 2. __x86_get_cpuid_registers returns a pointer to a cpuid_registers with all zeros if cpuid index >= COMMON_CPUID_INDEX_MAX. 3. __x86_get_arch_feature returns 0 if architecture index >= FEATURE_INDEX_MAX. This means: 1. Applications linked against the new __x86_get_cpu_kind will only run with the newer libc.so. 2. Applications linked against the new __x86_get_cpuid_registers and __x86_get_arch_feature will run with the older libc.so. But new CPU and architecture features won't be detected by the older libc.so. This program: https://github.com/hjl-tools/glibc/blob/hjl/platform/master/sysdeps/x86/tst-x86-platform-1.c may display: [hjl@gnu-efi-2 build-x86_64-linux]$ ./elf/tst-x86-platform-1 Vendor: Intel CPU features: SSE3 PCLMULQDQ DTES64 MONITOR DS_CPL VMX EST TM2 SSSE3 SDBG FMA CMPXCHG16B XTPRUPDCTRL PDCM PCID SSE4_1 SSE4_2 X2APIC MOVBE POPCOUNT TSC_DEADLINE AES XSAVE OSXSAVE AVX F16C RDRAND FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA CMOV PAT PSE_36 DS ACPI MMX FXSR SSE SSE2 SS HTT TM PBE FSGSBASE TSC_ADJUST SGX BMI1 AVX2 BMI2 ERMS INVPCID MPX RDSEED ADX SMAP TRACE LAHF64_SAHF64 LZCNT PREFETCHW SYSCALL_SYSRET NX PAGE1GB RDTSCP LM XSAVEOPT XSAVEC XGETBV_ECX_1 XSAVES INVARIANT_TSC Architecture features: AVX_Usable AVX2_Usable FMA_Usable XSAVEC_Usable TSC_To_NS_Usable [hjl@gnu-efi-2 build-x86_64-linux]$ Any comments? H.J.