]> granicus.if.org Git - llvm/commitdiff
[AArch64] Implement the .arch_extension directive
authorMartin Storsjo <martin@martin.st>
Sun, 30 Dec 2018 21:06:32 +0000 (21:06 +0000)
committerMartin Storsjo <martin@martin.st>
Sun, 30 Dec 2018 21:06:32 +0000 (21:06 +0000)
Differential Revision: https://reviews.llvm.org/D56131

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350169 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
test/MC/AArch64/directive-arch_extension-nosimd.s [new file with mode: 0644]
test/MC/AArch64/directive-arch_extension-simd.s [new file with mode: 0644]

index 384b474abe82b1359e68fc346f4e6e25df0f6307..d2f78afe0a210264b76d1f80056d3e8161d25394 100644 (file)
@@ -165,6 +165,7 @@ private:
                       OperandVector &Operands);
 
   bool parseDirectiveArch(SMLoc L);
+  bool parseDirectiveArchExtension(SMLoc L);
   bool parseDirectiveCPU(SMLoc L);
   bool parseDirectiveInst(SMLoc L);
 
@@ -5033,6 +5034,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
     parseDirectiveCFINegateRAState();
   else if (IDVal == ".cfi_b_key_frame")
     parseDirectiveCFIBKeyFrame();
+  else if (IDVal == ".arch_extension")
+    parseDirectiveArchExtension(Loc);
   else if (IsMachO) {
     if (IDVal == MCLOHDirectiveName())
       parseDirectiveLOH(IDVal, Loc);
@@ -5153,6 +5156,50 @@ bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
   return false;
 }
 
+/// parseDirectiveArchExtension
+///   ::= .arch_extension [no]feature
+bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
+  MCAsmParser &Parser = getParser();
+
+  if (getLexer().isNot(AsmToken::Identifier))
+    return Error(getLexer().getLoc(), "expected architecture extension name");
+
+  const AsmToken &Tok = Parser.getTok();
+  StringRef Name = Tok.getString();
+  SMLoc ExtLoc = Tok.getLoc();
+  Lex();
+
+  if (parseToken(AsmToken::EndOfStatement,
+                 "unexpected token in '.arch_extension' directive"))
+    return true;
+
+  bool EnableFeature = true;
+  if (Name.startswith_lower("no")) {
+    EnableFeature = false;
+    Name = Name.substr(2);
+  }
+
+  MCSubtargetInfo &STI = copySTI();
+  FeatureBitset Features = STI.getFeatureBits();
+  for (const auto &Extension : ExtensionMap) {
+    if (Extension.Name != Name)
+      continue;
+
+    if (Extension.Features.none())
+      return Error(ExtLoc, "unsupported architectural extension: " + Name);
+
+    FeatureBitset ToggleFeatures = EnableFeature
+                                       ? (~Features & Extension.Features)
+                                       : (Features & Extension.Features);
+    uint64_t Features =
+        ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
+    setAvailableFeatures(Features);
+    return false;
+  }
+
+  return Error(ExtLoc, "unknown architectural extension: " + Name);
+}
+
 static SMLoc incrementLoc(SMLoc L, int Offset) {
   return SMLoc::getFromPointer(L.getPointer() + Offset);
 }
diff --git a/test/MC/AArch64/directive-arch_extension-nosimd.s b/test/MC/AArch64/directive-arch_extension-nosimd.s
new file mode 100644 (file)
index 0000000..cbc03d0
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+       .arch_extension nosimd
+
+       add v0.8b, v0.8b, v0.8b
+// CHECK: error: instruction requires: neon
diff --git a/test/MC/AArch64/directive-arch_extension-simd.s b/test/MC/AArch64/directive-arch_extension-simd.s
new file mode 100644 (file)
index 0000000..04ebeee
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: llvm-mc -triple aarch64 -mattr=-simd -filetype asm -o - %s | FileCheck %s
+
+       .arch_extension simd
+
+       add v0.8b, v0.8b, v0.8b
+// CHECK: add v0.8b, v0.8b, v0.8b