Support issuing extended CPUID instructions

Information 'leaf' 7, indicated by the EAX register before issuing the
CPUID instruction, also takes a 'sub-leaf' parameter through ECX.

https://en.wikipedia.org/wiki/CPUID#Calling_CPUID
https://docs.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-170

Bug: b/214591655
Change-Id: I3682e35c67428e9fde87020824c8ba6dda66bcb8
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/62069
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Reactor/CPUID.cpp b/src/Reactor/CPUID.cpp
index dfd53ae..1dee743 100644
--- a/src/Reactor/CPUID.cpp
+++ b/src/Reactor/CPUID.cpp
@@ -29,29 +29,29 @@
 
 namespace rr {
 
-static void cpuid(int registers[4], int info)
+static void cpuid(int eax_ebx_ecx_edx[4], int eax, int ecx = 0)
 {
 #if defined(__i386__) || defined(__x86_64__)
 #	if defined(_WIN32)
-	__cpuid(registers, info);
+	__cpuidex(eax_ebx_ecx_edx, eax, ecx);
 #	else
 	__asm volatile("cpuid"
-	               : "=a"(registers[0]), "=b"(registers[1]), "=c"(registers[2]), "=d"(registers[3])
-	               : "a"(info));
+	               : "=a"(eax_ebx_ecx_edx[0]), "=b"(eax_ebx_ecx_edx[1]), "=c"(eax_ebx_ecx_edx[2]), "=d"(eax_ebx_ecx_edx[3])
+	               : "a"(eax), "c"(ecx));
 #	endif
 #else
-	registers[0] = 0;
-	registers[1] = 0;
-	registers[2] = 0;
-	registers[3] = 0;
+	eax_ebx_ecx_edx[0] = 0;
+	eax_ebx_ecx_edx[1] = 0;
+	eax_ebx_ecx_edx[2] = 0;
+	eax_ebx_ecx_edx[3] = 0;
 #endif
 }
 
 bool CPUID::supportsSSE4_1()
 {
-	int registers[4];
-	cpuid(registers, 1);
-	return (registers[2] & 0x00080000) != 0;
+	int eax_ebx_ecx_edx[4];
+	cpuid(eax_ebx_ecx_edx, 1);
+	return (eax_ebx_ecx_edx[2] & 0x00080000) != 0;
 }
 
 }  // namespace rr