OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 #include "vm/globals.h" |
| 6 #if !defined(TARGET_OS_MACOS) |
| 7 #include "vm/cpuid.h" |
| 8 |
| 9 #if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64) |
| 10 // GetCpuId() on Windows, __get_cpuid() on Linux |
| 11 #if defined(TARGET_OS_WINDOWS) |
| 12 #include <intrin.h> // NOLINT |
| 13 #else |
| 14 #include <cpuid.h> // NOLINT |
| 15 #endif |
| 16 #endif |
| 17 |
| 18 namespace dart { |
| 19 |
| 20 bool CpuId::sse2_ = false; |
| 21 bool CpuId::sse41_ = false; |
| 22 const char* CpuId::id_string_ = NULL; |
| 23 const char* CpuId::brand_string_ = NULL; |
| 24 |
| 25 #if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64) |
| 26 |
| 27 void CpuId::GetCpuId(int32_t level, uint32_t info[4]) { |
| 28 #if defined(TARGET_OS_WINDOWS) |
| 29 // The documentation for __cpuid is at: |
| 30 // http://msdn.microsoft.com/en-us/library/hskdteyh(v=vs.90).aspx |
| 31 __cpuid(reinterpret_cast<int*>(info), level); |
| 32 #else |
| 33 __get_cpuid(level, &info[0], &info[1], &info[2], &info[3]); |
| 34 #endif |
| 35 } |
| 36 |
| 37 |
| 38 void CpuId::InitOnce() { |
| 39 uint32_t info[4] = {-1}; |
| 40 |
| 41 GetCpuId(0, info); |
| 42 char* id_string = new char[3 * sizeof(int32_t)]; |
| 43 // Yes, these are supposed to be out of order. |
| 44 *reinterpret_cast<uint32_t*>(id_string) = info[1]; |
| 45 *reinterpret_cast<uint32_t*>(id_string + 4) = info[3]; |
| 46 *reinterpret_cast<uint32_t*>(id_string + 8) = info[2]; |
| 47 CpuId::id_string_ = id_string; |
| 48 |
| 49 GetCpuId(1, info); |
| 50 CpuId::sse41_ = (info[2] & (1 << 19)) != 0; |
| 51 CpuId::sse2_ = (info[3] & (1 << 26)) != 0; |
| 52 |
| 53 char* brand_string = new char[3 * 4 * sizeof(uint32_t)]; |
| 54 for (uint32_t i = 0x80000002; i <= 0x80000004; i++) { |
| 55 uint32_t off = (i - 0x80000002U) * 4 * sizeof(uint32_t); |
| 56 GetCpuId(i, info); |
| 57 *reinterpret_cast<int32_t*>(brand_string + off) = info[0]; |
| 58 *reinterpret_cast<int32_t*>(brand_string + off + 4) = info[1]; |
| 59 *reinterpret_cast<int32_t*>(brand_string + off + 8) = info[2]; |
| 60 *reinterpret_cast<int32_t*>(brand_string + off + 12) = info[3]; |
| 61 } |
| 62 CpuId::brand_string_ = brand_string; |
| 63 } |
| 64 |
| 65 |
| 66 void CpuId::Cleanup() { |
| 67 ASSERT(id_string_ != NULL); |
| 68 delete[] id_string_; |
| 69 id_string_ = NULL; |
| 70 |
| 71 ASSERT(brand_string_ != NULL); |
| 72 delete[] brand_string_; |
| 73 brand_string_ = NULL; |
| 74 } |
| 75 |
| 76 |
| 77 const char* CpuId::id_string() { |
| 78 return strdup(id_string_); |
| 79 } |
| 80 |
| 81 |
| 82 const char* CpuId::brand_string() { |
| 83 return strdup(brand_string_); |
| 84 } |
| 85 |
| 86 |
| 87 const char* CpuId::field(CpuInfoIndices idx) { |
| 88 switch (idx) { |
| 89 case kCpuInfoProcessor: |
| 90 return id_string(); |
| 91 case kCpuInfoModel: |
| 92 return brand_string(); |
| 93 case kCpuInfoHardware: |
| 94 return brand_string(); |
| 95 case kCpuInfoFeatures: { |
| 96 if (sse2() && sse41()) { |
| 97 return strdup("sse2 sse4.1"); |
| 98 } else if (sse2()) { |
| 99 return strdup("sse2"); |
| 100 } else if (sse41()) { |
| 101 return strdup("sse4.1"); |
| 102 } else { |
| 103 return strdup(""); |
| 104 } |
| 105 } |
| 106 default: { |
| 107 UNREACHABLE(); |
| 108 return NULL; |
| 109 } |
| 110 } |
| 111 } |
| 112 |
| 113 #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) |
| 114 } // namespace dart |
| 115 |
| 116 #endif // !defined(TARGET_OS_MACOS) |
OLD | NEW |