Add AVX2 and FMA support detection
The AVX2 feature bit corresponds to bit 5 of the EBX register after
issuing the CPUID instruction with EAX=7,ECX=0. This extended CPUID
functionality is in turn supported if AVX is supported, which is
indicated by bit 28 of ECX for CPUID issues with EAX=1.
We also check for OSXSAVE and FMA support as part of AVX2.
[0] https://en.wikipedia.org/wiki/CPUID#EAX=1:_Processor_Info_and_Feature_Bits
[1] https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features
Bug: b/214591655
Change-Id: Ia16d8d99bd8be7e33d6f823475b5b3951b5d23f9
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/62070
Reviewed-by: Alexis Hétu <sugoi@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Reactor/CPUID.cpp b/src/Reactor/CPUID.cpp
index 1dee743..b8a67cf 100644
--- a/src/Reactor/CPUID.cpp
+++ b/src/Reactor/CPUID.cpp
@@ -54,4 +54,23 @@
return (eax_ebx_ecx_edx[2] & 0x00080000) != 0;
}
+bool CPUID::supportsAVX2()
+{
+ int eax_ebx_ecx_edx[4];
+ cpuid(eax_ebx_ecx_edx, 1);
+ // Test bits 12 (FMA), 27 (OSXSAVE), and 28 (AVX) of ECX
+ bool osxsave_avx_fma = (eax_ebx_ecx_edx[2] & 0x18001000) == 0x18001000;
+
+ // AVX is a prerequisite of AVX2 and must be checked for first according to the Intel Software Developer's Manual.
+ // OSXSAVE ensures the operating system can save/restore ymm registers on context switches.
+ // FMA support is often considered an integral part of AVX2.
+ if(!osxsave_avx_fma)
+ {
+ return false;
+ }
+
+ cpuid(eax_ebx_ecx_edx, 7, 0); // Valid if AVX is supported
+ return (eax_ebx_ecx_edx[1] & 0x00000020) != 0;
+}
+
} // namespace rr
diff --git a/src/Reactor/CPUID.hpp b/src/Reactor/CPUID.hpp
index 8a5e342..931b730 100644
--- a/src/Reactor/CPUID.hpp
+++ b/src/Reactor/CPUID.hpp
@@ -29,6 +29,7 @@
{
public:
static bool supportsSSE4_1();
+ static bool supportsAVX2(); // Also ensures support for OSXSAVE and FMA
};
} // namespace rr