Go to the documentation of this file.
16 #ifndef HIGHWAY_HWY_DETECT_TARGETS_H_
17 #define HIGHWAY_HWY_DETECT_TARGETS_H_
74 #define HWY_HIGHEST_TARGET_BIT_X86 9
77 #define HWY_SVE2_128 0x1000
78 #define HWY_SVE_256 0x2000
79 #define HWY_SVE2 0x4000
80 #define HWY_SVE 0x8000
82 #define HWY_NEON 0x20000
84 #define HWY_HIGHEST_TARGET_BIT_ARM 17
87 #define HWY_PPC8 0x80000
90 #define HWY_HIGHEST_TARGET_BIT_PPC 20
93 #define HWY_WASM_EMU256 0x800000
94 #define HWY_WASM 0x1000000
96 #define HWY_HIGHEST_TARGET_BIT_WASM 24
99 #define HWY_RVV 0x10000000
101 #define HWY_HIGHEST_TARGET_BIT_RVV 28
103 #define HWY_EMU128 0x20000000
104 #define HWY_SCALAR 0x40000000
106 #define HWY_HIGHEST_TARGET_BIT_SCALAR 30
115 #ifndef HWY_DISABLED_TARGETS
116 #define HWY_DISABLED_TARGETS 0
121 #ifndef HWY_BROKEN_TARGETS
125 #if HWY_ARCH_X86 && (HWY_COMPILER_CLANG != 0 && HWY_COMPILER_CLANG < 700)
126 #define HWY_BROKEN_TARGETS (HWY_SSE4 | HWY_AVX2 | HWY_AVX3 | HWY_AVX3_DL)
129 #if !defined(HWY_COMPILE_ONLY_SCALAR)
130 #pragma message("x86 Clang <= 6: define HWY_COMPILE_ONLY_SCALAR or upgrade.")
134 #elif HWY_ARCH_X86_32
135 #define HWY_BROKEN_TARGETS (HWY_AVX2 | HWY_AVX3 | HWY_AVX3_DL)
138 #elif HWY_COMPILER_MSVC != 0
139 #define HWY_BROKEN_TARGETS (HWY_AVX3 | HWY_AVX3_DL)
142 #elif HWY_ARCH_ARM_V7 && \
143 (defined(__ARM_BIG_ENDIAN) || \
144 (defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN))
145 #define HWY_BROKEN_TARGETS (HWY_NEON)
148 #elif (HWY_COMPILER_CLANG && HWY_COMPILER_CLANG < 1100) ||\
149 (!HWY_COMPILER_CLANG && HWY_COMPILER_GCC && HWY_COMPILER_GCC < 1000)
150 #define HWY_BROKEN_TARGETS (HWY_SVE | HWY_SVE2 | HWY_SVE_256 | HWY_SVE2_128)
153 #define HWY_BROKEN_TARGETS 0
159 #define HWY_ENABLED(targets) \
160 ((targets) & ~((HWY_DISABLED_TARGETS) | (HWY_BROKEN_TARGETS)))
169 #if defined(HWY_COMPILE_ONLY_SCALAR)
170 #define HWY_BASELINE_SCALAR HWY_SCALAR
172 #define HWY_BASELINE_SCALAR HWY_EMU128
178 #if HWY_ARCH_WASM && defined(__wasm_simd128__)
179 #if defined(HWY_WANT_WASM2)
180 #define HWY_BASELINE_WASM HWY_WASM_EMU256
182 #define HWY_BASELINE_WASM HWY_WASM
185 #define HWY_BASELINE_WASM 0
189 #if HWY_ARCH_PPC && defined(__VSX__) && 0
190 #define HWY_BASELINE_PPC8 HWY_PPC8
192 #define HWY_BASELINE_PPC8 0
195 #if HWY_ARCH_ARM && defined(__ARM_FEATURE_SVE2)
196 #define HWY_BASELINE_SVE2 HWY_SVE2
198 #define HWY_BASELINE_SVE2 0
201 #if HWY_ARCH_ARM && defined(__ARM_FEATURE_SVE)
207 #define HWY_BASELINE_SVE HWY_SVE
209 #define HWY_BASELINE_SVE 0
213 #if HWY_ARCH_ARM && (defined(__ARM_NEON__) || defined(__ARM_NEON))
214 #define HWY_BASELINE_NEON HWY_NEON
216 #define HWY_BASELINE_NEON 0
220 #if HWY_COMPILER_MSVC && !HWY_COMPILER_CLANG
225 #define HWY_CHECK_SSSE3 1
226 #define HWY_CHECK_SSE4 1
228 #define HWY_CHECK_SSSE3 0
229 #define HWY_CHECK_SSE4 0
234 #define HWY_CHECK_PCLMUL_AES 1
235 #define HWY_CHECK_BMI2_FMA 1
236 #define HWY_CHECK_F16C 1
240 #if defined(__SSSE3__)
241 #define HWY_CHECK_SSSE3 1
243 #define HWY_CHECK_SSSE3 0
246 #if defined(__SSE4_1__) && defined(__SSE4_2__)
247 #define HWY_CHECK_SSE4 1
249 #define HWY_CHECK_SSE4 0
253 #if defined(HWY_DISABLE_PCLMUL_AES) || (defined(__PCLMUL__) && defined(__AES__))
254 #define HWY_CHECK_PCLMUL_AES 1
256 #define HWY_CHECK_PCLMUL_AES 0
259 #if defined(HWY_DISABLE_BMI2_FMA) || (defined(__BMI2__) && defined(__FMA__))
260 #define HWY_CHECK_BMI2_FMA 1
262 #define HWY_CHECK_BMI2_FMA 0
265 #if defined(HWY_DISABLE_F16C) || defined(__F16C__)
266 #define HWY_CHECK_F16C 1
268 #define HWY_CHECK_F16C 0
273 #if HWY_ARCH_X86 && (HWY_WANT_SSSE3 || HWY_CHECK_SSSE3)
274 #define HWY_BASELINE_SSSE3 HWY_SSSE3
276 #define HWY_BASELINE_SSSE3 0
279 #if HWY_ARCH_X86 && (HWY_WANT_SSE4 || (HWY_CHECK_SSE4 && HWY_CHECK_PCLMUL_AES))
280 #define HWY_BASELINE_SSE4 HWY_SSE4
282 #define HWY_BASELINE_SSE4 0
285 #if HWY_BASELINE_SSE4 != 0 && HWY_CHECK_BMI2_FMA && HWY_CHECK_F16C && \
287 #define HWY_BASELINE_AVX2 HWY_AVX2
289 #define HWY_BASELINE_AVX2 0
293 #if HWY_BASELINE_AVX2 != 0 && defined(__AVX512F__) && defined(__AVX512BW__) && \
294 defined(__AVX512DQ__) && defined(__AVX512VL__)
295 #define HWY_BASELINE_AVX3 HWY_AVX3
297 #define HWY_BASELINE_AVX3 0
301 #if HWY_BASELINE_AVX3 != 0 && defined(__AVXVNNI__) && defined(__VAES__) && \
302 defined(__VPCLMULQDQ__) && defined(__AVX512VBMI__) && \
303 defined(__AVX512VBMI2__) && defined(__AVX512VPOPCNTDQ__) && \
304 defined(__AVX512BITALG__)
305 #define HWY_BASELINE_AVX3_DL HWY_AVX3_DL
307 #define HWY_BASELINE_AVX3_DL 0
310 #if HWY_ARCH_RVV && defined(__riscv_vector)
311 #define HWY_BASELINE_RVV HWY_RVV
313 #define HWY_BASELINE_RVV 0
317 #ifndef HWY_BASELINE_TARGETS
318 #define HWY_BASELINE_TARGETS \
319 (HWY_BASELINE_SCALAR | HWY_BASELINE_WASM | HWY_BASELINE_PPC8 | \
320 HWY_BASELINE_SVE2 | HWY_BASELINE_SVE | HWY_BASELINE_NEON | \
321 HWY_BASELINE_SSSE3 | HWY_BASELINE_SSE4 | HWY_BASELINE_AVX2 | \
322 HWY_BASELINE_AVX3 | HWY_BASELINE_AVX3_DL | HWY_BASELINE_RVV)
328 #define HWY_ENABLED_BASELINE HWY_ENABLED(HWY_BASELINE_TARGETS)
329 #if HWY_ENABLED_BASELINE == 0
330 #error "At least one baseline target must be defined and enabled"
335 #define HWY_STATIC_TARGET (HWY_ENABLED_BASELINE & -HWY_ENABLED_BASELINE)
341 #define HWY_TARGET HWY_STATIC_TARGET
346 #if defined(HWY_COMPILE_ONLY_SCALAR) && defined(HWY_COMPILE_ONLY_STATIC)
347 #error "Defined both HWY_COMPILE_ONLY_{SCALAR|STATIC} - bug?"
354 #if defined(HWY_WANT_AVX3_DL) || (HWY_BASELINE & HWY_AVX3_DL)
355 #define HWY_ATTAINABLE_AVX3_DL HWY_AVX3_DL
357 #define HWY_ATTAINABLE_AVX3_DL 0
360 #if HWY_ARCH_ARM_A64 && (HWY_ENABLED_BASELINE & HWY_SVE)
361 #define HWY_ATTAINABLE_SVE_256 HWY_ENABLED(HWY_SVE_256)
363 #define HWY_ATTAINABLE_SVE_256 0
366 #if HWY_ARCH_ARM_A64 && (HWY_ENABLED_BASELINE & HWY_SVE2)
367 #define HWY_ATTAINABLE_SVE2_128 HWY_ENABLED(HWY_SVE2_128)
369 #define HWY_ATTAINABLE_SVE2_128 0
375 #define HWY_ATTAINABLE_TARGETS \
376 HWY_ENABLED(HWY_BASELINE_SCALAR | HWY_SSSE3 | HWY_SSE4 | HWY_AVX2 | \
377 HWY_AVX3 | HWY_ATTAINABLE_AVX3_DL)
379 #define HWY_ATTAINABLE_TARGETS \
380 (HWY_ENABLED_BASELINE | HWY_ATTAINABLE_SVE_256 | HWY_ATTAINABLE_SVE2_128)
385 #if defined(HWY_COMPILE_ONLY_SCALAR)
386 #undef HWY_STATIC_TARGET
387 #define HWY_STATIC_TARGET HWY_SCALAR
388 #define HWY_TARGETS HWY_SCALAR
391 #elif defined(HWY_COMPILE_ONLY_STATIC)
392 #define HWY_TARGETS HWY_STATIC_TARGET
395 #elif defined(HWY_COMPILE_ALL_ATTAINABLE) || defined(HWY_IS_TEST)
396 #define HWY_TARGETS HWY_ATTAINABLE_TARGETS
401 #define HWY_TARGETS (HWY_ATTAINABLE_TARGETS & (2 * HWY_STATIC_TARGET - 1))
408 #if (HWY_TARGETS & HWY_STATIC_TARGET) == 0
409 #error "Logic error: best baseline should be included in dynamic targets"