qsimd/x86: lower the target architecture for load-time code
That is, allow QtCore to get loaded and print its "missing features"
text without crashing with an undefined instruction. We'll still
abort(), so it's still a "crash", but it'll happen after the message is
printed.
Tested with Intel's Software Development Emulator[1]:
$ sde64 -wsm -- ./libexec/rcc
Incompatible processor. This Qt build requires the following features:
fma movbe avx f16c rdrnd bmi avx2 bmi2 avx512f avx512dq avx512ifma avx512cd sha avx512bw avx512vl avx512vbmi avx512vbmi2 gfni vaes avx512vnni avx512bitalg avx512vpopcntdq
[1] https://www.intel.com/software/sde
Change-Id: I6fcda969a9e9427198bffffd16ce8b86524a566e
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
bb10
parent
b7c37e5978
commit
9e0f1b905a
|
|
@ -55,6 +55,8 @@
|
|||
# include "../testlib/3rdparty/valgrind_p.h"
|
||||
#endif
|
||||
|
||||
#define QT_FUNCTION_TARGET_BASELINE
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
# if !defined(Q_CC_GNU)
|
||||
# include <intrin.h>
|
||||
|
|
@ -197,12 +199,24 @@ static inline quint64 detectProcessorFeatures()
|
|||
|
||||
#ifdef Q_PROCESSOR_X86_32
|
||||
# define PICreg "%%ebx"
|
||||
# define X86_BASELINE "i386"
|
||||
#else
|
||||
# define PICreg "%%rbx"
|
||||
# define X86_BASELINE "x86-64"
|
||||
#endif
|
||||
|
||||
#if defined(Q_CC_GNU)
|
||||
// lower the target for functions in this file
|
||||
# undef QT_FUNCTION_TARGET_BASELINE
|
||||
# define QT_FUNCTION_TARGET_BASELINE __attribute__((target("arch=" X86_BASELINE)))
|
||||
# define QT_FUNCTION_TARGET_STRING_BASELINE_RDRND \
|
||||
"arch=" X86_BASELINE \
|
||||
"," QT_FUNCTION_TARGET_STRING_RDRND
|
||||
#endif
|
||||
|
||||
static bool checkRdrndWorks() noexcept;
|
||||
|
||||
QT_FUNCTION_TARGET_BASELINE
|
||||
static int maxBasicCpuidSupported()
|
||||
{
|
||||
#if defined(Q_CC_EMSCRIPTEN)
|
||||
|
|
@ -250,6 +264,7 @@ static int maxBasicCpuidSupported()
|
|||
#endif
|
||||
}
|
||||
|
||||
QT_FUNCTION_TARGET_BASELINE
|
||||
static void cpuidFeatures01(uint &ecx, uint &edx)
|
||||
{
|
||||
#if defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)
|
||||
|
|
@ -279,6 +294,7 @@ static void cpuidFeatures01(uint &ecx, uint &edx)
|
|||
inline void __cpuidex(int info[4], int, __int64) { memset(info, 0, 4*sizeof(int));}
|
||||
#endif
|
||||
|
||||
QT_FUNCTION_TARGET_BASELINE
|
||||
static void cpuidFeatures07_00(uint &ebx, uint &ecx, uint &edx)
|
||||
{
|
||||
#if defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)
|
||||
|
|
@ -312,6 +328,7 @@ static void cpuidFeatures07_00(uint &ebx, uint &ecx, uint &edx)
|
|||
#endif
|
||||
}
|
||||
|
||||
QT_FUNCTION_TARGET_BASELINE
|
||||
#if defined(Q_OS_WIN) && !(defined(Q_CC_GNU) || defined(Q_CC_GHS))
|
||||
// fallback overload in case this intrinsic does not exist: unsigned __int64 _xgetbv(unsigned int);
|
||||
inline quint64 _xgetbv(__int64) { return 0; }
|
||||
|
|
@ -349,6 +366,7 @@ enum XCR0Flags {
|
|||
AVX512State = AVXState | OpMask | ZMM0_15Hi256 | ZMM16_31
|
||||
};
|
||||
|
||||
QT_FUNCTION_TARGET_BASELINE
|
||||
static quint64 adjustedXcr0(quint64 xcr0)
|
||||
{
|
||||
/*
|
||||
|
|
@ -374,6 +392,7 @@ static quint64 adjustedXcr0(quint64 xcr0)
|
|||
return xcr0;
|
||||
}
|
||||
|
||||
QT_FUNCTION_TARGET_BASELINE
|
||||
static quint64 detectProcessorFeatures()
|
||||
{
|
||||
static const quint64 AllAVX = AllAVX512 | CpuFeatureAVX | CpuFeatureAVX2 | CpuFeatureF16C
|
||||
|
|
@ -589,6 +608,7 @@ static const quint64 minFeature = qCompilerCpuFeatures;
|
|||
static constexpr auto SimdInitialized = QCpuFeatureType(1) << (sizeof(QCpuFeatureType) * 8 - 1);
|
||||
QBasicAtomicInteger<QCpuFeatureType> qt_cpu_features[1] = { 0 };
|
||||
|
||||
QT_FUNCTION_TARGET_BASELINE
|
||||
quint64 qDetectCpuFeatures()
|
||||
{
|
||||
auto minFeatureTest = minFeature;
|
||||
|
|
@ -638,6 +658,7 @@ quint64 qDetectCpuFeatures()
|
|||
return f;
|
||||
}
|
||||
|
||||
QT_FUNCTION_TARGET_BASELINE
|
||||
void qDumpCPUFeatures()
|
||||
{
|
||||
quint64 features = detectProcessorFeatures() & ~SimdInitialized;
|
||||
|
|
@ -730,7 +751,8 @@ out:
|
|||
return ptr;
|
||||
}
|
||||
|
||||
static QT_FUNCTION_TARGET(RDRND) Q_DECL_COLD_FUNCTION bool checkRdrndWorks() noexcept
|
||||
QT_FUNCTION_TARGET(BASELINE_RDRND) Q_DECL_COLD_FUNCTION
|
||||
static bool checkRdrndWorks() noexcept
|
||||
{
|
||||
/*
|
||||
* Some AMD CPUs (e.g. AMD A4-6250J and AMD Ryzen 3000-series) have a
|
||||
|
|
|
|||
Loading…
Reference in New Issue