diff options
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qsimd.cpp | 47 | ||||
-rw-r--r-- | src/corelib/tools/qsimd_p.h | 63 |
2 files changed, 67 insertions, 43 deletions
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index c399a5a527..df41e6bd6d 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -355,39 +355,9 @@ static const int features_indices[] = { static const int features_count = (sizeof features_indices - 1) / (sizeof features_indices[0]); -static const uint minFeature = None -#if defined __RTM__ - | RTM -#endif +// record what CPU features were enabled by default in this Qt build // don't define for HLE, since the HLE prefix can be run on older CPUs -#if defined __AVX2__ - | AVX2 -#endif -#if defined __AVX__ - | AVX -#endif -#if defined __SSE4_2__ - | SSE4_2 -#endif -#if defined __SSE4_1__ - | SSE4_1 -#endif -#if defined __SSSE3__ - | SSSE3 -#endif -#if defined __SSE3__ - | SSE3 -#endif -#if defined __SSE2__ - | SSE2 -#endif -#if defined __ARM_NEON__ - | NEON -#endif -#if defined __IWMMXT__ - | IWMMXT -#endif - ; +static const uint minFeature = qCompilerCpuFeatures & ~HLE; #ifdef Q_OS_WIN #if defined(Q_CC_GNU) @@ -405,12 +375,10 @@ int ffs(int i) #endif #endif // Q_OS_WIN -uint qDetectCPUFeatures() -{ - static QBasicAtomicInt features = Q_BASIC_ATOMIC_INITIALIZER(-1); - if (features.load() != -1) - return features.load(); +QBasicAtomicInt qt_cpu_features = Q_BASIC_ATOMIC_INITIALIZER(0); +void qDetectCpuFeatures() +{ uint f = detectProcessorFeatures(); QByteArray disable = qgetenv("QT_NO_CPU_FEATURE"); if (!disable.isEmpty()) { @@ -434,13 +402,12 @@ uint qDetectCPUFeatures() features_string + features_indices[ffs(missing) - 1]); } - features.store(f); - return f; + qt_cpu_features.store(f | QSimdInitialized); } void qDumpCPUFeatures() { - uint features = qDetectCPUFeatures(); + uint features = qCpuFeatures(); printf("Processor features: "); for (int i = 0; i < features_count; ++i) { if (features & (1 << i)) diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index 0cc6bf4b76..ce9c7b789f 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -43,6 +43,7 @@ #define QSIMD_P_H #include <qglobal.h> +#include <qatomic.h> QT_BEGIN_HEADER @@ -172,7 +173,6 @@ QT_BEGIN_NAMESPACE enum CPUFeatures { - None = 0, IWMMXT = 0x1, NEON = 0x2, SSE2 = 0x4, @@ -183,10 +183,67 @@ enum CPUFeatures { AVX = 0x80, AVX2 = 0x100, HLE = 0x200, - RTM = 0x400 + RTM = 0x400, + + // used only to indicate that the CPU detection was initialised + QSimdInitialized = 0x80000000 }; -Q_CORE_EXPORT uint qDetectCPUFeatures(); +static const uint qCompilerCpuFeatures = 0 +#if defined __RTM__ + | RTM +#endif +#if defined __HLE__ + | HLE +#endif +#if defined __AVX2__ + | AVX2 +#endif +#if defined __AVX__ + | AVX +#endif +#if defined __SSE4_2__ + | SSE4_2 +#endif +#if defined __SSE4_1__ + | SSE4_1 +#endif +#if defined __SSSE3__ + | SSSE3 +#endif +#if defined __SSE3__ + | SSE3 +#endif +#if defined __SSE2__ + | SSE2 +#endif +#if defined __ARM_NEON__ + | NEON +#endif +#if defined __IWMMXT__ + | IWMMXT +#endif + ; + + +extern Q_CORE_EXPORT QBasicAtomicInt qt_cpu_features; +Q_CORE_EXPORT void qDetectCpuFeatures(); + +inline uint qCpuFeatures() +{ + int features = qt_cpu_features.load(); + if (Q_UNLIKELY(features == 0)) { + qDetectCpuFeatures(); + features = qt_cpu_features.load(); + Q_ASSUME(features != 0); + } + return uint(features); +} + +inline uint qCpuHasFeature(CPUFeatures feature) +{ + return qCompilerCpuFeatures & feature || qCpuFeatures() & feature; +} #define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \ |