forked from OSchip/llvm-project
[Triple] Use clang-format to normalize the formatting of the ARM target
parsing logic prior to making substantial changes to it. This parsing logic is incredibly wasteful, so I'm planning to rewrite it. Just unittesting the triple parsing logic spends well over 80% of its time in the ARM parsing logic, and others have measured significant time spent here in real production compiles. Stay tuned... llvm-svn: 246369
This commit is contained in:
parent
aa0caeb431
commit
4fc3a9862c
|
@ -20,7 +20,7 @@
|
|||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class StringRef;
|
||||
class StringRef;
|
||||
|
||||
// Target specific information into their own namespaces. These should be
|
||||
// generated from TableGen because the information is already there, and there
|
||||
|
@ -29,173 +29,159 @@ namespace llvm {
|
|||
// even if the back-end is not compiled with LLVM, plus we need to create a new
|
||||
// back-end to TableGen to create these clean tables.
|
||||
namespace ARM {
|
||||
// FPU names.
|
||||
enum FPUKind {
|
||||
FK_INVALID = 0,
|
||||
FK_NONE,
|
||||
FK_VFP,
|
||||
FK_VFPV2,
|
||||
FK_VFPV3,
|
||||
FK_VFPV3_FP16,
|
||||
FK_VFPV3_D16,
|
||||
FK_VFPV3_D16_FP16,
|
||||
FK_VFPV3XD,
|
||||
FK_VFPV3XD_FP16,
|
||||
FK_VFPV4,
|
||||
FK_VFPV4_D16,
|
||||
FK_FPV4_SP_D16,
|
||||
FK_FPV5_D16,
|
||||
FK_FPV5_SP_D16,
|
||||
FK_FP_ARMV8,
|
||||
FK_NEON,
|
||||
FK_NEON_FP16,
|
||||
FK_NEON_VFPV4,
|
||||
FK_NEON_FP_ARMV8,
|
||||
FK_CRYPTO_NEON_FP_ARMV8,
|
||||
FK_SOFTVFP,
|
||||
FK_LAST
|
||||
};
|
||||
|
||||
// FPU Version
|
||||
enum FPUVersion {
|
||||
FV_NONE = 0,
|
||||
FV_VFPV2,
|
||||
FV_VFPV3,
|
||||
FV_VFPV3_FP16,
|
||||
FV_VFPV4,
|
||||
FV_VFPV5
|
||||
};
|
||||
// FPU names.
|
||||
enum FPUKind {
|
||||
FK_INVALID = 0,
|
||||
FK_NONE,
|
||||
FK_VFP,
|
||||
FK_VFPV2,
|
||||
FK_VFPV3,
|
||||
FK_VFPV3_FP16,
|
||||
FK_VFPV3_D16,
|
||||
FK_VFPV3_D16_FP16,
|
||||
FK_VFPV3XD,
|
||||
FK_VFPV3XD_FP16,
|
||||
FK_VFPV4,
|
||||
FK_VFPV4_D16,
|
||||
FK_FPV4_SP_D16,
|
||||
FK_FPV5_D16,
|
||||
FK_FPV5_SP_D16,
|
||||
FK_FP_ARMV8,
|
||||
FK_NEON,
|
||||
FK_NEON_FP16,
|
||||
FK_NEON_VFPV4,
|
||||
FK_NEON_FP_ARMV8,
|
||||
FK_CRYPTO_NEON_FP_ARMV8,
|
||||
FK_SOFTVFP,
|
||||
FK_LAST
|
||||
};
|
||||
|
||||
// An FPU name implies one of three levels of Neon support:
|
||||
enum NeonSupportLevel {
|
||||
NS_None = 0, ///< No Neon
|
||||
NS_Neon, ///< Neon
|
||||
NS_Crypto ///< Neon with Crypto
|
||||
};
|
||||
// FPU Version
|
||||
enum FPUVersion {
|
||||
FV_NONE = 0,
|
||||
FV_VFPV2,
|
||||
FV_VFPV3,
|
||||
FV_VFPV3_FP16,
|
||||
FV_VFPV4,
|
||||
FV_VFPV5
|
||||
};
|
||||
|
||||
// An FPU name restricts the FPU in one of three ways:
|
||||
enum FPURestriction {
|
||||
FR_None = 0, ///< No restriction
|
||||
FR_D16, ///< Only 16 D registers
|
||||
FR_SP_D16 ///< Only single-precision instructions, with 16 D registers
|
||||
};
|
||||
// An FPU name implies one of three levels of Neon support:
|
||||
enum NeonSupportLevel {
|
||||
NS_None = 0, ///< No Neon
|
||||
NS_Neon, ///< Neon
|
||||
NS_Crypto ///< Neon with Crypto
|
||||
};
|
||||
|
||||
// Arch names.
|
||||
enum ArchKind {
|
||||
AK_INVALID = 0,
|
||||
AK_ARMV2,
|
||||
AK_ARMV2A,
|
||||
AK_ARMV3,
|
||||
AK_ARMV3M,
|
||||
AK_ARMV4,
|
||||
AK_ARMV4T,
|
||||
AK_ARMV5T,
|
||||
AK_ARMV5TE,
|
||||
AK_ARMV5TEJ,
|
||||
AK_ARMV6,
|
||||
AK_ARMV6K,
|
||||
AK_ARMV6T2,
|
||||
AK_ARMV6Z,
|
||||
AK_ARMV6ZK,
|
||||
AK_ARMV6M,
|
||||
AK_ARMV6SM,
|
||||
AK_ARMV7A,
|
||||
AK_ARMV7R,
|
||||
AK_ARMV7M,
|
||||
AK_ARMV7EM,
|
||||
AK_ARMV8A,
|
||||
AK_ARMV8_1A,
|
||||
// Non-standard Arch names.
|
||||
AK_IWMMXT,
|
||||
AK_IWMMXT2,
|
||||
AK_XSCALE,
|
||||
AK_ARMV5,
|
||||
AK_ARMV5E,
|
||||
AK_ARMV6J,
|
||||
AK_ARMV6HL,
|
||||
AK_ARMV7,
|
||||
AK_ARMV7L,
|
||||
AK_ARMV7HL,
|
||||
AK_ARMV7S,
|
||||
AK_ARMV7K,
|
||||
AK_LAST
|
||||
};
|
||||
// An FPU name restricts the FPU in one of three ways:
|
||||
enum FPURestriction {
|
||||
FR_None = 0, ///< No restriction
|
||||
FR_D16, ///< Only 16 D registers
|
||||
FR_SP_D16 ///< Only single-precision instructions, with 16 D registers
|
||||
};
|
||||
|
||||
// Arch extension modifiers for CPUs.
|
||||
enum ArchExtKind : unsigned {
|
||||
AEK_INVALID = 0x0,
|
||||
AEK_NONE = 0x1,
|
||||
AEK_CRC = 0x2,
|
||||
AEK_CRYPTO = 0x4,
|
||||
AEK_FP = 0x8,
|
||||
AEK_HWDIV = 0x10,
|
||||
AEK_HWDIVARM = 0x20,
|
||||
AEK_MP = 0x40,
|
||||
AEK_SIMD = 0x80,
|
||||
AEK_SEC = 0x100,
|
||||
AEK_VIRT = 0x200,
|
||||
// Unsupported extensions.
|
||||
AEK_OS = 0x8000000,
|
||||
AEK_IWMMXT = 0x10000000,
|
||||
AEK_IWMMXT2 = 0x20000000,
|
||||
AEK_MAVERICK = 0x40000000,
|
||||
AEK_XSCALE = 0x80000000,
|
||||
};
|
||||
// Arch names.
|
||||
enum ArchKind {
|
||||
AK_INVALID = 0,
|
||||
AK_ARMV2,
|
||||
AK_ARMV2A,
|
||||
AK_ARMV3,
|
||||
AK_ARMV3M,
|
||||
AK_ARMV4,
|
||||
AK_ARMV4T,
|
||||
AK_ARMV5T,
|
||||
AK_ARMV5TE,
|
||||
AK_ARMV5TEJ,
|
||||
AK_ARMV6,
|
||||
AK_ARMV6K,
|
||||
AK_ARMV6T2,
|
||||
AK_ARMV6Z,
|
||||
AK_ARMV6ZK,
|
||||
AK_ARMV6M,
|
||||
AK_ARMV6SM,
|
||||
AK_ARMV7A,
|
||||
AK_ARMV7R,
|
||||
AK_ARMV7M,
|
||||
AK_ARMV7EM,
|
||||
AK_ARMV8A,
|
||||
AK_ARMV8_1A,
|
||||
// Non-standard Arch names.
|
||||
AK_IWMMXT,
|
||||
AK_IWMMXT2,
|
||||
AK_XSCALE,
|
||||
AK_ARMV5,
|
||||
AK_ARMV5E,
|
||||
AK_ARMV6J,
|
||||
AK_ARMV6HL,
|
||||
AK_ARMV7,
|
||||
AK_ARMV7L,
|
||||
AK_ARMV7HL,
|
||||
AK_ARMV7S,
|
||||
AK_ARMV7K,
|
||||
AK_LAST
|
||||
};
|
||||
|
||||
// ISA kinds.
|
||||
enum ISAKind {
|
||||
IK_INVALID = 0,
|
||||
IK_ARM,
|
||||
IK_THUMB,
|
||||
IK_AARCH64
|
||||
};
|
||||
// Arch extension modifiers for CPUs.
|
||||
enum ArchExtKind : unsigned {
|
||||
AEK_INVALID = 0x0,
|
||||
AEK_NONE = 0x1,
|
||||
AEK_CRC = 0x2,
|
||||
AEK_CRYPTO = 0x4,
|
||||
AEK_FP = 0x8,
|
||||
AEK_HWDIV = 0x10,
|
||||
AEK_HWDIVARM = 0x20,
|
||||
AEK_MP = 0x40,
|
||||
AEK_SIMD = 0x80,
|
||||
AEK_SEC = 0x100,
|
||||
AEK_VIRT = 0x200,
|
||||
// Unsupported extensions.
|
||||
AEK_OS = 0x8000000,
|
||||
AEK_IWMMXT = 0x10000000,
|
||||
AEK_IWMMXT2 = 0x20000000,
|
||||
AEK_MAVERICK = 0x40000000,
|
||||
AEK_XSCALE = 0x80000000,
|
||||
};
|
||||
|
||||
// Endianness
|
||||
// FIXME: BE8 vs. BE32?
|
||||
enum EndianKind {
|
||||
EK_INVALID = 0,
|
||||
EK_LITTLE,
|
||||
EK_BIG
|
||||
};
|
||||
// ISA kinds.
|
||||
enum ISAKind { IK_INVALID = 0, IK_ARM, IK_THUMB, IK_AARCH64 };
|
||||
|
||||
// v6/v7/v8 Profile
|
||||
enum ProfileKind {
|
||||
PK_INVALID = 0,
|
||||
PK_A,
|
||||
PK_R,
|
||||
PK_M
|
||||
};
|
||||
// Endianness
|
||||
// FIXME: BE8 vs. BE32?
|
||||
enum EndianKind { EK_INVALID = 0, EK_LITTLE, EK_BIG };
|
||||
|
||||
StringRef getCanonicalArchName(StringRef Arch);
|
||||
// v6/v7/v8 Profile
|
||||
enum ProfileKind { PK_INVALID = 0, PK_A, PK_R, PK_M };
|
||||
|
||||
// Information by ID
|
||||
const char * getFPUName(unsigned FPUKind);
|
||||
unsigned getFPUVersion(unsigned FPUKind);
|
||||
unsigned getFPUNeonSupportLevel(unsigned FPUKind);
|
||||
unsigned getFPURestriction(unsigned FPUKind);
|
||||
unsigned getDefaultFPU(StringRef CPU);
|
||||
// FIXME: This should be moved to TargetTuple once it exists
|
||||
bool getFPUFeatures(unsigned FPUKind, std::vector<const char *> &Features);
|
||||
bool getHWDivFeatures(unsigned HWDivKind,
|
||||
std::vector<const char *> &Features);
|
||||
const char *getArchName(unsigned ArchKind);
|
||||
unsigned getArchAttr(unsigned ArchKind);
|
||||
const char *getCPUAttr(unsigned ArchKind);
|
||||
const char *getSubArch(unsigned ArchKind);
|
||||
const char *getArchExtName(unsigned ArchExtKind);
|
||||
const char *getHWDivName(unsigned HWDivKind);
|
||||
const char *getDefaultCPU(StringRef Arch);
|
||||
StringRef getCanonicalArchName(StringRef Arch);
|
||||
|
||||
// Parser
|
||||
unsigned parseHWDiv(StringRef HWDiv);
|
||||
unsigned parseFPU(StringRef FPU);
|
||||
unsigned parseArch(StringRef Arch);
|
||||
unsigned parseArchExt(StringRef ArchExt);
|
||||
unsigned parseCPUArch(StringRef CPU);
|
||||
unsigned parseArchISA(StringRef Arch);
|
||||
unsigned parseArchEndian(StringRef Arch);
|
||||
unsigned parseArchProfile(StringRef Arch);
|
||||
unsigned parseArchVersion(StringRef Arch);
|
||||
// Information by ID
|
||||
const char *getFPUName(unsigned FPUKind);
|
||||
unsigned getFPUVersion(unsigned FPUKind);
|
||||
unsigned getFPUNeonSupportLevel(unsigned FPUKind);
|
||||
unsigned getFPURestriction(unsigned FPUKind);
|
||||
unsigned getDefaultFPU(StringRef CPU);
|
||||
// FIXME: This should be moved to TargetTuple once it exists
|
||||
bool getFPUFeatures(unsigned FPUKind, std::vector<const char *> &Features);
|
||||
bool getHWDivFeatures(unsigned HWDivKind, std::vector<const char *> &Features);
|
||||
const char *getArchName(unsigned ArchKind);
|
||||
unsigned getArchAttr(unsigned ArchKind);
|
||||
const char *getCPUAttr(unsigned ArchKind);
|
||||
const char *getSubArch(unsigned ArchKind);
|
||||
const char *getArchExtName(unsigned ArchExtKind);
|
||||
const char *getHWDivName(unsigned HWDivKind);
|
||||
const char *getDefaultCPU(StringRef Arch);
|
||||
|
||||
// Parser
|
||||
unsigned parseHWDiv(StringRef HWDiv);
|
||||
unsigned parseFPU(StringRef FPU);
|
||||
unsigned parseArch(StringRef Arch);
|
||||
unsigned parseArchExt(StringRef ArchExt);
|
||||
unsigned parseCPUArch(StringRef CPU);
|
||||
unsigned parseArchISA(StringRef Arch);
|
||||
unsigned parseArchEndian(StringRef Arch);
|
||||
unsigned parseArchProfile(StringRef Arch);
|
||||
unsigned parseArchVersion(StringRef Arch);
|
||||
|
||||
} // namespace ARM
|
||||
} // namespace llvm
|
||||
|
|
|
@ -282,12 +282,12 @@ unsigned llvm::ARM::getDefaultFPU(StringRef CPU) {
|
|||
}
|
||||
|
||||
bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
|
||||
std::vector<const char *> &Features) {
|
||||
std::vector<const char *> &Features) {
|
||||
|
||||
if (HWDivKind == ARM::AEK_INVALID)
|
||||
return false;
|
||||
|
||||
if (HWDivKind & ARM::AEK_HWDIVARM)
|
||||
if (HWDivKind & ARM::AEK_HWDIVARM)
|
||||
Features.push_back("+hwdiv-arm");
|
||||
else
|
||||
Features.push_back("-hwdiv-arm");
|
||||
|
@ -301,7 +301,7 @@ bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
|
|||
}
|
||||
|
||||
bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
|
||||
std::vector<const char *> &Features) {
|
||||
std::vector<const char *> &Features) {
|
||||
|
||||
if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
|
||||
return false;
|
||||
|
@ -440,38 +440,38 @@ const char *llvm::ARM::getDefaultCPU(StringRef Arch) {
|
|||
|
||||
static StringRef getHWDivSynonym(StringRef HWDiv) {
|
||||
return StringSwitch<StringRef>(HWDiv)
|
||||
.Case("thumb,arm", "arm,thumb")
|
||||
.Default(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);
|
||||
.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("v6sm", "v6s-m")
|
||||
.Case("v6m", "v6-m")
|
||||
.Case("v7a", "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")
|
||||
.Default(Arch);
|
||||
.Case("v6sm", "v6s-m")
|
||||
.Case("v6m", "v6-m")
|
||||
.Case("v7a", "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")
|
||||
.Default(Arch);
|
||||
}
|
||||
|
||||
// MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
|
||||
|
@ -495,7 +495,7 @@ StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
|
|||
// AArch64 uses "_be", not "eb" suffix.
|
||||
if (A.find("eb") != StringRef::npos)
|
||||
return Error;
|
||||
if (A.substr(offset,3) == "_be")
|
||||
if (A.substr(offset, 3) == "_be")
|
||||
offset += 3;
|
||||
}
|
||||
|
||||
|
@ -515,7 +515,7 @@ StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) {
|
|||
|
||||
// Only match non-marketing names
|
||||
if (offset != StringRef::npos) {
|
||||
// Must start with 'vN'.
|
||||
// Must start with 'vN'.
|
||||
if (A[0] != 'v' || !std::isdigit(A[1]))
|
||||
return Error;
|
||||
// Can't have an extra 'eb'.
|
||||
|
@ -576,16 +576,15 @@ unsigned llvm::ARM::parseCPUArch(StringRef CPU) {
|
|||
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)
|
||||
.StartsWith("arm64", ARM::IK_AARCH64)
|
||||
.StartsWith("thumb", ARM::IK_THUMB)
|
||||
.StartsWith("arm", ARM::IK_ARM)
|
||||
.Default(ARM::EK_INVALID);
|
||||
}
|
||||
|
||||
// Little/Big endian
|
||||
unsigned llvm::ARM::parseArchEndian(StringRef Arch) {
|
||||
if (Arch.startswith("armeb") ||
|
||||
Arch.startswith("thumbeb") ||
|
||||
if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
|
||||
Arch.startswith("aarch64_be"))
|
||||
return ARM::EK_BIG;
|
||||
|
||||
|
@ -605,7 +604,7 @@ unsigned llvm::ARM::parseArchEndian(StringRef Arch) {
|
|||
// Profile A/R/M
|
||||
unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
|
||||
Arch = getCanonicalArchName(Arch);
|
||||
switch(parseArch(Arch)) {
|
||||
switch (parseArch(Arch)) {
|
||||
case ARM::AK_ARMV6M:
|
||||
case ARM::AK_ARMV7M:
|
||||
case ARM::AK_ARMV6SM:
|
||||
|
@ -626,7 +625,7 @@ unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
|
|||
// Version number (ex. v7 = 7).
|
||||
unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
|
||||
Arch = getCanonicalArchName(Arch);
|
||||
switch(parseArch(Arch)) {
|
||||
switch (parseArch(Arch)) {
|
||||
case ARM::AK_ARMV2:
|
||||
case ARM::AK_ARMV2A:
|
||||
return 2;
|
||||
|
|
Loading…
Reference in New Issue