diff options
author | Vladimir Marko <vmarko@google.com> | 2016-02-10 12:52:59 +0000 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2016-02-10 13:18:41 +0000 |
commit | 8cdbc2aef0ece0f3665966e793c075844b52b67d (patch) | |
tree | df2370a274b937f5d2a911019efd8fa42f59bdd6 /disassembler/disassembler_arm.cc | |
parent | fc06b93dee031ec16272ec64fca92a0e639ae73e (diff) |
ART/Thumb2: Disassemble SBFX/UBFX.
Change-Id: I856206de81f41959f68de0653db021903dd1a210
Diffstat (limited to 'disassembler/disassembler_arm.cc')
-rw-r--r-- | disassembler/disassembler_arm.cc | 23 |
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; } |