From 9aec4229d509fc2247319ca3be5ba56656cf94ad Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Sat, 28 Nov 2015 23:39:06 +0100 Subject: [PATCH] x86emitter: support AVX2 (linux only?) Nah kidding, it is only the cpu detection for the log x86 Features Detected: SSE2.. SSE3.. SSSE3.. SSE4.1.. SSE4.2.. AVX.. AVX2.. FMA --- common/include/intrin_x86.h | 3 ++- common/include/x86emitter/tools.h | 2 ++ common/src/x86emitter/cpudetect.cpp | 9 +++++++++ pcsx2/System.cpp | 1 + 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/common/include/intrin_x86.h b/common/include/intrin_x86.h index 2755b2878c..076ae49dfb 100644 --- a/common/include/intrin_x86.h +++ b/common/include/intrin_x86.h @@ -96,7 +96,8 @@ static __inline__ __attribute__((always_inline)) s32 _InterlockedIncrement(volat /*** System information ***/ static __inline__ __attribute__((always_inline)) void __cpuid(int CPUInfo[], const int InfoType) { - __asm__ __volatile__("cpuid" : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "a" (InfoType)); + // ECX allow to select the leaf. Leaf 0 is the one that you want to get, so I just xor the register + __asm__ __volatile__("xor %%ecx, %%ecx\n" "cpuid": "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "a" (InfoType)); } static __inline__ __attribute__((always_inline)) unsigned long long __xgetbv(unsigned int index) diff --git a/common/include/x86emitter/tools.h b/common/include/x86emitter/tools.h index fcbe84a2d6..0ab33fa76c 100644 --- a/common/include/x86emitter/tools.h +++ b/common/include/x86emitter/tools.h @@ -44,6 +44,7 @@ public: u32 Flags2; // More Feature Flags u32 EFlags; // Extended Feature Flags u32 EFlags2; // Extended Feature Flags pg2 + u32 SEFlag; // Structured Extended Feature Flags Enumeration char VendorName[16]; // Vendor/Creator ID char FamilyName[50]; // the original cpu name @@ -88,6 +89,7 @@ public: u32 hasStreamingSIMD4Extensions :1; u32 hasStreamingSIMD4Extensions2 :1; u32 hasAVX :1; + u32 hasAVX2 :1; u32 hasFMA :1; // AMD-specific CPU Features diff --git a/common/src/x86emitter/cpudetect.cpp b/common/src/x86emitter/cpudetect.cpp index 0e58986660..f6140a6675 100644 --- a/common/src/x86emitter/cpudetect.cpp +++ b/common/src/x86emitter/cpudetect.cpp @@ -208,6 +208,14 @@ void x86capabilities::Identify() Flags2 = regs[ 2 ]; } + if ( cmds >= 0x00000007 ) + { + // Note: ECX must be 0. I did it directly in the __cpuid asm instrinsic + __cpuid( regs, 0x00000007 ); + + SEFlag = regs[ 1 ]; + } + __cpuid( regs, 0x80000000 ); cmds = regs[ 0 ]; if ( cmds >= 0x80000001 ) @@ -271,6 +279,7 @@ void x86capabilities::Identify() { hasAVX = ( Flags2 >> 28 ) & 1; //avx hasFMA = ( Flags2 >> 12 ) & 1; //fma + hasAVX2 = ( SEFlag >> 5 ) & 1; //avx2 } } diff --git a/pcsx2/System.cpp b/pcsx2/System.cpp index 96a6df6dea..277312c90c 100644 --- a/pcsx2/System.cpp +++ b/pcsx2/System.cpp @@ -267,6 +267,7 @@ void SysLogMachineCaps() if( x86caps.hasStreamingSIMD4Extensions ) features[0].Add( L"SSE4.1" ); if( x86caps.hasStreamingSIMD4Extensions2 ) features[0].Add( L"SSE4.2" ); if( x86caps.hasAVX ) features[0].Add( L"AVX" ); + if( x86caps.hasAVX2 ) features[0].Add( L"AVX2" ); if( x86caps.hasFMA) features[0].Add( L"FMA" ); if( x86caps.hasMultimediaExtensionsExt ) features[1].Add( L"MMX2 " );