2 * Copyright (c) Meta Platforms, Inc. and affiliates.
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
11 #ifndef ZSTD_COMMON_CPU_H
12 #define ZSTD_COMMON_CPU_H
15 * Implementation taken from folly/CpuId.h
16 * https://github.com/facebook/folly/blob/master/folly/CpuId.h
32 MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
37 #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
39 __cpuid((int*)reg, 0);
43 __cpuid((int*)reg, 1);
48 __cpuidex((int*)reg, 7, 0);
53 #elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__)
54 /* The following block like the normal cpuid branch below, but gcc
55 * reserves ebx for use of its pic register so we must specially
56 * handle the save and restore to avoid clobbering the register
72 : "=a"(f1a), "=c"(f1c), "=d"(f1d)
79 "movl %%ebx, %%eax\n\t"
81 : "=a"(f7b), "=c"(f7c)
85 #elif defined(__x86_64__) || defined(_M_X64) || defined(__i386__)
87 __asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "ecx", "edx");
90 __asm__("cpuid" : "=a"(f1a), "=c"(f1c), "=d"(f1d) : "a"(1) : "ebx");
95 : "=a"(f7a), "=b"(f7b), "=c"(f7c)
110 #define X(name, r, bit) \
111 MEM_STATIC int ZSTD_cpuid_##name(ZSTD_cpuid_t const cpuid) { \
112 return ((cpuid.r) & (1U << bit)) != 0; \
115 /* cpuid(1): Processor Info and Feature Bits. */
116 #define C(name, bit) X(name, f1c, bit)
147 #define D(name, bit) X(name, f1d, bit)
179 /* cpuid(7): Extended Features. */
180 #define B(name, bit) X(name, f7b, bit)
206 #define C(name, bit) X(name, f7c, bit)
213 #endif /* ZSTD_COMMON_CPU_H */