disasm: correctly handle VEX and XOP based opcodes

This commit is contained in:
Stanislav Shwartsman 2011-11-23 19:43:50 +00:00
parent 7158cf7228
commit 62b811e48f

View File

@ -326,42 +326,43 @@ x86_insn disassembler::decode(bx_bool is_32, bx_bool is_64, bx_address base, bx_
{ {
Bit8u prefix_byte = *(instr+i); Bit8u prefix_byte = *(instr+i);
if (prefix_byte == 0xF0) { if (prefix_byte == 0xF0) dis_sprintf("lock ");
const BxDisasmOpcodeTable_t *prefix = &(opcode_table[prefix_byte]);
dis_sprintf("%s ", OPCODE(prefix)->IntelOpcode);
}
if (insn.b1 == 0x90 && !insn.rex_b && prefix_byte == 0xF3) if (! insn.is_xop && ! insn.is_vex) {
continue; if (insn.b1 == 0x90 && !insn.rex_b && prefix_byte == 0xF3)
continue;
if (prefix_byte == 0xF3 || prefix_byte == 0xF2) { if (prefix_byte == 0xF3 || prefix_byte == 0xF2) {
if (! sse_opcode) { if (! sse_opcode) {
const BxDisasmOpcodeTable_t *prefix = &(opcode_table[prefix_byte]); const BxDisasmOpcodeTable_t *prefix = &(opcode_table[prefix_byte]);
dis_sprintf("%s ", OPCODE(prefix)->IntelOpcode); dis_sprintf("%s ", OPCODE(prefix)->IntelOpcode);
}
} }
}
// branch hint for jcc instructions // branch hint for jcc instructions
if ((insn.b1 >= 0x070 && insn.b1 <= 0x07F) || if ((insn.b1 >= 0x070 && insn.b1 <= 0x07F) ||
(insn.b1 >= 0x180 && insn.b1 <= 0x18F)) (insn.b1 >= 0x180 && insn.b1 <= 0x18F))
{ {
if (prefix_byte == BRANCH_NOT_TAKEN || prefix_byte == BRANCH_TAKEN) if (prefix_byte == BRANCH_NOT_TAKEN || prefix_byte == BRANCH_TAKEN)
branch_hint = prefix_byte; branch_hint = prefix_byte;
}
} }
} }
const BxDisasmOpcodeInfo_t *opcode = OPCODE(entry); const BxDisasmOpcodeInfo_t *opcode = OPCODE(entry);
// patch jecx opcode if (! insn.is_xop && ! insn.is_vex) {
if (insn.b1 == 0xE3 && insn.as_32 && !insn.as_64) // patch jecx opcode
opcode = &Ia_jecxz_Jb; if (insn.b1 == 0xE3 && insn.as_32 && !insn.as_64)
opcode = &Ia_jecxz_Jb;
// fix nop opcode // fix nop opcode
if (insn.b1 == 0x90) { if (insn.b1 == 0x90) {
if (sse_prefix == SSE_PREFIX_F3) if (sse_prefix == SSE_PREFIX_F3)
opcode = &Ia_pause; opcode = &Ia_pause;
else if (!insn.rex_b) else if (!insn.rex_b)
opcode = &Ia_nop; opcode = &Ia_nop;
}
} }
// print instruction disassembly // print instruction disassembly