Add Thumb HVC and ERET virtualisation extension instructions.
authorCharlie Turner <charlie.turner@arm.com>
Mon, 1 Dec 2014 08:39:19 +0000 (08:39 +0000)
committerCharlie Turner <charlie.turner@arm.com>
Mon, 1 Dec 2014 08:39:19 +0000 (08:39 +0000)
Patch by Matthew Wahab.

Change-Id: I131f71c1150d5fa797066a18e09d526c19bf9016

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

lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
test/MC/ARM/virtexts-thumb.s [new file with mode: 0644]
test/MC/Disassembler/ARM/virtexts-thumb.txt [new file with mode: 0644]

index 3670c82b121a18291b213d19346410134ea05071..5e41ea1c294d7d285609de1a4f4240a4e46575c0 100644 (file)
@@ -3824,6 +3824,27 @@ def t2SUBS_PC_LR : T2I <(outs), (ins imm0_255:$imm), NoItinerary,
   let Inst{7-0} = imm;
 }
 
+// Hypervisor Call is a system instruction.
+let isCall = 1 in {
+def t2HVC : T2XI <(outs), (ins imm0_65535:$imm16), IIC_Br, "hvc.w\t$imm16", []>,
+      Requires<[IsThumb2, HasVirtualization]>, Sched<[WriteBr]> {
+    bits<16> imm16;
+    let Inst{31-20} = 0b111101111110;
+    let Inst{19-16} = imm16{15-12};
+    let Inst{15-12} = 0b1000;
+    let Inst{11-0} = imm16{11-0};
+}
+}
+
+// Alias for HVC without the ".w" optional width specifier
+def : t2InstAlias<"hvc\t$imm16", (t2HVC imm0_65535:$imm16)>;
+
+// ERET - Return from exception in Hypervisor mode.
+// B9.3.3, B9.3.20: ERET is an alias for "SUBS PC, LR, #0" in an implementation that
+// includes virtualization extensions.
+def t2ERET : InstAlias<"eret${p}", (t2SUBS_PC_LR 0, pred:$p)>,
+             Requires<[IsThumb2, HasVirtualization]>;
+
 //===----------------------------------------------------------------------===//
 // Non-Instruction Patterns
 //
index a51680c20dac123e37d49e1a964f56c86389a5f5..03e4e0a5e17a622d05f1dfb6c8d8d9d219326818 100644 (file)
@@ -291,6 +291,21 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
       return;
     }
     break;
+  }
+    // B9.3.3 ERET (Thumb)
+    // For a target that has Virtualization Extensions, ERET is the preferred
+    // disassembly of SUBS PC, LR, #0
+  case ARM::t2SUBS_PC_LR: {
+    if (MI->getNumOperands() == 3 &&
+        MI->getOperand(0).isImm() &&
+        MI->getOperand(0).getImm() == 0 &&
+        (getAvailableFeatures() & ARM::FeatureVirtualization)) {
+      O << "\teret";
+      printPredicateOperand(MI, 1, O);
+      printAnnotation(O, Annot);
+      return;
+    }
+    break;
   }
   }
 
