[AArch64] Add ARMv8.2-A persistent memory instruction
authorOliver Stannard <oliver.stannard@arm.com>
Thu, 26 Nov 2015 15:28:47 +0000 (15:28 +0000)
committerOliver Stannard <oliver.stannard@arm.com>
Thu, 26 Nov 2015 15:28:47 +0000 (15:28 +0000)
ARMv8.2-A adds the "dc cvap" instruction, which is a system instruction
that cleans caches to the point of persistence (for systems that have
persistent memory). It is a required part of ARMv8.2-A, so no additional
subtarget features are required.

Differential Revision: http://reviews.llvm.org/D15016

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

lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h
test/MC/AArch64/armv8.2a-persistent-memory.s [new file with mode: 0644]
test/MC/Disassembler/AArch64/armv8.2a-persistent-memory.txt [new file with mode: 0644]

index e26420f6ed814acd9ee7c51b517690fdb9f21abc..fbf1534954ae4cd4887f89d0e09e1439ac113fce 100644 (file)
@@ -2465,6 +2465,13 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
     } else if (!Op.compare_lower("cisw")) {
       // SYS #0, C7, C14, #2
       SYS_ALIAS(0, 7, 14, 2);
+    } else if (!Op.compare_lower("cvap")) {
+      if (getSTI().getFeatureBits()[AArch64::HasV8_2aOps]) {
+        // SYS #3, C7, C12, #1
+        SYS_ALIAS(3, 7, 12, 1);
+      } else {
+        return TokError("DC CVAP requires ARMv8.2a");
+      }
     } else {
       return TokError("invalid operand for DC instruction");
     }
index f5c27dd8a78b576d69aaa487dd9b6ba116432023..3153fb2d650898c256f2c2ac5f4ad30e00e432eb 100644 (file)
@@ -55,7 +55,7 @@ void AArch64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
   unsigned Opcode = MI->getOpcode();
 
   if (Opcode == AArch64::SYSxt)
-    if (printSysAlias(MI, O)) {
+    if (printSysAlias(MI, STI, O)) {
       printAnnotation(O, Annot);
       return;
     }
@@ -674,7 +674,9 @@ void AArch64AppleInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
   AArch64InstPrinter::printInst(MI, O, Annot, STI);
 }
 
-bool AArch64InstPrinter::printSysAlias(const MCInst *MI, raw_ostream &O) {
+bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
+                                       const MCSubtargetInfo &STI,
+                                       raw_ostream &O) {
 #ifndef NDEBUG
   unsigned Opcode = MI->getOpcode();
   assert(Opcode == AArch64::SYSxt && "Invalid opcode for SYS alias!");
@@ -729,6 +731,11 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI, raw_ostream &O) {
       if (Op1Val == 3 && Op2Val == 1)
         Asm = "dc\tcvau";
       break;
+    case 12:
+      if (Op1Val == 3 && Op2Val == 1 &&
+          (STI.getFeatureBits()[AArch64::HasV8_2aOps]))
+        Asm = "dc\tcvap";
+      break;
     case 14:
       if (Op1Val == 3 && Op2Val == 1)
         Asm = "dc\tcivac";
index 15dee978e2298ac30b46b908f74c7e6d0f1d8ba2..a94721816d3357e45c185e62a4d39767f18803bb 100644 (file)
@@ -48,7 +48,8 @@ public:
                                      unsigned AltIdx = AArch64::NoRegAltName);
 
 protected:
-  bool printSysAlias(const MCInst *MI, raw_ostream &O);
+  bool printSysAlias(const MCInst *MI, const MCSubtargetInfo &STI,
+                     raw_ostream &O);
   // Operand printers
   void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
                     raw_ostream &O);
diff --git a/test/MC/AArch64/armv8.2a-persistent-memory.s b/test/MC/AArch64/armv8.2a-persistent-memory.s
new file mode 100644 (file)
index 0000000..8a7600e
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.2a < %s | FileCheck %s
+// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=-v8.2a < %s 2>&1 | FileCheck %s --check-prefix=ERROR
+
+  dc cvap, x7
+// CHECK: dc cvap, x7   // encoding: [0x27,0x7c,0x0b,0xd5]
+// ERROR: error: DC CVAP requires ARMv8.2a
diff --git a/test/MC/Disassembler/AArch64/armv8.2a-persistent-memory.txt b/test/MC/Disassembler/AArch64/armv8.2a-persistent-memory.txt
new file mode 100644 (file)
index 0000000..58f1f81
--- /dev/null
@@ -0,0 +1,6 @@
+# RUN: llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.2a --disassemble < %s | FileCheck %s
+# RUN: llvm-mc -triple aarch64-none-linux-gnu --disassemble < %s | FileCheck --check-prefix=NO_V82 %s
+
+[0x27,0x7c,0x0b,0xd5]
+# CHECK: dc cvap, x7
+# NO_V82: sys #3, c7, c12, #1, x7