summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp24
-rw-r--r--llvm/test/MC/Disassembler/ARM/invalid-virtexts.arm.txt10
2 files changed, 33 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index ef6541890bf..99d3331a368 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -405,6 +405,28 @@ static MCDisassembler *createThumbDisassembler(const Target &T,
return new ThumbDisassembler(STI, Ctx);
}
+// Post-decoding checks
+static DecodeStatus checkDecodedInstruction(MCInst &MI, uint64_t &Size,
+ uint64_t Address, raw_ostream &OS,
+ raw_ostream &CS,
+ uint32_t Insn,
+ DecodeStatus Result)
+{
+ switch (MI.getOpcode()) {
+ case ARM::HVC: {
+ // HVC is undefined if condition = 0xf otherwise upredictable
+ // if condition != 0xe
+ uint32_t Cond = (Insn >> 28) & 0xF;
+ if (Cond == 0xF)
+ return MCDisassembler::Fail;
+ if (Cond != 0xE)
+ return MCDisassembler::SoftFail;
+ return Result;
+ }
+ default: return Result;
+ }
+}
+
DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
ArrayRef<uint8_t> Bytes,
uint64_t Address, raw_ostream &OS,
@@ -430,7 +452,7 @@ DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
decodeInstruction(DecoderTableARM32, MI, Insn, Address, this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
- return Result;
+ return checkDecodedInstruction(MI, Size, Address, OS, CS, Insn, Result);
}
// VFP and NEON instructions, similarly, are shared between ARM
diff --git a/llvm/test/MC/Disassembler/ARM/invalid-virtexts.arm.txt b/llvm/test/MC/Disassembler/ARM/invalid-virtexts.arm.txt
new file mode 100644
index 00000000000..1daada98d67
--- /dev/null
+++ b/llvm/test/MC/Disassembler/ARM/invalid-virtexts.arm.txt
@@ -0,0 +1,10 @@
+# RUN: not llvm-mc -disassemble -triple armv7a -mcpu=cortex-a15 %s 2>&1 | FileCheck --check-prefix=CHECK-ARM %s
+
+# HVC (ARM)
+[0x7f,0xff,0x4f,0xf1]
+# CHECK-ARM: warning: invalid instruction encoding
+
+[0x70,0xff,0x4f,0x01]
+[0x7f,0xff,0x4f,0xd1]
+# CHECK-ARM: warning: potentially undefined instruction encoding
+# CHECK-ARM: warning: potentially undefined instruction encoding
OpenPOWER on IntegriCloud