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
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.")
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"