diff options
author | Andreas Kling <andreas.kling@nokia.com> | 2010-07-26 10:26:05 (GMT) |
---|---|---|
committer | Andreas Kling <andreas.kling@nokia.com> | 2010-07-26 10:38:11 (GMT) |
commit | 7500a3de97d828a05315cdac03df32a506f806c4 (patch) | |
tree | c03773ce2f219551a05589c09a9d91423b78263e /src | |
parent | efa190848270347362a1caab739961d185561627 (diff) | |
download | Qt-7500a3de97d828a05315cdac03df32a506f806c4.zip Qt-7500a3de97d828a05315cdac03df32a506f806c4.tar.gz Qt-7500a3de97d828a05315cdac03df32a506f806c4.tar.bz2 |
CPU feature detection for x86_64
Previously we've only done feature detection for i386 CPUs since we can
assume all x86_64 processors have MMX/3DNOW/SSE2.
No assumptions can be made about SSE3 and newer features, so now that
we start using those, we need to check for their presence with CPUID on
64-bit processors as well.
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/tools/qsimd.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index ea90b66..5aa7217 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -234,6 +234,73 @@ uint qDetectCPUFeatures() #endif // i386 +#if defined(__x86_64__) || defined(Q_OS_WIN64) + uint feature_result = 0; + +#if defined(Q_CC_GNU) + asm ("push %%rbx\n" + "pushf\n" + "pop %%rax\n" + "mov %%eax, %%ebx\n" + "xor $0x00200000, %%eax\n" + "push %%rax\n" + "popf\n" + "pushf\n" + "pop %%rax\n" + "xor %%edx, %%edx\n" + "xor %%ebx, %%eax\n" + "jz 1f\n" + + "mov $0x00000001, %%eax\n" + "cpuid\n" + "1:\n" + "pop %%rbx\n" + "mov %%ecx, %0\n" + : "=r" (feature_result) + : + : "%eax", "%ecx", "%edx" + ); +#elif defined (Q_OS_WIN64) + _asm { + push rax + push rbx + push rcx + push rdx + pushfd + pop rax + mov ebx, eax + xor eax, 00200000h + push rax + popfd + pushfd + pop rax + mov edx, 0 + xor eax, ebx + jz skip + + mov eax, 1 + cpuid + mov feature_result, ecx + skip: + pop rdx + pop rcx + pop rbx + pop rax + } +#endif + + if (feature_result & (1u)) + features |= SSE3; + if (feature_result & (1u << 9)) + features |= SSSE3; + if (feature_result & (1u << 19)) + features |= SSE4_1; + if (feature_result & (1u << 20)) + features |= SSE4_2; + if (feature_result & (1u << 28)) + features |= AVX; +#endif // x86_64 + #if defined(QT_HAVE_MMX) if (qgetenv("QT_NO_MMX").toInt()) features ^= MMX; |