6#define __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
15#if defined(QT_NO_DEBUG) && !defined(NDEBUG)
21# include "../testlib/3rdparty/valgrind_p.h"
24#define QT_FUNCTION_TARGET_BASELINE
27# if !defined(Q_CC_GNU)
30# if defined(Q_PROCESSOR_ARM_64)
32# include <processthreadsapi.h>
34#elif defined(Q_OS_LINUX) && defined(Q_PROCESSOR_MIPS_32)
35# include "private/qcore_unix_p.h"
36#elif QT_CONFIG(getauxval) && defined(Q_PROCESSOR_ARM)
43#define HWCAP_NEON 4096
46#define HWCAP2_AES (1 << 0)
47#define HWCAP2_CRC32 (1 << 4)
50#define HWCAP_AES (1 << 3)
51#define HWCAP_CRC32 (1 << 7)
57#elif defined(Q_CC_GHS)
58# include <INTEGRITY_types.h>
59#elif defined(Q_OS_DARWIN) && defined(Q_PROCESSOR_ARM)
60# include <sys/sysctl.h>
73#if defined(Q_PROCESSOR_ARM)
85#elif defined(Q_PROCESSOR_MIPS)
98#elif defined(Q_PROCESSOR_X86)
106#if defined(Q_PROCESSOR_ARM)
111#if QT_CONFIG(getauxval)
112 unsigned long auxvHwCap = getauxval(AT_HWCAP);
113 if (auxvHwCap != 0) {
114# if defined(Q_PROCESSOR_ARM_64)
116 features |= CpuFeatureNEON;
117 if (auxvHwCap & HWCAP_CRC32)
118 features |= CpuFeatureCRC32;
119 if (auxvHwCap & HWCAP_AES)
120 features |= CpuFeatureAES;
123 if (auxvHwCap & HWCAP_NEON)
124 features |= CpuFeatureNEON;
125 auxvHwCap = getauxval(AT_HWCAP2);
126 if (auxvHwCap & HWCAP2_CRC32)
127 features |= CpuFeatureCRC32;
128 if (auxvHwCap & HWCAP2_AES)
129 features |= CpuFeatureAES;
134#elif defined(Q_OS_DARWIN) && defined(Q_PROCESSOR_ARM)
136 size_t len =
sizeof(feature);
137 if (sysctlbyname(
"hw.optional.neon", &feature, &
len,
nullptr, 0) == 0)
138 features |= feature ? CpuFeatureNEON : 0;
139 if (sysctlbyname(
"hw.optional.armv8_crc32", &feature, &
len,
nullptr, 0) == 0)
140 features |= feature ? CpuFeatureCRC32 : 0;
142#if defined(__ARM_FEATURE_CRYPTO)
143 features |= CpuFeatureAES;
146#elif defined(Q_OS_WIN) && defined(Q_PROCESSOR_ARM_64)
147 features |= CpuFeatureNEON;
148 if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) != 0)
149 features |= CpuFeatureCRC32;
150 if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0)
151 features |= CpuFeatureAES;
154#if defined(__ARM_NEON__) || defined(__ARM_NEON)
155 features |= CpuFeatureNEON;
157#if defined(__ARM_FEATURE_CRC32)
158 features |= CpuFeatureCRC32;
160#if defined(__ARM_FEATURE_CRYPTO)
161 features |= CpuFeatureAES;
167#elif defined(Q_PROCESSOR_X86)
169#ifdef Q_PROCESSOR_X86_32
170# define PICreg "%%ebx"
172# define PICreg "%%rbx"
175# define X86_BASELINE "no-sse3"
177# define X86_BASELINE "no-sse"
182# undef QT_FUNCTION_TARGET_BASELINE
183# define QT_FUNCTION_TARGET_BASELINE __attribute__((target(X86_BASELINE)))
184# define QT_FUNCTION_TARGET_STRING_BASELINE_RDRND \
185 X86_BASELINE "," QT_FUNCTION_TARGET_STRING_RDRND
188static bool checkRdrndWorks() noexcept;
191static
int maxBasicCpuidSupported()
193#if defined(Q_CC_EMSCRIPTEN)
195#elif defined(Q_CC_GNU)
198# if Q_PROCESSOR_X86 < 5
200 long cpuid_supported;
204 "xor $0x00200000, %0\n"
210 :
"=a" (cpuid_supported),
"=r" (tmp1)
212 if (!cpuid_supported)
217 asm (
"xchg " PICreg
", %1\n"
219 "xchg " PICreg
", %1\n"
220 :
"=&a" (
result),
"=&r" (tmp1)
224#elif defined(Q_OS_WIN)
229#elif defined(Q_CC_GHS)
230 unsigned int info[4];
239static void cpuidFeatures01(
uint &ecx,
uint &edx)
241#if defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)
243 asm (
"xchg " PICreg
", %2\n"
245 "xchg " PICreg
", %2\n"
246 :
"=&c" (ecx),
"=&d" (edx),
"=&r" (tmp1)
248#elif defined(Q_OS_WIN)
253#elif defined(Q_CC_GHS)
254 unsigned int info[4];
265inline void __cpuidex(
int info[4],
int, __int64) { memset(
info, 0, 4*
sizeof(
int));}
269static void cpuidFeatures07_00(
uint &ebx,
uint &ecx,
uint &edx)
271#if defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)
273 qregisteruint rcx = 0;
274 qregisteruint rdx = 0;
275 asm (
"xchg " PICreg
", %0\n"
277 "xchg " PICreg
", %0\n"
278 :
"=&r" (rbx),
"+&c" (rcx),
"+&d" (rdx)
283#elif defined(Q_OS_WIN)
285 __cpuidex(
info, 7, 0);
289#elif defined(Q_CC_GHS)
290 unsigned int info[4];
291 __CPUIDEX(7, 0,
info);
303#if defined(Q_OS_WIN) && !(defined(Q_CC_GNU) || defined(Q_CC_GHS))
305inline quint64 _xgetbv(__int64) {
return 0; }
309#if (defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)) || defined(Q_CC_GHS)
310 asm (
".byte 0x0F, 0x01, 0xD0"
311 :
"=a" (eax),
"=d" (edx)
313#elif defined(Q_OS_WIN)
340 constexpr quintptr commpage =
sizeof(
void *) > 4 ?
Q_UINT64_C(0x00007fffffe00000) : 0xffff0000;
341 constexpr quintptr cpu_capabilities64 = commpage + 0x10;
343 if (capab & kHasAVX512F)
354 int cpuidLevel = maxBasicCpuidSupported();
355#if Q_PROCESSOR_X86 < 5
380 uint xgetbvA = 0, xgetbvD = 0;
381 xgetbv(0, xgetbvA, xgetbvD);
385 xcr0 |=
quint64(xgetbvD) << 32;
386 xcr0 = adjustedXcr0(xcr0);
390 if ((xcr0 & req.xsave_state) != req.xsave_state)
391 features &= ~req.cpu_features;
394 if (features & CpuFeatureRDRND && !checkRdrndWorks())
395 features &= ~(CpuFeatureRDRND | CpuFeatureRDSEED);
400#elif defined(Q_PROCESSOR_MIPS_32)
402#if defined(Q_OS_LINUX)
411 static const int chunk_size = 256;
417 ~QSimpleBuffer() { ::free(
data); }
419 void resize(
unsigned newsize)
421 if (newsize > alloc) {
422 unsigned newalloc = chunk_size * ((newsize / chunk_size) + 1);
423 if (newalloc < newsize)
425 if (newalloc != alloc) {
426 data =
static_cast<char *
>(::realloc(
data, newalloc));
432 void append(
const QSimpleBuffer &
other,
unsigned appendsize)
438 void popleft(
unsigned amount)
459static void bufReadLine(
int fd, QSimpleBuffer &
line, QSimpleBuffer &
buffer)
462 char *newline =
static_cast<char *
>(::memchr(
buffer.data,
'\n',
buffer.size));
464 unsigned piece_size = newline -
buffer.data + 1;
466 buffer.popleft(piece_size);
470 if (
buffer.size + QSimpleBuffer::chunk_size >
buffer.alloc) {
478 buffer.size += read_bytes;
488static bool procCpuinfoContains(
const char *prefix,
const char *
string)
491 if (cpuinfo_fd == -1)
494 unsigned string_len = ::strlen(
string);
495 unsigned prefix_len = ::strlen(prefix);
497 bool present =
false;
502 if (colon &&
line.
size > prefix_len + string_len) {
503 if (!::strncmp(prefix,
line.
data, prefix_len)) {
507 char *found = ::strstr(
line.cString(),
string);
508 if (found && ::isspace(found[-1]) &&
509 (::isspace(found[string_len]) || found[string_len] ==
'\0')) {
528#if defined __mips_dsp
529 flags |= CpuFeatureDSP;
530# if defined __mips_dsp_rev && __mips_dsp_rev >= 2
531 flags |= CpuFeatureDSPR2;
532# elif defined(Q_OS_LINUX)
533 if (procCpuinfoContains(
"cpu model",
"MIPS 74Kc") || procCpuinfoContains(
"cpu model",
"MIPS 74Kf"))
534 flags |= CpuFeatureDSPR2;
536#elif defined(Q_OS_LINUX)
537 if (procCpuinfoContains(
"ASEs implemented",
"dsp")) {
538 flags |= CpuFeatureDSP;
539 if (procCpuinfoContains(
"cpu model",
"MIPS 74Kc") || procCpuinfoContains(
"cpu model",
"MIPS 74Kf"))
540 flags |= CpuFeatureDSPR2;
564#if defined(Q_PROCESSOR_X86_64) && defined(cpu_feature_shstk)
568 minFeatureTest &= ~CpuFeatureSHSTK;
573 if (
char *disable = getenv(
"QT_NO_CPU_FEATURE"); disable && *disable) {
574#if _POSIX_C_SOURCE >= 200112L
575 char *saveptr =
nullptr;
576 auto strtok = [&saveptr](
char *
str,
const char *delim) {
577 return ::strtok_r(
str, delim, &saveptr);
580 while (
char *
token = strtok(disable,
" ")) {
589#ifdef RUNNING_ON_VALGRIND
590 bool runningOnValgrind = RUNNING_ON_VALGRIND;
592 bool runningOnValgrind =
false;
594 if (
Q_UNLIKELY(!runningOnValgrind && minFeatureTest != 0 && (
f & minFeatureTest) != minFeatureTest)) {
596 fprintf(stderr,
"Incompatible processor. This Qt build requires the following features:\n ");
601 fprintf(stderr,
"\n");
616 printf(
"Processor features: ");
623 printf(
"\n!!!!!!!!!!!!!!!!!!!!\n!!! Missing required features:");
628 printf(
"\n!!! Applications will likely crash with \"Invalid Instruction\"\n!!!!!!!!!!!!!!!!!!!!");
633#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND)
635# ifdef Q_PROCESSOR_X86_64
636# define _rdrandXX_step _rdrand64_step
637# define _rdseedXX_step _rdseed64_step
639# define _rdrandXX_step _rdrand32_step
640# define _rdseedXX_step _rdseed32_step
647template <
typename F>
struct ExtractParameter;
648template <
typename T>
struct ExtractParameter<int (T *)> {
using Type = T; };
649using randuint = ExtractParameter<
decltype(_rdrandXX_step)>
::Type;
652# if QT_COMPILER_SUPPORTS_HERE(RDSEED)
660 while (
ptr +
sizeof(randuint) /
sizeof(*
ptr) <=
end) {
661 if (_rdseedXX_step(
reinterpret_cast<randuint *
>(
ptr)) == 0)
663 ptr +=
sizeof(randuint) /
sizeof(*
ptr);
666 if (
sizeof(*
ptr) !=
sizeof(randuint) &&
ptr !=
end) {
667 if (_rdseed32_step(
ptr) == 0)
676static unsigned *qt_random_rdseed(
unsigned *
ptr,
unsigned *)
685 while (
ptr +
sizeof(randuint)/
sizeof(*
ptr) <=
end) {
686 if (_rdrandXX_step(
reinterpret_cast<randuint *
>(
ptr)))
687 ptr +=
sizeof(randuint)/
sizeof(*
ptr);
688 else if (--retries == 0)
692 while (
sizeof(*
ptr) !=
sizeof(randuint) &&
ptr !=
end) {
693 bool ok = _rdrand32_step(
ptr);
694 if (!
ok && --retries)
706static bool checkRdrndWorks() noexcept
720 unsigned testBuffer[TestBufferSize] = {};
722 unsigned *
end = qt_random_rdrnd(testBuffer, testBuffer + TestBufferSize);
723 if (
end < testBuffer + 3) {
731 if (testBuffer[0] == testBuffer[1]
732 && testBuffer[0] == testBuffer[2]
733 && (
end < testBuffer + TestBufferSize || testBuffer[0] == testBuffer[3])) {
734 fprintf(stderr,
"WARNING: CPU random generator seem to be failing, "
735 "disabling hardware random number generation\n"
736 "WARNING: RDRND generated:");
738 fprintf(stderr,
" 0x%x", *
ptr);
739 fprintf(stderr,
"\n");
749 unsigned *
ptr =
reinterpret_cast<unsigned *
>(
buffer);
757 return ptr -
reinterpret_cast<unsigned *
>(
buffer);
759#elif defined(Q_PROCESSOR_X86) && !defined(Q_PROCESSOR_ARM)
760static bool checkRdrndWorks() noexcept {
return false; }
763#if QT_SUPPORTS_INIT_PRIORITY
765struct QSimdInitializer
772Q_DECL_INIT_PRIORITY(01) static QSimdInitializer initializer;
qsizetype size() const noexcept
Returns the number of characters in this string.
QChar * data()
Returns a pointer to the data stored in the QString.
QString & append(QChar c)
void resize(qsizetype size)
Sets the size of the string to size characters.
list append(new Employee("Blackpool", "Stephen"))
Combined button and popup list for selecting options.
QT_BEGIN_NAMESPACE void qAbort()
#define Q_DECL_COLD_FUNCTION
static int qt_safe_open(const char *pathname, int flags, mode_t mode=0777)
static qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
static int qt_safe_close(int fd)
static ControlElement< T > * ptr(QWidget *widget)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
QT_BEGIN_NAMESPACE QT_FUNCTION_TARGET_BASELINE uint arraysize(T(&)[N])
#define QT_FUNCTION_TARGET_BASELINE
QT_FUNCTION_TARGET_BASELINE uint64_t QT_MANGLE_NAMESPACE qDetectCpuFeatures()
QT_FUNCTION_TARGET_BASELINE void qDumpCPUFeatures()
static constexpr auto SimdInitialized
static const quint64 minFeature
static uint detectProcessorFeatures()
static const char features_string[]
static const int features_indices[]
#define qCpuHasFeature(feature)
#define QT_FUNCTION_TARGET(x)
static const uint64_t qCompilerCpuFeatures
static const struct XSaveRequirementMapping xsave_requirements[]
static const uint16_t x86_locators[]
#define QT_MANGLE_NAMESPACE(name)
unsigned long long quint64
QTextStream out(stdout)
[7]