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 |