mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-04 10:30:01 +00:00
Make Triple::parseARMArch use ARMTargetParser
Simplifying Triple::parseARMArch, leaving all the parsing to ARMTargetParser. This commit also adds AArch64 detection to ARMTargetParser canonicalization, and a two RedHat arch names (v{6,7}hl, meaning hard-float / little-endian). Adding enough unit tests to cover the basics. Clang checks fine. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237902 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
897d9bccdc
commit
b6ea67e027
@ -76,7 +76,9 @@ namespace ARM {
|
||||
AK_ARMV5E,
|
||||
AK_ARMV5TEJ,
|
||||
AK_ARMV6SM,
|
||||
AK_ARMV6HL,
|
||||
AK_ARMV7L,
|
||||
AK_ARMV7HL,
|
||||
AK_ARMV7S,
|
||||
AK_ARMV7EM,
|
||||
AK_LAST
|
||||
@ -95,6 +97,21 @@ namespace ARM {
|
||||
AEK_LAST
|
||||
};
|
||||
|
||||
// ISA kinds.
|
||||
enum ISAKind {
|
||||
IK_INVALID = 0,
|
||||
IK_ARM,
|
||||
IK_THUMB,
|
||||
IK_AARCH64
|
||||
};
|
||||
|
||||
// Endianness
|
||||
// FIXME: BE8 vs. BE32?
|
||||
enum EndianKind {
|
||||
EK_INVALID = 0,
|
||||
EK_LITTLE,
|
||||
EK_BIG
|
||||
};
|
||||
} // namespace ARM
|
||||
|
||||
// Target Parsers, one per architecture.
|
||||
@ -118,6 +135,9 @@ public:
|
||||
static unsigned parseArch(StringRef Arch);
|
||||
static unsigned parseArchExt(StringRef ArchExt);
|
||||
static unsigned parseCPUArch(StringRef CPU);
|
||||
static unsigned parseArchISA(StringRef Arch);
|
||||
static unsigned parseArchEndian(StringRef Arch);
|
||||
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
@ -80,8 +80,10 @@ struct {
|
||||
{ "armv5e", ARM::AK_ARMV5E, "5E", ARMBuildAttrs::CPUArch::v5TE },
|
||||
{ "armv5tej", ARM::AK_ARMV5TEJ, "5TE", ARMBuildAttrs::CPUArch::v5TE },
|
||||
{ "armv6sm", ARM::AK_ARMV6SM, "6-M", ARMBuildAttrs::CPUArch::v6_M },
|
||||
{ "armv6hl", ARM::AK_ARMV6HL, "6-M", ARMBuildAttrs::CPUArch::v6_M },
|
||||
{ "armv7e-m", ARM::AK_ARMV7EM, "7E-M", ARMBuildAttrs::CPUArch::v7E_M },
|
||||
{ "armv7l", ARM::AK_ARMV7L, "7-L", ARMBuildAttrs::CPUArch::v7 },
|
||||
{ "armv7hl", ARM::AK_ARMV7HL, "7H-L", ARMBuildAttrs::CPUArch::v7 },
|
||||
{ "armv7s", ARM::AK_ARMV7S, "7-S", ARMBuildAttrs::CPUArch::v7 }
|
||||
};
|
||||
// List of canonical ARCH names (use getARCHSynonym)
|
||||
@ -179,7 +181,9 @@ struct {
|
||||
{ "arm1022e", ARM::AK_ARMV5E, true },
|
||||
{ "arm926ej-s", ARM::AK_ARMV5TEJ, true },
|
||||
{ "cortex-m0", ARM::AK_ARMV6SM, true },
|
||||
{ "arm1176jzf-s", ARM::AK_ARMV6HL, true },
|
||||
{ "cortex-a8", ARM::AK_ARMV7L, true },
|
||||
{ "cortex-a8", ARM::AK_ARMV7HL, true },
|
||||
{ "cortex-m4", ARM::AK_ARMV7EM, true },
|
||||
{ "swift", ARM::AK_ARMV7S, true },
|
||||
// Invalid CPU
|
||||
@ -269,6 +273,7 @@ StringRef ARMTargetParser::getArchSynonym(StringRef Arch) {
|
||||
.Cases("armv8", "v8", "armv8-a")
|
||||
.Cases("armv8a", "v8a", "armv8-a")
|
||||
.Cases("armv8.1a", "v8.1a", "armv8.1-a")
|
||||
.Cases("aarch64", "arm64", "armv8-a")
|
||||
.Default(Arch);
|
||||
}
|
||||
|
||||
@ -278,12 +283,22 @@ StringRef ARMTargetParser::getArchSynonym(StringRef Arch) {
|
||||
StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) {
|
||||
size_t offset = StringRef::npos;
|
||||
StringRef A = Arch;
|
||||
StringRef Error = "";
|
||||
|
||||
// Begins with "arm" / "thumb", move past it.
|
||||
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;
|
||||
@ -301,7 +316,7 @@ StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) {
|
||||
|
||||
// If can't find the arch, return an empty StringRef.
|
||||
if (parseArch(A) == ARM::AK_INVALID)
|
||||
A = A.substr(A.size());
|
||||
return Error;
|
||||
|
||||
// Arch will either be a 'v' name (v7a) or a marketing name (xscale)
|
||||
// or empty, if invalid.
|
||||
@ -343,4 +358,34 @@ unsigned ARMTargetParser::parseCPUArch(StringRef CPU) {
|
||||
return ARM::AK_INVALID;
|
||||
}
|
||||
|
||||
// ARM, Thumb, AArch64
|
||||
unsigned ARMTargetParser::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::EK_INVALID);
|
||||
}
|
||||
|
||||
// Little/Big endian
|
||||
unsigned ARMTargetParser::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;
|
||||
}
|
||||
|
||||
} // namespace llvm
|
||||
|
@ -236,60 +236,54 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
|
||||
.Default(UnknownArch);
|
||||
}
|
||||
|
||||
// FIXME: Use ARMTargetParser. This would require Triple::arm/thumb
|
||||
// to be recogniseable universally.
|
||||
static Triple::ArchType parseARMArch(StringRef ArchName) {
|
||||
size_t offset = StringRef::npos;
|
||||
unsigned ISA = ARMTargetParser::parseArchISA(ArchName);
|
||||
unsigned ENDIAN = ARMTargetParser::parseArchEndian(ArchName);
|
||||
|
||||
Triple::ArchType arch = Triple::UnknownArch;
|
||||
bool isThumb = ArchName.startswith("thumb");
|
||||
|
||||
if (ArchName.equals("arm"))
|
||||
return Triple::arm;
|
||||
if (ArchName.equals("armeb"))
|
||||
return Triple::armeb;
|
||||
if (ArchName.equals("thumb"))
|
||||
return Triple::thumb;
|
||||
if (ArchName.equals("thumbeb"))
|
||||
return Triple::thumbeb;
|
||||
if (ArchName.equals("arm64") || ArchName.equals("aarch64"))
|
||||
return Triple::aarch64;
|
||||
if (ArchName.equals("aarch64_be"))
|
||||
return Triple::aarch64_be;
|
||||
|
||||
if (ArchName.startswith("armv")) {
|
||||
offset = 3;
|
||||
if (ArchName.endswith("eb")) {
|
||||
arch = Triple::armeb;
|
||||
ArchName = ArchName.substr(0, ArchName.size() - 2);
|
||||
} else
|
||||
switch (ENDIAN) {
|
||||
case ARM::EK_LITTLE: {
|
||||
switch (ISA) {
|
||||
case ARM::IK_ARM:
|
||||
arch = Triple::arm;
|
||||
} else if (ArchName.startswith("armebv")) {
|
||||
offset = 5;
|
||||
arch = Triple::armeb;
|
||||
} else if (ArchName.startswith("thumbv")) {
|
||||
offset = 5;
|
||||
if (ArchName.endswith("eb")) {
|
||||
arch = Triple::thumbeb;
|
||||
ArchName = ArchName.substr(0, ArchName.size() - 2);
|
||||
} else
|
||||
break;
|
||||
case ARM::IK_THUMB:
|
||||
arch = Triple::thumb;
|
||||
} else if (ArchName.startswith("thumbebv")) {
|
||||
offset = 7;
|
||||
arch = Triple::thumbeb;
|
||||
break;
|
||||
case ARM::IK_AARCH64:
|
||||
arch = Triple::aarch64;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return StringSwitch<Triple::ArchType>(ArchName.substr(offset))
|
||||
.Cases("v2", "v2a", isThumb ? Triple::UnknownArch : arch)
|
||||
.Cases("v3", "v3m", isThumb ? Triple::UnknownArch : arch)
|
||||
.Cases("v4", "v4t", arch)
|
||||
.Cases("v5", "v5e", "v5t", "v5te", "v5tej", arch)
|
||||
.Cases("v6", "v6hl", "v6j", "v6k", arch)
|
||||
.Cases("v6m", "v6sm", arch)
|
||||
.Cases("v6t2", "v6z", "v6zk", arch)
|
||||
.Cases("v7", "v7a", "v7em", "v7hl", "v7l", arch)
|
||||
.Cases("v7m", "v7r", "v7s", arch)
|
||||
.Cases("v8", "v8a", arch)
|
||||
.Cases("v8.1", "v8.1a", arch)
|
||||
.Default(Triple::UnknownArch);
|
||||
case ARM::EK_BIG: {
|
||||
switch (ISA) {
|
||||
case ARM::IK_ARM:
|
||||
arch = Triple::armeb;
|
||||
break;
|
||||
case ARM::IK_THUMB:
|
||||
arch = Triple::thumbeb;
|
||||
break;
|
||||
case ARM::IK_AARCH64:
|
||||
arch = Triple::aarch64_be;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ArchName = ARMTargetParser::getCanonicalArchName(ArchName);
|
||||
if (ArchName.empty())
|
||||
return Triple::UnknownArch;
|
||||
|
||||
// Thumb only exists in v4+
|
||||
if (ISA == ARM::IK_THUMB &&
|
||||
(ArchName.startswith("v2") || ArchName.startswith("v3")))
|
||||
return Triple::UnknownArch;
|
||||
|
||||
// FIXME: Add isMProfile to ARMTargetParser and
|
||||
// either change armv6m to thumb or UnknownArch.
|
||||
return arch;
|
||||
}
|
||||
|
||||
static Triple::ArchType parseArch(StringRef ArchName) {
|
||||
|
@ -878,4 +878,69 @@ TEST(TripleTest, NormalizeARM) {
|
||||
EXPECT_EQ(Triple::armeb, T.getArch());
|
||||
}
|
||||
|
||||
TEST(TripleTest, ParseARMArch) {
|
||||
// ARM
|
||||
{
|
||||
Triple T = Triple("arm");
|
||||
EXPECT_EQ(Triple::arm, T.getArch());
|
||||
}
|
||||
{
|
||||
Triple T = Triple("armv6t2");
|
||||
EXPECT_EQ(Triple::arm, T.getArch());
|
||||
}
|
||||
{
|
||||
Triple T = Triple("armv8");
|
||||
EXPECT_EQ(Triple::arm, T.getArch());
|
||||
}
|
||||
{
|
||||
Triple T = Triple("armeb");
|
||||
EXPECT_EQ(Triple::armeb, T.getArch());
|
||||
}
|
||||
{
|
||||
Triple T = Triple("armv5eb");
|
||||
EXPECT_EQ(Triple::armeb, T.getArch());
|
||||
}
|
||||
// THUMB
|
||||
{
|
||||
Triple T = Triple("thumb");
|
||||
EXPECT_EQ(Triple::thumb, T.getArch());
|
||||
}
|
||||
{
|
||||
Triple T = Triple("thumbv7a");
|
||||
EXPECT_EQ(Triple::thumb, T.getArch());
|
||||
}
|
||||
{
|
||||
Triple T = Triple("thumbeb");
|
||||
EXPECT_EQ(Triple::thumbeb, T.getArch());
|
||||
}
|
||||
{
|
||||
Triple T = Triple("thumbv4teb");
|
||||
EXPECT_EQ(Triple::thumbeb, T.getArch());
|
||||
}
|
||||
{
|
||||
Triple T = Triple("thumbv2");
|
||||
EXPECT_EQ(Triple::UnknownArch, T.getArch());
|
||||
}
|
||||
// AARCH64
|
||||
{
|
||||
Triple T = Triple("arm64");
|
||||
EXPECT_EQ(Triple::aarch64, T.getArch());
|
||||
}
|
||||
{
|
||||
Triple T = Triple("aarch64");
|
||||
EXPECT_EQ(Triple::aarch64, T.getArch());
|
||||
}
|
||||
{
|
||||
Triple T = Triple("aarch64_be");
|
||||
EXPECT_EQ(Triple::aarch64_be, T.getArch());
|
||||
}
|
||||
{
|
||||
Triple T = Triple("aarch64be");
|
||||
EXPECT_EQ(Triple::UnknownArch, T.getArch());
|
||||
}
|
||||
{
|
||||
Triple T = Triple("arm64be");
|
||||
EXPECT_EQ(Triple::UnknownArch, T.getArch());
|
||||
}
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
Loading…
x
Reference in New Issue
Block a user