summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/ARM/ARMInstrInfo.td27
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp5
-rw-r--r--llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp4
-rw-r--r--llvm/test/MC/ARM/virtexts-arm.s42
-rw-r--r--llvm/test/MC/Disassembler/ARM/virtexts-arm.txt41
5 files changed, 116 insertions, 3 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index a34e3f312c8..a40f9bcd20b 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -2387,6 +2387,33 @@ def RFEIB_UPD : RFEI<1, "rfeib\t$Rn!"> {
let Inst{24-23} = 0b11;
}
+// Hypervisor Call is a system instruction
+let isCall = 1 in {
+def HVC : AInoP< (outs), (ins imm0_65535:$imm), BrFrm, NoItinerary,
+ "hvc", "\t$imm", []>,
+ Requires<[IsARM, HasVirtualization]> {
+ bits<16> imm;
+
+ // Even though HVC isn't predicable, it's encoding includes a condition field.
+ // The instruction is undefined if the condition field is 0xf otherwise it is
+ // unpredictable if it isn't condition AL (0xe).
+ let Inst{31-28} = 0b1110;
+ let Unpredictable{31-28} = 0b1111;
+ let Inst{27-24} = 0b0001;
+ let Inst{23-20} = 0b0100;
+ let Inst{19-8} = imm{15-4};
+ let Inst{7-4} = 0b0111;
+ let Inst{3-0} = imm{3-0};
+}
+}
+
+// Return from exception in Hypervisor mode.
+let isReturn = 1, isBarrier = 1, isTerminator = 1, Defs = [PC] in
+def ERET : ABI<0b0001, (outs), (ins), NoItinerary, "eret", "", []>,
+ Requires<[IsARM, HasVirtualization]> {
+ let Inst{23-0} = 0b011000000000000001101110;
+}
+
//===----------------------------------------------------------------------===//
// Load / Store Instructions.
//
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 0e474c0e153..7dd300d048c 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -5139,7 +5139,8 @@ StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
Mnemonic == "fmuls" || Mnemonic == "vmaxnm" || Mnemonic == "vminnm" ||
Mnemonic == "vcvta" || Mnemonic == "vcvtn" || Mnemonic == "vcvtp" ||
Mnemonic == "vcvtm" || Mnemonic == "vrinta" || Mnemonic == "vrintn" ||
- Mnemonic == "vrintp" || Mnemonic == "vrintm" || Mnemonic.startswith("vsel"))
+ Mnemonic == "vrintp" || Mnemonic == "vrintm" || Mnemonic == "hvc" ||
+ Mnemonic.startswith("vsel"))
return Mnemonic;
// First, split out any predication code. Ignore mnemonics we know aren't
@@ -5244,7 +5245,7 @@ getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst,
Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || Mnemonic == "vcvta" ||
Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || Mnemonic == "vcvtm" ||
Mnemonic == "vrinta" || Mnemonic == "vrintn" || Mnemonic == "vrintp" ||
- Mnemonic == "vrintm" || Mnemonic.startswith("aes") ||
+ Mnemonic == "vrintm" || Mnemonic.startswith("aes") || Mnemonic == "hvc" ||
Mnemonic.startswith("sha1") || Mnemonic.startswith("sha256") ||
(FullInst.startswith("vmull") && FullInst.endswith(".p64"))) {
// These mnemonics are never predicable
diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
index 0570084deb6..a51680c20da 100644
--- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -269,7 +269,7 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
// expressed as a GPRPair, so we have to manually merge them.
// FIXME: We would really like to be able to tablegen'erate this.
case ARM::LDREXD: case ARM::STREXD:
- case ARM::LDAEXD: case ARM::STLEXD:
+ case ARM::LDAEXD: case ARM::STLEXD: {
const MCRegisterClass& MRC = MRI.getRegClass(ARM::GPRRegClassID);
bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD;
unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg();
@@ -290,6 +290,8 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
printInstruction(&NewMI, O);
return;
}
+ break;
+ }
}
printInstruction(MI, O);
diff --git a/llvm/test/MC/ARM/virtexts-arm.s b/llvm/test/MC/ARM/virtexts-arm.s
new file mode 100644
index 00000000000..a67a8fea5c6
--- /dev/null
+++ b/llvm/test/MC/ARM/virtexts-arm.s
@@ -0,0 +1,42 @@
+# RUN: llvm-mc -triple armv7 -mattr=virtualization -show-encoding %s | FileCheck %s --check-prefix=CHECK-ARM
+
+ hvc #1
+ hvc #7
+ hvc #257
+ hvc #65535
+# CHECK-ARM: [0x71,0x00,0x40,0xe1]
+# CHECK-ARM: [0x77,0x00,0x40,0xe1]
+# CHECK-ARM: [0x71,0x10,0x40,0xe1]
+# CHECK-ARM: [0x7f,0xff,0x4f,0xe1]
+
+ eret
+ ereteq
+ eretne
+ ereths
+ eretlo
+ eretmi
+ eretpl
+ eretvs
+ eretvc
+ erethi
+ eretls
+ eretge
+ eretlt
+ eretgt
+ eretle
+# CHECK-ARM: [0x6e,0x00,0x60,0xe1]
+# CHECK-ARM: [0x6e,0x00,0x60,0x01]
+# CHECK-ARM: [0x6e,0x00,0x60,0x11]
+# CHECK-ARM: [0x6e,0x00,0x60,0x21]
+# CHECK-ARM: [0x6e,0x00,0x60,0x31]
+# CHECK-ARM: [0x6e,0x00,0x60,0x41]
+# CHECK-ARM: [0x6e,0x00,0x60,0x51]
+# CHECK-ARM: [0x6e,0x00,0x60,0x61]
+# CHECK-ARM: [0x6e,0x00,0x60,0x71]
+# CHECK-ARM: [0x6e,0x00,0x60,0x81]
+# CHECK-ARM: [0x6e,0x00,0x60,0x91]
+# CHECK-ARM: [0x6e,0x00,0x60,0xa1]
+# CHECK-ARM: [0x6e,0x00,0x60,0xb1]
+# CHECK-ARM: [0x6e,0x00,0x60,0xc1]
+# CHECK-ARM: [0x6e,0x00,0x60,0xd1]
+
diff --git a/llvm/test/MC/Disassembler/ARM/virtexts-arm.txt b/llvm/test/MC/Disassembler/ARM/virtexts-arm.txt
new file mode 100644
index 00000000000..a18466f2d66
--- /dev/null
+++ b/llvm/test/MC/Disassembler/ARM/virtexts-arm.txt
@@ -0,0 +1,41 @@
+# RUN: llvm-mc -disassemble -triple armv7a -mcpu=cortex-a15 %s | FileCheck %s
+
+[0x71,0x00,0x40,0xe1]
+[0x77,0x00,0x40,0xe1]
+[0x71,0x10,0x40,0xe1]
+[0x7f,0xff,0x4f,0xe1]
+# CHECK: hvc #1
+# CHECK: hvc #7
+# CHECK: hvc #257
+# CHECK: hvc #65535
+
+[0x6e,0x00,0x60,0xe1]
+[0x6e,0x00,0x60,0x01]
+[0x6e,0x00,0x60,0x11]
+[0x6e,0x00,0x60,0x21]
+[0x6e,0x00,0x60,0x31]
+[0x6e,0x00,0x60,0x41]
+[0x6e,0x00,0x60,0x51]
+[0x6e,0x00,0x60,0x61]
+[0x6e,0x00,0x60,0x71]
+[0x6e,0x00,0x60,0x81]
+[0x6e,0x00,0x60,0x91]
+[0x6e,0x00,0x60,0xa1]
+[0x6e,0x00,0x60,0xb1]
+[0x6e,0x00,0x60,0xc1]
+[0x6e,0x00,0x60,0xd1]
+# CHECK: eret
+# CHECK: ereteq
+# CHECK: eretne
+# CHECK: ereths
+# CHECK: eretlo
+# CHECK: eretmi
+# CHECK: eretpl
+# CHECK: eretvs
+# CHECK: eretvc
+# CHECK: erethi
+# CHECK: eretls
+# CHECK: eretge
+# CHECK: eretlt
+# CHECK: eretgt
+# CHECK: eretle
OpenPOWER on IntegriCloud