diff options
Diffstat (limited to 'contrib/llvm/lib/Support/TargetParser.cpp')
| -rw-r--r-- | contrib/llvm/lib/Support/TargetParser.cpp | 232 | 
1 files changed, 230 insertions, 2 deletions
| diff --git a/contrib/llvm/lib/Support/TargetParser.cpp b/contrib/llvm/lib/Support/TargetParser.cpp index 337532edbbc6..c3f86130b68c 100644 --- a/contrib/llvm/lib/Support/TargetParser.cpp +++ b/contrib/llvm/lib/Support/TargetParser.cpp @@ -21,6 +21,7 @@  using namespace llvm;  using namespace ARM; +using namespace AArch64;  namespace { @@ -75,6 +76,11 @@ static const struct {    {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH,       \     sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ID, ARCH_ATTR},  #include "llvm/Support/ARMTargetParser.def" +},AArch64ARCHNames[] = { +#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT)       \ +  {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH,       \ +   sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ID, ARCH_ATTR}, +#include "llvm/Support/AArch64TargetParser.def"  };  // List of Arch Extension names. @@ -91,6 +97,10 @@ static const struct {  #define ARM_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \    { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE },  #include "llvm/Support/ARMTargetParser.def" +},AArch64ARCHExtNames[] = { +#define AARCH64_ARCH_EXT_NAME(NAME, ID, FEATURE, NEGFEATURE) \ +  { NAME, sizeof(NAME) - 1, ID, FEATURE, NEGFEATURE }, +#include "llvm/Support/AArch64TargetParser.def"  };  // List of HWDiv names (use getHWDivSynonym) and which architectural @@ -124,6 +134,10 @@ static const struct {  #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \    { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT, DEFAULT_EXT },  #include "llvm/Support/ARMTargetParser.def" +},AArch64CPUNames[] = { +#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ +  { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT, DEFAULT_EXT }, +#include "llvm/Support/AArch64TargetParser.def"  };  } // namespace @@ -305,13 +319,13 @@ StringRef llvm::ARM::getArchName(unsigned ArchKind) {  }  StringRef llvm::ARM::getCPUAttr(unsigned ArchKind) { -  if (ArchKind >= ARM::AK_LAST) +  if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST)      return StringRef();    return ARCHNames[ArchKind].getCPUAttr();  }  StringRef llvm::ARM::getSubArch(unsigned ArchKind) { -  if (ArchKind >= ARM::AK_LAST) +  if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST)      return StringRef();    return ARCHNames[ArchKind].getSubArch();  } @@ -369,6 +383,156 @@ StringRef llvm::ARM::getDefaultCPU(StringRef Arch) {    return "generic";  } +StringRef llvm::AArch64::getFPUName(unsigned FPUKind) { +  return ARM::getFPUName(FPUKind); +} + +unsigned llvm::AArch64::getFPUVersion(unsigned FPUKind) { +  return ARM::getFPUVersion(FPUKind); +} + +unsigned llvm::AArch64::getFPUNeonSupportLevel(unsigned FPUKind) { +  return ARM::getFPUNeonSupportLevel( FPUKind); +} + +unsigned llvm::AArch64::getFPURestriction(unsigned FPUKind) { +  return ARM::getFPURestriction(FPUKind); +} + +unsigned llvm::AArch64::getDefaultFPU(StringRef CPU, unsigned ArchKind) { +  if (CPU == "generic") +    return AArch64ARCHNames[ArchKind].DefaultFPU; + +  return StringSwitch<unsigned>(CPU) +#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ +    .Case(NAME, DEFAULT_FPU) +#include "llvm/Support/AArch64TargetParser.def" +    .Default(ARM::FK_INVALID); +} + +unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, unsigned ArchKind) { +  if (CPU == "generic") +    return AArch64ARCHNames[ArchKind].ArchBaseExtensions; + +  return StringSwitch<unsigned>(CPU) +#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ +    .Case(NAME, AArch64ARCHNames[ID].ArchBaseExtensions | DEFAULT_EXT) +#include "llvm/Support/AArch64TargetParser.def" +    .Default(AArch64::AEK_INVALID); +} + +bool llvm::AArch64::getExtensionFeatures(unsigned Extensions, +                                     std::vector<const char *> &Features) { + +  if (Extensions == AArch64::AEK_INVALID) +    return false; + +  if (Extensions & AArch64::AEK_FP) +    Features.push_back("+fp-armv8"); +  if (Extensions & AArch64::AEK_SIMD) +    Features.push_back("+neon"); +  if (Extensions & AArch64::AEK_CRC) +    Features.push_back("+crc"); +  if (Extensions & AArch64::AEK_CRYPTO) +    Features.push_back("+crypto"); +  if (Extensions & AArch64::AEK_FP16) +    Features.push_back("+fullfp16"); +  if (Extensions & AArch64::AEK_PROFILE) +    Features.push_back("+spe"); +  if (Extensions & AArch64::AEK_RAS) +    Features.push_back("+ras"); + +  return true; +} + +bool llvm::AArch64::getFPUFeatures(unsigned FPUKind, +                               std::vector<const char *> &Features) { +  return ARM::getFPUFeatures(FPUKind, Features); +} + +bool llvm::AArch64::getArchFeatures(unsigned ArchKind, +                                     std::vector<const char *> &Features) { +  if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST) +    return false; + +  if (ArchKind == ARM::AK_ARMV8_1A) +    Features.push_back("+v8.1a"); +  if (ArchKind == ARM::AK_ARMV8_2A) +    Features.push_back("+v8.2a"); + +  return true; +} + +StringRef llvm::AArch64::getArchName(unsigned ArchKind) { +  for (const auto &AI : AArch64ARCHNames) +    if (AI.ID == ArchKind) +      return AI.getName(); +  return StringRef(); +} + +StringRef llvm::AArch64::getCPUAttr(unsigned ArchKind) { +  for (const auto &AI : AArch64ARCHNames) +    if (AI.ID == ArchKind) +      return AI.getCPUAttr(); +  return StringRef(); +} + +StringRef llvm::AArch64::getSubArch(unsigned ArchKind) { +  for (const auto &AI : AArch64ARCHNames) +    if (AI.ID == ArchKind) +      return AI.getSubArch(); +  return StringRef(); +} + +unsigned llvm::AArch64::getArchAttr(unsigned ArchKind) { +  for (const auto &AI : AArch64ARCHNames) +    if (AI.ID == ArchKind) +      return AI.ArchAttr; +  return ARMBuildAttrs::CPUArch::v8_A; +} + +StringRef llvm::AArch64::getArchExtName(unsigned AArchExtKind) { +  for (const auto &AE : AArch64ARCHExtNames) +    if (AArchExtKind == AE.ID) +      return AE.getName(); +  return StringRef(); +} + +const char *llvm::AArch64::getArchExtFeature(StringRef ArchExt) { +  if (ArchExt.startswith("no")) { +    StringRef ArchExtBase(ArchExt.substr(2)); +    for (const auto &AE : AArch64ARCHExtNames) { +      if (AE.NegFeature && ArchExtBase == AE.getName()) +        return AE.NegFeature; +    } +  } + +  for (const auto &AE : AArch64ARCHExtNames) +    if (AE.Feature && ArchExt == AE.getName()) +      return AE.Feature; +  return nullptr; +} + +StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) { +  unsigned AK = parseArch(Arch); +  if (AK == ARM::AK_INVALID) +    return StringRef(); + +  // Look for multiple AKs to find the default for pair AK+Name. +  for (const auto &CPU : AArch64CPUNames) +    if (CPU.ArchID == AK && CPU.Default) +      return CPU.getName(); + +  // If we can't find a default then target the architecture instead +  return "generic"; +} + +unsigned llvm::AArch64::checkArchVersion(StringRef Arch) { +  if (Arch[0] == 'v' && std::isdigit(Arch[1])) +    return (Arch[1] - 48); +  return 0; +} +  // ======================================================= //  // Parsers  // ======================================================= // @@ -411,6 +575,8 @@ static StringRef getArchSynonym(StringRef Arch) {        .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")        .Case("v8.1a", "v8.1-a")        .Case("v8.2a", "v8.2-a") +      .Case("v8m.base", "v8-m.base") +      .Case("v8m.main", "v8-m.main")        .Default(Arch);  } @@ -548,6 +714,8 @@ unsigned llvm::ARM::parseArchProfile(StringRef Arch) {    case ARM::AK_ARMV6M:    case ARM::AK_ARMV7M:    case ARM::AK_ARMV7EM: +  case ARM::AK_ARMV8MMainline: +  case ARM::AK_ARMV8MBaseline:      return ARM::PK_M;    case ARM::AK_ARMV7R:      return ARM::PK_R; @@ -597,7 +765,67 @@ unsigned llvm::ARM::parseArchVersion(StringRef Arch) {    case ARM::AK_ARMV8A:    case ARM::AK_ARMV8_1A:    case ARM::AK_ARMV8_2A: +  case ARM::AK_ARMV8MBaseline: +  case ARM::AK_ARMV8MMainline:      return 8;    }    return 0;  } + +StringRef llvm::AArch64::getCanonicalArchName(StringRef Arch) { +  return ARM::getCanonicalArchName(Arch); +} + +unsigned llvm::AArch64::parseFPU(StringRef FPU) { +  return ARM::parseFPU(FPU); +} + +// Allows partial match, ex. "v8a" matches "armv8a". +unsigned llvm::AArch64::parseArch(StringRef Arch) { +  Arch = getCanonicalArchName(Arch); +  if (checkArchVersion(Arch) < 8) +    return ARM::AK_INVALID; + +  StringRef Syn = getArchSynonym(Arch); +  for (const auto A : AArch64ARCHNames) { +    if (A.getName().endswith(Syn)) +      return A.ID; +  } +  return ARM::AK_INVALID; +} + +unsigned llvm::AArch64::parseArchExt(StringRef ArchExt) { +  for (const auto A : AArch64ARCHExtNames) { +    if (ArchExt == A.getName()) +      return A.ID; +  } +  return AArch64::AEK_INVALID; +} + +unsigned llvm::AArch64::parseCPUArch(StringRef CPU) { +  for (const auto C : AArch64CPUNames) { +    if (CPU == C.getName()) +      return C.ArchID; +  } +  return ARM::AK_INVALID; +} + +// ARM, Thumb, AArch64 +unsigned llvm::AArch64::parseArchISA(StringRef Arch) { +  return ARM::parseArchISA(Arch); +} + +// Little/Big endian +unsigned llvm::AArch64::parseArchEndian(StringRef Arch) { +  return ARM::parseArchEndian(Arch); +} + +// Profile A/R/M +unsigned llvm::AArch64::parseArchProfile(StringRef Arch) { +  return ARM::parseArchProfile(Arch); +} + +// Version number (ex. v8 = 8). +unsigned llvm::AArch64::parseArchVersion(StringRef Arch) { +  return ARM::parseArchVersion(Arch); +} | 
