1f09cf34dSArchibald Elliott //===-- Host.cpp - Implement OS Host Detection ------------------*- C++ -*-===// 2f09cf34dSArchibald Elliott // 3f09cf34dSArchibald Elliott // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4f09cf34dSArchibald Elliott // See https://llvm.org/LICENSE.txt for license information. 5f09cf34dSArchibald Elliott // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6f09cf34dSArchibald Elliott // 7f09cf34dSArchibald Elliott //===----------------------------------------------------------------------===// 8f09cf34dSArchibald Elliott // 9f09cf34dSArchibald Elliott // This file implements the operating system Host detection. 10f09cf34dSArchibald Elliott // 11f09cf34dSArchibald Elliott //===----------------------------------------------------------------------===// 12f09cf34dSArchibald Elliott 13f09cf34dSArchibald Elliott #include "llvm/TargetParser/Host.h" 14f09cf34dSArchibald Elliott #include "llvm/ADT/SmallVector.h" 15f09cf34dSArchibald Elliott #include "llvm/ADT/StringMap.h" 16f09cf34dSArchibald Elliott #include "llvm/ADT/StringRef.h" 17f09cf34dSArchibald Elliott #include "llvm/ADT/StringSwitch.h" 18f09cf34dSArchibald Elliott #include "llvm/Config/llvm-config.h" 19f09cf34dSArchibald Elliott #include "llvm/Support/MemoryBuffer.h" 20f09cf34dSArchibald Elliott #include "llvm/Support/raw_ostream.h" 21f09cf34dSArchibald Elliott #include "llvm/TargetParser/Triple.h" 22f09cf34dSArchibald Elliott #include "llvm/TargetParser/X86TargetParser.h" 23f09cf34dSArchibald Elliott #include <string.h> 24f09cf34dSArchibald Elliott 25f09cf34dSArchibald Elliott // Include the platform-specific parts of this class. 26f09cf34dSArchibald Elliott #ifdef LLVM_ON_UNIX 27f09cf34dSArchibald Elliott #include "Unix/Host.inc" 28f09cf34dSArchibald Elliott #include <sched.h> 29f09cf34dSArchibald Elliott #endif 30f09cf34dSArchibald Elliott #ifdef _WIN32 31f09cf34dSArchibald Elliott #include "Windows/Host.inc" 32f09cf34dSArchibald Elliott #endif 33f09cf34dSArchibald Elliott #ifdef _MSC_VER 34f09cf34dSArchibald Elliott #include <intrin.h> 35f09cf34dSArchibald Elliott #endif 36f09cf34dSArchibald Elliott #ifdef __MVS__ 37f09cf34dSArchibald Elliott #include "llvm/Support/BCD.h" 38f09cf34dSArchibald Elliott #endif 39f09cf34dSArchibald Elliott #if defined(__APPLE__) 40f09cf34dSArchibald Elliott #include <mach/host_info.h> 41f09cf34dSArchibald Elliott #include <mach/mach.h> 42f09cf34dSArchibald Elliott #include <mach/mach_host.h> 43f09cf34dSArchibald Elliott #include <mach/machine.h> 44f09cf34dSArchibald Elliott #include <sys/param.h> 45f09cf34dSArchibald Elliott #include <sys/sysctl.h> 46f09cf34dSArchibald Elliott #endif 47f09cf34dSArchibald Elliott #ifdef _AIX 48f09cf34dSArchibald Elliott #include <sys/systemcfg.h> 49f09cf34dSArchibald Elliott #endif 50f09cf34dSArchibald Elliott #if defined(__sun__) && defined(__svr4__) 51f09cf34dSArchibald Elliott #include <kstat.h> 52f09cf34dSArchibald Elliott #endif 53599f8e11SAiden Grossman #if defined(__GNUC__) || defined(__clang__) 54599f8e11SAiden Grossman #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER) 55599f8e11SAiden Grossman #include <cpuid.h> 56599f8e11SAiden Grossman #endif 57599f8e11SAiden Grossman #endif 58f09cf34dSArchibald Elliott 59f09cf34dSArchibald Elliott #define DEBUG_TYPE "host-detection" 60f09cf34dSArchibald Elliott 61f09cf34dSArchibald Elliott //===----------------------------------------------------------------------===// 62f09cf34dSArchibald Elliott // 63f09cf34dSArchibald Elliott // Implementations of the CPU detection routines 64f09cf34dSArchibald Elliott // 65f09cf34dSArchibald Elliott //===----------------------------------------------------------------------===// 66f09cf34dSArchibald Elliott 67f09cf34dSArchibald Elliott using namespace llvm; 68f09cf34dSArchibald Elliott 69f09cf34dSArchibald Elliott static std::unique_ptr<llvm::MemoryBuffer> 70f09cf34dSArchibald Elliott LLVM_ATTRIBUTE_UNUSED getProcCpuinfoContent() { 71133f8fa2SElvina Yakubova const char *CPUInfoFile = "/proc/cpuinfo"; 72133f8fa2SElvina Yakubova if (const char *CpuinfoIntercept = std::getenv("LLVM_CPUINFO")) 73133f8fa2SElvina Yakubova CPUInfoFile = CpuinfoIntercept; 74f09cf34dSArchibald Elliott llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text = 75133f8fa2SElvina Yakubova llvm::MemoryBuffer::getFileAsStream(CPUInfoFile); 76133f8fa2SElvina Yakubova 77f09cf34dSArchibald Elliott if (std::error_code EC = Text.getError()) { 78133f8fa2SElvina Yakubova llvm::errs() << "Can't read " << CPUInfoFile << ": " << EC.message() 79133f8fa2SElvina Yakubova << "\n"; 80f09cf34dSArchibald Elliott return nullptr; 81f09cf34dSArchibald Elliott } 82f09cf34dSArchibald Elliott return std::move(*Text); 83f09cf34dSArchibald Elliott } 84f09cf34dSArchibald Elliott 85f09cf34dSArchibald Elliott StringRef sys::detail::getHostCPUNameForPowerPC(StringRef ProcCpuinfoContent) { 86f09cf34dSArchibald Elliott // Access to the Processor Version Register (PVR) on PowerPC is privileged, 87f09cf34dSArchibald Elliott // and so we must use an operating-system interface to determine the current 88f09cf34dSArchibald Elliott // processor type. On Linux, this is exposed through the /proc/cpuinfo file. 89f09cf34dSArchibald Elliott const char *generic = "generic"; 90f09cf34dSArchibald Elliott 91f09cf34dSArchibald Elliott // The cpu line is second (after the 'processor: 0' line), so if this 92f09cf34dSArchibald Elliott // buffer is too small then something has changed (or is wrong). 93f09cf34dSArchibald Elliott StringRef::const_iterator CPUInfoStart = ProcCpuinfoContent.begin(); 94f09cf34dSArchibald Elliott StringRef::const_iterator CPUInfoEnd = ProcCpuinfoContent.end(); 95f09cf34dSArchibald Elliott 96f09cf34dSArchibald Elliott StringRef::const_iterator CIP = CPUInfoStart; 97f09cf34dSArchibald Elliott 98f09cf34dSArchibald Elliott StringRef::const_iterator CPUStart = nullptr; 99f09cf34dSArchibald Elliott size_t CPULen = 0; 100f09cf34dSArchibald Elliott 101f09cf34dSArchibald Elliott // We need to find the first line which starts with cpu, spaces, and a colon. 102f09cf34dSArchibald Elliott // After the colon, there may be some additional spaces and then the cpu type. 103f09cf34dSArchibald Elliott while (CIP < CPUInfoEnd && CPUStart == nullptr) { 104f09cf34dSArchibald Elliott if (CIP < CPUInfoEnd && *CIP == '\n') 105f09cf34dSArchibald Elliott ++CIP; 106f09cf34dSArchibald Elliott 107f09cf34dSArchibald Elliott if (CIP < CPUInfoEnd && *CIP == 'c') { 108f09cf34dSArchibald Elliott ++CIP; 109f09cf34dSArchibald Elliott if (CIP < CPUInfoEnd && *CIP == 'p') { 110f09cf34dSArchibald Elliott ++CIP; 111f09cf34dSArchibald Elliott if (CIP < CPUInfoEnd && *CIP == 'u') { 112f09cf34dSArchibald Elliott ++CIP; 113f09cf34dSArchibald Elliott while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) 114f09cf34dSArchibald Elliott ++CIP; 115f09cf34dSArchibald Elliott 116f09cf34dSArchibald Elliott if (CIP < CPUInfoEnd && *CIP == ':') { 117f09cf34dSArchibald Elliott ++CIP; 118f09cf34dSArchibald Elliott while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t')) 119f09cf34dSArchibald Elliott ++CIP; 120f09cf34dSArchibald Elliott 121f09cf34dSArchibald Elliott if (CIP < CPUInfoEnd) { 122f09cf34dSArchibald Elliott CPUStart = CIP; 123f09cf34dSArchibald Elliott while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' && 124f09cf34dSArchibald Elliott *CIP != ',' && *CIP != '\n')) 125f09cf34dSArchibald Elliott ++CIP; 126f09cf34dSArchibald Elliott CPULen = CIP - CPUStart; 127f09cf34dSArchibald Elliott } 128f09cf34dSArchibald Elliott } 129f09cf34dSArchibald Elliott } 130f09cf34dSArchibald Elliott } 131f09cf34dSArchibald Elliott } 132f09cf34dSArchibald Elliott 133f09cf34dSArchibald Elliott if (CPUStart == nullptr) 134f09cf34dSArchibald Elliott while (CIP < CPUInfoEnd && *CIP != '\n') 135f09cf34dSArchibald Elliott ++CIP; 136f09cf34dSArchibald Elliott } 137f09cf34dSArchibald Elliott 138f09cf34dSArchibald Elliott if (CPUStart == nullptr) 139f09cf34dSArchibald Elliott return generic; 140f09cf34dSArchibald Elliott 141f09cf34dSArchibald Elliott return StringSwitch<const char *>(StringRef(CPUStart, CPULen)) 142f09cf34dSArchibald Elliott .Case("604e", "604e") 143f09cf34dSArchibald Elliott .Case("604", "604") 144f09cf34dSArchibald Elliott .Case("7400", "7400") 145f09cf34dSArchibald Elliott .Case("7410", "7400") 146f09cf34dSArchibald Elliott .Case("7447", "7400") 147f09cf34dSArchibald Elliott .Case("7455", "7450") 148f09cf34dSArchibald Elliott .Case("G4", "g4") 149f09cf34dSArchibald Elliott .Case("POWER4", "970") 150f09cf34dSArchibald Elliott .Case("PPC970FX", "970") 151f09cf34dSArchibald Elliott .Case("PPC970MP", "970") 152f09cf34dSArchibald Elliott .Case("G5", "g5") 153f09cf34dSArchibald Elliott .Case("POWER5", "g5") 154f09cf34dSArchibald Elliott .Case("A2", "a2") 155f09cf34dSArchibald Elliott .Case("POWER6", "pwr6") 156f09cf34dSArchibald Elliott .Case("POWER7", "pwr7") 157f09cf34dSArchibald Elliott .Case("POWER8", "pwr8") 158f09cf34dSArchibald Elliott .Case("POWER8E", "pwr8") 159f09cf34dSArchibald Elliott .Case("POWER8NVL", "pwr8") 160f09cf34dSArchibald Elliott .Case("POWER9", "pwr9") 161f09cf34dSArchibald Elliott .Case("POWER10", "pwr10") 1621df4d866Sazhan92 .Case("POWER11", "pwr11") 163f09cf34dSArchibald Elliott // FIXME: If we get a simulator or machine with the capabilities of 164f09cf34dSArchibald Elliott // mcpu=future, we should revisit this and add the name reported by the 165f09cf34dSArchibald Elliott // simulator/machine. 166f09cf34dSArchibald Elliott .Default(generic); 167f09cf34dSArchibald Elliott } 168f09cf34dSArchibald Elliott 169f09cf34dSArchibald Elliott StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) { 170f09cf34dSArchibald Elliott // The cpuid register on arm is not accessible from user space. On Linux, 171f09cf34dSArchibald Elliott // it is exposed through the /proc/cpuinfo file. 172f09cf34dSArchibald Elliott 173f09cf34dSArchibald Elliott // Read 32 lines from /proc/cpuinfo, which should contain the CPU part line 174f09cf34dSArchibald Elliott // in all cases. 175f09cf34dSArchibald Elliott SmallVector<StringRef, 32> Lines; 176fd38a955SCraig Topper ProcCpuinfoContent.split(Lines, '\n'); 177f09cf34dSArchibald Elliott 178f09cf34dSArchibald Elliott // Look for the CPU implementer line. 179f09cf34dSArchibald Elliott StringRef Implementer; 180f09cf34dSArchibald Elliott StringRef Hardware; 181f09cf34dSArchibald Elliott StringRef Part; 182f09cf34dSArchibald Elliott for (unsigned I = 0, E = Lines.size(); I != E; ++I) { 183586ecdf2SKazu Hirata if (Lines[I].starts_with("CPU implementer")) 184f09cf34dSArchibald Elliott Implementer = Lines[I].substr(15).ltrim("\t :"); 185586ecdf2SKazu Hirata if (Lines[I].starts_with("Hardware")) 186f09cf34dSArchibald Elliott Hardware = Lines[I].substr(8).ltrim("\t :"); 187586ecdf2SKazu Hirata if (Lines[I].starts_with("CPU part")) 188f09cf34dSArchibald Elliott Part = Lines[I].substr(8).ltrim("\t :"); 189f09cf34dSArchibald Elliott } 190f09cf34dSArchibald Elliott 191f09cf34dSArchibald Elliott if (Implementer == "0x41") { // ARM Ltd. 192f09cf34dSArchibald Elliott // MSM8992/8994 may give cpu part for the core that the kernel is running on, 193f09cf34dSArchibald Elliott // which is undeterministic and wrong. Always return cortex-a53 for these SoC. 194586ecdf2SKazu Hirata if (Hardware.ends_with("MSM8994") || Hardware.ends_with("MSM8996")) 195f09cf34dSArchibald Elliott return "cortex-a53"; 196f09cf34dSArchibald Elliott 197f09cf34dSArchibald Elliott 198f09cf34dSArchibald Elliott // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 199f09cf34dSArchibald Elliott // values correspond to the "Part number" in the CP15/c0 register. The 200f09cf34dSArchibald Elliott // contents are specified in the various processor manuals. 201f09cf34dSArchibald Elliott // This corresponds to the Main ID Register in Technical Reference Manuals. 202f09cf34dSArchibald Elliott // and is used in programs like sys-utils 203f09cf34dSArchibald Elliott return StringSwitch<const char *>(Part) 204f09cf34dSArchibald Elliott .Case("0x926", "arm926ej-s") 205f09cf34dSArchibald Elliott .Case("0xb02", "mpcore") 206f09cf34dSArchibald Elliott .Case("0xb36", "arm1136j-s") 207f09cf34dSArchibald Elliott .Case("0xb56", "arm1156t2-s") 208f09cf34dSArchibald Elliott .Case("0xb76", "arm1176jz-s") 20999be3875SJonathan Thackray .Case("0xc05", "cortex-a5") 21099be3875SJonathan Thackray .Case("0xc07", "cortex-a7") 211f09cf34dSArchibald Elliott .Case("0xc08", "cortex-a8") 212f09cf34dSArchibald Elliott .Case("0xc09", "cortex-a9") 213f09cf34dSArchibald Elliott .Case("0xc0f", "cortex-a15") 21499be3875SJonathan Thackray .Case("0xc0e", "cortex-a17") 215f09cf34dSArchibald Elliott .Case("0xc20", "cortex-m0") 216f09cf34dSArchibald Elliott .Case("0xc23", "cortex-m3") 217f09cf34dSArchibald Elliott .Case("0xc24", "cortex-m4") 21899be3875SJonathan Thackray .Case("0xc27", "cortex-m7") 21999be3875SJonathan Thackray .Case("0xd20", "cortex-m23") 22099be3875SJonathan Thackray .Case("0xd21", "cortex-m33") 2218758e648SJonathan Thackray .Case("0xd24", "cortex-m52") 222f09cf34dSArchibald Elliott .Case("0xd22", "cortex-m55") 22399be3875SJonathan Thackray .Case("0xd23", "cortex-m85") 22499be3875SJonathan Thackray .Case("0xc18", "cortex-r8") 22599be3875SJonathan Thackray .Case("0xd13", "cortex-r52") 226917afa88SJonathan Thackray .Case("0xd16", "cortex-r52plus") 22799be3875SJonathan Thackray .Case("0xd15", "cortex-r82") 228e50a857fSJonathan Thackray .Case("0xd14", "cortex-r82ae") 229f09cf34dSArchibald Elliott .Case("0xd02", "cortex-a34") 230f09cf34dSArchibald Elliott .Case("0xd04", "cortex-a35") 231f09cf34dSArchibald Elliott .Case("0xd03", "cortex-a53") 232f09cf34dSArchibald Elliott .Case("0xd05", "cortex-a55") 233f09cf34dSArchibald Elliott .Case("0xd46", "cortex-a510") 234066c4524SJonathan Thackray .Case("0xd80", "cortex-a520") 235e85bfa65SJonathan Thackray .Case("0xd88", "cortex-a520ae") 236f09cf34dSArchibald Elliott .Case("0xd07", "cortex-a57") 23799be3875SJonathan Thackray .Case("0xd06", "cortex-a65") 23899be3875SJonathan Thackray .Case("0xd43", "cortex-a65ae") 239f09cf34dSArchibald Elliott .Case("0xd08", "cortex-a72") 240f09cf34dSArchibald Elliott .Case("0xd09", "cortex-a73") 241f09cf34dSArchibald Elliott .Case("0xd0a", "cortex-a75") 242f09cf34dSArchibald Elliott .Case("0xd0b", "cortex-a76") 24399be3875SJonathan Thackray .Case("0xd0e", "cortex-a76ae") 244f09cf34dSArchibald Elliott .Case("0xd0d", "cortex-a77") 245f09cf34dSArchibald Elliott .Case("0xd41", "cortex-a78") 24681601391SJonathan Thackray .Case("0xd42", "cortex-a78ae") 24799be3875SJonathan Thackray .Case("0xd4b", "cortex-a78c") 248f09cf34dSArchibald Elliott .Case("0xd47", "cortex-a710") 249f09cf34dSArchibald Elliott .Case("0xd4d", "cortex-a715") 250066c4524SJonathan Thackray .Case("0xd81", "cortex-a720") 251e85bfa65SJonathan Thackray .Case("0xd89", "cortex-a720ae") 252e80c5955SJonathan Thackray .Case("0xd87", "cortex-a725") 253f09cf34dSArchibald Elliott .Case("0xd44", "cortex-x1") 254f09cf34dSArchibald Elliott .Case("0xd4c", "cortex-x1c") 255f09cf34dSArchibald Elliott .Case("0xd48", "cortex-x2") 256f09cf34dSArchibald Elliott .Case("0xd4e", "cortex-x3") 257066c4524SJonathan Thackray .Case("0xd82", "cortex-x4") 258e80c5955SJonathan Thackray .Case("0xd85", "cortex-x925") 25999be3875SJonathan Thackray .Case("0xd4a", "neoverse-e1") 260f09cf34dSArchibald Elliott .Case("0xd0c", "neoverse-n1") 261f09cf34dSArchibald Elliott .Case("0xd49", "neoverse-n2") 262a670cdadSJonathan Thackray .Case("0xd8e", "neoverse-n3") 263f09cf34dSArchibald Elliott .Case("0xd40", "neoverse-v1") 264f09cf34dSArchibald Elliott .Case("0xd4f", "neoverse-v2") 265a670cdadSJonathan Thackray .Case("0xd84", "neoverse-v3") 266a670cdadSJonathan Thackray .Case("0xd83", "neoverse-v3ae") 267f09cf34dSArchibald Elliott .Default("generic"); 268f09cf34dSArchibald Elliott } 269f09cf34dSArchibald Elliott 270f09cf34dSArchibald Elliott if (Implementer == "0x42" || Implementer == "0x43") { // Broadcom | Cavium. 271f09cf34dSArchibald Elliott return StringSwitch<const char *>(Part) 272f09cf34dSArchibald Elliott .Case("0x516", "thunderx2t99") 273f09cf34dSArchibald Elliott .Case("0x0516", "thunderx2t99") 274f09cf34dSArchibald Elliott .Case("0xaf", "thunderx2t99") 275f09cf34dSArchibald Elliott .Case("0x0af", "thunderx2t99") 276f09cf34dSArchibald Elliott .Case("0xa1", "thunderxt88") 277f09cf34dSArchibald Elliott .Case("0x0a1", "thunderxt88") 278f09cf34dSArchibald Elliott .Default("generic"); 279f09cf34dSArchibald Elliott } 280f09cf34dSArchibald Elliott 281f09cf34dSArchibald Elliott if (Implementer == "0x46") { // Fujitsu Ltd. 282f09cf34dSArchibald Elliott return StringSwitch<const char *>(Part) 283f09cf34dSArchibald Elliott .Case("0x001", "a64fx") 284a1197a2cSKinoshita Kotaro .Case("0x003", "fujitsu-monaka") 285f09cf34dSArchibald Elliott .Default("generic"); 286f09cf34dSArchibald Elliott } 287f09cf34dSArchibald Elliott 288f09cf34dSArchibald Elliott if (Implementer == "0x4e") { // NVIDIA Corporation 289f09cf34dSArchibald Elliott return StringSwitch<const char *>(Part) 290f09cf34dSArchibald Elliott .Case("0x004", "carmel") 291f09cf34dSArchibald Elliott .Default("generic"); 292f09cf34dSArchibald Elliott } 293f09cf34dSArchibald Elliott 294f09cf34dSArchibald Elliott if (Implementer == "0x48") // HiSilicon Technologies, Inc. 295f09cf34dSArchibald Elliott // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 296f09cf34dSArchibald Elliott // values correspond to the "Part number" in the CP15/c0 register. The 297f09cf34dSArchibald Elliott // contents are specified in the various processor manuals. 298f09cf34dSArchibald Elliott return StringSwitch<const char *>(Part) 299f09cf34dSArchibald Elliott .Case("0xd01", "tsv110") 300f09cf34dSArchibald Elliott .Default("generic"); 301f09cf34dSArchibald Elliott 302f09cf34dSArchibald Elliott if (Implementer == "0x51") // Qualcomm Technologies, Inc. 303f09cf34dSArchibald Elliott // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The 304f09cf34dSArchibald Elliott // values correspond to the "Part number" in the CP15/c0 register. The 305f09cf34dSArchibald Elliott // contents are specified in the various processor manuals. 306f09cf34dSArchibald Elliott return StringSwitch<const char *>(Part) 307f09cf34dSArchibald Elliott .Case("0x06f", "krait") // APQ8064 308f09cf34dSArchibald Elliott .Case("0x201", "kryo") 309f09cf34dSArchibald Elliott .Case("0x205", "kryo") 310f09cf34dSArchibald Elliott .Case("0x211", "kryo") 311f09cf34dSArchibald Elliott .Case("0x800", "cortex-a73") // Kryo 2xx Gold 312f09cf34dSArchibald Elliott .Case("0x801", "cortex-a73") // Kryo 2xx Silver 313f09cf34dSArchibald Elliott .Case("0x802", "cortex-a75") // Kryo 3xx Gold 314f09cf34dSArchibald Elliott .Case("0x803", "cortex-a75") // Kryo 3xx Silver 315f09cf34dSArchibald Elliott .Case("0x804", "cortex-a76") // Kryo 4xx Gold 316f09cf34dSArchibald Elliott .Case("0x805", "cortex-a76") // Kryo 4xx/5xx Silver 317f09cf34dSArchibald Elliott .Case("0xc00", "falkor") 318f09cf34dSArchibald Elliott .Case("0xc01", "saphira") 3196b9753a0SWei Zhao .Case("0x001", "oryon-1") 320f09cf34dSArchibald Elliott .Default("generic"); 321f09cf34dSArchibald Elliott if (Implementer == "0x53") { // Samsung Electronics Co., Ltd. 322f09cf34dSArchibald Elliott // The Exynos chips have a convoluted ID scheme that doesn't seem to follow 323f09cf34dSArchibald Elliott // any predictive pattern across variants and parts. 324f09cf34dSArchibald Elliott unsigned Variant = 0, Part = 0; 325f09cf34dSArchibald Elliott 326f09cf34dSArchibald Elliott // Look for the CPU variant line, whose value is a 1 digit hexadecimal 327f09cf34dSArchibald Elliott // number, corresponding to the Variant bits in the CP15/C0 register. 328f09cf34dSArchibald Elliott for (auto I : Lines) 329f09cf34dSArchibald Elliott if (I.consume_front("CPU variant")) 330f09cf34dSArchibald Elliott I.ltrim("\t :").getAsInteger(0, Variant); 331f09cf34dSArchibald Elliott 332f09cf34dSArchibald Elliott // Look for the CPU part line, whose value is a 3 digit hexadecimal 333f09cf34dSArchibald Elliott // number, corresponding to the PartNum bits in the CP15/C0 register. 334f09cf34dSArchibald Elliott for (auto I : Lines) 335f09cf34dSArchibald Elliott if (I.consume_front("CPU part")) 336f09cf34dSArchibald Elliott I.ltrim("\t :").getAsInteger(0, Part); 337f09cf34dSArchibald Elliott 338f09cf34dSArchibald Elliott unsigned Exynos = (Variant << 12) | Part; 339f09cf34dSArchibald Elliott switch (Exynos) { 340f09cf34dSArchibald Elliott default: 341f09cf34dSArchibald Elliott // Default by falling through to Exynos M3. 342f09cf34dSArchibald Elliott [[fallthrough]]; 343f09cf34dSArchibald Elliott case 0x1002: 344f09cf34dSArchibald Elliott return "exynos-m3"; 345f09cf34dSArchibald Elliott case 0x1003: 346f09cf34dSArchibald Elliott return "exynos-m4"; 347f09cf34dSArchibald Elliott } 348f09cf34dSArchibald Elliott } 349f09cf34dSArchibald Elliott 35038eaea73Spcc if (Implementer == "0x61") { // Apple 35138eaea73Spcc return StringSwitch<const char *>(Part) 35238eaea73Spcc .Case("0x020", "apple-m1") 35338eaea73Spcc .Case("0x021", "apple-m1") 35438eaea73Spcc .Case("0x022", "apple-m1") 35538eaea73Spcc .Case("0x023", "apple-m1") 35638eaea73Spcc .Case("0x024", "apple-m1") 35738eaea73Spcc .Case("0x025", "apple-m1") 35838eaea73Spcc .Case("0x028", "apple-m1") 35938eaea73Spcc .Case("0x029", "apple-m1") 36038eaea73Spcc .Case("0x030", "apple-m2") 36138eaea73Spcc .Case("0x031", "apple-m2") 36238eaea73Spcc .Case("0x032", "apple-m2") 36338eaea73Spcc .Case("0x033", "apple-m2") 36438eaea73Spcc .Case("0x034", "apple-m2") 36538eaea73Spcc .Case("0x035", "apple-m2") 36638eaea73Spcc .Case("0x038", "apple-m2") 36738eaea73Spcc .Case("0x039", "apple-m2") 36838eaea73Spcc .Case("0x049", "apple-m3") 36938eaea73Spcc .Case("0x048", "apple-m3") 37038eaea73Spcc .Default("generic"); 37138eaea73Spcc } 37238eaea73Spcc 373aa2c0f35SAlbert Huang if (Implementer == "0x63") { // Arm China. 374aa2c0f35SAlbert Huang return StringSwitch<const char *>(Part) 375aa2c0f35SAlbert Huang .Case("0x132", "star-mc1") 376aa2c0f35SAlbert Huang .Default("generic"); 377aa2c0f35SAlbert Huang } 378aa2c0f35SAlbert Huang 379a690e867SAlexandros Lamprineas if (Implementer == "0x6d") { // Microsoft Corporation. 380a690e867SAlexandros Lamprineas // The Microsoft Azure Cobalt 100 CPU is handled as a Neoverse N2. 381a690e867SAlexandros Lamprineas return StringSwitch<const char *>(Part) 382a690e867SAlexandros Lamprineas .Case("0xd49", "neoverse-n2") 383a690e867SAlexandros Lamprineas .Default("generic"); 384a690e867SAlexandros Lamprineas } 385a690e867SAlexandros Lamprineas 386f09cf34dSArchibald Elliott if (Implementer == "0xc0") { // Ampere Computing 387f09cf34dSArchibald Elliott return StringSwitch<const char *>(Part) 388f09cf34dSArchibald Elliott .Case("0xac3", "ampere1") 389fb0af891SPhilipp Tomsich .Case("0xac4", "ampere1a") 390fbba818aSPhilipp Tomsich .Case("0xac5", "ampere1b") 391f09cf34dSArchibald Elliott .Default("generic"); 392f09cf34dSArchibald Elliott } 393f09cf34dSArchibald Elliott 394f09cf34dSArchibald Elliott return "generic"; 395f09cf34dSArchibald Elliott } 396f09cf34dSArchibald Elliott 397f09cf34dSArchibald Elliott namespace { 398f09cf34dSArchibald Elliott StringRef getCPUNameFromS390Model(unsigned int Id, bool HaveVectorSupport) { 399f09cf34dSArchibald Elliott switch (Id) { 400f09cf34dSArchibald Elliott case 2064: // z900 not supported by LLVM 401f09cf34dSArchibald Elliott case 2066: 402f09cf34dSArchibald Elliott case 2084: // z990 not supported by LLVM 403f09cf34dSArchibald Elliott case 2086: 404f09cf34dSArchibald Elliott case 2094: // z9-109 not supported by LLVM 405f09cf34dSArchibald Elliott case 2096: 406f09cf34dSArchibald Elliott return "generic"; 407f09cf34dSArchibald Elliott case 2097: 408f09cf34dSArchibald Elliott case 2098: 409f09cf34dSArchibald Elliott return "z10"; 410f09cf34dSArchibald Elliott case 2817: 411f09cf34dSArchibald Elliott case 2818: 412f09cf34dSArchibald Elliott return "z196"; 413f09cf34dSArchibald Elliott case 2827: 414f09cf34dSArchibald Elliott case 2828: 415f09cf34dSArchibald Elliott return "zEC12"; 416f09cf34dSArchibald Elliott case 2964: 417f09cf34dSArchibald Elliott case 2965: 418f09cf34dSArchibald Elliott return HaveVectorSupport? "z13" : "zEC12"; 419f09cf34dSArchibald Elliott case 3906: 420f09cf34dSArchibald Elliott case 3907: 421f09cf34dSArchibald Elliott return HaveVectorSupport? "z14" : "zEC12"; 422f09cf34dSArchibald Elliott case 8561: 423f09cf34dSArchibald Elliott case 8562: 424f09cf34dSArchibald Elliott return HaveVectorSupport? "z15" : "zEC12"; 425f09cf34dSArchibald Elliott case 3931: 426f09cf34dSArchibald Elliott case 3932: 427f09cf34dSArchibald Elliott return HaveVectorSupport? "z16" : "zEC12"; 4288424bf20SUlrich Weigand case 9175: 4298424bf20SUlrich Weigand case 9176: 4308424bf20SUlrich Weigand default: 4318424bf20SUlrich Weigand return HaveVectorSupport? "arch15" : "zEC12"; 432f09cf34dSArchibald Elliott } 433f09cf34dSArchibald Elliott } 434f09cf34dSArchibald Elliott } // end anonymous namespace 435f09cf34dSArchibald Elliott 436f09cf34dSArchibald Elliott StringRef sys::detail::getHostCPUNameForS390x(StringRef ProcCpuinfoContent) { 437f09cf34dSArchibald Elliott // STIDP is a privileged operation, so use /proc/cpuinfo instead. 438f09cf34dSArchibald Elliott 439f09cf34dSArchibald Elliott // The "processor 0:" line comes after a fair amount of other information, 440f09cf34dSArchibald Elliott // including a cache breakdown, but this should be plenty. 441f09cf34dSArchibald Elliott SmallVector<StringRef, 32> Lines; 442fd38a955SCraig Topper ProcCpuinfoContent.split(Lines, '\n'); 443f09cf34dSArchibald Elliott 444f09cf34dSArchibald Elliott // Look for the CPU features. 445f09cf34dSArchibald Elliott SmallVector<StringRef, 32> CPUFeatures; 446f09cf34dSArchibald Elliott for (unsigned I = 0, E = Lines.size(); I != E; ++I) 447586ecdf2SKazu Hirata if (Lines[I].starts_with("features")) { 448f09cf34dSArchibald Elliott size_t Pos = Lines[I].find(':'); 449f09cf34dSArchibald Elliott if (Pos != StringRef::npos) { 450f09cf34dSArchibald Elliott Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' '); 451f09cf34dSArchibald Elliott break; 452f09cf34dSArchibald Elliott } 453f09cf34dSArchibald Elliott } 454f09cf34dSArchibald Elliott 455f09cf34dSArchibald Elliott // We need to check for the presence of vector support independently of 456f09cf34dSArchibald Elliott // the machine type, since we may only use the vector register set when 457f09cf34dSArchibald Elliott // supported by the kernel (and hypervisor). 458f09cf34dSArchibald Elliott bool HaveVectorSupport = false; 459f09cf34dSArchibald Elliott for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { 460f09cf34dSArchibald Elliott if (CPUFeatures[I] == "vx") 461f09cf34dSArchibald Elliott HaveVectorSupport = true; 462f09cf34dSArchibald Elliott } 463f09cf34dSArchibald Elliott 464f09cf34dSArchibald Elliott // Now check the processor machine type. 465f09cf34dSArchibald Elliott for (unsigned I = 0, E = Lines.size(); I != E; ++I) { 466586ecdf2SKazu Hirata if (Lines[I].starts_with("processor ")) { 467f09cf34dSArchibald Elliott size_t Pos = Lines[I].find("machine = "); 468f09cf34dSArchibald Elliott if (Pos != StringRef::npos) { 469f09cf34dSArchibald Elliott Pos += sizeof("machine = ") - 1; 470f09cf34dSArchibald Elliott unsigned int Id; 471f09cf34dSArchibald Elliott if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) 472f09cf34dSArchibald Elliott return getCPUNameFromS390Model(Id, HaveVectorSupport); 473f09cf34dSArchibald Elliott } 474f09cf34dSArchibald Elliott break; 475f09cf34dSArchibald Elliott } 476f09cf34dSArchibald Elliott } 477f09cf34dSArchibald Elliott 478f09cf34dSArchibald Elliott return "generic"; 479f09cf34dSArchibald Elliott } 480f09cf34dSArchibald Elliott 481f09cf34dSArchibald Elliott StringRef sys::detail::getHostCPUNameForRISCV(StringRef ProcCpuinfoContent) { 482f09cf34dSArchibald Elliott // There are 24 lines in /proc/cpuinfo 483f09cf34dSArchibald Elliott SmallVector<StringRef> Lines; 484fd38a955SCraig Topper ProcCpuinfoContent.split(Lines, '\n'); 485f09cf34dSArchibald Elliott 486f09cf34dSArchibald Elliott // Look for uarch line to determine cpu name 487f09cf34dSArchibald Elliott StringRef UArch; 488f09cf34dSArchibald Elliott for (unsigned I = 0, E = Lines.size(); I != E; ++I) { 489586ecdf2SKazu Hirata if (Lines[I].starts_with("uarch")) { 490f09cf34dSArchibald Elliott UArch = Lines[I].substr(5).ltrim("\t :"); 491f09cf34dSArchibald Elliott break; 492f09cf34dSArchibald Elliott } 493f09cf34dSArchibald Elliott } 494f09cf34dSArchibald Elliott 495f09cf34dSArchibald Elliott return StringSwitch<const char *>(UArch) 496f09cf34dSArchibald Elliott .Case("sifive,u74-mc", "sifive-u74") 497f09cf34dSArchibald Elliott .Case("sifive,bullet0", "sifive-u74") 498578cf724SYingwei Zheng .Default(""); 499f09cf34dSArchibald Elliott } 500f09cf34dSArchibald Elliott 501f09cf34dSArchibald Elliott StringRef sys::detail::getHostCPUNameForBPF() { 502f09cf34dSArchibald Elliott #if !defined(__linux__) || !defined(__x86_64__) 503f09cf34dSArchibald Elliott return "generic"; 504f09cf34dSArchibald Elliott #else 505f09cf34dSArchibald Elliott uint8_t v3_insns[40] __attribute__ ((aligned (8))) = 506f09cf34dSArchibald Elliott /* BPF_MOV64_IMM(BPF_REG_0, 0) */ 507f09cf34dSArchibald Elliott { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 508f09cf34dSArchibald Elliott /* BPF_MOV64_IMM(BPF_REG_2, 1) */ 509f09cf34dSArchibald Elliott 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 510f09cf34dSArchibald Elliott /* BPF_JMP32_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */ 511f09cf34dSArchibald Elliott 0xae, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 512f09cf34dSArchibald Elliott /* BPF_MOV64_IMM(BPF_REG_0, 1) */ 513f09cf34dSArchibald Elliott 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 514f09cf34dSArchibald Elliott /* BPF_EXIT_INSN() */ 515f09cf34dSArchibald Elliott 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; 516f09cf34dSArchibald Elliott 517f09cf34dSArchibald Elliott uint8_t v2_insns[40] __attribute__ ((aligned (8))) = 518f09cf34dSArchibald Elliott /* BPF_MOV64_IMM(BPF_REG_0, 0) */ 519f09cf34dSArchibald Elliott { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 520f09cf34dSArchibald Elliott /* BPF_MOV64_IMM(BPF_REG_2, 1) */ 521f09cf34dSArchibald Elliott 0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 522f09cf34dSArchibald Elliott /* BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */ 523f09cf34dSArchibald Elliott 0xad, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 524f09cf34dSArchibald Elliott /* BPF_MOV64_IMM(BPF_REG_0, 1) */ 525f09cf34dSArchibald Elliott 0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 526f09cf34dSArchibald Elliott /* BPF_EXIT_INSN() */ 527f09cf34dSArchibald Elliott 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; 528f09cf34dSArchibald Elliott 529f09cf34dSArchibald Elliott struct bpf_prog_load_attr { 530f09cf34dSArchibald Elliott uint32_t prog_type; 531f09cf34dSArchibald Elliott uint32_t insn_cnt; 532f09cf34dSArchibald Elliott uint64_t insns; 533f09cf34dSArchibald Elliott uint64_t license; 534f09cf34dSArchibald Elliott uint32_t log_level; 535f09cf34dSArchibald Elliott uint32_t log_size; 536f09cf34dSArchibald Elliott uint64_t log_buf; 537f09cf34dSArchibald Elliott uint32_t kern_version; 538f09cf34dSArchibald Elliott uint32_t prog_flags; 539f09cf34dSArchibald Elliott } attr = {}; 540f09cf34dSArchibald Elliott attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */ 541f09cf34dSArchibald Elliott attr.insn_cnt = 5; 542f09cf34dSArchibald Elliott attr.insns = (uint64_t)v3_insns; 543f09cf34dSArchibald Elliott attr.license = (uint64_t)"DUMMY"; 544f09cf34dSArchibald Elliott 545f09cf34dSArchibald Elliott int fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr, 546f09cf34dSArchibald Elliott sizeof(attr)); 547f09cf34dSArchibald Elliott if (fd >= 0) { 548f09cf34dSArchibald Elliott close(fd); 549f09cf34dSArchibald Elliott return "v3"; 550f09cf34dSArchibald Elliott } 551f09cf34dSArchibald Elliott 552f09cf34dSArchibald Elliott /* Clear the whole attr in case its content changed by syscall. */ 553f09cf34dSArchibald Elliott memset(&attr, 0, sizeof(attr)); 554f09cf34dSArchibald Elliott attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */ 555f09cf34dSArchibald Elliott attr.insn_cnt = 5; 556f09cf34dSArchibald Elliott attr.insns = (uint64_t)v2_insns; 557f09cf34dSArchibald Elliott attr.license = (uint64_t)"DUMMY"; 558f09cf34dSArchibald Elliott fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr, sizeof(attr)); 559f09cf34dSArchibald Elliott if (fd >= 0) { 560f09cf34dSArchibald Elliott close(fd); 561f09cf34dSArchibald Elliott return "v2"; 562f09cf34dSArchibald Elliott } 563f09cf34dSArchibald Elliott return "v1"; 564f09cf34dSArchibald Elliott #endif 565f09cf34dSArchibald Elliott } 566f09cf34dSArchibald Elliott 567599f8e11SAiden Grossman #if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \ 568599f8e11SAiden Grossman defined(_M_X64) 569f09cf34dSArchibald Elliott 570f09cf34dSArchibald Elliott /// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in 571f09cf34dSArchibald Elliott /// the specified arguments. If we can't run cpuid on the host, return true. 572f09cf34dSArchibald Elliott static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX, 573f09cf34dSArchibald Elliott unsigned *rECX, unsigned *rEDX) { 574599f8e11SAiden Grossman #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER) 575599f8e11SAiden Grossman return !__get_cpuid(value, rEAX, rEBX, rECX, rEDX); 576f09cf34dSArchibald Elliott #elif defined(_MSC_VER) 577f09cf34dSArchibald Elliott // The MSVC intrinsic is portable across x86 and x64. 578f09cf34dSArchibald Elliott int registers[4]; 579f09cf34dSArchibald Elliott __cpuid(registers, value); 580f09cf34dSArchibald Elliott *rEAX = registers[0]; 581f09cf34dSArchibald Elliott *rEBX = registers[1]; 582f09cf34dSArchibald Elliott *rECX = registers[2]; 583f09cf34dSArchibald Elliott *rEDX = registers[3]; 584f09cf34dSArchibald Elliott return false; 585f09cf34dSArchibald Elliott #else 586f09cf34dSArchibald Elliott return true; 587f09cf34dSArchibald Elliott #endif 588f09cf34dSArchibald Elliott } 589f09cf34dSArchibald Elliott 590f09cf34dSArchibald Elliott namespace llvm { 591f09cf34dSArchibald Elliott namespace sys { 592f09cf34dSArchibald Elliott namespace detail { 593f09cf34dSArchibald Elliott namespace x86 { 594f09cf34dSArchibald Elliott 595f09cf34dSArchibald Elliott VendorSignatures getVendorSignature(unsigned *MaxLeaf) { 596f09cf34dSArchibald Elliott unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; 597f09cf34dSArchibald Elliott if (MaxLeaf == nullptr) 598f09cf34dSArchibald Elliott MaxLeaf = &EAX; 599f09cf34dSArchibald Elliott else 600f09cf34dSArchibald Elliott *MaxLeaf = 0; 601f09cf34dSArchibald Elliott 602f09cf34dSArchibald Elliott if (getX86CpuIDAndInfo(0, MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1) 603f09cf34dSArchibald Elliott return VendorSignatures::UNKNOWN; 604f09cf34dSArchibald Elliott 605f09cf34dSArchibald Elliott // "Genu ineI ntel" 606f09cf34dSArchibald Elliott if (EBX == 0x756e6547 && EDX == 0x49656e69 && ECX == 0x6c65746e) 607f09cf34dSArchibald Elliott return VendorSignatures::GENUINE_INTEL; 608f09cf34dSArchibald Elliott 609f09cf34dSArchibald Elliott // "Auth enti cAMD" 610f09cf34dSArchibald Elliott if (EBX == 0x68747541 && EDX == 0x69746e65 && ECX == 0x444d4163) 611f09cf34dSArchibald Elliott return VendorSignatures::AUTHENTIC_AMD; 612f09cf34dSArchibald Elliott 613f09cf34dSArchibald Elliott return VendorSignatures::UNKNOWN; 614f09cf34dSArchibald Elliott } 615f09cf34dSArchibald Elliott 616f09cf34dSArchibald Elliott } // namespace x86 617f09cf34dSArchibald Elliott } // namespace detail 618f09cf34dSArchibald Elliott } // namespace sys 619f09cf34dSArchibald Elliott } // namespace llvm 620f09cf34dSArchibald Elliott 621f09cf34dSArchibald Elliott using namespace llvm::sys::detail::x86; 622f09cf34dSArchibald Elliott 623f09cf34dSArchibald Elliott /// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return 624f09cf34dSArchibald Elliott /// the 4 values in the specified arguments. If we can't run cpuid on the host, 625f09cf34dSArchibald Elliott /// return true. 626f09cf34dSArchibald Elliott static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf, 627f09cf34dSArchibald Elliott unsigned *rEAX, unsigned *rEBX, unsigned *rECX, 628f09cf34dSArchibald Elliott unsigned *rEDX) { 629599f8e11SAiden Grossman // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang 630599f8e11SAiden Grossman // are such that __cpuidex is defined within cpuid.h for both, we can remove 631599f8e11SAiden Grossman // the __get_cpuid_count function and share the MSVC implementation between 632599f8e11SAiden Grossman // all three. 633599f8e11SAiden Grossman #if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER) 634599f8e11SAiden Grossman return !__get_cpuid_count(value, subleaf, rEAX, rEBX, rECX, rEDX); 635f09cf34dSArchibald Elliott #elif defined(_MSC_VER) 636f09cf34dSArchibald Elliott int registers[4]; 637f09cf34dSArchibald Elliott __cpuidex(registers, value, subleaf); 638f09cf34dSArchibald Elliott *rEAX = registers[0]; 639f09cf34dSArchibald Elliott *rEBX = registers[1]; 640f09cf34dSArchibald Elliott *rECX = registers[2]; 641f09cf34dSArchibald Elliott *rEDX = registers[3]; 642f09cf34dSArchibald Elliott return false; 643f09cf34dSArchibald Elliott #else 644f09cf34dSArchibald Elliott return true; 645f09cf34dSArchibald Elliott #endif 646f09cf34dSArchibald Elliott } 647f09cf34dSArchibald Elliott 648f09cf34dSArchibald Elliott // Read control register 0 (XCR0). Used to detect features such as AVX. 649f09cf34dSArchibald Elliott static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) { 650599f8e11SAiden Grossman // TODO(boomanaiden154): When the minimum toolchain versions for gcc and clang 651599f8e11SAiden Grossman // are such that _xgetbv is supported by both, we can unify the implementation 652599f8e11SAiden Grossman // with MSVC and remove all inline assembly. 653f09cf34dSArchibald Elliott #if defined(__GNUC__) || defined(__clang__) 654f09cf34dSArchibald Elliott // Check xgetbv; this uses a .byte sequence instead of the instruction 655f09cf34dSArchibald Elliott // directly because older assemblers do not include support for xgetbv and 656f09cf34dSArchibald Elliott // there is no easy way to conditionally compile based on the assembler used. 657f09cf34dSArchibald Elliott __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0)); 658f09cf34dSArchibald Elliott return false; 659f09cf34dSArchibald Elliott #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) 660f09cf34dSArchibald Elliott unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK); 661f09cf34dSArchibald Elliott *rEAX = Result; 662f09cf34dSArchibald Elliott *rEDX = Result >> 32; 663f09cf34dSArchibald Elliott return false; 664f09cf34dSArchibald Elliott #else 665f09cf34dSArchibald Elliott return true; 666f09cf34dSArchibald Elliott #endif 667f09cf34dSArchibald Elliott } 668f09cf34dSArchibald Elliott 669f09cf34dSArchibald Elliott static void detectX86FamilyModel(unsigned EAX, unsigned *Family, 670f09cf34dSArchibald Elliott unsigned *Model) { 671f09cf34dSArchibald Elliott *Family = (EAX >> 8) & 0xf; // Bits 8 - 11 672f09cf34dSArchibald Elliott *Model = (EAX >> 4) & 0xf; // Bits 4 - 7 673f09cf34dSArchibald Elliott if (*Family == 6 || *Family == 0xf) { 674f09cf34dSArchibald Elliott if (*Family == 0xf) 675f09cf34dSArchibald Elliott // Examine extended family ID if family ID is F. 676f09cf34dSArchibald Elliott *Family += (EAX >> 20) & 0xff; // Bits 20 - 27 677f09cf34dSArchibald Elliott // Examine extended model ID if family ID is 6 or F. 678f09cf34dSArchibald Elliott *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19 679f09cf34dSArchibald Elliott } 680f09cf34dSArchibald Elliott } 681f09cf34dSArchibald Elliott 68287e914dbSAiden Grossman #define testFeature(F) (Features[F / 32] & (1 << (F % 32))) != 0 683f09cf34dSArchibald Elliott 68487e914dbSAiden Grossman static StringRef getIntelProcessorTypeAndSubtype(unsigned Family, 68587e914dbSAiden Grossman unsigned Model, 68687e914dbSAiden Grossman const unsigned *Features, 68787e914dbSAiden Grossman unsigned *Type, 68887e914dbSAiden Grossman unsigned *Subtype) { 689f09cf34dSArchibald Elliott StringRef CPU; 690f09cf34dSArchibald Elliott 691f09cf34dSArchibald Elliott switch (Family) { 692f09cf34dSArchibald Elliott case 3: 693f09cf34dSArchibald Elliott CPU = "i386"; 694f09cf34dSArchibald Elliott break; 695f09cf34dSArchibald Elliott case 4: 696f09cf34dSArchibald Elliott CPU = "i486"; 697f09cf34dSArchibald Elliott break; 698f09cf34dSArchibald Elliott case 5: 699f09cf34dSArchibald Elliott if (testFeature(X86::FEATURE_MMX)) { 700f09cf34dSArchibald Elliott CPU = "pentium-mmx"; 701f09cf34dSArchibald Elliott break; 702f09cf34dSArchibald Elliott } 703f09cf34dSArchibald Elliott CPU = "pentium"; 704f09cf34dSArchibald Elliott break; 705f09cf34dSArchibald Elliott case 6: 706f09cf34dSArchibald Elliott switch (Model) { 707f09cf34dSArchibald Elliott case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile 708f09cf34dSArchibald Elliott // processor, Intel Core 2 Quad processor, Intel Core 2 Quad 709f09cf34dSArchibald Elliott // mobile processor, Intel Core 2 Extreme processor, Intel 710f09cf34dSArchibald Elliott // Pentium Dual-Core processor, Intel Xeon processor, model 711f09cf34dSArchibald Elliott // 0Fh. All processors are manufactured using the 65 nm process. 712f09cf34dSArchibald Elliott case 0x16: // Intel Celeron processor model 16h. All processors are 713f09cf34dSArchibald Elliott // manufactured using the 65 nm process 714f09cf34dSArchibald Elliott CPU = "core2"; 715f09cf34dSArchibald Elliott *Type = X86::INTEL_CORE2; 716f09cf34dSArchibald Elliott break; 717f09cf34dSArchibald Elliott case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model 718f09cf34dSArchibald Elliott // 17h. All processors are manufactured using the 45 nm process. 719f09cf34dSArchibald Elliott // 720f09cf34dSArchibald Elliott // 45nm: Penryn , Wolfdale, Yorkfield (XE) 721f09cf34dSArchibald Elliott case 0x1d: // Intel Xeon processor MP. All processors are manufactured using 722f09cf34dSArchibald Elliott // the 45 nm process. 723f09cf34dSArchibald Elliott CPU = "penryn"; 724f09cf34dSArchibald Elliott *Type = X86::INTEL_CORE2; 725f09cf34dSArchibald Elliott break; 726f09cf34dSArchibald Elliott case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All 727f09cf34dSArchibald Elliott // processors are manufactured using the 45 nm process. 728f09cf34dSArchibald Elliott case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz. 729f09cf34dSArchibald Elliott // As found in a Summer 2010 model iMac. 730f09cf34dSArchibald Elliott case 0x1f: 731f09cf34dSArchibald Elliott case 0x2e: // Nehalem EX 732f09cf34dSArchibald Elliott CPU = "nehalem"; 733f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 734f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_NEHALEM; 735f09cf34dSArchibald Elliott break; 736f09cf34dSArchibald Elliott case 0x25: // Intel Core i7, laptop version. 737f09cf34dSArchibald Elliott case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All 738f09cf34dSArchibald Elliott // processors are manufactured using the 32 nm process. 739f09cf34dSArchibald Elliott case 0x2f: // Westmere EX 740f09cf34dSArchibald Elliott CPU = "westmere"; 741f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 742f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_WESTMERE; 743f09cf34dSArchibald Elliott break; 744f09cf34dSArchibald Elliott case 0x2a: // Intel Core i7 processor. All processors are manufactured 745f09cf34dSArchibald Elliott // using the 32 nm process. 746f09cf34dSArchibald Elliott case 0x2d: 747f09cf34dSArchibald Elliott CPU = "sandybridge"; 748f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 749f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_SANDYBRIDGE; 750f09cf34dSArchibald Elliott break; 751f09cf34dSArchibald Elliott case 0x3a: 752f09cf34dSArchibald Elliott case 0x3e: // Ivy Bridge EP 753f09cf34dSArchibald Elliott CPU = "ivybridge"; 754f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 755f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_IVYBRIDGE; 756f09cf34dSArchibald Elliott break; 757f09cf34dSArchibald Elliott 758f09cf34dSArchibald Elliott // Haswell: 759f09cf34dSArchibald Elliott case 0x3c: 760f09cf34dSArchibald Elliott case 0x3f: 761f09cf34dSArchibald Elliott case 0x45: 762f09cf34dSArchibald Elliott case 0x46: 763f09cf34dSArchibald Elliott CPU = "haswell"; 764f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 765f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_HASWELL; 766f09cf34dSArchibald Elliott break; 767f09cf34dSArchibald Elliott 768f09cf34dSArchibald Elliott // Broadwell: 769f09cf34dSArchibald Elliott case 0x3d: 770f09cf34dSArchibald Elliott case 0x47: 771f09cf34dSArchibald Elliott case 0x4f: 772f09cf34dSArchibald Elliott case 0x56: 773f09cf34dSArchibald Elliott CPU = "broadwell"; 774f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 775f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_BROADWELL; 776f09cf34dSArchibald Elliott break; 777f09cf34dSArchibald Elliott 778f09cf34dSArchibald Elliott // Skylake: 779f09cf34dSArchibald Elliott case 0x4e: // Skylake mobile 780f09cf34dSArchibald Elliott case 0x5e: // Skylake desktop 781f09cf34dSArchibald Elliott case 0x8e: // Kaby Lake mobile 782f09cf34dSArchibald Elliott case 0x9e: // Kaby Lake desktop 783f09cf34dSArchibald Elliott case 0xa5: // Comet Lake-H/S 784f09cf34dSArchibald Elliott case 0xa6: // Comet Lake-U 785f09cf34dSArchibald Elliott CPU = "skylake"; 786f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 787f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_SKYLAKE; 788f09cf34dSArchibald Elliott break; 789f09cf34dSArchibald Elliott 790f09cf34dSArchibald Elliott // Rocketlake: 791f09cf34dSArchibald Elliott case 0xa7: 792f09cf34dSArchibald Elliott CPU = "rocketlake"; 793f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 794f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_ROCKETLAKE; 795f09cf34dSArchibald Elliott break; 796f09cf34dSArchibald Elliott 797f09cf34dSArchibald Elliott // Skylake Xeon: 798f09cf34dSArchibald Elliott case 0x55: 799f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 800f09cf34dSArchibald Elliott if (testFeature(X86::FEATURE_AVX512BF16)) { 801f09cf34dSArchibald Elliott CPU = "cooperlake"; 802f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_COOPERLAKE; 803f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_AVX512VNNI)) { 804f09cf34dSArchibald Elliott CPU = "cascadelake"; 805f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_CASCADELAKE; 806f09cf34dSArchibald Elliott } else { 807f09cf34dSArchibald Elliott CPU = "skylake-avx512"; 808f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512; 809f09cf34dSArchibald Elliott } 810f09cf34dSArchibald Elliott break; 811f09cf34dSArchibald Elliott 812f09cf34dSArchibald Elliott // Cannonlake: 813f09cf34dSArchibald Elliott case 0x66: 814f09cf34dSArchibald Elliott CPU = "cannonlake"; 815f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 816f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_CANNONLAKE; 817f09cf34dSArchibald Elliott break; 818f09cf34dSArchibald Elliott 819f09cf34dSArchibald Elliott // Icelake: 820f09cf34dSArchibald Elliott case 0x7d: 821f09cf34dSArchibald Elliott case 0x7e: 822f09cf34dSArchibald Elliott CPU = "icelake-client"; 823f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 824f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_ICELAKE_CLIENT; 825f09cf34dSArchibald Elliott break; 826f09cf34dSArchibald Elliott 827f09cf34dSArchibald Elliott // Tigerlake: 828f09cf34dSArchibald Elliott case 0x8c: 829f09cf34dSArchibald Elliott case 0x8d: 830f09cf34dSArchibald Elliott CPU = "tigerlake"; 831f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 832f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_TIGERLAKE; 833f09cf34dSArchibald Elliott break; 834f09cf34dSArchibald Elliott 835f09cf34dSArchibald Elliott // Alderlake: 836f09cf34dSArchibald Elliott case 0x97: 837f09cf34dSArchibald Elliott case 0x9a: 8383348b468SPhoebe Wang CPU = "alderlake"; 8393348b468SPhoebe Wang *Type = X86::INTEL_COREI7; 8403348b468SPhoebe Wang *Subtype = X86::INTEL_COREI7_ALDERLAKE; 8413348b468SPhoebe Wang break; 8423348b468SPhoebe Wang 8436acff539SFreddy Ye // Gracemont 8446acff539SFreddy Ye case 0xbe: 845a6393129SPhoebe Wang CPU = "gracemont"; 8463348b468SPhoebe Wang *Type = X86::INTEL_COREI7; 8473348b468SPhoebe Wang *Subtype = X86::INTEL_COREI7_ALDERLAKE; 8483348b468SPhoebe Wang break; 8493348b468SPhoebe Wang 850f09cf34dSArchibald Elliott // Raptorlake: 851f09cf34dSArchibald Elliott case 0xb7: 852cafbcfa0SFreddy Ye case 0xba: 853cafbcfa0SFreddy Ye case 0xbf: 8543348b468SPhoebe Wang CPU = "raptorlake"; 8553348b468SPhoebe Wang *Type = X86::INTEL_COREI7; 8563348b468SPhoebe Wang *Subtype = X86::INTEL_COREI7_ALDERLAKE; 8573348b468SPhoebe Wang break; 8583348b468SPhoebe Wang 859f09cf34dSArchibald Elliott // Meteorlake: 860f09cf34dSArchibald Elliott case 0xaa: 861f09cf34dSArchibald Elliott case 0xac: 8623348b468SPhoebe Wang CPU = "meteorlake"; 863f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 864f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_ALDERLAKE; 865f09cf34dSArchibald Elliott break; 866f09cf34dSArchibald Elliott 867c9d92e66SFreddy Ye // Arrowlake: 868c9d92e66SFreddy Ye case 0xc5: 8699e3d4653SFreddy Ye // Arrowlake U: 8709e3d4653SFreddy Ye case 0xb5: 871c9d92e66SFreddy Ye CPU = "arrowlake"; 872c9d92e66SFreddy Ye *Type = X86::INTEL_COREI7; 873c9d92e66SFreddy Ye *Subtype = X86::INTEL_COREI7_ARROWLAKE; 874c9d92e66SFreddy Ye break; 875c9d92e66SFreddy Ye 876c9d92e66SFreddy Ye // Arrowlake S: 877c9d92e66SFreddy Ye case 0xc6: 8783348b468SPhoebe Wang CPU = "arrowlake-s"; 8793348b468SPhoebe Wang *Type = X86::INTEL_COREI7; 8803348b468SPhoebe Wang *Subtype = X86::INTEL_COREI7_ARROWLAKE_S; 8813348b468SPhoebe Wang break; 8823348b468SPhoebe Wang 883c9d92e66SFreddy Ye // Lunarlake: 884c9d92e66SFreddy Ye case 0xbd: 8853348b468SPhoebe Wang CPU = "lunarlake"; 886c9d92e66SFreddy Ye *Type = X86::INTEL_COREI7; 887c9d92e66SFreddy Ye *Subtype = X86::INTEL_COREI7_ARROWLAKE_S; 888c9d92e66SFreddy Ye break; 889c9d92e66SFreddy Ye 890278e533eSFreddy Ye // Pantherlake: 891278e533eSFreddy Ye case 0xcc: 892278e533eSFreddy Ye CPU = "pantherlake"; 893278e533eSFreddy Ye *Type = X86::INTEL_COREI7; 894278e533eSFreddy Ye *Subtype = X86::INTEL_COREI7_PANTHERLAKE; 895278e533eSFreddy Ye break; 896278e533eSFreddy Ye 897f09cf34dSArchibald Elliott // Graniterapids: 898f09cf34dSArchibald Elliott case 0xad: 899f09cf34dSArchibald Elliott CPU = "graniterapids"; 900f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 901f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_GRANITERAPIDS; 902f09cf34dSArchibald Elliott break; 903f09cf34dSArchibald Elliott 9046d23a3faSFreddy Ye // Granite Rapids D: 9056d23a3faSFreddy Ye case 0xae: 9066d23a3faSFreddy Ye CPU = "graniterapids-d"; 9076d23a3faSFreddy Ye *Type = X86::INTEL_COREI7; 9086d23a3faSFreddy Ye *Subtype = X86::INTEL_COREI7_GRANITERAPIDS_D; 9096d23a3faSFreddy Ye break; 9106d23a3faSFreddy Ye 911f09cf34dSArchibald Elliott // Icelake Xeon: 912f09cf34dSArchibald Elliott case 0x6a: 913f09cf34dSArchibald Elliott case 0x6c: 914f09cf34dSArchibald Elliott CPU = "icelake-server"; 915f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 916f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_ICELAKE_SERVER; 917f09cf34dSArchibald Elliott break; 918f09cf34dSArchibald Elliott 91927b8f54fSFreddy Ye // Emerald Rapids: 92027b8f54fSFreddy Ye case 0xcf: 9213348b468SPhoebe Wang CPU = "emeraldrapids"; 9223348b468SPhoebe Wang *Type = X86::INTEL_COREI7; 9233348b468SPhoebe Wang *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS; 9243348b468SPhoebe Wang break; 9253348b468SPhoebe Wang 926f09cf34dSArchibald Elliott // Sapphire Rapids: 927f09cf34dSArchibald Elliott case 0x8f: 928f09cf34dSArchibald Elliott CPU = "sapphirerapids"; 929f09cf34dSArchibald Elliott *Type = X86::INTEL_COREI7; 930f09cf34dSArchibald Elliott *Subtype = X86::INTEL_COREI7_SAPPHIRERAPIDS; 931f09cf34dSArchibald Elliott break; 932f09cf34dSArchibald Elliott 933f09cf34dSArchibald Elliott case 0x1c: // Most 45 nm Intel Atom processors 934f09cf34dSArchibald Elliott case 0x26: // 45 nm Atom Lincroft 935f09cf34dSArchibald Elliott case 0x27: // 32 nm Atom Medfield 936f09cf34dSArchibald Elliott case 0x35: // 32 nm Atom Midview 937f09cf34dSArchibald Elliott case 0x36: // 32 nm Atom Midview 938f09cf34dSArchibald Elliott CPU = "bonnell"; 939f09cf34dSArchibald Elliott *Type = X86::INTEL_BONNELL; 940f09cf34dSArchibald Elliott break; 941f09cf34dSArchibald Elliott 942f09cf34dSArchibald Elliott // Atom Silvermont codes from the Intel software optimization guide. 943f09cf34dSArchibald Elliott case 0x37: 944f09cf34dSArchibald Elliott case 0x4a: 945f09cf34dSArchibald Elliott case 0x4d: 946f09cf34dSArchibald Elliott case 0x5a: 947f09cf34dSArchibald Elliott case 0x5d: 948f09cf34dSArchibald Elliott case 0x4c: // really airmont 949f09cf34dSArchibald Elliott CPU = "silvermont"; 950f09cf34dSArchibald Elliott *Type = X86::INTEL_SILVERMONT; 951f09cf34dSArchibald Elliott break; 952f09cf34dSArchibald Elliott // Goldmont: 953f09cf34dSArchibald Elliott case 0x5c: // Apollo Lake 954f09cf34dSArchibald Elliott case 0x5f: // Denverton 955f09cf34dSArchibald Elliott CPU = "goldmont"; 956f09cf34dSArchibald Elliott *Type = X86::INTEL_GOLDMONT; 957f09cf34dSArchibald Elliott break; 958f09cf34dSArchibald Elliott case 0x7a: 959f09cf34dSArchibald Elliott CPU = "goldmont-plus"; 960f09cf34dSArchibald Elliott *Type = X86::INTEL_GOLDMONT_PLUS; 961f09cf34dSArchibald Elliott break; 962f09cf34dSArchibald Elliott case 0x86: 963e972bdbaSlibenc case 0x8a: // Lakefield 964e972bdbaSlibenc case 0x96: // Elkhart Lake 965e972bdbaSlibenc case 0x9c: // Jasper Lake 966f09cf34dSArchibald Elliott CPU = "tremont"; 967f09cf34dSArchibald Elliott *Type = X86::INTEL_TREMONT; 968f09cf34dSArchibald Elliott break; 969f09cf34dSArchibald Elliott 970f09cf34dSArchibald Elliott // Sierraforest: 971f09cf34dSArchibald Elliott case 0xaf: 972f09cf34dSArchibald Elliott CPU = "sierraforest"; 973f09cf34dSArchibald Elliott *Type = X86::INTEL_SIERRAFOREST; 974f09cf34dSArchibald Elliott break; 975f09cf34dSArchibald Elliott 976f09cf34dSArchibald Elliott // Grandridge: 977f09cf34dSArchibald Elliott case 0xb6: 978f09cf34dSArchibald Elliott CPU = "grandridge"; 979f09cf34dSArchibald Elliott *Type = X86::INTEL_GRANDRIDGE; 980f09cf34dSArchibald Elliott break; 981f09cf34dSArchibald Elliott 982278e533eSFreddy Ye // Clearwaterforest: 983278e533eSFreddy Ye case 0xdd: 984278e533eSFreddy Ye CPU = "clearwaterforest"; 985278e533eSFreddy Ye *Type = X86::INTEL_CLEARWATERFOREST; 986278e533eSFreddy Ye break; 987278e533eSFreddy Ye 988f09cf34dSArchibald Elliott // Xeon Phi (Knights Landing + Knights Mill): 989f09cf34dSArchibald Elliott case 0x57: 990f09cf34dSArchibald Elliott CPU = "knl"; 991f09cf34dSArchibald Elliott *Type = X86::INTEL_KNL; 992f09cf34dSArchibald Elliott break; 993f09cf34dSArchibald Elliott case 0x85: 994f09cf34dSArchibald Elliott CPU = "knm"; 995f09cf34dSArchibald Elliott *Type = X86::INTEL_KNM; 996f09cf34dSArchibald Elliott break; 997f09cf34dSArchibald Elliott 998f09cf34dSArchibald Elliott default: // Unknown family 6 CPU, try to guess. 999f09cf34dSArchibald Elliott // Don't both with Type/Subtype here, they aren't used by the caller. 1000f09cf34dSArchibald Elliott // They're used above to keep the code in sync with compiler-rt. 1001f09cf34dSArchibald Elliott // TODO detect tigerlake host from model 1002f09cf34dSArchibald Elliott if (testFeature(X86::FEATURE_AVX512VP2INTERSECT)) { 1003f09cf34dSArchibald Elliott CPU = "tigerlake"; 1004f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_AVX512VBMI2)) { 1005f09cf34dSArchibald Elliott CPU = "icelake-client"; 1006f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_AVX512VBMI)) { 1007f09cf34dSArchibald Elliott CPU = "cannonlake"; 1008f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_AVX512BF16)) { 1009f09cf34dSArchibald Elliott CPU = "cooperlake"; 1010f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_AVX512VNNI)) { 1011f09cf34dSArchibald Elliott CPU = "cascadelake"; 1012f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_AVX512VL)) { 1013f09cf34dSArchibald Elliott CPU = "skylake-avx512"; 1014f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_CLFLUSHOPT)) { 1015f09cf34dSArchibald Elliott if (testFeature(X86::FEATURE_SHA)) 1016f09cf34dSArchibald Elliott CPU = "goldmont"; 1017f09cf34dSArchibald Elliott else 1018f09cf34dSArchibald Elliott CPU = "skylake"; 1019f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_ADX)) { 1020f09cf34dSArchibald Elliott CPU = "broadwell"; 1021f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_AVX2)) { 1022f09cf34dSArchibald Elliott CPU = "haswell"; 1023f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_AVX)) { 1024f09cf34dSArchibald Elliott CPU = "sandybridge"; 1025f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_SSE4_2)) { 1026f09cf34dSArchibald Elliott if (testFeature(X86::FEATURE_MOVBE)) 1027f09cf34dSArchibald Elliott CPU = "silvermont"; 1028f09cf34dSArchibald Elliott else 1029f09cf34dSArchibald Elliott CPU = "nehalem"; 1030f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_SSE4_1)) { 1031f09cf34dSArchibald Elliott CPU = "penryn"; 1032f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_SSSE3)) { 1033f09cf34dSArchibald Elliott if (testFeature(X86::FEATURE_MOVBE)) 1034f09cf34dSArchibald Elliott CPU = "bonnell"; 1035f09cf34dSArchibald Elliott else 1036f09cf34dSArchibald Elliott CPU = "core2"; 1037f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_64BIT)) { 1038f09cf34dSArchibald Elliott CPU = "core2"; 1039f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_SSE3)) { 1040f09cf34dSArchibald Elliott CPU = "yonah"; 1041f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_SSE2)) { 1042f09cf34dSArchibald Elliott CPU = "pentium-m"; 1043f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_SSE)) { 1044f09cf34dSArchibald Elliott CPU = "pentium3"; 1045f09cf34dSArchibald Elliott } else if (testFeature(X86::FEATURE_MMX)) { 1046f09cf34dSArchibald Elliott CPU = "pentium2"; 1047f09cf34dSArchibald Elliott } else { 1048f09cf34dSArchibald Elliott CPU = "pentiumpro"; 1049f09cf34dSArchibald Elliott } 1050f09cf34dSArchibald Elliott break; 1051f09cf34dSArchibald Elliott } 1052f09cf34dSArchibald Elliott break; 1053f09cf34dSArchibald Elliott case 15: { 1054f09cf34dSArchibald Elliott if (testFeature(X86::FEATURE_64BIT)) { 1055f09cf34dSArchibald Elliott CPU = "nocona"; 1056f09cf34dSArchibald Elliott break; 1057f09cf34dSArchibald Elliott } 1058f09cf34dSArchibald Elliott if (testFeature(X86::FEATURE_SSE3)) { 1059f09cf34dSArchibald Elliott CPU = "prescott"; 1060f09cf34dSArchibald Elliott break; 1061f09cf34dSArchibald Elliott } 1062f09cf34dSArchibald Elliott CPU = "pentium4"; 1063f09cf34dSArchibald Elliott break; 1064f09cf34dSArchibald Elliott } 106597836bedSFreddy Ye case 19: 106697836bedSFreddy Ye switch (Model) { 106797836bedSFreddy Ye // Diamond Rapids: 106897836bedSFreddy Ye case 0x01: 106997836bedSFreddy Ye CPU = "diamondrapids"; 107097836bedSFreddy Ye *Type = X86::INTEL_COREI7; 107197836bedSFreddy Ye *Subtype = X86::INTEL_COREI7_DIAMONDRAPIDS; 107297836bedSFreddy Ye break; 107397836bedSFreddy Ye 107497836bedSFreddy Ye default: // Unknown family 19 CPU. 107597836bedSFreddy Ye break; 107697836bedSFreddy Ye } 107797836bedSFreddy Ye break; 1078f09cf34dSArchibald Elliott default: 1079f09cf34dSArchibald Elliott break; // Unknown. 1080f09cf34dSArchibald Elliott } 1081f09cf34dSArchibald Elliott 1082f09cf34dSArchibald Elliott return CPU; 1083f09cf34dSArchibald Elliott } 1084f09cf34dSArchibald Elliott 108587e914dbSAiden Grossman static const char *getAMDProcessorTypeAndSubtype(unsigned Family, 108687e914dbSAiden Grossman unsigned Model, 1087f09cf34dSArchibald Elliott const unsigned *Features, 108887e914dbSAiden Grossman unsigned *Type, 108987e914dbSAiden Grossman unsigned *Subtype) { 109087e914dbSAiden Grossman const char *CPU = 0; 1091f09cf34dSArchibald Elliott 1092f09cf34dSArchibald Elliott switch (Family) { 1093f09cf34dSArchibald Elliott case 4: 1094f09cf34dSArchibald Elliott CPU = "i486"; 1095f09cf34dSArchibald Elliott break; 1096f09cf34dSArchibald Elliott case 5: 1097f09cf34dSArchibald Elliott CPU = "pentium"; 1098f09cf34dSArchibald Elliott switch (Model) { 1099f09cf34dSArchibald Elliott case 6: 1100f09cf34dSArchibald Elliott case 7: 1101f09cf34dSArchibald Elliott CPU = "k6"; 1102f09cf34dSArchibald Elliott break; 1103f09cf34dSArchibald Elliott case 8: 1104f09cf34dSArchibald Elliott CPU = "k6-2"; 1105f09cf34dSArchibald Elliott break; 1106f09cf34dSArchibald Elliott case 9: 1107f09cf34dSArchibald Elliott case 13: 1108f09cf34dSArchibald Elliott CPU = "k6-3"; 1109f09cf34dSArchibald Elliott break; 1110f09cf34dSArchibald Elliott case 10: 1111f09cf34dSArchibald Elliott CPU = "geode"; 1112f09cf34dSArchibald Elliott break; 1113f09cf34dSArchibald Elliott } 1114f09cf34dSArchibald Elliott break; 1115f09cf34dSArchibald Elliott case 6: 1116f09cf34dSArchibald Elliott if (testFeature(X86::FEATURE_SSE)) { 1117f09cf34dSArchibald Elliott CPU = "athlon-xp"; 1118f09cf34dSArchibald Elliott break; 1119f09cf34dSArchibald Elliott } 1120f09cf34dSArchibald Elliott CPU = "athlon"; 1121f09cf34dSArchibald Elliott break; 1122f09cf34dSArchibald Elliott case 15: 1123f09cf34dSArchibald Elliott if (testFeature(X86::FEATURE_SSE3)) { 1124f09cf34dSArchibald Elliott CPU = "k8-sse3"; 1125f09cf34dSArchibald Elliott break; 1126f09cf34dSArchibald Elliott } 1127f09cf34dSArchibald Elliott CPU = "k8"; 1128f09cf34dSArchibald Elliott break; 1129f09cf34dSArchibald Elliott case 16: 1130c5f7a323SRipleyTom case 18: 1131f09cf34dSArchibald Elliott CPU = "amdfam10"; 1132f09cf34dSArchibald Elliott *Type = X86::AMDFAM10H; // "amdfam10" 1133f09cf34dSArchibald Elliott switch (Model) { 1134f09cf34dSArchibald Elliott case 2: 1135f09cf34dSArchibald Elliott *Subtype = X86::AMDFAM10H_BARCELONA; 1136f09cf34dSArchibald Elliott break; 1137f09cf34dSArchibald Elliott case 4: 1138f09cf34dSArchibald Elliott *Subtype = X86::AMDFAM10H_SHANGHAI; 1139f09cf34dSArchibald Elliott break; 1140f09cf34dSArchibald Elliott case 8: 1141f09cf34dSArchibald Elliott *Subtype = X86::AMDFAM10H_ISTANBUL; 1142f09cf34dSArchibald Elliott break; 1143f09cf34dSArchibald Elliott } 1144f09cf34dSArchibald Elliott break; 1145f09cf34dSArchibald Elliott case 20: 1146f09cf34dSArchibald Elliott CPU = "btver1"; 1147f09cf34dSArchibald Elliott *Type = X86::AMD_BTVER1; 1148f09cf34dSArchibald Elliott break; 1149f09cf34dSArchibald Elliott case 21: 1150f09cf34dSArchibald Elliott CPU = "bdver1"; 1151f09cf34dSArchibald Elliott *Type = X86::AMDFAM15H; 1152f09cf34dSArchibald Elliott if (Model >= 0x60 && Model <= 0x7f) { 1153f09cf34dSArchibald Elliott CPU = "bdver4"; 1154f09cf34dSArchibald Elliott *Subtype = X86::AMDFAM15H_BDVER4; 1155f09cf34dSArchibald Elliott break; // 60h-7Fh: Excavator 1156f09cf34dSArchibald Elliott } 1157f09cf34dSArchibald Elliott if (Model >= 0x30 && Model <= 0x3f) { 1158f09cf34dSArchibald Elliott CPU = "bdver3"; 1159f09cf34dSArchibald Elliott *Subtype = X86::AMDFAM15H_BDVER3; 1160f09cf34dSArchibald Elliott break; // 30h-3Fh: Steamroller 1161f09cf34dSArchibald Elliott } 1162f09cf34dSArchibald Elliott if ((Model >= 0x10 && Model <= 0x1f) || Model == 0x02) { 1163f09cf34dSArchibald Elliott CPU = "bdver2"; 1164f09cf34dSArchibald Elliott *Subtype = X86::AMDFAM15H_BDVER2; 1165f09cf34dSArchibald Elliott break; // 02h, 10h-1Fh: Piledriver 1166f09cf34dSArchibald Elliott } 1167f09cf34dSArchibald Elliott if (Model <= 0x0f) { 1168f09cf34dSArchibald Elliott *Subtype = X86::AMDFAM15H_BDVER1; 1169f09cf34dSArchibald Elliott break; // 00h-0Fh: Bulldozer 1170f09cf34dSArchibald Elliott } 1171f09cf34dSArchibald Elliott break; 1172f09cf34dSArchibald Elliott case 22: 1173f09cf34dSArchibald Elliott CPU = "btver2"; 1174f09cf34dSArchibald Elliott *Type = X86::AMD_BTVER2; 1175f09cf34dSArchibald Elliott break; 1176f09cf34dSArchibald Elliott case 23: 1177f09cf34dSArchibald Elliott CPU = "znver1"; 1178f09cf34dSArchibald Elliott *Type = X86::AMDFAM17H; 1179a15532d7SAiden Grossman if ((Model >= 0x30 && Model <= 0x3f) || (Model == 0x47) || 1180a15532d7SAiden Grossman (Model >= 0x60 && Model <= 0x67) || (Model >= 0x68 && Model <= 0x6f) || 1181a15532d7SAiden Grossman (Model >= 0x70 && Model <= 0x7f) || (Model >= 0x84 && Model <= 0x87) || 1182a15532d7SAiden Grossman (Model >= 0x90 && Model <= 0x97) || (Model >= 0x98 && Model <= 0x9f) || 1183a15532d7SAiden Grossman (Model >= 0xa0 && Model <= 0xaf)) { 1184a15532d7SAiden Grossman // Family 17h Models 30h-3Fh (Starship) Zen 2 1185a15532d7SAiden Grossman // Family 17h Models 47h (Cardinal) Zen 2 1186a15532d7SAiden Grossman // Family 17h Models 60h-67h (Renoir) Zen 2 1187a15532d7SAiden Grossman // Family 17h Models 68h-6Fh (Lucienne) Zen 2 1188a15532d7SAiden Grossman // Family 17h Models 70h-7Fh (Matisse) Zen 2 1189a15532d7SAiden Grossman // Family 17h Models 84h-87h (ProjectX) Zen 2 1190a15532d7SAiden Grossman // Family 17h Models 90h-97h (VanGogh) Zen 2 1191a15532d7SAiden Grossman // Family 17h Models 98h-9Fh (Mero) Zen 2 1192a15532d7SAiden Grossman // Family 17h Models A0h-AFh (Mendocino) Zen 2 1193f09cf34dSArchibald Elliott CPU = "znver2"; 1194f09cf34dSArchibald Elliott *Subtype = X86::AMDFAM17H_ZNVER2; 1195a15532d7SAiden Grossman break; 1196f09cf34dSArchibald Elliott } 1197a15532d7SAiden Grossman if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x20 && Model <= 0x2f)) { 1198a15532d7SAiden Grossman // Family 17h Models 10h-1Fh (Raven1) Zen 1199a15532d7SAiden Grossman // Family 17h Models 10h-1Fh (Picasso) Zen+ 1200a15532d7SAiden Grossman // Family 17h Models 20h-2Fh (Raven2 x86) Zen 1201f09cf34dSArchibald Elliott *Subtype = X86::AMDFAM17H_ZNVER1; 1202a15532d7SAiden Grossman break; 1203f09cf34dSArchibald Elliott } 1204f09cf34dSArchibald Elliott break; 1205f09cf34dSArchibald Elliott case 25: 1206f09cf34dSArchibald Elliott CPU = "znver3"; 1207f09cf34dSArchibald Elliott *Type = X86::AMDFAM19H; 12083ddf3685SAiden Grossman if (Model <= 0x0f || (Model >= 0x20 && Model <= 0x2f) || 1209a15532d7SAiden Grossman (Model >= 0x30 && Model <= 0x3f) || (Model >= 0x40 && Model <= 0x4f) || 1210a15532d7SAiden Grossman (Model >= 0x50 && Model <= 0x5f)) { 1211a15532d7SAiden Grossman // Family 19h Models 00h-0Fh (Genesis, Chagall) Zen 3 1212a15532d7SAiden Grossman // Family 19h Models 20h-2Fh (Vermeer) Zen 3 1213a15532d7SAiden Grossman // Family 19h Models 30h-3Fh (Badami) Zen 3 1214a15532d7SAiden Grossman // Family 19h Models 40h-4Fh (Rembrandt) Zen 3+ 1215a15532d7SAiden Grossman // Family 19h Models 50h-5Fh (Cezanne) Zen 3 1216f09cf34dSArchibald Elliott *Subtype = X86::AMDFAM19H_ZNVER3; 1217f09cf34dSArchibald Elliott break; 1218f09cf34dSArchibald Elliott } 1219a15532d7SAiden Grossman if ((Model >= 0x10 && Model <= 0x1f) || (Model >= 0x60 && Model <= 0x6f) || 1220a15532d7SAiden Grossman (Model >= 0x70 && Model <= 0x77) || (Model >= 0x78 && Model <= 0x7f) || 1221a15532d7SAiden Grossman (Model >= 0xa0 && Model <= 0xaf)) { 1222a15532d7SAiden Grossman // Family 19h Models 10h-1Fh (Stones; Storm Peak) Zen 4 1223a15532d7SAiden Grossman // Family 19h Models 60h-6Fh (Raphael) Zen 4 1224a15532d7SAiden Grossman // Family 19h Models 70h-77h (Phoenix, Hawkpoint1) Zen 4 1225a15532d7SAiden Grossman // Family 19h Models 78h-7Fh (Phoenix 2, Hawkpoint2) Zen 4 1226a15532d7SAiden Grossman // Family 19h Models A0h-AFh (Stones-Dense) Zen 4 1227f09cf34dSArchibald Elliott CPU = "znver4"; 1228f09cf34dSArchibald Elliott *Subtype = X86::AMDFAM19H_ZNVER4; 1229f09cf34dSArchibald Elliott break; // "znver4" 1230f09cf34dSArchibald Elliott } 123187e914dbSAiden Grossman break; // family 19h 123202e4186dSGanesh case 26: 123302e4186dSGanesh CPU = "znver5"; 123402e4186dSGanesh *Type = X86::AMDFAM1AH; 123502e4186dSGanesh if (Model <= 0x77) { 123602e4186dSGanesh // Models 00h-0Fh (Breithorn). 123702e4186dSGanesh // Models 10h-1Fh (Breithorn-Dense). 123802e4186dSGanesh // Models 20h-2Fh (Strix 1). 123902e4186dSGanesh // Models 30h-37h (Strix 2). 124002e4186dSGanesh // Models 38h-3Fh (Strix 3). 124102e4186dSGanesh // Models 40h-4Fh (Granite Ridge). 124202e4186dSGanesh // Models 50h-5Fh (Weisshorn). 124302e4186dSGanesh // Models 60h-6Fh (Krackan1). 124402e4186dSGanesh // Models 70h-77h (Sarlak). 124502e4186dSGanesh CPU = "znver5"; 124602e4186dSGanesh *Subtype = X86::AMDFAM1AH_ZNVER5; 124702e4186dSGanesh break; // "znver5" 124802e4186dSGanesh } 124902e4186dSGanesh break; 125002e4186dSGanesh 1251f09cf34dSArchibald Elliott default: 1252f09cf34dSArchibald Elliott break; // Unknown AMD CPU. 1253f09cf34dSArchibald Elliott } 1254f09cf34dSArchibald Elliott 1255f09cf34dSArchibald Elliott return CPU; 1256f09cf34dSArchibald Elliott } 1257f09cf34dSArchibald Elliott 12583f9bff3dSHaojian Wu #undef testFeature 125987e914dbSAiden Grossman 1260f09cf34dSArchibald Elliott static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, 1261f09cf34dSArchibald Elliott unsigned *Features) { 1262f09cf34dSArchibald Elliott unsigned EAX, EBX; 1263f09cf34dSArchibald Elliott 1264f09cf34dSArchibald Elliott auto setFeature = [&](unsigned F) { 1265f09cf34dSArchibald Elliott Features[F / 32] |= 1U << (F % 32); 1266f09cf34dSArchibald Elliott }; 1267f09cf34dSArchibald Elliott 1268f09cf34dSArchibald Elliott if ((EDX >> 15) & 1) 1269f09cf34dSArchibald Elliott setFeature(X86::FEATURE_CMOV); 1270f09cf34dSArchibald Elliott if ((EDX >> 23) & 1) 1271f09cf34dSArchibald Elliott setFeature(X86::FEATURE_MMX); 1272f09cf34dSArchibald Elliott if ((EDX >> 25) & 1) 1273f09cf34dSArchibald Elliott setFeature(X86::FEATURE_SSE); 1274f09cf34dSArchibald Elliott if ((EDX >> 26) & 1) 1275f09cf34dSArchibald Elliott setFeature(X86::FEATURE_SSE2); 1276f09cf34dSArchibald Elliott 1277f09cf34dSArchibald Elliott if ((ECX >> 0) & 1) 1278f09cf34dSArchibald Elliott setFeature(X86::FEATURE_SSE3); 1279f09cf34dSArchibald Elliott if ((ECX >> 1) & 1) 1280f09cf34dSArchibald Elliott setFeature(X86::FEATURE_PCLMUL); 1281f09cf34dSArchibald Elliott if ((ECX >> 9) & 1) 1282f09cf34dSArchibald Elliott setFeature(X86::FEATURE_SSSE3); 1283f09cf34dSArchibald Elliott if ((ECX >> 12) & 1) 1284f09cf34dSArchibald Elliott setFeature(X86::FEATURE_FMA); 1285f09cf34dSArchibald Elliott if ((ECX >> 19) & 1) 1286f09cf34dSArchibald Elliott setFeature(X86::FEATURE_SSE4_1); 1287f09cf34dSArchibald Elliott if ((ECX >> 20) & 1) { 1288f09cf34dSArchibald Elliott setFeature(X86::FEATURE_SSE4_2); 1289f09cf34dSArchibald Elliott setFeature(X86::FEATURE_CRC32); 1290f09cf34dSArchibald Elliott } 1291f09cf34dSArchibald Elliott if ((ECX >> 23) & 1) 1292f09cf34dSArchibald Elliott setFeature(X86::FEATURE_POPCNT); 1293f09cf34dSArchibald Elliott if ((ECX >> 25) & 1) 1294f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AES); 1295f09cf34dSArchibald Elliott 1296f09cf34dSArchibald Elliott if ((ECX >> 22) & 1) 1297f09cf34dSArchibald Elliott setFeature(X86::FEATURE_MOVBE); 1298f09cf34dSArchibald Elliott 1299f09cf34dSArchibald Elliott // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV 1300f09cf34dSArchibald Elliott // indicates that the AVX registers will be saved and restored on context 1301f09cf34dSArchibald Elliott // switch, then we have full AVX support. 1302f09cf34dSArchibald Elliott const unsigned AVXBits = (1 << 27) | (1 << 28); 1303f09cf34dSArchibald Elliott bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) && 1304f09cf34dSArchibald Elliott ((EAX & 0x6) == 0x6); 1305f09cf34dSArchibald Elliott #if defined(__APPLE__) 1306f09cf34dSArchibald Elliott // Darwin lazily saves the AVX512 context on first use: trust that the OS will 1307f09cf34dSArchibald Elliott // save the AVX512 context if we use AVX512 instructions, even the bit is not 1308f09cf34dSArchibald Elliott // set right now. 1309f09cf34dSArchibald Elliott bool HasAVX512Save = true; 1310f09cf34dSArchibald Elliott #else 1311f09cf34dSArchibald Elliott // AVX512 requires additional context to be saved by the OS. 1312f09cf34dSArchibald Elliott bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0); 1313f09cf34dSArchibald Elliott #endif 1314f09cf34dSArchibald Elliott 1315f09cf34dSArchibald Elliott if (HasAVX) 1316f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX); 1317f09cf34dSArchibald Elliott 1318f09cf34dSArchibald Elliott bool HasLeaf7 = 1319f09cf34dSArchibald Elliott MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX); 1320f09cf34dSArchibald Elliott 1321f09cf34dSArchibald Elliott if (HasLeaf7 && ((EBX >> 3) & 1)) 1322f09cf34dSArchibald Elliott setFeature(X86::FEATURE_BMI); 1323f09cf34dSArchibald Elliott if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX) 1324f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX2); 1325f09cf34dSArchibald Elliott if (HasLeaf7 && ((EBX >> 8) & 1)) 1326f09cf34dSArchibald Elliott setFeature(X86::FEATURE_BMI2); 1327b3291793SPhoebe Wang if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) { 1328f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512F); 1329b3291793SPhoebe Wang setFeature(X86::FEATURE_EVEX512); 1330b3291793SPhoebe Wang } 1331f09cf34dSArchibald Elliott if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save) 1332f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512DQ); 1333f09cf34dSArchibald Elliott if (HasLeaf7 && ((EBX >> 19) & 1)) 1334f09cf34dSArchibald Elliott setFeature(X86::FEATURE_ADX); 1335f09cf34dSArchibald Elliott if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save) 1336f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512IFMA); 1337f09cf34dSArchibald Elliott if (HasLeaf7 && ((EBX >> 23) & 1)) 1338f09cf34dSArchibald Elliott setFeature(X86::FEATURE_CLFLUSHOPT); 1339f09cf34dSArchibald Elliott if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save) 1340f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512CD); 1341f09cf34dSArchibald Elliott if (HasLeaf7 && ((EBX >> 29) & 1)) 1342f09cf34dSArchibald Elliott setFeature(X86::FEATURE_SHA); 1343f09cf34dSArchibald Elliott if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save) 1344f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512BW); 1345f09cf34dSArchibald Elliott if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save) 1346f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512VL); 1347f09cf34dSArchibald Elliott 1348f09cf34dSArchibald Elliott if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save) 1349f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512VBMI); 1350f09cf34dSArchibald Elliott if (HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save) 1351f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512VBMI2); 1352f09cf34dSArchibald Elliott if (HasLeaf7 && ((ECX >> 8) & 1)) 1353f09cf34dSArchibald Elliott setFeature(X86::FEATURE_GFNI); 1354f09cf34dSArchibald Elliott if (HasLeaf7 && ((ECX >> 10) & 1) && HasAVX) 1355f09cf34dSArchibald Elliott setFeature(X86::FEATURE_VPCLMULQDQ); 1356f09cf34dSArchibald Elliott if (HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save) 1357f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512VNNI); 1358f09cf34dSArchibald Elliott if (HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save) 1359f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512BITALG); 1360f09cf34dSArchibald Elliott if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save) 1361f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512VPOPCNTDQ); 1362f09cf34dSArchibald Elliott 1363f09cf34dSArchibald Elliott if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save) 1364f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX5124VNNIW); 1365f09cf34dSArchibald Elliott if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save) 1366f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX5124FMAPS); 1367f09cf34dSArchibald Elliott if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save) 1368f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512VP2INTERSECT); 1369f09cf34dSArchibald Elliott 13702a5e3f4cSCraig Topper // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't 13712a5e3f4cSCraig Topper // return all 0s for invalid subleaves so check the limit. 1372f09cf34dSArchibald Elliott bool HasLeaf7Subleaf1 = 13732a5e3f4cSCraig Topper HasLeaf7 && EAX >= 1 && 13742a5e3f4cSCraig Topper !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX); 1375f09cf34dSArchibald Elliott if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save) 1376f09cf34dSArchibald Elliott setFeature(X86::FEATURE_AVX512BF16); 1377f09cf34dSArchibald Elliott 1378f09cf34dSArchibald Elliott unsigned MaxExtLevel; 1379f09cf34dSArchibald Elliott getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); 1380f09cf34dSArchibald Elliott 1381f09cf34dSArchibald Elliott bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 && 1382f09cf34dSArchibald Elliott !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); 1383f09cf34dSArchibald Elliott if (HasExtLeaf1 && ((ECX >> 6) & 1)) 1384f09cf34dSArchibald Elliott setFeature(X86::FEATURE_SSE4_A); 1385f09cf34dSArchibald Elliott if (HasExtLeaf1 && ((ECX >> 11) & 1)) 1386f09cf34dSArchibald Elliott setFeature(X86::FEATURE_XOP); 1387f09cf34dSArchibald Elliott if (HasExtLeaf1 && ((ECX >> 16) & 1)) 1388f09cf34dSArchibald Elliott setFeature(X86::FEATURE_FMA4); 1389f09cf34dSArchibald Elliott 1390f09cf34dSArchibald Elliott if (HasExtLeaf1 && ((EDX >> 29) & 1)) 1391f09cf34dSArchibald Elliott setFeature(X86::FEATURE_64BIT); 1392f09cf34dSArchibald Elliott } 1393f09cf34dSArchibald Elliott 1394f09cf34dSArchibald Elliott StringRef sys::getHostCPUName() { 1395f09cf34dSArchibald Elliott unsigned MaxLeaf = 0; 1396f09cf34dSArchibald Elliott const VendorSignatures Vendor = getVendorSignature(&MaxLeaf); 1397f09cf34dSArchibald Elliott if (Vendor == VendorSignatures::UNKNOWN) 1398f09cf34dSArchibald Elliott return "generic"; 1399f09cf34dSArchibald Elliott 1400f09cf34dSArchibald Elliott unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; 1401f09cf34dSArchibald Elliott getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX); 1402f09cf34dSArchibald Elliott 1403f09cf34dSArchibald Elliott unsigned Family = 0, Model = 0; 1404f09cf34dSArchibald Elliott unsigned Features[(X86::CPU_FEATURE_MAX + 31) / 32] = {0}; 1405f09cf34dSArchibald Elliott detectX86FamilyModel(EAX, &Family, &Model); 1406f09cf34dSArchibald Elliott getAvailableFeatures(ECX, EDX, MaxLeaf, Features); 1407f09cf34dSArchibald Elliott 1408f09cf34dSArchibald Elliott // These aren't consumed in this file, but we try to keep some source code the 1409f09cf34dSArchibald Elliott // same or similar to compiler-rt. 1410f09cf34dSArchibald Elliott unsigned Type = 0; 1411f09cf34dSArchibald Elliott unsigned Subtype = 0; 1412f09cf34dSArchibald Elliott 1413f09cf34dSArchibald Elliott StringRef CPU; 1414f09cf34dSArchibald Elliott 1415f09cf34dSArchibald Elliott if (Vendor == VendorSignatures::GENUINE_INTEL) { 1416f09cf34dSArchibald Elliott CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &Type, 1417f09cf34dSArchibald Elliott &Subtype); 1418f09cf34dSArchibald Elliott } else if (Vendor == VendorSignatures::AUTHENTIC_AMD) { 1419f09cf34dSArchibald Elliott CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, 1420f09cf34dSArchibald Elliott &Subtype); 1421f09cf34dSArchibald Elliott } 1422f09cf34dSArchibald Elliott 1423f09cf34dSArchibald Elliott if (!CPU.empty()) 1424f09cf34dSArchibald Elliott return CPU; 1425f09cf34dSArchibald Elliott 1426f09cf34dSArchibald Elliott return "generic"; 1427f09cf34dSArchibald Elliott } 1428f09cf34dSArchibald Elliott 1429f09cf34dSArchibald Elliott #elif defined(__APPLE__) && defined(__powerpc__) 1430f09cf34dSArchibald Elliott StringRef sys::getHostCPUName() { 1431f09cf34dSArchibald Elliott host_basic_info_data_t hostInfo; 1432f09cf34dSArchibald Elliott mach_msg_type_number_t infoCount; 1433f09cf34dSArchibald Elliott 1434f09cf34dSArchibald Elliott infoCount = HOST_BASIC_INFO_COUNT; 1435f09cf34dSArchibald Elliott mach_port_t hostPort = mach_host_self(); 1436f09cf34dSArchibald Elliott host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo, 1437f09cf34dSArchibald Elliott &infoCount); 1438f09cf34dSArchibald Elliott mach_port_deallocate(mach_task_self(), hostPort); 1439f09cf34dSArchibald Elliott 1440f09cf34dSArchibald Elliott if (hostInfo.cpu_type != CPU_TYPE_POWERPC) 1441f09cf34dSArchibald Elliott return "generic"; 1442f09cf34dSArchibald Elliott 1443f09cf34dSArchibald Elliott switch (hostInfo.cpu_subtype) { 1444f09cf34dSArchibald Elliott case CPU_SUBTYPE_POWERPC_601: 1445f09cf34dSArchibald Elliott return "601"; 1446f09cf34dSArchibald Elliott case CPU_SUBTYPE_POWERPC_602: 1447f09cf34dSArchibald Elliott return "602"; 1448f09cf34dSArchibald Elliott case CPU_SUBTYPE_POWERPC_603: 1449f09cf34dSArchibald Elliott return "603"; 1450f09cf34dSArchibald Elliott case CPU_SUBTYPE_POWERPC_603e: 1451f09cf34dSArchibald Elliott return "603e"; 1452f09cf34dSArchibald Elliott case CPU_SUBTYPE_POWERPC_603ev: 1453f09cf34dSArchibald Elliott return "603ev"; 1454f09cf34dSArchibald Elliott case CPU_SUBTYPE_POWERPC_604: 1455f09cf34dSArchibald Elliott return "604"; 1456f09cf34dSArchibald Elliott case CPU_SUBTYPE_POWERPC_604e: 1457f09cf34dSArchibald Elliott return "604e"; 1458f09cf34dSArchibald Elliott case CPU_SUBTYPE_POWERPC_620: 1459f09cf34dSArchibald Elliott return "620"; 1460f09cf34dSArchibald Elliott case CPU_SUBTYPE_POWERPC_750: 1461f09cf34dSArchibald Elliott return "750"; 1462f09cf34dSArchibald Elliott case CPU_SUBTYPE_POWERPC_7400: 1463f09cf34dSArchibald Elliott return "7400"; 1464f09cf34dSArchibald Elliott case CPU_SUBTYPE_POWERPC_7450: 1465f09cf34dSArchibald Elliott return "7450"; 1466f09cf34dSArchibald Elliott case CPU_SUBTYPE_POWERPC_970: 1467f09cf34dSArchibald Elliott return "970"; 1468f09cf34dSArchibald Elliott default:; 1469f09cf34dSArchibald Elliott } 1470f09cf34dSArchibald Elliott 1471f09cf34dSArchibald Elliott return "generic"; 1472f09cf34dSArchibald Elliott } 1473f09cf34dSArchibald Elliott #elif defined(__linux__) && defined(__powerpc__) 1474f09cf34dSArchibald Elliott StringRef sys::getHostCPUName() { 1475f09cf34dSArchibald Elliott std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1476f09cf34dSArchibald Elliott StringRef Content = P ? P->getBuffer() : ""; 1477f09cf34dSArchibald Elliott return detail::getHostCPUNameForPowerPC(Content); 1478f09cf34dSArchibald Elliott } 1479f09cf34dSArchibald Elliott #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) 1480f09cf34dSArchibald Elliott StringRef sys::getHostCPUName() { 1481f09cf34dSArchibald Elliott std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1482f09cf34dSArchibald Elliott StringRef Content = P ? P->getBuffer() : ""; 1483f09cf34dSArchibald Elliott return detail::getHostCPUNameForARM(Content); 1484f09cf34dSArchibald Elliott } 1485f09cf34dSArchibald Elliott #elif defined(__linux__) && defined(__s390x__) 1486f09cf34dSArchibald Elliott StringRef sys::getHostCPUName() { 1487f09cf34dSArchibald Elliott std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1488f09cf34dSArchibald Elliott StringRef Content = P ? P->getBuffer() : ""; 1489f09cf34dSArchibald Elliott return detail::getHostCPUNameForS390x(Content); 1490f09cf34dSArchibald Elliott } 1491f09cf34dSArchibald Elliott #elif defined(__MVS__) 1492f09cf34dSArchibald Elliott StringRef sys::getHostCPUName() { 1493f09cf34dSArchibald Elliott // Get pointer to Communications Vector Table (CVT). 1494f09cf34dSArchibald Elliott // The pointer is located at offset 16 of the Prefixed Save Area (PSA). 1495f09cf34dSArchibald Elliott // It is stored as 31 bit pointer and will be zero-extended to 64 bit. 1496f09cf34dSArchibald Elliott int *StartToCVTOffset = reinterpret_cast<int *>(0x10); 1497f09cf34dSArchibald Elliott // Since its stored as a 31-bit pointer, get the 4 bytes from the start 1498f09cf34dSArchibald Elliott // of address. 1499f09cf34dSArchibald Elliott int ReadValue = *StartToCVTOffset; 1500f09cf34dSArchibald Elliott // Explicitly clear the high order bit. 1501f09cf34dSArchibald Elliott ReadValue = (ReadValue & 0x7FFFFFFF); 1502f09cf34dSArchibald Elliott char *CVT = reinterpret_cast<char *>(ReadValue); 1503f09cf34dSArchibald Elliott // The model number is located in the CVT prefix at offset -6 and stored as 1504f09cf34dSArchibald Elliott // signless packed decimal. 1505f09cf34dSArchibald Elliott uint16_t Id = *(uint16_t *)&CVT[-6]; 1506f09cf34dSArchibald Elliott // Convert number to integer. 1507f09cf34dSArchibald Elliott Id = decodePackedBCD<uint16_t>(Id, false); 1508f09cf34dSArchibald Elliott // Check for vector support. It's stored in field CVTFLAG5 (offset 244), 1509f09cf34dSArchibald Elliott // bit CVTVEF (X'80'). The facilities list is part of the PSA but the vector 1510f09cf34dSArchibald Elliott // extension can only be used if bit CVTVEF is on. 1511f09cf34dSArchibald Elliott bool HaveVectorSupport = CVT[244] & 0x80; 1512f09cf34dSArchibald Elliott return getCPUNameFromS390Model(Id, HaveVectorSupport); 1513f09cf34dSArchibald Elliott } 1514f09cf34dSArchibald Elliott #elif defined(__APPLE__) && (defined(__arm__) || defined(__aarch64__)) 1515a082cc14SMads Marquart // Copied from <mach/machine.h> in the macOS SDK. 1516a082cc14SMads Marquart // 1517a082cc14SMads Marquart // Also available here, though usually not as up-to-date: 1518a082cc14SMads Marquart // https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.41.3/osfmk/mach/machine.h#L403-L452. 1519a082cc14SMads Marquart #define CPUFAMILY_UNKNOWN 0 1520a082cc14SMads Marquart #define CPUFAMILY_ARM_9 0xe73283ae 1521a082cc14SMads Marquart #define CPUFAMILY_ARM_11 0x8ff620d8 1522a082cc14SMads Marquart #define CPUFAMILY_ARM_XSCALE 0x53b005f5 1523a082cc14SMads Marquart #define CPUFAMILY_ARM_12 0xbd1b0ae9 1524a082cc14SMads Marquart #define CPUFAMILY_ARM_13 0x0cc90e64 1525a082cc14SMads Marquart #define CPUFAMILY_ARM_14 0x96077ef1 1526a082cc14SMads Marquart #define CPUFAMILY_ARM_15 0xa8511bca 1527f09cf34dSArchibald Elliott #define CPUFAMILY_ARM_SWIFT 0x1e2d6381 1528f09cf34dSArchibald Elliott #define CPUFAMILY_ARM_CYCLONE 0x37a09642 1529f09cf34dSArchibald Elliott #define CPUFAMILY_ARM_TYPHOON 0x2c91a47e 1530f09cf34dSArchibald Elliott #define CPUFAMILY_ARM_TWISTER 0x92fb37c8 1531f09cf34dSArchibald Elliott #define CPUFAMILY_ARM_HURRICANE 0x67ceee93 1532f09cf34dSArchibald Elliott #define CPUFAMILY_ARM_MONSOON_MISTRAL 0xe81e7ef6 1533f09cf34dSArchibald Elliott #define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07d34b9f 1534f09cf34dSArchibald Elliott #define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504d2 1535f09cf34dSArchibald Elliott #define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1b588bb3 153670da9155SMads Marquart #define CPUFAMILY_ARM_BLIZZARD_AVALANCHE 0xda33d83d 153770da9155SMads Marquart #define CPUFAMILY_ARM_EVEREST_SAWTOOTH 0x8765edea 1538a082cc14SMads Marquart #define CPUFAMILY_ARM_IBIZA 0xfa33415e 1539a082cc14SMads Marquart #define CPUFAMILY_ARM_PALMA 0x72015832 1540a082cc14SMads Marquart #define CPUFAMILY_ARM_COLL 0x2876f5b5 1541a082cc14SMads Marquart #define CPUFAMILY_ARM_LOBOS 0x5f4dea93 1542a082cc14SMads Marquart #define CPUFAMILY_ARM_DONAN 0x6f5129ac 1543a082cc14SMads Marquart #define CPUFAMILY_ARM_BRAVA 0x17d5b93a 1544a082cc14SMads Marquart #define CPUFAMILY_ARM_TAHITI 0x75d4acb9 1545a082cc14SMads Marquart #define CPUFAMILY_ARM_TUPAI 0x204526d0 1546f09cf34dSArchibald Elliott 1547f09cf34dSArchibald Elliott StringRef sys::getHostCPUName() { 1548f09cf34dSArchibald Elliott uint32_t Family; 1549f09cf34dSArchibald Elliott size_t Length = sizeof(Family); 1550f09cf34dSArchibald Elliott sysctlbyname("hw.cpufamily", &Family, &Length, NULL, 0); 1551f09cf34dSArchibald Elliott 1552a082cc14SMads Marquart // This is found by testing on actual hardware, and by looking at: 1553a082cc14SMads Marquart // https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.41.3/osfmk/arm/cpuid.c#L109-L231. 1554a082cc14SMads Marquart // 1555a082cc14SMads Marquart // Another great resource is 1556a082cc14SMads Marquart // https://github.com/AsahiLinux/docs/wiki/Codenames. 1557a082cc14SMads Marquart // 1558a082cc14SMads Marquart // NOTE: We choose to return `apple-mX` instead of `apple-aX`, since the M1, 1559a082cc14SMads Marquart // M2, M3 etc. aliases are more widely known to users than A14, A15, A16 etc. 1560a082cc14SMads Marquart // (and this code is basically only used on host macOS anyways). 1561f09cf34dSArchibald Elliott switch (Family) { 1562a082cc14SMads Marquart case CPUFAMILY_UNKNOWN: 1563a082cc14SMads Marquart return "generic"; 1564a082cc14SMads Marquart case CPUFAMILY_ARM_9: 1565a082cc14SMads Marquart return "arm920t"; // or arm926ej-s 1566a082cc14SMads Marquart case CPUFAMILY_ARM_11: 1567a082cc14SMads Marquart return "arm1136jf-s"; 1568a082cc14SMads Marquart case CPUFAMILY_ARM_XSCALE: 1569a082cc14SMads Marquart return "xscale"; 1570a082cc14SMads Marquart case CPUFAMILY_ARM_12: // Seems unused by the kernel 1571a082cc14SMads Marquart return "generic"; 1572a082cc14SMads Marquart case CPUFAMILY_ARM_13: 1573a082cc14SMads Marquart return "cortex-a8"; 1574a082cc14SMads Marquart case CPUFAMILY_ARM_14: 1575a082cc14SMads Marquart return "cortex-a9"; 1576a082cc14SMads Marquart case CPUFAMILY_ARM_15: 1577a082cc14SMads Marquart return "cortex-a7"; 1578f09cf34dSArchibald Elliott case CPUFAMILY_ARM_SWIFT: 1579f09cf34dSArchibald Elliott return "swift"; 1580f09cf34dSArchibald Elliott case CPUFAMILY_ARM_CYCLONE: 1581f09cf34dSArchibald Elliott return "apple-a7"; 1582f09cf34dSArchibald Elliott case CPUFAMILY_ARM_TYPHOON: 1583f09cf34dSArchibald Elliott return "apple-a8"; 1584f09cf34dSArchibald Elliott case CPUFAMILY_ARM_TWISTER: 1585f09cf34dSArchibald Elliott return "apple-a9"; 1586f09cf34dSArchibald Elliott case CPUFAMILY_ARM_HURRICANE: 1587f09cf34dSArchibald Elliott return "apple-a10"; 1588f09cf34dSArchibald Elliott case CPUFAMILY_ARM_MONSOON_MISTRAL: 1589f09cf34dSArchibald Elliott return "apple-a11"; 1590f09cf34dSArchibald Elliott case CPUFAMILY_ARM_VORTEX_TEMPEST: 1591f09cf34dSArchibald Elliott return "apple-a12"; 1592f09cf34dSArchibald Elliott case CPUFAMILY_ARM_LIGHTNING_THUNDER: 1593f09cf34dSArchibald Elliott return "apple-a13"; 1594a082cc14SMads Marquart case CPUFAMILY_ARM_FIRESTORM_ICESTORM: // A14 / M1 1595f09cf34dSArchibald Elliott return "apple-m1"; 1596a082cc14SMads Marquart case CPUFAMILY_ARM_BLIZZARD_AVALANCHE: // A15 / M2 159770da9155SMads Marquart return "apple-m2"; 1598a082cc14SMads Marquart case CPUFAMILY_ARM_EVEREST_SAWTOOTH: // A16 1599a082cc14SMads Marquart case CPUFAMILY_ARM_IBIZA: // M3 1600a082cc14SMads Marquart case CPUFAMILY_ARM_PALMA: // M3 Max 1601a082cc14SMads Marquart case CPUFAMILY_ARM_LOBOS: // M3 Pro 160270da9155SMads Marquart return "apple-m3"; 1603a082cc14SMads Marquart case CPUFAMILY_ARM_COLL: // A17 Pro 1604a082cc14SMads Marquart return "apple-a17"; 1605a082cc14SMads Marquart case CPUFAMILY_ARM_DONAN: // M4 1606a082cc14SMads Marquart case CPUFAMILY_ARM_BRAVA: // M4 Max 1607a082cc14SMads Marquart case CPUFAMILY_ARM_TAHITI: // A18 Pro 1608a082cc14SMads Marquart case CPUFAMILY_ARM_TUPAI: // A18 1609a082cc14SMads Marquart return "apple-m4"; 1610f09cf34dSArchibald Elliott default: 1611f09cf34dSArchibald Elliott // Default to the newest CPU we know about. 1612a082cc14SMads Marquart return "apple-m4"; 1613f09cf34dSArchibald Elliott } 1614f09cf34dSArchibald Elliott } 1615f09cf34dSArchibald Elliott #elif defined(_AIX) 1616f09cf34dSArchibald Elliott StringRef sys::getHostCPUName() { 1617f09cf34dSArchibald Elliott switch (_system_configuration.implementation) { 1618f09cf34dSArchibald Elliott case POWER_4: 1619f09cf34dSArchibald Elliott if (_system_configuration.version == PV_4_3) 1620f09cf34dSArchibald Elliott return "970"; 1621f09cf34dSArchibald Elliott return "pwr4"; 1622f09cf34dSArchibald Elliott case POWER_5: 1623f09cf34dSArchibald Elliott if (_system_configuration.version == PV_5) 1624f09cf34dSArchibald Elliott return "pwr5"; 1625f09cf34dSArchibald Elliott return "pwr5x"; 1626f09cf34dSArchibald Elliott case POWER_6: 1627f09cf34dSArchibald Elliott if (_system_configuration.version == PV_6_Compat) 1628f09cf34dSArchibald Elliott return "pwr6"; 1629f09cf34dSArchibald Elliott return "pwr6x"; 1630f09cf34dSArchibald Elliott case POWER_7: 1631f09cf34dSArchibald Elliott return "pwr7"; 1632f09cf34dSArchibald Elliott case POWER_8: 1633f09cf34dSArchibald Elliott return "pwr8"; 1634f09cf34dSArchibald Elliott case POWER_9: 1635f09cf34dSArchibald Elliott return "pwr9"; 1636f09cf34dSArchibald Elliott // TODO: simplify this once the macro is available in all OS levels. 1637f09cf34dSArchibald Elliott #ifdef POWER_10 1638f09cf34dSArchibald Elliott case POWER_10: 1639f09cf34dSArchibald Elliott #else 1640f09cf34dSArchibald Elliott case 0x40000: 1641f09cf34dSArchibald Elliott #endif 1642f09cf34dSArchibald Elliott return "pwr10"; 16431df4d866Sazhan92 #ifdef POWER_11 16441df4d866Sazhan92 case POWER_11: 16451df4d866Sazhan92 #else 16461df4d866Sazhan92 case 0x80000: 16471df4d866Sazhan92 #endif 16481df4d866Sazhan92 return "pwr11"; 1649f09cf34dSArchibald Elliott default: 1650f09cf34dSArchibald Elliott return "generic"; 1651f09cf34dSArchibald Elliott } 1652f09cf34dSArchibald Elliott } 1653e53f41c3Swanglei #elif defined(__loongarch__) 1654e53f41c3Swanglei StringRef sys::getHostCPUName() { 1655e53f41c3Swanglei // Use processor id to detect cpu name. 1656e53f41c3Swanglei uint32_t processor_id; 1657e53f41c3Swanglei __asm__("cpucfg %[prid], $zero\n\t" : [prid] "=r"(processor_id)); 16587e186d36SWeining Lu // Refer PRID_SERIES_MASK in linux kernel: arch/loongarch/include/asm/cpu.h. 16597e186d36SWeining Lu switch (processor_id & 0xf000) { 1660e53f41c3Swanglei case 0xc000: // Loongson 64bit, 4-issue 1661e53f41c3Swanglei return "la464"; 1662fcec2980SAmi-zhang case 0xd000: // Loongson 64bit, 6-issue 1663fcec2980SAmi-zhang return "la664"; 1664e53f41c3Swanglei // TODO: Others. 1665e53f41c3Swanglei default: 1666e53f41c3Swanglei break; 1667e53f41c3Swanglei } 1668e53f41c3Swanglei return "generic"; 1669e53f41c3Swanglei } 1670f09cf34dSArchibald Elliott #elif defined(__riscv) 1671f09cf34dSArchibald Elliott StringRef sys::getHostCPUName() { 1672f09cf34dSArchibald Elliott #if defined(__linux__) 1673f09cf34dSArchibald Elliott std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1674f09cf34dSArchibald Elliott StringRef Content = P ? P->getBuffer() : ""; 1675578cf724SYingwei Zheng StringRef Name = detail::getHostCPUNameForRISCV(Content); 1676578cf724SYingwei Zheng if (!Name.empty()) 1677578cf724SYingwei Zheng return Name; 1678578cf724SYingwei Zheng #endif 1679f09cf34dSArchibald Elliott #if __riscv_xlen == 64 1680f09cf34dSArchibald Elliott return "generic-rv64"; 1681f09cf34dSArchibald Elliott #elif __riscv_xlen == 32 1682f09cf34dSArchibald Elliott return "generic-rv32"; 1683f09cf34dSArchibald Elliott #else 1684f09cf34dSArchibald Elliott #error "Unhandled value of __riscv_xlen" 1685f09cf34dSArchibald Elliott #endif 1686f09cf34dSArchibald Elliott } 1687f09cf34dSArchibald Elliott #elif defined(__sparc__) 1688f09cf34dSArchibald Elliott #if defined(__linux__) 1689f09cf34dSArchibald Elliott StringRef sys::detail::getHostCPUNameForSPARC(StringRef ProcCpuinfoContent) { 1690f09cf34dSArchibald Elliott SmallVector<StringRef> Lines; 1691fd38a955SCraig Topper ProcCpuinfoContent.split(Lines, '\n'); 1692f09cf34dSArchibald Elliott 1693f09cf34dSArchibald Elliott // Look for cpu line to determine cpu name 1694f09cf34dSArchibald Elliott StringRef Cpu; 1695f09cf34dSArchibald Elliott for (unsigned I = 0, E = Lines.size(); I != E; ++I) { 1696038871aeSKazu Hirata if (Lines[I].starts_with("cpu")) { 1697f09cf34dSArchibald Elliott Cpu = Lines[I].substr(5).ltrim("\t :"); 1698f09cf34dSArchibald Elliott break; 1699f09cf34dSArchibald Elliott } 1700f09cf34dSArchibald Elliott } 1701f09cf34dSArchibald Elliott 1702f09cf34dSArchibald Elliott return StringSwitch<const char *>(Cpu) 1703f09cf34dSArchibald Elliott .StartsWith("SuperSparc", "supersparc") 1704f09cf34dSArchibald Elliott .StartsWith("HyperSparc", "hypersparc") 1705f09cf34dSArchibald Elliott .StartsWith("SpitFire", "ultrasparc") 1706f09cf34dSArchibald Elliott .StartsWith("BlackBird", "ultrasparc") 1707f09cf34dSArchibald Elliott .StartsWith("Sabre", " ultrasparc") 1708f09cf34dSArchibald Elliott .StartsWith("Hummingbird", "ultrasparc") 1709f09cf34dSArchibald Elliott .StartsWith("Cheetah", "ultrasparc3") 1710f09cf34dSArchibald Elliott .StartsWith("Jalapeno", "ultrasparc3") 1711f09cf34dSArchibald Elliott .StartsWith("Jaguar", "ultrasparc3") 1712f09cf34dSArchibald Elliott .StartsWith("Panther", "ultrasparc3") 1713f09cf34dSArchibald Elliott .StartsWith("Serrano", "ultrasparc3") 1714f09cf34dSArchibald Elliott .StartsWith("UltraSparc T1", "niagara") 1715f09cf34dSArchibald Elliott .StartsWith("UltraSparc T2", "niagara2") 1716f09cf34dSArchibald Elliott .StartsWith("UltraSparc T3", "niagara3") 1717f09cf34dSArchibald Elliott .StartsWith("UltraSparc T4", "niagara4") 1718f09cf34dSArchibald Elliott .StartsWith("UltraSparc T5", "niagara4") 1719f09cf34dSArchibald Elliott .StartsWith("LEON", "leon3") 1720f09cf34dSArchibald Elliott // niagara7/m8 not supported by LLVM yet. 1721f09cf34dSArchibald Elliott .StartsWith("SPARC-M7", "niagara4" /* "niagara7" */) 1722f09cf34dSArchibald Elliott .StartsWith("SPARC-S7", "niagara4" /* "niagara7" */) 1723f09cf34dSArchibald Elliott .StartsWith("SPARC-M8", "niagara4" /* "m8" */) 1724f09cf34dSArchibald Elliott .Default("generic"); 1725f09cf34dSArchibald Elliott } 1726f09cf34dSArchibald Elliott #endif 1727f09cf34dSArchibald Elliott 1728f09cf34dSArchibald Elliott StringRef sys::getHostCPUName() { 1729f09cf34dSArchibald Elliott #if defined(__linux__) 1730f09cf34dSArchibald Elliott std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 1731f09cf34dSArchibald Elliott StringRef Content = P ? P->getBuffer() : ""; 1732f09cf34dSArchibald Elliott return detail::getHostCPUNameForSPARC(Content); 1733f09cf34dSArchibald Elliott #elif defined(__sun__) && defined(__svr4__) 1734f09cf34dSArchibald Elliott char *buf = NULL; 1735f09cf34dSArchibald Elliott kstat_ctl_t *kc; 1736f09cf34dSArchibald Elliott kstat_t *ksp; 1737f09cf34dSArchibald Elliott kstat_named_t *brand = NULL; 1738f09cf34dSArchibald Elliott 1739f09cf34dSArchibald Elliott kc = kstat_open(); 1740f09cf34dSArchibald Elliott if (kc != NULL) { 1741f09cf34dSArchibald Elliott ksp = kstat_lookup(kc, const_cast<char *>("cpu_info"), -1, NULL); 1742f09cf34dSArchibald Elliott if (ksp != NULL && kstat_read(kc, ksp, NULL) != -1 && 1743f09cf34dSArchibald Elliott ksp->ks_type == KSTAT_TYPE_NAMED) 1744f09cf34dSArchibald Elliott brand = 1745f09cf34dSArchibald Elliott (kstat_named_t *)kstat_data_lookup(ksp, const_cast<char *>("brand")); 1746f09cf34dSArchibald Elliott if (brand != NULL && brand->data_type == KSTAT_DATA_STRING) 1747f09cf34dSArchibald Elliott buf = KSTAT_NAMED_STR_PTR(brand); 1748f09cf34dSArchibald Elliott } 1749f09cf34dSArchibald Elliott kstat_close(kc); 1750f09cf34dSArchibald Elliott 1751f09cf34dSArchibald Elliott return StringSwitch<const char *>(buf) 1752f09cf34dSArchibald Elliott .Case("TMS390S10", "supersparc") // Texas Instruments microSPARC I 1753f09cf34dSArchibald Elliott .Case("TMS390Z50", "supersparc") // Texas Instruments SuperSPARC I 1754f09cf34dSArchibald Elliott .Case("TMS390Z55", 1755f09cf34dSArchibald Elliott "supersparc") // Texas Instruments SuperSPARC I with SuperCache 1756f09cf34dSArchibald Elliott .Case("MB86904", "supersparc") // Fujitsu microSPARC II 1757f09cf34dSArchibald Elliott .Case("MB86907", "supersparc") // Fujitsu TurboSPARC 1758f09cf34dSArchibald Elliott .Case("RT623", "hypersparc") // Ross hyperSPARC 1759f09cf34dSArchibald Elliott .Case("RT625", "hypersparc") 1760f09cf34dSArchibald Elliott .Case("RT626", "hypersparc") 1761f09cf34dSArchibald Elliott .Case("UltraSPARC-I", "ultrasparc") 1762f09cf34dSArchibald Elliott .Case("UltraSPARC-II", "ultrasparc") 1763f09cf34dSArchibald Elliott .Case("UltraSPARC-IIe", "ultrasparc") 1764f09cf34dSArchibald Elliott .Case("UltraSPARC-IIi", "ultrasparc") 1765f09cf34dSArchibald Elliott .Case("SPARC64-III", "ultrasparc") 1766f09cf34dSArchibald Elliott .Case("SPARC64-IV", "ultrasparc") 1767f09cf34dSArchibald Elliott .Case("UltraSPARC-III", "ultrasparc3") 1768f09cf34dSArchibald Elliott .Case("UltraSPARC-III+", "ultrasparc3") 1769f09cf34dSArchibald Elliott .Case("UltraSPARC-IIIi", "ultrasparc3") 1770f09cf34dSArchibald Elliott .Case("UltraSPARC-IIIi+", "ultrasparc3") 1771f09cf34dSArchibald Elliott .Case("UltraSPARC-IV", "ultrasparc3") 1772f09cf34dSArchibald Elliott .Case("UltraSPARC-IV+", "ultrasparc3") 1773f09cf34dSArchibald Elliott .Case("SPARC64-V", "ultrasparc3") 1774f09cf34dSArchibald Elliott .Case("SPARC64-VI", "ultrasparc3") 1775f09cf34dSArchibald Elliott .Case("SPARC64-VII", "ultrasparc3") 1776f09cf34dSArchibald Elliott .Case("UltraSPARC-T1", "niagara") 1777f09cf34dSArchibald Elliott .Case("UltraSPARC-T2", "niagara2") 1778f09cf34dSArchibald Elliott .Case("UltraSPARC-T2", "niagara2") 1779f09cf34dSArchibald Elliott .Case("UltraSPARC-T2+", "niagara2") 1780f09cf34dSArchibald Elliott .Case("SPARC-T3", "niagara3") 1781f09cf34dSArchibald Elliott .Case("SPARC-T4", "niagara4") 1782f09cf34dSArchibald Elliott .Case("SPARC-T5", "niagara4") 1783f09cf34dSArchibald Elliott // niagara7/m8 not supported by LLVM yet. 1784f09cf34dSArchibald Elliott .Case("SPARC-M7", "niagara4" /* "niagara7" */) 1785f09cf34dSArchibald Elliott .Case("SPARC-S7", "niagara4" /* "niagara7" */) 1786f09cf34dSArchibald Elliott .Case("SPARC-M8", "niagara4" /* "m8" */) 1787f09cf34dSArchibald Elliott .Default("generic"); 1788f09cf34dSArchibald Elliott #else 1789f09cf34dSArchibald Elliott return "generic"; 1790f09cf34dSArchibald Elliott #endif 1791f09cf34dSArchibald Elliott } 1792f09cf34dSArchibald Elliott #else 1793f09cf34dSArchibald Elliott StringRef sys::getHostCPUName() { return "generic"; } 1794f09cf34dSArchibald Elliott namespace llvm { 1795f09cf34dSArchibald Elliott namespace sys { 1796f09cf34dSArchibald Elliott namespace detail { 1797f09cf34dSArchibald Elliott namespace x86 { 1798f09cf34dSArchibald Elliott 1799f09cf34dSArchibald Elliott VendorSignatures getVendorSignature(unsigned *MaxLeaf) { 1800f09cf34dSArchibald Elliott return VendorSignatures::UNKNOWN; 1801f09cf34dSArchibald Elliott } 1802f09cf34dSArchibald Elliott 1803f09cf34dSArchibald Elliott } // namespace x86 1804f09cf34dSArchibald Elliott } // namespace detail 1805f09cf34dSArchibald Elliott } // namespace sys 1806f09cf34dSArchibald Elliott } // namespace llvm 1807f09cf34dSArchibald Elliott #endif 1808f09cf34dSArchibald Elliott 1809f09cf34dSArchibald Elliott #if defined(__i386__) || defined(_M_IX86) || \ 1810f09cf34dSArchibald Elliott defined(__x86_64__) || defined(_M_X64) 181118e70a4dSDavid Spickett const StringMap<bool> sys::getHostCPUFeatures() { 1812f09cf34dSArchibald Elliott unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; 1813f09cf34dSArchibald Elliott unsigned MaxLevel; 181418e70a4dSDavid Spickett StringMap<bool> Features; 1815f09cf34dSArchibald Elliott 1816f09cf34dSArchibald Elliott if (getX86CpuIDAndInfo(0, &MaxLevel, &EBX, &ECX, &EDX) || MaxLevel < 1) 181718e70a4dSDavid Spickett return Features; 1818f09cf34dSArchibald Elliott 1819f09cf34dSArchibald Elliott getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX); 1820f09cf34dSArchibald Elliott 1821f09cf34dSArchibald Elliott Features["cx8"] = (EDX >> 8) & 1; 1822f09cf34dSArchibald Elliott Features["cmov"] = (EDX >> 15) & 1; 1823f09cf34dSArchibald Elliott Features["mmx"] = (EDX >> 23) & 1; 1824f09cf34dSArchibald Elliott Features["fxsr"] = (EDX >> 24) & 1; 1825f09cf34dSArchibald Elliott Features["sse"] = (EDX >> 25) & 1; 1826f09cf34dSArchibald Elliott Features["sse2"] = (EDX >> 26) & 1; 1827f09cf34dSArchibald Elliott 1828f09cf34dSArchibald Elliott Features["sse3"] = (ECX >> 0) & 1; 1829f09cf34dSArchibald Elliott Features["pclmul"] = (ECX >> 1) & 1; 1830f09cf34dSArchibald Elliott Features["ssse3"] = (ECX >> 9) & 1; 1831f09cf34dSArchibald Elliott Features["cx16"] = (ECX >> 13) & 1; 1832f09cf34dSArchibald Elliott Features["sse4.1"] = (ECX >> 19) & 1; 1833f09cf34dSArchibald Elliott Features["sse4.2"] = (ECX >> 20) & 1; 1834f09cf34dSArchibald Elliott Features["crc32"] = Features["sse4.2"]; 1835f09cf34dSArchibald Elliott Features["movbe"] = (ECX >> 22) & 1; 1836f09cf34dSArchibald Elliott Features["popcnt"] = (ECX >> 23) & 1; 1837f09cf34dSArchibald Elliott Features["aes"] = (ECX >> 25) & 1; 1838f09cf34dSArchibald Elliott Features["rdrnd"] = (ECX >> 30) & 1; 1839f09cf34dSArchibald Elliott 1840f09cf34dSArchibald Elliott // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV 1841f09cf34dSArchibald Elliott // indicates that the AVX registers will be saved and restored on context 1842f09cf34dSArchibald Elliott // switch, then we have full AVX support. 1843f09cf34dSArchibald Elliott bool HasXSave = ((ECX >> 27) & 1) && !getX86XCR0(&EAX, &EDX); 1844f09cf34dSArchibald Elliott bool HasAVXSave = HasXSave && ((ECX >> 28) & 1) && ((EAX & 0x6) == 0x6); 1845f09cf34dSArchibald Elliott #if defined(__APPLE__) 1846f09cf34dSArchibald Elliott // Darwin lazily saves the AVX512 context on first use: trust that the OS will 1847f09cf34dSArchibald Elliott // save the AVX512 context if we use AVX512 instructions, even the bit is not 1848f09cf34dSArchibald Elliott // set right now. 1849f09cf34dSArchibald Elliott bool HasAVX512Save = true; 1850f09cf34dSArchibald Elliott #else 1851f09cf34dSArchibald Elliott // AVX512 requires additional context to be saved by the OS. 1852f09cf34dSArchibald Elliott bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0); 1853f09cf34dSArchibald Elliott #endif 1854f09cf34dSArchibald Elliott // AMX requires additional context to be saved by the OS. 1855f09cf34dSArchibald Elliott const unsigned AMXBits = (1 << 17) | (1 << 18); 1856f09cf34dSArchibald Elliott bool HasAMXSave = HasXSave && ((EAX & AMXBits) == AMXBits); 1857f09cf34dSArchibald Elliott 1858f09cf34dSArchibald Elliott Features["avx"] = HasAVXSave; 1859f09cf34dSArchibald Elliott Features["fma"] = ((ECX >> 12) & 1) && HasAVXSave; 1860f09cf34dSArchibald Elliott // Only enable XSAVE if OS has enabled support for saving YMM state. 1861f09cf34dSArchibald Elliott Features["xsave"] = ((ECX >> 26) & 1) && HasAVXSave; 1862f09cf34dSArchibald Elliott Features["f16c"] = ((ECX >> 29) & 1) && HasAVXSave; 1863f09cf34dSArchibald Elliott 1864f09cf34dSArchibald Elliott unsigned MaxExtLevel; 1865f09cf34dSArchibald Elliott getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); 1866f09cf34dSArchibald Elliott 1867f09cf34dSArchibald Elliott bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 && 1868f09cf34dSArchibald Elliott !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); 1869f09cf34dSArchibald Elliott Features["sahf"] = HasExtLeaf1 && ((ECX >> 0) & 1); 1870f09cf34dSArchibald Elliott Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1); 1871f09cf34dSArchibald Elliott Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1); 1872f09cf34dSArchibald Elliott Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1); 1873f09cf34dSArchibald Elliott Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave; 1874f09cf34dSArchibald Elliott Features["lwp"] = HasExtLeaf1 && ((ECX >> 15) & 1); 1875f09cf34dSArchibald Elliott Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave; 1876f09cf34dSArchibald Elliott Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1); 1877f09cf34dSArchibald Elliott Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1); 1878f09cf34dSArchibald Elliott 1879f09cf34dSArchibald Elliott Features["64bit"] = HasExtLeaf1 && ((EDX >> 29) & 1); 1880f09cf34dSArchibald Elliott 1881f09cf34dSArchibald Elliott // Miscellaneous memory related features, detected by 1882f09cf34dSArchibald Elliott // using the 0x80000008 leaf of the CPUID instruction 1883f09cf34dSArchibald Elliott bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 && 1884f09cf34dSArchibald Elliott !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX); 1885f09cf34dSArchibald Elliott Features["clzero"] = HasExtLeaf8 && ((EBX >> 0) & 1); 1886f09cf34dSArchibald Elliott Features["rdpru"] = HasExtLeaf8 && ((EBX >> 4) & 1); 1887f09cf34dSArchibald Elliott Features["wbnoinvd"] = HasExtLeaf8 && ((EBX >> 9) & 1); 1888f09cf34dSArchibald Elliott 1889f09cf34dSArchibald Elliott bool HasLeaf7 = 1890f09cf34dSArchibald Elliott MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX); 1891f09cf34dSArchibald Elliott 1892f09cf34dSArchibald Elliott Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1); 1893f09cf34dSArchibald Elliott Features["sgx"] = HasLeaf7 && ((EBX >> 2) & 1); 1894f09cf34dSArchibald Elliott Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1); 1895f09cf34dSArchibald Elliott // AVX2 is only supported if we have the OS save support from AVX. 1896f09cf34dSArchibald Elliott Features["avx2"] = HasLeaf7 && ((EBX >> 5) & 1) && HasAVXSave; 1897f09cf34dSArchibald Elliott Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1); 1898f09cf34dSArchibald Elliott Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1); 1899f09cf34dSArchibald Elliott Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1); 1900f09cf34dSArchibald Elliott // AVX512 is only supported if the OS supports the context save for it. 1901f09cf34dSArchibald Elliott Features["avx512f"] = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save; 190287f34078SPhoebe Wang if (Features["avx512f"]) 190387f34078SPhoebe Wang Features["evex512"] = true; 1904f09cf34dSArchibald Elliott Features["avx512dq"] = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save; 1905f09cf34dSArchibald Elliott Features["rdseed"] = HasLeaf7 && ((EBX >> 18) & 1); 1906f09cf34dSArchibald Elliott Features["adx"] = HasLeaf7 && ((EBX >> 19) & 1); 1907f09cf34dSArchibald Elliott Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save; 1908f09cf34dSArchibald Elliott Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1); 1909f09cf34dSArchibald Elliott Features["clwb"] = HasLeaf7 && ((EBX >> 24) & 1); 1910f09cf34dSArchibald Elliott Features["avx512cd"] = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save; 1911f09cf34dSArchibald Elliott Features["sha"] = HasLeaf7 && ((EBX >> 29) & 1); 1912f09cf34dSArchibald Elliott Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save; 1913f09cf34dSArchibald Elliott Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save; 1914f09cf34dSArchibald Elliott 1915f09cf34dSArchibald Elliott Features["avx512vbmi"] = HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save; 1916f09cf34dSArchibald Elliott Features["pku"] = HasLeaf7 && ((ECX >> 4) & 1); 1917f09cf34dSArchibald Elliott Features["waitpkg"] = HasLeaf7 && ((ECX >> 5) & 1); 1918f09cf34dSArchibald Elliott Features["avx512vbmi2"] = HasLeaf7 && ((ECX >> 6) & 1) && HasAVX512Save; 1919f09cf34dSArchibald Elliott Features["shstk"] = HasLeaf7 && ((ECX >> 7) & 1); 1920f09cf34dSArchibald Elliott Features["gfni"] = HasLeaf7 && ((ECX >> 8) & 1); 1921f09cf34dSArchibald Elliott Features["vaes"] = HasLeaf7 && ((ECX >> 9) & 1) && HasAVXSave; 1922f09cf34dSArchibald Elliott Features["vpclmulqdq"] = HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave; 1923f09cf34dSArchibald Elliott Features["avx512vnni"] = HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save; 1924f09cf34dSArchibald Elliott Features["avx512bitalg"] = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save; 1925f09cf34dSArchibald Elliott Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save; 1926f09cf34dSArchibald Elliott Features["rdpid"] = HasLeaf7 && ((ECX >> 22) & 1); 1927f09cf34dSArchibald Elliott Features["kl"] = HasLeaf7 && ((ECX >> 23) & 1); // key locker 1928f09cf34dSArchibald Elliott Features["cldemote"] = HasLeaf7 && ((ECX >> 25) & 1); 1929f09cf34dSArchibald Elliott Features["movdiri"] = HasLeaf7 && ((ECX >> 27) & 1); 1930f09cf34dSArchibald Elliott Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1); 1931f09cf34dSArchibald Elliott Features["enqcmd"] = HasLeaf7 && ((ECX >> 29) & 1); 1932f09cf34dSArchibald Elliott 1933f09cf34dSArchibald Elliott Features["uintr"] = HasLeaf7 && ((EDX >> 5) & 1); 1934f09cf34dSArchibald Elliott Features["avx512vp2intersect"] = 1935f09cf34dSArchibald Elliott HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save; 1936f09cf34dSArchibald Elliott Features["serialize"] = HasLeaf7 && ((EDX >> 14) & 1); 1937f09cf34dSArchibald Elliott Features["tsxldtrk"] = HasLeaf7 && ((EDX >> 16) & 1); 1938f09cf34dSArchibald Elliott // There are two CPUID leafs which information associated with the pconfig 1939f09cf34dSArchibald Elliott // instruction: 1940f09cf34dSArchibald Elliott // EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th 1941f09cf34dSArchibald Elliott // bit of EDX), while the EAX=0x1b leaf returns information on the 1942f09cf34dSArchibald Elliott // availability of specific pconfig leafs. 1943f09cf34dSArchibald Elliott // The target feature here only refers to the the first of these two. 1944f09cf34dSArchibald Elliott // Users might need to check for the availability of specific pconfig 1945f09cf34dSArchibald Elliott // leaves using cpuid, since that information is ignored while 1946f09cf34dSArchibald Elliott // detecting features using the "-march=native" flag. 1947f09cf34dSArchibald Elliott // For more info, see X86 ISA docs. 1948f09cf34dSArchibald Elliott Features["pconfig"] = HasLeaf7 && ((EDX >> 18) & 1); 1949f09cf34dSArchibald Elliott Features["amx-bf16"] = HasLeaf7 && ((EDX >> 22) & 1) && HasAMXSave; 1950f09cf34dSArchibald Elliott Features["avx512fp16"] = HasLeaf7 && ((EDX >> 23) & 1) && HasAVX512Save; 1951f09cf34dSArchibald Elliott Features["amx-tile"] = HasLeaf7 && ((EDX >> 24) & 1) && HasAMXSave; 1952f09cf34dSArchibald Elliott Features["amx-int8"] = HasLeaf7 && ((EDX >> 25) & 1) && HasAMXSave; 19532a5e3f4cSCraig Topper // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't 19542a5e3f4cSCraig Topper // return all 0s for invalid subleaves so check the limit. 1955f09cf34dSArchibald Elliott bool HasLeaf7Subleaf1 = 19562a5e3f4cSCraig Topper HasLeaf7 && EAX >= 1 && 19572a5e3f4cSCraig Topper !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX); 1958fc3b7874SFreddy Ye Features["sha512"] = HasLeaf7Subleaf1 && ((EAX >> 0) & 1); 1959c6f66de2SFreddy Ye Features["sm3"] = HasLeaf7Subleaf1 && ((EAX >> 1) & 1); 1960049d6a3fSFreddy Ye Features["sm4"] = HasLeaf7Subleaf1 && ((EAX >> 2) & 1); 1961f09cf34dSArchibald Elliott Features["raoint"] = HasLeaf7Subleaf1 && ((EAX >> 3) & 1); 1962f09cf34dSArchibald Elliott Features["avxvnni"] = HasLeaf7Subleaf1 && ((EAX >> 4) & 1) && HasAVXSave; 1963f09cf34dSArchibald Elliott Features["avx512bf16"] = HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save; 1964f09cf34dSArchibald Elliott Features["amx-fp16"] = HasLeaf7Subleaf1 && ((EAX >> 21) & 1) && HasAMXSave; 1965f09cf34dSArchibald Elliott Features["cmpccxadd"] = HasLeaf7Subleaf1 && ((EAX >> 7) & 1); 1966f09cf34dSArchibald Elliott Features["hreset"] = HasLeaf7Subleaf1 && ((EAX >> 22) & 1); 1967f09cf34dSArchibald Elliott Features["avxifma"] = HasLeaf7Subleaf1 && ((EAX >> 23) & 1) && HasAVXSave; 1968c4248fa3SFreddy Ye Features["movrs"] = HasLeaf7Subleaf1 && ((EAX >> 31) & 1); 1969f09cf34dSArchibald Elliott Features["avxvnniint8"] = HasLeaf7Subleaf1 && ((EDX >> 4) & 1) && HasAVXSave; 1970f09cf34dSArchibald Elliott Features["avxneconvert"] = HasLeaf7Subleaf1 && ((EDX >> 5) & 1) && HasAVXSave; 197171249fd7SFreddy Ye Features["amx-complex"] = HasLeaf7Subleaf1 && ((EDX >> 8) & 1) && HasAMXSave; 19721c154bd7SFreddy Ye Features["avxvnniint16"] = HasLeaf7Subleaf1 && ((EDX >> 10) & 1) && HasAVXSave; 1973f09cf34dSArchibald Elliott Features["prefetchi"] = HasLeaf7Subleaf1 && ((EDX >> 14) & 1); 1974819ac45dSFreddy Ye Features["usermsr"] = HasLeaf7Subleaf1 && ((EDX >> 15) & 1); 1975259ca9eeSPhoebe Wang bool HasAVX10 = HasLeaf7Subleaf1 && ((EDX >> 19) & 1); 19761fe6be87SFreddy Ye bool HasAPXF = HasLeaf7Subleaf1 && ((EDX >> 21) & 1); 19771fe6be87SFreddy Ye Features["egpr"] = HasAPXF; 19781fe6be87SFreddy Ye Features["push2pop2"] = HasAPXF; 19791fe6be87SFreddy Ye Features["ppx"] = HasAPXF; 19801fe6be87SFreddy Ye Features["ndd"] = HasAPXF; 19811fe6be87SFreddy Ye Features["ccmp"] = HasAPXF; 198295e9afffSShengchen Kan Features["nf"] = HasAPXF; 19831fe6be87SFreddy Ye Features["cf"] = HasAPXF; 198495e9afffSShengchen Kan Features["zu"] = HasAPXF; 1985f09cf34dSArchibald Elliott 1986f09cf34dSArchibald Elliott bool HasLeafD = MaxLevel >= 0xd && 1987f09cf34dSArchibald Elliott !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX); 1988f09cf34dSArchibald Elliott 1989f09cf34dSArchibald Elliott // Only enable XSAVE if OS has enabled support for saving YMM state. 1990f09cf34dSArchibald Elliott Features["xsaveopt"] = HasLeafD && ((EAX >> 0) & 1) && HasAVXSave; 1991f09cf34dSArchibald Elliott Features["xsavec"] = HasLeafD && ((EAX >> 1) & 1) && HasAVXSave; 1992f09cf34dSArchibald Elliott Features["xsaves"] = HasLeafD && ((EAX >> 3) & 1) && HasAVXSave; 1993f09cf34dSArchibald Elliott 1994f09cf34dSArchibald Elliott bool HasLeaf14 = MaxLevel >= 0x14 && 1995f09cf34dSArchibald Elliott !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX); 1996f09cf34dSArchibald Elliott 1997f09cf34dSArchibald Elliott Features["ptwrite"] = HasLeaf14 && ((EBX >> 4) & 1); 1998f09cf34dSArchibald Elliott 1999f09cf34dSArchibald Elliott bool HasLeaf19 = 2000f09cf34dSArchibald Elliott MaxLevel >= 0x19 && !getX86CpuIDAndInfo(0x19, &EAX, &EBX, &ECX, &EDX); 2001f09cf34dSArchibald Elliott Features["widekl"] = HasLeaf7 && HasLeaf19 && ((EBX >> 2) & 1); 2002f09cf34dSArchibald Elliott 200381271624SFeng Zou bool HasLeaf1E = MaxLevel >= 0x1e && 200481271624SFeng Zou !getX86CpuIDAndInfoEx(0x1e, 0x1, &EAX, &EBX, &ECX, &EDX); 200581271624SFeng Zou Features["amx-fp8"] = HasLeaf1E && ((EAX >> 4) & 1) && HasAMXSave; 2006c72a751dSPhoebe Wang Features["amx-transpose"] = HasLeaf1E && ((EAX >> 5) & 1) && HasAMXSave; 2007eddb79d5SFeng Zou Features["amx-tf32"] = HasLeaf1E && ((EAX >> 6) & 1) && HasAMXSave; 20088f440137SPhoebe Wang Features["amx-avx512"] = HasLeaf1E && ((EAX >> 7) & 1) && HasAMXSave; 2009f77101eaSMalay Sanghi Features["amx-movrs"] = HasLeaf1E && ((EAX >> 8) & 1) && HasAMXSave; 201081271624SFeng Zou 2011cfbf0a50SPhoebe Wang bool HasLeaf24 = 2012cfbf0a50SPhoebe Wang MaxLevel >= 0x24 && !getX86CpuIDAndInfo(0x24, &EAX, &EBX, &ECX, &EDX); 2013259ca9eeSPhoebe Wang 2014259ca9eeSPhoebe Wang int AVX10Ver = HasLeaf24 && (EBX & 0xff); 2015259ca9eeSPhoebe Wang int Has512Len = HasLeaf24 && ((EBX >> 18) & 1); 2016259ca9eeSPhoebe Wang Features["avx10.1-256"] = HasAVX10 && AVX10Ver >= 1; 2017259ca9eeSPhoebe Wang Features["avx10.1-512"] = HasAVX10 && AVX10Ver >= 1 && Has512Len; 2018259ca9eeSPhoebe Wang Features["avx10.2-256"] = HasAVX10 && AVX10Ver >= 2; 2019259ca9eeSPhoebe Wang Features["avx10.2-512"] = HasAVX10 && AVX10Ver >= 2 && Has512Len; 2020cfbf0a50SPhoebe Wang 202118e70a4dSDavid Spickett return Features; 2022f09cf34dSArchibald Elliott } 2023f09cf34dSArchibald Elliott #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) 202418e70a4dSDavid Spickett const StringMap<bool> sys::getHostCPUFeatures() { 202518e70a4dSDavid Spickett StringMap<bool> Features; 2026f09cf34dSArchibald Elliott std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent(); 2027f09cf34dSArchibald Elliott if (!P) 202818e70a4dSDavid Spickett return Features; 2029f09cf34dSArchibald Elliott 2030f09cf34dSArchibald Elliott SmallVector<StringRef, 32> Lines; 2031fd38a955SCraig Topper P->getBuffer().split(Lines, '\n'); 2032f09cf34dSArchibald Elliott 2033f09cf34dSArchibald Elliott SmallVector<StringRef, 32> CPUFeatures; 2034f09cf34dSArchibald Elliott 2035f09cf34dSArchibald Elliott // Look for the CPU features. 2036f09cf34dSArchibald Elliott for (unsigned I = 0, E = Lines.size(); I != E; ++I) 2037038871aeSKazu Hirata if (Lines[I].starts_with("Features")) { 2038f09cf34dSArchibald Elliott Lines[I].split(CPUFeatures, ' '); 2039f09cf34dSArchibald Elliott break; 2040f09cf34dSArchibald Elliott } 2041f09cf34dSArchibald Elliott 2042f09cf34dSArchibald Elliott #if defined(__aarch64__) 2043b8028f6bSJubilee // All of these are "crypto" features, but we must sift out actual features 2044b8028f6bSJubilee // as the former meaning of "crypto" as a single feature is no more. 2045f09cf34dSArchibald Elliott enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 }; 2046f09cf34dSArchibald Elliott uint32_t crypto = 0; 2047f09cf34dSArchibald Elliott #endif 2048f09cf34dSArchibald Elliott 2049f09cf34dSArchibald Elliott for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { 2050f09cf34dSArchibald Elliott StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I]) 2051f09cf34dSArchibald Elliott #if defined(__aarch64__) 2052f09cf34dSArchibald Elliott .Case("asimd", "neon") 2053f09cf34dSArchibald Elliott .Case("fp", "fp-armv8") 2054f09cf34dSArchibald Elliott .Case("crc32", "crc") 2055f09cf34dSArchibald Elliott .Case("atomics", "lse") 2056f09cf34dSArchibald Elliott .Case("sve", "sve") 2057f09cf34dSArchibald Elliott .Case("sve2", "sve2") 2058f09cf34dSArchibald Elliott #else 2059f09cf34dSArchibald Elliott .Case("half", "fp16") 2060f09cf34dSArchibald Elliott .Case("neon", "neon") 2061f09cf34dSArchibald Elliott .Case("vfpv3", "vfp3") 2062f09cf34dSArchibald Elliott .Case("vfpv3d16", "vfp3d16") 2063f09cf34dSArchibald Elliott .Case("vfpv4", "vfp4") 2064f09cf34dSArchibald Elliott .Case("idiva", "hwdiv-arm") 2065f09cf34dSArchibald Elliott .Case("idivt", "hwdiv") 2066f09cf34dSArchibald Elliott #endif 2067f09cf34dSArchibald Elliott .Default(""); 2068f09cf34dSArchibald Elliott 2069f09cf34dSArchibald Elliott #if defined(__aarch64__) 2070f09cf34dSArchibald Elliott // We need to check crypto separately since we need all of the crypto 2071f09cf34dSArchibald Elliott // extensions to enable the subtarget feature 2072f09cf34dSArchibald Elliott if (CPUFeatures[I] == "aes") 2073f09cf34dSArchibald Elliott crypto |= CAP_AES; 2074f09cf34dSArchibald Elliott else if (CPUFeatures[I] == "pmull") 2075f09cf34dSArchibald Elliott crypto |= CAP_PMULL; 2076f09cf34dSArchibald Elliott else if (CPUFeatures[I] == "sha1") 2077f09cf34dSArchibald Elliott crypto |= CAP_SHA1; 2078f09cf34dSArchibald Elliott else if (CPUFeatures[I] == "sha2") 2079f09cf34dSArchibald Elliott crypto |= CAP_SHA2; 2080f09cf34dSArchibald Elliott #endif 2081f09cf34dSArchibald Elliott 2082f09cf34dSArchibald Elliott if (LLVMFeatureStr != "") 2083f09cf34dSArchibald Elliott Features[LLVMFeatureStr] = true; 2084f09cf34dSArchibald Elliott } 2085f09cf34dSArchibald Elliott 2086f09cf34dSArchibald Elliott #if defined(__aarch64__) 2087b8028f6bSJubilee // LLVM has decided some AArch64 CPUs have all the instructions they _may_ 2088b8028f6bSJubilee // have, as opposed to all the instructions they _must_ have, so allow runtime 2089b8028f6bSJubilee // information to correct us on that. 2090b8028f6bSJubilee uint32_t Aes = CAP_AES | CAP_PMULL; 2091b8028f6bSJubilee uint32_t Sha2 = CAP_SHA1 | CAP_SHA2; 2092b8028f6bSJubilee Features["aes"] = (crypto & Aes) == Aes; 2093b8028f6bSJubilee Features["sha2"] = (crypto & Sha2) == Sha2; 2094f09cf34dSArchibald Elliott #endif 2095f09cf34dSArchibald Elliott 209618e70a4dSDavid Spickett return Features; 2097f09cf34dSArchibald Elliott } 2098f09cf34dSArchibald Elliott #elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64)) 209918e70a4dSDavid Spickett const StringMap<bool> sys::getHostCPUFeatures() { 210018e70a4dSDavid Spickett StringMap<bool> Features; 210118e70a4dSDavid Spickett 2102b8028f6bSJubilee // If we're asking the OS at runtime, believe what the OS says 2103b8028f6bSJubilee Features["neon"] = 2104b8028f6bSJubilee IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE); 2105b8028f6bSJubilee Features["crc"] = 2106b8028f6bSJubilee IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE); 2107b8028f6bSJubilee 2108b8028f6bSJubilee // Avoid inferring "crypto" means more than the traditional AES + SHA2 2109b8028f6bSJubilee bool TradCrypto = 2110b8028f6bSJubilee IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE); 2111b8028f6bSJubilee Features["aes"] = TradCrypto; 2112b8028f6bSJubilee Features["sha2"] = TradCrypto; 2113f09cf34dSArchibald Elliott 211418e70a4dSDavid Spickett return Features; 2115f09cf34dSArchibald Elliott } 2116e53f41c3Swanglei #elif defined(__linux__) && defined(__loongarch__) 2117e53f41c3Swanglei #include <sys/auxv.h> 211818e70a4dSDavid Spickett const StringMap<bool> sys::getHostCPUFeatures() { 2119e53f41c3Swanglei unsigned long hwcap = getauxval(AT_HWCAP); 2120e53f41c3Swanglei bool HasFPU = hwcap & (1UL << 3); // HWCAP_LOONGARCH_FPU 2121e70f9e20SWeining Lu uint32_t cpucfg2 = 0x2, cpucfg3 = 0x3; 2122e53f41c3Swanglei __asm__("cpucfg %[cpucfg2], %[cpucfg2]\n\t" : [cpucfg2] "+r"(cpucfg2)); 21231d460207Stangaac __asm__("cpucfg %[cpucfg3], %[cpucfg3]\n\t" : [cpucfg3] "+r"(cpucfg3)); 2124e53f41c3Swanglei 212518e70a4dSDavid Spickett StringMap<bool> Features; 212618e70a4dSDavid Spickett 2127e53f41c3Swanglei Features["f"] = HasFPU && (cpucfg2 & (1U << 1)); // CPUCFG.2.FP_SP 2128e53f41c3Swanglei Features["d"] = HasFPU && (cpucfg2 & (1U << 2)); // CPUCFG.2.FP_DP 2129e53f41c3Swanglei 2130e53f41c3Swanglei Features["lsx"] = hwcap & (1UL << 4); // HWCAP_LOONGARCH_LSX 2131e53f41c3Swanglei Features["lasx"] = hwcap & (1UL << 5); // HWCAP_LOONGARCH_LASX 2132e53f41c3Swanglei Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ 2133e53f41c3Swanglei 21342283d504Stangaac Features["frecipe"] = cpucfg2 & (1U << 25); // CPUCFG.2.FRECIPE 2135f4379db4Stangaac Features["div32"] = cpucfg2 & (1U << 26); // CPUCFG.2.DIV32 21362283d504Stangaac Features["lam-bh"] = cpucfg2 & (1U << 27); // CPUCFG.2.LAM_BH 2137427be076Stangaac Features["lamcas"] = cpucfg2 & (1U << 28); // CPUCFG.2.LAMCAS 2138*19834b46Stangaac Features["scq"] = cpucfg2 & (1U << 30); // CPUCFG.2.SCQ 21392283d504Stangaac 21401d460207Stangaac Features["ld-seq-sa"] = cpucfg3 & (1U << 23); // CPUCFG.3.LD_SEQ_SA 21411d460207Stangaac 21422283d504Stangaac // TODO: Need to complete. 21432283d504Stangaac // Features["llacq-screl"] = cpucfg2 & (1U << 29); // CPUCFG.2.LLACQ_SCREL 214418e70a4dSDavid Spickett return Features; 2145e53f41c3Swanglei } 2146578cf724SYingwei Zheng #elif defined(__linux__) && defined(__riscv) 2147578cf724SYingwei Zheng // struct riscv_hwprobe 2148578cf724SYingwei Zheng struct RISCVHwProbe { 2149578cf724SYingwei Zheng int64_t Key; 2150578cf724SYingwei Zheng uint64_t Value; 2151578cf724SYingwei Zheng }; 2152578cf724SYingwei Zheng const StringMap<bool> sys::getHostCPUFeatures() { 2153578cf724SYingwei Zheng RISCVHwProbe Query[]{{/*RISCV_HWPROBE_KEY_BASE_BEHAVIOR=*/3, 0}, 2154bf895c71SYingwei Zheng {/*RISCV_HWPROBE_KEY_IMA_EXT_0=*/4, 0}, 2155bf895c71SYingwei Zheng {/*RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF=*/9, 0}}; 2156578cf724SYingwei Zheng int Ret = syscall(/*__NR_riscv_hwprobe=*/258, /*pairs=*/Query, 2157578cf724SYingwei Zheng /*pair_count=*/std::size(Query), /*cpu_count=*/0, 2158578cf724SYingwei Zheng /*cpus=*/0, /*flags=*/0); 2159578cf724SYingwei Zheng if (Ret != 0) 2160578cf724SYingwei Zheng return {}; 2161578cf724SYingwei Zheng 2162578cf724SYingwei Zheng StringMap<bool> Features; 2163578cf724SYingwei Zheng uint64_t BaseMask = Query[0].Value; 2164578cf724SYingwei Zheng // Check whether RISCV_HWPROBE_BASE_BEHAVIOR_IMA is set. 2165578cf724SYingwei Zheng if (BaseMask & 1) { 2166578cf724SYingwei Zheng Features["i"] = true; 2167578cf724SYingwei Zheng Features["m"] = true; 2168578cf724SYingwei Zheng Features["a"] = true; 2169578cf724SYingwei Zheng } 2170578cf724SYingwei Zheng 2171578cf724SYingwei Zheng uint64_t ExtMask = Query[1].Value; 2172578cf724SYingwei Zheng Features["f"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD 2173578cf724SYingwei Zheng Features["d"] = ExtMask & (1 << 0); // RISCV_HWPROBE_IMA_FD 2174578cf724SYingwei Zheng Features["c"] = ExtMask & (1 << 1); // RISCV_HWPROBE_IMA_C 2175578cf724SYingwei Zheng Features["v"] = ExtMask & (1 << 2); // RISCV_HWPROBE_IMA_V 2176578cf724SYingwei Zheng Features["zba"] = ExtMask & (1 << 3); // RISCV_HWPROBE_EXT_ZBA 2177578cf724SYingwei Zheng Features["zbb"] = ExtMask & (1 << 4); // RISCV_HWPROBE_EXT_ZBB 2178578cf724SYingwei Zheng Features["zbs"] = ExtMask & (1 << 5); // RISCV_HWPROBE_EXT_ZBS 2179578cf724SYingwei Zheng Features["zicboz"] = ExtMask & (1 << 6); // RISCV_HWPROBE_EXT_ZICBOZ 2180578cf724SYingwei Zheng Features["zbc"] = ExtMask & (1 << 7); // RISCV_HWPROBE_EXT_ZBC 2181578cf724SYingwei Zheng Features["zbkb"] = ExtMask & (1 << 8); // RISCV_HWPROBE_EXT_ZBKB 2182578cf724SYingwei Zheng Features["zbkc"] = ExtMask & (1 << 9); // RISCV_HWPROBE_EXT_ZBKC 2183578cf724SYingwei Zheng Features["zbkx"] = ExtMask & (1 << 10); // RISCV_HWPROBE_EXT_ZBKX 2184578cf724SYingwei Zheng Features["zknd"] = ExtMask & (1 << 11); // RISCV_HWPROBE_EXT_ZKND 2185578cf724SYingwei Zheng Features["zkne"] = ExtMask & (1 << 12); // RISCV_HWPROBE_EXT_ZKNE 2186578cf724SYingwei Zheng Features["zknh"] = ExtMask & (1 << 13); // RISCV_HWPROBE_EXT_ZKNH 2187578cf724SYingwei Zheng Features["zksed"] = ExtMask & (1 << 14); // RISCV_HWPROBE_EXT_ZKSED 2188578cf724SYingwei Zheng Features["zksh"] = ExtMask & (1 << 15); // RISCV_HWPROBE_EXT_ZKSH 2189578cf724SYingwei Zheng Features["zkt"] = ExtMask & (1 << 16); // RISCV_HWPROBE_EXT_ZKT 2190578cf724SYingwei Zheng Features["zvbb"] = ExtMask & (1 << 17); // RISCV_HWPROBE_EXT_ZVBB 2191578cf724SYingwei Zheng Features["zvbc"] = ExtMask & (1 << 18); // RISCV_HWPROBE_EXT_ZVBC 2192578cf724SYingwei Zheng Features["zvkb"] = ExtMask & (1 << 19); // RISCV_HWPROBE_EXT_ZVKB 2193578cf724SYingwei Zheng Features["zvkg"] = ExtMask & (1 << 20); // RISCV_HWPROBE_EXT_ZVKG 2194578cf724SYingwei Zheng Features["zvkned"] = ExtMask & (1 << 21); // RISCV_HWPROBE_EXT_ZVKNED 2195578cf724SYingwei Zheng Features["zvknha"] = ExtMask & (1 << 22); // RISCV_HWPROBE_EXT_ZVKNHA 2196578cf724SYingwei Zheng Features["zvknhb"] = ExtMask & (1 << 23); // RISCV_HWPROBE_EXT_ZVKNHB 2197578cf724SYingwei Zheng Features["zvksed"] = ExtMask & (1 << 24); // RISCV_HWPROBE_EXT_ZVKSED 2198578cf724SYingwei Zheng Features["zvksh"] = ExtMask & (1 << 25); // RISCV_HWPROBE_EXT_ZVKSH 2199578cf724SYingwei Zheng Features["zvkt"] = ExtMask & (1 << 26); // RISCV_HWPROBE_EXT_ZVKT 2200578cf724SYingwei Zheng Features["zfh"] = ExtMask & (1 << 27); // RISCV_HWPROBE_EXT_ZFH 2201578cf724SYingwei Zheng Features["zfhmin"] = ExtMask & (1 << 28); // RISCV_HWPROBE_EXT_ZFHMIN 2202578cf724SYingwei Zheng Features["zihintntl"] = ExtMask & (1 << 29); // RISCV_HWPROBE_EXT_ZIHINTNTL 2203578cf724SYingwei Zheng Features["zvfh"] = ExtMask & (1 << 30); // RISCV_HWPROBE_EXT_ZVFH 2204578cf724SYingwei Zheng Features["zvfhmin"] = ExtMask & (1ULL << 31); // RISCV_HWPROBE_EXT_ZVFHMIN 2205578cf724SYingwei Zheng Features["zfa"] = ExtMask & (1ULL << 32); // RISCV_HWPROBE_EXT_ZFA 2206578cf724SYingwei Zheng Features["ztso"] = ExtMask & (1ULL << 33); // RISCV_HWPROBE_EXT_ZTSO 2207614aeda9SAlex Bradbury Features["zacas"] = ExtMask & (1ULL << 34); // RISCV_HWPROBE_EXT_ZACAS 2208578cf724SYingwei Zheng Features["zicond"] = ExtMask & (1ULL << 35); // RISCV_HWPROBE_EXT_ZICOND 2209578cf724SYingwei Zheng Features["zihintpause"] = 2210578cf724SYingwei Zheng ExtMask & (1ULL << 36); // RISCV_HWPROBE_EXT_ZIHINTPAUSE 2211bf895c71SYingwei Zheng Features["zve32x"] = ExtMask & (1ULL << 37); // RISCV_HWPROBE_EXT_ZVE32X 2212bf895c71SYingwei Zheng Features["zve32f"] = ExtMask & (1ULL << 38); // RISCV_HWPROBE_EXT_ZVE32F 2213bf895c71SYingwei Zheng Features["zve64x"] = ExtMask & (1ULL << 39); // RISCV_HWPROBE_EXT_ZVE64X 2214bf895c71SYingwei Zheng Features["zve64f"] = ExtMask & (1ULL << 40); // RISCV_HWPROBE_EXT_ZVE64F 2215bf895c71SYingwei Zheng Features["zve64d"] = ExtMask & (1ULL << 41); // RISCV_HWPROBE_EXT_ZVE64D 2216bf895c71SYingwei Zheng Features["zimop"] = ExtMask & (1ULL << 42); // RISCV_HWPROBE_EXT_ZIMOP 2217bf895c71SYingwei Zheng Features["zca"] = ExtMask & (1ULL << 43); // RISCV_HWPROBE_EXT_ZCA 2218bf895c71SYingwei Zheng Features["zcb"] = ExtMask & (1ULL << 44); // RISCV_HWPROBE_EXT_ZCB 2219bf895c71SYingwei Zheng Features["zcd"] = ExtMask & (1ULL << 45); // RISCV_HWPROBE_EXT_ZCD 2220bf895c71SYingwei Zheng Features["zcf"] = ExtMask & (1ULL << 46); // RISCV_HWPROBE_EXT_ZCF 2221bf895c71SYingwei Zheng Features["zcmop"] = ExtMask & (1ULL << 47); // RISCV_HWPROBE_EXT_ZCMOP 2222bf895c71SYingwei Zheng Features["zawrs"] = ExtMask & (1ULL << 48); // RISCV_HWPROBE_EXT_ZAWRS 2223578cf724SYingwei Zheng 2224bf895c71SYingwei Zheng // Check whether the processor supports fast misaligned scalar memory access. 2225bf895c71SYingwei Zheng // NOTE: RISCV_HWPROBE_KEY_MISALIGNED_SCALAR_PERF is only available on 2226bf895c71SYingwei Zheng // Linux 6.11 or later. If it is not recognized, the key field will be cleared 2227bf895c71SYingwei Zheng // to -1. 2228bf895c71SYingwei Zheng if (Query[2].Key != -1 && 2229bf895c71SYingwei Zheng Query[2].Value == /*RISCV_HWPROBE_MISALIGNED_SCALAR_FAST=*/3) 2230bf895c71SYingwei Zheng Features["unaligned-scalar-mem"] = true; 2231578cf724SYingwei Zheng 2232578cf724SYingwei Zheng return Features; 2233578cf724SYingwei Zheng } 2234f09cf34dSArchibald Elliott #else 223518e70a4dSDavid Spickett const StringMap<bool> sys::getHostCPUFeatures() { return {}; } 2236f09cf34dSArchibald Elliott #endif 2237f09cf34dSArchibald Elliott 2238dc078e6eSJon Roelofs #if __APPLE__ 2239dc078e6eSJon Roelofs /// \returns the \p triple, but with the Host's arch spliced in. 2240dc078e6eSJon Roelofs static Triple withHostArch(Triple T) { 2241dc078e6eSJon Roelofs #if defined(__arm__) 2242dc078e6eSJon Roelofs T.setArch(Triple::arm); 2243dc078e6eSJon Roelofs T.setArchName("arm"); 2244dc078e6eSJon Roelofs #elif defined(__arm64e__) 2245dc078e6eSJon Roelofs T.setArch(Triple::aarch64, Triple::AArch64SubArch_arm64e); 2246dc078e6eSJon Roelofs T.setArchName("arm64e"); 2247dc078e6eSJon Roelofs #elif defined(__aarch64__) 2248dc078e6eSJon Roelofs T.setArch(Triple::aarch64); 2249dc078e6eSJon Roelofs T.setArchName("arm64"); 2250dc078e6eSJon Roelofs #elif defined(__x86_64h__) 2251dc078e6eSJon Roelofs T.setArch(Triple::x86_64); 2252dc078e6eSJon Roelofs T.setArchName("x86_64h"); 2253dc078e6eSJon Roelofs #elif defined(__x86_64__) 2254dc078e6eSJon Roelofs T.setArch(Triple::x86_64); 2255dc078e6eSJon Roelofs T.setArchName("x86_64"); 2256a5e10e24SKirill A. Korinsky #elif defined(__i386__) 2257a5e10e24SKirill A. Korinsky T.setArch(Triple::x86); 2258a5e10e24SKirill A. Korinsky T.setArchName("i386"); 2259dc078e6eSJon Roelofs #elif defined(__powerpc__) 2260dc078e6eSJon Roelofs T.setArch(Triple::ppc); 2261dc078e6eSJon Roelofs T.setArchName("powerpc"); 2262dc078e6eSJon Roelofs #else 2263dc078e6eSJon Roelofs # error "Unimplemented host arch fixup" 2264dc078e6eSJon Roelofs #endif 2265dc078e6eSJon Roelofs return T; 2266dc078e6eSJon Roelofs } 2267dc078e6eSJon Roelofs #endif 2268dc078e6eSJon Roelofs 2269f09cf34dSArchibald Elliott std::string sys::getProcessTriple() { 2270f09cf34dSArchibald Elliott std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE); 2271f09cf34dSArchibald Elliott Triple PT(Triple::normalize(TargetTripleString)); 2272f09cf34dSArchibald Elliott 2273dc078e6eSJon Roelofs #if __APPLE__ 2274dc078e6eSJon Roelofs /// In Universal builds, LLVM_HOST_TRIPLE will have the wrong arch in one of 2275dc078e6eSJon Roelofs /// the slices. This fixes that up. 2276dc078e6eSJon Roelofs PT = withHostArch(PT); 2277dc078e6eSJon Roelofs #endif 2278dc078e6eSJon Roelofs 2279f09cf34dSArchibald Elliott if (sizeof(void *) == 8 && PT.isArch32Bit()) 2280f09cf34dSArchibald Elliott PT = PT.get64BitArchVariant(); 2281f09cf34dSArchibald Elliott if (sizeof(void *) == 4 && PT.isArch64Bit()) 2282f09cf34dSArchibald Elliott PT = PT.get32BitArchVariant(); 2283f09cf34dSArchibald Elliott 2284f09cf34dSArchibald Elliott return PT.str(); 2285f09cf34dSArchibald Elliott } 2286f09cf34dSArchibald Elliott 2287f09cf34dSArchibald Elliott void sys::printDefaultTargetAndDetectedCPU(raw_ostream &OS) { 2288f09cf34dSArchibald Elliott #if LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO 2289f09cf34dSArchibald Elliott std::string CPU = std::string(sys::getHostCPUName()); 2290f09cf34dSArchibald Elliott if (CPU == "generic") 2291f09cf34dSArchibald Elliott CPU = "(unknown)"; 2292f09cf34dSArchibald Elliott OS << " Default target: " << sys::getDefaultTargetTriple() << '\n' 2293f09cf34dSArchibald Elliott << " Host CPU: " << CPU << '\n'; 2294f09cf34dSArchibald Elliott #endif 2295f09cf34dSArchibald Elliott } 2296