summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharlie Turner <charlie.turner@arm.com>2014-12-01 08:50:27 +0000
committerCharlie Turner <charlie.turner@arm.com>2014-12-01 08:50:27 +0000
commit30895f9ab8cd9ce82f695147dc517fd44b8a21dd (patch)
tree61f452e301245b8dd5002e3bee9f892c523f241f
parent3ae427d81183d6f7675811ed7d6ffa365adc1938 (diff)
downloadbcm5719-llvm-30895f9ab8cd9ce82f695147dc517fd44b8a21dd.tar.gz
bcm5719-llvm-30895f9ab8cd9ce82f695147dc517fd44b8a21dd.zip
Add post-decode checking of HVC instruction.
Add checkDecodedInstruction for post-decode checking of instructions, to catch the corner cases like HVC that don't fit into the general pattern. Needed to check for an invalid condition field in instruction encoding despite HVC not taking a predicate. Patch by Matthew Wahab. Change-Id: I48e28de981d7a9e43569594da3c45fb478b4f795 llvm-svn: 222992
-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