LCOV - code coverage report
Current view: top level - lib/Support - Host.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 130 558 23.3 %
Date: 2018-10-20 13:21:21 Functions: 8 13 61.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- Host.cpp - Implement OS Host Concept --------------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : //  This file implements the operating system Host concept.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "llvm/Support/Host.h"
      15             : #include "llvm/Support/TargetParser.h"
      16             : #include "llvm/ADT/SmallSet.h"
      17             : #include "llvm/ADT/SmallVector.h"
      18             : #include "llvm/ADT/StringRef.h"
      19             : #include "llvm/ADT/StringSwitch.h"
      20             : #include "llvm/ADT/Triple.h"
      21             : #include "llvm/Config/llvm-config.h"
      22             : #include "llvm/Support/Debug.h"
      23             : #include "llvm/Support/FileSystem.h"
      24             : #include "llvm/Support/MemoryBuffer.h"
      25             : #include "llvm/Support/raw_ostream.h"
      26             : #include <assert.h>
      27             : #include <string.h>
      28             : 
      29             : // Include the platform-specific parts of this class.
      30             : #ifdef LLVM_ON_UNIX
      31             : #include "Unix/Host.inc"
      32             : #endif
      33             : #ifdef _WIN32
      34             : #include "Windows/Host.inc"
      35             : #endif
      36             : #ifdef _MSC_VER
      37             : #include <intrin.h>
      38             : #endif
      39             : #if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
      40             : #include <mach/host_info.h>
      41             : #include <mach/mach.h>
      42             : #include <mach/mach_host.h>
      43             : #include <mach/machine.h>
      44             : #endif
      45             : 
      46             : #define DEBUG_TYPE "host-detection"
      47             : 
      48             : //===----------------------------------------------------------------------===//
      49             : //
      50             : //  Implementations of the CPU detection routines
      51             : //
      52             : //===----------------------------------------------------------------------===//
      53             : 
      54             : using namespace llvm;
      55             : 
      56             : static std::unique_ptr<llvm::MemoryBuffer>
      57             :     LLVM_ATTRIBUTE_UNUSED getProcCpuinfoContent() {
      58             :   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
      59             :       llvm::MemoryBuffer::getFileAsStream("/proc/cpuinfo");
      60             :   if (std::error_code EC = Text.getError()) {
      61             :     llvm::errs() << "Can't read "
      62             :                  << "/proc/cpuinfo: " << EC.message() << "\n";
      63             :     return nullptr;
      64             :   }
      65             :   return std::move(*Text);
      66             : }
      67             : 
      68           0 : StringRef sys::detail::getHostCPUNameForPowerPC(StringRef ProcCpuinfoContent) {
      69             :   // Access to the Processor Version Register (PVR) on PowerPC is privileged,
      70             :   // and so we must use an operating-system interface to determine the current
      71             :   // processor type. On Linux, this is exposed through the /proc/cpuinfo file.
      72             :   const char *generic = "generic";
      73             : 
      74             :   // The cpu line is second (after the 'processor: 0' line), so if this
      75             :   // buffer is too small then something has changed (or is wrong).
      76             :   StringRef::const_iterator CPUInfoStart = ProcCpuinfoContent.begin();
      77           0 :   StringRef::const_iterator CPUInfoEnd = ProcCpuinfoContent.end();
      78             : 
      79             :   StringRef::const_iterator CIP = CPUInfoStart;
      80             : 
      81             :   StringRef::const_iterator CPUStart = 0;
      82             :   size_t CPULen = 0;
      83             : 
      84             :   // We need to find the first line which starts with cpu, spaces, and a colon.
      85             :   // After the colon, there may be some additional spaces and then the cpu type.
      86           0 :   while (CIP < CPUInfoEnd && CPUStart == 0) {
      87           0 :     if (CIP < CPUInfoEnd && *CIP == '\n')
      88           0 :       ++CIP;
      89             : 
      90           0 :     if (CIP < CPUInfoEnd && *CIP == 'c') {
      91           0 :       ++CIP;
      92           0 :       if (CIP < CPUInfoEnd && *CIP == 'p') {
      93           0 :         ++CIP;
      94           0 :         if (CIP < CPUInfoEnd && *CIP == 'u') {
      95           0 :           ++CIP;
      96           0 :           while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
      97           0 :             ++CIP;
      98             : 
      99           0 :           if (CIP < CPUInfoEnd && *CIP == ':') {
     100           0 :             ++CIP;
     101           0 :             while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
     102           0 :               ++CIP;
     103             : 
     104           0 :             if (CIP < CPUInfoEnd) {
     105             :               CPUStart = CIP;
     106           0 :               while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
     107           0 :                                           *CIP != ',' && *CIP != '\n'))
     108           0 :                 ++CIP;
     109           0 :               CPULen = CIP - CPUStart;
     110             :             }
     111             :           }
     112             :         }
     113             :       }
     114             :     }
     115             : 
     116           0 :     if (CPUStart == 0)
     117           0 :       while (CIP < CPUInfoEnd && *CIP != '\n')
     118           0 :         ++CIP;
     119             :   }
     120             : 
     121           0 :   if (CPUStart == 0)
     122           0 :     return generic;
     123             : 
     124           0 :   return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
     125           0 :       .Case("604e", "604e")
     126           0 :       .Case("604", "604")
     127           0 :       .Case("7400", "7400")
     128           0 :       .Case("7410", "7400")
     129           0 :       .Case("7447", "7400")
     130           0 :       .Case("7455", "7450")
     131           0 :       .Case("G4", "g4")
     132           0 :       .Case("POWER4", "970")
     133           0 :       .Case("PPC970FX", "970")
     134           0 :       .Case("PPC970MP", "970")
     135           0 :       .Case("G5", "g5")
     136           0 :       .Case("POWER5", "g5")
     137           0 :       .Case("A2", "a2")
     138           0 :       .Case("POWER6", "pwr6")
     139           0 :       .Case("POWER7", "pwr7")
     140           0 :       .Case("POWER8", "pwr8")
     141           0 :       .Case("POWER8E", "pwr8")
     142           0 :       .Case("POWER8NVL", "pwr8")
     143           0 :       .Case("POWER9", "pwr9")
     144           0 :       .Default(generic);
     145             : }
     146             : 
     147          25 : StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) {
     148             :   // The cpuid register on arm is not accessible from user space. On Linux,
     149             :   // it is exposed through the /proc/cpuinfo file.
     150             : 
     151             :   // Read 32 lines from /proc/cpuinfo, which should contain the CPU part line
     152             :   // in all cases.
     153             :   SmallVector<StringRef, 32> Lines;
     154          25 :   ProcCpuinfoContent.split(Lines, "\n");
     155             : 
     156             :   // Look for the CPU implementer line.
     157             :   StringRef Implementer;
     158             :   StringRef Hardware;
     159         229 :   for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
     160         204 :     if (Lines[I].startswith("CPU implementer"))
     161          78 :       Implementer = Lines[I].substr(15).ltrim("\t :");
     162             :     if (Lines[I].startswith("Hardware"))
     163           4 :       Hardware = Lines[I].substr(8).ltrim("\t :");
     164             :   }
     165             : 
     166             :   if (Implementer == "0x41") { // ARM Ltd.
     167             :     // MSM8992/8994 may give cpu part for the core that the kernel is running on,
     168             :     // which is undeterministic and wrong. Always return cortex-a53 for these SoC.
     169             :     if (Hardware.endswith("MSM8994") || Hardware.endswith("MSM8996"))
     170           0 :       return "cortex-a53";
     171             : 
     172             : 
     173             :     // Look for the CPU part line.
     174          26 :     for (unsigned I = 0, E = Lines.size(); I != E; ++I)
     175          26 :       if (Lines[I].startswith("CPU part"))
     176             :         // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
     177             :         // values correspond to the "Part number" in the CP15/c0 register. The
     178             :         // contents are specified in the various processor manuals.
     179           8 :         return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
     180             :             .Case("0x926", "arm926ej-s")
     181             :             .Case("0xb02", "mpcore")
     182             :             .Case("0xb36", "arm1136j-s")
     183             :             .Case("0xb56", "arm1156t2-s")
     184             :             .Case("0xb76", "arm1176jz-s")
     185             :             .Case("0xc08", "cortex-a8")
     186             :             .Case("0xc09", "cortex-a9")
     187             :             .Case("0xc0f", "cortex-a15")
     188             :             .Case("0xc20", "cortex-m0")
     189             :             .Case("0xc23", "cortex-m3")
     190             :             .Case("0xc24", "cortex-m4")
     191             :             .Case("0xd04", "cortex-a35")
     192             :             .Case("0xd03", "cortex-a53")
     193             :             .Case("0xd07", "cortex-a57")
     194             :             .Case("0xd08", "cortex-a72")
     195             :             .Case("0xd09", "cortex-a73")
     196           4 :             .Default("generic");
     197             :   }
     198             : 
     199             :   if (Implementer == "0x42" || Implementer == "0x43") { // Broadcom | Cavium.
     200          80 :     for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
     201          80 :       if (Lines[I].startswith("CPU part")) {
     202          20 :         return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
     203             :           .Case("0x516", "thunderx2t99")
     204             :           .Case("0x0516", "thunderx2t99")
     205             :           .Case("0xaf", "thunderx2t99")
     206             :           .Case("0x0af", "thunderx2t99")
     207             :           .Case("0xa1", "thunderxt88")
     208             :           .Case("0x0a1", "thunderxt88")
     209          10 :           .Default("generic");
     210             :       }
     211             :     }
     212             :   }
     213             : 
     214             :   if (Implementer == "0x51") // Qualcomm Technologies, Inc.
     215             :     // Look for the CPU part line.
     216          12 :     for (unsigned I = 0, E = Lines.size(); I != E; ++I)
     217          12 :       if (Lines[I].startswith("CPU part"))
     218             :         // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The
     219             :         // values correspond to the "Part number" in the CP15/c0 register. The
     220             :         // contents are specified in the various processor manuals.
     221          12 :         return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :"))
     222             :             .Case("0x06f", "krait") // APQ8064
     223             :             .Case("0x201", "kryo")
     224             :             .Case("0x205", "kryo")
     225             :             .Case("0x211", "kryo")
     226             :             .Case("0x800", "cortex-a73")
     227             :             .Case("0x801", "cortex-a73")
     228             :             .Case("0xc00", "falkor")
     229             :             .Case("0xc01", "saphira")
     230           6 :             .Default("generic");
     231             : 
     232             :   if (Implementer == "0x53") { // Samsung Electronics Co., Ltd.
     233             :     // The Exynos chips have a convoluted ID scheme that doesn't seem to follow
     234             :     // any predictive pattern across variants and parts.
     235           3 :     unsigned Variant = 0, Part = 0;
     236             : 
     237             :     // Look for the CPU variant line, whose value is a 1 digit hexadecimal
     238             :     // number, corresponding to the Variant bits in the CP15/C0 register.
     239          45 :     for (auto I : Lines)
     240             :       if (I.consume_front("CPU variant"))
     241           6 :         I.ltrim("\t :").getAsInteger(0, Variant);
     242             : 
     243             :     // Look for the CPU part line, whose value is a 3 digit hexadecimal
     244             :     // number, corresponding to the PartNum bits in the CP15/C0 register.
     245          45 :     for (auto I : Lines)
     246             :       if (I.consume_front("CPU part"))
     247           6 :         I.ltrim("\t :").getAsInteger(0, Part);
     248             : 
     249           3 :     unsigned Exynos = (Variant << 12) | Part;
     250           3 :     switch (Exynos) {
     251             :     default:
     252             :       // Default by falling through to Exynos M1.
     253             :       LLVM_FALLTHROUGH;
     254             : 
     255             :     case 0x1001:
     256           2 :       return "exynos-m1";
     257             : 
     258             :     case 0x4001:
     259           1 :       return "exynos-m2";
     260             :     }
     261             :   }
     262             : 
     263           2 :   return "generic";
     264             : }
     265             : 
     266           0 : StringRef sys::detail::getHostCPUNameForS390x(StringRef ProcCpuinfoContent) {
     267             :   // STIDP is a privileged operation, so use /proc/cpuinfo instead.
     268             : 
     269             :   // The "processor 0:" line comes after a fair amount of other information,
     270             :   // including a cache breakdown, but this should be plenty.
     271             :   SmallVector<StringRef, 32> Lines;
     272           0 :   ProcCpuinfoContent.split(Lines, "\n");
     273             : 
     274             :   // Look for the CPU features.
     275             :   SmallVector<StringRef, 32> CPUFeatures;
     276           0 :   for (unsigned I = 0, E = Lines.size(); I != E; ++I)
     277           0 :     if (Lines[I].startswith("features")) {
     278           0 :       size_t Pos = Lines[I].find(":");
     279           0 :       if (Pos != StringRef::npos) {
     280           0 :         Lines[I].drop_front(Pos + 1).split(CPUFeatures, ' ');
     281           0 :         break;
     282             :       }
     283             :     }
     284             : 
     285             :   // We need to check for the presence of vector support independently of
     286             :   // the machine type, since we may only use the vector register set when
     287             :   // supported by the kernel (and hypervisor).
     288             :   bool HaveVectorSupport = false;
     289           0 :   for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
     290           0 :     if (CPUFeatures[I] == "vx")
     291             :       HaveVectorSupport = true;
     292             :   }
     293             : 
     294             :   // Now check the processor machine type.
     295           0 :   for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
     296           0 :     if (Lines[I].startswith("processor ")) {
     297           0 :       size_t Pos = Lines[I].find("machine = ");
     298           0 :       if (Pos != StringRef::npos) {
     299           0 :         Pos += sizeof("machine = ") - 1;
     300             :         unsigned int Id;
     301           0 :         if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) {
     302           0 :           if (Id >= 3906 && HaveVectorSupport)
     303           0 :             return "z14";
     304           0 :           if (Id >= 2964 && HaveVectorSupport)
     305           0 :             return "z13";
     306           0 :           if (Id >= 2827)
     307           0 :             return "zEC12";
     308           0 :           if (Id >= 2817)
     309           0 :             return "z196";
     310             :         }
     311             :       }
     312             :       break;
     313             :     }
     314             :   }
     315             : 
     316           0 :   return "generic";
     317             : }
     318             : 
     319           0 : StringRef sys::detail::getHostCPUNameForBPF() {
     320             : #if !defined(__linux__) || !defined(__x86_64__)
     321             :   return "generic";
     322             : #else
     323           0 :   uint8_t insns[40] __attribute__ ((aligned (8))) =
     324             :       /* BPF_MOV64_IMM(BPF_REG_0, 0) */
     325             :     { 0xb7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
     326             :       /* BPF_MOV64_IMM(BPF_REG_2, 1) */
     327             :       0xb7, 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
     328             :       /* BPF_JMP_REG(BPF_JLT, BPF_REG_0, BPF_REG_2, 1) */
     329             :       0xad, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
     330             :       /* BPF_MOV64_IMM(BPF_REG_0, 1) */
     331             :       0xb7, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
     332             :       /* BPF_EXIT_INSN() */
     333             :       0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
     334             : 
     335             :   struct bpf_prog_load_attr {
     336             :     uint32_t prog_type;
     337             :     uint32_t insn_cnt;
     338             :     uint64_t insns;
     339             :     uint64_t license;
     340             :     uint32_t log_level;
     341             :     uint32_t log_size;
     342             :     uint64_t log_buf;
     343             :     uint32_t kern_version;
     344             :     uint32_t prog_flags;
     345           0 :   } attr = {};
     346           0 :   attr.prog_type = 1; /* BPF_PROG_TYPE_SOCKET_FILTER */
     347           0 :   attr.insn_cnt = 5;
     348           0 :   attr.insns = (uint64_t)insns;
     349           0 :   attr.license = (uint64_t)"DUMMY";
     350             : 
     351           0 :   int fd = syscall(321 /* __NR_bpf */, 5 /* BPF_PROG_LOAD */, &attr, sizeof(attr));
     352           0 :   if (fd >= 0) {
     353           0 :     close(fd);
     354           0 :     return "v2";
     355             :   }
     356           0 :   return "v1";
     357             : #endif
     358             : }
     359             : 
     360             : #if defined(__i386__) || defined(_M_IX86) || \
     361             :     defined(__x86_64__) || defined(_M_X64)
     362             : 
     363             : enum VendorSignatures {
     364             :   SIG_INTEL = 0x756e6547 /* Genu */,
     365             :   SIG_AMD = 0x68747541 /* Auth */
     366             : };
     367             : 
     368             : // The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
     369             : // Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID
     370             : // support. Consequently, for i386, the presence of CPUID is checked first
     371             : // via the corresponding eflags bit.
     372             : // Removal of cpuid.h header motivated by PR30384
     373             : // Header cpuid.h and method __get_cpuid_max are not used in llvm, clang, openmp
     374             : // or test-suite, but are used in external projects e.g. libstdcxx
     375             : static bool isCpuIdSupported() {
     376             : #if defined(__GNUC__) || defined(__clang__)
     377             : #if defined(__i386__)
     378             :   int __cpuid_supported;
     379             :   __asm__("  pushfl\n"
     380             :           "  popl   %%eax\n"
     381             :           "  movl   %%eax,%%ecx\n"
     382             :           "  xorl   $0x00200000,%%eax\n"
     383             :           "  pushl  %%eax\n"
     384             :           "  popfl\n"
     385             :           "  pushfl\n"
     386             :           "  popl   %%eax\n"
     387             :           "  movl   $0,%0\n"
     388             :           "  cmpl   %%eax,%%ecx\n"
     389             :           "  je     1f\n"
     390             :           "  movl   $1,%0\n"
     391             :           "1:"
     392             :           : "=r"(__cpuid_supported)
     393             :           :
     394             :           : "eax", "ecx");
     395             :   if (!__cpuid_supported)
     396             :     return false;
     397             : #endif
     398             :   return true;
     399             : #endif
     400             :   return true;
     401             : }
     402             : 
     403             : /// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
     404             : /// the specified arguments.  If we can't run cpuid on the host, return true.
     405             : static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
     406             :                                unsigned *rECX, unsigned *rEDX) {
     407             : #if defined(__GNUC__) || defined(__clang__)
     408             : #if defined(__x86_64__)
     409             :   // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
     410             :   // FIXME: should we save this for Clang?
     411             :   __asm__("movq\t%%rbx, %%rsi\n\t"
     412             :           "cpuid\n\t"
     413             :           "xchgq\t%%rbx, %%rsi\n\t"
     414             :           : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
     415         156 :           : "a"(value));
     416             :   return false;
     417             : #elif defined(__i386__)
     418             :   __asm__("movl\t%%ebx, %%esi\n\t"
     419             :           "cpuid\n\t"
     420             :           "xchgl\t%%ebx, %%esi\n\t"
     421             :           : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
     422             :           : "a"(value));
     423             :   return false;
     424             : #else
     425             :   return true;
     426             : #endif
     427             : #elif defined(_MSC_VER)
     428             :   // The MSVC intrinsic is portable across x86 and x64.
     429             :   int registers[4];
     430             :   __cpuid(registers, value);
     431             :   *rEAX = registers[0];
     432             :   *rEBX = registers[1];
     433             :   *rECX = registers[2];
     434             :   *rEDX = registers[3];
     435             :   return false;
     436             : #else
     437             :   return true;
     438             : #endif
     439             : }
     440             : 
     441             : /// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
     442             : /// the 4 values in the specified arguments.  If we can't run cpuid on the host,
     443             : /// return true.
     444             : static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
     445             :                                  unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
     446             :                                  unsigned *rEDX) {
     447             : #if defined(__GNUC__) || defined(__clang__)
     448             : #if defined(__x86_64__)
     449             :   // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
     450             :   // FIXME: should we save this for Clang?
     451             :   __asm__("movq\t%%rbx, %%rsi\n\t"
     452             :           "cpuid\n\t"
     453             :           "xchgq\t%%rbx, %%rsi\n\t"
     454             :           : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
     455          39 :           : "a"(value), "c"(subleaf));
     456             :   return false;
     457             : #elif defined(__i386__)
     458             :   __asm__("movl\t%%ebx, %%esi\n\t"
     459             :           "cpuid\n\t"
     460             :           "xchgl\t%%ebx, %%esi\n\t"
     461             :           : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
     462             :           : "a"(value), "c"(subleaf));
     463             :   return false;
     464             : #else
     465             :   return true;
     466             : #endif
     467             : #elif defined(_MSC_VER)
     468             :   int registers[4];
     469             :   __cpuidex(registers, value, subleaf);
     470             :   *rEAX = registers[0];
     471             :   *rEBX = registers[1];
     472             :   *rECX = registers[2];
     473             :   *rEDX = registers[3];
     474             :   return false;
     475             : #else
     476             :   return true;
     477             : #endif
     478             : }
     479             : 
     480             : // Read control register 0 (XCR0). Used to detect features such as AVX.
     481             : static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {
     482             : #if defined(__GNUC__) || defined(__clang__)
     483             :   // Check xgetbv; this uses a .byte sequence instead of the instruction
     484             :   // directly because older assemblers do not include support for xgetbv and
     485             :   // there is no easy way to conditionally compile based on the assembler used.
     486           0 :   __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0));
     487             :   return false;
     488             : #elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
     489             :   unsigned long long Result = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
     490             :   *rEAX = Result;
     491             :   *rEDX = Result >> 32;
     492             :   return false;
     493             : #else
     494             :   return true;
     495             : #endif
     496             : }
     497             : 
     498          39 : static void detectX86FamilyModel(unsigned EAX, unsigned *Family,
     499             :                                  unsigned *Model) {
     500          39 :   *Family = (EAX >> 8) & 0xf; // Bits 8 - 11
     501          39 :   *Model = (EAX >> 4) & 0xf;  // Bits 4 - 7
     502          39 :   if (*Family == 6 || *Family == 0xf) {
     503          39 :     if (*Family == 0xf)
     504             :       // Examine extended family ID if family ID is F.
     505           0 :       *Family += (EAX >> 20) & 0xff; // Bits 20 - 27
     506             :     // Examine extended model ID if family ID is 6 or F.
     507          39 :     *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
     508             :   }
     509          39 : }
     510             : 
     511             : static void
     512          39 : getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model,
     513             :                                 unsigned Brand_id, unsigned Features,
     514             :                                 unsigned Features2, unsigned *Type,
     515             :                                 unsigned *Subtype) {
     516          39 :   if (Brand_id != 0)
     517             :     return;
     518          39 :   switch (Family) {
     519           0 :   case 3:
     520           0 :     *Type = X86::INTEL_i386;
     521           0 :     break;
     522           0 :   case 4:
     523           0 :     *Type = X86::INTEL_i486;
     524           0 :     break;
     525           0 :   case 5:
     526           0 :     if (Features & (1 << X86::FEATURE_MMX)) {
     527           0 :       *Type = X86::INTEL_PENTIUM_MMX;
     528           0 :       break;
     529             :     }
     530           0 :     *Type = X86::INTEL_PENTIUM;
     531           0 :     break;
     532          39 :   case 6:
     533             :     switch (Model) {
     534           0 :     case 0x01: // Pentium Pro processor
     535           0 :       *Type = X86::INTEL_PENTIUM_PRO;
     536           0 :       break;
     537           0 :     case 0x03: // Intel Pentium II OverDrive processor, Pentium II processor,
     538             :                // model 03
     539             :     case 0x05: // Pentium II processor, model 05, Pentium II Xeon processor,
     540             :                // model 05, and Intel Celeron processor, model 05
     541             :     case 0x06: // Celeron processor, model 06
     542           0 :       *Type = X86::INTEL_PENTIUM_II;
     543           0 :       break;
     544           0 :     case 0x07: // Pentium III processor, model 07, and Pentium III Xeon
     545             :                // processor, model 07
     546             :     case 0x08: // Pentium III processor, model 08, Pentium III Xeon processor,
     547             :                // model 08, and Celeron processor, model 08
     548             :     case 0x0a: // Pentium III Xeon processor, model 0Ah
     549             :     case 0x0b: // Pentium III processor, model 0Bh
     550           0 :       *Type = X86::INTEL_PENTIUM_III;
     551           0 :       break;
     552           0 :     case 0x09: // Intel Pentium M processor, Intel Celeron M processor model 09.
     553             :     case 0x0d: // Intel Pentium M processor, Intel Celeron M processor, model
     554             :                // 0Dh. All processors are manufactured using the 90 nm process.
     555             :     case 0x15: // Intel EP80579 Integrated Processor and Intel EP80579
     556             :                // Integrated Processor with Intel QuickAssist Technology
     557           0 :       *Type = X86::INTEL_PENTIUM_M;
     558           0 :       break;
     559           0 :     case 0x0e: // Intel Core Duo processor, Intel Core Solo processor, model
     560             :                // 0Eh. All processors are manufactured using the 65 nm process.
     561           0 :       *Type = X86::INTEL_CORE_DUO;
     562           0 :       break;   // yonah
     563          39 :     case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile
     564             :                // processor, Intel Core 2 Quad processor, Intel Core 2 Quad
     565             :                // mobile processor, Intel Core 2 Extreme processor, Intel
     566             :                // Pentium Dual-Core processor, Intel Xeon processor, model
     567             :                // 0Fh. All processors are manufactured using the 65 nm process.
     568             :     case 0x16: // Intel Celeron processor model 16h. All processors are
     569             :                // manufactured using the 65 nm process
     570          39 :       *Type = X86::INTEL_CORE2; // "core2"
     571          39 :       *Subtype = X86::INTEL_CORE2_65;
     572          39 :       break;
     573           0 :     case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, model
     574             :                // 17h. All processors are manufactured using the 45 nm process.
     575             :                //
     576             :                // 45nm: Penryn , Wolfdale, Yorkfield (XE)
     577             :     case 0x1d: // Intel Xeon processor MP. All processors are manufactured using
     578             :                // the 45 nm process.
     579           0 :       *Type = X86::INTEL_CORE2; // "penryn"
     580           0 :       *Subtype = X86::INTEL_CORE2_45;
     581           0 :       break;
     582           0 :     case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All
     583             :                // processors are manufactured using the 45 nm process.
     584             :     case 0x1e: // Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz.
     585             :                // As found in a Summer 2010 model iMac.
     586             :     case 0x1f:
     587             :     case 0x2e:             // Nehalem EX
     588           0 :       *Type = X86::INTEL_COREI7; // "nehalem"
     589           0 :       *Subtype = X86::INTEL_COREI7_NEHALEM;
     590           0 :       break;
     591           0 :     case 0x25: // Intel Core i7, laptop version.
     592             :     case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All
     593             :                // processors are manufactured using the 32 nm process.
     594             :     case 0x2f: // Westmere EX
     595           0 :       *Type = X86::INTEL_COREI7; // "westmere"
     596           0 :       *Subtype = X86::INTEL_COREI7_WESTMERE;
     597           0 :       break;
     598           0 :     case 0x2a: // Intel Core i7 processor. All processors are manufactured
     599             :                // using the 32 nm process.
     600             :     case 0x2d:
     601           0 :       *Type = X86::INTEL_COREI7; //"sandybridge"
     602           0 :       *Subtype = X86::INTEL_COREI7_SANDYBRIDGE;
     603           0 :       break;
     604           0 :     case 0x3a:
     605             :     case 0x3e:             // Ivy Bridge EP
     606           0 :       *Type = X86::INTEL_COREI7; // "ivybridge"
     607           0 :       *Subtype = X86::INTEL_COREI7_IVYBRIDGE;
     608           0 :       break;
     609             : 
     610             :     // Haswell:
     611           0 :     case 0x3c:
     612             :     case 0x3f:
     613             :     case 0x45:
     614             :     case 0x46:
     615           0 :       *Type = X86::INTEL_COREI7; // "haswell"
     616           0 :       *Subtype = X86::INTEL_COREI7_HASWELL;
     617           0 :       break;
     618             : 
     619             :     // Broadwell:
     620           0 :     case 0x3d:
     621             :     case 0x47:
     622             :     case 0x4f:
     623             :     case 0x56:
     624           0 :       *Type = X86::INTEL_COREI7; // "broadwell"
     625           0 :       *Subtype = X86::INTEL_COREI7_BROADWELL;
     626           0 :       break;
     627             : 
     628             :     // Skylake:
     629           0 :     case 0x4e: // Skylake mobile
     630             :     case 0x5e: // Skylake desktop
     631             :     case 0x8e: // Kaby Lake mobile
     632             :     case 0x9e: // Kaby Lake desktop
     633           0 :       *Type = X86::INTEL_COREI7; // "skylake"
     634           0 :       *Subtype = X86::INTEL_COREI7_SKYLAKE;
     635           0 :       break;
     636             : 
     637             :     // Skylake Xeon:
     638           0 :     case 0x55:
     639           0 :       *Type = X86::INTEL_COREI7;
     640           0 :       *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512; // "skylake-avx512"
     641           0 :       break;
     642             : 
     643             :     // Cannonlake:
     644           0 :     case 0x66:
     645           0 :       *Type = X86::INTEL_COREI7;
     646           0 :       *Subtype = X86::INTEL_COREI7_CANNONLAKE; // "cannonlake"
     647           0 :       break;
     648             : 
     649           0 :     case 0x1c: // Most 45 nm Intel Atom processors
     650             :     case 0x26: // 45 nm Atom Lincroft
     651             :     case 0x27: // 32 nm Atom Medfield
     652             :     case 0x35: // 32 nm Atom Midview
     653             :     case 0x36: // 32 nm Atom Midview
     654           0 :       *Type = X86::INTEL_BONNELL;
     655           0 :       break; // "bonnell"
     656             : 
     657             :     // Atom Silvermont codes from the Intel software optimization guide.
     658           0 :     case 0x37:
     659             :     case 0x4a:
     660             :     case 0x4d:
     661             :     case 0x5a:
     662             :     case 0x5d:
     663             :     case 0x4c: // really airmont
     664           0 :       *Type = X86::INTEL_SILVERMONT;
     665           0 :       break; // "silvermont"
     666             :     // Goldmont:
     667           0 :     case 0x5c: // Apollo Lake
     668             :     case 0x5f: // Denverton
     669           0 :       *Type = X86::INTEL_GOLDMONT;
     670           0 :       break; // "goldmont"
     671           0 :     case 0x7a:
     672           0 :       *Type = X86::INTEL_GOLDMONT_PLUS;
     673           0 :       break;
     674           0 :     case 0x57:
     675           0 :       *Type = X86::INTEL_KNL; // knl
     676           0 :       break;
     677           0 :     case 0x85:
     678           0 :       *Type = X86::INTEL_KNM; // knm
     679           0 :       break;
     680             : 
     681           0 :     default: // Unknown family 6 CPU, try to guess.
     682           0 :       if (Features & (1 << X86::FEATURE_AVX512VBMI)) {
     683           0 :         *Type = X86::INTEL_COREI7;
     684           0 :         *Subtype = X86::INTEL_COREI7_CANNONLAKE;
     685           0 :         break;
     686             :       }
     687             : 
     688           0 :       if (Features & (1 << X86::FEATURE_AVX512VL)) {
     689           0 :         *Type = X86::INTEL_COREI7;
     690           0 :         *Subtype = X86::INTEL_COREI7_SKYLAKE_AVX512;
     691           0 :         break;
     692             :       }
     693             : 
     694           0 :       if (Features & (1 << X86::FEATURE_AVX512ER)) {
     695           0 :         *Type = X86::INTEL_KNL; // knl
     696           0 :         break;
     697             :       }
     698             : 
     699           0 :       if (Features2 & (1 << (X86::FEATURE_CLFLUSHOPT - 32))) {
     700           0 :         if (Features2 & (1 << (X86::FEATURE_SHA - 32))) {
     701           0 :           *Type = X86::INTEL_GOLDMONT;
     702             :         } else {
     703           0 :           *Type = X86::INTEL_COREI7;
     704           0 :           *Subtype = X86::INTEL_COREI7_SKYLAKE;
     705             :         }
     706             :         break;
     707             :       }
     708           0 :       if (Features2 & (1 << (X86::FEATURE_ADX - 32))) {
     709           0 :         *Type = X86::INTEL_COREI7;
     710           0 :         *Subtype = X86::INTEL_COREI7_BROADWELL;
     711           0 :         break;
     712             :       }
     713           0 :       if (Features & (1 << X86::FEATURE_AVX2)) {
     714           0 :         *Type = X86::INTEL_COREI7;
     715           0 :         *Subtype = X86::INTEL_COREI7_HASWELL;
     716           0 :         break;
     717             :       }
     718           0 :       if (Features & (1 << X86::FEATURE_AVX)) {
     719           0 :         *Type = X86::INTEL_COREI7;
     720           0 :         *Subtype = X86::INTEL_COREI7_SANDYBRIDGE;
     721           0 :         break;
     722             :       }
     723           0 :       if (Features & (1 << X86::FEATURE_SSE4_2)) {
     724           0 :         if (Features2 & (1 << (X86::FEATURE_MOVBE - 32))) {
     725           0 :           *Type = X86::INTEL_SILVERMONT;
     726             :         } else {
     727           0 :           *Type = X86::INTEL_COREI7;
     728           0 :           *Subtype = X86::INTEL_COREI7_NEHALEM;
     729             :         }
     730             :         break;
     731             :       }
     732           0 :       if (Features & (1 << X86::FEATURE_SSE4_1)) {
     733           0 :         *Type = X86::INTEL_CORE2; // "penryn"
     734           0 :         *Subtype = X86::INTEL_CORE2_45;
     735           0 :         break;
     736             :       }
     737           0 :       if (Features & (1 << X86::FEATURE_SSSE3)) {
     738           0 :         if (Features2 & (1 << (X86::FEATURE_MOVBE - 32))) {
     739           0 :           *Type = X86::INTEL_BONNELL; // "bonnell"
     740             :         } else {
     741           0 :           *Type = X86::INTEL_CORE2; // "core2"
     742           0 :           *Subtype = X86::INTEL_CORE2_65;
     743             :         }
     744             :         break;
     745             :       }
     746           0 :       if (Features2 & (1 << (X86::FEATURE_EM64T - 32))) {
     747           0 :         *Type = X86::INTEL_CORE2; // "core2"
     748           0 :         *Subtype = X86::INTEL_CORE2_65;
     749           0 :         break;
     750             :       }
     751           0 :       if (Features & (1 << X86::FEATURE_SSE3)) {
     752           0 :         *Type = X86::INTEL_CORE_DUO;
     753           0 :         break;
     754             :       }
     755           0 :       if (Features & (1 << X86::FEATURE_SSE2)) {
     756           0 :         *Type = X86::INTEL_PENTIUM_M;
     757           0 :         break;
     758             :       }
     759           0 :       if (Features & (1 << X86::FEATURE_SSE)) {
     760           0 :         *Type = X86::INTEL_PENTIUM_III;
     761           0 :         break;
     762             :       }
     763           0 :       if (Features & (1 << X86::FEATURE_MMX)) {
     764           0 :         *Type = X86::INTEL_PENTIUM_II;
     765           0 :         break;
     766             :       }
     767           0 :       *Type = X86::INTEL_PENTIUM_PRO;
     768           0 :       break;
     769             :     }
     770             :     break;
     771           0 :   case 15: {
     772           0 :     if (Features2 & (1 << (X86::FEATURE_EM64T - 32))) {
     773           0 :       *Type = X86::INTEL_NOCONA;
     774           0 :       break;
     775             :     }
     776           0 :     if (Features & (1 << X86::FEATURE_SSE3)) {
     777           0 :       *Type = X86::INTEL_PRESCOTT;
     778           0 :       break;
     779             :     }
     780           0 :     *Type = X86::INTEL_PENTIUM_IV;
     781           0 :     break;
     782             :   }
     783             :   default:
     784             :     break; /*"generic"*/
     785             :   }
     786             : }
     787             : 
     788           0 : static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model,
     789             :                                           unsigned Features, unsigned *Type,
     790             :                                           unsigned *Subtype) {
     791             :   // FIXME: this poorly matches the generated SubtargetFeatureKV table.  There
     792             :   // appears to be no way to generate the wide variety of AMD-specific targets
     793             :   // from the information returned from CPUID.
     794           0 :   switch (Family) {
     795           0 :   case 4:
     796           0 :     *Type = X86::AMD_i486;
     797           0 :     break;
     798           0 :   case 5:
     799           0 :     *Type = X86::AMDPENTIUM;
     800             :     switch (Model) {
     801           0 :     case 6:
     802             :     case 7:
     803           0 :       *Subtype = X86::AMDPENTIUM_K6;
     804           0 :       break; // "k6"
     805           0 :     case 8:
     806           0 :       *Subtype = X86::AMDPENTIUM_K62;
     807           0 :       break; // "k6-2"
     808           0 :     case 9:
     809             :     case 13:
     810           0 :       *Subtype = X86::AMDPENTIUM_K63;
     811           0 :       break; // "k6-3"
     812           0 :     case 10:
     813           0 :       *Subtype = X86::AMDPENTIUM_GEODE;
     814           0 :       break; // "geode"
     815             :     }
     816             :     break;
     817           0 :   case 6:
     818           0 :     if (Features & (1 << X86::FEATURE_SSE)) {
     819           0 :       *Type = X86::AMD_ATHLON_XP;
     820           0 :       break; // "athlon-xp"
     821             :     }
     822           0 :     *Type = X86::AMD_ATHLON;
     823           0 :     break; // "athlon"
     824           0 :   case 15:
     825           0 :     if (Features & (1 << X86::FEATURE_SSE3)) {
     826           0 :       *Type = X86::AMD_K8SSE3;
     827           0 :       break; // "k8-sse3"
     828             :     }
     829           0 :     *Type = X86::AMD_K8;
     830           0 :     break; // "k8"
     831           0 :   case 16:
     832           0 :     *Type = X86::AMDFAM10H; // "amdfam10"
     833             :     switch (Model) {
     834           0 :     case 2:
     835           0 :       *Subtype = X86::AMDFAM10H_BARCELONA;
     836           0 :       break;
     837           0 :     case 4:
     838           0 :       *Subtype = X86::AMDFAM10H_SHANGHAI;
     839           0 :       break;
     840           0 :     case 8:
     841           0 :       *Subtype = X86::AMDFAM10H_ISTANBUL;
     842           0 :       break;
     843             :     }
     844             :     break;
     845           0 :   case 20:
     846           0 :     *Type = X86::AMD_BTVER1;
     847           0 :     break; // "btver1";
     848           0 :   case 21:
     849           0 :     *Type = X86::AMDFAM15H;
     850           0 :     if (Model >= 0x60 && Model <= 0x7f) {
     851           0 :       *Subtype = X86::AMDFAM15H_BDVER4;
     852           0 :       break; // "bdver4"; 60h-7Fh: Excavator
     853             :     }
     854           0 :     if (Model >= 0x30 && Model <= 0x3f) {
     855           0 :       *Subtype = X86::AMDFAM15H_BDVER3;
     856           0 :       break; // "bdver3"; 30h-3Fh: Steamroller
     857             :     }
     858           0 :     if ((Model >= 0x10 && Model <= 0x1f) || Model == 0x02) {
     859           0 :       *Subtype = X86::AMDFAM15H_BDVER2;
     860           0 :       break; // "bdver2"; 02h, 10h-1Fh: Piledriver
     861             :     }
     862           0 :     if (Model <= 0x0f) {
     863           0 :       *Subtype = X86::AMDFAM15H_BDVER1;
     864           0 :       break; // "bdver1"; 00h-0Fh: Bulldozer
     865             :     }
     866             :     break;
     867           0 :   case 22:
     868           0 :     *Type = X86::AMD_BTVER2;
     869           0 :     break; // "btver2"
     870           0 :   case 23:
     871           0 :     *Type = X86::AMDFAM17H;
     872           0 :     *Subtype = X86::AMDFAM17H_ZNVER1;
     873           0 :     break;
     874             :   default:
     875             :     break; // "generic"
     876             :   }
     877           0 : }
     878             : 
     879          39 : static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
     880             :                                  unsigned *FeaturesOut,
     881             :                                  unsigned *Features2Out) {
     882             :   unsigned Features = 0;
     883             :   unsigned Features2 = 0;
     884             :   unsigned EAX, EBX;
     885             : 
     886          39 :   if ((EDX >> 15) & 1)
     887             :     Features |= 1 << X86::FEATURE_CMOV;
     888          39 :   if ((EDX >> 23) & 1)
     889          39 :     Features |= 1 << X86::FEATURE_MMX;
     890          39 :   if ((EDX >> 25) & 1)
     891          39 :     Features |= 1 << X86::FEATURE_SSE;
     892          39 :   if ((EDX >> 26) & 1)
     893          39 :     Features |= 1 << X86::FEATURE_SSE2;
     894             : 
     895          39 :   if ((ECX >> 0) & 1)
     896          39 :     Features |= 1 << X86::FEATURE_SSE3;
     897          39 :   if ((ECX >> 1) & 1)
     898           0 :     Features |= 1 << X86::FEATURE_PCLMUL;
     899          39 :   if ((ECX >> 9) & 1)
     900          39 :     Features |= 1 << X86::FEATURE_SSSE3;
     901          39 :   if ((ECX >> 12) & 1)
     902           0 :     Features |= 1 << X86::FEATURE_FMA;
     903          39 :   if ((ECX >> 19) & 1)
     904           0 :     Features |= 1 << X86::FEATURE_SSE4_1;
     905          39 :   if ((ECX >> 20) & 1)
     906           0 :     Features |= 1 << X86::FEATURE_SSE4_2;
     907          39 :   if ((ECX >> 23) & 1)
     908           0 :     Features |= 1 << X86::FEATURE_POPCNT;
     909          39 :   if ((ECX >> 25) & 1)
     910           0 :     Features |= 1 << X86::FEATURE_AES;
     911             : 
     912          39 :   if ((ECX >> 22) & 1)
     913             :     Features2 |= 1 << (X86::FEATURE_MOVBE - 32);
     914             : 
     915             :   // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
     916             :   // indicates that the AVX registers will be saved and restored on context
     917             :   // switch, then we have full AVX support.
     918             :   const unsigned AVXBits = (1 << 27) | (1 << 28);
     919          39 :   bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) &&
     920           0 :                 ((EAX & 0x6) == 0x6);
     921          39 :   bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
     922             : 
     923          39 :   if (HasAVX)
     924           0 :     Features |= 1 << X86::FEATURE_AVX;
     925             : 
     926             :   bool HasLeaf7 =
     927          39 :       MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
     928             : 
     929          39 :   if (HasLeaf7 && ((EBX >> 3) & 1))
     930           0 :     Features |= 1 << X86::FEATURE_BMI;
     931          39 :   if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX)
     932           0 :     Features |= 1 << X86::FEATURE_AVX2;
     933          39 :   if (HasLeaf7 && ((EBX >> 9) & 1))
     934           0 :     Features |= 1 << X86::FEATURE_BMI2;
     935          39 :   if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save)
     936           0 :     Features |= 1 << X86::FEATURE_AVX512F;
     937          39 :   if (HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save)
     938           0 :     Features |= 1 << X86::FEATURE_AVX512DQ;
     939          39 :   if (HasLeaf7 && ((EBX >> 19) & 1))
     940           0 :     Features2 |= 1 << (X86::FEATURE_ADX - 32);
     941          39 :   if (HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save)
     942           0 :     Features |= 1 << X86::FEATURE_AVX512IFMA;
     943          39 :   if (HasLeaf7 && ((EBX >> 23) & 1))
     944           0 :     Features2 |= 1 << (X86::FEATURE_CLFLUSHOPT - 32);
     945          39 :   if (HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save)
     946           0 :     Features |= 1 << X86::FEATURE_AVX512PF;
     947          39 :   if (HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save)
     948           0 :     Features |= 1 << X86::FEATURE_AVX512ER;
     949          39 :   if (HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save)
     950           0 :     Features |= 1 << X86::FEATURE_AVX512CD;
     951          39 :   if (HasLeaf7 && ((EBX >> 29) & 1))
     952           0 :     Features2 |= 1 << (X86::FEATURE_SHA - 32);
     953          39 :   if (HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save)
     954           0 :     Features |= 1 << X86::FEATURE_AVX512BW;
     955          39 :   if (HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save)
     956           0 :     Features |= 1 << X86::FEATURE_AVX512VL;
     957             : 
     958          39 :   if (HasLeaf7 && ((ECX >> 1) & 1) && HasAVX512Save)
     959           0 :     Features |= 1 << X86::FEATURE_AVX512VBMI;
     960          39 :   if (HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save)
     961           0 :     Features |= 1 << X86::FEATURE_AVX512VPOPCNTDQ;
     962             : 
     963          39 :   if (HasLeaf7 && ((EDX >> 2) & 1) && HasAVX512Save)
     964           0 :     Features |= 1 << X86::FEATURE_AVX5124VNNIW;
     965          39 :   if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save)
     966           0 :     Features |= 1 << X86::FEATURE_AVX5124FMAPS;
     967             : 
     968             :   unsigned MaxExtLevel;
     969             :   getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
     970             : 
     971          39 :   bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
     972             :                      !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
     973          39 :   if (HasExtLeaf1 && ((ECX >> 6) & 1))
     974           0 :     Features |= 1 << X86::FEATURE_SSE4_A;
     975          39 :   if (HasExtLeaf1 && ((ECX >> 11) & 1))
     976           0 :     Features |= 1 << X86::FEATURE_XOP;
     977          39 :   if (HasExtLeaf1 && ((ECX >> 16) & 1))
     978           0 :     Features |= 1 << X86::FEATURE_FMA4;
     979             : 
     980          39 :   if (HasExtLeaf1 && ((EDX >> 29) & 1))
     981          39 :     Features2 |= 1 << (X86::FEATURE_EM64T - 32);
     982             : 
     983          39 :   *FeaturesOut  = Features;
     984          39 :   *Features2Out = Features2;
     985          39 : }
     986             : 
     987          39 : StringRef sys::getHostCPUName() {
     988             :   unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
     989             :   unsigned MaxLeaf, Vendor;
     990             : 
     991             : #if defined(__GNUC__) || defined(__clang__)
     992             :   //FIXME: include cpuid.h from clang or copy __get_cpuid_max here
     993             :   // and simplify it to not invoke __cpuid (like cpu_model.c in
     994             :   // compiler-rt/lib/builtins/cpu_model.c?
     995             :   // Opting for the second option.
     996             :   if(!isCpuIdSupported())
     997             :     return "generic";
     998             : #endif
     999          39 :   if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX) || MaxLeaf < 1)
    1000           0 :     return "generic";
    1001             :   getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
    1002             : 
    1003          39 :   unsigned Brand_id = EBX & 0xff;
    1004          39 :   unsigned Family = 0, Model = 0;
    1005          39 :   unsigned Features = 0, Features2 = 0;
    1006          39 :   detectX86FamilyModel(EAX, &Family, &Model);
    1007          39 :   getAvailableFeatures(ECX, EDX, MaxLeaf, &Features, &Features2);
    1008             : 
    1009          39 :   unsigned Type = 0;
    1010          39 :   unsigned Subtype = 0;
    1011             : 
    1012          39 :   if (Vendor == SIG_INTEL) {
    1013          39 :     getIntelProcessorTypeAndSubtype(Family, Model, Brand_id, Features,
    1014             :                                     Features2, &Type, &Subtype);
    1015           0 :   } else if (Vendor == SIG_AMD) {
    1016           0 :     getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type, &Subtype);
    1017             :   }
    1018             : 
    1019             :   // Check subtypes first since those are more specific.
    1020             : #define X86_CPU_SUBTYPE(ARCHNAME, ENUM) \
    1021             :   if (Subtype == X86::ENUM) \
    1022             :     return ARCHNAME;
    1023             : #include "llvm/Support/X86TargetParser.def"
    1024             : 
    1025             :   // Now check types.
    1026             : #define X86_CPU_TYPE(ARCHNAME, ENUM) \
    1027             :   if (Type == X86::ENUM) \
    1028             :     return ARCHNAME;
    1029             : #include "llvm/Support/X86TargetParser.def"
    1030             : 
    1031           0 :   return "generic";
    1032             : }
    1033             : 
    1034             : #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__))
    1035             : StringRef sys::getHostCPUName() {
    1036             :   host_basic_info_data_t hostInfo;
    1037             :   mach_msg_type_number_t infoCount;
    1038             : 
    1039             :   infoCount = HOST_BASIC_INFO_COUNT;
    1040             :   mach_port_t hostPort = mach_host_self();
    1041             :   host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo,
    1042             :             &infoCount);
    1043             :   mach_port_deallocate(mach_task_self(), hostPort);
    1044             : 
    1045             :   if (hostInfo.cpu_type != CPU_TYPE_POWERPC)
    1046             :     return "generic";
    1047             : 
    1048             :   switch (hostInfo.cpu_subtype) {
    1049             :   case CPU_SUBTYPE_POWERPC_601:
    1050             :     return "601";
    1051             :   case CPU_SUBTYPE_POWERPC_602:
    1052             :     return "602";
    1053             :   case CPU_SUBTYPE_POWERPC_603:
    1054             :     return "603";
    1055             :   case CPU_SUBTYPE_POWERPC_603e:
    1056             :     return "603e";
    1057             :   case CPU_SUBTYPE_POWERPC_603ev:
    1058             :     return "603ev";
    1059             :   case CPU_SUBTYPE_POWERPC_604:
    1060             :     return "604";
    1061             :   case CPU_SUBTYPE_POWERPC_604e:
    1062             :     return "604e";
    1063             :   case CPU_SUBTYPE_POWERPC_620:
    1064             :     return "620";
    1065             :   case CPU_SUBTYPE_POWERPC_750:
    1066             :     return "750";
    1067             :   case CPU_SUBTYPE_POWERPC_7400:
    1068             :     return "7400";
    1069             :   case CPU_SUBTYPE_POWERPC_7450:
    1070             :     return "7450";
    1071             :   case CPU_SUBTYPE_POWERPC_970:
    1072             :     return "970";
    1073             :   default:;
    1074             :   }
    1075             : 
    1076             :   return "generic";
    1077             : }
    1078             : #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
    1079             : StringRef sys::getHostCPUName() {
    1080             :   std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
    1081             :   StringRef Content = P ? P->getBuffer() : "";
    1082             :   return detail::getHostCPUNameForPowerPC(Content);
    1083             : }
    1084             : #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
    1085             : StringRef sys::getHostCPUName() {
    1086             :   std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
    1087             :   StringRef Content = P ? P->getBuffer() : "";
    1088             :   return detail::getHostCPUNameForARM(Content);
    1089             : }
    1090             : #elif defined(__linux__) && defined(__s390x__)
    1091             : StringRef sys::getHostCPUName() {
    1092             :   std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
    1093             :   StringRef Content = P ? P->getBuffer() : "";
    1094             :   return detail::getHostCPUNameForS390x(Content);
    1095             : }
    1096             : #else
    1097             : StringRef sys::getHostCPUName() { return "generic"; }
    1098             : #endif
    1099             : 
    1100             : #if defined(__linux__) && defined(__x86_64__)
    1101             : // On Linux, the number of physical cores can be computed from /proc/cpuinfo,
    1102             : // using the number of unique physical/core id pairs. The following
    1103             : // implementation reads the /proc/cpuinfo format on an x86_64 system.
    1104      113936 : static int computeHostNumPhysicalCores() {
    1105             :   // Read /proc/cpuinfo as a stream (until EOF reached). It cannot be
    1106             :   // mmapped because it appears to have 0 size.
    1107             :   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
    1108      113936 :       llvm::MemoryBuffer::getFileAsStream("/proc/cpuinfo");
    1109      113936 :   if (std::error_code EC = Text.getError()) {
    1110           0 :     llvm::errs() << "Can't read "
    1111           0 :                  << "/proc/cpuinfo: " << EC.message() << "\n";
    1112             :     return -1;
    1113             :   }
    1114             :   SmallVector<StringRef, 8> strs;
    1115      227872 :   (*Text)->getBuffer().split(strs, "\n", /*MaxSplit=*/-1,
    1116             :                              /*KeepEmpty=*/false);
    1117             :   int CurPhysicalId = -1;
    1118             :   int CurCoreId = -1;
    1119      113936 :   SmallSet<std::pair<int, int>, 32> UniqueItems;
    1120    23812624 :   for (auto &Line : strs) {
    1121    23698688 :     Line = Line.trim();
    1122             :     if (!Line.startswith("physical id") && !Line.startswith("core id"))
    1123    21875712 :       continue;
    1124     1822976 :     std::pair<StringRef, StringRef> Data = Line.split(':');
    1125     1822976 :     auto Name = Data.first.trim();
    1126     1822976 :     auto Val = Data.second.trim();
    1127             :     if (Name == "physical id") {
    1128             :       assert(CurPhysicalId == -1 &&
    1129             :              "Expected a core id before seeing another physical id");
    1130      911488 :       Val.getAsInteger(10, CurPhysicalId);
    1131             :     }
    1132             :     if (Name == "core id") {
    1133             :       assert(CurCoreId == -1 &&
    1134             :              "Expected a physical id before seeing another core id");
    1135      911488 :       Val.getAsInteger(10, CurCoreId);
    1136             :     }
    1137     1822976 :     if (CurPhysicalId != -1 && CurCoreId != -1) {
    1138      911488 :       UniqueItems.insert(std::make_pair(CurPhysicalId, CurCoreId));
    1139             :       CurPhysicalId = -1;
    1140             :       CurCoreId = -1;
    1141             :     }
    1142             :   }
    1143      113936 :   return UniqueItems.size();
    1144             : }
    1145             : #elif defined(__APPLE__) && defined(__x86_64__)
    1146             : #include <sys/param.h>
    1147             : #include <sys/sysctl.h>
    1148             : 
    1149             : // Gets the number of *physical cores* on the machine.
    1150             : static int computeHostNumPhysicalCores() {
    1151             :   uint32_t count;
    1152             :   size_t len = sizeof(count);
    1153             :   sysctlbyname("hw.physicalcpu", &count, &len, NULL, 0);
    1154             :   if (count < 1) {
    1155             :     int nm[2];
    1156             :     nm[0] = CTL_HW;
    1157             :     nm[1] = HW_AVAILCPU;
    1158             :     sysctl(nm, 2, &count, &len, NULL, 0);
    1159             :     if (count < 1)
    1160             :       return -1;
    1161             :   }
    1162             :   return count;
    1163             : }
    1164             : #else
    1165             : // On other systems, return -1 to indicate unknown.
    1166             : static int computeHostNumPhysicalCores() { return -1; }
    1167             : #endif
    1168             : 
    1169      114484 : int sys::getHostNumPhysicalCores() {
    1170      114484 :   static int NumCores = computeHostNumPhysicalCores();
    1171      114484 :   return NumCores;
    1172             : }
    1173             : 
    1174             : #if defined(__i386__) || defined(_M_IX86) || \
    1175             :     defined(__x86_64__) || defined(_M_X64)
    1176           0 : bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
    1177             :   unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
    1178             :   unsigned MaxLevel;
    1179             :   union {
    1180             :     unsigned u[3];
    1181             :     char c[12];
    1182             :   } text;
    1183             : 
    1184           0 :   if (getX86CpuIDAndInfo(0, &MaxLevel, text.u + 0, text.u + 2, text.u + 1) ||
    1185             :       MaxLevel < 1)
    1186             :     return false;
    1187             : 
    1188             :   getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX);
    1189             : 
    1190           0 :   Features["cmov"]   = (EDX >> 15) & 1;
    1191           0 :   Features["mmx"]    = (EDX >> 23) & 1;
    1192           0 :   Features["sse"]    = (EDX >> 25) & 1;
    1193           0 :   Features["sse2"]   = (EDX >> 26) & 1;
    1194             : 
    1195           0 :   Features["sse3"]   = (ECX >>  0) & 1;
    1196           0 :   Features["pclmul"] = (ECX >>  1) & 1;
    1197           0 :   Features["ssse3"]  = (ECX >>  9) & 1;
    1198           0 :   Features["cx16"]   = (ECX >> 13) & 1;
    1199           0 :   Features["sse4.1"] = (ECX >> 19) & 1;
    1200           0 :   Features["sse4.2"] = (ECX >> 20) & 1;
    1201           0 :   Features["movbe"]  = (ECX >> 22) & 1;
    1202           0 :   Features["popcnt"] = (ECX >> 23) & 1;
    1203           0 :   Features["aes"]    = (ECX >> 25) & 1;
    1204           0 :   Features["rdrnd"]  = (ECX >> 30) & 1;
    1205             : 
    1206             :   // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
    1207             :   // indicates that the AVX registers will be saved and restored on context
    1208             :   // switch, then we have full AVX support.
    1209           0 :   bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
    1210           0 :                     !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
    1211             :   // AVX512 requires additional context to be saved by the OS.
    1212           0 :   bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);
    1213             : 
    1214           0 :   Features["avx"]   = HasAVXSave;
    1215           0 :   Features["fma"]   = ((ECX >> 12) & 1) && HasAVXSave;
    1216             :   // Only enable XSAVE if OS has enabled support for saving YMM state.
    1217           0 :   Features["xsave"] = ((ECX >> 26) & 1) && HasAVXSave;
    1218           0 :   Features["f16c"]  = ((ECX >> 29) & 1) && HasAVXSave;
    1219             : 
    1220             :   unsigned MaxExtLevel;
    1221             :   getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
    1222             : 
    1223           0 :   bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 &&
    1224             :                      !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX);
    1225           0 :   Features["sahf"]   = HasExtLeaf1 && ((ECX >>  0) & 1);
    1226           0 :   Features["lzcnt"]  = HasExtLeaf1 && ((ECX >>  5) & 1);
    1227           0 :   Features["sse4a"]  = HasExtLeaf1 && ((ECX >>  6) & 1);
    1228           0 :   Features["prfchw"] = HasExtLeaf1 && ((ECX >>  8) & 1);
    1229           0 :   Features["xop"]    = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
    1230           0 :   Features["lwp"]    = HasExtLeaf1 && ((ECX >> 15) & 1);
    1231           0 :   Features["fma4"]   = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
    1232           0 :   Features["tbm"]    = HasExtLeaf1 && ((ECX >> 21) & 1);
    1233           0 :   Features["mwaitx"] = HasExtLeaf1 && ((ECX >> 29) & 1);
    1234             : 
    1235           0 :   Features["64bit"]  = HasExtLeaf1 && ((EDX >> 29) & 1);
    1236             : 
    1237             :   // Miscellaneous memory related features, detected by
    1238             :   // using the 0x80000008 leaf of the CPUID instruction
    1239           0 :   bool HasExtLeaf8 = MaxExtLevel >= 0x80000008 &&
    1240             :                      !getX86CpuIDAndInfo(0x80000008, &EAX, &EBX, &ECX, &EDX);
    1241           0 :   Features["clzero"]   = HasExtLeaf8 && ((EBX >> 0) & 1);
    1242           0 :   Features["wbnoinvd"] = HasExtLeaf8 && ((EBX >> 9) & 1);
    1243             : 
    1244             :   bool HasLeaf7 =
    1245           0 :       MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);
    1246             : 
    1247           0 :   Features["fsgsbase"]   = HasLeaf7 && ((EBX >>  0) & 1);
    1248           0 :   Features["sgx"]        = HasLeaf7 && ((EBX >>  2) & 1);
    1249           0 :   Features["bmi"]        = HasLeaf7 && ((EBX >>  3) & 1);
    1250             :   // AVX2 is only supported if we have the OS save support from AVX.
    1251           0 :   Features["avx2"]       = HasLeaf7 && ((EBX >>  5) & 1) && HasAVXSave;
    1252           0 :   Features["bmi2"]       = HasLeaf7 && ((EBX >>  8) & 1);
    1253           0 :   Features["invpcid"]    = HasLeaf7 && ((EBX >> 10) & 1);
    1254           0 :   Features["rtm"]        = HasLeaf7 && ((EBX >> 11) & 1);
    1255             :   // AVX512 is only supported if the OS supports the context save for it.
    1256           0 :   Features["avx512f"]    = HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save;
    1257           0 :   Features["avx512dq"]   = HasLeaf7 && ((EBX >> 17) & 1) && HasAVX512Save;
    1258           0 :   Features["rdseed"]     = HasLeaf7 && ((EBX >> 18) & 1);
    1259           0 :   Features["adx"]        = HasLeaf7 && ((EBX >> 19) & 1);
    1260           0 :   Features["avx512ifma"] = HasLeaf7 && ((EBX >> 21) & 1) && HasAVX512Save;
    1261           0 :   Features["clflushopt"] = HasLeaf7 && ((EBX >> 23) & 1);
    1262           0 :   Features["clwb"]       = HasLeaf7 && ((EBX >> 24) & 1);
    1263           0 :   Features["avx512pf"]   = HasLeaf7 && ((EBX >> 26) & 1) && HasAVX512Save;
    1264           0 :   Features["avx512er"]   = HasLeaf7 && ((EBX >> 27) & 1) && HasAVX512Save;
    1265           0 :   Features["avx512cd"]   = HasLeaf7 && ((EBX >> 28) & 1) && HasAVX512Save;
    1266           0 :   Features["sha"]        = HasLeaf7 && ((EBX >> 29) & 1);
    1267           0 :   Features["avx512bw"]   = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
    1268           0 :   Features["avx512vl"]   = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;
    1269             : 
    1270           0 :   Features["prefetchwt1"]     = HasLeaf7 && ((ECX >>  0) & 1);
    1271           0 :   Features["avx512vbmi"]      = HasLeaf7 && ((ECX >>  1) & 1) && HasAVX512Save;
    1272           0 :   Features["pku"]             = HasLeaf7 && ((ECX >>  4) & 1);
    1273           0 :   Features["waitpkg"]         = HasLeaf7 && ((ECX >>  5) & 1);
    1274           0 :   Features["avx512vbmi2"]     = HasLeaf7 && ((ECX >>  6) & 1) && HasAVX512Save;
    1275           0 :   Features["shstk"]           = HasLeaf7 && ((ECX >>  7) & 1);
    1276           0 :   Features["gfni"]            = HasLeaf7 && ((ECX >>  8) & 1);
    1277           0 :   Features["vaes"]            = HasLeaf7 && ((ECX >>  9) & 1) && HasAVXSave;
    1278           0 :   Features["vpclmulqdq"]      = HasLeaf7 && ((ECX >> 10) & 1) && HasAVXSave;
    1279           0 :   Features["avx512vnni"]      = HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save;
    1280           0 :   Features["avx512bitalg"]    = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save;
    1281           0 :   Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save;
    1282           0 :   Features["rdpid"]           = HasLeaf7 && ((ECX >> 22) & 1);
    1283           0 :   Features["cldemote"]        = HasLeaf7 && ((ECX >> 25) & 1);
    1284           0 :   Features["movdiri"]         = HasLeaf7 && ((ECX >> 27) & 1);
    1285           0 :   Features["movdir64b"]       = HasLeaf7 && ((ECX >> 28) & 1);
    1286             : 
    1287             :   // There are two CPUID leafs which information associated with the pconfig
    1288             :   // instruction:
    1289             :   // EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th
    1290             :   // bit of EDX), while the EAX=0x1b leaf returns information on the
    1291             :   // availability of specific pconfig leafs.
    1292             :   // The target feature here only refers to the the first of these two.
    1293             :   // Users might need to check for the availability of specific pconfig
    1294             :   // leaves using cpuid, since that information is ignored while
    1295             :   // detecting features using the "-march=native" flag.
    1296             :   // For more info, see X86 ISA docs.
    1297           0 :   Features["pconfig"] = HasLeaf7 && ((EDX >> 18) & 1);
    1298             : 
    1299           0 :   bool HasLeafD = MaxLevel >= 0xd &&
    1300             :                   !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
    1301             : 
    1302             :   // Only enable XSAVE if OS has enabled support for saving YMM state.
    1303           0 :   Features["xsaveopt"] = HasLeafD && ((EAX >> 0) & 1) && HasAVXSave;
    1304           0 :   Features["xsavec"]   = HasLeafD && ((EAX >> 1) & 1) && HasAVXSave;
    1305           0 :   Features["xsaves"]   = HasLeafD && ((EAX >> 3) & 1) && HasAVXSave;
    1306             : 
    1307           0 :   bool HasLeaf14 = MaxLevel >= 0x14 &&
    1308             :                   !getX86CpuIDAndInfoEx(0x14, 0x0, &EAX, &EBX, &ECX, &EDX);
    1309             : 
    1310           0 :   Features["ptwrite"] = HasLeaf14 && ((EBX >> 4) & 1);
    1311             : 
    1312           0 :   return true;
    1313             : }
    1314             : #elif defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
    1315             : bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
    1316             :   std::unique_ptr<llvm::MemoryBuffer> P = getProcCpuinfoContent();
    1317             :   if (!P)
    1318             :     return false;
    1319             : 
    1320             :   SmallVector<StringRef, 32> Lines;
    1321             :   P->getBuffer().split(Lines, "\n");
    1322             : 
    1323             :   SmallVector<StringRef, 32> CPUFeatures;
    1324             : 
    1325             :   // Look for the CPU features.
    1326             :   for (unsigned I = 0, E = Lines.size(); I != E; ++I)
    1327             :     if (Lines[I].startswith("Features")) {
    1328             :       Lines[I].split(CPUFeatures, ' ');
    1329             :       break;
    1330             :     }
    1331             : 
    1332             : #if defined(__aarch64__)
    1333             :   // Keep track of which crypto features we have seen
    1334             :   enum { CAP_AES = 0x1, CAP_PMULL = 0x2, CAP_SHA1 = 0x4, CAP_SHA2 = 0x8 };
    1335             :   uint32_t crypto = 0;
    1336             : #endif
    1337             : 
    1338             :   for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
    1339             :     StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
    1340             : #if defined(__aarch64__)
    1341             :                                    .Case("asimd", "neon")
    1342             :                                    .Case("fp", "fp-armv8")
    1343             :                                    .Case("crc32", "crc")
    1344             : #else
    1345             :                                    .Case("half", "fp16")
    1346             :                                    .Case("neon", "neon")
    1347             :                                    .Case("vfpv3", "vfp3")
    1348             :                                    .Case("vfpv3d16", "d16")
    1349             :                                    .Case("vfpv4", "vfp4")
    1350             :                                    .Case("idiva", "hwdiv-arm")
    1351             :                                    .Case("idivt", "hwdiv")
    1352             : #endif
    1353             :                                    .Default("");
    1354             : 
    1355             : #if defined(__aarch64__)
    1356             :     // We need to check crypto separately since we need all of the crypto
    1357             :     // extensions to enable the subtarget feature
    1358             :     if (CPUFeatures[I] == "aes")
    1359             :       crypto |= CAP_AES;
    1360             :     else if (CPUFeatures[I] == "pmull")
    1361             :       crypto |= CAP_PMULL;
    1362             :     else if (CPUFeatures[I] == "sha1")
    1363             :       crypto |= CAP_SHA1;
    1364             :     else if (CPUFeatures[I] == "sha2")
    1365             :       crypto |= CAP_SHA2;
    1366             : #endif
    1367             : 
    1368             :     if (LLVMFeatureStr != "")
    1369             :       Features[LLVMFeatureStr] = true;
    1370             :   }
    1371             : 
    1372             : #if defined(__aarch64__)
    1373             :   // If we have all crypto bits we can add the feature
    1374             :   if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2))
    1375             :     Features["crypto"] = true;
    1376             : #endif
    1377             : 
    1378             :   return true;
    1379             : }
    1380             : #else
    1381             : bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; }
    1382             : #endif
    1383             : 
    1384      141247 : std::string sys::getProcessTriple() {
    1385      282494 :   std::string TargetTripleString = updateTripleOSVersion(LLVM_HOST_TRIPLE);
    1386      141247 :   Triple PT(Triple::normalize(TargetTripleString));
    1387             : 
    1388      141247 :   if (sizeof(void *) == 8 && PT.isArch32Bit())
    1389           0 :     PT = PT.get64BitArchVariant();
    1390             :   if (sizeof(void *) == 4 && PT.isArch64Bit())
    1391             :     PT = PT.get32BitArchVariant();
    1392             : 
    1393      141247 :   return PT.str();
    1394             : }

Generated by: LCOV version 1.13