Index: llvm/trunk/lib/Support/Host.cpp =================================================================== --- llvm/trunk/lib/Support/Host.cpp +++ llvm/trunk/lib/Support/Host.cpp @@ -149,18 +149,28 @@ // The cpuid register on arm is not accessible from user space. On Linux, // it is exposed through the /proc/cpuinfo file. - // Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line + // Read 32 lines from /proc/cpuinfo, which should contain the CPU part line // in all cases. SmallVector Lines; ProcCpuinfoContent.split(Lines, "\n"); // Look for the CPU implementer line. StringRef Implementer; - for (unsigned I = 0, E = Lines.size(); I != E; ++I) + StringRef Hardware; + for (unsigned I = 0, E = Lines.size(); I != E; ++I) { if (Lines[I].startswith("CPU implementer")) Implementer = Lines[I].substr(15).ltrim("\t :"); + if (Lines[I].startswith("Hardware")) + Hardware = Lines[I].substr(8).ltrim("\t :"); + } + + if (Implementer == "0x41") { // ARM Ltd. + // MSM8992/8994 may give cpu part for the core that the kernel is running on, + // which is undeterministic and wrong. Always return cortex-a53 for these SoC. + if (Hardware.endswith("MSM8994") || Hardware.endswith("MSM8996")) + return "cortex-a53"; + - if (Implementer == "0x41") // ARM Ltd. // Look for the CPU part line. for (unsigned I = 0, E = Lines.size(); I != E; ++I) if (Lines[I].startswith("CPU part")) @@ -179,6 +189,22 @@ .Case("0xc20", "cortex-m0") .Case("0xc23", "cortex-m3") .Case("0xc24", "cortex-m4") + .Case("0xd03", "cortex-a53") + .Case("0xd07", "cortex-a57") + .Case("0xd08", "cortex-a72") + .Case("0xd09", "cortex-a73") + .Default("generic"); + } + + if (Implementer == "0x50") // Applied Micro Circuits Corporation (APM). + // Look for the CPU part line. + for (unsigned I = 0, E = Lines.size(); I != E; ++I) + if (Lines[I].startswith("CPU part")) + // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The + // values correspond to the "Part number" in the CP15/c0 register. The + // contents are specified in the various processor manuals. + return StringSwitch(Lines[I].substr(8).ltrim("\t :")) + .Case("0x000", "xgene1") .Default("generic"); if (Implementer == "0x51") // Qualcomm Technologies, Inc. @@ -190,6 +216,8 @@ // contents are specified in the various processor manuals. return StringSwitch(Lines[I].substr(8).ltrim("\t :")) .Case("0x06f", "krait") // APQ8064 + .Case("0x201", "kryo") + .Case("0x205", "kryo") .Default("generic"); return "generic"; @@ -1199,7 +1227,7 @@ const StringRef& Content = P ? P->getBuffer() : ""; return detail::getHostCPUNameForPowerPC(Content); } -#elif defined(__linux__) && defined(__arm__) +#elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) StringRef sys::getHostCPUName() { std::unique_ptr P = getProcCpuinfoContent(); const StringRef& Content = P ? P->getBuffer() : ""; Index: llvm/trunk/unittests/Support/Host.cpp =================================================================== --- llvm/trunk/unittests/Support/Host.cpp +++ llvm/trunk/unittests/Support/Host.cpp @@ -79,3 +79,38 @@ "CPU part : 0x06f"), "krait"); } + +TEST(getLinuxHostCPUName, AArch64) { + EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x41\n" + "CPU part : 0xd03"), + "cortex-a53"); + // Verify that both CPU implementer and CPU part are checked: + EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x40\n" + "CPU part : 0xd03"), + "generic"); + EXPECT_EQ(sys::detail::getHostCPUNameForARM("CPU implementer : 0x51\n" + "CPU part : 0x201"), + "kryo"); + + // MSM8992/4 weirdness + StringRef MSM8992ProcCpuInfo = R"( +Processor : AArch64 Processor rev 3 (aarch64) +processor : 0 +processor : 1 +processor : 2 +processor : 3 +processor : 4 +processor : 5 +Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 +CPU implementer : 0x41 +CPU architecture: 8 +CPU variant : 0x0 +CPU part : 0xd03 +CPU revision : 3 + +Hardware : Qualcomm Technologies, Inc MSM8992 +)"; + + EXPECT_EQ(sys::detail::getHostCPUNameForARM(MSM8992ProcCpuInfo), + "cortex-a53"); +}