diff options
author | Elliott Hughes <enh@google.com> | 2012-04-10 15:04:25 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2012-04-10 15:04:25 -0700 |
commit | 105afd2bd8f9f0ddfcfcb4b8db9f356ee82ae8cd (patch) | |
tree | fc5b59d5cd6f5ad4dccbe42c19fbd71e86271cef /src/disassembler_arm.cc | |
parent | b92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60 (diff) | |
download | art-105afd2bd8f9f0ddfcfcb4b8db9f356ee82ae8cd.zip art-105afd2bd8f9f0ddfcfcb4b8db9f356ee82ae8cd.tar.gz art-105afd2bd8f9f0ddfcfcb4b8db9f356ee82ae8cd.tar.bz2 |
Fancy disassembly of Thumb2 IT blocks.
Example:
0x60ce6ea4: 4291 cmp r1, r2
0x60ce6ea6: bf0e itee eq
0x60ce6ea8: 2001 movseq r0, #1
0x60ce6eaa: 1c10 movne r0, r2
0x60ce6eac: 47f0 blxne lr
0x60ce6eae: 1c06 mov r6, r0
Change-Id: I85deae2e471b8bfc513281be421e0bd46c1b60a0
Diffstat (limited to 'src/disassembler_arm.cc')
-rw-r--r-- | src/disassembler_arm.cc | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/src/disassembler_arm.cc b/src/disassembler_arm.cc index 57fcec3..2492f50 100644 --- a/src/disassembler_arm.cc +++ b/src/disassembler_arm.cc @@ -899,9 +899,29 @@ size_t DisassemblerArm::DumpThumb16(std::ostream& os, const uint8_t* instr_ptr) default: break; } } else { + uint32_t first_cond = opA; + uint32_t mask = opB; opcode << "it"; - args << reinterpret_cast<void*>(opB) << " "; - DumpCond(args, opA); + + // Flesh out the base "it" opcode with the specific collection of 't's and 'e's, + // and store up the actual condition codes we'll want to add to the next few opcodes. + size_t count = 3 - CTZ(mask); + it_conditions_.resize(count + 2); // Plus the implicit 't', plus the "" for the IT itself. + for (size_t i = 0; i < count; ++i) { + bool positive_cond = ((first_cond & 1) != 0); + bool positive_mask = ((mask & (1 << (3 - i))) != 0); + if (positive_mask == positive_cond) { + opcode << 't'; + it_conditions_[i] = kConditionCodeNames[first_cond]; + } else { + opcode << 'e'; + it_conditions_[i] = kConditionCodeNames[first_cond ^ 1]; + } + } + it_conditions_[count] = kConditionCodeNames[first_cond]; // The implicit 't'. + + it_conditions_[count + 1] = ""; // No condition code for the IT itself... + DumpCond(args, first_cond); // ...because it's considered an argument. } break; } @@ -943,6 +963,13 @@ size_t DisassemblerArm::DumpThumb16(std::ostream& os, const uint8_t* instr_ptr) opcode << "b"; DumpBranchTarget(args, instr_ptr + 4, imm32); } + + // Apply any IT-block conditions to the opcode if necessary. + if (!it_conditions_.empty()) { + opcode << it_conditions_.back(); + it_conditions_.pop_back(); + } + os << StringPrintf("\t\t\t%p: %04x \t%-7s ", instr_ptr, instr, opcode.str().c_str()) << args.str() << '\n'; } return 2; |