Index: src/x64/disasm-x64.cc |
diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc |
index 83f34d07a0bad5b7cea7799e1ef061b488bbb2c1..6adb820ef1216a44646bd245997a55afcbdc5ac1 100644 |
--- a/src/x64/disasm-x64.cc |
+++ b/src/x64/disasm-x64.cc |
@@ -11,6 +11,7 @@ |
#include "src/base/compiler-specific.h" |
#include "src/base/lazy-instance.h" |
#include "src/disasm.h" |
+#include "src/x64/sse-instr.h" |
namespace disasm { |
@@ -875,6 +876,7 @@ int DisassemblerX64::SetCC(byte* data) { |
return 3; // includes 0x0F |
} |
+const char* sf_str[4] = {"", "rl", "ra", "ll"}; |
int DisassemblerX64::AVXInstruction(byte* data) { |
byte opcode = *data; |
@@ -949,6 +951,18 @@ int DisassemblerX64::AVXInstruction(byte* data) { |
current += PrintRightOperand(current); |
AppendToBuffer(",%s", NameOfCPURegister(vvvv)); |
break; |
+#define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, notUsed3, \ |
+ opcode) \ |
+ case 0x##opcode: { \ |
+ AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \ |
+ NameOfXMMRegister(vvvv)); \ |
+ current += PrintRightXMMOperand(current); \ |
+ break; \ |
+ } |
+ |
+ SSSE3_INSTRUCTION_LIST(DECLARE_SSE_AVX_DIS_CASE) |
+ SSE4_INSTRUCTION_LIST(DECLARE_SSE_AVX_DIS_CASE) |
+#undef DECLARE_SSE_AVX_DIS_CASE |
default: |
UnimplementedInstruction(); |
} |
@@ -968,6 +982,33 @@ int DisassemblerX64::AVXInstruction(byte* data) { |
current += PrintRightXMMOperand(current); |
AppendToBuffer(",0x%x", *current++); |
break; |
+ case 0x14: |
+ AppendToBuffer("vpextrb "); |
+ current += PrintRightByteOperand(current); |
+ AppendToBuffer(",%s,0x%x,", NameOfXMMRegister(regop), *current++); |
+ break; |
+ case 0x15: |
+ AppendToBuffer("vpextrw "); |
+ current += PrintRightOperand(current); |
+ AppendToBuffer(",%s,0x%x,", NameOfXMMRegister(regop), *current++); |
+ break; |
+ case 0x16: |
+ AppendToBuffer("vpextrd "); |
+ current += PrintRightOperand(current); |
+ AppendToBuffer(",%s,0x%x,", NameOfXMMRegister(regop), *current++); |
+ break; |
+ case 0x20: |
+ AppendToBuffer("vpinsrb %s,%s,", NameOfXMMRegister(regop), |
+ NameOfXMMRegister(vvvv)); |
+ current += PrintRightByteOperand(current); |
+ AppendToBuffer(",0x%x", *current++); |
+ break; |
+ case 0x22: |
+ AppendToBuffer("vpinsrd %s,%s,", NameOfXMMRegister(regop), |
+ NameOfXMMRegister(vvvv)); |
+ current += PrintRightOperand(current); |
+ AppendToBuffer(",0x%x", *current++); |
+ break; |
default: |
UnimplementedInstruction(); |
} |
@@ -1112,6 +1153,10 @@ int DisassemblerX64::AVXInstruction(byte* data) { |
NameOfXMMRegister(vvvv)); |
current += PrintRightXMMOperand(current); |
break; |
+ case 0xf0: |
+ AppendToBuffer("vlddqu %s,", NameOfXMMRegister(regop)); |
+ current += PrintRightXMMOperand(current); |
+ break; |
default: |
UnimplementedInstruction(); |
} |
@@ -1326,16 +1371,28 @@ int DisassemblerX64::AVXInstruction(byte* data) { |
NameOfXMMRegister(regop)); |
current += PrintRightOperand(current); |
break; |
- case 0x73: |
- AppendToBuffer("%s %s,", regop == 6 ? "vpsllq" : "vpsrlq", |
+ case 0x70: |
+ AppendToBuffer("vpshufd %s,", NameOfXMMRegister(regop)); |
+ current += PrintRightXMMOperand(current); |
+ AppendToBuffer(",0x%x", *current++); |
+ break; |
+ case 0x71: |
+ AppendToBuffer("vps%sw %s,", sf_str[regop / 2], |
+ NameOfXMMRegister(vvvv)); |
+ current += PrintRightXMMOperand(current); |
+ AppendToBuffer(",%u", *current++); |
+ break; |
+ case 0x72: |
+ AppendToBuffer("vps%sd %s,", sf_str[regop / 2], |
NameOfXMMRegister(vvvv)); |
current += PrintRightXMMOperand(current); |
AppendToBuffer(",%u", *current++); |
break; |
- case 0x76: |
- AppendToBuffer("vpcmpeqd %s,%s,", NameOfXMMRegister(regop), |
+ case 0x73: |
+ AppendToBuffer("vps%sq %s,", sf_str[regop / 2], |
NameOfXMMRegister(vvvv)); |
current += PrintRightXMMOperand(current); |
+ AppendToBuffer(",%u", *current++); |
break; |
case 0x7e: |
AppendToBuffer("vmov%c ", vex_w() ? 'q' : 'd'); |
@@ -1352,6 +1409,27 @@ int DisassemblerX64::AVXInstruction(byte* data) { |
current += 1; |
break; |
} |
+ case 0xc4: |
+ AppendToBuffer("vpinsrw %s,%s,", NameOfXMMRegister(regop), |
+ NameOfXMMRegister(vvvv)); |
+ current += PrintRightOperand(current); |
+ AppendToBuffer(",0x%x", *current++); |
+ break; |
+ case 0xc5: |
+ AppendToBuffer("vpextrw %s,", NameOfCPURegister(regop)); |
+ current += PrintRightXMMOperand(current); |
+ AppendToBuffer(",0x%x", *current++); |
+ break; |
+#define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, opcode) \ |
+ case 0x##opcode: { \ |
+ AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \ |
+ NameOfXMMRegister(vvvv)); \ |
+ current += PrintRightXMMOperand(current); \ |
+ break; \ |
+ } |
+ |
+ SSE2_INSTRUCTION_LIST(DECLARE_SSE_AVX_DIS_CASE) |
+#undef DECLARE_SSE_AVX_DIS_CASE |
default: |
UnimplementedInstruction(); |
} |
@@ -1363,7 +1441,6 @@ int DisassemblerX64::AVXInstruction(byte* data) { |
return static_cast<int>(current - data); |
} |
- |
// Returns number of bytes used, including *data. |
int DisassemblerX64::FPUInstruction(byte* data) { |
byte escape_opcode = *data; |
@@ -1558,11 +1635,20 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { |
if (opcode == 0x38) { |
byte third_byte = *current; |
current = data + 3; |
- if (third_byte == 0x40) { |
- // pmulld xmm, xmm/m128 |
- get_modrm(*current, &mod, ®op, &rm); |
- AppendToBuffer("pmulld %s,", NameOfXMMRegister(regop)); |
- current += PrintRightXMMOperand(current); |
+ get_modrm(*current, &mod, ®op, &rm); |
+ switch (third_byte) { |
+#define SSE34_DIS_CASE(instruction, notUsed1, notUsed2, notUsed3, opcode) \ |
+ case 0x##opcode: { \ |
+ AppendToBuffer(#instruction " %s,", NameOfXMMRegister(regop)); \ |
+ current += PrintRightXMMOperand(current); \ |
+ break; \ |
+ } |
+ |
+ SSSE3_INSTRUCTION_LIST(SSE34_DIS_CASE) |
+ SSE4_INSTRUCTION_LIST(SSE34_DIS_CASE) |
+#undef SSE34_DIS_CASE |
+ default: |
+ UnimplementedInstruction(); |
} |
} else if (opcode == 0x3A) { |
byte third_byte = *current; |
@@ -1586,12 +1672,31 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { |
current += PrintRightXMMOperand(current); |
AppendToBuffer(",0x%x", (*current) & 3); |
current += 1; |
+ } else if (third_byte == 0x14) { |
+ get_modrm(*current, &mod, ®op, &rm); |
+ AppendToBuffer("pextrb "); // reg/m32, xmm, imm8 |
+ current += PrintRightOperand(current); |
+ AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); |
+ current += 1; |
+ } else if (third_byte == 0x15) { |
+ get_modrm(*current, &mod, ®op, &rm); |
+ AppendToBuffer("pextrw "); // reg/m32, xmm, imm8 |
+ current += PrintRightOperand(current); |
+ AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); |
+ current += 1; |
} else if (third_byte == 0x16) { |
get_modrm(*current, &mod, ®op, &rm); |
AppendToBuffer("pextrd "); // reg/m32, xmm, imm8 |
current += PrintRightOperand(current); |
AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3); |
current += 1; |
+ } else if (third_byte == 0x20) { |
+ get_modrm(*current, &mod, ®op, &rm); |
+ AppendToBuffer("pinsrd "); // xmm, reg/m32, imm8 |
+ AppendToBuffer(" %s,", NameOfXMMRegister(regop)); |
+ current += PrintRightOperand(current); |
+ AppendToBuffer(",%d", (*current) & 3); |
+ current += 1; |
} else if (third_byte == 0x21) { |
get_modrm(*current, &mod, ®op, &rm); |
// insertps xmm, xmm/m32, imm8 |
@@ -1666,15 +1771,20 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { |
current += PrintRightXMMOperand(current); |
AppendToBuffer(",0x%x", *current); |
current += 1; |
+ } else if (opcode == 0x71) { |
+ current += 1; |
+ AppendToBuffer("ps%sw %s,%d", sf_str[regop / 2], NameOfXMMRegister(rm), |
+ *current & 0x7f); |
+ current += 1; |
} else if (opcode == 0x72) { |
current += 1; |
- AppendToBuffer("%s %s,%d", (regop == 6) ? "pslld" : "psrld", |
- NameOfXMMRegister(rm), *current & 0x7f); |
+ AppendToBuffer("ps%sd %s,%d", sf_str[regop / 2], NameOfXMMRegister(rm), |
+ *current & 0x7f); |
current += 1; |
} else if (opcode == 0x73) { |
current += 1; |
- AppendToBuffer("%s %s,%d", (regop == 6) ? "psllq" : "psrlq", |
- NameOfXMMRegister(rm), *current & 0x7f); |
+ AppendToBuffer("ps%sq %s,%d", sf_str[regop / 2], NameOfXMMRegister(rm), |
+ *current & 0x7f); |
current += 1; |
} else if (opcode == 0xB1) { |
current += PrintOperands("cmpxchg", OPER_REG_OP_ORDER, current); |
@@ -1692,16 +1802,86 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { |
mnemonic = "ucomisd"; |
} else if (opcode == 0x2F) { |
mnemonic = "comisd"; |
+ } else if (opcode == 0x64) { |
+ mnemonic = "pcmpgtb"; |
+ } else if (opcode == 0x65) { |
+ mnemonic = "pcmpgtw"; |
+ } else if (opcode == 0x66) { |
+ mnemonic = "pcmpgtd"; |
+ } else if (opcode == 0x74) { |
+ mnemonic = "pcmpeqb"; |
+ } else if (opcode == 0x75) { |
+ mnemonic = "pcmpeqw"; |
} else if (opcode == 0x76) { |
mnemonic = "pcmpeqd"; |
} else if (opcode == 0x62) { |
mnemonic = "punpckldq"; |
+ } else if (opcode == 0x63) { |
+ mnemonic = "packsswb"; |
+ } else if (opcode == 0x67) { |
+ mnemonic = "packuswb"; |
} else if (opcode == 0x6A) { |
mnemonic = "punpckhdq"; |
+ } else if (opcode == 0x6B) { |
+ mnemonic = "packssdw"; |
+ } else if (opcode == 0xC4) { |
+ mnemonic = "pinsrw"; |
+ } else if (opcode == 0xC5) { |
+ mnemonic = "pextrw"; |
+ } else if (opcode == 0xD1) { |
+ mnemonic = "psrlw"; |
+ } else if (opcode == 0xD2) { |
+ mnemonic = "psrld"; |
+ } else if (opcode == 0xD5) { |
+ mnemonic = "pmullw"; |
+ } else if (opcode == 0xD7) { |
+ mnemonic = "pmovmskb"; |
+ } else if (opcode == 0xD8) { |
+ mnemonic = "psubusb"; |
+ } else if (opcode == 0xD9) { |
+ mnemonic = "psubusw"; |
+ } else if (opcode == 0xDA) { |
+ mnemonic = "pminub"; |
+ } else if (opcode == 0xDC) { |
+ mnemonic = "paddusb"; |
+ } else if (opcode == 0xDD) { |
+ mnemonic = "paddusw"; |
+ } else if (opcode == 0xDE) { |
+ mnemonic = "pmaxub"; |
+ } else if (opcode == 0xE1) { |
+ mnemonic = "psraw"; |
+ } else if (opcode == 0xE2) { |
+ mnemonic = "psrad"; |
+ } else if (opcode == 0xE8) { |
+ mnemonic = "psubsb"; |
+ } else if (opcode == 0xE9) { |
+ mnemonic = "psubsw"; |
+ } else if (opcode == 0xEA) { |
+ mnemonic = "pminsw"; |
+ } else if (opcode == 0xEC) { |
+ mnemonic = "paddsb"; |
+ } else if (opcode == 0xED) { |
+ mnemonic = "paddsw"; |
+ } else if (opcode == 0xEE) { |
+ mnemonic = "pmaxsw"; |
+ } else if (opcode == 0xEF) { |
+ mnemonic = "pxor"; |
+ } else if (opcode == 0xF1) { |
+ mnemonic = "psllw"; |
+ } else if (opcode == 0xF2) { |
+ mnemonic = "pslld"; |
} else if (opcode == 0xF4) { |
mnemonic = "pmuludq"; |
+ } else if (opcode == 0xF8) { |
+ mnemonic = "psubb"; |
+ } else if (opcode == 0xF9) { |
+ mnemonic = "psubw"; |
} else if (opcode == 0xFA) { |
mnemonic = "psubd"; |
+ } else if (opcode == 0xFC) { |
+ mnemonic = "paddb"; |
+ } else if (opcode == 0xFD) { |
+ mnemonic = "paddw"; |
} else if (opcode == 0xFE) { |
mnemonic = "paddd"; |
} else if (opcode == 0xC2) { |
@@ -1780,6 +1960,11 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { |
NameOfXMMRegister(regop), |
NameOfXMMRegister(rm)); |
current += 2; |
+ } else if (opcode == 0xF0) { |
+ int mod, regop, rm; |
+ get_modrm(*current, &mod, ®op, &rm); |
+ AppendToBuffer("lddqu %s,", NameOfXMMRegister(regop)); |
+ current += PrintRightOperand(current); |
} else { |
UnimplementedInstruction(); |
} |