| Index: source/cpu_id.cc
|
| diff --git a/source/cpu_id.cc b/source/cpu_id.cc
|
| index 2fdb82ab0e3bd6ccaeb3e7461e7a86cd0c3f4329..163da1014e4c13a66d25f5ef1fd15f304459d0b2 100644
|
| --- a/source/cpu_id.cc
|
| +++ b/source/cpu_id.cc
|
| @@ -48,7 +48,7 @@ extern "C" {
|
| !defined(__pnacl__) && !defined(__CLR_VER)
|
| LIBYUV_API
|
| void CpuId(uint32 info_eax, uint32 info_ecx, uint32* cpu_info) {
|
| -#if (defined(_MSC_VER) && !defined(__clang__)) && !defined(__clang__)
|
| +#if defined(_MSC_VER) && !defined(__clang__)
|
| // Visual C version uses intrinsic or inline x86 assembly.
|
| #if (_MSC_FULL_VER >= 160040219)
|
| __cpuidex((int*)(cpu_info), info_eax, info_ecx);
|
| @@ -63,7 +63,7 @@ void CpuId(uint32 info_eax, uint32 info_ecx, uint32* cpu_info) {
|
| mov [edi + 8], ecx
|
| mov [edi + 12], edx
|
| }
|
| -#else
|
| +#else // Visual C but not x86
|
| if (info_ecx == 0) {
|
| __cpuid((int*)(cpu_info), info_eax);
|
| } else {
|
| @@ -71,7 +71,7 @@ void CpuId(uint32 info_eax, uint32 info_ecx, uint32* cpu_info) {
|
| }
|
| #endif
|
| // GCC version uses inline x86 assembly.
|
| -#else // (defined(_MSC_VER) && !defined(__clang__)) && !defined(__clang__)
|
| +#else // defined(_MSC_VER) && !defined(__clang__)
|
| uint32 info_ebx, info_edx;
|
| asm volatile (
|
| #if defined( __i386__) && defined(__PIC__)
|
| @@ -89,7 +89,7 @@ void CpuId(uint32 info_eax, uint32 info_ecx, uint32* cpu_info) {
|
| cpu_info[1] = info_ebx;
|
| cpu_info[2] = info_ecx;
|
| cpu_info[3] = info_edx;
|
| -#endif // (defined(_MSC_VER) && !defined(__clang__)) && !defined(__clang__)
|
| +#endif // defined(_MSC_VER) && !defined(__clang__)
|
| }
|
| #else // (defined(_M_IX86) || defined(_M_X64) ...
|
| LIBYUV_API
|
| @@ -98,7 +98,18 @@ void CpuId(uint32 eax, uint32 ecx, uint32* cpu_info) {
|
| }
|
| #endif
|
|
|
| -// TODO(fbarchard): Enable xgetbv when validator supports it.
|
| +// For VS2010 and earlier emit can be used:
|
| +// _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0 // For VS2010 and earlier.
|
| +// __asm {
|
| +// xor ecx, ecx // xcr 0
|
| +// xgetbv
|
| +// mov xcr0, eax
|
| +// }
|
| +// For VS2013 and earlier 32 bit, the _xgetbv(0) optimizer produces bad code.
|
| +// https://code.google.com/p/libyuv/issues/detail?id=529
|
| +#if defined(_M_IX86) && (_MSC_VER < 1900)
|
| +#pragma optimize("g", off)
|
| +#endif
|
| #if (defined(_M_IX86) || defined(_M_X64) || \
|
| defined(__i386__) || defined(__x86_64__)) && \
|
| !defined(__pnacl__) && !defined(__CLR_VER) && !defined(__native_client__)
|
| @@ -106,20 +117,19 @@ void CpuId(uint32 eax, uint32 ecx, uint32* cpu_info) {
|
| // X86 CPUs have xgetbv to detect OS saves high parts of ymm registers.
|
| int GetXCR0() {
|
| uint32 xcr0 = 0u;
|
| -#if (defined(_MSC_VER) && !defined(__clang__)) && (_MSC_FULL_VER >= 160040219)
|
| +#if (_MSC_FULL_VER >= 160040219)
|
| xcr0 = (uint32)(_xgetbv(0)); // VS2010 SP1 required.
|
| -#elif defined(_M_IX86) && defined(_MSC_VER) && !defined(__clang__)
|
| - __asm {
|
| - xor ecx, ecx // xcr 0
|
| - _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0 // For VS2010 and earlier.
|
| - mov xcr0, eax
|
| - }
|
| #elif defined(__i386__) || defined(__x86_64__)
|
| + uint32 xcr0 = 0u;
|
| asm(".byte 0x0f, 0x01, 0xd0" : "=a" (xcr0) : "c" (0) : "%edx");
|
| #endif // defined(__i386__) || defined(__x86_64__)
|
| return xcr0;
|
| }
|
| #endif // defined(_M_IX86) || defined(_M_X64) ..
|
| +// Return optimization to previous setting.
|
| +#if defined(_M_IX86) && (_MSC_VER < 1900)
|
| +#pragma optimize("g", on)
|
| +#endif
|
|
|
| // based on libvpx arm_cpudetect.c
|
| // For Arm, but public to allow testing on any CPU
|
|
|