diff options
author | Owen Anderson <resistor@mac.com> | 2011-09-08 22:42:49 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2011-09-08 22:42:49 +0000 |
commit | d2fc31b3f75700dc89305cb161f3bca7f1a39bef (patch) | |
tree | 7ae16f78a64993dc671e148d28d621f1b557a199 | |
parent | d1e002a0a3c1c38bae064f3f3cc22b1653d47659 (diff) | |
download | external_llvm-d2fc31b3f75700dc89305cb161f3bca7f1a39bef.zip external_llvm-d2fc31b3f75700dc89305cb161f3bca7f1a39bef.tar.gz external_llvm-d2fc31b3f75700dc89305cb161f3bca7f1a39bef.tar.bz2 |
Soft fail CBZ/CBNZ in the disassembler if they appear inside an IT block.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139328 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 33 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/invalid-IT-CBNZ-thumb.txt | 5 |
2 files changed, 26 insertions, 12 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index fad7068..d361a60 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -77,7 +77,7 @@ public: EDInstInfo *getEDInfo() const; private: mutable std::vector<unsigned> ITBlock; - void AddThumbPredicate(MCInst&) const; + DecodeStatus AddThumbPredicate(MCInst&) const; void UpdateThumbVFPPredicate(MCInst&) const; }; } @@ -422,13 +422,20 @@ static void AddThumb1SBit(MCInst &MI, bool InITBlock) { // encoding, but rather get their predicates from IT context. We need // to fix up the predicate operands using this context information as a // post-pass. -void ThumbDisassembler::AddThumbPredicate(MCInst &MI) const { +MCDisassembler::DecodeStatus +ThumbDisassembler::AddThumbPredicate(MCInst &MI) const { // A few instructions actually have predicates encoded in them. Don't // try to overwrite it if we're seeing one of those. switch (MI.getOpcode()) { case ARM::tBcc: case ARM::t2Bcc: - return; + return Success; + case ARM::tCBZ: + case ARM::tCBNZ: + // Some instructions are not allowed in IT blocks. + if (!ITBlock.empty()) + return SoftFail; + break; default: break; } @@ -456,7 +463,7 @@ void ThumbDisassembler::AddThumbPredicate(MCInst &MI) const { MI.insert(I, MCOperand::CreateReg(0)); else MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); - return; + return Success; } } @@ -466,6 +473,8 @@ void ThumbDisassembler::AddThumbPredicate(MCInst &MI) const { MI.insert(I, MCOperand::CreateReg(0)); else MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); + + return Success; } // Thumb VFP instructions are a special case. Because we share their @@ -516,7 +525,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, DecodeStatus result = decodeThumbInstruction16(MI, insn16, Address, this, STI); if (result != MCDisassembler::Fail) { Size = 2; - AddThumbPredicate(MI); + Check(result, AddThumbPredicate(MI)); return result; } @@ -525,7 +534,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, if (result) { Size = 2; bool InITBlock = !ITBlock.empty(); - AddThumbPredicate(MI); + Check(result, AddThumbPredicate(MI)); AddThumb1SBit(MI, InITBlock); return result; } @@ -534,7 +543,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, result = decodeThumb2Instruction16(MI, insn16, Address, this, STI); if (result != MCDisassembler::Fail) { Size = 2; - AddThumbPredicate(MI); + Check(result, AddThumbPredicate(MI)); // If we find an IT instruction, we need to parse its condition // code and mask operands so that we can apply them correctly @@ -575,7 +584,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, if (result != MCDisassembler::Fail) { Size = 4; bool InITBlock = ITBlock.size(); - AddThumbPredicate(MI); + Check(result, AddThumbPredicate(MI)); AddThumb1SBit(MI, InITBlock); return result; } @@ -584,7 +593,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, result = decodeThumb2Instruction32(MI, insn32, Address, this, STI); if (result != MCDisassembler::Fail) { Size = 4; - AddThumbPredicate(MI); + Check(result, AddThumbPredicate(MI)); return result; } @@ -600,7 +609,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, result = decodeNEONDupInstruction32(MI, insn32, Address, this, STI); if (result != MCDisassembler::Fail) { Size = 4; - AddThumbPredicate(MI); + Check(result, AddThumbPredicate(MI)); return result; } @@ -612,7 +621,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, result = decodeNEONLoadStoreInstruction32(MI, NEONLdStInsn, Address, this, STI); if (result != MCDisassembler::Fail) { Size = 4; - AddThumbPredicate(MI); + Check(result, AddThumbPredicate(MI)); return result; } } @@ -626,7 +635,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, result = decodeNEONDataInstruction32(MI, NEONDataInsn, Address, this, STI); if (result != MCDisassembler::Fail) { Size = 4; - AddThumbPredicate(MI); + Check(result, AddThumbPredicate(MI)); return result; } } diff --git a/test/MC/Disassembler/ARM/invalid-IT-CBNZ-thumb.txt b/test/MC/Disassembler/ARM/invalid-IT-CBNZ-thumb.txt new file mode 100644 index 0000000..6174e92 --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-IT-CBNZ-thumb.txt @@ -0,0 +1,5 @@ +# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 |& grep {potentially undefined instruction encoding} + +# CBZ / CBNZ not allowed in IT block. + +0xdb 0xbf 0x42 0xbb |