diff options
author | Jørgen Lind <jorgen.lind@nokia.com> | 2010-08-03 10:53:57 (GMT) |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2010-08-03 10:53:57 (GMT) |
commit | d5491ecdde14659a913c9f476f18c45f1d9489bb (patch) | |
tree | 06cc52249feda9bd9e50ca47abb8ebd676c8a309 /src/corelib/tools/qsimd.cpp | |
parent | 42cdfaf86d34afeb6448723839fef70fe477deed (diff) | |
parent | a41128af5373a0225c3548abd3eb82cd7e8f7a0e (diff) | |
download | Qt-d5491ecdde14659a913c9f476f18c45f1d9489bb.zip Qt-d5491ecdde14659a913c9f476f18c45f1d9489bb.tar.gz Qt-d5491ecdde14659a913c9f476f18c45f1d9489bb.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt into lighthouse
Conflicts:
configure
Diffstat (limited to 'src/corelib/tools/qsimd.cpp')
-rw-r--r-- | src/corelib/tools/qsimd.cpp | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 11357b3..fcc8dd7 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -46,6 +46,10 @@ #include <windows.h> #endif +#if defined(Q_OS_WIN64) && !defined(Q_CC_GNU) +#include <intrin.h> +#endif + QT_BEGIN_NAMESPACE uint qDetectCPUFeatures() @@ -96,6 +100,7 @@ uint qDetectCPUFeatures() features = MMX|SSE|SSE2; #elif defined(__i386__) || defined(_M_IX86) unsigned int extended_result = 0; + unsigned int feature_result = 0; uint result = 0; /* see p. 118 of amd64 instruction set manual Vol3 */ #if defined(Q_CC_GNU) @@ -117,7 +122,8 @@ uint qDetectCPUFeatures() "1:\n" "pop %%ebx\n" "mov %%edx, %0\n" - : "=r" (result) + "mov %%ecx, %1\n" + : "=r" (result), "=r" (feature_result) : : "%eax", "%ecx", "%edx" ); @@ -169,6 +175,7 @@ uint qDetectCPUFeatures() mov eax, 1 cpuid mov result, edx + mov feature_result, ecx skip: pop edx pop ecx @@ -223,8 +230,65 @@ uint qDetectCPUFeatures() features |= SSE; if (result & (1u << 26)) features |= SSE2; + 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 // 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) + { + int info[4]; + __cpuid(info, 1); + feature_result = info[2]; + } +#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; |