Index: src/x64/disasm-x64.cc |
diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc |
index 4f5e74fa833075f24ba97ac44d773d2abb48833c..1db35198d3c190d036d6f1d6ecfaacec2aaf2bf7 100644 |
--- a/src/x64/disasm-x64.cc |
+++ b/src/x64/disasm-x64.cc |
@@ -870,7 +870,13 @@ int DisassemblerX64::SetCC(byte* data) { |
int DisassemblerX64::AVXInstruction(byte* data) { |
byte opcode = *data; |
byte* current = data + 1; |
- if (vex_66() && vex_0f38()) { |
+ if (vex_0f() && opcode == 0x2e) { |
+ int mod, regop, rm; |
+ get_modrm(*current, &mod, ®op, &rm); |
+ AppendToBuffer("vucomis%c %s,", vex_66() ? 'd' : 's', |
+ NameOfXMMRegister(regop)); |
+ current += PrintRightXMMOperand(current); |
+ } else if (vex_66() && vex_0f38()) { |
int mod, regop, rm, vvvv = vex_vreg(); |
get_modrm(*current, &mod, ®op, &rm); |
switch (opcode) { |
@@ -937,6 +943,43 @@ int DisassemblerX64::AVXInstruction(byte* data) { |
default: |
UnimplementedInstruction(); |
} |
+ } else if (vex_f3() && vex_0f()) { |
+ int mod, regop, rm, vvvv = vex_vreg(); |
+ get_modrm(*current, &mod, ®op, &rm); |
+ switch (opcode) { |
+ case 0x58: |
+ AppendToBuffer("vaddss %s,%s,", NameOfXMMRegister(regop), |
+ NameOfXMMRegister(vvvv)); |
+ current += PrintRightXMMOperand(current); |
+ break; |
+ case 0x59: |
+ AppendToBuffer("vmulss %s,%s,", NameOfXMMRegister(regop), |
+ NameOfXMMRegister(vvvv)); |
+ current += PrintRightXMMOperand(current); |
+ break; |
+ case 0x5c: |
+ AppendToBuffer("vsubss %s,%s,", NameOfXMMRegister(regop), |
+ NameOfXMMRegister(vvvv)); |
+ current += PrintRightXMMOperand(current); |
+ break; |
+ case 0x5d: |
+ AppendToBuffer("vminss %s,%s,", NameOfXMMRegister(regop), |
+ NameOfXMMRegister(vvvv)); |
+ current += PrintRightXMMOperand(current); |
+ break; |
+ case 0x5e: |
+ AppendToBuffer("vdivss %s,%s,", NameOfXMMRegister(regop), |
+ NameOfXMMRegister(vvvv)); |
+ current += PrintRightXMMOperand(current); |
+ break; |
+ case 0x5f: |
+ AppendToBuffer("vmaxss %s,%s,", NameOfXMMRegister(regop), |
+ NameOfXMMRegister(vvvv)); |
+ current += PrintRightXMMOperand(current); |
+ break; |
+ default: |
+ UnimplementedInstruction(); |
+ } |
} else if (vex_f2() && vex_0f()) { |
int mod, regop, rm, vvvv = vex_vreg(); |
get_modrm(*current, &mod, ®op, &rm); |
@@ -1304,7 +1347,7 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { |
// CVTSI2SD: integer to XMM double conversion. |
int mod, regop, rm; |
get_modrm(*current, &mod, ®op, &rm); |
- AppendToBuffer("%sd %s,", mnemonic, NameOfXMMRegister(regop)); |
+ AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); |
current += PrintRightOperand(current); |
} else if (opcode == 0x2C) { |
// CVTTSD2SI: |
@@ -1367,7 +1410,7 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { |
// CVTSI2SS: integer to XMM single conversion. |
int mod, regop, rm; |
get_modrm(*current, &mod, ®op, &rm); |
- AppendToBuffer("%ss %s,", mnemonic, NameOfXMMRegister(regop)); |
+ AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); |
current += PrintRightOperand(current); |
} else if (opcode == 0x2C) { |
// CVTTSS2SI: |
@@ -1377,38 +1420,27 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { |
AppendToBuffer("cvttss2si%c %s,", |
operand_size_code(), NameOfCPURegister(regop)); |
current += PrintRightXMMOperand(current); |
- } else if (opcode == 0x58) { |
- int mod, regop, rm; |
- get_modrm(*current, &mod, ®op, &rm); |
- AppendToBuffer("addss %s,", NameOfXMMRegister(regop)); |
- current += PrintRightXMMOperand(current); |
- } else if (opcode == 0x59) { |
- int mod, regop, rm; |
- get_modrm(*current, &mod, ®op, &rm); |
- AppendToBuffer("mulss %s,", NameOfXMMRegister(regop)); |
- current += PrintRightXMMOperand(current); |
- } else if (opcode == 0x5A) { |
- // CVTSS2SD: |
- // Convert scalar single-precision FP to scalar double-precision FP. |
- int mod, regop, rm; |
- get_modrm(*current, &mod, ®op, &rm); |
- AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop)); |
- current += PrintRightXMMOperand(current); |
- } else if (opcode == 0x5c) { |
+ } else if (opcode == 0x7E) { |
int mod, regop, rm; |
get_modrm(*current, &mod, ®op, &rm); |
- AppendToBuffer("subss %s,", NameOfXMMRegister(regop)); |
+ AppendToBuffer("movq %s,", NameOfXMMRegister(regop)); |
current += PrintRightXMMOperand(current); |
- } else if (opcode == 0x5e) { |
+ } else if ((opcode & 0xF8) == 0x58 || opcode == 0x51) { |
+ // XMM arithmetic. Mnemonic was retrieved at the start of this function. |
int mod, regop, rm; |
get_modrm(*current, &mod, ®op, &rm); |
- AppendToBuffer("divss %s,", NameOfXMMRegister(regop)); |
+ AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop)); |
current += PrintRightXMMOperand(current); |
- } else if (opcode == 0x7E) { |
+ } else if (opcode == 0xC2) { |
+ // Intel manual 2A, Table 3-18. |
int mod, regop, rm; |
get_modrm(*current, &mod, ®op, &rm); |
- AppendToBuffer("movq %s,", NameOfXMMRegister(regop)); |
- current += PrintRightXMMOperand(current); |
+ const char* const pseudo_op[] = {"cmpeqss", "cmpltss", "cmpless", |
+ "cmpunordss", "cmpneqss", "cmpnltss", |
+ "cmpnless", "cmpordss"}; |
+ AppendToBuffer("%s %s,%s", pseudo_op[current[1]], |
+ NameOfXMMRegister(regop), NameOfXMMRegister(rm)); |
+ current += 2; |
} else { |
UnimplementedInstruction(); |
} |
@@ -1544,23 +1576,23 @@ const char* DisassemblerX64::TwoByteMnemonic(byte opcode) { |
case 0x1F: |
return "nop"; |
case 0x2A: // F2/F3 prefix. |
- return "cvtsi2s"; |
- case 0x51: // F2 prefix. |
- return "sqrtsd"; |
- case 0x58: // F2 prefix. |
- return "addsd"; |
- case 0x59: // F2 prefix. |
- return "mulsd"; |
- case 0x5A: // F2 prefix. |
- return "cvtsd2ss"; |
- case 0x5D: // F2 prefix. |
- return "minsd"; |
- case 0x5C: // F2 prefix. |
- return "subsd"; |
- case 0x5E: // F2 prefix. |
- return "divsd"; |
- case 0x5F: // F2 prefix. |
- return "maxsd"; |
+ return (group_1_prefix_ == 0xF2) ? "cvtsi2sd" : "cvtsi2ss"; |
+ case 0x51: // F2/F3 prefix. |
+ return (group_1_prefix_ == 0xF2) ? "sqrtsd" : "sqrtss"; |
+ case 0x58: // F2/F3 prefix. |
+ return (group_1_prefix_ == 0xF2) ? "addsd" : "addss"; |
+ case 0x59: // F2/F3 prefix. |
+ return (group_1_prefix_ == 0xF2) ? "mulsd" : "mulss"; |
+ case 0x5A: // F2/F3 prefix. |
+ return (group_1_prefix_ == 0xF2) ? "cvtsd2ss" : "cvtss2sd"; |
+ case 0x5D: // F2/F3 prefix. |
+ return (group_1_prefix_ == 0xF2) ? "minsd" : "minss"; |
+ case 0x5C: // F2/F3 prefix. |
+ return (group_1_prefix_ == 0xF2) ? "subsd" : "subss"; |
+ case 0x5E: // F2/F3 prefix. |
+ return (group_1_prefix_ == 0xF2) ? "divsd" : "divss"; |
+ case 0x5F: // F2/F3 prefix. |
+ return (group_1_prefix_ == 0xF2) ? "maxsd" : "maxss"; |
case 0xA2: |
return "cpuid"; |
case 0xA5: |