llvm.org GIT mirror llvm / f4478f9
Refactor Thumb ITState handling in ARM Disassembler to more efficiently use its vector git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155439 91177308-0d34-0410-b5e6-96231b3b80d8 Richard Barton 8 years ago
1 changed file(s) with 69 addition(s) and 31 deletion(s). Raw diff Collapse all Expand all
2323 #include "llvm/Support/ErrorHandling.h"
2424 #include "llvm/Support/TargetRegistry.h"
2525 #include "llvm/Support/raw_ostream.h"
26 #include
2627
2728 using namespace llvm;
2829
2930 typedef MCDisassembler::DecodeStatus DecodeStatus;
31
32 namespace {
33 // Handles the condition code status of instructions in IT blocks
34 class ITStatus
35 {
36 public:
37 // Returns the condition code for instruction in IT block
38 unsigned getITCC() {
39 unsigned CC = ARMCC::AL;
40 if (instrInITBlock())
41 CC = ITStates.back();
42 return CC;
43 }
44
45 // Advances the IT block state to the next T or E
46 void advanceITState() {
47 ITStates.pop_back();
48 }
49
50 // Returns true if the current instruction is in an IT block
51 bool instrInITBlock() {
52 return !ITStates.empty();
53 }
54
55 // Returns true if current instruction is the last instruction in an IT block
56 bool instrLastInITBlock() {
57 return ITStates.size() == 1;
58 }
59
60 // Called when decoding an IT instruction. Sets the IT state for the following
61 // instructions that for the IT block. Firstcond and Mask correspond to the
62 // fields in the IT instruction encoding.
63 void setITState(char Firstcond, char Mask) {
64 // (3 - the number of trailing zeros) is the number of then / else.
65 unsigned CondBit0 = Mask >> 4 & 1;
66 unsigned NumTZ = CountTrailingZeros_32(Mask);
67 unsigned char CCBits = static_cast(Firstcond & 0xf);
68 assert(NumTZ <= 3 && "Invalid IT mask!");
69 // push condition codes onto the stack the correct order for the pops
70 for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
71 bool T = ((Mask >> Pos) & 1) == CondBit0;
72 if (T)
73 ITStates.push_back(CCBits);
74 else
75 ITStates.push_back(CCBits ^ 1);
76 }
77 ITStates.push_back(CCBits);
78 }
79
80 private:
81 std::vector ITStates;
82 };
83 }
3084
3185 namespace {
3286 /// ARMDisassembler - ARM disassembler for all ARM platforms.
77131 /// getEDInfo - See MCDisassembler.
78132 const EDInstInfo *getEDInfo() const;
79133 private:
80 mutable std::vector ITBlock;
134 mutable ITStatus ITBlock;
81135 DecodeStatus AddThumbPredicate(MCInst&) const;
82136 void UpdateThumbVFPPredicate(MCInst&) const;
83137 };
611665 case ARM::tSETEND:
612666 // Some instructions (mostly conditional branches) are not
613667 // allowed in IT blocks.
614 if (!ITBlock.empty())
668 if (ITBlock.instrInITBlock())
615669 S = SoftFail;
616670 else
617671 return Success;
622676 case ARM::t2TBH:
623677 // Some instructions (mostly unconditional branches) can
624678 // only appears at the end of, or outside of, an IT.
625 if (ITBlock.size() > 1)
679 if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
626680 S = SoftFail;
627681 break;
628682 default:
632686 // If we're in an IT block, base the predicate on that. Otherwise,
633687 // assume a predicate of AL.
634688 unsigned CC;
635 if (!ITBlock.empty()) {
636 CC = ITBlock.back();
637 if (CC == 0xF)
638 CC = ARMCC::AL;
639 ITBlock.pop_back();
640 } else
689 CC = ITBlock.getITCC();
690 if (CC == 0xF)
641691 CC = ARMCC::AL;
692 if (ITBlock.instrInITBlock())
693 ITBlock.advanceITState();
642694
643695 const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
644696 unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
673725 // context as a post-pass.
674726 void ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const {
675727 unsigned CC;
676 if (!ITBlock.empty()) {
677 CC = ITBlock.back();
678 ITBlock.pop_back();
679 } else
680 CC = ARMCC::AL;
728 CC = ITBlock.getITCC();
729 if (ITBlock.instrInITBlock())
730 ITBlock.advanceITState();
681731
682732 const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
683733 MCInst::iterator I = MI.begin();
725775 result = decodeThumbSBitInstruction16(MI, insn16, Address, this, STI);
726776 if (result) {
727777 Size = 2;
728 bool InITBlock = !ITBlock.empty();
778 bool InITBlock = ITBlock.instrInITBlock();
729779 Check(result, AddThumbPredicate(MI));
730780 AddThumb1SBit(MI, InITBlock);
731781 return result;
738788
739789 // Nested IT blocks are UNPREDICTABLE. Must be checked before we add
740790 // the Thumb predicate.
741 if (MI.getOpcode() == ARM::t2IT && !ITBlock.empty())
791 if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock())
742792 result = MCDisassembler::SoftFail;
743793
744794 Check(result, AddThumbPredicate(MI));
748798 // to the subsequent instructions.
749799 if (MI.getOpcode() == ARM::t2IT) {
750800
751 // (3 - the number of trailing zeros) is the number of then / else.
752 unsigned firstcond = MI.getOperand(0).getImm();
801 unsigned Firstcond = MI.getOperand(0).getImm();
753802 unsigned Mask = MI.getOperand(1).getImm();
754 unsigned CondBit0 = Mask >> 4 & 1;
755 unsigned NumTZ = CountTrailingZeros_32(Mask);
756 assert(NumTZ <= 3 && "Invalid IT mask!");
757 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
758 bool T = ((Mask >> Pos) & 1) == CondBit0;
759 if (T)
760 ITBlock.insert(ITBlock.begin(), firstcond);
761 else
762 ITBlock.insert(ITBlock.begin(), firstcond ^ 1);
763 }
764
765 ITBlock.push_back(firstcond);
803 ITBlock.setITState(Firstcond, Mask);
766804 }
767805
768806 return result;
782820 result = decodeThumbInstruction32(MI, insn32, Address, this, STI);
783821 if (result != MCDisassembler::Fail) {
784822 Size = 4;
785 bool InITBlock = ITBlock.size();
823 bool InITBlock = ITBlock.instrInITBlock();
786824 Check(result, AddThumbPredicate(MI));
787825 AddThumb1SBit(MI, InITBlock);
788826 return result;