diff options
author | Vladimir Kostyukov <vladimir.kostyukov@intel.com> | 2014-06-30 15:44:12 +0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2014-07-03 16:23:28 -0700 |
commit | e443a8063518fb1c5229afa3081b9fd1f6d33b16 (patch) | |
tree | a4e64dea6743e787e77369241ec14f3969c43c0d /disassembler/disassembler_x86.cc | |
parent | ca8ff32bbb1f034b3b1f25de1fe20a9015bc87ec (diff) | |
download | art-e443a8063518fb1c5229afa3081b9fd1f6d33b16.zip art-e443a8063518fb1c5229afa3081b9fd1f6d33b16.tar.gz art-e443a8063518fb1c5229afa3081b9fd1f6d33b16.tar.bz2 |
ART: FF-opcodes are target-specific
Some of the FF-opcodes' (i.e., push, call, jmp) register names
depend on the the target (32-bit vs 64-bit). This patch makes
such opcodes target-specific.
Change-Id: I4fa0b7ee5310e14f4022850ac2160c21be5d1c99
Signed-off-by: Vladimir Kostyukov <vladimir.kostyukov@intel.com>
Diffstat (limited to 'disassembler/disassembler_x86.cc')
-rw-r--r-- | disassembler/disassembler_x86.cc | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc index 1021789..14a5b5f 100644 --- a/disassembler/disassembler_x86.cc +++ b/disassembler/disassembler_x86.cc @@ -1012,11 +1012,18 @@ DISASSEMBLER_ENTRY(cmp, immediate_bytes = ((instr[1] & 0x38) == 0) ? 1 : 0; break; case 0xFF: - static const char* ff_opcodes[] = {"inc", "dec", "call", "call", "jmp", "jmp", "push", "unknown-ff"}; - modrm_opcodes = ff_opcodes; - has_modrm = true; - reg_is_opcode = true; - load = true; + { + static const char* ff_opcodes[] = {"inc", "dec", "call", "call", "jmp", "jmp", "push", "unknown-ff"}; + modrm_opcodes = ff_opcodes; + has_modrm = true; + reg_is_opcode = true; + load = true; + const uint8_t opcode_digit = (instr[1] >> 3) & 7; + // 'call', 'jmp' and 'push' are target specific instructions + if (opcode_digit == 2 || opcode_digit == 4 || opcode_digit == 6) { + target_specific = true; + } + } break; default: opcode << StringPrintf("unknown opcode '%02X'", *instr); @@ -1026,10 +1033,10 @@ DISASSEMBLER_ENTRY(cmp, // We force the REX prefix to be available for 64-bit target // in order to dump addr (base/index) registers correctly. uint8_t rex64 = supports_rex_ ? (rex | 0x40) : rex; + // REX.W should be forced for 64-target and target-specific instructions (i.e., push or pop). + uint8_t rex_w = (supports_rex_ && target_specific) ? (rex | 0x48) : rex; if (reg_in_opcode) { DCHECK(!has_modrm); - // REX.W should be forced for 64-target and target-specific instructions (i.e., push or pop). - uint8_t rex_w = (supports_rex_ && target_specific) ? (rex | 0x48) : rex; DumpOpcodeReg(args, rex_w, *instr & 0x7); } instr++; @@ -1090,7 +1097,7 @@ DISASSEMBLER_ENTRY(cmp, } else { if (mod == 3) { if (!no_ops) { - DumpRmReg(address, rex, rm, byte_operand, prefix[2], load ? src_reg_file : dst_reg_file); + DumpRmReg(address, rex_w, rm, byte_operand, prefix[2], load ? src_reg_file : dst_reg_file); } } else { address << "["; |