| Index: src/x64/disasm-x64.cc
|
| diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc
|
| index 1db35198d3c190d036d6f1d6ecfaacec2aaf2bf7..4799a32f23db7027c331a6070968b1cdd0ef7f6e 100644
|
| --- a/src/x64/disasm-x64.cc
|
| +++ b/src/x64/disasm-x64.cc
|
| @@ -359,6 +359,12 @@ class DisassemblerX64 {
|
| return (checked & 4) != 1;
|
| }
|
|
|
| + bool vex_none() {
|
| + DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
|
| + byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
|
| + return (checked & 3) == 0;
|
| + }
|
| +
|
| bool vex_66() {
|
| DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
|
| byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
|
| @@ -940,6 +946,12 @@ int DisassemblerX64::AVXInstruction(byte* data) {
|
| NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
|
| current += PrintRightXMMOperand(current);
|
| break;
|
| + case 0xf7:
|
| + AppendToBuffer("shlx%c %s,", operand_size_code(),
|
| + NameOfCPURegister(regop));
|
| + current += PrintRightOperand(current);
|
| + AppendToBuffer(",%s", NameOfCPURegister(vvvv));
|
| + break;
|
| default:
|
| UnimplementedInstruction();
|
| }
|
| @@ -1017,6 +1029,114 @@ int DisassemblerX64::AVXInstruction(byte* data) {
|
| default:
|
| UnimplementedInstruction();
|
| }
|
| + } else if (vex_none() && vex_0f38()) {
|
| + int mod, regop, rm, vvvv = vex_vreg();
|
| + get_modrm(*current, &mod, ®op, &rm);
|
| + const char* mnem = "?";
|
| + switch (opcode) {
|
| + case 0xf2:
|
| + AppendToBuffer("andn%c %s,%s,", operand_size_code(),
|
| + NameOfCPURegister(regop), NameOfCPURegister(vvvv));
|
| + current += PrintRightOperand(current);
|
| + break;
|
| + case 0xf5:
|
| + AppendToBuffer("bzhi%c %s,", operand_size_code(),
|
| + NameOfCPURegister(regop));
|
| + current += PrintRightOperand(current);
|
| + AppendToBuffer(",%s", NameOfCPURegister(vvvv));
|
| + break;
|
| + case 0xf7:
|
| + AppendToBuffer("bextr%c %s,", operand_size_code(),
|
| + NameOfCPURegister(regop));
|
| + current += PrintRightOperand(current);
|
| + AppendToBuffer(",%s", NameOfCPURegister(vvvv));
|
| + break;
|
| + case 0xf3:
|
| + switch (regop) {
|
| + case 1:
|
| + mnem = "blsr";
|
| + break;
|
| + case 2:
|
| + mnem = "blsmsk";
|
| + break;
|
| + case 3:
|
| + mnem = "blsi";
|
| + break;
|
| + default:
|
| + UnimplementedInstruction();
|
| + }
|
| + AppendToBuffer("%s%c %s,", mnem, operand_size_code(),
|
| + NameOfCPURegister(vvvv));
|
| + current += PrintRightOperand(current);
|
| + mnem = "?";
|
| + break;
|
| + default:
|
| + UnimplementedInstruction();
|
| + }
|
| + } else if (vex_f2() && vex_0f38()) {
|
| + int mod, regop, rm, vvvv = vex_vreg();
|
| + get_modrm(*current, &mod, ®op, &rm);
|
| + switch (opcode) {
|
| + case 0xf5:
|
| + AppendToBuffer("pdep%c %s,%s,", operand_size_code(),
|
| + NameOfCPURegister(regop), NameOfCPURegister(vvvv));
|
| + current += PrintRightOperand(current);
|
| + break;
|
| + case 0xf6:
|
| + AppendToBuffer("mulx%c %s,%s,", operand_size_code(),
|
| + NameOfCPURegister(regop), NameOfCPURegister(vvvv));
|
| + current += PrintRightOperand(current);
|
| + break;
|
| + case 0xf7:
|
| + AppendToBuffer("shrx%c %s,", operand_size_code(),
|
| + NameOfCPURegister(regop));
|
| + current += PrintRightOperand(current);
|
| + AppendToBuffer(",%s", NameOfCPURegister(vvvv));
|
| + break;
|
| + default:
|
| + UnimplementedInstruction();
|
| + }
|
| + } else if (vex_f3() && vex_0f38()) {
|
| + int mod, regop, rm, vvvv = vex_vreg();
|
| + get_modrm(*current, &mod, ®op, &rm);
|
| + switch (opcode) {
|
| + case 0xf5:
|
| + AppendToBuffer("pext%c %s,%s,", operand_size_code(),
|
| + NameOfCPURegister(regop), NameOfCPURegister(vvvv));
|
| + current += PrintRightOperand(current);
|
| + break;
|
| + case 0xf7:
|
| + AppendToBuffer("sarx%c %s,", operand_size_code(),
|
| + NameOfCPURegister(regop));
|
| + current += PrintRightOperand(current);
|
| + AppendToBuffer(",%s", NameOfCPURegister(vvvv));
|
| + break;
|
| + default:
|
| + UnimplementedInstruction();
|
| + }
|
| + } else if (vex_f2() && vex_0f3a()) {
|
| + int mod, regop, rm;
|
| + get_modrm(*current, &mod, ®op, &rm);
|
| + switch (opcode) {
|
| + case 0xf0:
|
| + AppendToBuffer("rorx%c %s,", operand_size_code(),
|
| + NameOfCPURegister(regop));
|
| + current += PrintRightOperand(current);
|
| + switch (operand_size()) {
|
| + case OPERAND_DOUBLEWORD_SIZE:
|
| + AppendToBuffer(",%d", *current & 0x1f);
|
| + break;
|
| + case OPERAND_QUADWORD_SIZE:
|
| + AppendToBuffer(",%d", *current & 0x3f);
|
| + break;
|
| + default:
|
| + UnimplementedInstruction();
|
| + }
|
| + current += 1;
|
| + break;
|
| + default:
|
| + UnimplementedInstruction();
|
| + }
|
| } else {
|
| UnimplementedInstruction();
|
| }
|
| @@ -1431,6 +1551,24 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
|
| get_modrm(*current, &mod, ®op, &rm);
|
| AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop));
|
| current += PrintRightXMMOperand(current);
|
| + } else if (opcode == 0xB8) {
|
| + int mod, regop, rm;
|
| + get_modrm(*current, &mod, ®op, &rm);
|
| + AppendToBuffer("popcnt%c %s,", operand_size_code(),
|
| + NameOfCPURegister(regop));
|
| + current += PrintRightOperand(current);
|
| + } else if (opcode == 0xBC) {
|
| + int mod, regop, rm;
|
| + get_modrm(*current, &mod, ®op, &rm);
|
| + AppendToBuffer("tzcnt%c %s,", operand_size_code(),
|
| + NameOfCPURegister(regop));
|
| + current += PrintRightOperand(current);
|
| + } else if (opcode == 0xBD) {
|
| + int mod, regop, rm;
|
| + get_modrm(*current, &mod, ®op, &rm);
|
| + AppendToBuffer("lzcnt%c %s,", operand_size_code(),
|
| + NameOfCPURegister(regop));
|
| + current += PrintRightOperand(current);
|
| } else if (opcode == 0xC2) {
|
| // Intel manual 2A, Table 3-18.
|
| int mod, regop, rm;
|
| @@ -1643,12 +1781,14 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
|
| vex_byte1_ = *(data + 1);
|
| vex_byte2_ = *(data + 2);
|
| setRex(0x40 | (~(vex_byte1_ >> 5) & 7) | ((vex_byte2_ >> 4) & 8));
|
| - data += 2;
|
| + data += 3;
|
| + break; // Vex is the last prefix.
|
| } else if (current == VEX2_PREFIX) {
|
| vex_byte0_ = current;
|
| vex_byte1_ = *(data + 1);
|
| setRex(0x40 | (~(vex_byte1_ >> 5) & 4));
|
| - data++;
|
| + data += 2;
|
| + break; // Vex is the last prefix.
|
| } else { // Not a prefix - an opcode.
|
| break;
|
| }
|
|
|