summaryrefslogtreecommitdiffstats
path: root/src/disassembler_arm.cc
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2012-04-10 15:04:25 -0700
committerElliott Hughes <enh@google.com>2012-04-10 15:04:25 -0700
commit105afd2bd8f9f0ddfcfcb4b8db9f356ee82ae8cd (patch)
treefc5b59d5cd6f5ad4dccbe42c19fbd71e86271cef /src/disassembler_arm.cc
parentb92bcabcbb28f69fe99e1c2f2e5559ab2c47aa60 (diff)
downloadart-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.cc31
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;