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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint detectProcessorFeatures()
|
static quint64 detectProcessorFeatures()
|
||||||
{
|
{
|
||||||
// Flags from the CR0 / XCR0 state register
|
// Flags from the CR0 / XCR0 state register
|
||||||
enum XCR0Flags {
|
enum XCR0Flags {
|
||||||
@ -258,7 +258,7 @@ static inline uint detectProcessorFeatures()
|
|||||||
AVX512State = AVXState | OpMask | ZMM0_15Hi256 | ZMM16_31
|
AVX512State = AVXState | OpMask | ZMM0_15Hi256 | ZMM16_31
|
||||||
};
|
};
|
||||||
|
|
||||||
uint features = 0;
|
quint64 features = 0;
|
||||||
int cpuidLevel = maxBasicCpuidSupported();
|
int cpuidLevel = maxBasicCpuidSupported();
|
||||||
#if Q_PROCESSOR_X86 < 5
|
#if Q_PROCESSOR_X86 < 5
|
||||||
if (cpuidLevel < 1)
|
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]);
|
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
|
// 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
|
#ifdef Q_OS_WIN
|
||||||
#if defined(Q_CC_GNU)
|
#if defined(Q_CC_GNU)
|
||||||
# define ffs __builtin_ffs
|
# define ffsll __builtin_ffsll
|
||||||
#else
|
#else
|
||||||
int ffs(int i)
|
int ffsll(quint64 i)
|
||||||
{
|
{
|
||||||
#ifndef Q_OS_WINCE
|
#if defined(Q_OS_WIN64)
|
||||||
unsigned long result;
|
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
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#elif defined(Q_OS_ANDROID)
|
#elif defined(Q_OS_ANDROID) || defined(Q_OS_QNX)
|
||||||
# define ffs __builtin_ffs
|
# define ffsll __builtin_ffsll
|
||||||
#endif
|
#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()
|
void qDetectCpuFeatures()
|
||||||
{
|
{
|
||||||
@ -547,11 +555,11 @@ void qDetectCpuFeatures()
|
|||||||
// contains all the features that the code required. Qt 4 ran for years
|
// contains all the features that the code required. Qt 4 ran for years
|
||||||
// like that, so it shouldn't be a problem.
|
// like that, so it shouldn't be a problem.
|
||||||
|
|
||||||
qt_cpu_features.store(minFeature | QSimdInitialized);
|
qt_cpu_features.store(minFeature | quint32(QSimdInitialized));
|
||||||
return;
|
return;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
uint f = detectProcessorFeatures();
|
quint64 f = detectProcessorFeatures();
|
||||||
QByteArray disable = qgetenv("QT_NO_CPU_FEATURE");
|
QByteArray disable = qgetenv("QT_NO_CPU_FEATURE");
|
||||||
if (!disable.isEmpty()) {
|
if (!disable.isEmpty()) {
|
||||||
disable.prepend(' ');
|
disable.prepend(' ');
|
||||||
@ -567,29 +575,32 @@ void qDetectCpuFeatures()
|
|||||||
bool runningOnValgrind = false;
|
bool runningOnValgrind = false;
|
||||||
#endif
|
#endif
|
||||||
if (!runningOnValgrind && (minFeature != 0 && (f & minFeature) != minFeature)) {
|
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 ");
|
fprintf(stderr, "Incompatible processor. This Qt build requires the following features:\n ");
|
||||||
for (int i = 0; i < features_count; ++i) {
|
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, "%s", features_string + features_indices[i]);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
qFatal("Aborted. Incompatible processor: missing feature 0x%x -%s.", missing,
|
qFatal("Aborted. Incompatible processor: missing feature 0x%llx -%s.", missing,
|
||||||
features_string + features_indices[ffs(missing) - 1]);
|
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()
|
void qDumpCPUFeatures()
|
||||||
{
|
{
|
||||||
uint features = qCpuFeatures();
|
quint64 features = qCpuFeatures() & ~quint64(QSimdInitialized);
|
||||||
printf("Processor features: ");
|
printf("Processor features: ");
|
||||||
for (int i = 0; i < features_count; ++i) {
|
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],
|
printf("%s%s", features_string + features_indices[i],
|
||||||
minFeature & (1 << i) ? "[required]" : "");
|
minFeature & (Q_UINT64_C(1) << i) ? "[required]" : "");
|
||||||
}
|
}
|
||||||
puts("");
|
puts("");
|
||||||
}
|
}
|
||||||
|
@ -298,18 +298,28 @@ static const uint qCompilerCpuFeatures = 0
|
|||||||
#endif
|
#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();
|
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)) {
|
if (Q_UNLIKELY(features == 0)) {
|
||||||
qDetectCpuFeatures();
|
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);
|
Q_ASSUME(features != 0);
|
||||||
}
|
}
|
||||||
return uint(features);
|
return features;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define qCpuHasFeature(feature) ((qCompilerCpuFeatures & (feature)) || (qCpuFeatures() & (feature)))
|
#define qCpuHasFeature(feature) ((qCompilerCpuFeatures & (feature)) || (qCpuFeatures() & (feature)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user