diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 03e1d447b66..dae8618fa07 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -6305,10 +6305,6 @@ bool ARMAsmParser::validatetLDMRegList(const MCInst &Inst, else if (ListContainsPC && ListContainsLR) return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(), "PC and LR may not be in the register list simultaneously"); - else if (inITBlock() && !lastInITBlock() && ListContainsPC) - return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(), - "instruction must be outside of IT block or the last " - "instruction in an IT block"); return false; } @@ -6370,6 +6366,12 @@ bool ARMAsmParser::validateInstruction(MCInst &Inst, return Warning(Loc, "predicated instructions should be in IT block"); } + // PC-setting instructions in an IT block, but not the last instruction of + // the block, are UNPREDICTABLE. + if (inExplicitITBlock() && !lastInITBlock() && isITBlockTerminator(Inst)) { + return Error(Loc, "instruction must be outside of IT block or the last instruction in an IT block"); + } + const unsigned Opcode = Inst.getOpcode(); switch (Opcode) { case ARM::LDRD: @@ -9013,6 +9015,7 @@ bool ARMAsmParser::isITBlockTerminator(MCInst &Inst) const { // operands. We only care about Thumb instructions here, as ARM instructions // obviously can't be in an IT block. switch (Inst.getOpcode()) { + case ARM::tLDMIA: case ARM::t2LDMIA: case ARM::t2LDMIA_UPD: case ARM::t2LDMDB: |