Skip to content

Commit

Permalink
[AArch64] Merge duplicate extension information.
Browse files Browse the repository at this point in the history
When we moved the extension information into tablegen in #90987, some
features (FEAT_DPB, FEAT_DPB2, FEAT_FLAGM2, FEAT_FRINTTS, FEAT_RCPC2)
were defined as FMVOnlyExtension despite already having an equivalent
SubtargetFeature in place. This patch is fusing these duplications.

As a result these features are no longer AEK_NONE, which means they
would become available to the command line. Since we don't want that
I added a new field in ExtensionInfo to indicate whether a feature
IsFMVOnly. That made the class FMVOnlyExtension redundant so I have
removed it from tablegen.

To reject such features on the command line but have them accepted
in attribute strings we need two different parsing functions. I made
parseArchExtension skip over IsFMVOnly entries and created a new one
called parseFMVExtension which doesn't skip them.

Making all extensions have ArchExtKind != AEK_NONE is a stepping stone
towards deprecating DependentFeatures from ExtensionInfo completely,
since we will be able to express them through ExtensionDependency.
  • Loading branch information
labrinea committed May 17, 2024
1 parent c7c5666 commit 0c00fc2
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 77 deletions.
8 changes: 4 additions & 4 deletions clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const {
if (Name == "default")
return 0;
if (auto Ext = llvm::AArch64::parseArchExtension(Name))
if (auto Ext = llvm::AArch64::parseFMVExtension(Name))
return Ext->FmvPriority;
return 0;
}
Expand All @@ -670,13 +670,13 @@ unsigned AArch64TargetInfo::multiVersionFeatureCost() const {
}

bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const {
if (auto Ext = llvm::AArch64::parseArchExtension(Name))
if (auto Ext = llvm::AArch64::parseFMVExtension(Name))
return !Ext->DependentFeatures.empty();
return false;
}

