Index: runtime/vm/cpuid.cc |
=================================================================== |
--- runtime/vm/cpuid.cc (revision 0) |
+++ runtime/vm/cpuid.cc (revision 0) |
@@ -0,0 +1,116 @@ |
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+#include "vm/globals.h" |
+#if !defined(TARGET_OS_MACOS) |
+#include "vm/cpuid.h" |
+ |
+#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64) |
+// GetCpuId() on Windows, __get_cpuid() on Linux |
+#if defined(TARGET_OS_WINDOWS) |
+#include <intrin.h> // NOLINT |
+#else |
+#include <cpuid.h> // NOLINT |
+#endif |
+#endif |
+ |
+namespace dart { |
+ |
+bool CpuId::sse2_ = false; |
+bool CpuId::sse41_ = false; |
+const char* CpuId::id_string_ = NULL; |
+const char* CpuId::brand_string_ = NULL; |
+ |
+#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64) |
+ |
+void CpuId::GetCpuId(int32_t level, uint32_t info[4]) { |
+#if defined(TARGET_OS_WINDOWS) |
+ // The documentation for __cpuid is at: |
+ // http://msdn.microsoft.com/en-us/library/hskdteyh(v=vs.90).aspx |
+ __cpuid(reinterpret_cast<int*>(info), level); |
+#else |
+ __get_cpuid(level, &info[0], &info[1], &info[2], &info[3]); |
+#endif |
+} |
+ |
+ |
+void CpuId::InitOnce() { |
+ uint32_t info[4] = {-1}; |
+ |
+ GetCpuId(0, info); |
+ char* id_string = new char[3 * sizeof(int32_t)]; |
+ // Yes, these are supposed to be out of order. |
+ *reinterpret_cast<uint32_t*>(id_string) = info[1]; |
+ *reinterpret_cast<uint32_t*>(id_string + 4) = info[3]; |
+ *reinterpret_cast<uint32_t*>(id_string + 8) = info[2]; |
+ CpuId::id_string_ = id_string; |
+ |
+ GetCpuId(1, info); |
+ CpuId::sse41_ = (info[2] & (1 << 19)) != 0; |
+ CpuId::sse2_ = (info[3] & (1 << 26)) != 0; |
+ |
+ char* brand_string = new char[3 * 4 * sizeof(uint32_t)]; |
+ for (uint32_t i = 0x80000002; i <= 0x80000004; i++) { |
+ uint32_t off = (i - 0x80000002U) * 4 * sizeof(uint32_t); |
+ GetCpuId(i, info); |
+ *reinterpret_cast<int32_t*>(brand_string + off) = info[0]; |
+ *reinterpret_cast<int32_t*>(brand_string + off + 4) = info[1]; |
+ *reinterpret_cast<int32_t*>(brand_string + off + 8) = info[2]; |
+ *reinterpret_cast<int32_t*>(brand_string + off + 12) = info[3]; |
+ } |
+ CpuId::brand_string_ = brand_string; |
+} |
+ |
+ |
+void CpuId::Cleanup() { |
+ ASSERT(id_string_ != NULL); |
+ delete[] id_string_; |
+ id_string_ = NULL; |
+ |
+ ASSERT(brand_string_ != NULL); |
+ delete[] brand_string_; |
+ brand_string_ = NULL; |
+} |
+ |
+ |
+const char* CpuId::id_string() { |
+ return strdup(id_string_); |
+} |
+ |
+ |
+const char* CpuId::brand_string() { |
+ return strdup(brand_string_); |
+} |
+ |
+ |
+const char* CpuId::field(CpuInfoIndices idx) { |
+ switch (idx) { |
+ case kCpuInfoProcessor: |
+ return id_string(); |
+ case kCpuInfoModel: |
+ return brand_string(); |
+ case kCpuInfoHardware: |
+ return brand_string(); |
+ case kCpuInfoFeatures: { |
+ if (sse2() && sse41()) { |
+ return strdup("sse2 sse4.1"); |
+ } else if (sse2()) { |
+ return strdup("sse2"); |
+ } else if (sse41()) { |
+ return strdup("sse4.1"); |
+ } else { |
+ return strdup(""); |
+ } |
+ } |
+ default: { |
+ UNREACHABLE(); |
+ return NULL; |
+ } |
+ } |
+} |
+ |
+#endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) |
+} // namespace dart |
+ |
+#endif // !defined(TARGET_OS_MACOS) |