summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qsimd.cpp47
-rw-r--r--src/corelib/tools/qsimd_p.h63
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) \