summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp72
-rw-r--r--llvm/test/MC/AArch64/directive-cpu.s63
2 files changed, 135 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) {
diff --git a/llvm/test/MC/AArch64/directive-cpu.s b/llvm/test/MC/AArch64/directive-cpu.s
new file mode 100644
index 00000000000..8e7d4533744
--- /dev/null
+++ b/llvm/test/MC/AArch64/directive-cpu.s
@@ -0,0 +1,63 @@
+// RUN: not llvm-mc -triple aarch64-unknown-none-eabi -filetype asm -o - %s 2>&1 | FileCheck %s
+
+ .cpu generic
+
+ fminnm d0, d0, d1
+
+ .cpu generic+fp
+
+ fminnm d0, d0, d1
+
+ .cpu generic+nofp
+
+ fminnm d0, d0, d1
+
+ .cpu generic+simd
+
+ addp v0.4s, v0.4s, v0.4s
+
+ .cpu generic+nosimd
+
+ addp v0.4s, v0.4s, v0.4s
+
+ .cpu generic+crc
+
+ crc32cx w0, w1, x3
+
+ .cpu generic+nocrc
+
+ crc32cx w0, w1, x3
+
+ .cpu generic+crypto+nocrc
+
+ aesd v0.16b, v2.16b
+
+ .cpu generic+nocrypto+crc
+
+ aesd v0.16b, v2.16b
+
+// NOTE: the errors precede the actual output! The errors appear in order
+// though, so validate by hoisting them to the top and preservering relative
+// ordering
+
+// CHECK: error: instruction requires: fp-armv8
+// CHECK: fminnm d0, d0, d1
+// CHECK: ^
+
+// CHECK: error: instruction requires: neon
+// CHECK: addp v0.4s, v0.4s, v0.4s
+// CHECK: ^
+
+// CHECK: error: instruction requires: crc
+// CHECK: crc32cx w0, w1, x3
+// CHECK: ^
+
+// CHECK: error: instruction requires: crypto
+// CHECK: aesd v0.16b, v2.16b
+// CHECK: ^
+
+// CHECK: fminnm d0, d0, d1
+// CHECK: fminnm d0, d0, d1
+// CHECK: addp v0.4s, v0.4s, v0.4s
+// CHECK: crc32cx w0, w1, x3
+// CHECK: aesd v0.16b, v2.16b
OpenPOWER on IntegriCloud