Detect SSE4.1 support for Subzero.

Bug swiftshader:20

Change-Id: I20c2ab7cb4c00c365520ff8b8500f7594127498b
Reviewed-on: https://swiftshader-review.googlesource.com/8468
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 0a78f6e..bd23e35 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -57,6 +57,34 @@
 	Ice::Fdstream *out = nullptr;
 }
 
+namespace
+{
+	class CPUID
+	{
+	public:
+		const static bool SSE4_1;
+
+	private:
+		static void cpuid(int registers[4], int info)
+		{
+			#if defined(_WIN32)
+				__cpuid(registers, info);
+			#else
+				__asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
+			#endif
+		}
+
+		static bool detectSSE4_1()
+		{
+			int registers[4];
+			cpuid(registers, 1);
+			return (registers[2] & 0x00080000) != 0;
+		}
+	};
+
+	const bool CPUID::SSE4_1 = CPUID::detectSSE4_1();
+}
+
 namespace sw
 {
 	enum EmulatedType
@@ -402,7 +430,7 @@
 		Flags.setOutFileType(Ice::FT_Elf);
 		Flags.setOptLevel(Ice::Opt_2);
 		Flags.setApplicationBinaryInterface(Ice::ABI_Platform);
-		Flags.setTargetInstructionSet(Ice::X86InstructionSet_SSE4_1);
+		Flags.setTargetInstructionSet(CPUID::SSE4_1 ? Ice::X86InstructionSet_SSE4_1 : Ice::X86InstructionSet_SSE2);
 		Flags.setVerbose(false ? Ice::IceV_All : Ice::IceV_None);
 
 		static llvm::raw_os_ostream cout(std::cout);