/src/libdeflate/lib/x86/cpu_features.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * x86/cpu_features.h - feature detection for x86 CPUs |
3 | | * |
4 | | * Copyright 2016 Eric Biggers |
5 | | * |
6 | | * Permission is hereby granted, free of charge, to any person |
7 | | * obtaining a copy of this software and associated documentation |
8 | | * files (the "Software"), to deal in the Software without |
9 | | * restriction, including without limitation the rights to use, |
10 | | * copy, modify, merge, publish, distribute, sublicense, and/or sell |
11 | | * copies of the Software, and to permit persons to whom the |
12 | | * Software is furnished to do so, subject to the following |
13 | | * conditions: |
14 | | * |
15 | | * The above copyright notice and this permission notice shall be |
16 | | * included in all copies or substantial portions of the Software. |
17 | | * |
18 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
19 | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
20 | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
21 | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
22 | | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
23 | | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
24 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
25 | | * OTHER DEALINGS IN THE SOFTWARE. |
26 | | */ |
27 | | |
28 | | #ifndef LIB_X86_CPU_FEATURES_H |
29 | | #define LIB_X86_CPU_FEATURES_H |
30 | | |
31 | | #include "../lib_common.h" |
32 | | |
33 | | #if defined(ARCH_X86_32) || defined(ARCH_X86_64) |
34 | | |
35 | 6 | #define X86_CPU_FEATURE_SSE2 (1 << 0) |
36 | 6 | #define X86_CPU_FEATURE_PCLMULQDQ (1 << 1) |
37 | 6 | #define X86_CPU_FEATURE_AVX (1 << 2) |
38 | 18 | #define X86_CPU_FEATURE_AVX2 (1 << 3) |
39 | 12 | #define X86_CPU_FEATURE_BMI2 (1 << 4) |
40 | | /* |
41 | | * ZMM indicates whether 512-bit vectors (zmm registers) should be used. On |
42 | | * some CPUs, to avoid downclocking issues we don't set ZMM even if the CPU and |
43 | | * operating system support AVX-512. On these CPUs, we may still use AVX-512 |
44 | | * instructions, but only with xmm and ymm registers. |
45 | | */ |
46 | 6 | #define X86_CPU_FEATURE_ZMM (1 << 5) |
47 | 6 | #define X86_CPU_FEATURE_AVX512BW (1 << 6) |
48 | 0 | #define X86_CPU_FEATURE_AVX512VL (1 << 7) |
49 | 0 | #define X86_CPU_FEATURE_VPCLMULQDQ (1 << 8) |
50 | 0 | #define X86_CPU_FEATURE_AVX512VNNI (1 << 9) |
51 | 6 | #define X86_CPU_FEATURE_AVXVNNI (1 << 10) |
52 | | |
53 | | #if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) |
54 | | /* Runtime x86 CPU feature detection is supported. */ |
55 | 6 | # define X86_CPU_FEATURES_KNOWN (1U << 31) |
56 | | extern volatile u32 libdeflate_x86_cpu_features; |
57 | | |
58 | | void libdeflate_init_x86_cpu_features(void); |
59 | | |
60 | | static inline u32 get_x86_cpu_features(void) |
61 | 12 | { |
62 | 12 | if (libdeflate_x86_cpu_features == 0) |
63 | 6 | libdeflate_init_x86_cpu_features(); |
64 | 12 | return libdeflate_x86_cpu_features; |
65 | 12 | } Unexecuted instantiation: deflate_compress.c:get_x86_cpu_features deflate_decompress.c:get_x86_cpu_features Line | Count | Source | 61 | 6 | { | 62 | 6 | if (libdeflate_x86_cpu_features == 0) | 63 | 6 | libdeflate_init_x86_cpu_features(); | 64 | 6 | return libdeflate_x86_cpu_features; | 65 | 6 | } |
Unexecuted instantiation: cpu_features.c:get_x86_cpu_features adler32.c:get_x86_cpu_features Line | Count | Source | 61 | 6 | { | 62 | 6 | if (libdeflate_x86_cpu_features == 0) | 63 | 0 | libdeflate_init_x86_cpu_features(); | 64 | 6 | return libdeflate_x86_cpu_features; | 65 | 6 | } |
|
66 | | /* |
67 | | * x86 intrinsics are also supported. Include the headers needed to use them. |
68 | | * Normally just immintrin.h suffices. With clang in MSVC compatibility mode, |
69 | | * immintrin.h incorrectly skips including sub-headers, so include those too. |
70 | | */ |
71 | | # include <immintrin.h> |
72 | | # if defined(_MSC_VER) && defined(__clang__) |
73 | | # include <tmmintrin.h> |
74 | | # include <smmintrin.h> |
75 | | # include <wmmintrin.h> |
76 | | # include <avxintrin.h> |
77 | | # include <avx2intrin.h> |
78 | | # include <avx512fintrin.h> |
79 | | # include <avx512bwintrin.h> |
80 | | # include <avx512vlintrin.h> |
81 | | # if __has_include(<avx512vlbwintrin.h>) |
82 | | # include <avx512vlbwintrin.h> |
83 | | # endif |
84 | | # if __has_include(<vpclmulqdqintrin.h>) |
85 | | # include <vpclmulqdqintrin.h> |
86 | | # endif |
87 | | # if __has_include(<avx512vnniintrin.h>) |
88 | | # include <avx512vnniintrin.h> |
89 | | # endif |
90 | | # if __has_include(<avx512vlvnniintrin.h>) |
91 | | # include <avx512vlvnniintrin.h> |
92 | | # endif |
93 | | # if __has_include(<avxvnniintrin.h>) |
94 | | # include <avxvnniintrin.h> |
95 | | # endif |
96 | | # endif |
97 | | #else |
98 | | static inline u32 get_x86_cpu_features(void) { return 0; } |
99 | | #endif |
100 | | |
101 | | #if defined(__SSE2__) || \ |
102 | | (defined(_MSC_VER) && \ |
103 | | (defined(ARCH_X86_64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2))) |
104 | 0 | # define HAVE_SSE2(features) 1 |
105 | | # define HAVE_SSE2_NATIVE 1 |
106 | | #else |
107 | | # define HAVE_SSE2(features) ((features) & X86_CPU_FEATURE_SSE2) |
108 | | # define HAVE_SSE2_NATIVE 0 |
109 | | #endif |
110 | | |
111 | | #if (defined(__PCLMUL__) && defined(__SSE4_1__)) || \ |
112 | | (defined(_MSC_VER) && defined(__AVX2__)) |
113 | | # define HAVE_PCLMULQDQ(features) 1 |
114 | | #else |
115 | | # define HAVE_PCLMULQDQ(features) ((features) & X86_CPU_FEATURE_PCLMULQDQ) |
116 | | #endif |
117 | | |
118 | | #ifdef __AVX__ |
119 | | # define HAVE_AVX(features) 1 |
120 | | #else |
121 | | # define HAVE_AVX(features) ((features) & X86_CPU_FEATURE_AVX) |
122 | | #endif |
123 | | |
124 | | #ifdef __AVX2__ |
125 | | # define HAVE_AVX2(features) 1 |
126 | | #else |
127 | 18 | # define HAVE_AVX2(features) ((features) & X86_CPU_FEATURE_AVX2) |
128 | | #endif |
129 | | |
130 | | #if defined(__BMI2__) || (defined(_MSC_VER) && defined(__AVX2__)) |
131 | | # define HAVE_BMI2(features) 1 |
132 | | # define HAVE_BMI2_NATIVE 1 |
133 | | #else |
134 | 6 | # define HAVE_BMI2(features) ((features) & X86_CPU_FEATURE_BMI2) |
135 | | # define HAVE_BMI2_NATIVE 0 |
136 | | #endif |
137 | | |
138 | | #ifdef __AVX512BW__ |
139 | | # define HAVE_AVX512BW(features) 1 |
140 | | #else |
141 | 18 | # define HAVE_AVX512BW(features) ((features) & X86_CPU_FEATURE_AVX512BW) |
142 | | #endif |
143 | | |
144 | | #ifdef __AVX512VL__ |
145 | | # define HAVE_AVX512VL(features) 1 |
146 | | #else |
147 | 6 | # define HAVE_AVX512VL(features) ((features) & X86_CPU_FEATURE_AVX512VL) |
148 | | #endif |
149 | | |
150 | | #ifdef __VPCLMULQDQ__ |
151 | | # define HAVE_VPCLMULQDQ(features) 1 |
152 | | #else |
153 | | # define HAVE_VPCLMULQDQ(features) ((features) & X86_CPU_FEATURE_VPCLMULQDQ) |
154 | | #endif |
155 | | |
156 | | #ifdef __AVX512VNNI__ |
157 | | # define HAVE_AVX512VNNI(features) 1 |
158 | | #else |
159 | 0 | # define HAVE_AVX512VNNI(features) ((features) & X86_CPU_FEATURE_AVX512VNNI) |
160 | | #endif |
161 | | |
162 | | #ifdef __AVXVNNI__ |
163 | | # define HAVE_AVXVNNI(features) 1 |
164 | | #else |
165 | 6 | # define HAVE_AVXVNNI(features) ((features) & X86_CPU_FEATURE_AVXVNNI) |
166 | | #endif |
167 | | |
168 | | #endif /* ARCH_X86_32 || ARCH_X86_64 */ |
169 | | |
170 | | #endif /* LIB_X86_CPU_FEATURES_H */ |