summaryrefslogtreecommitdiff
path: root/disassembler/disassembler_arm.cc
diff options
context:
space:
mode:
authorVladimir Marko <vmarko@google.com>2016-02-10 12:52:59 +0000
committerVladimir Marko <vmarko@google.com>2016-02-10 13:18:41 +0000
commit8cdbc2aef0ece0f3665966e793c075844b52b67d (patch)
treedf2370a274b937f5d2a911019efd8fa42f59bdd6 /disassembler/disassembler_arm.cc
parentfc06b93dee031ec16272ec64fca92a0e639ae73e (diff)
ART/Thumb2: Disassemble SBFX/UBFX.
Change-Id: I856206de81f41959f68de0653db021903dd1a210
Diffstat (limited to 'disassembler/disassembler_arm.cc')
-rw-r--r--disassembler/disassembler_arm.cc23
1 files changed, 17 insertions, 6 deletions
diff --git a/disassembler/disassembler_arm.cc b/disassembler/disassembler_arm.cc
index 5e2cf6b81d..0e709eb419 100644
--- a/disassembler/disassembler_arm.cc
+++ b/disassembler/disassembler_arm.cc
@@ -1152,8 +1152,10 @@ size_t DisassemblerArm::DumpThumb32(std::ostream& os, const uint8_t* instr_ptr)
args << Rd << ", #" << imm16;
break;
}
- case 0x16: {
+ case 0x16: case 0x14: case 0x1C: {
// BFI Rd, Rn, #lsb, #width - 111 10 0 11 011 0 nnnn 0 iii dddd ii 0 iiiii
+ // SBFX Rd, Rn, #lsb, #width - 111 10 0 11 010 0 nnnn 0 iii dddd ii 0 iiiii
+ // UBFX Rd, Rn, #lsb, #width - 111 10 0 11 110 0 nnnn 0 iii dddd ii 0 iiiii
ArmRegister Rd(instr, 8);
ArmRegister Rn(instr, 16);
uint32_t msb = instr & 0x1F;
@@ -1161,12 +1163,21 @@ size_t DisassemblerArm::DumpThumb32(std::ostream& os, const uint8_t* instr_ptr)
uint32_t imm3 = (instr >> 12) & 0x7;
uint32_t lsb = (imm3 << 2) | imm2;
uint32_t width = msb - lsb + 1;
- if (Rn.r != 0xF) {
- opcode << "bfi";
- args << Rd << ", " << Rn << ", #" << lsb << ", #" << width;
+ if (op3 == 0x16) {
+ if (Rn.r != 0xF) {
+ opcode << "bfi";
+ args << Rd << ", " << Rn << ", #" << lsb << ", #" << width;
+ } else {
+ opcode << "bfc";
+ args << Rd << ", #" << lsb << ", #" << width;
+ }
} else {
- opcode << "bfc";
- args << Rd << ", #" << lsb << ", #" << width;
+ opcode << ((op3 & 0x8) != 0u ? "ubfx" : "sbfx");
+ args << Rd << ", " << Rn << ", #" << lsb << ", #" << width;
+ if (Rd.r == 13 || Rd.r == 15 || Rn.r == 13 || Rn.r == 15 ||
+ (instr & 0x04000020) != 0u) {
+ args << " (UNPREDICTABLE)";
+ }
}
break;
}