diff --git a/include/cpuinfo_x86.h b/include/cpuinfo_x86.h index 5988bb97..adb11896 100644 --- a/include/cpuinfo_x86.h +++ b/include/cpuinfo_x86.h @@ -116,6 +116,9 @@ CacheInfo GetX86CacheInfo(void); typedef enum { X86_UNKNOWN, + INTEL_80486, // 80486 + INTEL_P5, // P5 + INTEL_LAKEMONT, // LAKEMONT INTEL_CORE, // CORE INTEL_PNR, // PENRYN INTEL_NHM, // NEHALEM @@ -135,6 +138,13 @@ typedef enum { INTEL_ICL, // ICE LAKE INTEL_TGL, // TIGER LAKE INTEL_SPR, // SAPPHIRE RAPIDS + INTEL_ADL, // ALDER LAKE + INTEL_RCL, // ROCKET LAKE + INTEL_KNIGHTS_M, // KNIGHTS MILL + INTEL_KNIGHTS_L, // KNIGHTS LANDING + INTEL_KNIGHTS_F, // KNIGHTS FERRY + INTEL_KNIGHTS_C, // KNIGHTS CORNER + INTEL_NETBURST, // NETBURST AMD_HAMMER, // K8 HAMMER AMD_K10, // K10 AMD_K11, // K11 diff --git a/src/impl_x86__base_implementation.inl b/src/impl_x86__base_implementation.inl index 3f474123..3a0326a3 100644 --- a/src/impl_x86__base_implementation.inl +++ b/src/impl_x86__base_implementation.inl @@ -384,6 +384,27 @@ X86Info GetX86Info(void) { X86Microarchitecture GetX86Microarchitecture(const X86Info* info) { if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_GENUINE_INTEL)) { switch (CPUID(info->family, info->model)) { + case CPUID(0x04, 0x01): + case CPUID(0x04, 0x02): + case CPUID(0x04, 0x03): + case CPUID(0x04, 0x04): + case CPUID(0x04, 0x05): + case CPUID(0x04, 0x07): + case CPUID(0x04, 0x08): + case CPUID(0x04, 0x09): + // https://en.wikichip.org/wiki/intel/microarchitectures/80486 + return INTEL_80486; + case CPUID(0x05, 0x01): + case CPUID(0x05, 0x02): + case CPUID(0x05, 0x04): + case CPUID(0x05, 0x07): + case CPUID(0x05, 0x08): + // https://en.wikichip.org/wiki/intel/microarchitectures/p5 + return INTEL_P5; + case CPUID(0x05, 0x09): + case CPUID(0x05, 0x0A): + // https://en.wikichip.org/wiki/intel/quark + return INTEL_LAKEMONT; case CPUID(0x06, 0x1C): // Intel(R) Atom(TM) CPU 230 @ 1.60GHz case CPUID(0x06, 0x35): case CPUID(0x06, 0x36): @@ -477,6 +498,32 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info) { // https://en.wikipedia.org/wiki/Kaby_Lake return INTEL_KBL; } + case CPUID(0x06, 0x97): + case CPUID(0x06, 0x9A): + // https://en.wikichip.org/wiki/intel/microarchitectures/alder_lake + return INTEL_ADL; + case CPUID(0x06, 0xA7): + // https://en.wikichip.org/wiki/intel/microarchitectures/rocket_lake + return INTEL_RCL; + case CPUID(0x06, 0x85): + // https://en.wikichip.org/wiki/intel/microarchitectures/knights_mill + return INTEL_KNIGHTS_M; + case CPUID(0x06, 0x57): + // https://en.wikichip.org/wiki/intel/microarchitectures/knights_landing + return INTEL_KNIGHTS_L; + case CPUID(0x0B, 0x00): + // https://en.wikichip.org/wiki/intel/microarchitectures/knights_ferry + return INTEL_KNIGHTS_F; + case CPUID(0x0B, 0x01): + // https://en.wikichip.org/wiki/intel/microarchitectures/knights_corner + return INTEL_KNIGHTS_C; + case CPUID(0x0F, 0x01): + case CPUID(0x0F, 0x02): + case CPUID(0x0F, 0x03): + case CPUID(0x0F, 0x04): + case CPUID(0x0F, 0x06): + // https://en.wikichip.org/wiki/intel/microarchitectures/netburst + return INTEL_NETBURST; default: return X86_UNKNOWN; } @@ -1623,6 +1670,9 @@ CacheInfo GetX86CacheInfo(void) { #define X86_MICROARCHITECTURE_NAMES \ LINE(X86_UNKNOWN) \ + LINE(INTEL_80486) \ + LINE(INTEL_P5) \ + LINE(INTEL_LAKEMONT) \ LINE(INTEL_CORE) \ LINE(INTEL_PNR) \ LINE(INTEL_NHM) \ @@ -1642,6 +1692,13 @@ CacheInfo GetX86CacheInfo(void) { LINE(INTEL_ICL) \ LINE(INTEL_TGL) \ LINE(INTEL_SPR) \ + LINE(INTEL_ADL) \ + LINE(INTEL_RCL) \ + LINE(INTEL_KNIGHTS_M) \ + LINE(INTEL_KNIGHTS_L) \ + LINE(INTEL_KNIGHTS_F) \ + LINE(INTEL_KNIGHTS_C) \ + LINE(INTEL_NETBURST) \ LINE(AMD_HAMMER) \ LINE(AMD_K10) \ LINE(AMD_K11) \ diff --git a/test/cpuinfo_x86_test.cc b/test/cpuinfo_x86_test.cc index 1c5d86e2..889190ec 100644 --- a/test/cpuinfo_x86_test.cc +++ b/test/cpuinfo_x86_test.cc @@ -1033,6 +1033,64 @@ flags : fpu mmx sse #endif // !defined(CPU_FEATURES_OS_WINDOWS) } +// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000480_486_CPUID.txt +TEST_F(CpuidX86Test, INTEL_80486) { + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x00000001, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x00000480, 0x00000000, 0x00000000, 0x00000003}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x04); + EXPECT_EQ(info.model, 0x08); + EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_80486); +} + +// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000526_P54C_CPUID.txt +TEST_F(CpuidX86Test, INTEL_P54C) { + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x00000001, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x00000525, 0x00000000, 0x00000000, 0x000001BF}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x05); + EXPECT_EQ(info.model, 0x02); + EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_P5); +} + +// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000590_Lakemont_CPUID2.txt +TEST_F(CpuidX86Test, INTEL_LAKEMONT) { + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x00000002, 0x756E6547, 0x6c65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x00000590, 0x00000000, 0x00010200, 0x8000237B}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x05); + EXPECT_EQ(info.model, 0x09); + EXPECT_EQ(GetX86Microarchitecture(&info), + X86Microarchitecture::INTEL_LAKEMONT); +} + +// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0050670_KnightsLanding_CPUID.txt +TEST_F(CpuidX86Test, INTEL_KNIGHTS_LANDING) { + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x00050670, 0x02FF0800, 0x7FF8F3BF, 0xBFEBFBFF}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x06); + EXPECT_EQ(info.model, 0x57); + EXPECT_EQ(GetX86Microarchitecture(&info), + X86Microarchitecture::INTEL_KNIGHTS_L); +} + // TODO(user): test what happens when xsave/osxsave are not present. // TODO(user): test what happens when xmm/ymm/zmm os support are not // present.