diff options
Diffstat (limited to 'disassembler')
-rw-r--r-- | disassembler/disassembler_x86.cc | 93 |
1 files changed, 34 insertions, 59 deletions
diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc index 7551add..1848abe 100644 --- a/disassembler/disassembler_x86.cc +++ b/disassembler/disassembler_x86.cc @@ -558,14 +558,19 @@ DISASSEMBLER_ENTRY(cmp, has_modrm = true; src_reg_file = dst_reg_file = SSE; break; - case 0x62: + case 0x60: case 0x61: case 0x62: case 0x6C: if (prefix[2] == 0x66) { src_reg_file = dst_reg_file = SSE; prefix[2] = 0; // Clear prefix now. It has served its purpose as part of the opcode. } else { src_reg_file = dst_reg_file = MMX; } - opcode << "punpckldq"; + switch (*instr) { + case 0x60: opcode << "punpcklbw"; break; + case 0x61: opcode << "punpcklwd"; break; + case 0x62: opcode << "punpckldq"; break; + case 0x6c: opcode << "punpcklqdq"; break; + } load = true; has_modrm = true; break; @@ -650,7 +655,7 @@ DISASSEMBLER_ENTRY(cmp, } else { dst_reg_file = MMX; } - static const char* x73_opcodes[] = {"unknown-73", "unknown-73", "psrlq", "unknown-73", "unknown-73", "unknown-73", "psllq", "unknown-73"}; + static const char* x73_opcodes[] = {"unknown-73", "unknown-73", "psrlq", "psrldq", "unknown-73", "unknown-73", "psllq", "unknown-73"}; modrm_opcodes = x73_opcodes; reg_is_opcode = true; has_modrm = true; @@ -800,6 +805,18 @@ DISASSEMBLER_ENTRY(cmp, opcode << "bswap"; reg_in_opcode = true; break; + case 0xD4: + if (prefix[2] == 0x66) { + src_reg_file = dst_reg_file = SSE; + prefix[2] = 0; + } else { + src_reg_file = dst_reg_file = MMX; + } + opcode << "paddq"; + prefix[2] = 0; + has_modrm = true; + load = true; + break; case 0xDB: if (prefix[2] == 0x66) { src_reg_file = dst_reg_file = SSE; @@ -847,66 +864,14 @@ DISASSEMBLER_ENTRY(cmp, has_modrm = true; load = true; break; + case 0xF4: + case 0xF6: case 0xF8: - if (prefix[2] == 0x66) { - src_reg_file = dst_reg_file = SSE; - prefix[2] = 0; // clear prefix now it's served its purpose as part of the opcode - } else { - src_reg_file = dst_reg_file = MMX; - } - opcode << "psubb"; - prefix[2] = 0; - has_modrm = true; - load = true; - break; case 0xF9: - if (prefix[2] == 0x66) { - src_reg_file = dst_reg_file = SSE; - prefix[2] = 0; // clear prefix now it's served its purpose as part of the opcode - } else { - src_reg_file = dst_reg_file = MMX; - } - opcode << "psubw"; - prefix[2] = 0; - has_modrm = true; - load = true; - break; case 0xFA: - if (prefix[2] == 0x66) { - src_reg_file = dst_reg_file = SSE; - prefix[2] = 0; // clear prefix now it's served its purpose as part of the opcode - } else { - src_reg_file = dst_reg_file = MMX; - } - opcode << "psubd"; - prefix[2] = 0; - has_modrm = true; - load = true; - break; + case 0xFB: case 0xFC: - if (prefix[2] == 0x66) { - src_reg_file = dst_reg_file = SSE; - prefix[2] = 0; // clear prefix now it's served its purpose as part of the opcode - } else { - src_reg_file = dst_reg_file = MMX; - } - opcode << "paddb"; - prefix[2] = 0; - has_modrm = true; - load = true; - break; case 0xFD: - if (prefix[2] == 0x66) { - src_reg_file = dst_reg_file = SSE; - prefix[2] = 0; // clear prefix now it's served its purpose as part of the opcode - } else { - src_reg_file = dst_reg_file = MMX; - } - opcode << "paddw"; - prefix[2] = 0; - has_modrm = true; - load = true; - break; case 0xFE: if (prefix[2] == 0x66) { src_reg_file = dst_reg_file = SSE; @@ -914,7 +879,17 @@ DISASSEMBLER_ENTRY(cmp, } else { src_reg_file = dst_reg_file = MMX; } - opcode << "paddd"; + switch (*instr) { + case 0xF4: opcode << "pmuludq"; break; + case 0xF6: opcode << "psadbw"; break; + case 0xF8: opcode << "psubb"; break; + case 0xF9: opcode << "psubw"; break; + case 0xFA: opcode << "psubd"; break; + case 0xFB: opcode << "psubq"; break; + case 0xFC: opcode << "paddb"; break; + case 0xFD: opcode << "paddw"; break; + case 0xFE: opcode << "paddd"; break; + } prefix[2] = 0; has_modrm = true; load = true; |