//===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a target parser to recognise hardware features such as
// FPU/CPU/ARCH names as well as specific support such as HDIV, etc.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include <cctype>

using namespace llvm;
using namespace ARM;
using namespace AArch64;

namespace {

// List of canonical FPU names (use getFPUSynonym) and which architectural
// features they correspond to (use getFPUFeatures).
// FIXME: TableGen this.
// The entries must appear in the order listed in ARM::FPUKind for correct indexing
static const struct {
  const char *NameCStr;
  size_t NameLength;
  ARM::FPUKind ID;
  ARM::FPUVersion FPUVersion;
  ARM::NeonSupportLevel NeonSupport;
  ARM::FPURestriction Restriction;

  StringRef getName() const { return StringRef(NameCStr, NameLength); }
} FPUNames[] = {
#define ARM_FPU(NAME, KIND, VERSION, NEON_SUPPORT, RESTRICTION) \
  { NAME, sizeof(NAME) - 1, KIND, VERSION, NEON_SUPPORT, RESTRICTION },
#include "llvm/Support/ARMTargetParser.def"
};

// List of canonical arch names (use getArchSynonym).
// This table also provides the build attribute fields for CPU arch
// and Arch ID, according to the Addenda to the ARM ABI, chapters
// 2.4 and 2.3.5.2 respectively.
// FIXME: SubArch values were simplified to fit into the expectations
// of the triples and are not conforming with their official names.
// Check to see if the expectation should be changed.
// FIXME: TableGen this.
template <typename T> struct ArchNames {
  const char *NameCStr;
  size_t NameLength;
  const char *CPUAttrCStr;
  size_t CPUAttrLength;
  const char *SubArchCStr;
  size_t SubArchLength;
  unsigned DefaultFPU;
  unsigned ArchBaseExtensions;
  T ID;
  ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.

  StringRef getName() const { return StringRef(NameCStr, NameLength); }

  // CPU class in build attributes.
  StringRef getCPUAttr() const { return StringRef(CPUAttrCStr, CPUAttrLength); }

  // Sub-Arch name.
  StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
};
ArchNames<ARM::ArchKind> ARCHNames[] = {
#define ARM_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/ARMTargetParser.def"
};

ArchNames<AArch64::ArchKind> 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, AArch64::ArchKind::ID, ARCH_ATTR},
 #include "llvm/Support/AArch64TargetParser.def"
 };


// List of Arch Extension names.
// FIXME: TableGen this.
static const struct {
  const char *NameCStr;
  size_t NameLength;
  unsigned ID;
  const char *Feature;
  const char *NegFeature;

  StringRef getName() const { return StringRef(NameCStr, NameLength); }
} ARCHExtNames[] = {
#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
// features they correspond to (use getHWDivFeatures).
// FIXME: TableGen this.
static const struct {
  const char *NameCStr;
  size_t NameLength;
  unsigned ID;

  StringRef getName() const { return StringRef(NameCStr, NameLength); }
} HWDivNames[] = {
#define ARM_HW_DIV_NAME(NAME, ID) { NAME, sizeof(NAME) - 1, ID },
#include "llvm/Support/ARMTargetParser.def"
};

// List of CPU names and their arches.
// The same CPU can have multiple arches and can be default on multiple arches.
// When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
// When this becomes table-generated, we'd probably need two tables.
// FIXME: TableGen this.
template <typename T> struct CpuNames {
  const char *NameCStr;
  size_t NameLength;
  T ArchID;
  bool Default; // is $Name the default CPU for $ArchID ?
  unsigned DefaultExtensions;

  StringRef getName() const { return StringRef(NameCStr, NameLength); }
};
CpuNames<ARM::ArchKind> CPUNames[] = {
#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"
};

CpuNames<AArch64::ArchKind> AArch64CPUNames[] = {
 #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
   { NAME, sizeof(NAME) - 1, AArch64::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
 #include "llvm/Support/AArch64TargetParser.def"
 };

} // namespace

// ======================================================= //
// Information by ID
// ======================================================= //

StringRef llvm::ARM::getFPUName(unsigned FPUKind) {
  if (FPUKind >= ARM::FK_LAST)
    return StringRef();
  return FPUNames[FPUKind].getName();
}

unsigned llvm::ARM::getFPUVersion(unsigned FPUKind) {
  if (FPUKind >= ARM::FK_LAST)
    return 0;
  return FPUNames[FPUKind].FPUVersion;
}

unsigned llvm::ARM::getFPUNeonSupportLevel(unsigned FPUKind) {
  if (FPUKind >= ARM::FK_LAST)
    return 0;
  return FPUNames[FPUKind].NeonSupport;
}

unsigned llvm::ARM::getFPURestriction(unsigned FPUKind) {
  if (FPUKind >= ARM::FK_LAST)
    return 0;
  return FPUNames[FPUKind].Restriction;
}

unsigned llvm::ARM::getDefaultFPU(StringRef CPU, unsigned ArchKind) {
  if (CPU == "generic")
    return ARCHNames[ArchKind].DefaultFPU;

  return StringSwitch<unsigned>(CPU)
#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
    .Case(NAME, DEFAULT_FPU)
#include "llvm/Support/ARMTargetParser.def"
    .Default(ARM::FK_INVALID);
}

unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, unsigned ArchKind) {
  if (CPU == "generic")
    return ARCHNames[ArchKind].ArchBaseExtensions;

  return StringSwitch<unsigned>(CPU)
#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
    .Case(NAME, ARCHNames[ID].ArchBaseExtensions | DEFAULT_EXT)
#include "llvm/Support/ARMTargetParser.def"
    .Default(ARM::AEK_INVALID);
}

bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
                                 std::vector<StringRef> &Features) {

  if (HWDivKind == ARM::AEK_INVALID)
    return false;

  if (HWDivKind & ARM::AEK_HWDIVARM)
    Features.push_back("+hwdiv-arm");
  else
    Features.push_back("-hwdiv-arm");

  if (HWDivKind & ARM::AEK_HWDIV)
    Features.push_back("+hwdiv");
  else
    Features.push_back("-hwdiv");

  return true;
}

bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
                                     std::vector<StringRef> &Features) {

  if (Extensions == ARM::AEK_INVALID)
    return false;

  if (Extensions & ARM::AEK_CRC)
    Features.push_back("+crc");
  else
    Features.push_back("-crc");

  if (Extensions & ARM::AEK_DSP)
    Features.push_back("+dsp");
  else
    Features.push_back("-dsp");

  return getHWDivFeatures(Extensions, Features);
}

bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
                               std::vector<StringRef> &Features) {

  if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
    return false;

  // fp-only-sp and d16 subtarget features are independent of each other, so we
  // must enable/disable both.
  switch (FPUNames[FPUKind].Restriction) {
  case ARM::FR_SP_D16:
    Features.push_back("+fp-only-sp");
    Features.push_back("+d16");
    break;
  case ARM::FR_D16:
    Features.push_back("-fp-only-sp");
    Features.push_back("+d16");
    break;
  case ARM::FR_None:
    Features.push_back("-fp-only-sp");
    Features.push_back("-d16");
    break;
  }

  // FPU version subtarget features are inclusive of lower-numbered ones, so
  // enable the one corresponding to this version and disable all that are
  // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
  // as +vfp4 implies +fp16 but -vfp4 does not imply -fp16.
  switch (FPUNames[FPUKind].FPUVersion) {
  case ARM::FV_VFPV5:
    Features.push_back("+fp-armv8");
    break;
  case ARM::FV_VFPV4:
    Features.push_back("+vfp4");
    Features.push_back("-fp-armv8");
    break;
  case ARM::FV_VFPV3_FP16:
    Features.push_back("+vfp3");
    Features.push_back("+fp16");
    Features.push_back("-vfp4");
    Features.push_back("-fp-armv8");
    break;
  case ARM::FV_VFPV3:
    Features.push_back("+vfp3");
    Features.push_back("-fp16");
    Features.push_back("-vfp4");
    Features.push_back("-fp-armv8");
    break;
  case ARM::FV_VFPV2:
    Features.push_back("+vfp2");
    Features.push_back("-vfp3");
    Features.push_back("-fp16");
    Features.push_back("-vfp4");
    Features.push_back("-fp-armv8");
    break;
  case ARM::FV_NONE:
    Features.push_back("-vfp2");
    Features.push_back("-vfp3");
    Features.push_back("-fp16");
    Features.push_back("-vfp4");
    Features.push_back("-fp-armv8");
    break;
  }

  // crypto includes neon, so we handle this similarly to FPU version.
  switch (FPUNames[FPUKind].NeonSupport) {
  case ARM::NS_Crypto:
    Features.push_back("+neon");
    Features.push_back("+crypto");
    break;
  case ARM::NS_Neon:
    Features.push_back("+neon");
    Features.push_back("-crypto");
    break;
  case ARM::NS_None:
    Features.push_back("-neon");
    Features.push_back("-crypto");
    break;
  }

  return true;
}

