diff options
| author | Saleem Abdulrasool <compnerd@compnerd.org> | 2016-04-02 19:29:52 +0000 |
|---|---|---|
| committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2016-04-02 19:29:52 +0000 |
| commit | 85b43639b1d4d2598d0c1f1f9a3b0c33edd838c8 (patch) | |
| tree | af6ab3d7f11cbbbe3897424bdb2548c201f3d10a /llvm/lib | |
| parent | 8fe7ce590361b8d88c85a4941563665649a8b73f (diff) | |
| download | bcm5719-llvm-85b43639b1d4d2598d0c1f1f9a3b0c33edd838c8.tar.gz bcm5719-llvm-85b43639b1d4d2598d0c1f1f9a3b0c33edd838c8.zip | |
AArch64: support .cpu directive
Add support for the AArch64 .cpu directive. This is a slightly involved
directive since the parameter is actually a variable encoded string. The
general structure is:
<cpu>[[+-]<feature>]*
We now map some of the supported string names for features for internal
representation of feature flags. If we encounter one which we do not support,
bail out as we cannot validate the assembly any longer.
Resolves PR27010.
llvm-svn: 265240
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 4938b38b3b0..a00272dcb5f 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -70,6 +70,7 @@ private: bool Error(SMLoc L, const Twine &Msg) { return getParser().Error(L, Msg); } bool showMatchError(SMLoc Loc, unsigned ErrCode); + bool parseDirectiveCPU(SMLoc L); bool parseDirectiveWord(unsigned Size, SMLoc L); bool parseDirectiveInst(SMLoc L); @@ -4195,6 +4196,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) { StringRef IDVal = DirectiveID.getIdentifier(); SMLoc Loc = DirectiveID.getLoc(); + if (IDVal == ".cpu") + return parseDirectiveCPU(Loc); if (IDVal == ".hword") return parseDirectiveWord(2, Loc); if (IDVal == ".word") @@ -4216,6 +4219,75 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) { return parseDirectiveLOH(IDVal, Loc); } +static const struct { + const char *Name; + const FeatureBitset Features; +} ExtensionMap[] = { + { "crc", {AArch64::FeatureCRC} }, + { "crypto", {AArch64::FeatureCrypto} }, + { "fp", {AArch64::FeatureFPARMv8} }, + { "simd", {AArch64::FeatureNEON} }, + + // FIXME: Unsupported extensions + { "lse", {} }, + { "pan", {} }, + { "lor", {} }, + { "rdma", {} }, + { "profile", {} }, +}; + +/// parseDirectiveCPU +/// ::= .cpu id +bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) { + SMLoc CPULoc = getLoc(); + + StringRef CPU, ExtensionString; + std::tie(CPU, ExtensionString) = + getParser().parseStringToEndOfStatement().trim().split('+'); + + SmallVector<StringRef, 4> RequestedExtensions; + if (!ExtensionString.empty()) + ExtensionString.split(RequestedExtensions, '+'); + + // FIXME This is using tablegen data, but should be moved to ARMTargetParser + // once that is tablegen'ed + if (!getSTI().isCPUStringValid(CPU)) { + Error(CPULoc, "unknown CPU name"); + return false; + } + + MCSubtargetInfo &STI = copySTI(); + STI.setDefaultFeatures(CPU, ""); + + FeatureBitset Features = STI.getFeatureBits(); + for (auto Name : RequestedExtensions) { + bool EnableFeature = true; + + if (Name.startswith_lower("no")) { + EnableFeature = false; + Name = Name.substr(2); + } + + for (const auto &Extension : ExtensionMap) { + if (Extension.Name != Name) + continue; + + if (Extension.Features.none()) + report_fatal_error("unsupported architectural extension: " + Name); + + FeatureBitset ToggleFeatures = EnableFeature + ? (~Features & Extension.Features) + : ( Features & Extension.Features); + uint64_t Features = + ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures)); + setAvailableFeatures(Features); + + break; + } + } + return false; +} + /// parseDirectiveWord /// ::= .word [ expression (, expression)* ] bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { |

