19#include <QtCore/private/qglobal_p.h>
20#include <QtCore/qsimd.h>
23QT_WARNING_DISABLE_CLANG(
"-Wundef")
24QT_WARNING_DISABLE_GCC(
"-Wundef")
25QT_WARNING_DISABLE_INTEL(103)
27#define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length)
28 for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4
- ((reinterpret_cast<quintptr>(ptr) >> 2
) & 0x3
)) & 0x3
))); ++i)
30#define ALIGNMENT_PROLOGUE_32BYTES(ptr, i, length)
31 for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((8
- ((reinterpret_cast<quintptr>(ptr) >> 2
) & 0x7
)) & 0x7
))); ++i)
33#define SIMD_EPILOGUE(i, length, max)
34 for (int _i = 0
; _i < max && i < length; ++i, ++_i)
37
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
96#if defined(__MINGW64_VERSION_MAJOR) || defined(Q_CC_MSVC)
100#define QT_COMPILER_SUPPORTS(x) (defined QT_COMPILER_SUPPORTS_##x && QT_COMPILER_SUPPORTS_##x)
102#if defined(Q_PROCESSOR_ARM_64)
103# define QT_COMPILER_SUPPORTS_HERE(x) ((defined __ARM_FEATURE_##x && __ARM_FEATURE_##x) || (defined __##x##__ && __##x##__) || QT_COMPILER_SUPPORTS(x))
104# if defined(Q_CC_GNU) || defined(Q_CC_CLANG)
106# define QT_FUNCTION_TARGET(x) __attribute__((__target__(QT_FUNCTION_TARGET_STRING_ ## x)))
108# define QT_FUNCTION_TARGET(x)
110#elif defined(Q_PROCESSOR_ARM_32)
112# define QT_COMPILER_SUPPORTS_HERE(x) ((defined __ARM_FEATURE_##x && __ARM_FEATURE_##x) || (defined __##x##__ && __##x##__))
113# define QT_FUNCTION_TARGET(x)
114#elif defined(Q_PROCESSOR_MIPS)
115# define QT_COMPILER_SUPPORTS_HERE(x) (defined __##x##__ && __##x##__)
116# define QT_FUNCTION_TARGET(x)
117# if !defined(__MIPS_DSP__) && defined(__mips_dsp) && defined(Q_PROCESSOR_MIPS_32)
120# if !defined(__MIPS_DSPR2__) && defined(__mips_dspr2) && defined(Q_PROCESSOR_MIPS_32)
121# define __MIPS_DSPR2__
123#elif defined(Q_PROCESSOR_LOONGARCH)
124# define QT_COMPILER_SUPPORTS_HERE(x) QT_COMPILER_SUPPORTS(x)
125# define QT_FUNCTION_TARGET(x)
126#elif defined(Q_PROCESSOR_X86)
127# if defined(Q_CC_CLANG) && defined(Q_CC_MSVC) && (Q_CC_CLANG < 1900
)
128# define QT_COMPILER_SUPPORTS_HERE(x) (defined __##x##__ && __##x##__)
130# define QT_COMPILER_SUPPORTS_HERE(x) ((defined __##x##__ && __##x##__) || QT_COMPILER_SUPPORTS(x))
132# if defined(Q_CC_GNU) || defined(Q_CC_CLANG)
134# define QT_FUNCTION_TARGET(x) __attribute__((__target__(QT_FUNCTION_TARGET_STRING_ ## x)))
136# define QT_FUNCTION_TARGET(x)
139# define QT_COMPILER_SUPPORTS_HERE(x) (defined __##x##__ && __##x##__)
140# define QT_FUNCTION_TARGET(x)
143#if defined(__SSE2__
) && !defined(QT_COMPILER_SUPPORTS_SSE2) && !defined(QT_BOOTSTRAPPED)
169# undef __AVX512IFMA__
170# undef __AVX512VBMI__
172# undef __AVX512VBMI2__
173# undef __AVX512BITALG__
174# undef __AVX512VNNI__
175# undef __AVX512VPOPCNTDQ__
180#ifdef Q_PROCESSOR_X86
183# if defined(QT_COMPILER_SUPPORTS_RDSEED) && defined(Q_OS_QNX)
185# undef QT_COMPILER_SUPPORTS_RDSEED
187# if defined(Q_CC_MSVC) && (defined(_M_X64) || _M_IX86_FP >= 2
)
192# if defined(Q_OS_WIN) && defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
197 ".macro vmovapd args:vararg\n"
200 ".macro vmovaps args:vararg\n"
203 ".macro vmovdqa args:vararg\n"
206 ".macro vmovdqa32 args:vararg\n"
207 " vmovdqu32 \\args\n"
209 ".macro vmovdqa64 args:vararg\n"
210 " vmovdqu64 \\args\n"
215# if defined(Q_CC_GNU) && !defined(Q_OS_WASM)
217# include <x86intrin.h>
220# include <immintrin.h>
223# include <QtCore/private/qsimd_x86_p.h>
234# if defined(__AVX2__)
237# define ARCH_HASWELL_MACROS
238 (__AVX2__ + __BMI__ + __BMI2__ + __F16C__ + __FMA__ + __LZCNT__ + __POPCNT__)
239# if ARCH_HASWELL_MACROS != 7
240# error "Please enable all x86-64-v3 extensions; you probably want to use -march=haswell or -march=x86-64-v3 instead of -mavx2"
242static_assert(ARCH_HASWELL_MACROS,
"Undeclared identifiers indicate which features are missing.");
243# define __haswell__ 1
244# undef ARCH_HASWELL_MACROS
254# define ARCH_SKX_MACROS (__AVX512F__ + __AVX512BW__ + __AVX512CD__ + __AVX512DQ__ + __AVX512VL__)
255# if ARCH_SKX_MACROS != 0
256# if ARCH_SKX_MACROS != 5
257# error "Please enable all x86-64-v4 extensions; you probably want to use -march=skylake-avx512 or -march=x86-64-v4 instead of -mavx512f"
259static_assert(ARCH_SKX_MACROS,
"Undeclared identifiers indicate which features are missing.");
260# define __skylake_avx512__ 1
262# undef ARCH_SKX_MACROS
267#if defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(_M_ARM64)
268#if defined(Q_CC_CLANG)
269#define QT_FUNCTION_TARGET_STRING_NEON "neon"
271#define QT_FUNCTION_TARGET_STRING_NEON "+neon"
278#ifndef Q_PROCESSOR_ARM_64
279static inline uint16_t vaddvq_u16(uint16x8_t v8)
281 const uint64x2_t v2 = vpaddlq_u32(vpaddlq_u16(v8));
282 const uint64x1_t v1 = vadd_u64(vget_low_u64(v2), vget_high_u64(v2));
283 return vget_lane_u16(vreinterpret_u16_u64(v1), 0);
286static inline uint8_t vaddv_u8(uint8x8_t v8)
288 const uint64x1_t v1 = vpaddl_u32(vpaddl_u16(vpaddl_u8(v8)));
289 return vget_lane_u8(vreinterpret_u8_u64(v1), 0);
294static inline uint16x8_t qvsetq_n_u16(uint16_t v1, uint16_t v2, uint16_t v3, uint16_t v4,
295 uint16_t v5, uint16_t v6, uint16_t v7, uint16_t v8)
297#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
298 using u64 = uint64_t;
299 const uint16x8_t vmask = {
300 v1 | (v2 << 16) | (u64(v3) << 32) | (u64(v4) << 48),
301 v5 | (v6 << 16) | (u64(v7) << 32) | (u64(v8) << 48)
304 const uint16x8_t vmask = { v1, v2, v3, v4, v5, v6, v7, v8 };
308static inline uint8x8_t qvset_n_u8(uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5,
309 uint8_t v6, uint8_t v7, uint8_t v8)
311#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
312 using u64 = uint64_t;
313 const uint8x8_t vmask = {
314 v1 | (v2 << 8) | (v3 << 16) | (v4 << 24) |
315 (u64(v5) << 32) | (u64(v6) << 40) | (u64(v7) << 48) | (u64(v8) << 56)
318 const uint8x8_t vmask = { v1, v2, v3, v4, v5, v6, v7, v8 };
322static inline uint8x16_t qvsetq_n_u8(uint8_t v1, uint8_t v2, uint8_t v3, uint8_t v4, uint8_t v5,
323 uint8_t v6, uint8_t v7, uint8_t v8, uint8_t v9, uint8_t v10,
324 uint8_t v11, uint8_t v12, uint8_t v13, uint8_t v14,
325 uint8_t v15, uint8_t v16)
327#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
328 using u64 = uint64_t;
329 const uint8x16_t vmask = {
330 v1 | (v2 << 8) | (v3 << 16) | (v4 << 24) |
331 (u64(v5) << 32) | (u64(v6) << 40) | (u64(v7) << 48) | (u64(v8) << 56),
332 v9 | (v10 << 8) | (v11 << 16) | (v12 << 24) |
333 (u64(v13) << 32) | (u64(v14) << 40) | (u64(v15) << 48) | (u64(v16) << 56)
336 const uint8x16_t vmask = { v1, v2, v3, v4, v5, v6, v7, v8,
337 v9, v10, v11, v12, v13, v14, v15, v16};
341static inline uint32x4_t qvsetq_n_u32(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
343#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
344 return uint32x4_t{ (uint64_t(b) << 32) | a, (uint64_t(d) << 32) | c };
346 return uint32x4_t{ a, b, c, d };
351#if defined(_M_ARM64) && __ARM_ARCH >= 800
352#define __ARM_FEATURE_CRYPTO 1
353#define __ARM_FEATURE_CRC32 1
356#if defined(Q_PROCESSOR_ARM_64)
357#if defined(Q_CC_CLANG)
358#define QT_FUNCTION_TARGET_STRING_AES "aes"
359#define QT_FUNCTION_TARGET_STRING_CRC32 "crc"
360#define QT_FUNCTION_TARGET_STRING_SVE "sve"
361#elif defined(Q_CC_GNU)
362#define QT_FUNCTION_TARGET_STRING_AES "+crypto"
363#define QT_FUNCTION_TARGET_STRING_CRC32 "+crc"
364#define QT_FUNCTION_TARGET_STRING_SVE "+sve"
365#elif defined(Q_CC_MSVC)
366#define QT_FUNCTION_TARGET_STRING_AES
367#define QT_FUNCTION_TARGET_STRING_CRC32
368#define QT_FUNCTION_TARGET_STRING_SVE
370#elif defined(Q_PROCESSOR_ARM_32)
371#if defined(Q_CC_CLANG)
372#define QT_FUNCTION_TARGET_STRING_AES "armv8-a,crypto"
373#define QT_FUNCTION_TARGET_STRING_CRC32 "armv8-a,crc"
374#elif defined(Q_CC_GNU)
375#define QT_FUNCTION_TARGET_STRING_AES "arch=armv8-a+crypto"
376#define QT_FUNCTION_TARGET_STRING_CRC32 "arch=armv8-a+crc"
380#ifndef Q_PROCESSOR_X86
382#if defined(Q_PROCESSOR_ARM)
384 CpuFeatureARM_NEON = CpuFeatureNEON,
387 CpuFeatureARM_CRYPTO = CpuFeatureAES,
389#elif defined(Q_PROCESSOR_MIPS)
392#elif defined(Q_PROCESSOR_LOONGARCH)
399#if defined __ARM_NEON__
402#if !(defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM_64))
408#if defined __ARM_FEATURE_CRC32
411#if defined (__ARM_FEATURE_CRYPTO) || defined(__ARM_FEATURE_AES)
415#if defined(__ARM_FEATURE_SVE) && defined(Q_PROCESSOR_ARM_64)
418#if defined __mips_dsp
421#if defined __mips_dspr2
424#if defined __loongarch_sx
427#if defined __loongarch_asx
435# define Q_ATOMIC(T) std::atomic<T>
437using std::atomic_load_explicit;
438static constexpr auto memory_order_relaxed =
std::memory_order_relaxed;
441# include <stdatomic.h>
442# define Q_ATOMIC(T) _Atomic(T)
445#ifdef Q_PROCESSOR_X86
446typedef uint64_t QCpuFeatureType;
447static const QCpuFeatureType qCompilerCpuFeatures = _compilerCpuFeatures;
448static const QCpuFeatureType CpuFeatureArchHaswell = cpu_haswell;
449static const QCpuFeatureType CpuFeatureArchSkylakeAvx512 = cpu_skylake_avx512;
453extern Q_CORE_EXPORT
Q_ATOMIC(QCpuFeatureType) QT_MANGLE_NAMESPACE(qt_cpu_features)[1];
454Q_CORE_EXPORT uint64_t QT_MANGLE_NAMESPACE(qDetectCpuFeatures)();
458#ifdef QT_BOOTSTRAPPED
459 return qCompilerCpuFeatures;
461 quint64 features = atomic_load_explicit(QT_MANGLE_NAMESPACE(qt_cpu_features), memory_order_relaxed);
462 if (!QT_SUPPORTS_INIT_PRIORITY) {
463 if (Q_UNLIKELY(features == 0))
464 features = QT_MANGLE_NAMESPACE(qDetectCpuFeatures)();
470#define qCpuHasFeature(feature) (((qCompilerCpuFeatures & CpuFeature ## feature) == CpuFeature ## feature)
471 || ((qCpuFeatures() & CpuFeature ## feature) == CpuFeature ## feature))
477Q_CORE_EXPORT qsizetype qRandomCpu(
void *, qsizetype)
noexcept;
479static inline bool qHasHwrng()
481 return qCpuHasFeature(RDRND);
484static inline qsizetype qRandomCpu(
void *, qsizetype)
noexcept
488static inline bool qHasHwrng()
#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
#define QT_COMPILER_SUPPORTS_HERE(x)
static const uint64_t qCompilerCpuFeatures
static uint64_t qCpuFeatures()