Go to the documentation of this file.
15 #ifndef HIGHWAY_HWY_DETECT_TARGETS_H_
16 #define HIGHWAY_HWY_DETECT_TARGETS_H_
69 #define HWY_HIGHEST_TARGET_BIT_X86 9
71 #define HWY_SVE2 0x400
74 #define HWY_NEON 0x2000
76 #define HWY_HIGHEST_TARGET_BIT_ARM 13
79 #define HWY_PPC8 0x10000
82 #define HWY_HIGHEST_TARGET_BIT_PPC 18
85 #define HWY_WASM 0x100000
87 #define HWY_HIGHEST_TARGET_BIT_WASM 20
91 #define HWY_RVV 0x1000000
93 #define HWY_HIGHEST_TARGET_BIT_RVV 24
97 #define HWY_SCALAR 0x20000000
99 #define HWY_HIGHEST_TARGET_BIT_SCALAR 29
108 #ifndef HWY_DISABLED_TARGETS
109 #define HWY_DISABLED_TARGETS 0
114 #ifndef HWY_BROKEN_TARGETS
118 #if HWY_ARCH_X86 && (HWY_COMPILER_CLANG != 0 && HWY_COMPILER_CLANG < 700)
119 #define HWY_BROKEN_TARGETS (HWY_SSE4 | HWY_AVX2 | HWY_AVX3 | HWY_AVX3_DL)
122 #if !defined(HWY_COMPILE_ONLY_SCALAR)
123 #pragma message("x86 Clang <= 6: define HWY_COMPILE_ONLY_SCALAR or upgrade.")
127 #elif HWY_ARCH_X86_32
128 #define HWY_BROKEN_TARGETS (HWY_AVX2 | HWY_AVX3 | HWY_AVX3_DL)
131 #elif HWY_COMPILER_MSVC != 0
132 #define HWY_BROKEN_TARGETS (HWY_AVX3 | HWY_AVX3_DL)
135 #elif HWY_ARCH_ARM_V7 && \
136 (defined(__ARM_BIG_ENDIAN) || \
137 (defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN))
138 #define HWY_BROKEN_TARGETS (HWY_NEON)
141 #elif (HWY_COMPILER_CLANG && HWY_COMPILER_CLANG < 1100) ||\
142 (!HWY_COMPILER_CLANG && HWY_COMPILER_GCC && HWY_COMPILER_GCC < 1000)
143 #define HWY_BROKEN_TARGETS (HWY_SVE | HWY_SVE2)
146 #define HWY_BROKEN_TARGETS 0
152 #define HWY_ENABLED(targets) \
153 ((targets) & ~((HWY_DISABLED_TARGETS) | (HWY_BROKEN_TARGETS)))
162 #ifndef HWY_BASELINE_TARGETS
164 #if defined(HWY_EMULATE_SVE)
165 #define HWY_BASELINE_TARGETS HWY_SVE
166 #define HWY_BASELINE_AVX3_DL 0
172 #if HWY_ARCH_WASM && defined(__wasm_simd128__)
173 #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)
311 #define HWY_BASELINE_AVX3_DL (HWY_BASELINE_TARGETS & HWY_AVX3_DL)
317 #define HWY_ENABLED_BASELINE HWY_ENABLED(HWY_BASELINE_TARGETS)
318 #if HWY_ENABLED_BASELINE == 0
319 #error "At least one baseline target must be defined and enabled"
324 #define HWY_STATIC_TARGET (HWY_ENABLED_BASELINE & -HWY_ENABLED_BASELINE)
330 #define HWY_TARGET HWY_STATIC_TARGET
335 #if (defined(HWY_COMPILE_ONLY_SCALAR) + defined(HWY_COMPILE_ONLY_STATIC) + \
336 defined(HWY_COMPILE_ALL_ATTAINABLE)) > 1
337 #error "Invalid config: can only define a single policy for targets"
343 #if defined(HWY_WANT_AVX3_DL)
344 #define HWY_CHECK_AVX3_DL HWY_AVX3_DL
346 #define HWY_CHECK_AVX3_DL HWY_BASELINE_AVX3_DL
352 #define HWY_ATTAINABLE_TARGETS \
353 HWY_ENABLED(HWY_SCALAR | HWY_SSSE3 | HWY_SSE4 | HWY_AVX2 | HWY_AVX3 | \
356 #define HWY_ATTAINABLE_TARGETS HWY_ENABLED_BASELINE
361 #if defined(HWY_COMPILE_ONLY_SCALAR)
362 #undef HWY_STATIC_TARGET
363 #define HWY_STATIC_TARGET HWY_SCALAR
364 #define HWY_TARGETS HWY_SCALAR
367 #elif defined(HWY_COMPILE_ONLY_STATIC)
368 #define HWY_TARGETS HWY_STATIC_TARGET
371 #elif defined(HWY_COMPILE_ALL_ATTAINABLE) || defined(HWY_IS_TEST)
372 #define HWY_TARGETS HWY_ATTAINABLE_TARGETS
377 #define HWY_TARGETS (HWY_ATTAINABLE_TARGETS & (2 * HWY_STATIC_TARGET - 1))
384 #if (HWY_TARGETS & HWY_STATIC_TARGET) == 0
385 #error "Logic error: best baseline should be included in dynamic targets"