1 // Copyright 2017 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "cpuinfo_x86.h"
16
17 #include <cassert>
18 #include <cstdio>
19 #include <map>
20 #include <set>
21 #if defined(CPU_FEATURES_OS_WINDOWS)
22 #include "internal/windows_utils.h"
23 #endif // CPU_FEATURES_OS_WINDOWS
24
25 #include "filesystem_for_testing.h"
26 #include "gtest/gtest.h"
27 #include "internal/cpuid_x86.h"
28
29 namespace cpu_features {
30
31 class FakeCpu {
32 public:
GetCpuidLeaf(uint32_t leaf_id,int ecx) const33 Leaf GetCpuidLeaf(uint32_t leaf_id, int ecx) const {
34 const auto itr = cpuid_leaves_.find(std::make_pair(leaf_id, ecx));
35 if (itr != cpuid_leaves_.end()) {
36 return itr->second;
37 }
38 return {0, 0, 0, 0};
39 }
40
GetXCR0Eax() const41 uint32_t GetXCR0Eax() const { return xcr0_eax_; }
42
SetLeaves(std::map<std::pair<uint32_t,int>,Leaf> configuration)43 void SetLeaves(std::map<std::pair<uint32_t, int>, Leaf> configuration) {
44 cpuid_leaves_ = std::move(configuration);
45 }
46
SetOsBackupsExtendedRegisters(bool os_backups_extended_registers)47 void SetOsBackupsExtendedRegisters(bool os_backups_extended_registers) {
48 xcr0_eax_ = os_backups_extended_registers ? -1 : 0;
49 }
50
51 #if defined(CPU_FEATURES_OS_MACOS)
GetDarwinSysCtlByName(std::string name) const52 bool GetDarwinSysCtlByName(std::string name) const {
53 return darwin_sysctlbyname_.count(name);
54 }
55
SetDarwinSysCtlByName(std::string name)56 void SetDarwinSysCtlByName(std::string name) {
57 darwin_sysctlbyname_.insert(name);
58 }
59 #endif // CPU_FEATURES_OS_MACOS
60
61 #if defined(CPU_FEATURES_OS_WINDOWS)
GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)62 bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) {
63 return windows_isprocessorfeaturepresent_.count(ProcessorFeature);
64 }
65
SetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)66 void SetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) {
67 windows_isprocessorfeaturepresent_.insert(ProcessorFeature);
68 }
69 #endif // CPU_FEATURES_OS_WINDOWS
70
71 private:
72 std::map<std::pair<uint32_t, int>, Leaf> cpuid_leaves_;
73 #if defined(CPU_FEATURES_OS_MACOS)
74 std::set<std::string> darwin_sysctlbyname_;
75 #endif // CPU_FEATURES_OS_MACOS
76 #if defined(CPU_FEATURES_OS_WINDOWS)
77 std::set<DWORD> windows_isprocessorfeaturepresent_;
78 #endif // CPU_FEATURES_OS_WINDOWS
79 uint32_t xcr0_eax_;
80 };
81
82 static FakeCpu* g_fake_cpu_instance = nullptr;
83
cpu()84 static FakeCpu& cpu() {
85 assert(g_fake_cpu_instance != nullptr);
86 return *g_fake_cpu_instance;
87 }
88
GetCpuidLeaf(uint32_t leaf_id,int ecx)89 extern "C" Leaf GetCpuidLeaf(uint32_t leaf_id, int ecx) {
90 return cpu().GetCpuidLeaf(leaf_id, ecx);
91 }
92
GetXCR0Eax(void)93 extern "C" uint32_t GetXCR0Eax(void) { return cpu().GetXCR0Eax(); }
94
95 #if defined(CPU_FEATURES_OS_MACOS)
GetDarwinSysCtlByName(const char * name)96 extern "C" bool GetDarwinSysCtlByName(const char* name) {
97 return cpu().GetDarwinSysCtlByName(name);
98 }
99 #endif // CPU_FEATURES_OS_MACOS
100
101 #if defined(CPU_FEATURES_OS_WINDOWS)
GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)102 extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) {
103 return cpu().GetWindowsIsProcessorFeaturePresent(ProcessorFeature);
104 }
105 #endif // CPU_FEATURES_OS_WINDOWS
106
107 namespace {
108
109 class CpuidX86Test : public ::testing::Test {
110 protected:
SetUp()111 void SetUp() override {
112 assert(g_fake_cpu_instance == nullptr);
113 g_fake_cpu_instance = new FakeCpu();
114 }
TearDown()115 void TearDown() override {
116 delete g_fake_cpu_instance;
117 g_fake_cpu_instance = nullptr;
118 }
119 };
120
TEST_F(CpuidX86Test,X86MicroarchitectureEnum)121 TEST_F(CpuidX86Test, X86MicroarchitectureEnum) {
122 const char *last_name = GetX86MicroarchitectureName(X86_MICROARCHITECTURE_LAST_);
123 EXPECT_STREQ(last_name, "unknown microarchitecture");
124 for (int i = static_cast<int>(X86_UNKNOWN); i != static_cast<int>(X86_MICROARCHITECTURE_LAST_); ++i) {
125 const auto micro = static_cast<X86Microarchitecture>(i);
126 const char *name = GetX86MicroarchitectureName(micro);
127 ASSERT_FALSE(name == nullptr);
128 EXPECT_STRNE(name, "");
129 EXPECT_STRNE(name, last_name);
130 }
131 }
132
TEST_F(CpuidX86Test,X86FeaturesEnum)133 TEST_F(CpuidX86Test, X86FeaturesEnum) {
134 const char *last_name = GetX86FeaturesEnumName(X86_LAST_);
135 EXPECT_STREQ(last_name, "unknown_feature");
136 for (int i = static_cast<int>(X86_FPU); i != static_cast<int>(X86_LAST_); ++i) {
137 const auto feature = static_cast<X86FeaturesEnum>(i);
138 const char *name = GetX86FeaturesEnumName(feature);
139 ASSERT_FALSE(name == nullptr);
140 EXPECT_STRNE(name, "");
141 EXPECT_STRNE(name, last_name);
142 }
143 }
144
TEST_F(CpuidX86Test,SandyBridge)145 TEST_F(CpuidX86Test, SandyBridge) {
146 cpu().SetOsBackupsExtendedRegisters(true);
147 cpu().SetLeaves({
148 {{0x00000000, 0}, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}},
149 {{0x00000001, 0}, Leaf{0x000206A6, 0x00100800, 0x1F9AE3BF, 0xBFEBFBFF}},
150 {{0x00000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
151 });
152 const auto info = GetX86Info();
153 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
154 EXPECT_EQ(info.family, 0x06);
155 EXPECT_EQ(info.model, 0x02A);
156 EXPECT_EQ(info.stepping, 0x06);
157 // Leaf 7 is zeroed out so none of the Leaf 7 flags are set.
158 const auto features = info.features;
159 EXPECT_FALSE(features.erms);
160 EXPECT_FALSE(features.avx2);
161 EXPECT_FALSE(features.avx512f);
162 EXPECT_FALSE(features.avx512cd);
163 EXPECT_FALSE(features.avx512er);
164 EXPECT_FALSE(features.avx512pf);
165 EXPECT_FALSE(features.avx512bw);
166 EXPECT_FALSE(features.avx512dq);
167 EXPECT_FALSE(features.avx512vl);
168 EXPECT_FALSE(features.avx512ifma);
169 EXPECT_FALSE(features.avx512vbmi);
170 EXPECT_FALSE(features.avx512vbmi2);
171 EXPECT_FALSE(features.avx512vnni);
172 EXPECT_FALSE(features.avx512bitalg);
173 EXPECT_FALSE(features.avx512vpopcntdq);
174 EXPECT_FALSE(features.avx512_4vnniw);
175 EXPECT_FALSE(features.avx512_4fmaps);
176 // All old cpu features should be set.
177 EXPECT_TRUE(features.aes);
178 EXPECT_TRUE(features.ssse3);
179 EXPECT_TRUE(features.sse4_1);
180 EXPECT_TRUE(features.sse4_2);
181 EXPECT_TRUE(features.avx);
182 EXPECT_FALSE(features.sha);
183 EXPECT_TRUE(features.popcnt);
184 EXPECT_FALSE(features.movbe);
185 EXPECT_FALSE(features.rdrnd);
186 EXPECT_FALSE(features.adx);
187 EXPECT_FALSE(features.lam);
188 EXPECT_FALSE(features.uai);
189 }
190
191 const int UNDEF = -1;
192 const int KiB = 1024;
193 const int MiB = 1024 * KiB;
194
TEST_F(CpuidX86Test,SandyBridgeTestOsSupport)195 TEST_F(CpuidX86Test, SandyBridgeTestOsSupport) {
196 cpu().SetLeaves({
197 {{0x00000000, 0}, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}},
198 {{0x00000001, 0}, Leaf{0x000206A6, 0x00100800, 0x1F9AE3BF, 0xBFEBFBFF}},
199 {{0x00000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
200 });
201 // avx is disabled if os does not support backing up ymm registers.
202 cpu().SetOsBackupsExtendedRegisters(false);
203 EXPECT_FALSE(GetX86Info().features.avx);
204 // avx is disabled if os does not support backing up ymm registers.
205 cpu().SetOsBackupsExtendedRegisters(true);
206 EXPECT_TRUE(GetX86Info().features.avx);
207 }
208
TEST_F(CpuidX86Test,SkyLake)209 TEST_F(CpuidX86Test, SkyLake) {
210 cpu().SetOsBackupsExtendedRegisters(true);
211 cpu().SetLeaves({
212 {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
213 {{0x00000001, 0}, Leaf{0x000406E3, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
214 {{0x00000007, 0}, Leaf{0x00000000, 0x029C67AF, 0x00000000, 0x00000000}},
215 });
216 const auto info = GetX86Info();
217 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
218 EXPECT_EQ(info.family, 0x06);
219 EXPECT_EQ(info.model, 0x04E);
220 EXPECT_EQ(info.stepping, 0x03);
221 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_SKL);
222 }
223
224 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel0050654_SkylakeXeon_CPUID8.txt
TEST_F(CpuidX86Test,SkyLakeXeon)225 TEST_F(CpuidX86Test, SkyLakeXeon) {
226 cpu().SetLeaves({
227 {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
228 {{0x00000001, 0}, Leaf{0x00050654, 0x00100800, 0x7FFEFBFF, 0xBFEBFBFF}}
229 });
230 const auto info = GetX86Info();
231 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
232 EXPECT_EQ(info.family, 0x06);
233 EXPECT_EQ(info.model, 0x055);
234 EXPECT_EQ(info.stepping, 0x04);
235 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_SKL);
236 }
237
238 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel0050657_CascadeLakeXeon_CPUID.txt
TEST_F(CpuidX86Test,CascadeLake)239 TEST_F(CpuidX86Test, CascadeLake) {
240 cpu().SetLeaves({
241 {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
242 {{0x00000001, 0}, Leaf{0x00050657, 0x00400800, 0x7FFEFBFF, 0xBFEBFBFF}}
243 });
244 const auto info = GetX86Info();
245 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
246 EXPECT_EQ(info.family, 0x06);
247 EXPECT_EQ(info.model, 0x055);
248 EXPECT_EQ(info.stepping, 0x07);
249 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_CCL);
250 }
251
TEST_F(CpuidX86Test,Branding)252 TEST_F(CpuidX86Test, Branding) {
253 cpu().SetLeaves({
254 {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
255 {{0x00000001, 0}, Leaf{0x000406E3, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
256 {{0x00000007, 0}, Leaf{0x00000000, 0x029C67AF, 0x00000000, 0x00000000}},
257 {{0x80000000, 0}, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}},
258 {{0x80000001, 0}, Leaf{0x00000000, 0x00000000, 0x00000121, 0x2C100000}},
259 {{0x80000002, 0}, Leaf{0x65746E49, 0x2952286C, 0x726F4320, 0x4D542865}},
260 {{0x80000003, 0}, Leaf{0x37692029, 0x3035362D, 0x43205530, 0x40205550}},
261 {{0x80000004, 0}, Leaf{0x352E3220, 0x7A484730, 0x00000000, 0x00000000}},
262 });
263 const auto info = GetX86Info();
264 EXPECT_STREQ(info.brand_string, "Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz");
265 }
266
TEST_F(CpuidX86Test,KabyLakeCache)267 TEST_F(CpuidX86Test, KabyLakeCache) {
268 cpu().SetLeaves({
269 {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
270 {{0x00000001, 0}, Leaf{0x000406E3, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
271 {{0x00000004, 0}, Leaf{0x1C004121, 0x01C0003F, 0x0000003F, 0x00000000}},
272 {{0x00000004, 1}, Leaf{0x1C004122, 0x01C0003F, 0x0000003F, 0x00000000}},
273 {{0x00000004, 2}, Leaf{0x1C004143, 0x00C0003F, 0x000003FF, 0x00000000}},
274 {{0x00000004, 3}, Leaf{0x1C03C163, 0x02C0003F, 0x00001FFF, 0x00000002}},
275 {{0x00000007, 0}, Leaf{0x00000000, 0x029C67AF, 0x00000000, 0x00000000}},
276 {{0x80000000, 0}, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}},
277 {{0x80000001, 0}, Leaf{0x00000000, 0x00000000, 0x00000121, 0x2C100000}},
278 {{0x80000002, 0}, Leaf{0x65746E49, 0x2952286C, 0x726F4320, 0x4D542865}},
279 {{0x80000003, 0}, Leaf{0x37692029, 0x3035362D, 0x43205530, 0x40205550}},
280 });
281 const auto info = GetX86CacheInfo();
282 EXPECT_EQ(info.size, 4);
283 EXPECT_EQ(info.levels[0].level, 1);
284 EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA);
285 EXPECT_EQ(info.levels[0].cache_size, 32 * KiB);
286 EXPECT_EQ(info.levels[0].ways, 8);
287 EXPECT_EQ(info.levels[0].line_size, 64);
288 EXPECT_EQ(info.levels[0].tlb_entries, 64);
289 EXPECT_EQ(info.levels[0].partitioning, 1);
290
291 EXPECT_EQ(info.levels[1].level, 1);
292 EXPECT_EQ(info.levels[1].cache_type,
293 CacheType::CPU_FEATURE_CACHE_INSTRUCTION);
294 EXPECT_EQ(info.levels[1].cache_size, 32 * KiB);
295 EXPECT_EQ(info.levels[1].ways, 8);
296 EXPECT_EQ(info.levels[1].line_size, 64);
297 EXPECT_EQ(info.levels[1].tlb_entries, 64);
298 EXPECT_EQ(info.levels[1].partitioning, 1);
299
300 EXPECT_EQ(info.levels[2].level, 2);
301 EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
302 EXPECT_EQ(info.levels[2].cache_size, 256 * KiB);
303 EXPECT_EQ(info.levels[2].ways, 4);
304 EXPECT_EQ(info.levels[2].line_size, 64);
305 EXPECT_EQ(info.levels[2].tlb_entries, 1024);
306 EXPECT_EQ(info.levels[2].partitioning, 1);
307
308 EXPECT_EQ(info.levels[3].level, 3);
309 EXPECT_EQ(info.levels[3].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
310 EXPECT_EQ(info.levels[3].cache_size, 6 * MiB);
311 EXPECT_EQ(info.levels[3].ways, 12);
312 EXPECT_EQ(info.levels[3].line_size, 64);
313 EXPECT_EQ(info.levels[3].tlb_entries, 8192);
314 EXPECT_EQ(info.levels[3].partitioning, 1);
315 }
316
TEST_F(CpuidX86Test,HSWCache)317 TEST_F(CpuidX86Test, HSWCache) {
318 cpu().SetLeaves({
319 {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
320 {{0x00000001, 0}, Leaf{0x000406E3, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
321 {{0x00000004, 0}, Leaf{0x1C004121, 0x01C0003F, 0x0000003F, 0x00000000}},
322 {{0x00000004, 1}, Leaf{0x1C004122, 0x01C0003F, 0x0000003F, 0x00000000}},
323 {{0x00000004, 2}, Leaf{0x1C004143, 0x01C0003F, 0x000001FF, 0x00000000}},
324 {{0x00000004, 3}, Leaf{0x1C03C163, 0x02C0003F, 0x00001FFF, 0x00000006}},
325 {{0x00000007, 0}, Leaf{0x00000000, 0x029C67AF, 0x00000000, 0x00000000}},
326 {{0x80000000, 0}, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}},
327 {{0x80000001, 0}, Leaf{0x00000000, 0x00000000, 0x00000121, 0x2C100000}},
328 {{0x80000002, 0}, Leaf{0x65746E49, 0x2952286C, 0x726F4320, 0x4D542865}},
329 {{0x80000003, 0}, Leaf{0x37692029, 0x3035362D, 0x43205530, 0x40205550}},
330 });
331 const auto info = GetX86CacheInfo();
332 EXPECT_EQ(info.size, 4);
333 EXPECT_EQ(info.levels[0].level, 1);
334 EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA);
335 EXPECT_EQ(info.levels[0].cache_size, 32 * KiB);
336 EXPECT_EQ(info.levels[0].ways, 8);
337 EXPECT_EQ(info.levels[0].line_size, 64);
338 EXPECT_EQ(info.levels[0].tlb_entries, 64);
339 EXPECT_EQ(info.levels[0].partitioning, 1);
340
341 EXPECT_EQ(info.levels[1].level, 1);
342 EXPECT_EQ(info.levels[1].cache_type,
343 CacheType::CPU_FEATURE_CACHE_INSTRUCTION);
344 EXPECT_EQ(info.levels[1].cache_size, 32 * KiB);
345 EXPECT_EQ(info.levels[1].ways, 8);
346 EXPECT_EQ(info.levels[1].line_size, 64);
347 EXPECT_EQ(info.levels[1].tlb_entries, 64);
348 EXPECT_EQ(info.levels[1].partitioning, 1);
349
350 EXPECT_EQ(info.levels[2].level, 2);
351 EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
352 EXPECT_EQ(info.levels[2].cache_size, 256 * KiB);
353 EXPECT_EQ(info.levels[2].ways, 8);
354 EXPECT_EQ(info.levels[2].line_size, 64);
355 EXPECT_EQ(info.levels[2].tlb_entries, 512);
356 EXPECT_EQ(info.levels[2].partitioning, 1);
357
358 EXPECT_EQ(info.levels[3].level, 3);
359 EXPECT_EQ(info.levels[3].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
360 EXPECT_EQ(info.levels[3].cache_size, 6 * MiB);
361 EXPECT_EQ(info.levels[3].ways, 12);
362 EXPECT_EQ(info.levels[3].line_size, 64);
363 EXPECT_EQ(info.levels[3].tlb_entries, 8192);
364 EXPECT_EQ(info.levels[3].partitioning, 1);
365 }
366
367 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0200F30_K11_Griffin_CPUID.txt
TEST_F(CpuidX86Test,AMD_K11_GRIFFIN)368 TEST_F(CpuidX86Test, AMD_K11_GRIFFIN) {
369 cpu().SetLeaves({
370 {{0x00000000, 0}, Leaf{0x00000001, 0x68747541, 0x444D4163, 0x69746E65}},
371 {{0x00000001, 0}, Leaf{0x00200F30, 0x00020800, 0x00002001, 0x178BFBFF}},
372 {{0x80000000, 0}, Leaf{0x8000001A, 0x68747541, 0x444D4163, 0x69746E65}},
373 {{0x80000001, 0}, Leaf{0x00200F30, 0x20000000, 0x0000131F, 0xEBD3FBFF}},
374 });
375 const auto info = GetX86Info();
376
377 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
378 EXPECT_EQ(info.family, 0x11);
379 EXPECT_EQ(info.model, 0x03);
380 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_K11);
381 }
382
383 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0300F10_K12_Llano_CPUID.txt
TEST_F(CpuidX86Test,AMD_K12_LLANO)384 TEST_F(CpuidX86Test, AMD_K12_LLANO) {
385 cpu().SetLeaves({
386 {{0x00000000, 0}, Leaf{0x00000006, 0x68747541, 0x444D4163, 0x69746E65}},
387 {{0x00000001, 0}, Leaf{0x00300F10, 0x00040800, 0x00802009, 0x178BFBFF}},
388 {{0x80000000, 0}, Leaf{0x8000001B, 0x68747541, 0x444D4163, 0x69746E65}},
389 {{0x80000001, 0}, Leaf{0x00300F10, 0x20002B31, 0x000037FF, 0xEFD3FBFF}},
390 });
391 const auto info = GetX86Info();
392
393 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
394 EXPECT_EQ(info.family, 0x12);
395 EXPECT_EQ(info.model, 0x01);
396 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_K12);
397 }
398
399 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0500F01_K14_Bobcat_CPUID.txt
TEST_F(CpuidX86Test,AMD_K14_BOBCAT_AMD0500F01)400 TEST_F(CpuidX86Test, AMD_K14_BOBCAT_AMD0500F01) {
401 cpu().SetLeaves({
402 {{0x00000000, 0}, Leaf{0x00000006, 0x68747541, 0x444D4163, 0x69746E65}},
403 {{0x00000001, 0}, Leaf{0x00500F01, 0x00020800, 0x00802209, 0x178BFBFF}},
404 {{0x80000000, 0}, Leaf{0x8000001B, 0x68747541, 0x444D4163, 0x69746E65}},
405 {{0x80000001, 0}, Leaf{0x00500F01, 0x00000000, 0x000035FF, 0x2FD3FBFF}},
406 });
407 const auto info = GetX86Info();
408
409 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
410 EXPECT_EQ(info.family, 0x14);
411 EXPECT_EQ(info.model, 0x00);
412 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_BOBCAT);
413 }
414
415 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0500F10_K14_Bobcat_CPUID.txt
TEST_F(CpuidX86Test,AMD_K14_BOBCAT_AMD0500F10)416 TEST_F(CpuidX86Test, AMD_K14_BOBCAT_AMD0500F10) {
417 cpu().SetLeaves({
418 {{0x00000000, 0}, Leaf{0x00000006, 0x68747541, 0x444D4163, 0x69746E65}},
419 {{0x00000001, 0}, Leaf{0x00500F10, 0x00020800, 0x00802209, 0x178BFBFF}},
420 {{0x00000002, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
421 {{0x00000003, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
422 {{0x00000005, 0}, Leaf{0x00000040, 0x00000040, 0x00000003, 0x00000000}},
423 {{0x00000006, 0}, Leaf{0x00000000, 0x00000000, 0x00000001, 0x00000000}},
424 {{0x80000000, 0}, Leaf{0x8000001B, 0x68747541, 0x444D4163, 0x69746E65}},
425 {{0x80000001, 0}, Leaf{0x00500F10, 0x00001242, 0x000035FF, 0x2FD3FBFF}},
426 {{0x80000002, 0}, Leaf{0x20444D41, 0x35332D45, 0x72502030, 0x7365636F}},
427 {{0x80000003, 0}, Leaf{0x00726F73, 0x00000000, 0x00000000, 0x00000000}},
428 {{0x80000004, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
429 {{0x80000005, 0}, Leaf{0xFF08FF08, 0xFF280000, 0x20080140, 0x20020140}},
430 });
431 const auto info = GetX86Info();
432
433 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
434 EXPECT_EQ(info.family, 0x14);
435 EXPECT_EQ(info.model, 0x01);
436 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_BOBCAT);
437 }
438
439 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0500F20_K14_Bobcat_CPUID.txt
TEST_F(CpuidX86Test,AMD_K14_BOBCAT_AMD0500F20)440 TEST_F(CpuidX86Test, AMD_K14_BOBCAT_AMD0500F20) {
441 cpu().SetLeaves({
442 {{0x00000000, 0}, Leaf{0x00000006, 0x68747541, 0x444D4163, 0x69746E65}},
443 {{0x00000001, 0}, Leaf{0x00500F20, 0x00020800, 0x00802209, 0x178BFBFF}},
444 {{0x80000000, 0}, Leaf{0x8000001B, 0x68747541, 0x444D4163, 0x69746E65}},
445 {{0x80000001, 0}, Leaf{0x00500F20, 0x000012E9, 0x000035FF, 0x2FD3FBFF}},
446 });
447 const auto info = GetX86Info();
448
449 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
450 EXPECT_EQ(info.family, 0x14);
451 EXPECT_EQ(info.model, 0x02);
452 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_BOBCAT);
453 }
454
455 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0670F00_K15_StoneyRidge_CPUID.txt
TEST_F(CpuidX86Test,AMD_K15_EXCAVATOR_STONEY_RIDGE)456 TEST_F(CpuidX86Test, AMD_K15_EXCAVATOR_STONEY_RIDGE) {
457 cpu().SetLeaves({
458 {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
459 {{0x00000001, 0}, Leaf{0x00670F00, 0x00020800, 0x7ED8320B, 0x178BFBFF}},
460 {{0x00000007, 0}, Leaf{0x00000000, 0x000001A9, 0x00000000, 0x00000000}},
461 {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
462 {{0x80000001, 0}, Leaf{0x00670F00, 0x00000000, 0x2FABBFFF, 0x2FD3FBFF}},
463 {{0x80000002, 0}, Leaf{0x20444D41, 0x392D3941, 0x20303134, 0x45444152}},
464 {{0x80000003, 0}, Leaf{0x52204E4F, 0x35202C35, 0x4D4F4320, 0x45545550}},
465 {{0x80000004, 0}, Leaf{0x524F4320, 0x32205345, 0x47332B43, 0x00202020}},
466 });
467 const auto info = GetX86Info();
468
469 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
470 EXPECT_EQ(info.family, 0x15);
471 EXPECT_EQ(info.model, 0x70);
472 EXPECT_STREQ(info.brand_string,
473 "AMD A9-9410 RADEON R5, 5 COMPUTE CORES 2C+3G ");
474 EXPECT_EQ(GetX86Microarchitecture(&info),
475 X86Microarchitecture::AMD_EXCAVATOR);
476 }
477
478 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0600F20_K15_AbuDhabi_CPUID0.txt
TEST_F(CpuidX86Test,AMD_K15_PILEDRIVER_ABU_DHABI)479 TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI) {
480 cpu().SetLeaves({
481 {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
482 {{0x00000001, 0}, Leaf{0x00600F20, 0x00100800, 0x3E98320B, 0x178BFBFF}},
483 {{0x00000007, 0}, Leaf{0x00000000, 0x00000008, 0x00000000, 0x00000000}},
484 {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
485 {{0x80000001, 0}, Leaf{0x00600F20, 0x30000000, 0x01EBBFFF, 0x2FD3FBFF}},
486 {{0x80000002, 0}, Leaf{0x20444D41, 0x6574704F, 0x286E6F72, 0x20296D74}},
487 {{0x80000003, 0}, Leaf{0x636F7250, 0x6F737365, 0x33362072, 0x20203637}},
488 {{0x80000004, 0}, Leaf{0x20202020, 0x20202020, 0x20202020, 0x00202020}},
489 });
490 const auto info = GetX86Info();
491
492 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
493 EXPECT_EQ(info.family, 0x15);
494 EXPECT_EQ(info.model, 0x02);
495 EXPECT_STREQ(info.brand_string,
496 "AMD Opteron(tm) Processor 6376 ");
497 EXPECT_EQ(GetX86Microarchitecture(&info),
498 X86Microarchitecture::AMD_PILEDRIVER);
499
500 EXPECT_STREQ(info.brand_string, "AMD Opteron(tm) Processor 6376 ");
501 }
502
503 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0600F20_K15_AbuDhabi_CPUID0.txt
TEST_F(CpuidX86Test,AMD_K15_PILEDRIVER_ABU_DHABI_CACHE_INFO)504 TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI_CACHE_INFO) {
505 cpu().SetLeaves({
506 {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
507 {{0x00000001, 0}, Leaf{0x00600F20, 0x00100800, 0x3E98320B, 0x178BFBFF}},
508 {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
509 {{0x80000001, 0}, Leaf{0x00600F20, 0x30000000, 0x01EBBFFF, 0x2FD3FBFF}},
510 {{0x8000001D, 0}, Leaf{0x00000121, 0x00C0003F, 0x0000003F, 0x00000000}},
511 {{0x8000001D, 1}, Leaf{0x00004122, 0x0040003F, 0x000001FF, 0x00000000}},
512 {{0x8000001D, 2}, Leaf{0x00004143, 0x03C0003F, 0x000007FF, 0x00000001}},
513 {{0x8000001D, 3}, Leaf{0x0001C163, 0x0BC0003F, 0x000007FF, 0x00000001}},
514 });
515 const auto info = GetX86CacheInfo();
516
517 EXPECT_EQ(info.size, 4);
518 EXPECT_EQ(info.levels[0].level, 1);
519 EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA);
520 EXPECT_EQ(info.levels[0].cache_size, 16 * KiB);
521 EXPECT_EQ(info.levels[0].ways, 4);
522 EXPECT_EQ(info.levels[0].line_size, 64);
523 EXPECT_EQ(info.levels[0].tlb_entries, 64);
524 EXPECT_EQ(info.levels[0].partitioning, 1);
525
526 EXPECT_EQ(info.levels[1].level, 1);
527 EXPECT_EQ(info.levels[1].cache_type,
528 CacheType::CPU_FEATURE_CACHE_INSTRUCTION);
529 EXPECT_EQ(info.levels[1].cache_size, 64 * KiB);
530 EXPECT_EQ(info.levels[1].ways, 2);
531 EXPECT_EQ(info.levels[1].line_size, 64);
532 EXPECT_EQ(info.levels[1].tlb_entries, 512);
533 EXPECT_EQ(info.levels[1].partitioning, 1);
534
535 EXPECT_EQ(info.levels[2].level, 2);
536 EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
537 EXPECT_EQ(info.levels[2].cache_size, 2 * MiB);
538 EXPECT_EQ(info.levels[2].ways, 16);
539 EXPECT_EQ(info.levels[2].line_size, 64);
540 EXPECT_EQ(info.levels[2].tlb_entries, 2048);
541 EXPECT_EQ(info.levels[2].partitioning, 1);
542
543 EXPECT_EQ(info.levels[3].level, 3);
544 EXPECT_EQ(info.levels[3].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
545 EXPECT_EQ(info.levels[3].cache_size, 6 * MiB);
546 EXPECT_EQ(info.levels[3].ways, 48);
547 EXPECT_EQ(info.levels[3].line_size, 64);
548 EXPECT_EQ(info.levels[3].tlb_entries, 2048);
549 EXPECT_EQ(info.levels[3].partitioning, 1);
550 }
551
552 // https://github.com/InstLatx64/InstLatx64/blob/master/AuthenticAMD/AuthenticAMD0610F01_K15_Piledriver_CPUID.txt
TEST_F(CpuidX86Test,AMD_K15_PILEDRIVER_A10)553 TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_A10) {
554 cpu().SetLeaves({
555 {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
556 {{0x00000001, 0}, Leaf{0x00610F01, 0x00040800, 0x3E98320B, 0x178BFBFF}},
557 {{0x00000007, 0}, Leaf{0x00000000, 0x00000008, 0x00000000, 0x00000000}},
558 {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
559 {{0x80000001, 0}, Leaf{0x00610F01, 0x20000000, 0x01EBBFFF, 0x2FD3FBFF}},
560 {{0x80000002, 0}, Leaf{0x20444D41, 0x2D303141, 0x30303835, 0x5041204B}},
561 {{0x80000003, 0}, Leaf{0x69772055, 0x52206874, 0x6F656461, 0x6D74286E}},
562 {{0x80000004, 0}, Leaf{0x44482029, 0x61724720, 0x63696870, 0x00202073}},
563 });
564 const auto info = GetX86Info();
565
566 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
567 EXPECT_EQ(info.family, 0x15);
568 EXPECT_EQ(info.model, 0x10);
569 EXPECT_STREQ(info.brand_string,
570 "AMD A10-5800K APU with Radeon(tm) HD Graphics ");
571 EXPECT_EQ(GetX86Microarchitecture(&info),
572 X86Microarchitecture::AMD_PILEDRIVER);
573 }
574
575 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0600F12_K15_Interlagos_CPUID3.txt
TEST_F(CpuidX86Test,AMD_K15_BULLDOZER_INTERLAGOS)576 TEST_F(CpuidX86Test, AMD_K15_BULLDOZER_INTERLAGOS) {
577 cpu().SetLeaves({
578 {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
579 {{0x00000001, 0}, Leaf{0x00600F12, 0x000C0800, 0x1E98220B, 0x178BFBFF}},
580 {{0x00000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
581 {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
582 {{0x80000001, 0}, Leaf{0x00600F12, 0x30000000, 0x01C9BFFF, 0x2FD3FBFF}},
583 {{0x80000002, 0}, Leaf{0x20444D41, 0x6574704F, 0x286E6F72, 0x20294D54}},
584 {{0x80000003, 0}, Leaf{0x636F7250, 0x6F737365, 0x32362072, 0x20203833}},
585 {{0x80000004, 0}, Leaf{0x20202020, 0x20202020, 0x20202020, 0x00202020}},
586 });
587 const auto info = GetX86Info();
588
589 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
590 EXPECT_EQ(info.family, 0x15);
591 EXPECT_EQ(info.model, 0x01);
592 EXPECT_STREQ(info.brand_string,
593 "AMD Opteron(TM) Processor 6238 ");
594 EXPECT_EQ(GetX86Microarchitecture(&info),
595 X86Microarchitecture::AMD_BULLDOZER);
596 }
597
598 // http://users.atw.hu/instlatx64/AuthenticAMD0630F81_K15_Godavari_CPUID.txt
TEST_F(CpuidX86Test,AMD_K15_STREAMROLLER_GODAVARI)599 TEST_F(CpuidX86Test, AMD_K15_STREAMROLLER_GODAVARI) {
600 cpu().SetLeaves({
601 {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
602 {{0x00000001, 0}, Leaf{0x00630F81, 0x00040800, 0x3E98320B, 0x178BFBFF}},
603 {{0x00000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
604 {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
605 {{0x80000001, 0}, Leaf{0x00630F81, 0x10000000, 0x0FEBBFFF, 0x2FD3FBFF}},
606 {{0x80000002, 0}, Leaf{0x20444D41, 0x372D3841, 0x4B303736, 0x64615220}},
607 {{0x80000003, 0}, Leaf{0x206E6F65, 0x202C3752, 0x43203031, 0x75706D6F}},
608 {{0x80000004, 0}, Leaf{0x43206574, 0x7365726F, 0x2B433420, 0x00204736}},
609 {{0x80000005, 0}, Leaf{0xFF40FF18, 0xFF40FF30, 0x10040140, 0x60030140}},
610 });
611 const auto info = GetX86Info();
612
613 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
614 EXPECT_EQ(info.family, 0x15);
615 EXPECT_EQ(info.model, 0x38);
616 EXPECT_EQ(info.stepping, 0x01);
617 EXPECT_STREQ(info.brand_string,
618 "AMD A8-7670K Radeon R7, 10 Compute Cores 4C+6G ");
619 EXPECT_EQ(GetX86Microarchitecture(&info),
620 X86Microarchitecture::AMD_STREAMROLLER);
621 }
622
623 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0600F12_K15_Zambezi8C_CPUID.txt
TEST_F(CpuidX86Test,AMD_K15_BULLDOZER_ZAMBEZI_ABM)624 TEST_F(CpuidX86Test, AMD_K15_BULLDOZER_ZAMBEZI_ABM) {
625 cpu().SetLeaves({
626 {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
627 {{0x00000001, 0}, Leaf{0x00600F12, 0x00080800, 0x1E98220B, 0x178BFBFF}},
628 {{0x00000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
629 {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
630 {{0x80000001, 0}, Leaf{0x00600F12, 0x10000000, 0x01C9BFFF, 0x2FD3FBFF}},
631 });
632 const auto info = GetX86Info();
633
634 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
635 EXPECT_EQ(info.family, 0x15);
636 EXPECT_EQ(info.model, 0x01);
637
638 EXPECT_EQ(GetX86Microarchitecture(&info),
639 X86Microarchitecture::AMD_BULLDOZER);
640
641 EXPECT_TRUE(info.features.lzcnt);
642 }
643
644 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0700F01_K16_Kabini_CPUID.txt
TEST_F(CpuidX86Test,AMD_K16_JAGUAR_KABINI)645 TEST_F(CpuidX86Test, AMD_K16_JAGUAR_KABINI) {
646 cpu().SetLeaves({
647 {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
648 {{0x00000001, 0}, Leaf{0x00700F01, 0x00040800, 0x3ED8220B, 0x178BFBFF}},
649 {{0x00000007, 0}, Leaf{0x00000000, 0x00000008, 0x00000000, 0x00000000}},
650 {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
651 {{0x80000001, 0}, Leaf{0x00700F01, 0x00000000, 0x154037FF, 0x2FD3FBFF}},
652 {{0x80000002, 0}, Leaf{0x20444D41, 0x352D3441, 0x20303030, 0x20555041}},
653 {{0x80000003, 0}, Leaf{0x68746977, 0x64615220, 0x286E6F65, 0x20294D54}},
654 {{0x80000004, 0}, Leaf{0x47204448, 0x68706172, 0x20736369, 0x00202020}},
655 });
656 const auto info = GetX86Info();
657
658 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
659 EXPECT_EQ(info.family, 0x16);
660 EXPECT_EQ(info.model, 0x00);
661 EXPECT_STREQ(info.brand_string,
662 "AMD A4-5000 APU with Radeon(TM) HD Graphics ");
663 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_JAGUAR);
664 }
665
666 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0730F01_K16_Beema_CPUID2.txt
TEST_F(CpuidX86Test,AMD_K16_PUMA_BEEMA)667 TEST_F(CpuidX86Test, AMD_K16_PUMA_BEEMA) {
668 cpu().SetLeaves({
669 {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
670 {{0x00000001, 0}, Leaf{0x00730F01, 0x00040800, 0x7ED8220B, 0x178BFBFF}},
671 {{0x00000007, 0}, Leaf{0x00000000, 0x00000008, 0x00000000, 0x00000000}},
672 {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
673 {{0x80000001, 0}, Leaf{0x00730F01, 0x00000000, 0x1D4037FF, 0x2FD3FBFF}},
674 {{0x80000002, 0}, Leaf{0x20444D41, 0x362D3641, 0x20303133, 0x20555041}},
675 {{0x80000003, 0}, Leaf{0x68746977, 0x444D4120, 0x64615220, 0x206E6F65}},
676 {{0x80000004, 0}, Leaf{0x47203452, 0x68706172, 0x20736369, 0x00202020}},
677 });
678 const auto info = GetX86Info();
679
680 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
681 EXPECT_EQ(info.family, 0x16);
682 EXPECT_EQ(info.model, 0x30);
683 EXPECT_STREQ(info.brand_string,
684 "AMD A6-6310 APU with AMD Radeon R4 Graphics ");
685 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_PUMA);
686 }
687
688 // https://github.com/InstLatx64/InstLatx64/blob/master/AuthenticAMD/AuthenticAMD0720F61_K16_Cato_CPUID.txt
TEST_F(CpuidX86Test,AMD_K16_CATO)689 TEST_F(CpuidX86Test, AMD_K16_CATO) {
690 cpu().SetLeaves({
691 {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
692 {{0x00000001, 0}, Leaf{0x00720F61, 0x00080800, 0x3ED8220B, 0x178BFBFF}},
693 {{0x00000007, 0}, Leaf{0x00000000, 0x00000008, 0x00000000, 0x00000000}},
694 {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
695 {{0x80000001, 0}, Leaf{0x00720F61, 0x00000000, 0x154837FF, 0x2FD3FBFF}},
696 {{0x80000002, 0}, Leaf{0x20444D41, 0x392D3941, 0x20303238, 0x636F7250}},
697 {{0x80000003, 0}, Leaf{0x6F737365, 0x00000072, 0x00000000, 0x00000000}},
698 {{0x80000004, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
699 });
700 const auto info = GetX86Info();
701
702 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
703 EXPECT_EQ(info.family, 0x16);
704 EXPECT_EQ(info.model, 0x26);
705 EXPECT_STREQ(info.brand_string,
706 "AMD A9-9820 Processor");
707 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_JAGUAR);
708 }
709
710 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0820F01_K17_Dali_CPUID.txt
TEST_F(CpuidX86Test,AMD_K17_ZEN_DALI)711 TEST_F(CpuidX86Test, AMD_K17_ZEN_DALI) {
712 cpu().SetLeaves({
713 {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
714 {{0x00000001, 0}, Leaf{0x00820F01, 0x00020800, 0x7ED8320B, 0x178BFBFF}},
715 {{0x00000007, 0}, Leaf{0x00000000, 0x209C01A9, 0x00000000, 0x00000000}},
716 {{0x80000000, 0}, Leaf{0x8000001F, 0x68747541, 0x444D4163, 0x69746E65}},
717 {{0x80000001, 0}, Leaf{0x00820F01, 0x00000000, 0x35C233FF, 0x2FD3FBFF}},
718 {{0x80000002, 0}, Leaf{0x20444D41, 0x30323033, 0x69772065, 0x52206874}},
719 {{0x80000003, 0}, Leaf{0x6F656461, 0x7247206E, 0x69687061, 0x20207363}},
720 {{0x80000004, 0}, Leaf{0x20202020, 0x20202020, 0x20202020, 0x00202020}},
721 });
722 const auto info = GetX86Info();
723
724 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
725 EXPECT_EQ(info.family, 0x17);
726 EXPECT_EQ(info.model, 0x20);
727 EXPECT_STREQ(info.brand_string,
728 "AMD 3020e with Radeon Graphics ");
729 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
730 }
731
732 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0800F82_K17_ZenP_CPUID.txt
TEST_F(CpuidX86Test,AMD_K17_ZEN_PLUS_PINNACLE_RIDGE)733 TEST_F(CpuidX86Test, AMD_K17_ZEN_PLUS_PINNACLE_RIDGE) {
734 cpu().SetLeaves({
735 {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
736 {{0x00000001, 0}, Leaf{0x00800F82, 0x00100800, 0x7ED8320B, 0x178BFBFF}},
737 {{0x00000007, 0}, Leaf{0x00000000, 0x209C01A9, 0x00000000, 0x00000000}},
738 {{0x80000000, 0}, Leaf{0x8000001F, 0x68747541, 0x444D4163, 0x69746E65}},
739 {{0x80000001, 0}, Leaf{0x00800F82, 0x20000000, 0x35C233FF, 0x2FD3FBFF}},
740 {{0x80000002, 0}, Leaf{0x20444D41, 0x657A7952, 0x2037206E, 0x30303732}},
741 {{0x80000003, 0}, Leaf{0x69452058, 0x2D746867, 0x65726F43, 0x6F725020}},
742 {{0x80000004, 0}, Leaf{0x73736563, 0x2020726F, 0x20202020, 0x00202020}},
743 });
744 const auto info = GetX86Info();
745
746 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
747 EXPECT_EQ(info.family, 0x17);
748 EXPECT_EQ(info.model, 0x08);
749 EXPECT_STREQ(info.brand_string,
750 "AMD Ryzen 7 2700X Eight-Core Processor ");
751 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN_PLUS);
752 }
753
754 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0840F70_K17_CPUID.txt
TEST_F(CpuidX86Test,AMD_K17_ZEN2_XBOX_SERIES_X)755 TEST_F(CpuidX86Test, AMD_K17_ZEN2_XBOX_SERIES_X) {
756 cpu().SetLeaves({
757 {{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
758 {{0x00000001, 0}, Leaf{0x00840F70, 0x00100800, 0x7ED8320B, 0x178BFBFF}},
759 {{0x00000007, 0}, Leaf{0x00000000, 0x219C91A9, 0x00400004, 0x00000000}},
760 {{0x80000000, 0}, Leaf{0x80000020, 0x68747541, 0x444D4163, 0x69746E65}},
761 {{0x80000001, 0}, Leaf{0x00840F70, 0x00000000, 0xF5C2B7FF, 0x2FD3FBFF}},
762 {{0x80000002, 0}, Leaf{0x20444D41, 0x30303734, 0x2D382053, 0x65726F43}},
763 {{0x80000003, 0}, Leaf{0x6F725020, 0x73736563, 0x4420726F, 0x746B7365}},
764 {{0x80000004, 0}, Leaf{0x4B20706F, 0x00007469, 0x00000000, 0x00000000}},
765 });
766 const auto info = GetX86Info();
767
768 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
769 EXPECT_EQ(info.family, 0x17);
770 EXPECT_EQ(info.model, 0x47);
771 EXPECT_STREQ(info.brand_string, "AMD 4700S 8-Core Processor Desktop Kit");
772 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
773 }
774
775 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0880F40_K17_CPUID.txt
TEST_F(CpuidX86Test,AMD_K17_ZEN2_4800S)776 TEST_F(CpuidX86Test, AMD_K17_ZEN2_4800S) {
777 cpu().SetLeaves({
778 {{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
779 {{0x00000001, 0}, Leaf{0x00880F40, 0x00100800, 0x7ED8320B, 0x178BFBFF}},
780 });
781 const auto info = GetX86Info();
782
783 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
784 EXPECT_EQ(info.family, 0x17);
785 EXPECT_EQ(info.model, 0x84);
786 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
787 }
788
789 // http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F02_Hygon_CPUID3.txt
TEST_F(CpuidX86Test,AMD_K18_ZEN_DHYANA)790 TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA) {
791 cpu().SetLeaves({
792 {{0x00000000, 0}, Leaf{0x0000000D, 0x6F677948, 0x656E6975, 0x6E65476E}},
793 {{0x00000001, 0}, Leaf{0x00900F02, 0x00100800, 0x74D83209, 0x178BFBFF}},
794 {{0x00000007, 0}, Leaf{0x00000000, 0x009C01A9, 0x0040068C, 0x00000000}},
795 {{0x80000000, 0}, Leaf{0x8000001F, 0x6F677948, 0x656E6975, 0x6E65476E}},
796 {{0x80000001, 0}, Leaf{0x00900F02, 0x60000000, 0x35C233FF, 0x2FD3FBFF}},
797 {{0x80000002, 0}, Leaf{0x6F677948, 0x3843206E, 0x31332036, 0x20203538}},
798 {{0x80000003, 0}, Leaf{0x6F632D38, 0x50206572, 0x65636F72, 0x726F7373}},
799 {{0x80000004, 0}, Leaf{0x20202020, 0x20202020, 0x20202020, 0x00202020}},
800 });
801 const auto info = GetX86Info();
802
803 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_HYGON_GENUINE);
804 EXPECT_EQ(info.family, 0x18);
805 EXPECT_EQ(info.model, 0x00);
806 EXPECT_STREQ(info.brand_string,
807 "Hygon C86 3185 8-core Processor ");
808 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
809 }
810
811 // http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F02_Hygon_CPUID.txt
TEST_F(CpuidX86Test,AMD_K18_ZEN_DHYANA_CACHE_INFO)812 TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_CACHE_INFO) {
813 cpu().SetLeaves({
814 {{0x00000000, 0}, Leaf{0x0000000D, 0x6F677948, 0x656E6975, 0x6E65476E}},
815 {{0x00000001, 0}, Leaf{0x00900F02, 0x00100800, 0x74D83209, 0x178BFBFF}},
816 {{0x80000000, 0}, Leaf{0x8000001F, 0x6F677948, 0x656E6975, 0x6E65476E}},
817 {{0x80000001, 0}, Leaf{0x00900F02, 0x60000000, 0x35C233FF, 0x2FD3FBFF}},
818 {{0x8000001D, 0}, Leaf{0x00004121, 0x01C0003F, 0x0000003F, 0x00000000}},
819 {{0x8000001D, 1}, Leaf{0x00004122, 0x00C0003F, 0x000000FF, 0x00000000}},
820 {{0x8000001D, 2}, Leaf{0x00004143, 0x01C0003F, 0x000003FF, 0x00000002}},
821 {{0x8000001D, 3}, Leaf{0x0001C163, 0x03C0003F, 0x00001FFF, 0x00000001}},
822 });
823 const auto info = GetX86CacheInfo();
824
825 EXPECT_EQ(info.size, 4);
826 EXPECT_EQ(info.levels[0].level, 1);
827 EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA);
828 EXPECT_EQ(info.levels[0].cache_size, 32 * KiB);
829 EXPECT_EQ(info.levels[0].ways, 8);
830 EXPECT_EQ(info.levels[0].line_size, 64);
831 EXPECT_EQ(info.levels[0].tlb_entries, 64);
832 EXPECT_EQ(info.levels[0].partitioning, 1);
833
834 EXPECT_EQ(info.levels[1].level, 1);
835 EXPECT_EQ(info.levels[1].cache_type,
836 CacheType::CPU_FEATURE_CACHE_INSTRUCTION);
837 EXPECT_EQ(info.levels[1].cache_size, 64 * KiB);
838 EXPECT_EQ(info.levels[1].ways, 4);
839 EXPECT_EQ(info.levels[1].line_size, 64);
840 EXPECT_EQ(info.levels[1].tlb_entries, 256);
841 EXPECT_EQ(info.levels[1].partitioning, 1);
842
843 EXPECT_EQ(info.levels[2].level, 2);
844 EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
845 EXPECT_EQ(info.levels[2].cache_size, 512 * KiB);
846 EXPECT_EQ(info.levels[2].ways, 8);
847 EXPECT_EQ(info.levels[2].line_size, 64);
848 EXPECT_EQ(info.levels[2].tlb_entries, 1024);
849 EXPECT_EQ(info.levels[2].partitioning, 1);
850
851 EXPECT_EQ(info.levels[3].level, 3);
852 EXPECT_EQ(info.levels[3].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
853 EXPECT_EQ(info.levels[3].cache_size, 8 * MiB);
854 EXPECT_EQ(info.levels[3].ways, 16);
855 EXPECT_EQ(info.levels[3].line_size, 64);
856 EXPECT_EQ(info.levels[3].tlb_entries, 8192);
857 EXPECT_EQ(info.levels[3].partitioning, 1);
858 }
859
860 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0A20F10_K19_Vermeer2_CPUID.txt
TEST_F(CpuidX86Test,AMD_K19_ZEN3_VERMEER)861 TEST_F(CpuidX86Test, AMD_K19_ZEN3_VERMEER) {
862 cpu().SetLeaves({
863 {{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
864 {{0x00000001, 0}, Leaf{0x00A20F10, 0x01180800, 0x7ED8320B, 0x178BFBFF}},
865 {{0x00000007, 0}, Leaf{0x00000000, 0x219C97A9, 0x0040068C, 0x00000000}},
866 {{0x80000000, 0}, Leaf{0x80000023, 0x68747541, 0x444D4163, 0x69746E65}},
867 {{0x80000001, 0}, Leaf{0x00A20F10, 0x20000000, 0x75C237FF, 0x2FD3FBFF}},
868 {{0x80000002, 0}, Leaf{0x20444D41, 0x657A7952, 0x2039206E, 0x30303935}},
869 {{0x80000003, 0}, Leaf{0x32312058, 0x726F432D, 0x72502065, 0x7365636F}},
870 {{0x80000004, 0}, Leaf{0x20726F73, 0x20202020, 0x20202020, 0x00202020}},
871 });
872 const auto info = GetX86Info();
873
874 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
875 EXPECT_EQ(info.family, 0x19);
876 EXPECT_EQ(info.model, 0x21);
877 EXPECT_STREQ(info.brand_string,
878 "AMD Ryzen 9 5900X 12-Core Processor ");
879 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN3);
880 }
881
882 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0A40F41_K19_Rembrandt_03_CPUID.txt
TEST_F(CpuidX86Test,AMD_K19_ZEN3)883 TEST_F(CpuidX86Test, AMD_K19_ZEN3) {
884 cpu().SetLeaves({
885 {{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
886 {{0x00000001, 0}, Leaf{0x00A40F41, 0x00100800, 0x7EF8320B, 0x178BFBFF}},
887 {{0x80000000, 0}, Leaf{0x80000023, 0x68747541, 0x444D4163, 0x69746E65}},
888 {{0x80000001, 0}, Leaf{0x00A40F41, 0x50000000, 0x75C237FF, 0x2FD3FBFF}},
889 {{0x80000002, 0}, Leaf{0x20444D41, 0x657A7952, 0x2039206E, 0x30303936}},
890 {{0x80000003, 0}, Leaf{0x77205848, 0x20687469, 0x65646152, 0x47206E6F}},
891 {{0x80000004, 0}, Leaf{0x68706172, 0x20736369, 0x20202020, 0x00202020}},
892 });
893 const auto info = GetX86Info();
894
895 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
896 EXPECT_EQ(info.family, 0x19);
897 EXPECT_EQ(info.model, 0x44);
898 EXPECT_STREQ(info.brand_string,
899 "AMD Ryzen 9 6900HX with Radeon Graphics ");
900 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN3);
901 }
902
903 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0A60F12_K19_Raphael_01_CPUID.txt
TEST_F(CpuidX86Test,AMD_K19_ZEN4_RAPHAEL)904 TEST_F(CpuidX86Test, AMD_K19_ZEN4_RAPHAEL) {
905 cpu().SetLeaves({
906 {{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
907 {{0x00000001, 0}, Leaf{0x00A60F12, 0x000C0800, 0x7EF8320B, 0x178BFBFF}},
908 {{0x80000000, 0}, Leaf{0x80000028, 0x68747541, 0x444D4163, 0x69746E65}},
909 {{0x80000001, 0}, Leaf{0x00A60F12, 0x00000000, 0x75C237FF, 0x2FD3FBFF}},
910 {{0x80000002, 0}, Leaf{0x20444D41, 0x657A7952, 0x2035206E, 0x30303637}},
911 {{0x80000003, 0}, Leaf{0x2D362058, 0x65726F43, 0x6F725020, 0x73736563}},
912 {{0x80000004, 0}, Leaf{0x2020726F, 0x20202020, 0x20202020, 0x00202020}},
913 {{0x80000021, 0}, Leaf{0x00062FCF, 0x0000015C, 0x00000000, 0x00000000}},
914 });
915 const auto info = GetX86Info();
916
917 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
918 EXPECT_EQ(info.family, 0x19);
919 EXPECT_EQ(info.model, 0x61);
920 EXPECT_STREQ(info.brand_string,
921 "AMD Ryzen 5 7600X 6-Core Processor ");
922 EXPECT_TRUE(info.features.uai);
923 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN4);
924 }
925
926 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0A70F41_K19_Phoenix_03_CPUID.txt
TEST_F(CpuidX86Test,AMD_K19_ZEN4_PHOENIX)927 TEST_F(CpuidX86Test, AMD_K19_ZEN4_PHOENIX) {
928 cpu().SetLeaves({
929 {{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
930 {{0x00000001, 0}, Leaf{0x00A70F41, 0x00100800, 0x7EF8320B, 0x178BFBFF}},
931 {{0x80000000, 0}, Leaf{0x80000028, 0x68747541, 0x444D4163, 0x69746E65}},
932 {{0x80000001, 0}, Leaf{0x00A70F41, 0x50000000, 0x75C237FF, 0x2FD3FBFF}},
933 });
934 const auto info = GetX86Info();
935
936 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
937 EXPECT_EQ(info.family, 0x19);
938 EXPECT_EQ(info.model, 0x74);
939 }
940
941 // http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F11_Hygon_01_CPUID.txt
TEST_F(CpuidX86Test,AMD_K18_ZEN_DHYANA_OCTAL_CORE_C86_3250)942 TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_OCTAL_CORE_C86_3250) {
943 cpu().SetLeaves({
944 {{0x00000000, 0}, Leaf{0x0000000D, 0x6F677948, 0x656E6975, 0x6E65476E}},
945 {{0x00000001, 0}, Leaf{0x00900F11, 0x00100800, 0x76D8320B, 0x178BFBFF}},
946 {{0x80000000, 0}, Leaf{0x8000001F, 0x6F677948, 0x656E6975, 0x6E65476E}},
947 {{0x80000001, 0}, Leaf{0x00900F11, 0x60000000, 0x35C233FF, 0x2FD3FBFF}},
948 {{0x80000002, 0}, Leaf{0x6F677948, 0x3843206E, 0x32332036, 0x20203035}},
949 {{0x80000003, 0}, Leaf{0x6F632D38, 0x50206572, 0x65636F72, 0x726F7373}},
950 {{0x80000004, 0}, Leaf{0x20202020, 0x20202020, 0x20202020, 0x00202020}},
951 });
952 const auto info = GetX86Info();
953
954 EXPECT_EQ(info.model, 0x01);
955 EXPECT_EQ(info.family, 0x18);
956 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_HYGON_GENUINE);
957 EXPECT_STREQ(info.brand_string,
958 "Hygon C86 3250 8-core Processor ");
959 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
960 }
961
962 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD08A0F00_K17_Mendocino_01_CPUID.txt
TEST_F(CpuidX86Test,AMD_ZEN2_MENDOCINO)963 TEST_F(CpuidX86Test, AMD_ZEN2_MENDOCINO) {
964 cpu().SetLeaves({
965 {{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
966 {{0x00000001, 0}, Leaf{0x008A0F00, 0x00080800, 0x7EF8320B, 0x178BFBFF}},
967 });
968 const auto info = GetX86Info();
969
970 EXPECT_EQ(info.model, 0xA0);
971 EXPECT_EQ(info.family, 0x17);
972 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
973 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
974 }
975
976 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0A10F11_K19_Genoa_02_CPUID.txt
TEST_F(CpuidX86Test,AMD_K19_ZEN4_GENOA)977 TEST_F(CpuidX86Test, AMD_K19_ZEN4_GENOA) {
978 cpu().SetLeaves({
979 {{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
980 {{0x00000001, 0}, Leaf{0x00A10F11, 0x00200800, 0x7EFA320B, 0x178BFBFF}},
981 });
982 const auto info = GetX86Info();
983
984 EXPECT_EQ(info.model, 0x11);
985 EXPECT_EQ(info.family, 0x19);
986 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
987 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN4);
988 }
989
990 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00906A4_AlderLakeP_00_CPUID.txt
TEST_F(CpuidX86Test,INTEL_ALDER_LAKE_AVX_VNNI)991 TEST_F(CpuidX86Test, INTEL_ALDER_LAKE_AVX_VNNI) {
992 cpu().SetOsBackupsExtendedRegisters(true);
993 cpu().SetLeaves({
994 {{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}},
995 {{0x00000001, 0}, Leaf{0x000906A4, 0x00400800, 0x7FFAFBBF, 0xBFEBFBFF}},
996 {{0x00000007, 0}, Leaf{0x00000001, 0x239CA7EB, 0x984007AC, 0xFC18C410}},
997 {{0x00000007, 1}, Leaf{0x00400810, 0x00000000, 0x00000000, 0x00000000}},
998 });
999 const auto info = GetX86Info();
1000
1001 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1002 EXPECT_EQ(info.family, 0x06);
1003 EXPECT_EQ(info.model, 0x9A);
1004 EXPECT_TRUE(info.features.avx_vnni);
1005 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ADL);
1006 }
1007
1008 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0090672_AlderLake_BC_AVX512_CPUID01.txt
TEST_F(CpuidX86Test,INTEL_ALDER_LAKE_AVX512)1009 TEST_F(CpuidX86Test, INTEL_ALDER_LAKE_AVX512) {
1010 cpu().SetOsBackupsExtendedRegisters(true);
1011 #if defined(CPU_FEATURES_OS_MACOS)
1012 cpu().SetDarwinSysCtlByName("hw.optional.avx512f");
1013 #endif
1014 cpu().SetLeaves({
1015 {{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}},
1016 {{0x00000001, 0}, Leaf{0x000906A4, 0x00400800, 0x7FFAFBBF, 0xBFEBFBFF}},
1017 {{0x00000007, 0}, Leaf{0x00000001, 0xF3BFA7EB, 0x98C07FEE, 0xFC9CC510}},
1018 {{0x00000007, 1}, Leaf{0x00401C30, 0x00000000, 0x00000000, 0x00000000}},
1019 });
1020
1021 const auto info = GetX86Info();
1022
1023 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1024 EXPECT_EQ(info.family, 0x06);
1025 EXPECT_EQ(info.model, 0x9A);
1026 EXPECT_TRUE(info.features.avx512f);
1027 EXPECT_TRUE(info.features.avx512bw);
1028 EXPECT_TRUE(info.features.avx512dq);
1029 EXPECT_TRUE(info.features.avx512cd);
1030 EXPECT_TRUE(info.features.avx512vl);
1031 EXPECT_TRUE(info.features.avx512_vp2intersect);
1032 EXPECT_TRUE(info.features.avx512vbmi);
1033 EXPECT_TRUE(info.features.avx512vbmi2);
1034 EXPECT_TRUE(info.features.avx512bitalg);
1035 EXPECT_TRUE(info.features.avx512vpopcntdq);
1036 EXPECT_TRUE(info.features.avx512ifma);
1037 EXPECT_TRUE(info.features.avx512_bf16);
1038 EXPECT_TRUE(info.features.avx512_fp16);
1039
1040 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ADL);
1041 }
1042
1043 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00806C1_TigerLake_CPUID3.txt
TEST_F(CpuidX86Test,INTEL_TIGER_LAKE_AVX512)1044 TEST_F(CpuidX86Test, INTEL_TIGER_LAKE_AVX512) {
1045 cpu().SetOsBackupsExtendedRegisters(true);
1046 #if defined(CPU_FEATURES_OS_MACOS)
1047 cpu().SetDarwinSysCtlByName("hw.optional.avx512f");
1048 #endif
1049 cpu().SetLeaves({
1050 {{0x00000000, 0}, Leaf{0x0000001B, 0x756E6547, 0x6C65746E, 0x49656E69}},
1051 {{0x00000001, 0}, Leaf{0x000806C1, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
1052 {{0x00000007, 0}, Leaf{0x00000000, 0xF3BFA7EB, 0x18C05FCE, 0xFC100510}},
1053 });
1054
1055 const auto info = GetX86Info();
1056
1057 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1058 EXPECT_EQ(info.family, 0x06);
1059 EXPECT_EQ(info.model, 0x8C);
1060 EXPECT_TRUE(info.features.avx512f);
1061 EXPECT_TRUE(info.features.avx512bw);
1062 EXPECT_TRUE(info.features.avx512dq);
1063 EXPECT_TRUE(info.features.avx512cd);
1064 EXPECT_TRUE(info.features.avx512vl);
1065 EXPECT_TRUE(info.features.avx512_vp2intersect);
1066 EXPECT_TRUE(info.features.avx512vbmi);
1067 EXPECT_TRUE(info.features.avx512vbmi2);
1068 EXPECT_TRUE(info.features.avx512bitalg);
1069 EXPECT_TRUE(info.features.avx512vpopcntdq);
1070 EXPECT_TRUE(info.features.avx512ifma);
1071
1072 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_TGL);
1073 }
1074
1075 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00706E5_IceLakeY_CPUID.txt
TEST_F(CpuidX86Test,INTEL_ICE_LAKE_GFNI)1076 TEST_F(CpuidX86Test, INTEL_ICE_LAKE_GFNI) {
1077 cpu().SetLeaves({
1078 {{0x00000000, 0}, Leaf{0x0000001B, 0x756E6547, 0x6C65746E, 0x49656E69}},
1079 {{0x00000001, 0}, Leaf{0x000706E5, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
1080 {{0x00000007, 0}, Leaf{0x00000000, 0xF2BF27EF, 0x40405F4E, 0xBC000410}},
1081 });
1082
1083 const auto info = GetX86Info();
1084
1085 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1086 EXPECT_EQ(info.family, 0x06);
1087 EXPECT_EQ(info.model, 0x7E);
1088 EXPECT_TRUE(info.features.gfni);
1089
1090 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ICL);
1091 }
1092
1093 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00906C0_JasperLake_CPUID01.txt
TEST_F(CpuidX86Test,INTEL_TREMONT_JASPER_LAKE_MOVDR)1094 TEST_F(CpuidX86Test, INTEL_TREMONT_JASPER_LAKE_MOVDR) {
1095 cpu().SetLeaves({
1096 {{0x00000000, 0}, Leaf{0x0000001B, 0x756E6547, 0x6C65746E, 0x49656E69}},
1097 {{0x00000001, 0}, Leaf{0x00090661, 0x00800800, 0x4FF8EBBF, 0xBFEBFBFF}},
1098 {{0x00000007, 0}, Leaf{0x00000000, 0x2394A2C3, 0x18400124, 0xFC000400}},
1099 });
1100
1101 const auto info = GetX86Info();
1102
1103 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1104 EXPECT_EQ(info.family, 0x06);
1105 EXPECT_EQ(info.model, 0x96);
1106 EXPECT_TRUE(info.features.movdiri);
1107 EXPECT_TRUE(info.features.movdir64b);
1108
1109 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ATOM_TMT);
1110 }
1111
1112 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel0090672_AlderLake_LC_BC_CPUID01.txt
TEST_F(CpuidX86Test,INTEL_ALDER_LAKE_REP)1113 TEST_F(CpuidX86Test, INTEL_ALDER_LAKE_REP) {
1114 cpu().SetLeaves({
1115 {{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}},
1116 {{0x00000001, 0}, Leaf{0x00090672, 0x00800800, 0x7FFAFBFF, 0xBFEBFBFF}},
1117 {{0x00000007, 0}, Leaf{0x00000001, 0x239CA7EB, 0x98C027AC, 0xFC1CC410}},
1118 {{0x00000007, 1}, Leaf{0x00400810, 0x00000000, 0x00000000, 0x00000000}},
1119 });
1120
1121 const auto info = GetX86Info();
1122
1123 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1124 EXPECT_EQ(info.family, 0x06);
1125 EXPECT_EQ(info.model, 0x97);
1126 EXPECT_TRUE(info.features.erms);
1127 EXPECT_TRUE(info.features.fs_rep_mov);
1128 EXPECT_FALSE(info.features.fz_rep_movsb);
1129 EXPECT_TRUE(info.features.fs_rep_stosb);
1130 EXPECT_FALSE(info.features.fs_rep_cmpsb_scasb);
1131
1132 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ADL);
1133 }
1134
1135 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0100FA0_K10_Thuban_CPUID.txt
TEST_F(CpuidX86Test,AMD_THUBAN_CACHE_INFO)1136 TEST_F(CpuidX86Test, AMD_THUBAN_CACHE_INFO) {
1137 cpu().SetLeaves({
1138 {{0x00000000, 0}, Leaf{0x00000006, 0x68747541, 0x444D4163, 0x69746E65}},
1139 {{0x80000000, 0}, Leaf{0x8000001B, 0x68747541, 0x444D4163, 0x69746E65}},
1140 {{0x80000001, 0}, Leaf{0x00100FA0, 0x10000050, 0x000037FF, 0xEFD3FBFF}},
1141 {{0x80000005, 0}, Leaf{0xFF30FF10, 0xFF30FF20, 0x40020140, 0x40020140}},
1142 {{0x80000006, 0}, Leaf{0x20800000, 0x42004200, 0x02008140, 0x0030B140}},
1143 });
1144 const auto info = GetX86CacheInfo();
1145
1146 EXPECT_EQ(info.size, 4);
1147 EXPECT_EQ(info.levels[0].level, 1);
1148 EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA);
1149 EXPECT_EQ(info.levels[0].cache_size, 64 * KiB);
1150 EXPECT_EQ(info.levels[0].ways, 2);
1151 EXPECT_EQ(info.levels[0].line_size, 64);
1152
1153 EXPECT_EQ(info.levels[1].level, 1);
1154 EXPECT_EQ(info.levels[1].cache_type,
1155 CacheType::CPU_FEATURE_CACHE_INSTRUCTION);
1156 EXPECT_EQ(info.levels[1].cache_size, 64 * KiB);
1157 EXPECT_EQ(info.levels[1].ways, 2);
1158 EXPECT_EQ(info.levels[1].line_size, 64);
1159
1160 EXPECT_EQ(info.levels[2].level, 2);
1161 EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
1162 EXPECT_EQ(info.levels[2].cache_size, 512 * KiB);
1163 EXPECT_EQ(info.levels[2].ways, 16);
1164 EXPECT_EQ(info.levels[2].line_size, 64);
1165
1166 EXPECT_EQ(info.levels[3].level, 3);
1167 EXPECT_EQ(info.levels[3].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
1168 EXPECT_EQ(info.levels[3].cache_size, 6 * MiB);
1169 EXPECT_EQ(info.levels[3].ways, 48);
1170 EXPECT_EQ(info.levels[3].line_size, 64);
1171 }
1172
1173 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0020FB1_K8_Manchester_CPUID.txt
TEST_F(CpuidX86Test,AMD_MANCHESTER_CACHE_INFO)1174 TEST_F(CpuidX86Test, AMD_MANCHESTER_CACHE_INFO) {
1175 cpu().SetLeaves({
1176 {{0x00000000, 0}, Leaf{0x00000001, 0x68747541, 0x444D4163, 0x69746E65}},
1177 {{0x80000000, 0}, Leaf{0x80000018, 0x68747541, 0x444D4163, 0x69746E65}},
1178 {{0x80000001, 0}, Leaf{0x00020FB1, 0x00000150, 0x00000003, 0xE3D3FBFF}},
1179 {{0x80000005, 0}, Leaf{0xFF08FF08, 0xFF20FF20, 0x40020140, 0x40020140}},
1180 {{0x80000006, 0}, Leaf{0x00000000, 0x42004200, 0x02008140, 0x00000000}},
1181 });
1182 const auto info = GetX86CacheInfo();
1183
1184 EXPECT_EQ(info.size, 3);
1185 EXPECT_EQ(info.levels[0].level, 1);
1186 EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA);
1187 EXPECT_EQ(info.levels[0].cache_size, 64 * KiB);
1188 EXPECT_EQ(info.levels[0].ways, 2);
1189 EXPECT_EQ(info.levels[0].line_size, 64);
1190
1191 EXPECT_EQ(info.levels[1].level, 1);
1192 EXPECT_EQ(info.levels[1].cache_type,
1193 CacheType::CPU_FEATURE_CACHE_INSTRUCTION);
1194 EXPECT_EQ(info.levels[1].cache_size, 64 * KiB);
1195 EXPECT_EQ(info.levels[1].ways, 2);
1196 EXPECT_EQ(info.levels[1].line_size, 64);
1197
1198 EXPECT_EQ(info.levels[2].level, 2);
1199 EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
1200 EXPECT_EQ(info.levels[2].cache_size, 512 * KiB);
1201 EXPECT_EQ(info.levels[2].ways, 16);
1202 EXPECT_EQ(info.levels[2].line_size, 64);
1203 }
1204
1205 // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0100F22_K10_Agena_CPUID.txt
TEST_F(CpuidX86Test,AMD_AGENA_CACHE_INFO)1206 TEST_F(CpuidX86Test, AMD_AGENA_CACHE_INFO) {
1207 cpu().SetLeaves({
1208 {{0x00000000, 0}, Leaf{0x00000005, 0x68747541, 0x444D4163, 0x69746E65}},
1209 {{0x80000000, 0}, Leaf{0x8000001A, 0x68747541, 0x444D4163, 0x69746E65}},
1210 {{0x80000001, 0}, Leaf{0x00100F22, 0x10000000, 0x000007FF, 0xEFD3FBFF}},
1211 {{0x80000005, 0}, Leaf{0xFF30FF10, 0xFF30FF20, 0x40020140, 0x40020140}},
1212 {{0x80000006, 0}, Leaf{0x20800000, 0x42004200, 0x02008140, 0x0010A140}},
1213 });
1214 const auto info = GetX86CacheInfo();
1215
1216 EXPECT_EQ(info.size, 4);
1217 EXPECT_EQ(info.levels[0].level, 1);
1218 EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA);
1219 EXPECT_EQ(info.levels[0].cache_size, 64 * KiB);
1220 EXPECT_EQ(info.levels[0].ways, 2);
1221 EXPECT_EQ(info.levels[0].line_size, 64);
1222
1223 EXPECT_EQ(info.levels[1].level, 1);
1224 EXPECT_EQ(info.levels[1].cache_type,
1225 CacheType::CPU_FEATURE_CACHE_INSTRUCTION);
1226 EXPECT_EQ(info.levels[1].cache_size, 64 * KiB);
1227 EXPECT_EQ(info.levels[1].ways, 2);
1228 EXPECT_EQ(info.levels[1].line_size, 64);
1229
1230 EXPECT_EQ(info.levels[2].level, 2);
1231 EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
1232 EXPECT_EQ(info.levels[2].cache_size, 512 * KiB);
1233 EXPECT_EQ(info.levels[2].ways, 16);
1234 EXPECT_EQ(info.levels[2].line_size, 64);
1235
1236 EXPECT_EQ(info.levels[3].level, 3);
1237 EXPECT_EQ(info.levels[3].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED);
1238 EXPECT_EQ(info.levels[3].cache_size, 2 * MiB);
1239 EXPECT_EQ(info.levels[3].ways, 32);
1240 EXPECT_EQ(info.levels[3].line_size, 64);
1241 }
1242
1243 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00106A1_Nehalem_CPUID.txt
TEST_F(CpuidX86Test,Nehalem)1244 TEST_F(CpuidX86Test, Nehalem) {
1245 // Pre AVX cpus don't have xsave
1246 cpu().SetOsBackupsExtendedRegisters(false);
1247 #if defined(CPU_FEATURES_OS_WINDOWS)
1248 cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
1249 cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
1250 cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE);
1251 cpu().SetWindowsIsProcessorFeaturePresent(PF_SSSE3_INSTRUCTIONS_AVAILABLE);
1252 cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE4_1_INSTRUCTIONS_AVAILABLE);
1253 cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE4_2_INSTRUCTIONS_AVAILABLE);
1254 #elif defined(CPU_FEATURES_OS_MACOS)
1255 cpu().SetDarwinSysCtlByName("hw.optional.sse");
1256 cpu().SetDarwinSysCtlByName("hw.optional.sse2");
1257 cpu().SetDarwinSysCtlByName("hw.optional.sse3");
1258 cpu().SetDarwinSysCtlByName("hw.optional.supplementalsse3");
1259 cpu().SetDarwinSysCtlByName("hw.optional.sse4_1");
1260 cpu().SetDarwinSysCtlByName("hw.optional.sse4_2");
1261 #elif defined(CPU_FEATURES_OS_FREEBSD)
1262 auto& fs = GetEmptyFilesystem();
1263 fs.CreateFile("/var/run/dmesg.boot", R"(
1264 ---<<BOOT>>---
1265 Copyright (c) 1992-2020 The FreeBSD Project.
1266 FreeBSD is a registered trademark of The FreeBSD Foundation.
1267 Features=0x1783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2,HTT>
1268 Features2=0x5eda2203<SSE3,PCLMULQDQ,SSSE3,CX16,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,RDRAND>
1269 real memory = 2147418112 (2047 MB)
1270 )");
1271 #elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
1272 auto& fs = GetEmptyFilesystem();
1273 fs.CreateFile("/proc/cpuinfo", R"(processor :
1274 flags : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2
1275 )");
1276 #endif
1277 cpu().SetLeaves({
1278 {{0x00000000, 0}, Leaf{0x0000000B, 0x756E6547, 0x6C65746E, 0x49656E69}},
1279 {{0x00000001, 0}, Leaf{0x000106A2, 0x00100800, 0x00BCE3BD, 0xBFEBFBFF}},
1280 {{0x00000002, 0}, Leaf{0x55035A01, 0x00F0B0E3, 0x00000000, 0x09CA212C}},
1281 {{0x00000003, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
1282 {{0x00000004, 0}, Leaf{0x1C004121, 0x01C0003F, 0x0000003F, 0x00000000}},
1283 {{0x00000004, 0}, Leaf{0x1C004122, 0x00C0003F, 0x0000007F, 0x00000000}},
1284 {{0x00000004, 0}, Leaf{0x1C004143, 0x01C0003F, 0x000001FF, 0x00000000}},
1285 {{0x00000004, 0}, Leaf{0x1C03C163, 0x03C0003F, 0x00000FFF, 0x00000002}},
1286 {{0x00000005, 0}, Leaf{0x00000040, 0x00000040, 0x00000003, 0x00021120}},
1287 {{0x00000006, 0}, Leaf{0x00000001, 0x00000002, 0x00000001, 0x00000000}},
1288 {{0x00000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
1289 {{0x00000008, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
1290 {{0x00000009, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
1291 {{0x0000000A, 0}, Leaf{0x07300403, 0x00000000, 0x00000000, 0x00000603}},
1292 {{0x0000000B, 0}, Leaf{0x00000001, 0x00000001, 0x00000100, 0x00000000}},
1293 {{0x0000000B, 0}, Leaf{0x00000004, 0x00000002, 0x00000201, 0x00000000}},
1294 {{0x80000000, 0}, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}},
1295 {{0x80000001, 0}, Leaf{0x00000000, 0x00000000, 0x00000001, 0x28100000}},
1296 {{0x80000002, 0}, Leaf{0x756E6547, 0x20656E69, 0x65746E49, 0x2952286C}},
1297 {{0x80000003, 0}, Leaf{0x55504320, 0x20202020, 0x20202020, 0x40202020}},
1298 {{0x80000004, 0}, Leaf{0x30303020, 0x20402030, 0x37382E31, 0x007A4847}},
1299 {{0x80000005, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
1300 {{0x80000006, 0}, Leaf{0x00000000, 0x00000000, 0x01006040, 0x00000000}},
1301 {{0x80000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000100}},
1302 {{0x80000008, 0}, Leaf{0x00003028, 0x00000000, 0x00000000, 0x00000000}},
1303 });
1304 const auto info = GetX86Info();
1305
1306 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1307 EXPECT_EQ(info.family, 0x06);
1308 EXPECT_EQ(info.model, 0x1A);
1309 EXPECT_EQ(info.stepping, 0x02);
1310 EXPECT_STREQ(info.brand_string,
1311 "Genuine Intel(R) CPU @ 0000 @ 1.87GHz");
1312 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_NHM);
1313
1314 EXPECT_TRUE(info.features.sse);
1315 EXPECT_TRUE(info.features.sse2);
1316 EXPECT_TRUE(info.features.sse3);
1317 EXPECT_TRUE(info.features.ssse3);
1318 EXPECT_TRUE(info.features.sse4_1);
1319 EXPECT_TRUE(info.features.sse4_2);
1320 }
1321
1322 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0030673_Silvermont3_CPUID.txt
TEST_F(CpuidX86Test,Atom)1323 TEST_F(CpuidX86Test, Atom) {
1324 // Pre AVX cpus don't have xsave
1325 cpu().SetOsBackupsExtendedRegisters(false);
1326 #if defined(CPU_FEATURES_OS_WINDOWS)
1327 cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
1328 cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
1329 cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE);
1330 cpu().SetWindowsIsProcessorFeaturePresent(PF_SSSE3_INSTRUCTIONS_AVAILABLE);
1331 cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE4_1_INSTRUCTIONS_AVAILABLE);
1332 cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE4_2_INSTRUCTIONS_AVAILABLE);
1333 #elif defined(CPU_FEATURES_OS_MACOS)
1334 cpu().SetDarwinSysCtlByName("hw.optional.sse");
1335 cpu().SetDarwinSysCtlByName("hw.optional.sse2");
1336 cpu().SetDarwinSysCtlByName("hw.optional.sse3");
1337 cpu().SetDarwinSysCtlByName("hw.optional.supplementalsse3");
1338 cpu().SetDarwinSysCtlByName("hw.optional.sse4_1");
1339 cpu().SetDarwinSysCtlByName("hw.optional.sse4_2");
1340 #elif defined(CPU_FEATURES_OS_FREEBSD)
1341 auto& fs = GetEmptyFilesystem();
1342 fs.CreateFile("/var/run/dmesg.boot", R"(
1343 ---<<BOOT>>---
1344 Copyright (c) 1992-2020 The FreeBSD Project.
1345 FreeBSD is a registered trademark of The FreeBSD Foundation.
1346 Features=0x1783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2,HTT>
1347 Features2=0x5eda2203<SSE3,PCLMULQDQ,SSSE3,CX16,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,RDRAND>
1348 real memory = 2147418112 (2047 MB)
1349 )");
1350 #elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
1351 auto& fs = GetEmptyFilesystem();
1352 fs.CreateFile("/proc/cpuinfo", R"(
1353 flags : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2
1354 )");
1355 #endif
1356 cpu().SetLeaves({
1357 {{0x00000000, 0}, Leaf{0x0000000B, 0x756E6547, 0x6C65746E, 0x49656E69}},
1358 {{0x00000001, 0}, Leaf{0x00030673, 0x00100800, 0x41D8E3BF, 0xBFEBFBFF}},
1359 {{0x00000002, 0}, Leaf{0x61B3A001, 0x0000FFC2, 0x00000000, 0x00000000}},
1360 {{0x00000003, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
1361 {{0x00000004, 0}, Leaf{0x1C000121, 0x0140003F, 0x0000003F, 0x00000001}},
1362 {{0x00000004, 1}, Leaf{0x1C000122, 0x01C0003F, 0x0000003F, 0x00000001}},
1363 {{0x00000004, 2}, Leaf{0x1C00C143, 0x03C0003F, 0x000003FF, 0x00000001}},
1364 {{0x00000005, 0}, Leaf{0x00000040, 0x00000040, 0x00000003, 0x33000020}},
1365 {{0x00000006, 0}, Leaf{0x00000005, 0x00000002, 0x00000009, 0x00000000}},
1366 {{0x00000007, 0}, Leaf{0x00000000, 0x00002282, 0x00000000, 0x00000000}},
1367 {{0x00000008, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
1368 {{0x00000009, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
1369 {{0x0000000A, 0}, Leaf{0x07280203, 0x00000000, 0x00000000, 0x00004503}},
1370 {{0x0000000B, 0}, Leaf{0x00000001, 0x00000001, 0x00000100, 0x00000000}},
1371 {{0x0000000B, 1}, Leaf{0x00000004, 0x00000004, 0x00000201, 0x00000000}},
1372 {{0x80000000, 0}, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}},
1373 {{0x80000001, 0}, Leaf{0x00000000, 0x00000000, 0x00000101, 0x28100000}},
1374 {{0x80000002, 0}, Leaf{0x20202020, 0x6E492020, 0x286C6574, 0x43202952}},
1375 {{0x80000003, 0}, Leaf{0x72656C65, 0x52286E6F, 0x50432029, 0x4A202055}},
1376 {{0x80000004, 0}, Leaf{0x30303931, 0x20402020, 0x39392E31, 0x007A4847}},
1377 {{0x80000005, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
1378 {{0x80000006, 0}, Leaf{0x00000000, 0x00000000, 0x04008040, 0x00000000}},
1379 {{0x80000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000100}},
1380 {{0x80000008, 0}, Leaf{0x00003024, 0x00000000, 0x00000000, 0x00000000}},
1381 });
1382 const auto info = GetX86Info();
1383
1384 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1385 EXPECT_EQ(info.family, 0x06);
1386 EXPECT_EQ(info.model, 0x37);
1387 EXPECT_EQ(info.stepping, 0x03);
1388 EXPECT_STREQ(info.brand_string,
1389 " Intel(R) Celeron(R) CPU J1900 @ 1.99GHz");
1390 EXPECT_EQ(GetX86Microarchitecture(&info),
1391 X86Microarchitecture::INTEL_ATOM_SMT);
1392
1393 EXPECT_TRUE(info.features.sse);
1394 EXPECT_TRUE(info.features.sse2);
1395 EXPECT_TRUE(info.features.sse3);
1396 EXPECT_TRUE(info.features.ssse3);
1397 EXPECT_TRUE(info.features.sse4_1);
1398 EXPECT_TRUE(info.features.sse4_2);
1399 }
1400
1401 // https://www.felixcloutier.com/x86/cpuid#example-3-1--example-of-cache-and-tlb-interpretation
TEST_F(CpuidX86Test,P4_CacheInfo)1402 TEST_F(CpuidX86Test, P4_CacheInfo) {
1403 cpu().SetLeaves({
1404 {{0x00000000, 0}, Leaf{0x00000002, 0x756E6547, 0x6C65746E, 0x49656E69}},
1405 {{0x00000001, 0}, Leaf{0x00000F0A, 0x00010808, 0x00000000, 0x3FEBFBFF}},
1406 {{0x00000002, 0}, Leaf{0x665B5001, 0x00000000, 0x00000000, 0x007A7000}},
1407 });
1408
1409 const auto info = GetX86CacheInfo();
1410 EXPECT_EQ(info.size, 5);
1411
1412 EXPECT_EQ(info.levels[0].level, UNDEF);
1413 EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_TLB);
1414 EXPECT_EQ(info.levels[0].cache_size, 4 * KiB);
1415 EXPECT_EQ(info.levels[0].ways, UNDEF);
1416 EXPECT_EQ(info.levels[0].line_size, UNDEF);
1417 EXPECT_EQ(info.levels[0].tlb_entries, 64);
1418 EXPECT_EQ(info.levels[0].partitioning, 0);
1419
1420 EXPECT_EQ(info.levels[1].level, UNDEF);
1421 EXPECT_EQ(info.levels[1].cache_type, CacheType::CPU_FEATURE_CACHE_TLB);
1422 EXPECT_EQ(info.levels[1].cache_size, 4 * KiB);
1423 EXPECT_EQ(info.levels[1].ways, UNDEF);
1424 EXPECT_EQ(info.levels[1].line_size, UNDEF);
1425 EXPECT_EQ(info.levels[1].tlb_entries, 64);
1426 EXPECT_EQ(info.levels[1].partitioning, 0);
1427
1428 EXPECT_EQ(info.levels[2].level, 1);
1429 EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_DATA);
1430 EXPECT_EQ(info.levels[2].cache_size, 8 * KiB);
1431 EXPECT_EQ(info.levels[2].ways, 4);
1432 EXPECT_EQ(info.levels[2].line_size, 64);
1433 EXPECT_EQ(info.levels[2].tlb_entries, UNDEF);
1434 EXPECT_EQ(info.levels[2].partitioning, 0);
1435
1436 EXPECT_EQ(info.levels[3].level, 1);
1437 EXPECT_EQ(info.levels[3].cache_type,
1438 CacheType::CPU_FEATURE_CACHE_INSTRUCTION);
1439 EXPECT_EQ(info.levels[3].cache_size, 12 * KiB);
1440 EXPECT_EQ(info.levels[3].ways, 8);
1441 EXPECT_EQ(info.levels[3].line_size, UNDEF);
1442 EXPECT_EQ(info.levels[3].tlb_entries, UNDEF);
1443 EXPECT_EQ(info.levels[3].partitioning, 0);
1444
1445 EXPECT_EQ(info.levels[4].level, 2);
1446 EXPECT_EQ(info.levels[4].cache_type, CacheType::CPU_FEATURE_CACHE_DATA);
1447 EXPECT_EQ(info.levels[4].cache_size, 256 * KiB);
1448 EXPECT_EQ(info.levels[4].ways, 8);
1449 EXPECT_EQ(info.levels[4].line_size, 64);
1450 EXPECT_EQ(info.levels[4].tlb_entries, UNDEF);
1451 EXPECT_EQ(info.levels[4].partitioning, 2);
1452 }
1453
1454 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000673_P3_KatmaiDP_CPUID.txt
TEST_F(CpuidX86Test,P3)1455 TEST_F(CpuidX86Test, P3) {
1456 // Pre AVX cpus don't have xsave
1457 cpu().SetOsBackupsExtendedRegisters(false);
1458 #if defined(CPU_FEATURES_OS_WINDOWS)
1459 cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
1460 #elif defined(CPU_FEATURES_OS_MACOS)
1461 cpu().SetDarwinSysCtlByName("hw.optional.sse");
1462 #elif defined(CPU_FEATURES_OS_FREEBSD)
1463 auto& fs = GetEmptyFilesystem();
1464 fs.CreateFile("/var/run/dmesg.boot", R"(
1465 ---<<BOOT>>---
1466 Copyright (c) 1992-2020 The FreeBSD Project.
1467 FreeBSD is a registered trademark of The FreeBSD Foundation.
1468 Features=0x1783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE>
1469 real memory = 2147418112 (2047 MB)
1470 )");
1471 #elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
1472 auto& fs = GetEmptyFilesystem();
1473 fs.CreateFile("/proc/cpuinfo", R"(
1474 flags : fpu mmx sse
1475 )");
1476 #endif
1477 cpu().SetLeaves({
1478 {{0x00000000, 0}, Leaf{0x00000003, 0x756E6547, 0x6C65746E, 0x49656E69}},
1479 {{0x00000001, 0}, Leaf{0x00000673, 0x00000000, 0x00000000, 0x0387FBFF}},
1480 {{0x00000002, 0}, Leaf{0x03020101, 0x00000000, 0x00000000, 0x0C040843}},
1481 {{0x00000003, 0}, Leaf{0x00000000, 0x00000000, 0x4CECC782, 0x00006778}},
1482 });
1483 const auto info = GetX86Info();
1484
1485 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1486 EXPECT_EQ(info.family, 0x06);
1487 EXPECT_EQ(info.model, 0x07);
1488 EXPECT_EQ(info.stepping, 0x03);
1489 EXPECT_STREQ(info.brand_string, "");
1490 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::X86_UNKNOWN);
1491
1492 EXPECT_TRUE(info.features.mmx);
1493 EXPECT_TRUE(info.features.sse);
1494 EXPECT_FALSE(info.features.sse2);
1495 EXPECT_FALSE(info.features.sse3);
1496 EXPECT_FALSE(info.features.ssse3);
1497 EXPECT_FALSE(info.features.sse4_1);
1498 EXPECT_FALSE(info.features.sse4_2);
1499 }
1500
1501 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000480_486_CPUID.txt
TEST_F(CpuidX86Test,INTEL_80486)1502 TEST_F(CpuidX86Test, INTEL_80486) {
1503 cpu().SetLeaves({
1504 {{0x00000000, 0}, Leaf{0x00000001, 0x756E6547, 0x6C65746E, 0x49656E69}},
1505 {{0x00000001, 0}, Leaf{0x00000480, 0x00000000, 0x00000000, 0x00000003}},
1506 });
1507 const auto info = GetX86Info();
1508
1509 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1510 EXPECT_EQ(info.family, 0x04);
1511 EXPECT_EQ(info.model, 0x08);
1512 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_80486);
1513 }
1514
1515 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000526_P54C_CPUID.txt
TEST_F(CpuidX86Test,INTEL_P54C)1516 TEST_F(CpuidX86Test, INTEL_P54C) {
1517 cpu().SetLeaves({
1518 {{0x00000000, 0}, Leaf{0x00000001, 0x756E6547, 0x6C65746E, 0x49656E69}},
1519 {{0x00000001, 0}, Leaf{0x00000525, 0x00000000, 0x00000000, 0x000001BF}},
1520 });
1521 const auto info = GetX86Info();
1522
1523 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1524 EXPECT_EQ(info.family, 0x05);
1525 EXPECT_EQ(info.model, 0x02);
1526 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_P5);
1527 }
1528
1529 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000590_Lakemont_CPUID2.txt
TEST_F(CpuidX86Test,INTEL_LAKEMONT)1530 TEST_F(CpuidX86Test, INTEL_LAKEMONT) {
1531 cpu().SetLeaves({
1532 {{0x00000000, 0}, Leaf{0x00000002, 0x756E6547, 0x6c65746E, 0x49656E69}},
1533 {{0x00000001, 0}, Leaf{0x00000590, 0x00000000, 0x00010200, 0x8000237B}},
1534 });
1535 const auto info = GetX86Info();
1536
1537 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1538 EXPECT_EQ(info.family, 0x05);
1539 EXPECT_EQ(info.model, 0x09);
1540 EXPECT_EQ(GetX86Microarchitecture(&info),
1541 X86Microarchitecture::INTEL_LAKEMONT);
1542 }
1543
1544 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00006E8_PM_Yonah_CPUID.txt
TEST_F(CpuidX86Test,INTEL_CORE_YONAH)1545 TEST_F(CpuidX86Test, INTEL_CORE_YONAH) {
1546 cpu().SetLeaves({
1547 {{0x00000000, 0}, Leaf{0x0000000A, 0x756E6547, 0x6C65746E, 0x49656E69}},
1548 {{0x00000001, 0}, Leaf{0x000006E8, 0x00010800, 0x0000C109, 0xAFE9FBFF}},
1549 });
1550 const auto info = GetX86Info();
1551
1552 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1553 EXPECT_EQ(info.family, 0x06);
1554 EXPECT_EQ(info.model, 0x0E);
1555 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_CORE);
1556 }
1557
1558 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00706A8_GoldmontPlus_CPUID.txt
TEST_F(CpuidX86Test,INTEL_GOLDMONT_PLUS)1559 TEST_F(CpuidX86Test, INTEL_GOLDMONT_PLUS) {
1560 cpu().SetLeaves({
1561 {{0x00000000, 0}, Leaf{0x00000018, 0x756E6547, 0x6c65746E, 0x49656E69}},
1562 {{0x00000001, 0}, Leaf{0x000706A8, 0x00400800, 0x4FF8EBBF, 0xBFEBFBFF}},
1563 });
1564 const auto info = GetX86Info();
1565
1566 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1567 EXPECT_EQ(info.family, 0x06);
1568 EXPECT_EQ(info.model, 0x7A);
1569 EXPECT_EQ(GetX86Microarchitecture(&info),
1570 X86Microarchitecture::INTEL_ATOM_GMT_PLUS);
1571 }
1572
1573 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0050670_KnightsLanding_CPUID.txt
TEST_F(CpuidX86Test,INTEL_KNIGHTS_LANDING)1574 TEST_F(CpuidX86Test, INTEL_KNIGHTS_LANDING) {
1575 cpu().SetLeaves({
1576 {{0x00000000, 0}, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}},
1577 {{0x00000001, 0}, Leaf{0x00050670, 0x02FF0800, 0x7FF8F3BF, 0xBFEBFBFF}},
1578 });
1579 const auto info = GetX86Info();
1580
1581 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1582 EXPECT_EQ(info.family, 0x06);
1583 EXPECT_EQ(info.model, 0x57);
1584 EXPECT_EQ(GetX86Microarchitecture(&info),
1585 X86Microarchitecture::INTEL_KNIGHTS_L);
1586 }
1587
1588 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00806EC_CometLake_CPUID2.txt
TEST_F(CpuidX86Test,INTEL_CML_U)1589 TEST_F(CpuidX86Test, INTEL_CML_U) {
1590 cpu().SetLeaves({
1591 {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
1592 {{0x00000001, 0}, Leaf{0x000806EC, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
1593 });
1594 const auto info = GetX86Info();
1595
1596 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1597 EXPECT_EQ(info.family, 0x06);
1598 EXPECT_EQ(info.model, 0x8E);
1599 EXPECT_EQ(info.stepping, 0x0C);
1600 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_CML);
1601 }
1602
1603 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00A0652_CometLake_CPUID1.txt
TEST_F(CpuidX86Test,INTEL_CML_H)1604 TEST_F(CpuidX86Test, INTEL_CML_H) {
1605 cpu().SetLeaves({
1606 {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
1607 {{0x00000001, 0}, Leaf{0x000A0652, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
1608 });
1609 const auto info = GetX86Info();
1610
1611 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1612 EXPECT_EQ(info.family, 0x06);
1613 EXPECT_EQ(info.model, 0xA5);
1614 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_CML);
1615 }
1616
1617 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00A0660_CometLake_CPUID1.txt
TEST_F(CpuidX86Test,INTEL_CML_U2)1618 TEST_F(CpuidX86Test, INTEL_CML_U2) {
1619 cpu().SetLeaves({
1620 {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
1621 {{0x00000001, 0}, Leaf{0x000A0660, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
1622 });
1623 const auto info = GetX86Info();
1624
1625 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1626 EXPECT_EQ(info.family, 0x06);
1627 EXPECT_EQ(info.model, 0xA6);
1628 EXPECT_EQ(info.stepping, 0x00);
1629 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_CML);
1630 }
1631
1632 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00806A1_Lakefield_CPUID.txt
TEST_F(CpuidX86Test,INTEL_ATOM_TMT_LAKEFIELD)1633 TEST_F(CpuidX86Test, INTEL_ATOM_TMT_LAKEFIELD) {
1634 cpu().SetLeaves({
1635 {{0x00000000, 0}, Leaf{0x0000001B, 0x756E6547, 0x6C65746E, 0x49656E69}},
1636 {{0x00000001, 0}, Leaf{0x000806A1, 0x00100800, 0x4FD8EBBF, 0xBFEBFBFF}},
1637 });
1638 const auto info = GetX86Info();
1639
1640 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1641 EXPECT_EQ(info.family, 0x06);
1642 EXPECT_EQ(info.model, 0x8A);
1643 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ATOM_TMT);
1644 }
1645
1646 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0090661_ElkhartLake_CPUID01.txt
TEST_F(CpuidX86Test,INTEL_ATOM_TMT_ELKHART_LAKE)1647 TEST_F(CpuidX86Test, INTEL_ATOM_TMT_ELKHART_LAKE) {
1648 cpu().SetLeaves({
1649 {{0x00000000, 0}, Leaf{0x0000001B, 0x756E6547, 0x6C65746E, 0x49656E69}},
1650 {{0x00000001, 0}, Leaf{0x00090661, 0x00800800, 0x4FF8EBBF, 0xBFEBFBFF}},
1651 });
1652 const auto info = GetX86Info();
1653
1654 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1655 EXPECT_EQ(info.family, 0x06);
1656 EXPECT_EQ(info.model, 0x96);
1657 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ATOM_TMT);
1658 }
1659
1660 // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00906C0_JasperLake_01_CPUID.txt
TEST_F(CpuidX86Test,INTEL_ATOM_TMT_JASPER_LAKE)1661 TEST_F(CpuidX86Test, INTEL_ATOM_TMT_JASPER_LAKE) {
1662 cpu().SetLeaves({
1663 {{0x00000000, 0}, Leaf{0x0000001B, 0x756E6547, 0x6C65746E, 0x49656E69}},
1664 {{0x00000001, 0}, Leaf{0x000906C0, 0x00800800, 0x4FF8EBBF, 0xBFEBFBFF}},
1665 });
1666 const auto info = GetX86Info();
1667
1668 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1669 EXPECT_EQ(info.family, 0x06);
1670 EXPECT_EQ(info.model, 0x9C);
1671 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ATOM_TMT);
1672 }
1673
1674 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00B0671_RaptorLake_02_CPUID.txt
TEST_F(CpuidX86Test,INTEL_RAPTOR_LAKE)1675 TEST_F(CpuidX86Test, INTEL_RAPTOR_LAKE) {
1676 cpu().SetLeaves({
1677 {{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}},
1678 {{0x00000001, 0}, Leaf{0x000B0671, 0x00800800, 0x7FFAFBBF, 0xBFEBFBFF}},
1679 });
1680 const auto info = GetX86Info();
1681
1682 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1683 EXPECT_EQ(info.family, 0x06);
1684 EXPECT_EQ(info.model, 0xB7);
1685 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_RPL);
1686 }
1687
1688 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00306F2_HaswellEP2_CPUID.txt
TEST_F(CpuidX86Test,INTEL_HASWELL_LZCNT)1689 TEST_F(CpuidX86Test, INTEL_HASWELL_LZCNT) {
1690 cpu().SetLeaves({
1691 {{0x00000000, 0}, Leaf{0x0000000F, 0x756E6547, 0x6C65746E, 0x49656E69}},
1692 {{0x00000001, 0}, Leaf{0x000306F2, 0x00200800, 0x7FFEFBFF, 0xBFEBFBFF}},
1693 {{0x00000007, 0}, Leaf{0x00000000, 0x000037AB, 0x00000000, 0x00000000}},
1694 {{0x80000000, 0}, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}},
1695 {{0x80000001, 0}, Leaf{0x00000000, 0x00000000, 0x00000021, 0x2C100000}},
1696 });
1697 const auto info = GetX86Info();
1698
1699 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1700 EXPECT_EQ(info.family, 0x06);
1701 EXPECT_EQ(info.model, 0x3F);
1702 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_HSW);
1703
1704 EXPECT_TRUE(info.features.lzcnt);
1705 }
1706
1707 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00B06A2_RaptorLakeP_03_CPUID.txt
TEST_F(CpuidX86Test,INTEL_RAPTOR_LAKE_P)1708 TEST_F(CpuidX86Test, INTEL_RAPTOR_LAKE_P) {
1709 cpu().SetLeaves({
1710 {{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}},
1711 {{0x00000001, 0}, Leaf{0x000B06A3, 0x00400800, 0x7FFAFBFF, 0xBFEBFBFF}},
1712 {{0x80000000, 0}, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}},
1713 {{0x80000001, 0}, Leaf{0x00000000, 0x00000000, 0x00000121, 0x2C100000}},
1714 });
1715 const auto info = GetX86Info();
1716
1717 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1718 EXPECT_EQ(info.family, 0x06);
1719 EXPECT_EQ(info.model, 0xBA);
1720 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_RPL);
1721 }
1722
1723 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00B06F2_RaptorLakeS_02_CPUID.txt
TEST_F(CpuidX86Test,INTEL_RAPTOR_LAKE_S)1724 TEST_F(CpuidX86Test, INTEL_RAPTOR_LAKE_S) {
1725 cpu().SetLeaves({
1726 {{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}},
1727 {{0x00000001, 0}, Leaf{0x000B06F2, 0x00800800, 0x7FFAFBFF, 0xBFEBFBFF}},
1728 {{0x80000000, 0}, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}},
1729 {{0x80000001, 0}, Leaf{0x00000000, 0x00000000, 0x00000121, 0x2C100000}},
1730 });
1731 const auto info = GetX86Info();
1732
1733 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1734 EXPECT_EQ(info.family, 0x06);
1735 EXPECT_EQ(info.model, 0xBF);
1736 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_RPL);
1737 }
1738
1739 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00B06E0_AlderLakeN_03_CPUID.txt
TEST_F(CpuidX86Test,INTEL_ALDER_LAKE_N)1740 TEST_F(CpuidX86Test, INTEL_ALDER_LAKE_N) {
1741 cpu().SetLeaves({
1742 {{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}},
1743 {{0x00000001, 0}, Leaf{0x000B06E0, 0x00800800, 0x7FFAFBBF, 0xBFEBFBFF}},
1744 });
1745 const auto info = GetX86Info();
1746
1747 EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
1748 EXPECT_EQ(info.family, 0x06);
1749 EXPECT_EQ(info.model, 0xBE);
1750 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ADL);
1751 }
1752
1753 // https://github.com/google/cpu_features/issues/200
1754 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00206F2_Eagleton_CPUID.txt
1755 #if defined(CPU_FEATURES_OS_WINDOWS)
TEST_F(CpuidX86Test,WIN_INTEL_WESTMERE_EX)1756 TEST_F(CpuidX86Test, WIN_INTEL_WESTMERE_EX) {
1757 // Pre AVX cpus don't have xsave
1758 cpu().SetOsBackupsExtendedRegisters(false);
1759 cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
1760 cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
1761 cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE);
1762 cpu().SetWindowsIsProcessorFeaturePresent(PF_SSSE3_INSTRUCTIONS_AVAILABLE);
1763 cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE4_1_INSTRUCTIONS_AVAILABLE);
1764 cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE4_2_INSTRUCTIONS_AVAILABLE);
1765
1766 cpu().SetLeaves({
1767 {{0x00000000, 0}, Leaf{0x0000000B, 0x756E6547, 0x6C65746E, 0x49656E69}},
1768 {{0x00000001, 0}, Leaf{0x000206F2, 0x00400800, 0x02BEE3FF, 0xBFEBFBFF}},
1769 });
1770 const auto info = GetX86Info();
1771
1772 EXPECT_EQ(info.family, 0x06);
1773 EXPECT_EQ(info.model, 0x2F);
1774 EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_WSM);
1775
1776 EXPECT_TRUE(info.features.sse);
1777 EXPECT_TRUE(info.features.sse2);
1778 EXPECT_TRUE(info.features.sse3);
1779 EXPECT_TRUE(info.features.ssse3);
1780 EXPECT_TRUE(info.features.sse4_1);
1781 EXPECT_TRUE(info.features.sse4_2);
1782 }
1783 #endif // CPU_FEATURES_OS_WINDOWS
1784
1785 // TODO(user): test what happens when xsave/osxsave are not present.
1786 // TODO(user): test what happens when xmm/ymm/zmm os support are not
1787 // present.
1788
1789 } // namespace
1790 } // namespace cpu_features
1791