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
This commit is contained in:
Owen Anderson 2011-09-08 22:42:49 +00:00
parent d1e002a0a3
commit d2fc31b3f7
2 changed files with 26 additions and 12 deletions

View File

@ -77,7 +77,7 @@ public:
EDInstInfo *getEDInfo() const; EDInstInfo *getEDInfo() const;
private: private:
mutable std::vector<unsigned> ITBlock; mutable std::vector<unsigned> ITBlock;
void AddThumbPredicate(MCInst&) const; DecodeStatus AddThumbPredicate(MCInst&) const;
void UpdateThumbVFPPredicate(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 // encoding, but rather get their predicates from IT context. We need
// to fix up the predicate operands using this context information as a // to fix up the predicate operands using this context information as a
// post-pass. // 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 // A few instructions actually have predicates encoded in them. Don't
// try to overwrite it if we're seeing one of those. // try to overwrite it if we're seeing one of those.
switch (MI.getOpcode()) { switch (MI.getOpcode()) {
case ARM::tBcc: case ARM::tBcc:
case ARM::t2Bcc: 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: default:
break; break;
} }
@ -456,7 +463,7 @@ void ThumbDisassembler::AddThumbPredicate(MCInst &MI) const {
MI.insert(I, MCOperand::CreateReg(0)); MI.insert(I, MCOperand::CreateReg(0));
else else
MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); 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)); MI.insert(I, MCOperand::CreateReg(0));
else else
MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
return Success;
} }
// Thumb VFP instructions are a special case. Because we share their // 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); DecodeStatus result = decodeThumbInstruction16(MI, insn16, Address, this, STI);
if (result != MCDisassembler::Fail) { if (result != MCDisassembler::Fail) {
Size = 2; Size = 2;
AddThumbPredicate(MI); Check(result, AddThumbPredicate(MI));
return result; return result;
} }
@ -525,7 +534,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
if (result) { if (result) {
Size = 2; Size = 2;
bool InITBlock = !ITBlock.empty(); bool InITBlock = !ITBlock.empty();
AddThumbPredicate(MI); Check(result, AddThumbPredicate(MI));
AddThumb1SBit(MI, InITBlock); AddThumb1SBit(MI, InITBlock);
return result; return result;
} }
@ -534,7 +543,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
result = decodeThumb2Instruction16(MI, insn16, Address, this, STI); result = decodeThumb2Instruction16(MI, insn16, Address, this, STI);
if (result != MCDisassembler::Fail) { if (result != MCDisassembler::Fail) {
Size = 2; Size = 2;
AddThumbPredicate(MI); Check(result, AddThumbPredicate(MI));
// If we find an IT instruction, we need to parse its condition // If we find an IT instruction, we need to parse its condition
// code and mask operands so that we can apply them correctly // 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) { if (result != MCDisassembler::Fail) {
Size = 4; Size = 4;
bool InITBlock = ITBlock.size(); bool InITBlock = ITBlock.size();
AddThumbPredicate(MI); Check(result, AddThumbPredicate(MI));
AddThumb1SBit(MI, InITBlock); AddThumb1SBit(MI, InITBlock);
return result; return result;
} }
@ -584,7 +593,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
result = decodeThumb2Instruction32(MI, insn32, Address, this, STI); result = decodeThumb2Instruction32(MI, insn32, Address, this, STI);
if (result != MCDisassembler::Fail) { if (result != MCDisassembler::Fail) {
Size = 4; Size = 4;
AddThumbPredicate(MI); Check(result, AddThumbPredicate(MI));
return result; return result;
} }
@ -600,7 +609,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
result = decodeNEONDupInstruction32(MI, insn32, Address, this, STI); result = decodeNEONDupInstruction32(MI, insn32, Address, this, STI);
if (result != MCDisassembler::Fail) { if (result != MCDisassembler::Fail) {
Size = 4; Size = 4;
AddThumbPredicate(MI); Check(result, AddThumbPredicate(MI));
return result; return result;
} }
@ -612,7 +621,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
result = decodeNEONLoadStoreInstruction32(MI, NEONLdStInsn, Address, this, STI); result = decodeNEONLoadStoreInstruction32(MI, NEONLdStInsn, Address, this, STI);
if (result != MCDisassembler::Fail) { if (result != MCDisassembler::Fail) {
Size = 4; Size = 4;
AddThumbPredicate(MI); Check(result, AddThumbPredicate(MI));
return result; return result;
} }
} }
@ -626,7 +635,7 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
result = decodeNEONDataInstruction32(MI, NEONDataInsn, Address, this, STI); result = decodeNEONDataInstruction32(MI, NEONDataInsn, Address, this, STI);
if (result != MCDisassembler::Fail) { if (result != MCDisassembler::Fail) {
Size = 4; Size = 4;
AddThumbPredicate(MI); Check(result, AddThumbPredicate(MI));
return result; return result;
} }
} }

View File

@ -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