diff --git a/test/MC/ARM/virtexts-thumb.s b/test/MC/ARM/virtexts-thumb.s
new file mode 100644 (file)
index 0000000..d911e1d
--- /dev/null
@@ -0,0 +1,59 @@
+# RUN: llvm-mc -triple thumbv7 -mattr=virtualization -show-encoding %s | FileCheck %s --check-prefix=CHECK-THUMB
+
+    hvc    #1
+    hvc    #7
+    hvc    #257
+    hvc    #65535
+# CHECK-THUMB: [0xe0,0xf7,0x01,0x80]
+# CHECK-THUMB: [0xe0,0xf7,0x07,0x80]
+# CHECK-THUMB: [0xe0,0xf7,0x01,0x81]
+# CHECK-THUMB: [0xef,0xf7,0xff,0x8f]
+
+    hvc.w    #1
+    hvc.w    #7
+    hvc.w    #257
+    hvc.w    #65535
+# CHECK-THUMB: [0xe0,0xf7,0x01,0x80]
+# CHECK-THUMB: [0xe0,0xf7,0x07,0x80]
+# CHECK-THUMB: [0xe0,0xf7,0x01,0x81]
+# CHECK-THUMB: [0xef,0xf7,0xff,0x8f]
+
+    eret
+    it eq; ereteq
+    it ne; eretne
+    it hs; ereths
+    it lo; eretlo
+    it mi; eretmi
+    it pl; eretpl
+    it vs; eretvs
+    it vc; eretvc
+    it hi; erethi
+    it ls; eretls
+    it ge; eretge
+    it lt; eretlt
+    it gt; eretgt
+    it le; eretle
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
+
+# SUBS PC, LR, #0 should have the same encoding as ERET.
+# The conditional forms can't be tested becuse the ARM assembler parser doesn't
+# accept SUBS<cond> PC, LR, #<imm>, only the unconditonal form is allowed. This
+# is due to the way that the custom parser handles optional operands; see the
+# FIXME in ARM/AsmParser/ARMAsmParser.cpp.
+
+    subs pc, lr, #0
+# CHECK-THUMB: [0xde,0xf3,0x00,0x8f]
diff --git a/test/MC/Disassembler/ARM/virtexts-thumb.txt b/test/MC/Disassembler/ARM/virtexts-thumb.txt
new file mode 100644 (file)
index 0000000..da0f621
--- /dev/null
@@ -0,0 +1,61 @@
+# RUN: llvm-mc -disassemble -triple thumbv7 -mcpu=cortex-a15 %s | FileCheck %s --check-prefix=CHECK-THUMB
+# RUN: not llvm-mc -disassemble -triple thumbv7 -mcpu=cortex-a9 %s 2>&1 | FileCheck %s --check-prefix=CHECK-NOVIRT
+
+[0xe0,0xf7,0x01,0x80]
+[0xe0,0xf7,0x07,0x80]
+[0xe0,0xf7,0x01,0x81]
+[0xef,0xf7,0xff,0x8f]
+# CHECK-THUMB:    hvc.w    #1
+# CHECK-THUMB:    hvc.w    #7
+# CHECK-THUMB:    hvc.w    #257
+# CHECK-THUMB:    hvc.w    #65535
+# CHECK-NOVIRT:    warning: invalid instruction encoding
+# CHECK-NOVIRT:    warning: invalid instruction encoding
+# CHECK-NOVIRT:    warning: invalid instruction encoding
+# CHECK-NOVIRT:    warning: invalid instruction encoding
+
+[0xde,0xf3,0x00,0x8f]
+[0x08,0xbf] [0xde,0xf3,0x00,0x8f]
+[0x18,0xbf] [0xde,0xf3,0x00,0x8f]
+[0x28,0xbf] [0xde,0xf3,0x00,0x8f]
+[0x38,0xbf] [0xde,0xf3,0x00,0x8f]
+[0x48,0xbf] [0xde,0xf3,0x00,0x8f]
+[0x58,0xbf] [0xde,0xf3,0x00,0x8f]
+[0x68,0xbf] [0xde,0xf3,0x00,0x8f]
+[0x78,0xbf] [0xde,0xf3,0x00,0x8f]
+[0x88,0xbf] [0xde,0xf3,0x00,0x8f]
+[0x98,0xbf] [0xde,0xf3,0x00,0x8f]
+[0xa8,0xbf] [0xde,0xf3,0x00,0x8f]
+[0xb8,0xbf] [0xde,0xf3,0x00,0x8f]
+[0xc8,0xbf] [0xde,0xf3,0x00,0x8f]
+[0xd8,0xbf] [0xde,0xf3,0x00,0x8f]
+# CHECK-THUMB:    eret
+# CHECK-THUMB:    ereteq
+# CHECK-THUMB:    eretne
+# CHECK-THUMB:    ereths
+# CHECK-THUMB:    eretlo
+# CHECK-THUMB:    eretmi
+# CHECK-THUMB:    eretpl
+# CHECK-THUMB:    eretvs
+# CHECK-THUMB:    eretvc
+# CHECK-THUMB:    erethi
+# CHECK-THUMB:    eretls
+# CHECK-THUMB:    eretge
+# CHECK-THUMB:    eretlt
+# CHECK-THUMB:    eretgt
+# CHECK-THUMB:    eretle
+# CHECK-NOVIRT:    subs    pc, lr, #0
+# CHECK-NOVIRT:    subseq  pc, lr, #0
+# CHECK-NOVIRT:    subsne  pc, lr, #0
+# CHECK-NOVIRT:    subshs  pc, lr, #0
+# CHECK-NOVIRT:    subslo  pc, lr, #0
+# CHECK-NOVIRT:    subsmi  pc, lr, #0
+# CHECK-NOVIRT:    subspl  pc, lr, #0
+# CHECK-NOVIRT:    subsvs  pc, lr, #0
+# CHECK-NOVIRT:    subsvc  pc, lr, #0
+# CHECK-NOVIRT:    subshi  pc, lr, #0
+# CHECK-NOVIRT:    subsls  pc, lr, #0
+# CHECK-NOVIRT:    subsge  pc, lr, #0
+# CHECK-NOVIRT:    subslt  pc, lr, #0
+# CHECK-NOVIRT:    subsgt  pc, lr, #0
+# CHECK-NOVIRT:    subsle  pc, lr, #0