1diff --git CMakeLists.txt CMakeLists.txt 2index e594def..cab4d05 100644 3--- CMakeLists.txt 4+++ CMakeLists.txt 5@@ -119,7 +119,8 @@ ENDIF() 6 # ---[ cpuinfo library 7 SET(CPUINFO_SRCS 8 src/init.c 9- src/api.c) 10+ src/api.c 11+ src/cache.c) 12 13 IF(CPUINFO_SUPPORTED_PLATFORM) 14 IF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i[3-6]86|AMD64|x86(_64)?)$" OR IOS_ARCH MATCHES "^(i386|x86_64)$") 15diff --git LICENSE LICENSE 16index 4910bfe..3f9a4f0 100644 17--- LICENSE 18+++ LICENSE 19@@ -1,3 +1,4 @@ 20+Copyright (c) 2019 Google LLC 21 Copyright (c) 2017-2018 Facebook Inc. 22 Copyright (C) 2012-2017 Georgia Institute of Technology 23 Copyright (C) 2010-2012 Marat Dukhan 24diff --git include/cpuinfo.h include/cpuinfo.h 25index 7d5833f..9938d2b 100644 26--- include/cpuinfo.h 27+++ include/cpuinfo.h 28@@ -38,10 +38,18 @@ 29 #define CPUINFO_ARCH_PNACL 1 30 #endif 31 32-#if defined(EMSCRIPTEN) 33+#if defined(__asmjs__) 34 #define CPUINFO_ARCH_ASMJS 1 35 #endif 36 37+#if defined(__wasm__) 38+ #if defined(__wasm_simd128__) 39+ #define CPUINFO_ARCH_WASMSIMD 1 40+ #else 41+ #define CPUINFO_ARCH_WASM 1 42+ #endif 43+#endif 44+ 45 #if CPUINFO_ARCH_X86 && defined(_MSC_VER) 46 #define CPUINFO_ABI __cdecl 47 #elif CPUINFO_ARCH_X86 && defined(__GNUC__) 48@@ -80,6 +88,14 @@ 49 #define CPUINFO_ARCH_ASMJS 0 50 #endif 51 52+#ifndef CPUINFO_ARCH_WASM 53+ #define CPUINFO_ARCH_WASM 0 54+#endif 55+ 56+#ifndef CPUINFO_ARCH_WASMSIMD 57+ #define CPUINFO_ARCH_WASMSIMD 0 58+#endif 59+ 60 #define CPUINFO_CACHE_UNIFIED 0x00000001 61 #define CPUINFO_CACHE_INCLUSIVE 0x00000002 62 #define CPUINFO_CACHE_COMPLEX_INDEXING 0x00000004 63@@ -278,10 +294,14 @@ enum cpuinfo_uarch { 64 cpuinfo_uarch_haswell = 0x00100208, 65 /** Intel Broadwell microarchitecture. */ 66 cpuinfo_uarch_broadwell = 0x00100209, 67- /** Intel Sky Lake microarchitecture. */ 68+ /** Intel Sky Lake microarchitecture (14 nm, including Kaby/Coffee/Whiskey/Amber/Comet/Cascade/Cooper Lake). */ 69 cpuinfo_uarch_sky_lake = 0x0010020A, 70- /** Intel Kaby Lake microarchitecture. */ 71- cpuinfo_uarch_kaby_lake = 0x0010020B, 72+ /** DEPRECATED (Intel Kaby Lake microarchitecture). */ 73+ cpuinfo_uarch_kaby_lake = 0x0010020A, 74+ /** Intel Palm Cove microarchitecture (10 nm, Cannon Lake). */ 75+ cpuinfo_uarch_palm_cove = 0x0010020B, 76+ /** Intel Sunny Cove microarchitecture (10 nm, Ice Lake). */ 77+ cpuinfo_uarch_sunny_cove = 0x0010020C, 78 79 /** Pentium 4 with Willamette, Northwood, or Foster cores. */ 80 cpuinfo_uarch_willamette = 0x00100300, 81@@ -289,13 +309,17 @@ enum cpuinfo_uarch { 82 cpuinfo_uarch_prescott = 0x00100301, 83 84 /** Intel Atom on 45 nm process. */ 85- cpuinfo_uarch_bonnell = 0x00100400, 86+ cpuinfo_uarch_bonnell = 0x00100400, 87 /** Intel Atom on 32 nm process. */ 88- cpuinfo_uarch_saltwell = 0x00100401, 89+ cpuinfo_uarch_saltwell = 0x00100401, 90 /** Intel Silvermont microarchitecture (22 nm out-of-order Atom). */ 91- cpuinfo_uarch_silvermont = 0x00100402, 92+ cpuinfo_uarch_silvermont = 0x00100402, 93 /** Intel Airmont microarchitecture (14 nm out-of-order Atom). */ 94- cpuinfo_uarch_airmont = 0x00100403, 95+ cpuinfo_uarch_airmont = 0x00100403, 96+ /** Intel Goldmont microarchitecture (Denverton, Apollo Lake). */ 97+ cpuinfo_uarch_goldmont = 0x00100404, 98+ /** Intel Goldmont Plus microarchitecture (Gemini Lake). */ 99+ cpuinfo_uarch_goldmont_plus = 0x00100405, 100 101 /** Intel Knights Ferry HPC boards. */ 102 cpuinfo_uarch_knights_ferry = 0x00100500, 103@@ -335,8 +359,10 @@ enum cpuinfo_uarch { 104 cpuinfo_uarch_steamroller = 0x00200107, 105 /** AMD Excavator microarchitecture (Carizzo APUs). */ 106 cpuinfo_uarch_excavator = 0x00200108, 107- /** AMD Zen microarchitecture (Ryzen CPUs). */ 108+ /** AMD Zen microarchitecture (12/14 nm Ryzen and EPYC CPUs). */ 109 cpuinfo_uarch_zen = 0x00200109, 110+ /** AMD Zen 2 microarchitecture (7 nm Ryzen and EPYC CPUs). */ 111+ cpuinfo_uarch_zen2 = 0x0020010A, 112 113 /** NSC Geode and AMD Geode GX and LX. */ 114 cpuinfo_uarch_geode = 0x00200200, 115@@ -370,23 +396,34 @@ enum cpuinfo_uarch { 116 cpuinfo_uarch_cortex_a17 = 0x00300217, 117 118 /** ARM Cortex-A32. */ 119- cpuinfo_uarch_cortex_a32 = 0x00300332, 120+ cpuinfo_uarch_cortex_a32 = 0x00300332, 121 /** ARM Cortex-A35. */ 122- cpuinfo_uarch_cortex_a35 = 0x00300335, 123+ cpuinfo_uarch_cortex_a35 = 0x00300335, 124 /** ARM Cortex-A53. */ 125- cpuinfo_uarch_cortex_a53 = 0x00300353, 126+ cpuinfo_uarch_cortex_a53 = 0x00300353, 127 /** ARM Cortex-A55. */ 128- cpuinfo_uarch_cortex_a55 = 0x00300355, 129+ cpuinfo_uarch_cortex_a55 = 0x00300355, 130 /** ARM Cortex-A57. */ 131- cpuinfo_uarch_cortex_a57 = 0x00300357, 132+ cpuinfo_uarch_cortex_a57 = 0x00300357, 133+ /** ARM Cortex-A65. */ 134+ cpuinfo_uarch_cortex_a65 = 0x00300365, 135 /** ARM Cortex-A72. */ 136- cpuinfo_uarch_cortex_a72 = 0x00300372, 137+ cpuinfo_uarch_cortex_a72 = 0x00300372, 138 /** ARM Cortex-A73. */ 139- cpuinfo_uarch_cortex_a73 = 0x00300373, 140+ cpuinfo_uarch_cortex_a73 = 0x00300373, 141 /** ARM Cortex-A75. */ 142- cpuinfo_uarch_cortex_a75 = 0x00300375, 143+ cpuinfo_uarch_cortex_a75 = 0x00300375, 144 /** ARM Cortex-A76. */ 145- cpuinfo_uarch_cortex_a76 = 0x00300376, 146+ cpuinfo_uarch_cortex_a76 = 0x00300376, 147+ /** ARM Cortex-A76AE. */ 148+ cpuinfo_uarch_cortex_a76ae = 0x00300378, 149+ /** ARM Cortex-A77. */ 150+ cpuinfo_uarch_cortex_a77 = 0x00300377, 151+ 152+ /** ARM Neoverse N1. */ 153+ cpuinfo_uarch_neoverse_n1 = 0x00300400, 154+ /** ARM Neoverse E1. */ 155+ cpuinfo_uarch_neoverse_e1 = 0x00300401, 156 157 /** Qualcomm Scorpion. */ 158 cpuinfo_uarch_scorpion = 0x00400100, 159@@ -406,12 +443,22 @@ enum cpuinfo_uarch { 160 /** Nvidia Carmel. */ 161 cpuinfo_uarch_carmel = 0x00500102, 162 163- /** Samsung Mongoose M1 (Exynos 8890 big cores). */ 164+ /** Samsung Exynos M1 (Exynos 8890 big cores). */ 165+ cpuinfo_uarch_exynos_m1 = 0x00600100, 166+ /** Samsung Exynos M2 (Exynos 8895 big cores). */ 167+ cpuinfo_uarch_exynos_m2 = 0x00600101, 168+ /** Samsung Exynos M3 (Exynos 9810 big cores). */ 169+ cpuinfo_uarch_exynos_m3 = 0x00600102, 170+ /** Samsung Exynos M4 (Exynos 9820 big cores). */ 171+ cpuinfo_uarch_exynos_m4 = 0x00600103, 172+ /** Samsung Exynos M5 (Exynos 9830 big cores). */ 173+ cpuinfo_uarch_exynos_m5 = 0x00600104, 174+ 175+ /* Old names for Exynos. */ 176 cpuinfo_uarch_mongoose_m1 = 0x00600100, 177- /** Samsung Mongoose M2 (Exynos 8895 big cores). */ 178 cpuinfo_uarch_mongoose_m2 = 0x00600101, 179- /** Samsung Meerkat M3 (Exynos 9810 big cores). */ 180 cpuinfo_uarch_meerkat_m3 = 0x00600102, 181+ cpuinfo_uarch_meerkat_m4 = 0x00600103, 182 183 /** Apple A6 and A6X processors. */ 184 cpuinfo_uarch_swift = 0x00700100, 185@@ -640,6 +687,8 @@ void CPUINFO_ABI cpuinfo_deinitialize(void); 186 bool avx512bitalg; 187 bool avx512vpopcntdq; 188 bool avx512vnni; 189+ bool avx512bf16; 190+ bool avx512vp2intersect; 191 bool avx512_4vnniw; 192 bool avx512_4fmaps; 193 bool hle; 194@@ -1110,6 +1159,22 @@ static inline bool cpuinfo_has_x86_avx512vnni(void) { 195 #endif 196 } 197 198+static inline bool cpuinfo_has_x86_avx512bf16(void) { 199+ #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 200+ return cpuinfo_isa.avx512bf16; 201+ #else 202+ return false; 203+ #endif 204+} 205+ 206+static inline bool cpuinfo_has_x86_avx512vp2intersect(void) { 207+ #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 208+ return cpuinfo_isa.avx512vp2intersect; 209+ #else 210+ return false; 211+ #endif 212+} 213+ 214 static inline bool cpuinfo_has_x86_avx512_4vnniw(void) { 215 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 216 return cpuinfo_isa.avx512_4vnniw; 217@@ -1682,6 +1747,11 @@ uint32_t CPUINFO_ABI cpuinfo_get_l2_caches_count(void); 218 uint32_t CPUINFO_ABI cpuinfo_get_l3_caches_count(void); 219 uint32_t CPUINFO_ABI cpuinfo_get_l4_caches_count(void); 220 221+/** 222+ * Returns upper bound on cache size. 223+ */ 224+uint32_t CPUINFO_ABI cpuinfo_get_max_cache_size(void); 225+ 226 const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_current_processor(void); 227 const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_current_core(void); 228 229diff --git src/api.c src/api.c 230index 98b5805..83744f5 100644 231--- src/api.c 232+++ src/api.c 233@@ -18,6 +18,7 @@ uint32_t cpuinfo_cores_count = 0; 234 uint32_t cpuinfo_clusters_count = 0; 235 uint32_t cpuinfo_packages_count = 0; 236 uint32_t cpuinfo_cache_count[cpuinfo_cache_level_max] = { 0 }; 237+uint32_t cpuinfo_max_cache_size = 0; 238 239 240 const struct cpuinfo_processor* cpuinfo_get_processors(void) { 241diff --git src/arm/api.h src/arm/api.h 242index 11e588b..69274bc 100644 243--- src/arm/api.h 244+++ src/arm/api.h 245@@ -104,6 +104,9 @@ CPUINFO_INTERNAL void cpuinfo_arm_decode_cache( 246 struct cpuinfo_cache l1d[restrict static 1], 247 struct cpuinfo_cache l2[restrict static 1], 248 struct cpuinfo_cache l3[restrict static 1]); 249+ 250+CPUINFO_INTERNAL uint32_t cpuinfo_arm_compute_max_cache_size( 251+ const struct cpuinfo_processor processor[restrict static 1]); 252 #else /* defined(__cplusplus) */ 253 CPUINFO_INTERNAL void cpuinfo_arm_decode_cache( 254 enum cpuinfo_uarch uarch, 255diff --git src/arm/cache.c src/arm/cache.c 256index 5ada7d9..ccadeb4 100644 257--- src/arm/cache.c 258+++ src/arm/cache.c 259@@ -1,10 +1,12 @@ 260 #include <stdint.h> 261 262 #include <cpuinfo.h> 263+#include <cpuinfo/internal-api.h> 264 #include <cpuinfo/log.h> 265 #include <arm/api.h> 266 #include <arm/midr.h> 267 268+ 269 void cpuinfo_arm_decode_cache( 270 enum cpuinfo_uarch uarch, 271 uint32_t cluster_cores, 272@@ -109,7 +111,7 @@ void cpuinfo_arm_decode_cache( 273 * memory accesses and has been optimized for use with the Cortex-A5 processor. 274 * 8.1.7. Exclusive L2 cache 275 * The Cortex-A5 processor can be connected to an L2 cache that supports an exclusive cache mode. 276- * This mode must be activated both in the Cortex-A5 processor and in the L2 cache controller. 277+ * This mode must be activated both in the Cortex-A5 processor and in the L2 cache controller. 278 * 279 * +--------------------+-----------+-----------+----------+-----------+ 280 * | Processor model | L1D cache | L1I cache | L2 cache | Reference | 281@@ -698,7 +700,7 @@ void cpuinfo_arm_decode_cache( 282 * [3] https://en.wikichip.org/wiki/hisilicon/kirin/980 283 */ 284 if (midr_is_qualcomm_cortex_a55_silver(midr)) { 285- /* Qualcomm-modified Cortex-A55 in Snapdragon 710 / 845 */ 286+ /* Qualcomm-modified Cortex-A55 in Snapdragon 670 / 710 / 845 */ 287 uint32_t l3_size = 1024 * 1024; 288 switch (chipset->series) { 289 case cpuinfo_arm_chipset_series_qualcomm_snapdragon: 290@@ -827,6 +829,62 @@ void cpuinfo_arm_decode_cache( 291 .flags = CPUINFO_CACHE_INCLUSIVE 292 }; 293 break; 294+ case cpuinfo_uarch_cortex_a65: 295+ { 296+ /* 297+ * ARM Cortex‑A65 Core Technical Reference Manual 298+ * A6.1. About the L1 memory system 299+ * The L1 memory system enhances the performance and power efficiency in the Cortex‑A65 core. 300+ * It consists of separate instruction and data caches. You can configure instruction and data caches 301+ * independently during implementation to sizes of 32KB or 64KB. 302+ * 303+ * L1 instruction-side memory system 304+ * The L1 instruction-side memory system provides an instruction stream to the DPU. Its key features are: 305+ * - 64-byte instruction side cache line length. 306+ * - 4-way set associative L1 instruction cache. 307+ * 308+ * L1 data-side memory system 309+ * - 64-byte data side cache line length. 310+ * - 4-way set associative L1 data cache. 311+ * 312+ * A7.1 About the L2 memory system 313+ * The Cortex‑A65 L2 memory system is required to interface the Cortex‑A65 cores to the L3 memory system. 314+ * The L2 memory subsystem consists of: 315+ * - An optional 4-way, set-associative L2 cache with a configurable size of 64KB, 128KB, or 256KB. 316+ * Cache lines have a fixed length of 64 bytes. 317+ * 318+ * The main features of the L2 memory system are: 319+ * - Strictly exclusive with L1 data cache. 320+ * - Pseudo-inclusive with L1 instruction cache. 321+ * - Private per-core unified L2 cache. 322+ */ 323+ const uint32_t l1_size = 32 * 1024; 324+ const uint32_t l2_size = 128 * 1024; 325+ const uint32_t l3_size = 512 * 1024; 326+ *l1i = (struct cpuinfo_cache) { 327+ .size = l1_size, 328+ .associativity = 4, 329+ .line_size = 64, 330+ }; 331+ *l1d = (struct cpuinfo_cache) { 332+ .size = l1_size, 333+ .associativity = 4, 334+ .line_size = 64, 335+ }; 336+ *l2 = (struct cpuinfo_cache) { 337+ .size = l2_size, 338+ .associativity = 4, 339+ .line_size = 64, 340+ .flags = CPUINFO_CACHE_INCLUSIVE 341+ }; 342+ *l3 = (struct cpuinfo_cache) { 343+ .size = l3_size, 344+ /* DynamIQ */ 345+ .associativity = 16, 346+ .line_size = 64, 347+ }; 348+ break; 349+ } 350 case cpuinfo_uarch_cortex_a72: 351 { 352 /* 353@@ -1047,6 +1105,7 @@ void cpuinfo_arm_decode_cache( 354 break; 355 } 356 case cpuinfo_uarch_cortex_a76: 357+ case cpuinfo_uarch_cortex_a76ae: 358 { 359 /* 360 * ARM Cortex-A76 Core Technical Reference Manual 361@@ -1119,6 +1178,57 @@ void cpuinfo_arm_decode_cache( 362 }; 363 break; 364 } 365+ case cpuinfo_uarch_cortex_a77: 366+ { 367+ /* 368+ * ARM Cortex-A77 Core Technical Reference Manual 369+ * A6.1. About the L1 memory system 370+ * The L1 memory system consists of separate instruction and data caches. Both have a fixed size of 64KB. 371+ * 372+ * A6.1.1 L1 instruction-side memory system 373+ * The L1 instruction memory system has the following key features: 374+ * - Virtually Indexed, Physically Tagged (VIPT), which behaves as a Physically Indexed, 375+ * Physically Tagged (PIPT) 4-way set-associative L1 data cache. 376+ * - Fixed cache line length of 64 bytes. 377+ * 378+ * A6.1.2 L1 data-side memory system 379+ * The L1 data memory system has the following features: 380+ * - Virtually Indexed, Physically Tagged (VIPT), which behaves as a Physically Indexed, 381+ * Physically Tagged (PIPT) 4-way set-associative L1 data cache. 382+ * - Fixed cache line length of 64 bytes. 383+ * - Pseudo-LRU cache replacement policy. 384+ * 385+ * A7.1 About the L2 memory system 386+ * The L2 memory subsystem consist of: 387+ * - An 8-way set associative L2 cache with a configurable size of 128KB, 256KB or 512KB. Cache lines 388+ * have a fixed length of 64 bytes. 389+ * - Strictly inclusive with L1 data cache. Weakly inclusive with L1 instruction cache. 390+ */ 391+ const uint32_t l2_size = 256 * 1024; 392+ const uint32_t l3_size = 1024 * 1024; 393+ *l1i = (struct cpuinfo_cache) { 394+ .size = 64 * 1024, 395+ .associativity = 4, 396+ .line_size = 64, 397+ }; 398+ *l1d = (struct cpuinfo_cache) { 399+ .size = 64 * 1024, 400+ .associativity = 4, 401+ .line_size = 64, 402+ }; 403+ *l2 = (struct cpuinfo_cache) { 404+ .size = l2_size, 405+ .associativity = 8, 406+ .line_size = 64, 407+ .flags = CPUINFO_CACHE_INCLUSIVE, 408+ }; 409+ *l3 = (struct cpuinfo_cache) { 410+ .size = l3_size, 411+ .associativity = 16, 412+ .line_size = 64, 413+ }; 414+ break; 415+ } 416 #if CPUINFO_ARCH_ARM && !defined(__ARM_ARCH_8A__) 417 case cpuinfo_uarch_scorpion: 418 /* 419@@ -1248,8 +1358,8 @@ void cpuinfo_arm_decode_cache( 420 .line_size = 64 421 }; 422 break; 423- case cpuinfo_uarch_mongoose_m1: 424- case cpuinfo_uarch_mongoose_m2: 425+ case cpuinfo_uarch_exynos_m1: 426+ case cpuinfo_uarch_exynos_m2: 427 /* 428 * - "Moving past branch prediction we can see some elements of how the cache is set up for the L1 I$, 429 * namely 64 KB split into four sets with 128-byte line sizes for 128 cache lines per set" [1] 430@@ -1283,7 +1393,7 @@ void cpuinfo_arm_decode_cache( 431 .line_size = 64 432 }; 433 break; 434- case cpuinfo_uarch_meerkat_m3: 435+ case cpuinfo_uarch_exynos_m3: 436 /* 437 * +--------------------+-------+-----------+-----------+-----------+----------+------------+ 438 * | Processor model | Cores | L1D cache | L1I cache | L2 cache | L3 cache | Reference | 439@@ -1294,19 +1404,19 @@ void cpuinfo_arm_decode_cache( 440 * [1] https://www.anandtech.com/show/12478/exynos-9810-handson-awkward-first-results 441 */ 442 *l1i = (struct cpuinfo_cache) { 443- .size = 64 * 1024 /* assume same as in Mongoose cores */, 444- .associativity = 4 /* assume same as in Mongoose cores */, 445- .line_size = 128 /* assume same as in Mongoose cores */ 446+ .size = 64 * 1024 /* assume same as in Exynos M1/M2 cores */, 447+ .associativity = 4 /* assume same as in Exynos M1/M2 cores */, 448+ .line_size = 128 /* assume same as in Exynos M1/M2 cores */ 449 }; 450 *l1d = (struct cpuinfo_cache) { 451 .size = 64 * 1024, 452- .associativity = 8 /* assume same as in Mongoose cores */, 453- .line_size = 64 /* assume same as in Mongoose cores */, 454+ .associativity = 8 /* assume same as in Exynos M1/M2 cores */, 455+ .line_size = 64 /* assume same as in Exynos M1/M2 cores */, 456 }; 457 *l2 = (struct cpuinfo_cache) { 458 .size = 512 * 1024, 459- .associativity = 16 /* assume same as in Mongoose cores */, 460- .line_size = 64 /* assume same as in Mongoose cores */, 461+ .associativity = 16 /* assume same as in Exynos M1/M2 cores */, 462+ .line_size = 64 /* assume same as in Exynos M1/M2 cores */, 463 }; 464 *l3 = (struct cpuinfo_cache) { 465 .size = 4 * 1024 * 1024, 466@@ -1393,3 +1503,124 @@ void cpuinfo_arm_decode_cache( 467 } 468 } 469 } 470+ 471+uint32_t cpuinfo_arm_compute_max_cache_size(const struct cpuinfo_processor* processor) { 472+ /* 473+ * There is no precise way to detect cache size on ARM/ARM64, and cache size reported by cpuinfo 474+ * may underestimate the actual cache size. Thus, we use microarchitecture-specific maximum. 475+ */ 476+ switch (processor->core->uarch) { 477+ case cpuinfo_uarch_xscale: 478+ case cpuinfo_uarch_arm11: 479+ case cpuinfo_uarch_scorpion: 480+ case cpuinfo_uarch_krait: 481+ case cpuinfo_uarch_kryo: 482+ case cpuinfo_uarch_exynos_m1: 483+ case cpuinfo_uarch_exynos_m2: 484+ case cpuinfo_uarch_exynos_m3: 485+ /* cpuinfo-detected cache size always correct */ 486+ return cpuinfo_compute_max_cache_size(processor); 487+ case cpuinfo_uarch_cortex_a5: 488+ /* Max observed (NXP Vybrid SoC) */ 489+ return 512 * 1024; 490+ case cpuinfo_uarch_cortex_a7: 491+ /* 492+ * Cortex-A7 MPCore Technical Reference Manual: 493+ * 7.1. About the L2 Memory system 494+ * The L2 memory system consists of an: 495+ * - Optional tightly-coupled L2 cache that includes: 496+ * - Configurable L2 cache size of 128KB, 256KB, 512KB, and 1MB. 497+ */ 498+ return 1024 * 1024; 499+ case cpuinfo_uarch_cortex_a8: 500+ /* 501+ * Cortex-A8 Technical Reference Manual: 502+ * 8.1. About the L2 memory system 503+ * The key features of the L2 memory system include: 504+ * - configurable cache size of 0KB, 128KB, 256KB, 512KB, and 1MB 505+ */ 506+ return 1024 * 1024; 507+ case cpuinfo_uarch_cortex_a9: 508+ /* Max observed (e.g. Exynos 4212) */ 509+ return 1024 * 1024; 510+ case cpuinfo_uarch_cortex_a12: 511+ case cpuinfo_uarch_cortex_a17: 512+ /* 513+ * ARM Cortex-A17 MPCore Processor Technical Reference Manual: 514+ * 7.1. About the L2 Memory system 515+ * The key features of the L2 memory system include: 516+ * - An integrated L2 cache: 517+ * - The cache size is implemented as either 256KB, 512KB, 1MB, 2MB, 4MB or 8MB. 518+ */ 519+ return 8 * 1024 * 1024; 520+ case cpuinfo_uarch_cortex_a15: 521+ /* 522+ * ARM Cortex-A15 MPCore Processor Technical Reference Manual: 523+ * 7.1. About the L2 memory system 524+ * The features of the L2 memory system include: 525+ * - Configurable L2 cache size of 512KB, 1MB, 2MB and 4MB. 526+ */ 527+ return 4 * 1024 * 1024; 528+ case cpuinfo_uarch_cortex_a35: 529+ /* 530+ * ARM Cortex‑A35 Processor Technical Reference Manual: 531+ * 7.1 About the L2 memory system 532+ * L2 cache 533+ * - Further features of the L2 cache are: 534+ * - Configurable size of 128KB, 256KB, 512KB, and 1MB. 535+ */ 536+ return 1024 * 1024; 537+ case cpuinfo_uarch_cortex_a53: 538+ /* 539+ * ARM Cortex-A53 MPCore Processor Technical Reference Manual: 540+ * 7.1. About the L2 memory system 541+ * The L2 memory system consists of an: 542+ * - Optional tightly-coupled L2 cache that includes: 543+ * - Configurable L2 cache size of 128KB, 256KB, 512KB, 1MB and 2MB. 544+ */ 545+ return 2 * 1024 * 1024; 546+ case cpuinfo_uarch_cortex_a57: 547+ /* 548+ * ARM Cortex-A57 MPCore Processor Technical Reference Manual: 549+ * 7.1 About the L2 memory system 550+ * The features of the L2 memory system include: 551+ * - Configurable L2 cache size of 512KB, 1MB, and 2MB. 552+ */ 553+ return 2 * 1024 * 1024; 554+ case cpuinfo_uarch_cortex_a72: 555+ /* 556+ * ARM Cortex-A72 MPCore Processor Technical Reference Manual: 557+ * 7.1 About the L2 memory system 558+ * The features of the L2 memory system include: 559+ * - Configurable L2 cache size of 512KB, 1MB, 2MB and 4MB. 560+ */ 561+ return 4 * 1024 * 1024; 562+ case cpuinfo_uarch_cortex_a73: 563+ /* 564+ * ARM Cortex‑A73 MPCore Processor Technical Reference Manual 565+ * 7.1 About the L2 memory system 566+ * The L2 memory system consists of: 567+ * - A tightly-integrated L2 cache with: 568+ * - A configurable size of 256KB, 512KB, 1MB, 2MB, 4MB, or 8MB. 569+ */ 570+ return 8 * 1024 * 1024; 571+ case cpuinfo_uarch_cortex_a55: 572+ case cpuinfo_uarch_cortex_a75: 573+ case cpuinfo_uarch_cortex_a76: 574+ case cpuinfo_uarch_exynos_m4: 575+ default: 576+ /* 577+ * ARM DynamIQ Shared Unit Technical Reference Manual 578+ * 1.3 Implementation options 579+ * L3_CACHE_SIZE 580+ * - 256KB 581+ * - 512KB 582+ * - 1024KB 583+ * - 1536KB 584+ * - 2048KB 585+ * - 3072KB 586+ * - 4096KB 587+ */ 588+ return 4 * 1024 * 1024; 589+ } 590+} 591diff --git src/arm/linux/init.c src/arm/linux/init.c 592index a297f63..f0c432c 100644 593--- src/arm/linux/init.c 594+++ src/arm/linux/init.c 595@@ -678,6 +678,8 @@ void cpuinfo_arm_linux_init(void) { 596 cpuinfo_cache_count[cpuinfo_cache_level_2] = l2_count; 597 cpuinfo_cache_count[cpuinfo_cache_level_3] = l3_count; 598 599+ cpuinfo_max_cache_size = cpuinfo_arm_compute_max_cache_size(&processors[0]); 600+ 601 __sync_synchronize(); 602 603 cpuinfo_is_initialized = true; 604diff --git src/arm/linux/midr.c src/arm/linux/midr.c 605index 668fc72..2c3116b 100644 606--- src/arm/linux/midr.c 607+++ src/arm/linux/midr.c 608@@ -220,7 +220,7 @@ static const struct cluster_config cluster_configs[] = { 609 .model = UINT16_C(7420), 610 .clusters = 2, 611 .cluster_cores = { 612- [0] = 4, 613+ [0] = 4, 614 [1] = 4, 615 }, 616 .cluster_midr = { 617@@ -229,7 +229,7 @@ static const struct cluster_config cluster_configs[] = { 618 }, 619 }, 620 { 621- /* Exynos 8890: 4x Mongoose + 4x Cortex-A53 */ 622+ /* Exynos 8890: 4x Exynos M1 + 4x Cortex-A53 */ 623 .cores = 8, 624 .series = cpuinfo_arm_chipset_series_samsung_exynos, 625 .model = UINT16_C(8890), 626@@ -695,7 +695,7 @@ static void cpuinfo_arm_linux_detect_cluster_midr_by_sequential_scan( 627 if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) { 628 if (processors[i].package_leader_id == i) { 629 if (bitmask_all(processors[i].flags, CPUINFO_ARM_LINUX_VALID_MIDR)) { 630- midr = processors[i].midr; 631+ midr = processors[i].midr; 632 } else { 633 cpuinfo_log_info("assume processor %"PRIu32" to have MIDR %08"PRIx32, i, midr); 634 /* To be consistent, we copy the MIDR entirely, rather than by parts */ 635@@ -836,7 +836,7 @@ uint32_t cpuinfo_arm_linux_detect_cluster_midr( 636 * - Clusters preceeding the first reported MIDR value are assumed to have the last reported MIDR value. 637 * - Clusters following any reported MIDR value to have that MIDR value. 638 */ 639- 640+ 641 if (cpuinfo_arm_linux_detect_cluster_midr_by_chipset( 642 chipset, clusters_count, cluster_leaders, usable_processors, processors, true)) 643 { 644diff --git src/arm/mach/init.c src/arm/mach/init.c 645index 5b14b49..e64cc18 100644 646--- src/arm/mach/init.c 647+++ src/arm/mach/init.c 648@@ -562,6 +562,8 @@ void cpuinfo_arm_mach_init(void) { 649 cpuinfo_clusters_count = num_clusters; 650 cpuinfo_packages_count = mach_topology.packages; 651 652+ cpuinfo_max_cache_size = cpuinfo_compute_max_cache_size(&processors[0]); 653+ 654 __sync_synchronize(); 655 656 cpuinfo_is_initialized = true; 657diff --git src/arm/midr.h src/arm/midr.h 658index 6363ed7..d5a28e3 100644 659--- src/arm/midr.h 660+++ src/arm/midr.h 661@@ -33,31 +33,31 @@ 662 #define CPUINFO_ARM_MIDR_KRYO_SILVER_821 UINT32_C(0x510F2010) 663 #define CPUINFO_ARM_MIDR_KRYO_GOLD UINT32_C(0x510F2050) 664 #define CPUINFO_ARM_MIDR_KRYO_SILVER_820 UINT32_C(0x510F2110) 665-#define CPUINFO_ARM_MIDR_MONGOOSE UINT32_C(0x530F0010) 666+#define CPUINFO_ARM_MIDR_EXYNOS_M1_M2 UINT32_C(0x530F0010) 667 #define CPUINFO_ARM_MIDR_DENVER2 UINT32_C(0x4E0F0030) 668 669 inline static uint32_t midr_set_implementer(uint32_t midr, uint32_t implementer) { 670- return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) | 671+ return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) | 672 ((implementer << CPUINFO_ARM_MIDR_IMPLEMENTER_OFFSET) & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK); 673 } 674 675 inline static uint32_t midr_set_variant(uint32_t midr, uint32_t variant) { 676- return (midr & ~CPUINFO_ARM_MIDR_VARIANT_MASK) | 677+ return (midr & ~CPUINFO_ARM_MIDR_VARIANT_MASK) | 678 ((variant << CPUINFO_ARM_MIDR_VARIANT_OFFSET) & CPUINFO_ARM_MIDR_VARIANT_MASK); 679 } 680 681 inline static uint32_t midr_set_architecture(uint32_t midr, uint32_t architecture) { 682- return (midr & ~CPUINFO_ARM_MIDR_ARCHITECTURE_MASK) | 683+ return (midr & ~CPUINFO_ARM_MIDR_ARCHITECTURE_MASK) | 684 ((architecture << CPUINFO_ARM_MIDR_ARCHITECTURE_OFFSET) & CPUINFO_ARM_MIDR_ARCHITECTURE_MASK); 685 } 686 687 inline static uint32_t midr_set_part(uint32_t midr, uint32_t part) { 688- return (midr & ~CPUINFO_ARM_MIDR_PART_MASK) | 689+ return (midr & ~CPUINFO_ARM_MIDR_PART_MASK) | 690 ((part << CPUINFO_ARM_MIDR_PART_OFFSET) & CPUINFO_ARM_MIDR_PART_MASK); 691 } 692 693 inline static uint32_t midr_set_revision(uint32_t midr, uint32_t revision) { 694- return (midr & ~CPUINFO_ARM_MIDR_REVISION_MASK) | 695+ return (midr & ~CPUINFO_ARM_MIDR_REVISION_MASK) | 696 ((revision << CPUINFO_ARM_MIDR_REVISION_OFFSET) & CPUINFO_ARM_MIDR_REVISION_MASK); 697 } 698 699@@ -171,13 +171,20 @@ inline static bool midr_is_kryo_gold(uint32_t midr) { 700 inline static uint32_t midr_score_core(uint32_t midr) { 701 const uint32_t core_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK; 702 switch (midr & core_mask) { 703+ case UINT32_C(0x53000040): /* Exynos M5 */ 704+ case UINT32_C(0x53000030): /* Exynos M4 */ 705+ /* These cores are in big role w.r.t Cortex-A75 or Cortex-A76 */ 706+ return 6; 707 case UINT32_C(0x4E000030): /* Denver 2 */ 708- case UINT32_C(0x53000010): /* Mongoose */ 709- case UINT32_C(0x53000020): /* Meerkat */ 710+ case UINT32_C(0x53000010): /* Exynos M1 and Exynos M2 */ 711+ case UINT32_C(0x53000020): /* Exynos M3 */ 712+ case UINT32_C(0x51008040): /* Kryo 485 Gold / Gold Prime */ 713 case UINT32_C(0x51008020): /* Kryo 385 Gold */ 714 case UINT32_C(0x51008000): /* Kryo 260 / 280 Gold */ 715 case UINT32_C(0x51002050): /* Kryo Gold */ 716 case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */ 717+ case UINT32_C(0x4100D0D0): /* Cortex-A77 */ 718+ case UINT32_C(0x4100D0E0): /* Cortex-A76AE */ 719 case UINT32_C(0x4100D0B0): /* Cortex-A76 */ 720 case UINT32_C(0x4100D0A0): /* Cortex-A75 */ 721 case UINT32_C(0x4100D090): /* Cortex-A73 */ 722@@ -191,12 +198,14 @@ inline static uint32_t midr_score_core(uint32_t midr) { 723 case UINT32_C(0x4100D070): /* Cortex-A57 */ 724 /* Cortex-A57 can be in LITTLE role w.r.t. Denver 2, or in big role w.r.t. Cortex-A53 */ 725 return 4; 726+ case UINT32_C(0x4100D060): /* Cortex-A65 */ 727 case UINT32_C(0x4100D050): /* Cortex-A55 */ 728 case UINT32_C(0x4100D030): /* Cortex-A53 */ 729 /* Cortex-A53 is usually in LITTLE role, but can be in big role w.r.t. Cortex-A35 */ 730 return 2; 731 case UINT32_C(0x4100D040): /* Cortex-A35 */ 732 case UINT32_C(0x4100C070): /* Cortex-A7 */ 733+ case UINT32_C(0x51008050): /* Kryo 485 Silver */ 734 case UINT32_C(0x51008030): /* Kryo 385 Silver */ 735 case UINT32_C(0x51008010): /* Kryo 260 / 280 Silver */ 736 case UINT32_C(0x51002110): /* Kryo Silver (Snapdragon 820) */ 737@@ -215,7 +224,7 @@ inline static uint32_t midr_score_core(uint32_t midr) { 738 } 739 740 inline static uint32_t midr_little_core_for_big(uint32_t midr) { 741- const uint32_t core_mask = 742+ const uint32_t core_mask = 743 CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_ARCHITECTURE_MASK | CPUINFO_ARM_MIDR_PART_MASK; 744 switch (midr & core_mask) { 745 case CPUINFO_ARM_MIDR_CORTEX_A75: 746@@ -223,7 +232,7 @@ inline static uint32_t midr_little_core_for_big(uint32_t midr) { 747 case CPUINFO_ARM_MIDR_CORTEX_A73: 748 case CPUINFO_ARM_MIDR_CORTEX_A72: 749 case CPUINFO_ARM_MIDR_CORTEX_A57: 750- case CPUINFO_ARM_MIDR_MONGOOSE: 751+ case CPUINFO_ARM_MIDR_EXYNOS_M1_M2: 752 return CPUINFO_ARM_MIDR_CORTEX_A53; 753 case CPUINFO_ARM_MIDR_CORTEX_A17: 754 case CPUINFO_ARM_MIDR_CORTEX_A15: 755diff --git src/arm/uarch.c src/arm/uarch.c 756index d7d2c63..a38250a 100644 757--- src/arm/uarch.c 758+++ src/arm/uarch.c 759@@ -60,6 +60,9 @@ void cpuinfo_arm_decode_vendor_uarch( 760 case 0xD05: 761 *uarch = cpuinfo_uarch_cortex_a55; 762 break; 763+ case 0xD06: 764+ *uarch = cpuinfo_uarch_cortex_a65; 765+ break; 766 case 0xD07: 767 *uarch = cpuinfo_uarch_cortex_a57; 768 break; 769@@ -75,6 +78,22 @@ void cpuinfo_arm_decode_vendor_uarch( 770 case 0xD0B: 771 *uarch = cpuinfo_uarch_cortex_a76; 772 break; 773+#if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) 774+ case 0xD0C: 775+ *uarch = cpuinfo_uarch_neoverse_n1; 776+ break; 777+#endif /* CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) */ 778+ case 0xD0D: 779+ *uarch = cpuinfo_uarch_cortex_a77; 780+ break; 781+ case 0xD0E: 782+ *uarch = cpuinfo_uarch_cortex_a76ae; 783+ break; 784+#if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) 785+ case 0xD4A: 786+ *uarch = cpuinfo_uarch_neoverse_e1; 787+ break; 788+#endif /* CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) */ 789 default: 790 switch (midr_get_part(midr) >> 8) { 791 #if CPUINFO_ARCH_ARM 792@@ -242,10 +261,14 @@ void cpuinfo_arm_decode_vendor_uarch( 793 *vendor = cpuinfo_vendor_arm; 794 *uarch = cpuinfo_uarch_cortex_a55; 795 break; 796- case 0x804: 797+ case 0x804: /* High-performance Kryo 485 "Gold" / "Gold Prime" -> Cortex-A76 */ 798 *vendor = cpuinfo_vendor_arm; 799 *uarch = cpuinfo_uarch_cortex_a76; 800 break; 801+ case 0x805: /* Low-performance Kryo 485 "Silver" -> Cortex-A55 */ 802+ *vendor = cpuinfo_vendor_arm; 803+ *uarch = cpuinfo_uarch_cortex_a55; 804+ break; 805 #if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) 806 case 0xC00: 807 *uarch = cpuinfo_uarch_falkor; 808@@ -263,27 +286,43 @@ void cpuinfo_arm_decode_vendor_uarch( 809 switch (midr & (CPUINFO_ARM_MIDR_VARIANT_MASK | CPUINFO_ARM_MIDR_PART_MASK)) { 810 case 0x00100010: 811 /* 812- * Exynos 8890 MIDR = 0x531F0011, assume Mongoose M1 has: 813+ * Exynos 8890 MIDR = 0x531F0011, assume Exynos M1 has: 814 * - CPU variant 0x1 815 * - CPU part 0x001 816 */ 817- *uarch = cpuinfo_uarch_mongoose_m1; 818+ *uarch = cpuinfo_uarch_exynos_m1; 819 break; 820 case 0x00400010: 821 /* 822- * Exynos 8895 MIDR = 0x534F0010, assume Mongoose M2 has: 823+ * Exynos 8895 MIDR = 0x534F0010, assume Exynos M2 has: 824 * - CPU variant 0x4 825 * - CPU part 0x001 826 */ 827- *uarch = cpuinfo_uarch_mongoose_m2; 828+ *uarch = cpuinfo_uarch_exynos_m2; 829 break; 830 case 0x00100020: 831 /* 832- * Exynos 9810 MIDR = 0x531F0020, assume Meerkat M3 has: 833+ * Exynos 9810 MIDR = 0x531F0020, assume Exynos M3 has: 834 * - CPU variant 0x1 835 * - CPU part 0x002 836 */ 837- *uarch = cpuinfo_uarch_meerkat_m3; 838+ *uarch = cpuinfo_uarch_exynos_m3; 839+ break; 840+ case 0x00100030: 841+ /* 842+ * Exynos 9820 MIDR = 0x531F0030, assume Exynos M4 has: 843+ * - CPU variant 0x1 844+ * - CPU part 0x003 845+ */ 846+ *uarch = cpuinfo_uarch_exynos_m4; 847+ break; 848+ case 0x00100040: 849+ /* 850+ * Exynos 9820 MIDR = 0x531F0040, assume Exynos M5 has: 851+ * - CPU variant 0x1 852+ * - CPU part 0x004 853+ */ 854+ *uarch = cpuinfo_uarch_exynos_m5; 855 break; 856 default: 857 cpuinfo_log_warning("unknown Samsung CPU variant 0x%01"PRIx32" part 0x%03"PRIx32" ignored", 858diff --git src/cache.c src/cache.c 859new file mode 100644 860index 0000000..b976b87 861--- /dev/null 862+++ src/cache.c 863@@ -0,0 +1,18 @@ 864+#include <stddef.h> 865+ 866+#include <cpuinfo.h> 867+#include <cpuinfo/internal-api.h> 868+ 869+ 870+uint32_t cpuinfo_compute_max_cache_size(const struct cpuinfo_processor* processor) { 871+ if (processor->cache.l4 != NULL) { 872+ return processor->cache.l4->size; 873+ } else if (processor->cache.l3 != NULL) { 874+ return processor->cache.l3->size; 875+ } else if (processor->cache.l2 != NULL) { 876+ return processor->cache.l2->size; 877+ } else if (processor->cache.l1d != NULL) { 878+ return processor->cache.l1d->size; 879+ } 880+ return 0; 881+} 882diff --git src/cpuinfo/internal-api.h src/cpuinfo/internal-api.h 883index 6045750..717b810 100644 884--- src/cpuinfo/internal-api.h 885+++ src/cpuinfo/internal-api.h 886@@ -31,6 +31,7 @@ extern CPUINFO_INTERNAL uint32_t cpuinfo_cores_count; 887 extern CPUINFO_INTERNAL uint32_t cpuinfo_clusters_count; 888 extern CPUINFO_INTERNAL uint32_t cpuinfo_packages_count; 889 extern CPUINFO_INTERNAL uint32_t cpuinfo_cache_count[cpuinfo_cache_level_max]; 890+extern CPUINFO_INTERNAL uint32_t cpuinfo_max_cache_size; 891 892 CPUINFO_PRIVATE void cpuinfo_x86_mach_init(void); 893 CPUINFO_PRIVATE void cpuinfo_x86_linux_init(void); 894@@ -40,4 +41,6 @@ CPUINFO_PRIVATE void cpuinfo_x86_linux_init(void); 895 CPUINFO_PRIVATE void cpuinfo_arm_mach_init(void); 896 CPUINFO_PRIVATE void cpuinfo_arm_linux_init(void); 897 898+CPUINFO_PRIVATE uint32_t cpuinfo_compute_max_cache_size(const struct cpuinfo_processor* processor); 899+ 900 typedef void (*cpuinfo_processor_callback)(uint32_t); 901diff --git src/x86/isa.c src/x86/isa.c 902index bca1ecd..d27dbca 100644 903--- src/x86/isa.c 904+++ src/x86/isa.c 905@@ -42,8 +42,10 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( 906 { 907 struct cpuinfo_x86_isa isa = { 0 }; 908 909- const struct cpuid_regs structured_feature_info = 910+ const struct cpuid_regs structured_feature_info0 = 911 (max_base_index >= 7) ? cpuidex(7, 0) : (struct cpuid_regs) { 0, 0, 0, 0}; 912+ const struct cpuid_regs structured_feature_info1 = 913+ (max_base_index >= 7) ? cpuidex(7, 1) : (struct cpuid_regs) { 0, 0, 0, 0}; 914 915 const uint32_t processor_capacity_info_index = UINT32_C(0x80000008); 916 const struct cpuid_regs processor_capacity_info = 917@@ -144,9 +146,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( 918 919 /* 920 * CLFLUSHOPT instruction: 921- * - Intel: ebx[bit 23] in structured feature info. 922+ * - Intel: ebx[bit 23] in structured feature info (ecx = 0). 923 */ 924- isa.clflushopt = !!(structured_feature_info.ebx & UINT32_C(0x00800000)); 925+ isa.clflushopt = !!(structured_feature_info0.ebx & UINT32_C(0x00800000)); 926 927 /* 928 * MWAIT/MONITOR instructions: 929@@ -273,9 +275,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( 930 931 /* 932 * PREFETCHWT1 instruction: 933- * - Intel: ecx[bit 0] of structured feature info. Reserved bit on AMD. 934+ * - Intel: ecx[bit 0] of structured feature info (ecx = 0). Reserved bit on AMD. 935 */ 936- isa.prefetchwt1 = !!(structured_feature_info.ecx & UINT32_C(0x00000001)); 937+ isa.prefetchwt1 = !!(structured_feature_info0.ecx & UINT32_C(0x00000001)); 938 939 #if CPUINFO_ARCH_X86 940 /* 941@@ -386,111 +388,123 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( 942 943 /* 944 * AVX2 instructions: 945- * - Intel: ebx[bit 5] in structured feature info. 946+ * - Intel: ebx[bit 5] in structured feature info (ecx = 0). 947 */ 948- isa.avx2 = avx_regs && !!(structured_feature_info.ebx & UINT32_C(0x00000020)); 949+ isa.avx2 = avx_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00000020)); 950 951 /* 952 * AVX512F instructions: 953- * - Intel: ebx[bit 16] in structured feature info. 954+ * - Intel: ebx[bit 16] in structured feature info (ecx = 0). 955 */ 956- isa.avx512f = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x00010000)); 957+ isa.avx512f = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00010000)); 958 959 /* 960 * AVX512PF instructions: 961- * - Intel: ebx[bit 26] in structured feature info. 962+ * - Intel: ebx[bit 26] in structured feature info (ecx = 0). 963 */ 964- isa.avx512pf = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x04000000)); 965+ isa.avx512pf = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x04000000)); 966 967 /* 968 * AVX512ER instructions: 969- * - Intel: ebx[bit 27] in structured feature info. 970+ * - Intel: ebx[bit 27] in structured feature info (ecx = 0). 971 */ 972- isa.avx512er = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x08000000)); 973+ isa.avx512er = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x08000000)); 974 975 /* 976 * AVX512CD instructions: 977- * - Intel: ebx[bit 28] in structured feature info. 978+ * - Intel: ebx[bit 28] in structured feature info (ecx = 0). 979 */ 980- isa.avx512cd = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x10000000)); 981+ isa.avx512cd = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x10000000)); 982 983 /* 984 * AVX512DQ instructions: 985- * - Intel: ebx[bit 17] in structured feature info. 986+ * - Intel: ebx[bit 17] in structured feature info (ecx = 0). 987 */ 988- isa.avx512dq = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x00020000)); 989+ isa.avx512dq = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00020000)); 990 991 /* 992 * AVX512BW instructions: 993- * - Intel: ebx[bit 30] in structured feature info. 994+ * - Intel: ebx[bit 30] in structured feature info (ecx = 0). 995 */ 996- isa.avx512bw = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x40000000)); 997+ isa.avx512bw = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x40000000)); 998 999 /* 1000 * AVX512VL instructions: 1001- * - Intel: ebx[bit 31] in structured feature info. 1002+ * - Intel: ebx[bit 31] in structured feature info (ecx = 0). 1003 */ 1004- isa.avx512vl = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x80000000)); 1005+ isa.avx512vl = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x80000000)); 1006 1007 /* 1008 * AVX512IFMA instructions: 1009- * - Intel: ebx[bit 21] in structured feature info. 1010+ * - Intel: ebx[bit 21] in structured feature info (ecx = 0). 1011 */ 1012- isa.avx512ifma = avx512_regs && !!(structured_feature_info.ebx & UINT32_C(0x00200000)); 1013+ isa.avx512ifma = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00200000)); 1014 1015 /* 1016 * AVX512VBMI instructions: 1017- * - Intel: ecx[bit 1] in structured feature info. 1018+ * - Intel: ecx[bit 1] in structured feature info (ecx = 0). 1019 */ 1020- isa.avx512vbmi = avx512_regs && !!(structured_feature_info.ecx & UINT32_C(0x00000002)); 1021+ isa.avx512vbmi = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00000002)); 1022 1023 /* 1024 * AVX512VBMI2 instructions: 1025- * - Intel: ecx[bit 6] in structured feature info. 1026+ * - Intel: ecx[bit 6] in structured feature info (ecx = 0). 1027 */ 1028- isa.avx512vbmi2 = avx512_regs && !!(structured_feature_info.ecx & UINT32_C(0x00000040)); 1029+ isa.avx512vbmi2 = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00000040)); 1030 1031 /* 1032 * AVX512BITALG instructions: 1033- * - Intel: ecx[bit 12] in structured feature info. 1034+ * - Intel: ecx[bit 12] in structured feature info (ecx = 0). 1035 */ 1036- isa.avx512bitalg = avx512_regs && !!(structured_feature_info.ecx & UINT32_C(0x00001000)); 1037+ isa.avx512bitalg = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00001000)); 1038 1039 /* 1040 * AVX512VPOPCNTDQ instructions: 1041- * - Intel: ecx[bit 14] in structured feature info. 1042+ * - Intel: ecx[bit 14] in structured feature info (ecx = 0). 1043 */ 1044- isa.avx512vpopcntdq = avx512_regs && !!(structured_feature_info.ecx & UINT32_C(0x00004000)); 1045+ isa.avx512vpopcntdq = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00004000)); 1046 1047 /* 1048 * AVX512VNNI instructions: 1049- * - Intel: ecx[bit 11] in structured feature info. 1050+ * - Intel: ecx[bit 11] in structured feature info (ecx = 0). 1051 */ 1052- isa.avx512vnni = avx512_regs && !!(structured_feature_info.ecx & UINT32_C(0x00000800)); 1053+ isa.avx512vnni = avx512_regs && !!(structured_feature_info0.ecx & UINT32_C(0x00000800)); 1054 1055 /* 1056 * AVX512_4VNNIW instructions: 1057- * - Intel: edx[bit 2] in structured feature info. 1058+ * - Intel: edx[bit 2] in structured feature info (ecx = 0). 1059 */ 1060- isa.avx512_4vnniw = avx512_regs && !!(structured_feature_info.edx & UINT32_C(0x00000004)); 1061+ isa.avx512_4vnniw = avx512_regs && !!(structured_feature_info0.edx & UINT32_C(0x00000004)); 1062 1063 /* 1064 * AVX512_4FMAPS instructions: 1065- * - Intel: edx[bit 3] in structured feature info. 1066+ * - Intel: edx[bit 3] in structured feature info (ecx = 0). 1067 */ 1068- isa.avx512_4fmaps = avx512_regs && !!(structured_feature_info.edx & UINT32_C(0x00000008)); 1069+ isa.avx512_4fmaps = avx512_regs && !!(structured_feature_info0.edx & UINT32_C(0x00000008)); 1070+ 1071+ /* 1072+ * AVX512_VP2INTERSECT instructions: 1073+ * - Intel: edx[bit 8] in structured feature info (ecx = 0). 1074+ */ 1075+ isa.avx512vp2intersect = avx512_regs && !!(structured_feature_info0.edx & UINT32_C(0x00000100)); 1076+ 1077+ /* 1078+ * AVX512_BF16 instructions: 1079+ * - Intel: eax[bit 5] in structured feature info (ecx = 1). 1080+ */ 1081+ isa.avx512bf16 = avx512_regs && !!(structured_feature_info1.eax & UINT32_C(0x00000020)); 1082 1083 /* 1084 * HLE instructions: 1085- * - Intel: ebx[bit 4] in structured feature info. 1086+ * - Intel: ebx[bit 4] in structured feature info (ecx = 0). 1087 */ 1088- isa.hle = !!(structured_feature_info.ebx & UINT32_C(0x00000010)); 1089+ isa.hle = !!(structured_feature_info0.ebx & UINT32_C(0x00000010)); 1090 1091 /* 1092 * RTM instructions: 1093- * - Intel: ebx[bit 11] in structured feature info. 1094+ * - Intel: ebx[bit 11] in structured feature info (ecx = 0). 1095 */ 1096- isa.rtm = !!(structured_feature_info.ebx & UINT32_C(0x00000800)); 1097+ isa.rtm = !!(structured_feature_info0.ebx & UINT32_C(0x00000800)); 1098 1099 /* 1100 * XTEST instruction: 1101@@ -500,9 +514,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( 1102 1103 /* 1104 * MPX registers and instructions: 1105- * - Intel: ebx[bit 14] in structured feature info. 1106+ * - Intel: ebx[bit 14] in structured feature info (ecx = 0). 1107 */ 1108- isa.mpx = mpx_regs && !!(structured_feature_info.ebx & UINT32_C(0x00004000)); 1109+ isa.mpx = mpx_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00004000)); 1110 1111 #if CPUINFO_ARCH_X86 1112 /* 1113@@ -528,9 +542,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( 1114 1115 /* 1116 * CLWB instruction: 1117- * - Intel: ebx[bit 24] in structured feature info. 1118+ * - Intel: ebx[bit 24] in structured feature info (ecx = 0). 1119 */ 1120- isa.clwb = !!(structured_feature_info.ebx & UINT32_C(0x01000000)); 1121+ isa.clwb = !!(structured_feature_info0.ebx & UINT32_C(0x01000000)); 1122 1123 /* 1124 * MOVBE instruction: 1125@@ -549,9 +563,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( 1126 1127 /* 1128 * RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE instructions. 1129- * - Intel: ebx[bit 0] in structured feature info. 1130+ * - Intel: ebx[bit 0] in structured feature info (ecx = 0). 1131 */ 1132- isa.fs_gs_base = !!(structured_feature_info.ebx & UINT32_C(0x00000001)); 1133+ isa.fs_gs_base = !!(structured_feature_info0.ebx & UINT32_C(0x00000001)); 1134 1135 /* 1136 * LZCNT instruction: 1137@@ -573,21 +587,21 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( 1138 1139 /* 1140 * BMI instructions: 1141- * - Intel, AMD: ebx[bit 3] in structured feature info. 1142+ * - Intel, AMD: ebx[bit 3] in structured feature info (ecx = 0). 1143 */ 1144- isa.bmi = !!(structured_feature_info.ebx & UINT32_C(0x00000008)); 1145+ isa.bmi = !!(structured_feature_info0.ebx & UINT32_C(0x00000008)); 1146 1147 /* 1148 * BMI2 instructions: 1149- * - Intel: ebx[bit 8] in structured feature info. 1150+ * - Intel: ebx[bit 8] in structured feature info (ecx = 0). 1151 */ 1152- isa.bmi2 = !!(structured_feature_info.ebx & UINT32_C(0x00000100)); 1153+ isa.bmi2 = !!(structured_feature_info0.ebx & UINT32_C(0x00000100)); 1154 1155 /* 1156 * ADCX/ADOX instructions: 1157- * - Intel: ebx[bit 19] in structured feature info. 1158+ * - Intel: ebx[bit 19] in structured feature info (ecx = 0). 1159 */ 1160- isa.adx = !!(structured_feature_info.ebx & UINT32_C(0x00080000)); 1161+ isa.adx = !!(structured_feature_info0.ebx & UINT32_C(0x00080000)); 1162 1163 /* 1164 * AES instructions: 1165@@ -597,9 +611,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( 1166 1167 /* 1168 * VAES instructions: 1169- * - Intel: ecx[bit 9] in structured feature info. 1170+ * - Intel: ecx[bit 9] in structured feature info (ecx = 0). 1171 */ 1172- isa.vaes = !!(structured_feature_info.ecx & UINT32_C(0x00000200)); 1173+ isa.vaes = !!(structured_feature_info0.ecx & UINT32_C(0x00000200)); 1174 1175 /* 1176 * PCLMULQDQ instruction: 1177@@ -609,15 +623,15 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( 1178 1179 /* 1180 * VPCLMULQDQ instruction: 1181- * - Intel: ecx[bit 10] in structured feature info. 1182+ * - Intel: ecx[bit 10] in structured feature info (ecx = 0). 1183 */ 1184- isa.vpclmulqdq = !!(structured_feature_info.ecx & UINT32_C(0x00000400)); 1185+ isa.vpclmulqdq = !!(structured_feature_info0.ecx & UINT32_C(0x00000400)); 1186 1187 /* 1188 * GFNI instructions: 1189- * - Intel: ecx[bit 8] in structured feature info. 1190+ * - Intel: ecx[bit 8] in structured feature info (ecx = 0). 1191 */ 1192- isa.gfni = !!(structured_feature_info.ecx & UINT32_C(0x00000100)); 1193+ isa.gfni = !!(structured_feature_info0.ecx & UINT32_C(0x00000100)); 1194 1195 /* 1196 * RDRAND instruction: 1197@@ -627,15 +641,15 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( 1198 1199 /* 1200 * RDSEED instruction: 1201- * - Intel: ebx[bit 18] in structured feature info. 1202+ * - Intel: ebx[bit 18] in structured feature info (ecx = 0). 1203 */ 1204- isa.rdseed = !!(structured_feature_info.ebx & UINT32_C(0x00040000)); 1205+ isa.rdseed = !!(structured_feature_info0.ebx & UINT32_C(0x00040000)); 1206 1207 /* 1208 * SHA instructions: 1209- * - Intel: ebx[bit 29] in structured feature info. 1210+ * - Intel: ebx[bit 29] in structured feature info (ecx = 0). 1211 */ 1212- isa.sha = !!(structured_feature_info.ebx & UINT32_C(0x20000000)); 1213+ isa.sha = !!(structured_feature_info0.ebx & UINT32_C(0x20000000)); 1214 1215 if (vendor == cpuinfo_vendor_via) { 1216 const struct cpuid_regs padlock_meta_info = cpuid(UINT32_C(0xC0000000)); 1217@@ -700,9 +714,9 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( 1218 1219 /* 1220 * RDPID instruction: 1221- * - Intel: ecx[bit 22] in structured feature info. 1222+ * - Intel: ecx[bit 22] in structured feature info (ecx = 0). 1223 */ 1224- isa.rdpid = !!(structured_feature_info.ecx & UINT32_C(0x00400000)); 1225+ isa.rdpid = !!(structured_feature_info0.ecx & UINT32_C(0x00400000)); 1226 1227 return isa; 1228 } 1229diff --git src/x86/linux/init.c src/x86/linux/init.c 1230index b5f74d0..c096336 100644 1231--- src/x86/linux/init.c 1232+++ src/x86/linux/init.c 1233@@ -592,6 +592,8 @@ void cpuinfo_x86_linux_init(void) { 1234 cpuinfo_cache_count[cpuinfo_cache_level_3] = l3_count; 1235 cpuinfo_cache_count[cpuinfo_cache_level_4] = l4_count; 1236 1237+ cpuinfo_max_cache_size = cpuinfo_compute_max_cache_size(&processors[0]); 1238+ 1239 __sync_synchronize(); 1240 1241 cpuinfo_is_initialized = true; 1242diff --git src/x86/mach/init.c src/x86/mach/init.c 1243index 7b41ad0..ae2be33 100644 1244--- src/x86/mach/init.c 1245+++ src/x86/mach/init.c 1246@@ -327,6 +327,8 @@ void cpuinfo_x86_mach_init(void) { 1247 cpuinfo_clusters_count = mach_topology.packages; 1248 cpuinfo_packages_count = mach_topology.packages; 1249 1250+ cpuinfo_max_cache_size = cpuinfo_compute_max_cache_size(&processors[0]); 1251+ 1252 __sync_synchronize(); 1253 1254 cpuinfo_is_initialized = true; 1255diff --git src/x86/uarch.c src/x86/uarch.c 1256index 71c899e..ba72d8a 100644 1257--- src/x86/uarch.c 1258+++ src/x86/uarch.c 1259@@ -74,13 +74,19 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch( 1260 case 0x4F: // Broadwell-E 1261 case 0x56: // Broadwell-DE 1262 return cpuinfo_uarch_broadwell; 1263- case 0x4E: // Skylake-U/Y 1264- case 0x55: // Skylake Server (SKX) 1265- case 0x5E: // Skylake-H/S 1266+ case 0x4E: // Sky Lake Client Y/U 1267+ case 0x55: // Sky/Cascade/Cooper Lake Server 1268+ case 0x5E: // Sky Lake Client DT/H/S 1269+ case 0x8E: // Kaby/Whiskey/Amber/Comet Lake Y/U 1270+ case 0x9E: // Kaby/Coffee Lake DT/H/S 1271 return cpuinfo_uarch_sky_lake; 1272- case 0x8E: // Kaby Lake U/Y 1273- case 0x9E: // Kaby Lake H/S 1274- return cpuinfo_uarch_kaby_lake; 1275+ case 0x66: // Cannon Lake (Core i3-8121U) 1276+ return cpuinfo_uarch_palm_cove; 1277+ case 0x6A: // Ice Lake-DE 1278+ case 0x6C: // Ice Lake-SP 1279+ case 0x7D: // Ice Lake-Y 1280+ case 0x7E: // Ice Lake-U 1281+ return cpuinfo_uarch_sunny_cove; 1282 1283 /* Low-power cores */ 1284 case 0x1C: // Diamondville, Silverthorne, Pineview 1285@@ -90,18 +96,20 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch( 1286 case 0x35: // Cloverview 1287 case 0x36: // Cedarview, Centerton 1288 return cpuinfo_uarch_saltwell; 1289- case 0x37: 1290- case 0x4A: 1291- case 0x4D: 1292+ case 0x37: // Bay Trail 1293+ case 0x4A: // Merrifield 1294+ case 0x4D: // Avoton, Rangeley 1295 case 0x5A: // Moorefield 1296 case 0x5D: // SoFIA 1297 return cpuinfo_uarch_silvermont; 1298- case 0x4C: // Braswell 1299- case 0x5F: // Denverton 1300+ case 0x4C: // Braswell, Cherry Trail 1301 case 0x75: // Spreadtrum SC9853I-IA 1302- case 0x7A: // Goldmont+ 1303 return cpuinfo_uarch_airmont; 1304- 1305+ case 0x5C: // Apollo Lake 1306+ case 0x5F: // Denverton 1307+ return cpuinfo_uarch_goldmont; 1308+ case 0x7A: // Gemini Lake 1309+ return cpuinfo_uarch_goldmont_plus; 1310 /* Knights-series cores */ 1311 case 0x57: 1312 return cpuinfo_uarch_knights_landing; 1313@@ -190,7 +198,15 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch( 1314 return cpuinfo_uarch_jaguar; 1315 } 1316 case 0x17: 1317- return cpuinfo_uarch_zen; 1318+ switch (model_info->model) { 1319+ case 0x01: // 14 nm Naples, Whitehaven, Summit Ridge, Snowy Owl 1320+ case 0x08: // 12 nm Pinnacle Ridge 1321+ case 0x11: // 14 nm Raven Ridge 1322+ case 0x18: // 12 nm Picasso 1323+ return cpuinfo_uarch_zen; 1324+ case 0x71: // Matisse 1325+ return cpuinfo_uarch_zen2; 1326+ } 1327 } 1328 break; 1329 default: 1330diff --git src/x86/windows/init.c src/x86/windows/init.c 1331index eb3498a..7a2090e 100644 1332--- src/x86/windows/init.c 1333+++ src/x86/windows/init.c 1334@@ -571,6 +571,8 @@ BOOL CALLBACK cpuinfo_x86_windows_init(PINIT_ONCE init_once, PVOID parameter, PV 1335 cpuinfo_clusters_count = packages_count; 1336 cpuinfo_packages_count = packages_count; 1337 1338+ cpuinfo_max_cache_size = cpuinfo_compute_max_cache_size(&processors[0]); 1339+ 1340 MemoryBarrier(); 1341 1342 cpuinfo_is_initialized = true; 1343diff --git tools/cache-info.c tools/cache-info.c 1344index ba0706f..05f69ee 100644 1345--- tools/cache-info.c 1346+++ tools/cache-info.c 1347@@ -60,6 +60,8 @@ int main(int argc, char** argv) { 1348 fprintf(stderr, "failed to initialize CPU information\n"); 1349 exit(EXIT_FAILURE); 1350 } 1351+ printf("Max cache size (upper bound): %"PRIu32" bytes\n", cpuinfo_get_max_cache_size()); 1352+ 1353 if (cpuinfo_get_l1i_caches_count() != 0 && (cpuinfo_get_l1i_cache(0)->flags & CPUINFO_CACHE_UNIFIED) == 0) { 1354 report_cache(cpuinfo_get_l1i_caches_count(), cpuinfo_get_l1i_cache(0), 1, "instruction"); 1355 } 1356diff --git tools/cpu-info.c tools/cpu-info.c 1357index caef424..7fa5187 100644 1358--- tools/cpu-info.c 1359+++ tools/cpu-info.c 1360@@ -73,8 +73,10 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) { 1361 return "Broadwell"; 1362 case cpuinfo_uarch_sky_lake: 1363 return "Sky Lake"; 1364- case cpuinfo_uarch_kaby_lake: 1365- return "Kaby Lake"; 1366+ case cpuinfo_uarch_palm_cove: 1367+ return "Palm Cove"; 1368+ case cpuinfo_uarch_sunny_cove: 1369+ return "Sunny Cove"; 1370 case cpuinfo_uarch_willamette: 1371 return "Willamette"; 1372 case cpuinfo_uarch_prescott: 1373@@ -87,6 +89,10 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) { 1374 return "Silvermont"; 1375 case cpuinfo_uarch_airmont: 1376 return "Airmont"; 1377+ case cpuinfo_uarch_goldmont: 1378+ return "Goldmont"; 1379+ case cpuinfo_uarch_goldmont_plus: 1380+ return "Goldmont Plus"; 1381 case cpuinfo_uarch_knights_ferry: 1382 return "Knights Ferry"; 1383 case cpuinfo_uarch_knights_corner: 1384@@ -117,6 +123,8 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) { 1385 return "Excavator"; 1386 case cpuinfo_uarch_zen: 1387 return "Zen"; 1388+ case cpuinfo_uarch_zen2: 1389+ return "Zen 2"; 1390 case cpuinfo_uarch_geode: 1391 return "Geode"; 1392 case cpuinfo_uarch_bobcat: 1393@@ -157,6 +165,8 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) { 1394 return "Cortex-A55"; 1395 case cpuinfo_uarch_cortex_a57: 1396 return "Cortex-A57"; 1397+ case cpuinfo_uarch_cortex_a65: 1398+ return "Cortex-A65"; 1399 case cpuinfo_uarch_cortex_a72: 1400 return "Cortex-A72"; 1401 case cpuinfo_uarch_cortex_a73: 1402@@ -165,6 +175,10 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) { 1403 return "Cortex-A75"; 1404 case cpuinfo_uarch_cortex_a76: 1405 return "Cortex-A76"; 1406+ case cpuinfo_uarch_cortex_a76ae: 1407+ return "Cortex-A76AE"; 1408+ case cpuinfo_uarch_cortex_a77: 1409+ return "Cortex-A77"; 1410 case cpuinfo_uarch_scorpion: 1411 return "Scorpion"; 1412 case cpuinfo_uarch_krait: 1413@@ -181,12 +195,16 @@ static const char* uarch_to_string(enum cpuinfo_uarch uarch) { 1414 return "Denver 2"; 1415 case cpuinfo_uarch_carmel: 1416 return "Carmel"; 1417- case cpuinfo_uarch_mongoose_m1: 1418- return "Mongoose M1"; 1419- case cpuinfo_uarch_mongoose_m2: 1420- return "Mongoose M2"; 1421- case cpuinfo_uarch_meerkat_m3: 1422- return "Meerkat M3"; 1423+ case cpuinfo_uarch_exynos_m1: 1424+ return "Exynos M1"; 1425+ case cpuinfo_uarch_exynos_m2: 1426+ return "Exynos M2"; 1427+ case cpuinfo_uarch_exynos_m3: 1428+ return "Exynos M3"; 1429+ case cpuinfo_uarch_exynos_m4: 1430+ return "Exynos M4"; 1431+ case cpuinfo_uarch_exynos_m5: 1432+ return "Exynos M5"; 1433 case cpuinfo_uarch_swift: 1434 return "Swift"; 1435 case cpuinfo_uarch_cyclone: 1436@@ -258,13 +276,23 @@ int main(int argc, char** argv) { 1437 printf(", %s %s\n", vendor_string, uarch_string); 1438 } 1439 } 1440- printf("Logical processors:\n"); 1441+ printf("Logical processors"); 1442+ #if defined(__linux__) 1443+ printf(" (System ID)"); 1444+ #endif 1445+ printf(":\n"); 1446 for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) { 1447 const struct cpuinfo_processor* processor = cpuinfo_get_processor(i); 1448+ printf("\t%"PRIu32"", i); 1449+ 1450+ #if defined(__linux__) 1451+ printf(" (%"PRId32")", processor->linux_id); 1452+ #endif 1453+ 1454 #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 1455- printf("\t%"PRIu32": APIC ID 0x%08"PRIx32"\n", i, processor->apic_id); 1456+ printf(": APIC ID 0x%08"PRIx32"\n", processor->apic_id); 1457 #else 1458- printf("\t%"PRIu32"\n", i); 1459+ printf("\n"); 1460 #endif 1461 } 1462 } 1463diff --git tools/isa-info.c tools/isa-info.c 1464index 594c46a..98ef919 100644 1465--- tools/isa-info.c 1466+++ tools/isa-info.c 1467@@ -67,6 +67,8 @@ int main(int argc, char** argv) { 1468 printf("\tAVX512BITALG: %s\n", cpuinfo_has_x86_avx512bitalg() ? "yes" : "no"); 1469 printf("\tAVX512VPOPCNTDQ: %s\n", cpuinfo_has_x86_avx512vpopcntdq() ? "yes" : "no"); 1470 printf("\tAVX512VNNI: %s\n", cpuinfo_has_x86_avx512vnni() ? "yes" : "no"); 1471+ printf("\tAVX512BF16: %s\n", cpuinfo_has_x86_avx512bf16() ? "yes" : "no"); 1472+ printf("\tAVX512VP2INTERSECT: %s\n", cpuinfo_has_x86_avx512vp2intersect() ? "yes" : "no"); 1473 printf("\tAVX512_4VNNIW: %s\n", cpuinfo_has_x86_avx512_4vnniw() ? "yes" : "no"); 1474 printf("\tAVX512_4FMAPS: %s\n", cpuinfo_has_x86_avx512_4fmaps() ? "yes" : "no"); 1475 1476