StringRef AArch64TargetInfo::getFeatureDependencies(StringRef Name) const {
if (auto Ext = llvm::AArch64::parseArchExtension(Name))
if (auto Ext = llvm::AArch64::parseFMVExtension(Name))
return Ext->DependentFeatures;
return StringRef();
}
Expand All @@ -686,7 +686,7 @@ bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
llvm::SmallVector<StringRef, 8> Features;
FeatureStr.split(Features, "+");
for (auto &Feature : Features)
if (!llvm::AArch64::parseArchExtension(Feature.trim()).has_value())
if (!llvm::AArch64::parseFMVExtension(Feature.trim()).has_value())
return false;
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14259,7 +14259,7 @@ Value *CodeGenFunction::EmitAArch64CpuSupports(const CallExpr *E) {
ArgStr.split(Features, "+");
for (auto &Feature : Features) {
Feature = Feature.trim();
if (!llvm::AArch64::parseArchExtension(Feature))
if (!llvm::AArch64::parseFMVExtension(Feature))
return Builder.getFalse();
if (Feature != "default")
Features.push_back(Feature);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,7 @@ void AArch64ABIInfo::appendAttributeMangling(StringRef AttrStr,

llvm::SmallDenseSet<StringRef, 8> UniqueFeats;
for (auto &Feat : Features)
if (auto Ext = llvm::AArch64::parseArchExtension(Feat))
if (auto Ext = llvm::AArch64::parseFMVExtension(Feat))
if (UniqueFeats.insert(Ext->Name).second)
Out << 'M' << Ext->Name;
}
Expand Down
41 changes: 41 additions & 0 deletions clang/test/Driver/aarch64-fmv-only-feature.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Test that features which are meaningful only for Function Multiversioning are rejected from the command line.

// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+dgh %s 2>&1 | FileCheck %s --check-prefix=DGH
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+ebf16 %s 2>&1 | FileCheck %s --check-prefix=EBF16
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+ls64_accdata %s 2>&1 | FileCheck %s --check-prefix=LS64_ACCDATA
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+ls64_v %s 2>&1 | FileCheck %s --check-prefix=LS64_V
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+memtag2 %s 2>&1 | FileCheck %s --check-prefix=MEMTAG2
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+memtag3 %s 2>&1 | FileCheck %s --check-prefix=MEMTAG3
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+pmull %s 2>&1 | FileCheck %s --check-prefix=PMULL
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+rpres %s 2>&1 | FileCheck %s --check-prefix=RPRES
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+sha1 %s 2>&1 | FileCheck %s --check-prefix=SHA1
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+ssbs2 %s 2>&1 | FileCheck %s --check-prefix=SSBS2
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+sve-bf16 %s 2>&1 | FileCheck %s --check-prefix=SVE_BF16
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+sve-ebf16 %s 2>&1 | FileCheck %s --check-prefix=SVE_EBF16
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+sve-i8mm %s 2>&1 | FileCheck %s --check-prefix=SVE_I8MM
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+sve2-pmull128 %s 2>&1 | FileCheck %s --check-prefix=SVE2_PMULL128
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+dpb %s 2>&1 | FileCheck %s --check-prefix=DPB
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+rcpc2 %s 2>&1 | FileCheck %s --check-prefix=RCPC2
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+flagm2 %s 2>&1 | FileCheck %s --check-prefix=FLAGM2
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+frintts %s 2>&1 | FileCheck %s --check-prefix=FRINTTS
// RUN: not %clang --target=aarch64-linux-gnu -march=armv8-a+dpb2 %s 2>&1 | FileCheck %s --check-prefix=DPB2

// DGH: error: unsupported argument 'armv8-a+dgh' to option '-march='
// EBF16: error: unsupported argument 'armv8-a+ebf16' to option '-march='
// LS64_ACCDATA: error: unsupported argument 'armv8-a+ls64_accdata' to option '-march='
// LS64_V: error: unsupported argument 'armv8-a+ls64_v' to option '-march='
// MEMTAG2: error: unsupported argument 'armv8-a+memtag2' to option '-march='
// MEMTAG3: error: unsupported argument 'armv8-a+memtag3' to option '-march='
// PMULL: error: unsupported argument 'armv8-a+pmull' to option '-march='
// RPRES: error: unsupported argument 'armv8-a+rpres' to option '-march='
// SHA1: error: unsupported argument 'armv8-a+sha1' to option '-march='
// SSBS2: error: unsupported argument 'armv8-a+ssbs2' to option '-march='
// SVE_BF16: error: unsupported argument 'armv8-a+sve-bf16' to option '-march='
// SVE_EBF16: error: unsupported argument 'armv8-a+sve-ebf16' to option '-march='
// SVE_I8MM: error: unsupported argument 'armv8-a+sve-i8mm' to option '-march='
// SVE2_PMULL128: error: unsupported argument 'armv8-a+sve2-pmull128' to option '-march='
// DPB: error: unsupported argument 'armv8-a+dpb' to option '-march='
// RCPC2: error: unsupported argument 'armv8-a+rcpc2' to option '-march='
// FLAGM2: error: unsupported argument 'armv8-a+flagm2' to option '-march='
// FRINTTS: error: unsupported argument 'armv8-a+frintts' to option '-march='
// DPB2: error: unsupported argument 'armv8-a+dpb2' to option '-march='
21 changes: 12 additions & 9 deletions llvm/include/llvm/TargetParser/AArch64TargetParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,22 +109,24 @@ static_assert(FEAT_MAX < 62,

using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>;

// Represents an extension that can be enabled with -march=<arch>+<extension>.
// Typically these correspond to Arm Architecture extensions, unlike
// SubtargetFeature which may represent either an actual extension or some
// internal LLVM property.
// Represents an extension that can be enabled with -march=<arch>+<extension>,
// or via a Function Multiversion (FMV) attribute. Typically these correspond
// to Arm Architecture extensions, unlike SubtargetFeature which may represent
// either an actual extension or some internal LLVM property.
struct ExtensionInfo {
StringRef Name; // Human readable name, e.g. "profile".
std::optional<StringRef> Alias; // An alias for this extension, if one exists.
ArchExtKind ID; // Corresponding to the ArchExtKind, this
// extensions representation in the bitfield.
StringRef Feature; // -mattr enable string, e.g. "+spe"
StringRef NegFeature; // -mattr disable string, e.g. "-spe"
CPUFeatures CPUFeature; // Function Multi Versioning (FMV) bitfield value
// set in __aarch64_cpu_features
StringRef DependentFeatures; // FMV enabled features string,
// e.g. "+dotprod,+fp-armv8,+neon"
unsigned FmvPriority; // FMV feature priority
bool IsFMVOnly; // Flag indicating whether the extension is
// available on the command line or not.
CPUFeatures CPUFeature; // FMV bitfield value set in
// __aarch64_cpu_features
StringRef DependentFeatures; // FMV enabled features string,
// e.g. "+dotprod,+fp-armv8,+neon"
unsigned FmvPriority; // FMV feature priority
static constexpr unsigned MaxFMVPriority =
1000; // Maximum priority for FMV feature
};
Expand Down Expand Up @@ -690,6 +692,7 @@ const ArchInfo *getArchForCpu(StringRef CPU);
// Parser
const ArchInfo *parseArch(StringRef Arch);
std::optional<ExtensionInfo> parseArchExtension(StringRef Extension);
std::optional<ExtensionInfo> parseFMVExtension(StringRef Extension);
// Given the name of a CPU or alias, return the correponding CpuInfo.
std::optional<CpuInfo> parseCpu(StringRef Name);
// Used by target parser tests
Expand Down
139 changes: 82 additions & 57 deletions llvm/lib/Target/AArch64/AArch64Features.td
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,12 @@
//
//===----------------------------------------------------------------------===//

// A SubtargetFeature that can be toggled from the command line, and therefore
// has an AEK_* entry in ArmExtKind.
// A SubtargetFeature that can be toggled from the command line, or be part of
// a Function Multiversioning (FMV) attribute string.
//
// If Function MultiVersioning (FMV) properties are left at their defaults
// (FEAT_INIT, no dependencies, priority 0) it indiates that this extension is
// not an FMV feature, but can be enabled via the command line (-march, -mcpu,
// etc).
//
// Conversely if the ArchExtKindSpelling is set to AEK_NONE, this indicates
// that a feature is FMV-only, and can not be selected on the command line.
// Such extensions should be added via FMVOnlyExtension.
// If FMV properties are left at their defaults (FEAT_INIT, no dependencies,
// priority 0) it indiates that this extension is not an FMV feature, but can
// be enabled via the command line (-march, -mcpu, etc).
class Extension<
string TargetFeatureName, // String used for -target-feature and -march, unless overridden.
string Spelling, // The XYZ in HasXYZ and AEK_XYZ.
Expand All @@ -28,7 +23,8 @@ class Extension<
// FMV properties
string _FMVBit = "FEAT_INIT", // FEAT_INIT is repurposed to indicate "not an FMV feature"
string _FMVDependencies = "",
int _FMVPriority = 0
int _FMVPriority = 0,
string _IsFMVOnly = "false" // Indicates if the extension is available on the command line.
> : SubtargetFeature<TargetFeatureName, "Has" # Spelling, "true", Desc, Implies>
{
string ArchExtKindSpelling = "AEK_" # Spelling; // ArchExtKind enum name.
Expand All @@ -43,7 +39,7 @@ class Extension<
// Used for correcting historical names while remaining backwards compatible.
string MArchAlias = "";

// Function MultiVersioning (FMV) properties
// Function Multiversioning (FMV) properties

// A C++ expression giving the number of the bit in the FMV ABI.
// Currently this is given as a value from the enum "CPUFeatures".
Expand All @@ -56,43 +52,64 @@ class Extension<

// The FMV priority
int FMVPriority = _FMVPriority;

// Indicates if the extension is available on the command line.
string IsFMVOnly = _IsFMVOnly;
}

// Some extensions are available for FMV but can not be controlled via the
// command line. These entries:
// - are SubtargetFeatures, so they have (unused) FieldNames on the subtarget
// e.g. HasFMVOnlyFEAT_XYZ
// - have incorrect (empty) Implies fields, because the code that handles FMV
// ignores these dependencies and looks only at FMVDependencies.
// - have no description.
//
// In the generated data structures for extensions (ExtensionInfo), AEK_NONE is
// used to indicate that a feature is FMV only. Therefore ArchExtKindSpelling is
// manually overridden here.
class FMVOnlyExtension<string FMVBit, string Name, string Deps, int Priority>
: Extension<Name, "FMVOnly"#FMVBit, "", [], FMVBit, Deps, Priority> {
let ArchExtKindSpelling = "AEK_NONE"; // AEK_NONE indicates FMV-only feature
}
// command line, neither have a TargetFeatureName. Since they have no effect
// on their own, their description is left empty. However they can have side
// effects by implying other Subtarget Features. These extensions are used
// in FMV for detection purposes.

let MArchName = "dgh" in
def : Extension<"", "DGH", "", [], "FEAT_DGH", "", 260, "true">;

let MArchName = "ebf16" in
def : Extension<"", "EBF16", "", [], "FEAT_EBF16", "+bf16", 290, "true">;

let MArchName = "ls64_accdata" in
def : Extension<"", "LS64_ACCDATA", "", [], "FEAT_LS64_ACCDATA",
"+ls64", 540, "true">;

let MArchName = "ls64_v" in
def : Extension<"", "LS64_V", "", [], "FEAT_LS64_V", "", 530, "true">;

let MArchName = "memtag2" in
def : Extension<"", "MEMTAG2", "", [], "FEAT_MEMTAG2", "+mte", 450, "true">;

let MArchName = "memtag3" in
def : Extension<"", "MEMTAG3", "", [], "FEAT_MEMTAG3", "+mte", 460, "true">;

let MArchName = "pmull" in
def : Extension<"", "PMULL", "", [], "FEAT_PMULL",
"+aes,+fp-armv8,+neon", 160, "true">;

let MArchName = "rpres" in
def : Extension<"", "RPRES", "", [], "FEAT_RPRES", "", 300, "true">;

let MArchName = "sha1" in
def : Extension<"", "SHA1", "", [], "FEAT_SHA1", "+fp-armv8,+neon", 120, "true">;

let MArchName = "ssbs2" in
def : Extension<"", "SSBS2", "", [], "FEAT_SSBS2", "+ssbs", 500, "true">;

let MArchName = "sve-bf16" in
def : Extension<"", "SVE_BF16", "", [], "FEAT_SVE_BF16",
"+sve,+bf16,+fullfp16,+fp-armv8,+neon", 320, "true">;

let MArchName = "sve-ebf16" in
def : Extension<"", "SVE_EBF16", "", [], "FEAT_SVE_EBF16",
"+sve,+bf16,+fullfp16,+fp-armv8,+neon", 330, "true">;

let MArchName = "sve-i8mm" in
def : Extension<"", "SVE_I8MM", "", [], "FEAT_SVE_I8MM",
"+sve,+i8mm,+fullfp16,+fp-armv8,+neon", 340, "true">;

def : FMVOnlyExtension<"FEAT_DGH", "dgh", "", 260>;
def : FMVOnlyExtension<"FEAT_DPB", "dpb", "+ccpp", 190>;
def : FMVOnlyExtension<"FEAT_DPB2", "dpb2", "+ccpp,+ccdp", 200>;
def : FMVOnlyExtension<"FEAT_EBF16", "ebf16", "+bf16", 290>;
def : FMVOnlyExtension<"FEAT_FLAGM2", "flagm2", "+flagm,+altnzcv", 30>;
def : FMVOnlyExtension<"FEAT_FRINTTS", "frintts", "+fptoint", 250>;
def : FMVOnlyExtension<"FEAT_LS64_ACCDATA", "ls64_accdata", "+ls64", 540>;
def : FMVOnlyExtension<"FEAT_LS64_V", "ls64_v", "", 530>;
def : FMVOnlyExtension<"FEAT_MEMTAG2", "memtag2", "+mte", 450>;
def : FMVOnlyExtension<"FEAT_MEMTAG3", "memtag3", "+mte", 460>;
def : FMVOnlyExtension<"FEAT_PMULL", "pmull", "+aes,+fp-armv8,+neon", 160>;
def : FMVOnlyExtension<"FEAT_RCPC2", "rcpc2", "+rcpc", 240>;
def : FMVOnlyExtension<"FEAT_RPRES", "rpres", "", 300>;
def : FMVOnlyExtension<"FEAT_SHA1", "sha1", "+fp-armv8,+neon", 120>;
def : FMVOnlyExtension<"FEAT_SSBS2", "ssbs2", "+ssbs", 500>;
def : FMVOnlyExtension<"FEAT_SVE_BF16", "sve-bf16", "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 320>;
def : FMVOnlyExtension<"FEAT_SVE_EBF16", "sve-ebf16", "+sve,+bf16,+fullfp16,+fp-armv8,+neon", 330>;
def : FMVOnlyExtension<"FEAT_SVE_I8MM", "sve-i8mm", "+sve,+i8mm,+fullfp16,+fp-armv8,+neon", 340>;
def : FMVOnlyExtension<"FEAT_SVE_PMULL128", "sve2-pmull128", "+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 390>;
let MArchName = "sve2-pmull128" in
def : Extension<"", "SVE_PMULL128", "", [], "FEAT_SVE_PMULL128",
"+sve2,+sve,+sve2-aes,+fullfp16,+fp-armv8,+neon", 390, "true">;


// Each SubtargetFeature which corresponds to an Arm Architecture feature should
Expand Down Expand Up @@ -216,8 +233,10 @@ def FeaturePAN_RWV : SubtargetFeature<
def FeaturePsUAO : SubtargetFeature< "uaops", "HasPsUAO", "true",
"Enable v8.2 UAO PState (FEAT_UAO)">;

def FeatureCCPP : SubtargetFeature<"ccpp", "HasCCPP",
"true", "Enable v8.2 data Cache Clean to Point of Persistence (FEAT_DPB)" >;
let MArchName = "dpb" in
def FeatureCCPP : Extension<"ccpp", "CCPP",
"Enable v8.2 data Cache Clean to Point of Persistence (FEAT_DPB)", [],
"FEAT_DPB", "+ccpp", 190, "true">;

def FeatureSVE : Extension<"sve", "SVE",
"Enable Scalable Vector Extension (SVE) instructions (FEAT_SVE)", [FeatureFullFP16],
Expand Down Expand Up @@ -491,9 +510,10 @@ def FeatureFlagM : Extension<
"FEAT_FLAGM", "+flagm", 20>;

// 8.4 RCPC enchancements: LDAPR & STLR instructions with Immediate Offset
def FeatureRCPC_IMMO : SubtargetFeature<"rcpc-immo", "HasRCPC_IMMO", "true",
let MArchName = "rcpc2" in
def FeatureRCPC_IMMO : Extension<"rcpc-immo", "RCPC_IMMO",
"Enable v8.4-A RCPC instructions with Immediate Offsets (FEAT_LRCPC2)",
[FeatureRCPC]>;
[FeatureRCPC], "FEAT_RCPC2", "+rcpc", 240, "true">;

def FeatureNoNegativeImmediates : SubtargetFeature<"no-neg-immediates",
"NegativeImmediates", "false",
Expand Down Expand Up @@ -525,12 +545,16 @@ def FeatureAggressiveFMA :
"true",
"Enable Aggressive FMA for floating-point.">;

def FeatureAltFPCmp : SubtargetFeature<"altnzcv", "HasAlternativeNZCV", "true",
"Enable alternative NZCV format for floating point comparisons (FEAT_FlagM2)">;
let MArchName = "flagm2" in
def FeatureAltFPCmp : Extension<"altnzcv", "AlternativeNZCV",
"Enable alternative NZCV format for floating point comparisons (FEAT_FlagM2)",
[], "FEAT_FLAGM2", "+flagm,+altnzcv", 30, "true">;

def FeatureFRInt3264 : SubtargetFeature<"fptoint", "HasFRInt3264", "true",
let MArchName = "frintts" in
def FeatureFRInt3264 : Extension<"fptoint", "FRInt3264",
"Enable FRInt[32|64][Z|X] instructions that round a floating-point number to "
"an integer (in FP format) forcing it to fit into a 32- or 64-bit int (FEAT_FRINTTS)" >;
"an integer (in FP format) forcing it to fit into a 32- or 64-bit int (FEAT_FRINTTS)",
[], "FEAT_FRINTTS", "+fptoint", 250, "true">;

def FeatureSpecRestrict : SubtargetFeature<"specrestrict", "HasSpecRestrict",
"true", "Enable architectural speculation restriction (FEAT_CSV2_2)">;
Expand All @@ -547,13 +571,14 @@ def FeaturePredRes : Extension<"predres", "PredRes",
"Enable v8.5a execution and data prediction invalidation instructions (FEAT_SPECRES)", [],
"FEAT_PREDRES", "+predres", 480>;

def FeatureCacheDeepPersist : SubtargetFeature<"ccdp", "CCDP", "true",
"Enable v8.5 Cache Clean to Point of Deep Persistence (FEAT_DPB2)" >;
let MArchName = "dpb2" in
def FeatureCacheDeepPersist : Extension<"ccdp", "CCDP",
"Enable v8.5 Cache Clean to Point of Deep Persistence (FEAT_DPB2)", [],
"FEAT_DPB2", "+ccpp,+ccdp", 200, "true">;

let ArchExtKindSpelling = "AEK_NONE" in
def FeatureBranchTargetId : Extension<"bti", "BTI",
"Enable Branch Target Identification (FEAT_BTI)", [],
"FEAT_BTI", "+bti", 510>;
"FEAT_BTI", "+bti", 510, "true">;

let ArchExtKindSpelling = "AEK_RAND", MArchName = "rng" in
def FeatureRandGen : Extension<"rand", "RandGen",
Expand Down
13 changes: 12 additions & 1 deletion llvm/lib/TargetParser/AArch64TargetParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ std::optional<AArch64::ArchInfo> AArch64::ArchInfo::findBySubArch(StringRef SubA
uint64_t AArch64::getCpuSupportsMask(ArrayRef<StringRef> FeatureStrs) {
uint64_t FeaturesMask = 0;
for (const StringRef &FeatureStr : FeatureStrs) {
if (auto Ext = parseArchExtension(FeatureStr))
if (auto Ext = parseFMVExtension(FeatureStr))
FeaturesMask |= (1ULL << Ext->CPUFeature);
}
return FeaturesMask;
Expand Down Expand Up @@ -116,12 +116,23 @@ const AArch64::ArchInfo *AArch64::parseArch(StringRef Arch) {
std::optional<AArch64::ExtensionInfo>
AArch64::parseArchExtension(StringRef ArchExt) {
for (const auto &A : Extensions) {
if (A.IsFMVOnly)
continue;
if (ArchExt == A.Name || ArchExt == A.Alias)
return A;
}
return {};
}

std::optional<AArch64::ExtensionInfo>
AArch64::parseFMVExtension(StringRef FMVExt) {
for (const auto &E : Extensions) {
if (FMVExt == E.Name || FMVExt == E.Alias)
return E;
}
return {};
}

std::optional<AArch64::CpuInfo> AArch64::parseCpu(StringRef Name) {
// Resolve aliases first.
Name = resolveCPUAlias(Name);
Expand Down
Loading

0 comments on commit 0c00fc2

Please sign in to comment.