20#include <QtCore/private/qglobal_p.h>
21#include <QtCore/qsimd.h>
24QT_WARNING_DISABLE_CLANG(
"-Wundef")
25QT_WARNING_DISABLE_GCC(
"-Wundef")
26QT_WARNING_DISABLE_INTEL(103)
28#define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length)
29 for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4
- ((reinterpret_cast<quintptr>(ptr) >> 2
) & 0x3
)) & 0x3
))); ++i)
31#define ALIGNMENT_PROLOGUE_32BYTES(ptr, i, length)
32 for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((8
- ((reinterpret_cast<quintptr>(ptr) >> 2
) & 0x7
)) & 0x7
))); ++i)
34#define SIMD_EPILOGUE(i, length, max)
35 for (int _i = 0
; _i < max && i < length; ++i, ++_i)
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
97#if defined(__MINGW64_VERSION_MAJOR) || defined(Q_CC_MSVC)
101#define QT_COMPILER_SUPPORTS(x) (defined QT_COMPILER_SUPPORTS_##x && QT_COMPILER_SUPPORTS_##x)
103#if defined(Q_PROCESSOR_ARM_64)
104# define QT_COMPILER_SUPPORTS_HERE(x) ((defined __ARM_FEATURE_##x && __ARM_FEATURE_##x) || (defined __##x##__ && __##x##__) || QT_COMPILER_SUPPORTS(x))
105# if defined(Q_CC_GNU) || defined(Q_CC_CLANG)
107# define QT_FUNCTION_TARGET(x) __attribute__((__target__(QT_FUNCTION_TARGET_STRING_ ## x)))
109# define QT_FUNCTION_TARGET(x)
111#elif defined(Q_PROCESSOR_ARM_32)
113# define QT_COMPILER_SUPPORTS_HERE(x) ((defined __ARM_FEATURE_##x && __ARM_FEATURE_##x) || (defined __##x##__ && __##x##__))
114# define QT_FUNCTION_TARGET(x)
115#elif defined(Q_PROCESSOR_MIPS)
116# define QT_COMPILER_SUPPORTS_HERE(x) (defined __##x##__ && __##x##__)
117# define QT_FUNCTION_TARGET(x)
118# if !defined(__MIPS_DSP__) && defined(__mips_dsp) && defined(Q_PROCESSOR_MIPS_32)
121# if !defined(__MIPS_DSPR2__) && defined(__mips_dspr2) && defined(Q_PROCESSOR_MIPS_32)
122# define __MIPS_DSPR2__
124#elif defined(Q_PROCESSOR_LOONGARCH)
125# define QT_COMPILER_SUPPORTS_HERE(x) QT_COMPILER_SUPPORTS(x)
126# define QT_FUNCTION_TARGET(x)
127#elif defined(Q_PROCESSOR_X86)
128# if defined(Q_CC_CLANG) && defined(Q_CC_MSVC) && (Q_CC_CLANG < 1900
)
129# define QT_COMPILER_SUPPORTS_HERE(x) (defined __##x##__ && __##x##__)
131# define QT_COMPILER_SUPPORTS_HERE(x) ((defined __##x##__ && __##x##__) || QT_COMPILER_SUPPORTS(x))
133# if defined(Q_CC_GNU) || defined(Q_CC_CLANG)
135# define QT_FUNCTION_TARGET(x) __attribute__((__target__(QT_FUNCTION_TARGET_STRING_ ## x)))
137# define QT_FUNCTION_TARGET(x)
140# define QT_COMPILER_SUPPORTS_HERE(x) (defined __##x##__ && __##x##__)
141# define QT_FUNCTION_TARGET(x)
144#if defined(__SSE2__
) && !defined(QT_COMPILER_SUPPORTS_SSE2) && !defined(QT_BOOTSTRAPPED)
170# undef __AVX512IFMA__
171# undef __AVX512VBMI__
173# undef __AVX512VBMI2__
174# undef __AVX512BITALG__
175# undef __AVX512VNNI__
176# undef __AVX512VPOPCNTDQ__
181#ifdef Q_PROCESSOR_X86
184# if defined(QT_COMPILER_SUPPORTS_RDSEED) && defined(Q_OS_QNX)
186# undef QT_COMPILER_SUPPORTS_RDSEED
188# if defined(Q_CC_MSVC) && (defined(_M_X64) || _M_IX86_FP >= 2
)
193# if defined(Q_OS_WIN) && defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
198 ".macro vmovapd args:vararg\n"
201 ".macro vmovaps args:vararg\n"
204 ".macro vmovdqa args:vararg\n"
207 ".macro vmovdqa32 args:vararg\n"
208 " vmovdqu32 \\args\n"
210 ".macro vmovdqa64 args:vararg\n"
211 " vmovdqu64 \\args\n"
216# if defined(Q_CC_GNU) && !defined(Q_OS_WASM)
218# include <x86intrin.h>
221# include <immintrin.h>
224# include <QtCore/private/qsimd_x86_p.h>
235# if defined(__AVX2__)
238# define ARCH_HASWELL_MACROS
239 (__AVX2__ + __BMI__ + __BMI2__ + __F16C__ + __FMA__ + __LZCNT__ + __POPCNT__)
240# if ARCH_HASWELL_MACROS != 7
241# error "Please enable all x86-64-v3 extensions; you probably want to use -march=haswell or -march=x86-64-v3 instead of -mavx2"
243static_assert(ARCH_HASWELL_MACROS,
"Undeclared identifiers indicate which features are missing.");
244# define __haswell__ 1
245# undef ARCH_HASWELL_MACROS
255# define ARCH_SKX_MACROS (__AVX512F__ + __AVX512BW__ + __AVX512CD__ + __AVX512DQ__ + __AVX512VL__)
256# if ARCH_SKX_MACROS != 0
257# if ARCH_SKX_MACROS != 5
258# error "Please enable all x86-64-v4 extensions; you probably want to use -march=skylake-avx512 or -march=x86-64-v4 instead of -mavx512f"
260static_assert(ARCH_SKX_MACROS,
"Undeclared identifiers indicate which features are missing.");
261# define __skylake_avx512__ 1
263# undef ARCH_SKX_MACROS
268#if defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(_M_ARM64)
269#if defined(Q_CC_CLANG)
270#define QT_FUNCTION_TARGET_STRING_NEON "neon"
272#define QT_FUNCTION_TARGET_STRING_NEON "+neon"
279#ifndef Q_PROCESSOR_ARM_64
280static inline uint16_t vaddvq_u16(uint16x8_t v8)
282 const uint64x2_t v2 = vpaddlq_u32(vpaddlq_u16(v8));
283 const uint64x1_t v1 = vadd_u64(vget_low_u64(v2), vget_high_u64(v2));
284 return vget_lane_u16(vreinterpret_u16_u64(v1), 0);
287static inline uint8_t vaddv_u8(uint8x8_t v8)
289 const uint64x1_t v1 = vpaddl_u32(vpaddl_u16(vpaddl_u8(v8)));
290 return vget_lane_u8(vreinterpret_u8_u64(v1), 0);
295static inline uint16x8_t qvsetq_n_u16(uint16_t v1, uint16_t v2, uint16_t v3, uint16_t v4,
296 uint16_t v5, uint16_t v6, uint16_t v7, uint16_t v8)
298#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
299 using u64 = uint64_t;
300 const uint16x8_t vmask = {
301 v1 | (v2 << 16) | (u64(v3) << 32) | (u64(v4) << 48),
302 v5 | (v6 << 16) | (u64(v7) << 32) | (u64(v8) << 48)
305 const uint16x8_t vmask = { v1, v2, v3, v4, v5, v6, v7, v8 };
309static inline uint8x8_t qvset_n_u8(uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5,
310 uint8_t v6, uint8_t v7, uint8_t v8)
312#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
313 using u64 = uint64_t;
314 const uint8x8_t vmask = {
315 v1 | (v2 << 8) | (v3 << 16) | (v4 << 24) |
316 (u64(v5) << 32) | (u64(v6) << 40) | (u64(v7) << 48) | (u64(v8) << 56)
319 const uint8x8_t vmask = { v1, v2, v3, v4, v5, v6, v7, v8 };
323static inline uint8x16_t qvsetq_n_u8(uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5,
324 uint8_t v6, uint8_t v7, uint8_t v8, uint8_t v9, uint8_t v10,
325 uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14,
326 uint8_t v15, uint8_t v16)
328#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
329 using u64 = uint64_t;
330 const uint8x16_t vmask = {
331 v1 | (v2 << 8) | (v3 << 16) | (v4 << 24) |
332 (u64(v5) << 32) | (u64(v6) << 40) | (u64(v7) << 48) | (u64(v8) << 56),
333 v9 | (v10 << 8) | (v11 << 16) | (v12 << 24) |
334 (u64(v13) << 32) | (u64(v14) << 40) | (u64(v15) << 48) | (u64(v16) << 56)
337 const uint8x16_t vmask = { v1, v2, v3, v4, v5, v6, v7, v8,
338 v9, v10, v11, v12, v13, v14, v15, v16};
342static inline uint32x4_t qvsetq_n_u32(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
344#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
345 return uint32x4_t{ (uint64_t(b) << 32) | a, (uint64_t(d) << 32) | c };
347 return uint32x4_t{ a, b, c, d };
352#if defined(_M_ARM64) && __ARM_ARCH >= 800
353#define __ARM_FEATURE_CRYPTO 1
354#define __ARM_FEATURE_CRC32 1
357#if defined(Q_PROCESSOR_ARM_64)
358#if defined(Q_CC_CLANG)
359#define QT_FUNCTION_TARGET_STRING_AES "aes"
360#define QT_FUNCTION_TARGET_STRING_CRC32 "crc"
361#define QT_FUNCTION_TARGET_STRING_SVE "sve"
362#elif defined(Q_CC_GNU)
363#define QT_FUNCTION_TARGET_STRING_AES "+crypto"
364#define QT_FUNCTION_TARGET_STRING_CRC32 "+crc"
365#define QT_FUNCTION_TARGET_STRING_SVE "+sve"
366#elif defined(Q_CC_MSVC)
367#define QT_FUNCTION_TARGET_STRING_AES
368#define QT_FUNCTION_TARGET_STRING_CRC32
369#define QT_FUNCTION_TARGET_STRING_SVE
371#elif defined(Q_PROCESSOR_ARM_32)
372#if defined(Q_CC_CLANG)
373#define QT_FUNCTION_TARGET_STRING_AES "armv8-a,crypto"
374#define QT_FUNCTION_TARGET_STRING_CRC32 "armv8-a,crc"
375#elif defined(Q_CC_GNU)
376#define QT_FUNCTION_TARGET_STRING_AES "arch=armv8-a+crypto"
377#define QT_FUNCTION_TARGET_STRING_CRC32 "arch=armv8-a+crc"
381#ifndef Q_PROCESSOR_X86
383#if defined(Q_PROCESSOR_ARM)
385 CpuFeatureARM_NEON = CpuFeatureNEON,
388 CpuFeatureARM_CRYPTO = CpuFeatureAES,
390#elif defined(Q_PROCESSOR_MIPS)
393#elif defined(Q_PROCESSOR_LOONGARCH)
400#if defined __ARM_NEON__
403#if !(defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM_64))
409#if defined __ARM_FEATURE_CRC32
412#if defined (__ARM_FEATURE_CRYPTO) || defined(__ARM_FEATURE_AES)
416#if defined(__ARM_FEATURE_SVE) && defined(Q_PROCESSOR_ARM_64)
419#if defined __mips_dsp
422#if defined __mips_dspr2
425#if defined __loongarch_sx
428#if defined __loongarch_asx
436# define Q_ATOMIC(T) std::atomic<T>
438using std::atomic_load_explicit;
439static constexpr auto memory_order_relaxed =
std::memory_order_relaxed;
442# include <stdatomic.h>
443# define Q_ATOMIC(T) _Atomic(T)
446#ifdef Q_PROCESSOR_X86
447typedef uint64_t QCpuFeatureType;
448static const QCpuFeatureType qCompilerCpuFeatures = _compilerCpuFeatures;
449static const QCpuFeatureType CpuFeatureArchHaswell = cpu_haswell;
450static const QCpuFeatureType CpuFeatureArchSkylakeAvx512 = cpu_skylake_avx512;
454extern Q_CORE_EXPORT
Q_ATOMIC(QCpuFeatureType) QT_MANGLE_NAMESPACE(qt_cpu_features)[1];
455Q_CORE_EXPORT uint64_t QT_MANGLE_NAMESPACE(qDetectCpuFeatures)();
459#ifdef QT_BOOTSTRAPPED
460 return qCompilerCpuFeatures;
462 quint64 features = atomic_load_explicit(QT_MANGLE_NAMESPACE(qt_cpu_features), memory_order_relaxed);
463 if (!QT_SUPPORTS_INIT_PRIORITY) {
464 if (Q_UNLIKELY(features == 0))
465 features = QT_MANGLE_NAMESPACE(qDetectCpuFeatures)();
471#define qCpuHasFeature(feature) (((qCompilerCpuFeatures & CpuFeature ## feature) == CpuFeature ## feature)
472 || ((qCpuFeatures() & CpuFeature ## feature) == CpuFeature ## feature))
#define QT_FUNCTION_TARGET_BASELINE
QT_FUNCTION_TARGET_BASELINE uint64_t QT_MANGLE_NAMESPACE qDetectCpuFeatures()
static constexpr auto SimdInitialized
static const int features_indices[]
static uint detectProcessorFeatures()
static const char features_string[]
static const quint64 minFeature
static const uint64_t qCompilerCpuFeatures
static uint64_t qCpuFeatures()