Index: runtime/vm/cpu_ia32.cc |
=================================================================== |
--- runtime/vm/cpu_ia32.cc (revision 31402) |
+++ runtime/vm/cpu_ia32.cc (working copy) |
@@ -3,18 +3,21 @@ |
// BSD-style license that can be found in the LICENSE file. |
#include "vm/globals.h" |
- |
#if defined(TARGET_ARCH_IA32) |
#include "vm/cpu.h" |
+#include "vm/assembler.h" |
#include "vm/constants_ia32.h" |
+#include "vm/cpuinfo.h" |
#include "vm/heap.h" |
#include "vm/isolate.h" |
#include "vm/object.h" |
namespace dart { |
+DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available"); |
+ |
void CPU::FlushICache(uword start, uword size) { |
// Nothing to be done here. |
} |
@@ -24,6 +27,69 @@ |
return "ia32"; |
} |
+ |
+bool CPUFeatures::sse2_supported_ = false; |
+bool CPUFeatures::sse4_1_supported_ = false; |
+char CPUFeatures::hardware_[HARDWARE_LEN] = {0}; |
+#ifdef DEBUG |
+bool CPUFeatures::initialized_ = false; |
+#endif |
+ |
+ |
+bool CPUFeatures::sse2_supported() { |
+ DEBUG_ASSERT(initialized_); |
+ return sse2_supported_; |
+} |
+ |
+ |
+bool CPUFeatures::sse4_1_supported() { |
+ DEBUG_ASSERT(initialized_); |
+ return sse4_1_supported_ && FLAG_use_sse41; |
+} |
+ |
+ |
+char* CPUFeatures::hardware() { |
+ DEBUG_ASSERT(initialized_); |
+ return hardware_; |
+} |
+ |
+ |
+#define __ assembler. |
+ |
+void CPUFeatures::InitOnce() { |
+ Assembler assembler; |
+ __ pushl(EBP); |
+ __ pushl(EBX); |
+ __ movl(EBP, ESP); |
+ // Get feature information in ECX:EDX and return it in EDX:EAX. |
+ __ movl(EAX, Immediate(1)); |
+ __ cpuid(); |
+ __ movl(EAX, EDX); |
+ __ movl(EDX, ECX); |
+ __ movl(ESP, EBP); |
+ __ popl(EBX); |
+ __ popl(EBP); |
+ __ ret(); |
+ |
+ const Code& code = |
+ Code::Handle(Code::FinalizeCode("DetectCPUFeatures", &assembler)); |
+ Instructions& instructions = Instructions::Handle(code.instructions()); |
+ typedef uint64_t (*DetectCPUFeatures)(); |
+ uint64_t features = |
+ reinterpret_cast<DetectCPUFeatures>(instructions.EntryPoint())(); |
+ sse2_supported_ = (features & kSSE2BitMask) != 0; |
+ sse4_1_supported_ = (features & kSSE4_1BitMask) != 0; |
+ |
+ CpuInfo::Read(); |
+ CpuInfo::GetCpuModel(hardware_, HARDWARE_LEN); |
+ |
+#ifdef DEBUG |
+ initialized_ = true; |
+#endif |
+} |
+ |
+#undef __ |
+ |
} // namespace dart |
#endif // defined TARGET_ARCH_IA32 |