StringRef llvm::ARM::getArchName(unsigned ArchKind) {
  if (ArchKind >= ARM::AK_LAST)
    return StringRef();
  return ARCHNames[ArchKind].getName();
}

StringRef llvm::ARM::getCPUAttr(unsigned ArchKind) {
  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_INVALID || ArchKind >= ARM::AK_LAST)
    return StringRef();
  return ARCHNames[ArchKind].getSubArch();
}

unsigned llvm::ARM::getArchAttr(unsigned ArchKind) {
  if (ArchKind >= ARM::AK_LAST)
    return ARMBuildAttrs::CPUArch::Pre_v4;
  return ARCHNames[ArchKind].ArchAttr;
}

StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
  for (const auto AE : ARCHExtNames) {
    if (ArchExtKind == AE.ID)
      return AE.getName();
  }
  return StringRef();
}

StringRef llvm::ARM::getArchExtFeature(StringRef ArchExt) {
  if (ArchExt.startswith("no")) {
    StringRef ArchExtBase(ArchExt.substr(2));
    for (const auto AE : ARCHExtNames) {
      if (AE.NegFeature && ArchExtBase == AE.getName())
        return StringRef(AE.NegFeature);
    }
  }
  for (const auto AE : ARCHExtNames) {
    if (AE.Feature && ArchExt == AE.getName())
      return StringRef(AE.Feature);
  }

  return StringRef();
}

StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
  for (const auto D : HWDivNames) {
    if (HWDivKind == D.ID)
      return D.getName();
  }
  return StringRef();
}

StringRef llvm::ARM::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 : CPUNames) {
    if (CPU.ArchID == AK && CPU.Default)
      return CPU.getName();
  }

  // If we can't find a default then target the architecture instead
  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, DEFAULT_EXT)
#include "llvm/Support/AArch64TargetParser.def"
    .Default(AArch64::AEK_INVALID);
}

bool llvm::AArch64::getExtensionFeatures(unsigned Extensions,
                                     std::vector<StringRef> &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<StringRef> &Features) {
  return ARM::getFPUFeatures(FPUKind, Features);
}

bool llvm::AArch64::getArchFeatures(unsigned ArchKind,
                                     std::vector<StringRef> &Features) {
  if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8_1A))
    Features.push_back("+v8.1a");
  if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8_2A))
    Features.push_back("+v8.2a");

  return ArchKind > static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) &&
         ArchKind < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
}

StringRef llvm::AArch64::getArchName(unsigned ArchKind) {
  if (ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
    return StringRef();
  return AArch64ARCHNames[ArchKind].getName();
}

StringRef llvm::AArch64::getCPUAttr(unsigned ArchKind) {
  if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
      ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
    return StringRef();
  return AArch64ARCHNames[ArchKind].getCPUAttr();
}

StringRef llvm::AArch64::getSubArch(unsigned ArchKind) {
  if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
      ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
    return StringRef();
  return AArch64ARCHNames[ArchKind].getSubArch();
}

unsigned llvm::AArch64::getArchAttr(unsigned ArchKind) {
  if (ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
    return ARMBuildAttrs::CPUArch::v8_A;
  return AArch64ARCHNames[ArchKind].ArchAttr;
}

StringRef llvm::AArch64::getArchExtName(unsigned ArchExtKind) {
  for (const auto &AE : AArch64ARCHExtNames)
    if (ArchExtKind == AE.ID)
      return AE.getName();
  return StringRef();
}

StringRef 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 StringRef(AE.NegFeature);
    }
  }

  for (const auto &AE : AArch64ARCHExtNames)
    if (AE.Feature && ArchExt == AE.getName())
      return StringRef(AE.Feature);
  return StringRef();
}

StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) {
  unsigned AK = parseArch(Arch);
  if (AK == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID))
    return StringRef();

  // Look for multiple AKs to find the default for pair AK+Name.
  for (const auto &CPU : AArch64CPUNames)
    if (static_cast<unsigned>(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
// ======================================================= //

static StringRef getHWDivSynonym(StringRef HWDiv) {
  return StringSwitch<StringRef>(HWDiv)
      .Case("thumb,arm", "arm,thumb")
      .Default(HWDiv);
}

static StringRef getFPUSynonym(StringRef FPU) {
  return StringSwitch<StringRef>(FPU)
      .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported
      .Case("vfp2", "vfpv2")
      .Case("vfp3", "vfpv3")
      .Case("vfp4", "vfpv4")
      .Case("vfp3-d16", "vfpv3-d16")
      .Case("vfp4-d16", "vfpv4-d16")
      .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16")
      .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16")
      .Case("fp5-sp-d16", "fpv5-sp-d16")
      .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16")
      // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3.
      .Case("neon-vfpv3", "neon")
      .Default(FPU);
}

static StringRef getArchSynonym(StringRef Arch) {
  return StringSwitch<StringRef>(Arch)
      .Case("v5", "v5t")
      .Case("v5e", "v5te")
      .Case("v6j", "v6")
      .Case("v6hl", "v6k")
      .Cases("v6m", "v6sm", "v6s-m", "v6-m")
      .Cases("v6z", "v6zk", "v6kz")
      .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
      .Case("v7r", "v7-r")
      .Case("v7m", "v7-m")
      .Case("v7em", "v7e-m")
      .Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
      .Case("v8.1a", "v8.1-a")
      .Case("v8.2a", "v8.2-a")
      .Case("v8r", "v8-r")
      .Case("v8m.base", "v8-m.base")
      .Case("v8m.main", "v8-m.main")
      .Default(Arch);
}

// MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
// (iwmmxt|xscale)(eb)? is also permitted. If the former, return
// "v.+", if the latter, return unmodified string, minus 'eb'.
// If invalid, return empty string.
StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
  size_t offset = StringRef::npos;
  StringRef A = Arch;
  StringRef Error = "";

  // Begins with "arm" / "thumb", move past it.
  if (A.startswith("arm64"))
    offset = 5;
  else if (A.startswith("arm"))
    offset = 3;
  else if (A.startswith("thumb"))
    offset = 5;
  else if (A.startswith("aarch64")) {
    offset = 7;
    // AArch64 uses "_be", not "eb" suffix.
    if (A.find("eb") != StringRef::npos)
      return Error;
    if (A.substr(offset, 3) == "_be")
      offset += 3;
  }

  // Ex. "armebv7", move past the "eb".
  if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
    offset += 2;
  // Or, if it ends with eb ("armv7eb"), chop it off.
  else if (A.endswith("eb"))
    A = A.substr(0, A.size() - 2);
  // Trim the head
  if (offset != StringRef::npos)
    A = A.substr(offset);

  // Empty string means offset reached the end, which means it's valid.
  if (A.empty())
    return Arch;

  // Only match non-marketing names
  if (offset != StringRef::npos) {
    // Must start with 'vN'.
    if (A[0] != 'v' || !std::isdigit(A[1]))
      return Error;
    // Can't have an extra 'eb'.
    if (A.find("eb") != StringRef::npos)
      return Error;
  }

  // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
  return A;
}

unsigned llvm::ARM::parseHWDiv(StringRef HWDiv) {
  StringRef Syn = getHWDivSynonym(HWDiv);
  for (const auto D : HWDivNames) {
    if (Syn == D.getName())
      return D.ID;
  }
  return ARM::AEK_INVALID;
}

unsigned llvm::ARM::parseFPU(StringRef FPU) {
  StringRef Syn = getFPUSynonym(FPU);
  for (const auto F : FPUNames) {
    if (Syn == F.getName())
      return F.ID;
  }
  return ARM::FK_INVALID;
}

// Allows partial match, ex. "v7a" matches "armv7a".
unsigned llvm::ARM::parseArch(StringRef Arch) {
  Arch = getCanonicalArchName(Arch);
  StringRef Syn = getArchSynonym(Arch);
  for (const auto A : ARCHNames) {
    if (A.getName().endswith(Syn))
      return A.ID;
  }
  return ARM::AK_INVALID;
}

unsigned llvm::ARM::parseArchExt(StringRef ArchExt) {
  for (const auto A : ARCHExtNames) {
    if (ArchExt == A.getName())
      return A.ID;
  }
  return ARM::AEK_INVALID;
}

unsigned llvm::ARM::parseCPUArch(StringRef CPU) {
  for (const auto C : CPUNames) {
    if (CPU == C.getName())
      return C.ArchID;
  }
  return ARM::AK_INVALID;
}

// ARM, Thumb, AArch64
unsigned llvm::ARM::parseArchISA(StringRef Arch) {
  return StringSwitch<unsigned>(Arch)
      .StartsWith("aarch64", ARM::IK_AARCH64)
      .StartsWith("arm64", ARM::IK_AARCH64)
      .StartsWith("thumb", ARM::IK_THUMB)
      .StartsWith("arm", ARM::IK_ARM)
      .Default(ARM::IK_INVALID);
}

// Little/Big endian
unsigned llvm::ARM::parseArchEndian(StringRef Arch) {
  if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
      Arch.startswith("aarch64_be"))
    return ARM::EK_BIG;

  if (Arch.startswith("arm") || Arch.startswith("thumb")) {
    if (Arch.endswith("eb"))
      return ARM::EK_BIG;
    else
      return ARM::EK_LITTLE;
  }

  if (Arch.startswith("aarch64"))
    return ARM::EK_LITTLE;

  return ARM::EK_INVALID;
}

