Change the CPU feature status word to be 64-bit instead of 32-bit
I'm going to need the extra bits for x86. Change-Id: Ib306f8f647014b399b87ffff13f1d3d23e138518 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>
This commit is contained in:
parent
b2ca127ec4
commit
15b42af111
@ -240,7 +240,7 @@ static void xgetbv(uint in, uint &eax, uint &edx)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint detectProcessorFeatures()
|
||||
static quint64 detectProcessorFeatures()
|
||||
{
|
||||
// Flags from the CR0 / XCR0 state register
|
||||
enum XCR0Flags {
|
||||
@ -258,7 +258,7 @@ static inline uint detectProcessorFeatures()
|
||||
AVX512State = AVXState | OpMask | ZMM0_15Hi256 | ZMM16_31
|
||||
};
|
||||
|
||||
uint features = 0;
|
||||
quint64 features = 0;
|
||||
int cpuidLevel = maxBasicCpuidSupported();
|
||||
#if Q_PROCESSOR_X86 < 5
|
||||
if (cpuidLevel < 1)
|
||||
@ -505,27 +505,35 @@ static const int features_indices[] = {
|
||||
static const int features_count = (sizeof features_indices - 1) / (sizeof features_indices[0]);
|
||||
|
||||
// record what CPU features were enabled by default in this Qt build
|
||||
static const uint minFeature = qCompilerCpuFeatures;
|
||||
static const quint64 minFeature = qCompilerCpuFeatures;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#if defined(Q_CC_GNU)
|
||||
# define ffs __builtin_ffs
|
||||
# define ffsll __builtin_ffsll
|
||||
#else
|
||||
int ffs(int i)
|
||||
int ffsll(quint64 i)
|
||||
{
|
||||
#ifndef Q_OS_WINCE
|
||||
#if defined(Q_OS_WIN64)
|
||||
unsigned long result;
|
||||
return _BitScanForward(&result, i) ? result : 0;
|
||||
return _BitScanForward64(&result, i) ? result : 0;
|
||||
#elif !defined(Q_OS_WINCE)
|
||||
unsigned long result;
|
||||
return _BitScanForward(&result, i) ? result :
|
||||
_BitScanForward(&result, i >> 32) ? result + 32 : 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
# define ffs __builtin_ffs
|
||||
#elif defined(Q_OS_ANDROID) || defined(Q_OS_QNX)
|
||||
# define ffsll __builtin_ffsll
|
||||
#endif
|
||||
|
||||
QBasicAtomicInt qt_cpu_features = Q_BASIC_ATOMIC_INITIALIZER(0);
|
||||
#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
|
||||
Q_CORE_EXPORT QBasicAtomicInteger<quint64> qt_cpu_features[1] = { Q_BASIC_ATOMIC_INITIALIZER(0) };
|
||||
#else
|
||||
Q_CORE_EXPORT QBasicAtomicInteger<unsigned> qt_cpu_features[2] = { Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0) };
|
||||
#endif
|
||||
|
||||
void qDetectCpuFeatures()
|
||||
{
|
||||
@ -547,11 +555,11 @@ void qDetectCpuFeatures()
|
||||
// contains all the features that the code required. Qt 4 ran for years
|
||||
// like that, so it shouldn't be a problem.
|
||||
|
||||
qt_cpu_features.store(minFeature | QSimdInitialized);
|
||||
qt_cpu_features.store(minFeature | quint32(QSimdInitialized));
|
||||
return;
|
||||
# endif
|
||||
#endif
|
||||
uint f = detectProcessorFeatures();
|
||||
quint64 f = detectProcessorFeatures();
|
||||
QByteArray disable = qgetenv("QT_NO_CPU_FEATURE");
|
||||
if (!disable.isEmpty()) {
|
||||
disable.prepend(' ');
|
||||
@ -567,29 +575,32 @@ void qDetectCpuFeatures()
|
||||
bool runningOnValgrind = false;
|
||||
#endif
|
||||
if (!runningOnValgrind && (minFeature != 0 && (f & minFeature) != minFeature)) {
|
||||
uint missing = minFeature & ~f;
|
||||
quint64 missing = minFeature & ~f;
|
||||
fprintf(stderr, "Incompatible processor. This Qt build requires the following features:\n ");
|
||||
for (int i = 0; i < features_count; ++i) {
|
||||
if (missing & (1 << i))
|
||||
if (missing & (Q_UINT64_C(1) << i))
|
||||
fprintf(stderr, "%s", features_string + features_indices[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
fflush(stderr);
|
||||
qFatal("Aborted. Incompatible processor: missing feature 0x%x -%s.", missing,
|
||||
features_string + features_indices[ffs(missing) - 1]);
|
||||
qFatal("Aborted. Incompatible processor: missing feature 0x%llx -%s.", missing,
|
||||
features_string + features_indices[ffsll(missing) - 1]);
|
||||
}
|
||||
|
||||
qt_cpu_features.store(f | QSimdInitialized);
|
||||
qt_cpu_features[0].store(f | quint32(QSimdInitialized));
|
||||
#ifndef Q_ATOMIC_INT64_IS_SUPPORTED
|
||||
qt_cpu_features[1].store(f >> 32);
|
||||
#endif
|
||||
}
|
||||
|
||||
void qDumpCPUFeatures()
|
||||
{
|
||||
uint features = qCpuFeatures();
|
||||
quint64 features = qCpuFeatures() & ~quint64(QSimdInitialized);
|
||||
printf("Processor features: ");
|
||||
for (int i = 0; i < features_count; ++i) {
|
||||
if (features & (1 << i))
|
||||
if (features & (Q_UINT64_C(1) << i))
|
||||
printf("%s%s", features_string + features_indices[i],
|
||||
minFeature & (1 << i) ? "[required]" : "");
|
||||
minFeature & (Q_UINT64_C(1) << i) ? "[required]" : "");
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
|
@ -298,18 +298,28 @@ static const uint qCompilerCpuFeatures = 0
|
||||
#endif
|
||||
;
|
||||
|
||||
extern Q_CORE_EXPORT QBasicAtomicInt qt_cpu_features;
|
||||
#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
|
||||
extern Q_CORE_EXPORT QBasicAtomicInteger<quint64> qt_cpu_features[1];
|
||||
#else
|
||||
extern Q_CORE_EXPORT QBasicAtomicInteger<unsigned> qt_cpu_features[2];
|
||||
#endif
|
||||
Q_CORE_EXPORT void qDetectCpuFeatures();
|
||||
|
||||
static inline uint qCpuFeatures()
|
||||
static inline quint64 qCpuFeatures()
|
||||
{
|
||||
int features = qt_cpu_features.load();
|
||||
quint64 features = qt_cpu_features[0].load();
|
||||
#ifndef Q_ATOMIC_INT64_IS_SUPPORTED
|
||||
features |= quint64(qt_cpu_features[1].load()) << 32;
|
||||
#endif
|
||||
if (Q_UNLIKELY(features == 0)) {
|
||||
qDetectCpuFeatures();
|
||||
features = qt_cpu_features.load();
|
||||
features = qt_cpu_features[0].load();
|
||||
#ifndef Q_ATOMIC_INT64_IS_SUPPORTED
|
||||
features |= quint64(qt_cpu_features[1].load()) << 32;
|
||||
#endif
|
||||
Q_ASSUME(features != 0);
|
||||
}
|
||||
return uint(features);
|
||||
return features;
|
||||
}
|
||||
|
||||
#define qCpuHasFeature(feature) ((qCompilerCpuFeatures & (feature)) || (qCpuFeatures() & (feature)))
|
||||
|
Loading…
x
Reference in New Issue
Block a user