Go to the documentation of this file.
16 #ifndef HIGHWAY_HWY_DETECT_TARGETS_H_
17 #define HIGHWAY_HWY_DETECT_TARGETS_H_
70 #define HWY_HIGHEST_TARGET_BIT_X86 9
72 #define HWY_SVE2 0x400
75 #define HWY_NEON 0x2000
77 #define HWY_HIGHEST_TARGET_BIT_ARM 13
80 #define HWY_PPC8 0x10000
83 #define HWY_HIGHEST_TARGET_BIT_PPC 18
85 #define HWY_WASM2 0x80000
86 #define HWY_WASM 0x100000
88 #define HWY_HIGHEST_TARGET_BIT_WASM 20
92 #define HWY_RVV 0x1000000
94 #define HWY_HIGHEST_TARGET_BIT_RVV 24
98 #define HWY_SCALAR 0x20000000
100 #define HWY_HIGHEST_TARGET_BIT_SCALAR 29
109 #ifndef HWY_DISABLED_TARGETS
110 #define HWY_DISABLED_TARGETS 0
115 #ifndef HWY_BROKEN_TARGETS
119 #if HWY_ARCH_X86 && (HWY_COMPILER_CLANG != 0 && HWY_COMPILER_CLANG < 700)
120 #define HWY_BROKEN_TARGETS (HWY_SSE4 | HWY_AVX2 | HWY_AVX3 | HWY_AVX3_DL)
123 #if !defined(HWY_COMPILE_ONLY_SCALAR)
124 #pragma message("x86 Clang <= 6: define HWY_COMPILE_ONLY_SCALAR or upgrade.")
128 #elif HWY_ARCH_X86_32
129 #define HWY_BROKEN_TARGETS (HWY_AVX2 | HWY_AVX3 | HWY_AVX3_DL)
132 #elif HWY_COMPILER_MSVC != 0
133 #define HWY_BROKEN_TARGETS (HWY_AVX3 | HWY_AVX3_DL)
136 #elif HWY_ARCH_ARM_V7 && \
137 (defined(__ARM_BIG_ENDIAN) || \
138 (defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN))
139 #define HWY_BROKEN_TARGETS (HWY_NEON)
142 #elif (HWY_COMPILER_CLANG && HWY_COMPILER_CLANG < 1100) ||\
143 (!HWY_COMPILER_CLANG && HWY_COMPILER_GCC && HWY_COMPILER_GCC < 1000)
144 #define HWY_BROKEN_TARGETS (HWY_SVE | HWY_SVE2)
147 #define HWY_BROKEN_TARGETS 0
153 #define HWY_ENABLED(targets) \
154 ((targets) & ~((HWY_DISABLED_TARGETS) | (HWY_BROKEN_TARGETS)))
163 #ifndef HWY_BASELINE_TARGETS
168 #if HWY_ARCH_WASM && defined(__wasm_simd128__)
169 #if defined(HWY_WANT_WASM2)
170 #define HWY_BASELINE_WASM HWY_WASM2
172 #define HWY_BASELINE_WASM HWY_WASM
175 #define HWY_BASELINE_WASM 0
179 #if HWY_ARCH_PPC && defined(__VSX__) && 0
180 #define HWY_BASELINE_PPC8 HWY_PPC8
182 #define HWY_BASELINE_PPC8 0
186 #if HWY_ARCH_ARM && defined(__ARM_FEATURE_SVE2)
187 #define HWY_BASELINE_SVE2 HWY_SVE2
189 #define HWY_BASELINE_SVE2 0
192 #if HWY_ARCH_ARM && defined(__ARM_FEATURE_SVE)
193 #define HWY_BASELINE_SVE HWY_SVE
195 #define HWY_BASELINE_SVE 0
199 #if HWY_ARCH_ARM && (defined(__ARM_NEON__) || defined(__ARM_NEON))
200 #define HWY_BASELINE_NEON HWY_NEON
202 #define HWY_BASELINE_NEON 0
206 #if HWY_COMPILER_MSVC && !HWY_COMPILER_CLANG
211 #define HWY_CHECK_SSSE3 1
212 #define HWY_CHECK_SSE4 1
214 #define HWY_CHECK_SSSE3 0
215 #define HWY_CHECK_SSE4 0
220 #define HWY_CHECK_PCLMUL_AES 1
221 #define HWY_CHECK_BMI2_FMA 1
222 #define HWY_CHECK_F16C 1
226 #if defined(__SSSE3__)
227 #define HWY_CHECK_SSSE3 1
229 #define HWY_CHECK_SSSE3 0
232 #if defined(__SSE4_1__) && defined(__SSE4_2__)
233 #define HWY_CHECK_SSE4 1
235 #define HWY_CHECK_SSE4 0
239 #if defined(HWY_DISABLE_PCLMUL_AES) || (defined(__PCLMUL__) && defined(__AES__))
240 #define HWY_CHECK_PCLMUL_AES 1
242 #define HWY_CHECK_PCLMUL_AES 0
245 #if defined(HWY_DISABLE_BMI2_FMA) || (defined(__BMI2__) && defined(__FMA__))
246 #define HWY_CHECK_BMI2_FMA 1
248 #define HWY_CHECK_BMI2_FMA 0
251 #if defined(HWY_DISABLE_F16C) || defined(__F16C__)
252 #define HWY_CHECK_F16C 1
254 #define HWY_CHECK_F16C 0
259 #if HWY_ARCH_X86 && HWY_CHECK_SSSE3
260 #define HWY_BASELINE_SSSE3 HWY_SSSE3
262 #define HWY_BASELINE_SSSE3 0
265 #if HWY_ARCH_X86 && HWY_CHECK_SSE4 && HWY_CHECK_PCLMUL_AES
266 #define HWY_BASELINE_SSE4 HWY_SSE4
268 #define HWY_BASELINE_SSE4 0
271 #if HWY_BASELINE_SSE4 != 0 && HWY_CHECK_BMI2_FMA && HWY_CHECK_F16C && \
273 #define HWY_BASELINE_AVX2 HWY_AVX2
275 #define HWY_BASELINE_AVX2 0
279 #if HWY_BASELINE_AVX2 != 0 && defined(__AVX512F__) && defined(__AVX512BW__) && \
280 defined(__AVX512DQ__) && defined(__AVX512VL__)
281 #define HWY_BASELINE_AVX3 HWY_AVX3
283 #define HWY_BASELINE_AVX3 0
287 #if HWY_BASELINE_AVX3 != 0 && defined(__AVXVNNI__) && defined(__VAES__) && \
288 defined(__VPCLMULQDQ__)
289 #define HWY_BASELINE_AVX3_DL HWY_AVX3_DL
291 #define HWY_BASELINE_AVX3_DL 0
294 #if HWY_ARCH_RVV && defined(__riscv_vector)
295 #define HWY_BASELINE_RVV HWY_RVV
297 #define HWY_BASELINE_RVV 0
300 #define HWY_BASELINE_TARGETS \
301 (HWY_SCALAR | HWY_BASELINE_WASM | HWY_BASELINE_PPC8 | HWY_BASELINE_SVE2 | \
302 HWY_BASELINE_SVE | HWY_BASELINE_NEON | HWY_BASELINE_SSSE3 | \
303 HWY_BASELINE_SSE4 | HWY_BASELINE_AVX2 | HWY_BASELINE_AVX3 | \
304 HWY_BASELINE_AVX3_DL | HWY_BASELINE_RVV)
309 #define HWY_BASELINE_AVX3_DL (HWY_BASELINE_TARGETS & HWY_AVX3_DL)
315 #define HWY_ENABLED_BASELINE HWY_ENABLED(HWY_BASELINE_TARGETS)
316 #if HWY_ENABLED_BASELINE == 0
317 #error "At least one baseline target must be defined and enabled"
322 #define HWY_STATIC_TARGET (HWY_ENABLED_BASELINE & -HWY_ENABLED_BASELINE)
328 #define HWY_TARGET HWY_STATIC_TARGET
333 #if (defined(HWY_COMPILE_ONLY_SCALAR) + defined(HWY_COMPILE_ONLY_STATIC) + \
334 defined(HWY_COMPILE_ALL_ATTAINABLE)) > 1
335 #error "Invalid config: can only define a single policy for targets"
341 #if defined(HWY_WANT_AVX3_DL)
342 #define HWY_CHECK_AVX3_DL HWY_AVX3_DL
344 #define HWY_CHECK_AVX3_DL HWY_BASELINE_AVX3_DL
350 #define HWY_ATTAINABLE_TARGETS \
351 HWY_ENABLED(HWY_SCALAR | HWY_SSSE3 | HWY_SSE4 | HWY_AVX2 | HWY_AVX3 | \
354 #define HWY_ATTAINABLE_TARGETS HWY_ENABLED_BASELINE
359 #if defined(HWY_COMPILE_ONLY_SCALAR)
360 #undef HWY_STATIC_TARGET
361 #define HWY_STATIC_TARGET HWY_SCALAR
362 #define HWY_TARGETS HWY_SCALAR
365 #elif defined(HWY_COMPILE_ONLY_STATIC)
366 #define HWY_TARGETS HWY_STATIC_TARGET
369 #elif defined(HWY_COMPILE_ALL_ATTAINABLE) || defined(HWY_IS_TEST)
370 #define HWY_TARGETS HWY_ATTAINABLE_TARGETS
375 #define HWY_TARGETS (HWY_ATTAINABLE_TARGETS & (2 * HWY_STATIC_TARGET - 1))
382 #if (HWY_TARGETS & HWY_STATIC_TARGET) == 0
383 #error "Logic error: best baseline should be included in dynamic targets"