OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012, 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_WINDOWS) |
| 7 |
| 8 #include "vm/cpuinfo.h" |
| 9 |
| 10 // __cpuid() |
| 11 #include <intrin.h> // NOLINT |
| 12 #include <string.h> // NOLINT |
| 13 |
| 14 #include "platform/assert.h" |
| 15 |
| 16 namespace dart { |
| 17 |
| 18 struct CpuIdData { |
| 19 static bool sse2; |
| 20 static bool sse41; |
| 21 static char* id_string; |
| 22 static char* brand_string; |
| 23 }; |
| 24 |
| 25 |
| 26 char* CpuInfo::data_ = NULL; |
| 27 intptr_t CpuInfo::datalen_ = 0; |
| 28 bool CpuIdData::sse2 = false; |
| 29 bool CpuIdData::sse41 = false; |
| 30 char* CpuIdData::id_string = NULL; |
| 31 char* CpuIdData::brand_string = NULL; |
| 32 |
| 33 |
| 34 // The documentation for __cpuid is at: |
| 35 // http://msdn.microsoft.com/en-us/library/hskdteyh(v=vs.90).aspx |
| 36 // InitOnce reads and caches __cpuid results for use by CpuInfo. |
| 37 void CpuInfo::InitOnce() { |
| 38 int32_t info[4] = {-1}; |
| 39 |
| 40 InitializeFields(); |
| 41 |
| 42 __cpuid(info, 0); |
| 43 char *id_string = new char[3 * sizeof(int32_t)]; |
| 44 // Yes, these are supposed to be out of order. |
| 45 *reinterpret_cast<int32_t*>(id_string) = info[1]; |
| 46 *reinterpret_cast<int32_t*>(id_string + 4) = info[3]; |
| 47 *reinterpret_cast<int32_t*>(id_string + 8) = info[2]; |
| 48 CpuIdData::id_string = id_string; |
| 49 |
| 50 __cpuid(info, 1); |
| 51 CpuIdData::sse41 = (info[2] & (1 << 19)) != 0; |
| 52 CpuIdData::sse2 = (info[3] & (1 << 26)) != 0; |
| 53 |
| 54 char* brand_string = new char[3 * 4 * sizeof(int32_t)]; |
| 55 for (intptr_t i = 0x80000002; i <= 0x80000004; i++) { |
| 56 intptr_t off = (i - 0x80000002) * 4 * sizeof(int32_t); |
| 57 __cpuid(info, i); |
| 58 *reinterpret_cast<int32_t*>(brand_string + off) = info[0]; |
| 59 *reinterpret_cast<int32_t*>(brand_string + off + 4) = info[1]; |
| 60 *reinterpret_cast<int32_t*>(brand_string + off + 8) = info[2]; |
| 61 *reinterpret_cast<int32_t*>(brand_string + off + 12) = info[3]; |
| 62 } |
| 63 CpuIdData::brand_string = brand_string; |
| 64 } |
| 65 |
| 66 |
| 67 bool CpuInfo::FieldContains(const char* field, const char* search_string) { |
| 68 if (strcmp(field, fields_[kCpuInfoProcessor]) == 0) { |
| 69 return strstr(CpuIdData::id_string, search_string); |
| 70 } else if (strcmp(field, fields_[kCpuInfoModel]) == 0) { |
| 71 return strstr(CpuIdData::brand_string, search_string); |
| 72 } else if (strcmp(field, fields_[kCpuInfoFeatures]) == 0) { |
| 73 if (strcmp(search_string, "sse2") == 0) { |
| 74 return CpuIdData::sse2; |
| 75 } else if (strcmp(search_string, "sse4.1") == 0) { |
| 76 return CpuIdData::sse41; |
| 77 } else { |
| 78 return false; |
| 79 } |
| 80 } else { |
| 81 UNIMPLEMENTED(); |
| 82 } |
| 83 return false; |
| 84 } |
| 85 |
| 86 |
| 87 char* CpuInfo::ExtractField(const char* field) { |
| 88 if (strcmp(field, fields_[kCpuInfoProcessor]) == 0) { |
| 89 return CpuIdData::id_string; |
| 90 } else if (strcmp(field, fields_[kCpuInfoModel]) == 0) { |
| 91 return CpuIdData::brand_string; |
| 92 } else { |
| 93 UNIMPLEMENTED(); |
| 94 } |
| 95 return NULL; |
| 96 } |
| 97 |
| 98 |
| 99 bool CpuInfo::HasField(const char* field) { |
| 100 return (strcmp(field, fields_[kCpuInfoProcessor]) == 0) || |
| 101 (strcmp(field, fields_[kCpuInfoModel]) == 0) || |
| 102 (strcmp(field, fields_[kCpuInfoFeatures]) == 0); |
| 103 } |
| 104 |
| 105 |
| 106 const char* CpuInfo::fields_[kCpuInfoMax] = {0}; |
| 107 void CpuInfo::InitializeFields() { |
| 108 fields_[kCpuInfoProcessor] = "Processor"; |
| 109 fields_[kCpuInfoModel] = "Hardware"; |
| 110 fields_[kCpuInfoFeatures] = "Features"; |
| 111 } |
| 112 |
| 113 } // namespace dart |
| 114 |
| 115 #endif // defined(TARGET_OS_WINDOWS) |
OLD | NEW |