mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-03-05 00:48:08 +00:00
[AArch64] Add all predecessor archs in target info
A given function is compatible with all previous arch versions. To avoid compering values of the attribute this logic adds all predecessor architecture values. Reviewed By: dmgreen, DavidSpickett Differential Revision: https://reviews.llvm.org/D134353
This commit is contained in:
parent
97dfa53626
commit
712de9d171
@ -529,6 +529,22 @@ bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
|
||||
.Default(false);
|
||||
}
|
||||
|
||||
void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
|
||||
StringRef Name, bool Enabled) const {
|
||||
Features[Name] = Enabled;
|
||||
llvm::AArch64::ArchKind AK = llvm::AArch64::getSubArchArchKind(Name);
|
||||
// Add all previous architecture versions.
|
||||
// In case of v9.x the v8.x counterparts are added too.
|
||||
if ("9" == getArchVersionString(AK))
|
||||
for (llvm::AArch64::ArchKind I = llvm::AArch64::convertV9toV8(AK);
|
||||
I != llvm::AArch64::ArchKind::INVALID; --I)
|
||||
Features[llvm::AArch64::getSubArch(I)] = Enabled;
|
||||
|
||||
for (llvm::AArch64::ArchKind I = --AK; I != llvm::AArch64::ArchKind::INVALID;
|
||||
--I)
|
||||
Features[llvm::AArch64::getSubArch(I)] = Enabled;
|
||||
}
|
||||
|
||||
bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
||||
DiagnosticsEngine &Diags) {
|
||||
FPU = FPUMode;
|
||||
@ -620,31 +636,32 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
|
||||
HasSM4 = true;
|
||||
if (Feature == "+strict-align")
|
||||
HasUnaligned = false;
|
||||
if (Feature == "+v8a")
|
||||
// All predecessor archs are added but select the latest one for ArchKind.
|
||||
if (Feature == "+v8a" && ArchKind < llvm::AArch64::ArchKind::ARMV8A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV8A;
|
||||
if (Feature == "+v8.1a")
|
||||
if (Feature == "+v8.1a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_1A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
|
||||
if (Feature == "+v8.2a")
|
||||
if (Feature == "+v8.2a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_2A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
|
||||
if (Feature == "+v8.3a")
|
||||
if (Feature == "+v8.3a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_3A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
|
||||
if (Feature == "+v8.4a")
|
||||
if (Feature == "+v8.4a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_4A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
|
||||
if (Feature == "+v8.5a")
|
||||
if (Feature == "+v8.5a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_5A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
|
||||
if (Feature == "+v8.6a")
|
||||
if (Feature == "+v8.6a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_6A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV8_6A;
|
||||
if (Feature == "+v8.7a")
|
||||
if (Feature == "+v8.7a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_7A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV8_7A;
|
||||
if (Feature == "+v8.8a")
|
||||
if (Feature == "+v8.8a" && ArchKind < llvm::AArch64::ArchKind::ARMV8_8A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV8_8A;
|
||||
if (Feature == "+v9a")
|
||||
if (Feature == "+v9a" && ArchKind < llvm::AArch64::ArchKind::ARMV9A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV9A;
|
||||
if (Feature == "+v9.1a")
|
||||
if (Feature == "+v9.1a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_1A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV9_1A;
|
||||
if (Feature == "+v9.2a")
|
||||
if (Feature == "+v9.2a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_2A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV9_2A;
|
||||
if (Feature == "+v9.3a")
|
||||
if (Feature == "+v9.3a" && ArchKind < llvm::AArch64::ArchKind::ARMV9_3A)
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV9_3A;
|
||||
if (Feature == "+v8r")
|
||||
ArchKind = llvm::AArch64::ArchKind::ARMV8R;
|
||||
|
@ -114,6 +114,8 @@ public:
|
||||
getVScaleRange(const LangOptions &LangOpts) const override;
|
||||
|
||||
bool hasFeature(StringRef Feature) const override;
|
||||
void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
|
||||
bool Enabled) const override;
|
||||
bool handleTargetFeatures(std::vector<std::string> &Features,
|
||||
DiagnosticsEngine &Diags) override;
|
||||
|
||||
|
71
clang/test/CodeGen/aarch64-subarch-compatbility.c
Normal file
71
clang/test/CodeGen/aarch64-subarch-compatbility.c
Normal file
@ -0,0 +1,71 @@
|
||||
// REQUIRES: aarch64-registered-target
|
||||
// RUN: %clang -target aarch64-none-linux -march=armv9.3-a -o %t -c %s 2>&1 | FileCheck --allow-empty %s
|
||||
|
||||
// Successor targets should be ableto call predecessor target functions.
|
||||
__attribute__((__always_inline__,target("v8a")))
|
||||
int armv80(int i) {
|
||||
return i + 42;
|
||||
}
|
||||
|
||||
__attribute__((__always_inline__,target("v8.1a")))
|
||||
int armv81(int i) {
|
||||
return armv80(i);
|
||||
}
|
||||
|
||||
__attribute__((__always_inline__,target("v8.2a")))
|
||||
int armv82(int i) {
|
||||
return armv81(i);
|
||||
}
|
||||
|
||||
__attribute__((__always_inline__,target("v8.3a")))
|
||||
int armv83(int i) {
|
||||
return armv82(i);
|
||||
}
|
||||
|
||||
__attribute__((__always_inline__,target("v8.4a")))
|
||||
int armv84(int i) {
|
||||
return armv83(i);
|
||||
}
|
||||
|
||||
__attribute__((__always_inline__,target("v8.5a")))
|
||||
int armv85(int i) {
|
||||
return armv84(i);
|
||||
}
|
||||
|
||||
__attribute__((__always_inline__,target("v8.6a")))
|
||||
int armv86(int i) {
|
||||
return armv85(i);
|
||||
}
|
||||
|
||||
__attribute__((__always_inline__,target("v8.7a")))
|
||||
int armv87(int i) {
|
||||
return armv86(i);
|
||||
}
|
||||
|
||||
__attribute__((__always_inline__,target("v8.8a")))
|
||||
int armv88(int i) {
|
||||
return armv87(i);
|
||||
}
|
||||
|
||||
__attribute__((__always_inline__,target("v9a")))
|
||||
int armv9(int i) {
|
||||
return armv85(i);
|
||||
}
|
||||
|
||||
__attribute__((__always_inline__,target("v9.1a")))
|
||||
int armv91(int i) {
|
||||
return armv9(i);
|
||||
}
|
||||
|
||||
__attribute__((__always_inline__,target("v9.2a")))
|
||||
int armv92(int i) {
|
||||
return armv91(i);
|
||||
}
|
||||
|
||||
__attribute__((__always_inline__,target("v9.3a")))
|
||||
int armv93(int i) {
|
||||
return armv92(i);
|
||||
}
|
||||
|
||||
// CHECK-NOT: always_inline function {{.*}} requires target feature {{.*}}, but would be inlined into function {{.*}} that is compiled without support for {{.*}}
|
||||
// CHECK-NOT: {{.*}} is not a recognized feature for this target
|
@ -15,6 +15,8 @@
|
||||
#ifndef AARCH64_ARCH
|
||||
#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT)
|
||||
#endif
|
||||
// NOTE: The order and the grouping of the elements matter to make ArchKind iterable.
|
||||
// List is organised as armv8a -> armv8n-a, armv9a -> armv9m-a and armv8-r.
|
||||
AARCH64_ARCH("invalid", INVALID, "", "",
|
||||
ARMBuildAttrs::CPUArch::v8_A, FK_NONE, AArch64::AEK_NONE)
|
||||
AARCH64_ARCH("armv8-a", ARMV8A, "8-A", "v8a", ARMBuildAttrs::CPUArch::v8_A,
|
||||
|
@ -113,6 +113,17 @@ const ArchKind ArchKinds[] = {
|
||||
#include "AArch64TargetParser.def"
|
||||
};
|
||||
|
||||
inline ArchKind &operator--(ArchKind &Kind) {
|
||||
if ((Kind == ArchKind::INVALID) || (Kind == ArchKind::ARMV8A) ||
|
||||
(Kind == ArchKind::ARMV9A) || (Kind == ArchKind::ARMV8R))
|
||||
Kind = ArchKind::INVALID;
|
||||
else {
|
||||
unsigned KindAsInteger = static_cast<unsigned>(Kind);
|
||||
Kind = static_cast<ArchKind>(--KindAsInteger);
|
||||
}
|
||||
return Kind;
|
||||
}
|
||||
|
||||
// FIXME: These should be moved to TargetTuple once it exists
|
||||
bool getExtensionFeatures(uint64_t Extensions,
|
||||
std::vector<StringRef> &Features);
|
||||
@ -124,12 +135,14 @@ StringRef getCPUAttr(ArchKind AK);
|
||||
StringRef getSubArch(ArchKind AK);
|
||||
StringRef getArchExtName(unsigned ArchExtKind);
|
||||
StringRef getArchExtFeature(StringRef ArchExt);
|
||||
ArchKind convertV9toV8(ArchKind AK);
|
||||
|
||||
// Information by Name
|
||||
unsigned getDefaultFPU(StringRef CPU, ArchKind AK);
|
||||
uint64_t getDefaultExtensions(StringRef CPU, ArchKind AK);
|
||||
StringRef getDefaultCPU(StringRef Arch);
|
||||
ArchKind getCPUArchKind(StringRef CPU);
|
||||
ArchKind getSubArchArchKind(StringRef SubArch);
|
||||
|
||||
// Parser
|
||||
ArchKind parseArch(StringRef Arch);
|
||||
|
@ -59,6 +59,15 @@ AArch64::ArchKind AArch64::getCPUArchKind(StringRef CPU) {
|
||||
.Default(ArchKind::INVALID);
|
||||
}
|
||||
|
||||
AArch64::ArchKind AArch64::getSubArchArchKind(StringRef SubArch) {
|
||||
return StringSwitch<AArch64::ArchKind>(SubArch)
|
||||
#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, \
|
||||
ARCH_BASE_EXT) \
|
||||
.Case(SUB_ARCH, ArchKind::ID)
|
||||
#include "../../include/llvm/Support/AArch64TargetParser.def"
|
||||
.Default(ArchKind::INVALID);
|
||||
}
|
||||
|
||||
bool AArch64::getExtensionFeatures(uint64_t Extensions,
|
||||
std::vector<StringRef> &Features) {
|
||||
if (Extensions == AArch64::AEK_INVALID)
|
||||
@ -123,6 +132,19 @@ StringRef AArch64::getArchExtFeature(StringRef ArchExt) {
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
AArch64::ArchKind AArch64::convertV9toV8(AArch64::ArchKind AK) {
|
||||
if (AK == AArch64::ArchKind::INVALID)
|
||||
return AK;
|
||||
if (AK < AArch64::ArchKind::ARMV9A)
|
||||
return AK;
|
||||
if (AK >= AArch64::ArchKind::ARMV8R)
|
||||
return AArch64::ArchKind::INVALID;
|
||||
unsigned AK_v8 = static_cast<unsigned>(AArch64::ArchKind::ARMV8_5A);
|
||||
AK_v8 += static_cast<unsigned>(AK) -
|
||||
static_cast<unsigned>(AArch64::ArchKind::ARMV9A);
|
||||
return static_cast<AArch64::ArchKind>(AK_v8);
|
||||
}
|
||||
|
||||
StringRef AArch64::getDefaultCPU(StringRef Arch) {
|
||||
ArchKind AK = parseArch(Arch);
|
||||
if (AK == ArchKind::INVALID)
|
||||
|
@ -1584,6 +1584,27 @@ TEST(TargetParserTest, AArch64ArchFeatures) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TargetParserTest, AArch64ArchV9toV8Conversion) {
|
||||
for (auto AK : AArch64::ArchKinds) {
|
||||
if (AK == AArch64::ArchKind::INVALID)
|
||||
EXPECT_EQ(AK, AArch64::convertV9toV8(AK));
|
||||
else if (AK < AArch64::ArchKind::ARMV9A)
|
||||
EXPECT_EQ(AK, AArch64::convertV9toV8(AK));
|
||||
else if (AK >= AArch64::ArchKind::ARMV8R)
|
||||
EXPECT_EQ(AArch64::ArchKind::INVALID, AArch64::convertV9toV8(AK));
|
||||
else
|
||||
EXPECT_TRUE(AArch64::convertV9toV8(AK) < AArch64::ArchKind::ARMV9A);
|
||||
}
|
||||
EXPECT_EQ(AArch64::ArchKind::ARMV8_5A,
|
||||
AArch64::convertV9toV8(AArch64::ArchKind::ARMV9A));
|
||||
EXPECT_EQ(AArch64::ArchKind::ARMV8_6A,
|
||||
AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_1A));
|
||||
EXPECT_EQ(AArch64::ArchKind::ARMV8_7A,
|
||||
AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_2A));
|
||||
EXPECT_EQ(AArch64::ArchKind::ARMV8_8A,
|
||||
AArch64::convertV9toV8(AArch64::ArchKind::ARMV9_3A));
|
||||
}
|
||||
|
||||
TEST(TargetParserTest, AArch64ArchExtFeature) {
|
||||
const char *ArchExt[][4] = {
|
||||
{"crc", "nocrc", "+crc", "-crc"},
|
||||
|
Loading…
x
Reference in New Issue
Block a user