[llvm] [win][aarch64] Add support for detecting the Host CPU on Arm64 Windows (PR #151596)
Eli Friedman via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 4 14:07:08 PDT 2025
================
@@ -1450,6 +1462,48 @@ StringRef sys::getHostCPUName() {
return "generic";
}
+#elif defined(_M_ARM64) || defined(_M_ARM64EC)
+
+union MIDR_EL1 {
+ uint64_t Raw;
+ struct _Parts {
+ uint64_t Revision : 4;
+ uint64_t Partnum : 12;
+ uint64_t Architecture : 4;
+ uint64_t Variant : 4;
+ uint64_t Implementer : 8;
+ uint64_t Reserved : 32;
+ } Parts;
+};
+
+StringRef sys::getHostCPUName() {
+ StringRef CPU = "generic";
+
+ // The "CP 4000" registry key contains a cached copy of the MIDR_EL1 register.
+ HKEY Key;
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
+ "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0,
+ KEY_READ, &Key) == ERROR_SUCCESS) {
+ MIDR_EL1 RegValue;
+ DWORD ActualType;
+ DWORD RegValueSize = sizeof(RegValue);
+ if ((RegQueryValueExA(Key, "CP 4000", nullptr, &ActualType,
+ (PBYTE)&RegValue, &RegValueSize) == ERROR_SUCCESS) &&
+ (ActualType == REG_QWORD) && RegValueSize == sizeof(RegValue)) {
+ auto Part = "0x" + utohexstr(RegValue.Parts.Partnum, /*LowerCase*/ true,
+ /*Width*/ 3);
+ CPU = detail::getHostCPUNameForARM(
+ "0x" + utohexstr(RegValue.Parts.Implementer, /*LowerCase*/ true,
----------------
efriedma-quic wrote:
On an 8cx Gen 3, CPU 0-3 have "CP 4000" = 0x410fd4b0, CPU 4-7 have "CP 4000" = 0x410fd4c0.
I think Windows enumerates cores essentially the same way as Linux. So I think we should pick the "primary" part the same way as Linux, which would be the highest numbered part, not the lowest-numbered part. Doing something different on Linux vs. Windows is more confusing than helpful.
That's likely not 100% reliable, but we can leave OS-independent improvements for a followup.
https://github.com/llvm/llvm-project/pull/151596
More information about the llvm-commits
mailing list