// Profile A/R/M
unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
  Arch = getCanonicalArchName(Arch);
  switch (parseArch(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:
  case ARM::AK_ARMV8R:
    return ARM::PK_R;
  case ARM::AK_ARMV7A:
  case ARM::AK_ARMV7K:
  case ARM::AK_ARMV8A:
  case ARM::AK_ARMV8_1A:
  case ARM::AK_ARMV8_2A:
    return ARM::PK_A;
  }
  return ARM::PK_INVALID;
}

// Version number (ex. v7 = 7).
unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
  Arch = getCanonicalArchName(Arch);
  switch (parseArch(Arch)) {
  case ARM::AK_ARMV2:
  case ARM::AK_ARMV2A:
    return 2;
  case ARM::AK_ARMV3:
  case ARM::AK_ARMV3M:
    return 3;
  case ARM::AK_ARMV4:
  case ARM::AK_ARMV4T:
    return 4;
  case ARM::AK_ARMV5T:
  case ARM::AK_ARMV5TE:
  case ARM::AK_IWMMXT:
  case ARM::AK_IWMMXT2:
  case ARM::AK_XSCALE:
  case ARM::AK_ARMV5TEJ:
    return 5;
  case ARM::AK_ARMV6:
  case ARM::AK_ARMV6K:
  case ARM::AK_ARMV6T2:
  case ARM::AK_ARMV6KZ:
  case ARM::AK_ARMV6M:
    return 6;
  case ARM::AK_ARMV7A:
  case ARM::AK_ARMV7R:
  case ARM::AK_ARMV7M:
  case ARM::AK_ARMV7S:
  case ARM::AK_ARMV7EM:
  case ARM::AK_ARMV7K:
    return 7;
  case ARM::AK_ARMV8A:
  case ARM::AK_ARMV8_1A:
  case ARM::AK_ARMV8_2A:
  case ARM::AK_ARMV8R:
  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 static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);

  StringRef Syn = getArchSynonym(Arch);
  for (const auto A : AArch64ARCHNames) {
    if (A.getName().endswith(Syn))
      return static_cast<unsigned>(A.ID);
  }
  return static_cast<unsigned>(AArch64::ArchKind::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 static_cast<unsigned>(C.ArchID);
  }
  return static_cast<unsigned>(AArch64::ArchKind::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);
}
