From e443a8063518fb1c5229afa3081b9fd1f6d33b16 Mon Sep 17 00:00:00 2001 From: Vladimir Kostyukov Date: Mon, 30 Jun 2014 15:44:12 +0700 Subject: 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 --- disassembler/disassembler_x86.cc | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'disassembler/disassembler_x86.cc') diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc index 1021789908..14a5b5f2bf 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 << "["; -- cgit v1.2.3-59-g8ed1b