9 #if V8_TARGET_ARCH_IA32 11 #include "src/base/compiler-specific.h" 12 #include "src/disasm.h" 13 #include "src/ia32/sse-instr.h" 30 OperandOrder op_order_;
33 static const ByteMnemonic two_operands_instr[] = {
34 {0x01,
"add", OPER_REG_OP_ORDER}, {0x03,
"add", REG_OPER_OP_ORDER},
35 {0x09,
"or", OPER_REG_OP_ORDER}, {0x0B,
"or", REG_OPER_OP_ORDER},
36 {0x13,
"adc", REG_OPER_OP_ORDER}, {0x1B,
"sbb", REG_OPER_OP_ORDER},
37 {0x21,
"and", OPER_REG_OP_ORDER}, {0x23,
"and", REG_OPER_OP_ORDER},
38 {0x29,
"sub", OPER_REG_OP_ORDER}, {0x2A,
"subb", REG_OPER_OP_ORDER},
39 {0x2B,
"sub", REG_OPER_OP_ORDER}, {0x31,
"xor", OPER_REG_OP_ORDER},
40 {0x33,
"xor", REG_OPER_OP_ORDER}, {0x38,
"cmpb", OPER_REG_OP_ORDER},
41 {0x39,
"cmp", OPER_REG_OP_ORDER}, {0x3A,
"cmpb", REG_OPER_OP_ORDER},
42 {0x3B,
"cmp", REG_OPER_OP_ORDER}, {0x84,
"test_b", REG_OPER_OP_ORDER},
43 {0x85,
"test", REG_OPER_OP_ORDER}, {0x86,
"xchg_b", REG_OPER_OP_ORDER},
44 {0x87,
"xchg", REG_OPER_OP_ORDER}, {0x8A,
"mov_b", REG_OPER_OP_ORDER},
45 {0x8B,
"mov", REG_OPER_OP_ORDER}, {0x8D,
"lea", REG_OPER_OP_ORDER},
46 {-1,
"", UNSET_OP_ORDER}};
48 static const ByteMnemonic zero_operands_instr[] = {
49 {0xC3,
"ret", UNSET_OP_ORDER},
50 {0xC9,
"leave", UNSET_OP_ORDER},
51 {0x90,
"nop", UNSET_OP_ORDER},
52 {0xF4,
"hlt", UNSET_OP_ORDER},
53 {0xCC,
"int3", UNSET_OP_ORDER},
54 {0x60,
"pushad", UNSET_OP_ORDER},
55 {0x61,
"popad", UNSET_OP_ORDER},
56 {0x9C,
"pushfd", UNSET_OP_ORDER},
57 {0x9D,
"popfd", UNSET_OP_ORDER},
58 {0x9E,
"sahf", UNSET_OP_ORDER},
59 {0x99,
"cdq", UNSET_OP_ORDER},
60 {0x9B,
"fwait", UNSET_OP_ORDER},
61 {0xFC,
"cld", UNSET_OP_ORDER},
62 {0xAB,
"stos", UNSET_OP_ORDER},
63 {-1,
"", UNSET_OP_ORDER}
67 static const ByteMnemonic call_jump_instr[] = {
68 {0xE8,
"call", UNSET_OP_ORDER},
69 {0xE9,
"jmp", UNSET_OP_ORDER},
70 {-1,
"", UNSET_OP_ORDER}
74 static const ByteMnemonic short_immediate_instr[] = {
75 {0x05,
"add", UNSET_OP_ORDER},
76 {0x0D,
"or", UNSET_OP_ORDER},
77 {0x15,
"adc", UNSET_OP_ORDER},
78 {0x25,
"and", UNSET_OP_ORDER},
79 {0x2D,
"sub", UNSET_OP_ORDER},
80 {0x35,
"xor", UNSET_OP_ORDER},
81 {0x3D,
"cmp", UNSET_OP_ORDER},
82 {-1,
"", UNSET_OP_ORDER}
90 static ByteMnemonic byte_immediate_instr[] = {{0x0C,
"or", UNSET_OP_ORDER},
91 {0x24,
"and", UNSET_OP_ORDER},
92 {0x34,
"xor", UNSET_OP_ORDER},
93 {0x3C,
"cmp", UNSET_OP_ORDER},
94 {-1,
"", UNSET_OP_ORDER}};
96 static const char*
const jump_conditional_mnem[] = {
97 "jo",
"jno",
"jc",
"jnc",
98 "jz",
"jnz",
"jna",
"ja",
99 "js",
"jns",
"jpe",
"jpo",
100 "jl",
"jnl",
"jng",
"jg" 104 static const char*
const set_conditional_mnem[] = {
105 "seto",
"setno",
"setc",
"setnc",
106 "setz",
"setnz",
"setna",
"seta",
107 "sets",
"setns",
"setpe",
"setpo",
108 "setl",
"setnl",
"setng",
"setg" 112 static const char*
const conditional_move_mnem[] = {
113 "cmovo",
"cmovno",
"cmovc",
"cmovnc",
114 "cmovz",
"cmovnz",
"cmovna",
"cmova",
115 "cmovs",
"cmovns",
"cmovpe",
"cmovpo",
116 "cmovl",
"cmovnl",
"cmovng",
"cmovg" 120 enum InstructionType {
124 JUMP_CONDITIONAL_SHORT_INSTR,
128 SHORT_IMMEDIATE_INSTR,
133 struct InstructionDesc {
135 InstructionType type;
136 OperandOrder op_order_;
140 class InstructionTable {
143 const InstructionDesc& Get(byte x)
const {
return instructions_[x]; }
144 static InstructionTable* get_instance() {
145 static InstructionTable table;
150 InstructionDesc instructions_[256];
153 void CopyTable(
const ByteMnemonic bm[], InstructionType type);
154 void SetTableRange(InstructionType type,
158 void AddJumpConditionalShort();
162 InstructionTable::InstructionTable() {
168 void InstructionTable::Clear() {
169 for (
int i = 0;
i < 256;
i++) {
170 instructions_[
i].mnem =
"";
171 instructions_[
i].type = NO_INSTR;
172 instructions_[
i].op_order_ = UNSET_OP_ORDER;
177 void InstructionTable::Init() {
178 CopyTable(two_operands_instr, TWO_OPERANDS_INSTR);
179 CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR);
180 CopyTable(call_jump_instr, CALL_JUMP_INSTR);
181 CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
182 CopyTable(byte_immediate_instr, BYTE_IMMEDIATE_INSTR);
183 AddJumpConditionalShort();
184 SetTableRange(REGISTER_INSTR, 0x40, 0x47,
"inc");
185 SetTableRange(REGISTER_INSTR, 0x48, 0x4F,
"dec");
186 SetTableRange(REGISTER_INSTR, 0x50, 0x57,
"push");
187 SetTableRange(REGISTER_INSTR, 0x58, 0x5F,
"pop");
188 SetTableRange(REGISTER_INSTR, 0x91, 0x97,
"xchg eax,");
189 SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF,
"mov");
193 void InstructionTable::CopyTable(
const ByteMnemonic bm[],
194 InstructionType type) {
195 for (
int i = 0; bm[
i].b >= 0;
i++) {
196 InstructionDesc*
id = &instructions_[bm[
i].b];
197 id->mnem = bm[
i].mnem;
198 id->op_order_ = bm[
i].op_order_;
199 DCHECK_EQ(NO_INSTR, id->type);
205 void InstructionTable::SetTableRange(InstructionType type,
209 for (byte b = start; b <= end; b++) {
210 InstructionDesc*
id = &instructions_[b];
211 DCHECK_EQ(NO_INSTR, id->type);
218 void InstructionTable::AddJumpConditionalShort() {
219 for (byte b = 0x70; b <= 0x7F; b++) {
220 InstructionDesc*
id = &instructions_[b];
221 DCHECK_EQ(NO_INSTR, id->type);
222 id->mnem = jump_conditional_mnem[b & 0x0F];
223 id->type = JUMP_CONDITIONAL_SHORT_INSTR;
229 class DisassemblerIA32 {
232 const NameConverter& converter,
233 Disassembler::UnimplementedOpcodeAction unimplemented_opcode_action)
234 : converter_(converter),
238 instruction_table_(InstructionTable::get_instance()),
240 unimplemented_opcode_action_(unimplemented_opcode_action) {
241 tmp_buffer_[0] =
'\0';
244 virtual ~DisassemblerIA32() {}
251 const NameConverter& converter_;
255 InstructionTable* instruction_table_;
257 unsigned int tmp_buffer_pos_;
258 Disassembler::UnimplementedOpcodeAction unimplemented_opcode_action_;
272 enum ShiftOpcodeExtension {
283 DCHECK(vex_byte0_ == 0xC4 || vex_byte0_ == 0xC5);
284 byte checked = vex_byte0_ == 0xC4 ? vex_byte2_ : vex_byte1_;
285 return (checked & 4) == 0;
289 DCHECK(vex_byte0_ == 0xC4 || vex_byte0_ == 0xC5);
290 byte checked = vex_byte0_ == 0xC4 ? vex_byte2_ : vex_byte1_;
291 return (checked & 3) == 0;
295 DCHECK(vex_byte0_ == 0xC4 || vex_byte0_ == 0xC5);
296 byte checked = vex_byte0_ == 0xC4 ? vex_byte2_ : vex_byte1_;
297 return (checked & 3) == 1;
301 DCHECK(vex_byte0_ == 0xC4 || vex_byte0_ == 0xC5);
302 byte checked = vex_byte0_ == 0xC4 ? vex_byte2_ : vex_byte1_;
303 return (checked & 3) == 2;
307 DCHECK(vex_byte0_ == 0xC4 || vex_byte0_ == 0xC5);
308 byte checked = vex_byte0_ == 0xC4 ? vex_byte2_ : vex_byte1_;
309 return (checked & 3) == 3;
313 if (vex_byte0_ == 0xC5)
return false;
314 return (vex_byte2_ & 0x80) != 0;
318 if (vex_byte0_ == 0xC5)
return true;
319 return (vex_byte1_ & 3) == 1;
323 if (vex_byte0_ == 0xC5)
return false;
324 return (vex_byte1_ & 3) == 2;
328 if (vex_byte0_ == 0xC5)
return false;
329 return (vex_byte1_ & 3) == 3;
333 DCHECK(vex_byte0_ == 0xC4 || vex_byte0_ == 0xC5);
334 byte checked = vex_byte0_ == 0xC4 ? vex_byte2_ : vex_byte1_;
335 return ~(checked >> 3) & 0xF;
338 char float_size_code() {
return "sd"[vex_w()]; }
340 const char* NameOfCPURegister(
int reg)
const {
341 return converter_.NameOfCPURegister(reg);
345 const char* NameOfByteCPURegister(
int reg)
const {
346 return converter_.NameOfByteCPURegister(reg);
350 const char* NameOfXMMRegister(
int reg)
const {
351 return converter_.NameOfXMMRegister(reg);
355 const char* NameOfAddress(byte* addr)
const {
356 return converter_.NameOfAddress(addr);
361 static void get_modrm(byte data,
int* mod,
int* regop,
int* rm) {
362 *mod = (data >> 6) & 3;
363 *regop = (data & 0x38) >> 3;
368 static void get_sib(byte data,
int* scale,
int* index,
int* base) {
369 *scale = (data >> 6) & 3;
370 *index = (data >> 3) & 7;
374 typedef const char* (DisassemblerIA32::*RegisterNameMapping)(
int reg)
const;
376 int PrintRightOperandHelper(byte* modrmp, RegisterNameMapping register_name);
377 int PrintRightOperand(byte* modrmp);
378 int PrintRightByteOperand(byte* modrmp);
379 int PrintRightXMMOperand(byte* modrmp);
380 int PrintOperands(
const char* mnem, OperandOrder op_order, byte* data);
381 int PrintImmediateOp(byte* data);
382 int F7Instruction(byte* data);
383 int D1D3C1Instruction(byte* data);
384 int JumpShort(byte* data);
385 int JumpConditional(byte* data,
const char* comment);
386 int JumpConditionalShort(byte* data,
const char* comment);
387 int SetCC(byte* data);
388 int CMov(byte* data);
389 int FPUInstruction(byte* data);
390 int MemoryFPUInstruction(
int escape_opcode,
int regop, byte* modrm_start);
391 int RegisterFPUInstruction(
int escape_opcode, byte modrm_byte);
392 int AVXInstruction(byte* data);
393 PRINTF_FORMAT(2, 3) void AppendToBuffer(const
char* format, ...);
395 void UnimplementedInstruction() {
396 if (unimplemented_opcode_action_ ==
397 Disassembler::kAbortOnUnimplementedOpcode) {
398 FATAL(
"Unimplemented instruction in disassembler");
400 AppendToBuffer(
"'Unimplemented Instruction'");
406 void DisassemblerIA32::AppendToBuffer(
const char* format, ...) {
409 va_start(args, format);
410 int result = v8::internal::VSNPrintF(buf, format, args);
412 tmp_buffer_pos_ += result;
415 int DisassemblerIA32::PrintRightOperandHelper(
417 RegisterNameMapping direct_register_name) {
419 get_modrm(*modrmp, &mod, ®op, &rm);
420 RegisterNameMapping register_name = (mod == 3) ? direct_register_name :
421 &DisassemblerIA32::NameOfCPURegister;
425 int32_t disp = *
reinterpret_cast<int32_t*
>(modrmp+1);
426 AppendToBuffer(
"[0x%x]", disp);
428 }
else if (rm == esp) {
429 byte sib = *(modrmp + 1);
430 int scale, index, base;
431 get_sib(sib, &scale, &index, &base);
432 if (index == esp && base == esp && scale == 0 ) {
433 AppendToBuffer(
"[%s]", (this->*register_name)(rm));
435 }
else if (base == ebp) {
436 int32_t disp = *
reinterpret_cast<int32_t*
>(modrmp + 2);
437 AppendToBuffer(
"[%s*%d%s0x%x]",
438 (this->*register_name)(index),
440 disp < 0 ?
"-" :
"+",
441 disp < 0 ? -disp : disp);
443 }
else if (index != esp && base != ebp) {
445 AppendToBuffer(
"[%s+%s*%d]",
446 (this->*register_name)(base),
447 (this->*register_name)(index),
451 UnimplementedInstruction();
455 AppendToBuffer(
"[%s]", (this->*register_name)(rm));
462 byte sib = *(modrmp + 1);
463 int scale, index, base;
464 get_sib(sib, &scale, &index, &base);
465 int disp = mod == 2 ? *
reinterpret_cast<int32_t*
>(modrmp + 2)
466 : *reinterpret_cast<int8_t*>(modrmp + 2);
467 if (index == base && index == rm && scale == 0 ) {
468 AppendToBuffer(
"[%s%s0x%x]",
469 (this->*register_name)(rm),
470 disp < 0 ?
"-" :
"+",
471 disp < 0 ? -disp : disp);
473 AppendToBuffer(
"[%s+%s*%d%s0x%x]",
474 (this->*register_name)(base),
475 (this->*register_name)(index),
477 disp < 0 ?
"-" :
"+",
478 disp < 0 ? -disp : disp);
480 return mod == 2 ? 6 : 3;
483 int disp = mod == 2 ? *
reinterpret_cast<int32_t*
>(modrmp + 1)
484 : *reinterpret_cast<int8_t*>(modrmp + 1);
485 AppendToBuffer(
"[%s%s0x%x]",
486 (this->*register_name)(rm),
487 disp < 0 ?
"-" :
"+",
488 disp < 0 ? -disp : disp);
489 return mod == 2 ? 5 : 2;
493 AppendToBuffer(
"%s", (this->*register_name)(rm));
496 UnimplementedInstruction();
503 int DisassemblerIA32::PrintRightOperand(byte* modrmp) {
504 return PrintRightOperandHelper(modrmp, &DisassemblerIA32::NameOfCPURegister);
508 int DisassemblerIA32::PrintRightByteOperand(byte* modrmp) {
509 return PrintRightOperandHelper(modrmp,
510 &DisassemblerIA32::NameOfByteCPURegister);
514 int DisassemblerIA32::PrintRightXMMOperand(byte* modrmp) {
515 return PrintRightOperandHelper(modrmp,
516 &DisassemblerIA32::NameOfXMMRegister);
522 int DisassemblerIA32::PrintOperands(
const char* mnem,
523 OperandOrder op_order,
527 get_modrm(modrm, &mod, ®op, &rm);
530 case REG_OPER_OP_ORDER: {
531 AppendToBuffer(
"%s %s,", mnem, NameOfCPURegister(regop));
532 advance = PrintRightOperand(data);
535 case OPER_REG_OP_ORDER: {
536 AppendToBuffer(
"%s ", mnem);
537 advance = PrintRightOperand(data);
538 AppendToBuffer(
",%s", NameOfCPURegister(regop));
551 int DisassemblerIA32::PrintImmediateOp(byte* data) {
552 bool sign_extension_bit = (*data & 0x02) != 0;
553 byte modrm = *(data+1);
555 get_modrm(modrm, &mod, ®op, &rm);
556 const char* mnem =
"Imm???";
558 case 0: mnem =
"add";
break;
559 case 1: mnem =
"or";
break;
560 case 2: mnem =
"adc";
break;
561 case 4: mnem =
"and";
break;
562 case 5: mnem =
"sub";
break;
563 case 6: mnem =
"xor";
break;
564 case 7: mnem =
"cmp";
break;
565 default: UnimplementedInstruction();
567 AppendToBuffer(
"%s ", mnem);
568 int count = PrintRightOperand(data+1);
569 if (sign_extension_bit) {
570 AppendToBuffer(
",0x%x", *(data + 1 + count));
571 return 1 + count + 1 ;
573 AppendToBuffer(
",0x%x", *reinterpret_cast<int32_t*>(data + 1 + count));
574 return 1 + count + 4 ;
580 int DisassemblerIA32::F7Instruction(byte* data) {
581 DCHECK_EQ(0xF7, *data);
582 byte modrm = *++data;
584 get_modrm(modrm, &mod, ®op, &rm);
585 const char* mnem =
nullptr;
609 UnimplementedInstruction();
611 AppendToBuffer(
"%s ", mnem);
612 int count = PrintRightOperand(data);
614 AppendToBuffer(
",0x%x", *reinterpret_cast<int32_t*>(data + count));
621 int DisassemblerIA32::D1D3C1Instruction(byte* data) {
623 DCHECK(op == 0xD1 || op == 0xD3 || op == 0xC1);
624 byte modrm = *++data;
626 get_modrm(modrm, &mod, ®op, &rm);
628 const char* mnem =
nullptr;
652 UnimplementedInstruction();
654 AppendToBuffer(
"%s ", mnem);
655 int count = PrintRightOperand(data);
658 }
else if (op == 0xC1) {
661 }
else if (op == 0xD3) {
665 AppendToBuffer(
",%d", imm8);
667 AppendToBuffer(
",cl");
674 int DisassemblerIA32::JumpShort(byte* data) {
675 DCHECK_EQ(0xEB, *data);
677 byte* dest = data +
static_cast<int8_t
>(b) + 2;
678 AppendToBuffer(
"jmp %s", NameOfAddress(dest));
684 int DisassemblerIA32::JumpConditional(byte* data,
const char* comment) {
685 DCHECK_EQ(0x0F, *data);
686 byte cond = *(data+1) & 0x0F;
687 byte* dest = data + *
reinterpret_cast<int32_t*
>(data+2) + 6;
688 const char* mnem = jump_conditional_mnem[cond];
689 AppendToBuffer(
"%s %s", mnem, NameOfAddress(dest));
690 if (comment !=
nullptr) {
691 AppendToBuffer(
", %s", comment);
698 int DisassemblerIA32::JumpConditionalShort(byte* data,
const char* comment) {
699 byte cond = *data & 0x0F;
701 byte* dest = data +
static_cast<int8_t
>(b) + 2;
702 const char* mnem = jump_conditional_mnem[cond];
703 AppendToBuffer(
"%s %s", mnem, NameOfAddress(dest));
704 if (comment !=
nullptr) {
705 AppendToBuffer(
", %s", comment);
712 int DisassemblerIA32::SetCC(byte* data) {
713 DCHECK_EQ(0x0F, *data);
714 byte cond = *(data+1) & 0x0F;
715 const char* mnem = set_conditional_mnem[cond];
716 AppendToBuffer(
"%s ", mnem);
717 PrintRightByteOperand(data+2);
723 int DisassemblerIA32::CMov(byte* data) {
724 DCHECK_EQ(0x0F, *data);
725 byte cond = *(data + 1) & 0x0F;
726 const char* mnem = conditional_move_mnem[cond];
727 int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2);
731 const char* sf_str[4] = {
"",
"rl",
"ra",
"ll"};
733 int DisassemblerIA32::AVXInstruction(byte* data) {
735 byte* current = data + 1;
736 if (vex_66() && vex_0f38()) {
737 int mod, regop, rm, vvvv = vex_vreg();
738 get_modrm(*current, &mod, ®op, &rm);
741 AppendToBuffer(
"vfmadd132s%c %s,%s,", float_size_code(),
742 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
743 current += PrintRightXMMOperand(current);
746 AppendToBuffer(
"vfmadd213s%c %s,%s,", float_size_code(),
747 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
748 current += PrintRightXMMOperand(current);
751 AppendToBuffer(
"vfmadd231s%c %s,%s,", float_size_code(),
752 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
753 current += PrintRightXMMOperand(current);
756 AppendToBuffer(
"vfmsub132s%c %s,%s,", float_size_code(),
757 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
758 current += PrintRightXMMOperand(current);
761 AppendToBuffer(
"vfmsub213s%c %s,%s,", float_size_code(),
762 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
763 current += PrintRightXMMOperand(current);
766 AppendToBuffer(
"vfmsub231s%c %s,%s,", float_size_code(),
767 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
768 current += PrintRightXMMOperand(current);
771 AppendToBuffer(
"vfnmadd132s%c %s,%s,", float_size_code(),
772 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
773 current += PrintRightXMMOperand(current);
776 AppendToBuffer(
"vfnmadd213s%c %s,%s,", float_size_code(),
777 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
778 current += PrintRightXMMOperand(current);
781 AppendToBuffer(
"vfnmadd231s%c %s,%s,", float_size_code(),
782 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
783 current += PrintRightXMMOperand(current);
786 AppendToBuffer(
"vfnmsub132s%c %s,%s,", float_size_code(),
787 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
788 current += PrintRightXMMOperand(current);
791 AppendToBuffer(
"vfnmsub213s%c %s,%s,", float_size_code(),
792 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
793 current += PrintRightXMMOperand(current);
796 AppendToBuffer(
"vfnmsub231s%c %s,%s,", float_size_code(),
797 NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
798 current += PrintRightXMMOperand(current);
801 AppendToBuffer(
"shlx %s,", NameOfCPURegister(regop));
802 current += PrintRightOperand(current);
803 AppendToBuffer(
",%s", NameOfCPURegister(vvvv));
805 #define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, notUsed3, \ 808 AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \ 809 NameOfXMMRegister(vvvv)); \ 810 current += PrintRightXMMOperand(current); \ 814 SSSE3_INSTRUCTION_LIST(DECLARE_SSE_AVX_DIS_CASE)
815 SSE4_INSTRUCTION_LIST(DECLARE_SSE_AVX_DIS_CASE)
816 #undef DECLARE_SSE_AVX_DIS_CASE 817 #define DECLARE_SSE_AVX_RM_DIS_CASE(instruction, notUsed1, notUsed2, notUsed3, \ 820 AppendToBuffer("v" #instruction " %s,", NameOfXMMRegister(regop)); \ 821 current += PrintRightXMMOperand(current); \ 825 SSE4_RM_INSTRUCTION_LIST(DECLARE_SSE_AVX_RM_DIS_CASE)
826 #undef DECLARE_SSE_AVX_RM_DIS_CASE 828 UnimplementedInstruction();
830 }
else if (vex_66() && vex_0f3a()) {
831 int mod, regop, rm, vvvv = vex_vreg();
832 get_modrm(*current, &mod, ®op, &rm);
835 AppendToBuffer(
"vpblendw %s,%s,", NameOfXMMRegister(regop),
836 NameOfXMMRegister(vvvv));
837 current += PrintRightXMMOperand(current);
838 AppendToBuffer(
",%d", *reinterpret_cast<uint8_t*>(current));
842 AppendToBuffer(
"vpalignr %s,%s,", NameOfXMMRegister(regop),
843 NameOfXMMRegister(vvvv));
844 current += PrintRightXMMOperand(current);
845 AppendToBuffer(
",%d", *reinterpret_cast<uint8_t*>(current));
849 AppendToBuffer(
"vpextrb ");
850 current += PrintRightOperand(current);
851 AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop),
852 *reinterpret_cast<int8_t*>(current));
856 AppendToBuffer(
"vpextrw ");
857 current += PrintRightOperand(current);
858 AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop),
859 *reinterpret_cast<int8_t*>(current));
863 AppendToBuffer(
"vpextrd ");
864 current += PrintRightOperand(current);
865 AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop),
866 *reinterpret_cast<int8_t*>(current));
870 AppendToBuffer(
"vpinsrb %s,%s,", NameOfXMMRegister(regop),
871 NameOfXMMRegister(vvvv));
872 current += PrintRightOperand(current);
873 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(current));
877 AppendToBuffer(
"vinsertps %s,%s,", NameOfXMMRegister(regop),
878 NameOfXMMRegister(vvvv));
879 current += PrintRightXMMOperand(current);
880 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(current));
884 AppendToBuffer(
"vpinsrd %s,%s,", NameOfXMMRegister(regop),
885 NameOfXMMRegister(vvvv));
886 current += PrintRightOperand(current);
887 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(current));
891 UnimplementedInstruction();
893 }
else if (vex_f2() && vex_0f()) {
894 int mod, regop, rm, vvvv = vex_vreg();
895 get_modrm(*current, &mod, ®op, &rm);
898 AppendToBuffer(
"vsqrtsd %s,%s,", NameOfXMMRegister(regop),
899 NameOfXMMRegister(vvvv));
900 current += PrintRightXMMOperand(current);
903 AppendToBuffer(
"vaddsd %s,%s,", NameOfXMMRegister(regop),
904 NameOfXMMRegister(vvvv));
905 current += PrintRightXMMOperand(current);
908 AppendToBuffer(
"vmulsd %s,%s,", NameOfXMMRegister(regop),
909 NameOfXMMRegister(vvvv));
910 current += PrintRightXMMOperand(current);
913 AppendToBuffer(
"vsubsd %s,%s,", NameOfXMMRegister(regop),
914 NameOfXMMRegister(vvvv));
915 current += PrintRightXMMOperand(current);
918 AppendToBuffer(
"vminsd %s,%s,", NameOfXMMRegister(regop),
919 NameOfXMMRegister(vvvv));
920 current += PrintRightXMMOperand(current);
923 AppendToBuffer(
"vdivsd %s,%s,", NameOfXMMRegister(regop),
924 NameOfXMMRegister(vvvv));
925 current += PrintRightXMMOperand(current);
928 AppendToBuffer(
"vmaxsd %s,%s,", NameOfXMMRegister(regop),
929 NameOfXMMRegister(vvvv));
930 current += PrintRightXMMOperand(current);
933 AppendToBuffer(
"vpshuflw %s,", NameOfXMMRegister(regop));
934 current += PrintRightXMMOperand(current);
935 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(current));
939 AppendToBuffer(
"vhaddps %s,%s,", NameOfXMMRegister(regop),
940 NameOfXMMRegister(vvvv));
941 current += PrintRightXMMOperand(current);
944 UnimplementedInstruction();
946 }
else if (vex_f3() && vex_0f()) {
947 int mod, regop, rm, vvvv = vex_vreg();
948 get_modrm(*current, &mod, ®op, &rm);
951 AppendToBuffer(
"vsqrtss %s,%s,", NameOfXMMRegister(regop),
952 NameOfXMMRegister(vvvv));
953 current += PrintRightXMMOperand(current);
956 AppendToBuffer(
"vaddss %s,%s,", NameOfXMMRegister(regop),
957 NameOfXMMRegister(vvvv));
958 current += PrintRightXMMOperand(current);
961 AppendToBuffer(
"vmulss %s,%s,", NameOfXMMRegister(regop),
962 NameOfXMMRegister(vvvv));
963 current += PrintRightXMMOperand(current);
966 AppendToBuffer(
"vcvttps2dq %s,", NameOfXMMRegister(regop));
967 current += PrintRightXMMOperand(current);
970 AppendToBuffer(
"vsubss %s,%s,", NameOfXMMRegister(regop),
971 NameOfXMMRegister(vvvv));
972 current += PrintRightXMMOperand(current);
975 AppendToBuffer(
"vminss %s,%s,", NameOfXMMRegister(regop),
976 NameOfXMMRegister(vvvv));
977 current += PrintRightXMMOperand(current);
980 AppendToBuffer(
"vdivss %s,%s,", NameOfXMMRegister(regop),
981 NameOfXMMRegister(vvvv));
982 current += PrintRightXMMOperand(current);
985 AppendToBuffer(
"vmaxss %s,%s,", NameOfXMMRegister(regop),
986 NameOfXMMRegister(vvvv));
987 current += PrintRightXMMOperand(current);
990 AppendToBuffer(
"vmovdqu %s,", NameOfXMMRegister(regop));
991 current += PrintRightOperand(current);
994 AppendToBuffer(
"vpshufhw %s,", NameOfXMMRegister(regop));
995 current += PrintRightXMMOperand(current);
996 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(current));
1000 AppendToBuffer(
"vmovdqu ");
1001 current += PrintRightOperand(current);
1002 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
1005 UnimplementedInstruction();
1007 }
else if (vex_none() && vex_0f38()) {
1008 int mod, regop, rm, vvvv = vex_vreg();
1009 get_modrm(*current, &mod, ®op, &rm);
1010 const char* mnem =
"?";
1013 AppendToBuffer(
"andn %s,%s,", NameOfCPURegister(regop),
1014 NameOfCPURegister(vvvv));
1015 current += PrintRightOperand(current);
1018 AppendToBuffer(
"bzhi %s,", NameOfCPURegister(regop));
1019 current += PrintRightOperand(current);
1020 AppendToBuffer(
",%s", NameOfCPURegister(vvvv));
1023 AppendToBuffer(
"bextr %s,", NameOfCPURegister(regop));
1024 current += PrintRightOperand(current);
1025 AppendToBuffer(
",%s", NameOfCPURegister(vvvv));
1039 UnimplementedInstruction();
1041 AppendToBuffer(
"%s %s,", mnem, NameOfCPURegister(vvvv));
1042 current += PrintRightOperand(current);
1046 UnimplementedInstruction();
1048 }
else if (vex_f2() && vex_0f38()) {
1049 int mod, regop, rm, vvvv = vex_vreg();
1050 get_modrm(*current, &mod, ®op, &rm);
1053 AppendToBuffer(
"pdep %s,%s,", NameOfCPURegister(regop),
1054 NameOfCPURegister(vvvv));
1055 current += PrintRightOperand(current);
1058 AppendToBuffer(
"mulx %s,%s,", NameOfCPURegister(regop),
1059 NameOfCPURegister(vvvv));
1060 current += PrintRightOperand(current);
1063 AppendToBuffer(
"shrx %s,", NameOfCPURegister(regop));
1064 current += PrintRightOperand(current);
1065 AppendToBuffer(
",%s", NameOfCPURegister(vvvv));
1068 UnimplementedInstruction();
1070 }
else if (vex_f3() && vex_0f38()) {
1071 int mod, regop, rm, vvvv = vex_vreg();
1072 get_modrm(*current, &mod, ®op, &rm);
1075 AppendToBuffer(
"pext %s,%s,", NameOfCPURegister(regop),
1076 NameOfCPURegister(vvvv));
1077 current += PrintRightOperand(current);
1080 AppendToBuffer(
"sarx %s,", NameOfCPURegister(regop));
1081 current += PrintRightOperand(current);
1082 AppendToBuffer(
",%s", NameOfCPURegister(vvvv));
1085 UnimplementedInstruction();
1087 }
else if (vex_f2() && vex_0f3a()) {
1089 get_modrm(*current, &mod, ®op, &rm);
1092 AppendToBuffer(
"rorx %s,", NameOfCPURegister(regop));
1093 current += PrintRightOperand(current);
1094 AppendToBuffer(
",%d", *current & 0x1F);
1098 UnimplementedInstruction();
1100 }
else if (vex_none() && vex_0f()) {
1101 int mod, regop, rm, vvvv = vex_vreg();
1102 get_modrm(*current, &mod, ®op, &rm);
1105 AppendToBuffer(
"vmovaps %s,", NameOfXMMRegister(regop));
1106 current += PrintRightXMMOperand(current);
1109 AppendToBuffer(
"vrsqrtps %s,", NameOfXMMRegister(regop));
1110 current += PrintRightXMMOperand(current);
1113 AppendToBuffer(
"vrcpps %s,", NameOfXMMRegister(regop));
1114 current += PrintRightXMMOperand(current);
1117 AppendToBuffer(
"vandps %s,%s,", NameOfXMMRegister(regop),
1118 NameOfXMMRegister(vvvv));
1119 current += PrintRightXMMOperand(current);
1122 AppendToBuffer(
"vxorps %s,%s,", NameOfXMMRegister(regop),
1123 NameOfXMMRegister(vvvv));
1124 current += PrintRightXMMOperand(current);
1127 AppendToBuffer(
"vaddps %s,%s,", NameOfXMMRegister(regop),
1128 NameOfXMMRegister(vvvv));
1129 current += PrintRightXMMOperand(current);
1132 AppendToBuffer(
"vmulps %s,%s,", NameOfXMMRegister(regop),
1133 NameOfXMMRegister(vvvv));
1134 current += PrintRightXMMOperand(current);
1137 AppendToBuffer(
"vcvtdq2ps %s,", NameOfXMMRegister(regop));
1138 current += PrintRightXMMOperand(current);
1141 AppendToBuffer(
"vsubps %s,%s,", NameOfXMMRegister(regop),
1142 NameOfXMMRegister(vvvv));
1143 current += PrintRightXMMOperand(current);
1146 AppendToBuffer(
"vminps %s,%s,", NameOfXMMRegister(regop),
1147 NameOfXMMRegister(vvvv));
1148 current += PrintRightXMMOperand(current);
1151 AppendToBuffer(
"vdivps %s,%s,", NameOfXMMRegister(regop),
1152 NameOfXMMRegister(vvvv));
1153 current += PrintRightXMMOperand(current);
1156 AppendToBuffer(
"vmaxps %s,%s,", NameOfXMMRegister(regop),
1157 NameOfXMMRegister(vvvv));
1158 current += PrintRightXMMOperand(current);
1161 const char*
const pseudo_op[] = {
"eq",
"lt",
"le",
"unord",
1162 "neq",
"nlt",
"nle",
"ord"};
1163 AppendToBuffer(
"vcmpps %s,%s,", NameOfXMMRegister(regop),
1164 NameOfXMMRegister(vvvv));
1165 current += PrintRightXMMOperand(current);
1166 AppendToBuffer(
", (%s)", pseudo_op[*current]);
1171 AppendToBuffer(
"vshufps %s,%s,", NameOfXMMRegister(regop),
1172 NameOfXMMRegister(vvvv));
1173 current += PrintRightXMMOperand(current);
1174 AppendToBuffer(
", %d", (*current) & 3);
1178 UnimplementedInstruction();
1180 }
else if (vex_66() && vex_0f()) {
1181 int mod, regop, rm, vvvv = vex_vreg();
1182 get_modrm(*current, &mod, ®op, &rm);
1185 AppendToBuffer(
"vandpd %s,%s,", NameOfXMMRegister(regop),
1186 NameOfXMMRegister(vvvv));
1187 current += PrintRightXMMOperand(current);
1190 AppendToBuffer(
"vxorpd %s,%s,", NameOfXMMRegister(regop),
1191 NameOfXMMRegister(vvvv));
1192 current += PrintRightXMMOperand(current);
1195 AppendToBuffer(
"vaddpd %s,%s,", NameOfXMMRegister(regop),
1196 NameOfXMMRegister(vvvv));
1197 current += PrintRightXMMOperand(current);
1200 AppendToBuffer(
"vmulpd %s,%s,", NameOfXMMRegister(regop),
1201 NameOfXMMRegister(vvvv));
1202 current += PrintRightXMMOperand(current);
1205 AppendToBuffer(
"vsubpd %s,%s,", NameOfXMMRegister(regop),
1206 NameOfXMMRegister(vvvv));
1207 current += PrintRightXMMOperand(current);
1210 AppendToBuffer(
"vminpd %s,%s,", NameOfXMMRegister(regop),
1211 NameOfXMMRegister(vvvv));
1212 current += PrintRightXMMOperand(current);
1215 AppendToBuffer(
"vdivpd %s,%s,", NameOfXMMRegister(regop),
1216 NameOfXMMRegister(vvvv));
1217 current += PrintRightXMMOperand(current);
1220 AppendToBuffer(
"vmaxpd %s,%s,", NameOfXMMRegister(regop),
1221 NameOfXMMRegister(vvvv));
1222 current += PrintRightXMMOperand(current);
1225 AppendToBuffer(
"vmovd %s,", NameOfXMMRegister(regop));
1226 current += PrintRightOperand(current);
1229 AppendToBuffer(
"vpshufd %s,", NameOfXMMRegister(regop));
1230 current += PrintRightXMMOperand(current);
1231 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(current));
1235 AppendToBuffer(
"vps%sw %s,%s", sf_str[regop / 2],
1236 NameOfXMMRegister(vvvv), NameOfXMMRegister(rm));
1238 AppendToBuffer(
",%u", *current++);
1241 AppendToBuffer(
"vps%sd %s,%s", sf_str[regop / 2],
1242 NameOfXMMRegister(vvvv), NameOfXMMRegister(rm));
1244 AppendToBuffer(
",%u", *current++);
1247 AppendToBuffer(
"vmovd ");
1248 current += PrintRightOperand(current);
1249 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
1252 AppendToBuffer(
"vpinsrw %s,%s,", NameOfXMMRegister(regop),
1253 NameOfXMMRegister(vvvv));
1254 current += PrintRightOperand(current);
1255 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(current));
1258 #define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, opcode) \ 1259 case 0x##opcode: { \ 1260 AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \ 1261 NameOfXMMRegister(vvvv)); \ 1262 current += PrintRightXMMOperand(current); \ 1266 SSE2_INSTRUCTION_LIST(DECLARE_SSE_AVX_DIS_CASE)
1267 #undef DECLARE_SSE_AVX_DIS_CASE 1269 UnimplementedInstruction();
1272 UnimplementedInstruction();
1275 return static_cast<int>(current - data);
1280 int DisassemblerIA32::FPUInstruction(byte* data) {
1281 byte escape_opcode = *data;
1282 DCHECK_EQ(0xD8, escape_opcode & 0xF8);
1283 byte modrm_byte = *(data+1);
1285 if (modrm_byte >= 0xC0) {
1286 return RegisterFPUInstruction(escape_opcode, modrm_byte);
1288 return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1);
1292 int DisassemblerIA32::MemoryFPUInstruction(
int escape_opcode,
1294 byte* modrm_start) {
1295 const char* mnem =
"?";
1296 int regop = (modrm_byte >> 3) & 0x7;
1297 switch (escape_opcode) {
1298 case 0xD9:
switch (regop) {
1299 case 0: mnem =
"fld_s";
break;
1300 case 2: mnem =
"fst_s";
break;
1301 case 3: mnem =
"fstp_s";
break;
1302 case 7: mnem =
"fstcw";
break;
1303 default: UnimplementedInstruction();
1307 case 0xDB:
switch (regop) {
1308 case 0: mnem =
"fild_s";
break;
1309 case 1: mnem =
"fisttp_s";
break;
1310 case 2: mnem =
"fist_s";
break;
1311 case 3: mnem =
"fistp_s";
break;
1312 default: UnimplementedInstruction();
1316 case 0xDD:
switch (regop) {
1317 case 0: mnem =
"fld_d";
break;
1318 case 1: mnem =
"fisttp_d";
break;
1319 case 2: mnem =
"fst_d";
break;
1320 case 3: mnem =
"fstp_d";
break;
1321 default: UnimplementedInstruction();
1325 case 0xDF:
switch (regop) {
1326 case 5: mnem =
"fild_d";
break;
1327 case 7: mnem =
"fistp_d";
break;
1328 default: UnimplementedInstruction();
1332 default: UnimplementedInstruction();
1334 AppendToBuffer(
"%s ", mnem);
1335 int count = PrintRightOperand(modrm_start);
1339 int DisassemblerIA32::RegisterFPUInstruction(
int escape_opcode,
1341 bool has_register =
false;
1342 const char* mnem =
"?";
1344 switch (escape_opcode) {
1346 has_register =
true;
1347 switch (modrm_byte & 0xF8) {
1348 case 0xC0: mnem =
"fadd_i";
break;
1349 case 0xE0: mnem =
"fsub_i";
break;
1350 case 0xC8: mnem =
"fmul_i";
break;
1351 case 0xF0: mnem =
"fdiv_i";
break;
1352 default: UnimplementedInstruction();
1357 switch (modrm_byte & 0xF8) {
1360 has_register =
true;
1364 has_register =
true;
1367 switch (modrm_byte) {
1368 case 0xE0: mnem =
"fchs";
break;
1369 case 0xE1: mnem =
"fabs";
break;
1370 case 0xE4: mnem =
"ftst";
break;
1371 case 0xE8: mnem =
"fld1";
break;
1372 case 0xEB: mnem =
"fldpi";
break;
1373 case 0xED: mnem =
"fldln2";
break;
1374 case 0xEE: mnem =
"fldz";
break;
1375 case 0xF0: mnem =
"f2xm1";
break;
1376 case 0xF1: mnem =
"fyl2x";
break;
1377 case 0xF4: mnem =
"fxtract";
break;
1378 case 0xF5: mnem =
"fprem1";
break;
1379 case 0xF7: mnem =
"fincstp";
break;
1380 case 0xF8: mnem =
"fprem";
break;
1381 case 0xFC: mnem =
"frndint";
break;
1382 case 0xFD: mnem =
"fscale";
break;
1383 case 0xFE: mnem =
"fsin";
break;
1384 case 0xFF: mnem =
"fcos";
break;
1385 default: UnimplementedInstruction();
1391 if (modrm_byte == 0xE9) {
1394 UnimplementedInstruction();
1399 if ((modrm_byte & 0xF8) == 0xE8) {
1401 has_register =
true;
1402 }
else if (modrm_byte == 0xE2) {
1404 }
else if (modrm_byte == 0xE3) {
1407 UnimplementedInstruction();
1412 has_register =
true;
1413 switch (modrm_byte & 0xF8) {
1414 case 0xC0: mnem =
"fadd";
break;
1415 case 0xE8: mnem =
"fsub";
break;
1416 case 0xC8: mnem =
"fmul";
break;
1417 case 0xF8: mnem =
"fdiv";
break;
1418 default: UnimplementedInstruction();
1423 has_register =
true;
1424 switch (modrm_byte & 0xF8) {
1425 case 0xC0: mnem =
"ffree";
break;
1426 case 0xD0: mnem =
"fst";
break;
1427 case 0xD8: mnem =
"fstp";
break;
1428 default: UnimplementedInstruction();
1433 if (modrm_byte == 0xD9) {
1436 has_register =
true;
1437 switch (modrm_byte & 0xF8) {
1438 case 0xC0: mnem =
"faddp";
break;
1439 case 0xE8: mnem =
"fsubp";
break;
1440 case 0xC8: mnem =
"fmulp";
break;
1441 case 0xF8: mnem =
"fdivp";
break;
1442 default: UnimplementedInstruction();
1448 if (modrm_byte == 0xE0) {
1450 }
else if ((modrm_byte & 0xF8) == 0xE8) {
1452 has_register =
true;
1456 default: UnimplementedInstruction();
1460 AppendToBuffer(
"%s st%d", mnem, modrm_byte & 0x7);
1462 AppendToBuffer(
"%s", mnem);
1469 static const char* F0Mnem(byte f0byte) {
1516 tmp_buffer_pos_ = 0;
1519 const char* branch_hint =
nullptr;
1521 if (*data == 0x3E ) {
1522 branch_hint =
"predicted taken";
1524 }
else if (*data == 0x2E ) {
1525 branch_hint =
"predicted not taken";
1527 }
else if (*data == 0xC4 && *(data + 1) >= 0xC0) {
1529 vex_byte1_ = *(data + 1);
1530 vex_byte2_ = *(data + 2);
1532 }
else if (*data == 0xC5 && *(data + 1) >= 0xC0) {
1534 vex_byte1_ = *(data + 1);
1536 }
else if (*data == 0xF0 ) {
1537 AppendToBuffer(
"lock ");
1541 bool processed =
true;
1544 if (vex_byte0_ != 0) {
1545 data += AVXInstruction(data);
1547 const InstructionDesc& idesc = instruction_table_->Get(*data);
1548 switch (idesc.type) {
1549 case ZERO_OPERANDS_INSTR:
1550 AppendToBuffer(
"%s", idesc.mnem);
1554 case TWO_OPERANDS_INSTR:
1556 data += PrintOperands(idesc.mnem, idesc.op_order_, data);
1559 case JUMP_CONDITIONAL_SHORT_INSTR:
1560 data += JumpConditionalShort(data, branch_hint);
1563 case REGISTER_INSTR:
1564 AppendToBuffer(
"%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
1568 case MOVE_REG_INSTR: {
1570 reinterpret_cast<byte*
>(*
reinterpret_cast<int32_t*
>(data + 1));
1571 AppendToBuffer(
"mov %s,%s", NameOfCPURegister(*data & 0x07),
1572 NameOfAddress(addr));
1577 case CALL_JUMP_INSTR: {
1578 byte* addr = data + *
reinterpret_cast<int32_t*
>(data + 1) + 5;
1579 AppendToBuffer(
"%s %s", idesc.mnem, NameOfAddress(addr));
1584 case SHORT_IMMEDIATE_INSTR: {
1586 reinterpret_cast<byte*
>(*
reinterpret_cast<int32_t*
>(data + 1));
1587 AppendToBuffer(
"%s eax,%s", idesc.mnem, NameOfAddress(addr));
1592 case BYTE_IMMEDIATE_INSTR: {
1593 AppendToBuffer(
"%s al,0x%x", idesc.mnem, data[1]);
1610 AppendToBuffer(
"ret 0x%x", *reinterpret_cast<uint16_t*>(data+1));
1616 data += PrintOperands(
"imul", REG_OPER_OP_ORDER, data);
1617 AppendToBuffer(
",%d", *data);
1623 data += PrintOperands(
"imul", REG_OPER_OP_ORDER, data);
1624 AppendToBuffer(
",%d", *reinterpret_cast<int32_t*>(data));
1632 get_modrm(*data, &mod, ®op, &rm);
1634 AppendToBuffer(
"test_b ");
1635 data += PrintRightByteOperand(data);
1636 int32_t imm = *data;
1637 AppendToBuffer(
",0x%x", imm);
1640 UnimplementedInstruction();
1647 data += PrintImmediateOp(data);
1651 { byte f0byte = data[1];
1652 const char* f0mnem = F0Mnem(f0byte);
1653 if (f0byte == 0x18) {
1656 get_modrm(*data, &mod, ®op, &rm);
1657 const char* suffix[] = {
"nta",
"1",
"2",
"3"};
1658 AppendToBuffer(
"%s%s ", f0mnem, suffix[regop & 0x03]);
1659 data += PrintRightOperand(data);
1660 }
else if (f0byte == 0x1F && data[2] == 0) {
1661 AppendToBuffer(
"nop");
1663 }
else if (f0byte == 0x1F && data[2] == 0x40 && data[3] == 0) {
1664 AppendToBuffer(
"nop");
1666 }
else if (f0byte == 0x1F && data[2] == 0x44 && data[3] == 0 &&
1668 AppendToBuffer(
"nop");
1670 }
else if (f0byte == 0x1F && data[2] == 0x80 && data[3] == 0 &&
1671 data[4] == 0 && data[5] == 0 && data[6] == 0) {
1672 AppendToBuffer(
"nop");
1674 }
else if (f0byte == 0x1F && data[2] == 0x84 && data[3] == 0 &&
1675 data[4] == 0 && data[5] == 0 && data[6] == 0 &&
1677 AppendToBuffer(
"nop");
1679 }
else if (f0byte == 0x0B || f0byte == 0xA2 || f0byte == 0x31) {
1680 AppendToBuffer(
"%s", f0mnem);
1682 }
else if (f0byte == 0x28) {
1685 get_modrm(*data, &mod, ®op, &rm);
1686 AppendToBuffer(
"movaps %s,%s",
1687 NameOfXMMRegister(regop),
1688 NameOfXMMRegister(rm));
1690 }
else if (f0byte == 0x10 || f0byte == 0x11) {
1695 get_modrm(*data, &mod, ®op, &rm);
1696 AppendToBuffer(
"movups ");
1697 if (f0byte == 0x11) {
1698 data += PrintRightXMMOperand(data);
1699 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
1701 AppendToBuffer(
"%s,", NameOfXMMRegister(regop));
1702 data += PrintRightXMMOperand(data);
1704 }
else if (f0byte == 0x2E) {
1707 get_modrm(*data, &mod, ®op, &rm);
1708 AppendToBuffer(
"ucomiss %s,", NameOfXMMRegister(regop));
1709 data += PrintRightXMMOperand(data);
1710 }
else if (f0byte >= 0x52 && f0byte <= 0x5F) {
1711 const char*
const pseudo_op[] = {
1712 "rsqrtps",
"rcpps",
"andps",
"andnps",
"orps",
1713 "xorps",
"addps",
"mulps",
"cvtps2pd",
"cvtdq2ps",
1714 "subps",
"minps",
"divps",
"maxps",
1719 get_modrm(*data, &mod, ®op, &rm);
1720 AppendToBuffer(
"%s %s,", pseudo_op[f0byte - 0x52],
1721 NameOfXMMRegister(regop));
1722 data += PrintRightXMMOperand(data);
1723 }
else if (f0byte == 0x50) {
1726 get_modrm(*data, &mod, ®op, &rm);
1727 AppendToBuffer(
"movmskps %s,%s",
1728 NameOfCPURegister(regop),
1729 NameOfXMMRegister(rm));
1731 }
else if (f0byte == 0xC2) {
1734 get_modrm(*data, &mod, ®op, &rm);
1735 const char*
const pseudo_op[] = {
"eq",
"lt",
"le",
"unord",
1736 "neq",
"nlt",
"nle",
"ord"};
1737 AppendToBuffer(
"cmpps %s, ", NameOfXMMRegister(regop));
1738 data += PrintRightXMMOperand(data);
1739 AppendToBuffer(
", (%s)", pseudo_op[*data]);
1741 }
else if (f0byte== 0xC6) {
1745 get_modrm(*data, &mod, ®op, &rm);
1746 int8_t imm8 =
static_cast<int8_t
>(data[1]);
1747 AppendToBuffer(
"shufps %s,%s,%d",
1748 NameOfXMMRegister(rm),
1749 NameOfXMMRegister(regop),
1750 static_cast<int>(imm8));
1752 }
else if (f0byte >= 0xC8 && f0byte <= 0xCF) {
1755 int reg = f0byte - 0xC8;
1756 AppendToBuffer(
"bswap %s", NameOfCPURegister(reg));
1757 }
else if ((f0byte & 0xF0) == 0x80) {
1758 data += JumpConditional(data, branch_hint);
1759 }
else if (f0byte == 0xBE || f0byte == 0xBF || f0byte == 0xB6 ||
1760 f0byte == 0xB7 || f0byte == 0xAF) {
1762 data += PrintOperands(f0mnem, REG_OPER_OP_ORDER, data);
1763 }
else if ((f0byte & 0xF0) == 0x90) {
1764 data += SetCC(data);
1765 }
else if ((f0byte & 0xF0) == 0x40) {
1767 }
else if (f0byte == 0xA4 || f0byte == 0xAC) {
1770 AppendToBuffer(
"%s ", f0mnem);
1772 get_modrm(*data, &mod, ®op, &rm);
1773 int8_t imm8 =
static_cast<int8_t
>(data[1]);
1775 AppendToBuffer(
"%s,%s,%d", NameOfCPURegister(rm),
1776 NameOfCPURegister(regop), static_cast<int>(imm8));
1777 }
else if (f0byte == 0xAB || f0byte == 0xA5 || f0byte == 0xAD) {
1780 AppendToBuffer(
"%s ", f0mnem);
1782 get_modrm(*data, &mod, ®op, &rm);
1783 data += PrintRightOperand(data);
1784 if (f0byte == 0xAB) {
1785 AppendToBuffer(
",%s", NameOfCPURegister(regop));
1787 AppendToBuffer(
",%s,cl", NameOfCPURegister(regop));
1789 }
else if (f0byte == 0xB0) {
1792 AppendToBuffer(
"%s ", f0mnem);
1794 get_modrm(*data, &mod, ®op, &rm);
1795 data += PrintRightOperand(data);
1796 AppendToBuffer(
",%s", NameOfByteCPURegister(regop));
1797 }
else if (f0byte == 0xB1) {
1800 data += PrintOperands(f0mnem, OPER_REG_OP_ORDER, data);
1801 }
else if (f0byte == 0xBC) {
1804 get_modrm(*data, &mod, ®op, &rm);
1805 AppendToBuffer(
"%s %s,", f0mnem, NameOfCPURegister(regop));
1806 data += PrintRightOperand(data);
1807 }
else if (f0byte == 0xBD) {
1810 get_modrm(*data, &mod, ®op, &rm);
1811 AppendToBuffer(
"%s %s,", f0mnem, NameOfCPURegister(regop));
1812 data += PrintRightOperand(data);
1813 }
else if (f0byte == 0xC7) {
1816 AppendToBuffer(
"%s ", f0mnem);
1818 get_modrm(*data, &mod, ®op, &rm);
1819 data += PrintRightOperand(data);
1820 }
else if (f0byte == 0xAE && (data[2] & 0xF8) == 0xE8) {
1821 AppendToBuffer(
"lfence");
1824 UnimplementedInstruction();
1832 get_modrm(*data, &mod, ®op, &rm);
1834 AppendToBuffer(
"pop ");
1835 data += PrintRightOperand(data);
1843 get_modrm(*data, &mod, ®op, &rm);
1844 const char* mnem =
nullptr;
1846 case esi: mnem =
"push";
break;
1847 case eax: mnem =
"inc";
break;
1848 case ecx: mnem =
"dec";
break;
1849 case edx: mnem =
"call";
break;
1850 case esp: mnem =
"jmp";
break;
1851 default: mnem =
"???";
1853 AppendToBuffer(
"%s ", mnem);
1854 data += PrintRightOperand(data);
1860 {
bool is_byte = *data == 0xC6;
1863 AppendToBuffer(
"%s ",
"mov_b");
1864 data += PrintRightByteOperand(data);
1865 int32_t imm = *data;
1866 AppendToBuffer(
",0x%x", imm);
1869 AppendToBuffer(
"%s ",
"mov");
1870 data += PrintRightOperand(data);
1871 int32_t imm = *
reinterpret_cast<int32_t*
>(data);
1872 AppendToBuffer(
",0x%x", imm);
1881 get_modrm(*data, &mod, ®op, &rm);
1882 const char* mnem =
nullptr;
1884 case 5: mnem =
"subb";
break;
1885 case 7: mnem =
"cmpb";
break;
1886 default: UnimplementedInstruction();
1888 AppendToBuffer(
"%s ", mnem);
1889 data += PrintRightByteOperand(data);
1890 int32_t imm = *data;
1891 AppendToBuffer(
",0x%x", imm);
1898 {
bool is_byte = *data == 0x88;
1901 get_modrm(*data, &mod, ®op, &rm);
1903 AppendToBuffer(
"%s ",
"mov_b");
1904 data += PrintRightByteOperand(data);
1905 AppendToBuffer(
",%s", NameOfByteCPURegister(regop));
1907 AppendToBuffer(
"%s ",
"mov");
1908 data += PrintRightOperand(data);
1909 AppendToBuffer(
",%s", NameOfCPURegister(regop));
1915 while (*data == 0x66) data++;
1916 if (*data == 0xF && data[1] == 0x1F) {
1917 AppendToBuffer(
"nop");
1918 }
else if (*data == 0x39) {
1920 data += PrintOperands(
"cmpw", OPER_REG_OP_ORDER, data);
1921 }
else if (*data == 0x3B) {
1923 data += PrintOperands(
"cmpw", REG_OPER_OP_ORDER, data);
1924 }
else if (*data == 0x81) {
1926 AppendToBuffer(
"cmpw ");
1927 data += PrintRightOperand(data);
1928 int imm = *
reinterpret_cast<int16_t*
>(data);
1929 AppendToBuffer(
",0x%x", imm);
1931 }
else if (*data == 0x87) {
1934 get_modrm(*data, &mod, ®op, &rm);
1935 AppendToBuffer(
"xchg_w %s,", NameOfCPURegister(regop));
1936 data += PrintRightOperand(data);
1937 }
else if (*data == 0x89) {
1940 get_modrm(*data, &mod, ®op, &rm);
1941 AppendToBuffer(
"mov_w ");
1942 data += PrintRightOperand(data);
1943 AppendToBuffer(
",%s", NameOfCPURegister(regop));
1944 }
else if (*data == 0x8B) {
1946 data += PrintOperands(
"mov_w", REG_OPER_OP_ORDER, data);
1947 }
else if (*data == 0x90) {
1948 AppendToBuffer(
"nop");
1949 }
else if (*data == 0xC7) {
1951 AppendToBuffer(
"%s ",
"mov_w");
1952 data += PrintRightOperand(data);
1953 int imm = *
reinterpret_cast<int16_t*
>(data);
1954 AppendToBuffer(
",0x%x", imm);
1956 }
else if (*data == 0xF7) {
1958 AppendToBuffer(
"%s ",
"test_w");
1959 data += PrintRightOperand(data);
1960 int imm = *
reinterpret_cast<int16_t*
>(data);
1961 AppendToBuffer(
",0x%x", imm);
1963 }
else if (*data == 0x0F) {
1965 if (*data == 0x38) {
1970 get_modrm(*data, &mod, ®op, &rm);
1972 #define SSE34_DIS_CASE(instruction, notUsed1, notUsed2, notUsed3, opcode) \ 1973 case 0x##opcode: { \ 1974 AppendToBuffer(#instruction " %s,", NameOfXMMRegister(regop)); \ 1975 data += PrintRightXMMOperand(data); \ 1979 SSSE3_INSTRUCTION_LIST(SSE34_DIS_CASE)
1980 SSE4_INSTRUCTION_LIST(SSE34_DIS_CASE)
1981 SSE4_RM_INSTRUCTION_LIST(SSE34_DIS_CASE)
1982 #undef SSE34_DIS_CASE 1984 UnimplementedInstruction();
1986 }
else if (*data == 0x3A) {
1988 if (*data == 0x0A) {
1991 get_modrm(*data, &mod, ®op, &rm);
1992 int8_t imm8 =
static_cast<int8_t
>(data[1]);
1993 AppendToBuffer(
"roundss %s,%s,%d", NameOfXMMRegister(regop),
1994 NameOfXMMRegister(rm), static_cast<int>(imm8));
1996 }
else if (*data == 0x0B) {
1999 get_modrm(*data, &mod, ®op, &rm);
2000 int8_t imm8 =
static_cast<int8_t
>(data[1]);
2001 AppendToBuffer(
"roundsd %s,%s,%d",
2002 NameOfXMMRegister(regop),
2003 NameOfXMMRegister(rm),
2004 static_cast<int>(imm8));
2006 }
else if (*data == 0x0E) {
2009 get_modrm(*data, &mod, ®op, &rm);
2010 AppendToBuffer(
"pblendw %s,", NameOfXMMRegister(regop));
2011 data += PrintRightXMMOperand(data);
2012 AppendToBuffer(
",%d", *reinterpret_cast<uint8_t*>(data));
2014 }
else if (*data == 0x0F) {
2017 get_modrm(*data, &mod, ®op, &rm);
2018 AppendToBuffer(
"palignr %s,", NameOfXMMRegister(regop));
2019 data += PrintRightXMMOperand(data);
2020 AppendToBuffer(
",%d", *reinterpret_cast<uint8_t*>(data));
2022 }
else if (*data == 0x14) {
2025 get_modrm(*data, &mod, ®op, &rm);
2026 AppendToBuffer(
"pextrb ");
2027 data += PrintRightOperand(data);
2028 AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop),
2029 *reinterpret_cast<int8_t*>(data));
2031 }
else if (*data == 0x15) {
2034 get_modrm(*data, &mod, ®op, &rm);
2035 AppendToBuffer(
"pextrw ");
2036 data += PrintRightOperand(data);
2037 AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop),
2038 *reinterpret_cast<int8_t*>(data));
2040 }
else if (*data == 0x16) {
2043 get_modrm(*data, &mod, ®op, &rm);
2044 AppendToBuffer(
"pextrd ");
2045 data += PrintRightOperand(data);
2046 AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop),
2047 *reinterpret_cast<int8_t*>(data));
2049 }
else if (*data == 0x17) {
2052 get_modrm(*data, &mod, ®op, &rm);
2053 int8_t imm8 =
static_cast<int8_t
>(data[1]);
2054 AppendToBuffer(
"extractps %s,%s,%d",
2055 NameOfCPURegister(rm),
2056 NameOfXMMRegister(regop),
2057 static_cast<int>(imm8));
2059 }
else if (*data == 0x20) {
2062 get_modrm(*data, &mod, ®op, &rm);
2063 AppendToBuffer(
"pinsrb %s,", NameOfXMMRegister(regop));
2064 data += PrintRightOperand(data);
2065 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(data));
2067 }
else if (*data == 0x21) {
2070 get_modrm(*data, &mod, ®op, &rm);
2071 AppendToBuffer(
"insertps %s,", NameOfXMMRegister(regop));
2072 data += PrintRightXMMOperand(data);
2073 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(data));
2075 }
else if (*data == 0x22) {
2078 get_modrm(*data, &mod, ®op, &rm);
2079 AppendToBuffer(
"pinsrd %s,", NameOfXMMRegister(regop));
2080 data += PrintRightOperand(data);
2081 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(data));
2084 UnimplementedInstruction();
2086 }
else if (*data == 0x2E || *data == 0x2F) {
2087 const char* mnem = (*data == 0x2E) ?
"ucomisd" :
"comisd";
2090 get_modrm(*data, &mod, ®op, &rm);
2092 AppendToBuffer(
"%s %s,%s", mnem,
2093 NameOfXMMRegister(regop),
2094 NameOfXMMRegister(rm));
2097 AppendToBuffer(
"%s %s,", mnem, NameOfXMMRegister(regop));
2098 data += PrintRightOperand(data);
2100 }
else if (*data == 0x50) {
2103 get_modrm(*data, &mod, ®op, &rm);
2104 AppendToBuffer(
"movmskpd %s,%s",
2105 NameOfCPURegister(regop),
2106 NameOfXMMRegister(rm));
2108 }
else if (*data == 0x54) {
2111 get_modrm(*data, &mod, ®op, &rm);
2112 AppendToBuffer(
"andpd %s,%s",
2113 NameOfXMMRegister(regop),
2114 NameOfXMMRegister(rm));
2116 }
else if (*data == 0x56) {
2119 get_modrm(*data, &mod, ®op, &rm);
2120 AppendToBuffer(
"orpd %s,%s",
2121 NameOfXMMRegister(regop),
2122 NameOfXMMRegister(rm));
2124 }
else if (*data == 0x57) {
2127 get_modrm(*data, &mod, ®op, &rm);
2128 AppendToBuffer(
"xorpd %s,%s",
2129 NameOfXMMRegister(regop),
2130 NameOfXMMRegister(rm));
2132 }
else if (*data == 0x6E) {
2135 get_modrm(*data, &mod, ®op, &rm);
2136 AppendToBuffer(
"movd %s,", NameOfXMMRegister(regop));
2137 data += PrintRightOperand(data);
2138 }
else if (*data == 0x6F) {
2141 get_modrm(*data, &mod, ®op, &rm);
2142 AppendToBuffer(
"movdqa %s,", NameOfXMMRegister(regop));
2143 data += PrintRightXMMOperand(data);
2144 }
else if (*data == 0x70) {
2147 get_modrm(*data, &mod, ®op, &rm);
2148 AppendToBuffer(
"pshufd %s,", NameOfXMMRegister(regop));
2149 data += PrintRightXMMOperand(data);
2150 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(data));
2152 }
else if (*data == 0x90) {
2154 AppendToBuffer(
"nop");
2155 }
else if (*data == 0xF3) {
2158 get_modrm(*data, &mod, ®op, &rm);
2159 AppendToBuffer(
"psllq %s,%s",
2160 NameOfXMMRegister(regop),
2161 NameOfXMMRegister(rm));
2163 }
else if (*data == 0x71) {
2166 get_modrm(*data, &mod, ®op, &rm);
2167 int8_t imm8 =
static_cast<int8_t
>(data[1]);
2168 AppendToBuffer(
"ps%sw %s,%d", sf_str[regop / 2],
2169 NameOfXMMRegister(rm), static_cast<int>(imm8));
2171 }
else if (*data == 0x72) {
2174 get_modrm(*data, &mod, ®op, &rm);
2175 int8_t imm8 =
static_cast<int8_t
>(data[1]);
2176 AppendToBuffer(
"ps%sd %s,%d", sf_str[regop / 2],
2177 NameOfXMMRegister(rm), static_cast<int>(imm8));
2179 }
else if (*data == 0x73) {
2182 get_modrm(*data, &mod, ®op, &rm);
2183 int8_t imm8 =
static_cast<int8_t
>(data[1]);
2184 DCHECK(regop == esi || regop == edx);
2185 AppendToBuffer(
"ps%sq %s,%d", sf_str[regop / 2],
2186 NameOfXMMRegister(rm), static_cast<int>(imm8));
2188 }
else if (*data == 0xD3) {
2191 get_modrm(*data, &mod, ®op, &rm);
2192 AppendToBuffer(
"psrlq %s,%s",
2193 NameOfXMMRegister(regop),
2194 NameOfXMMRegister(rm));
2196 }
else if (*data == 0x7F) {
2197 AppendToBuffer(
"movdqa ");
2200 get_modrm(*data, &mod, ®op, &rm);
2201 data += PrintRightXMMOperand(data);
2202 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
2203 }
else if (*data == 0x7E) {
2206 get_modrm(*data, &mod, ®op, &rm);
2207 AppendToBuffer(
"movd ");
2208 data += PrintRightOperand(data);
2209 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
2210 }
else if (*data == 0xC4) {
2213 get_modrm(*data, &mod, ®op, &rm);
2214 AppendToBuffer(
"pinsrw %s,", NameOfXMMRegister(regop));
2215 data += PrintRightOperand(data);
2216 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(data));
2218 }
else if (*data == 0xE7) {
2221 get_modrm(*data, &mod, ®op, &rm);
2224 UnimplementedInstruction();
2226 UnimplementedInstruction();
2228 }
else if (*data == 0xB1) {
2230 data += PrintOperands(
"cmpxchg_w", OPER_REG_OP_ORDER, data);
2235 get_modrm(*data, &mod, ®op, &rm);
2237 #define SSE2_DIS_CASE(instruction, notUsed1, notUsed2, opcode) \ 2238 case 0x##opcode: { \ 2239 AppendToBuffer(#instruction " %s,", NameOfXMMRegister(regop)); \ 2240 data += PrintRightXMMOperand(data); \ 2244 SSE2_INSTRUCTION_LIST(SSE2_DIS_CASE)
2245 #undef SSE2_DIS_CASE 2247 UnimplementedInstruction();
2251 UnimplementedInstruction();
2258 get_modrm(*data, &mod, ®op, &rm);
2260 AppendToBuffer(
"dec_b ");
2261 data += PrintRightOperand(data);
2263 UnimplementedInstruction();
2269 AppendToBuffer(
"push 0x%x", *reinterpret_cast<int32_t*>(data+1));
2274 AppendToBuffer(
"push 0x%x", *reinterpret_cast<int8_t*>(data + 1));
2279 AppendToBuffer(
"test al,0x%x", *reinterpret_cast<uint8_t*>(data+1));
2284 AppendToBuffer(
"test eax,0x%x", *reinterpret_cast<int32_t*>(data+1));
2291 data += D1D3C1Instruction(data);
2302 data += FPUInstruction(data);
2306 data += JumpShort(data);
2310 if (*(data+1) == 0x0F) {
2311 byte b2 = *(data+2);
2313 AppendToBuffer(
"movsd ");
2316 get_modrm(*data, &mod, ®op, &rm);
2317 data += PrintRightXMMOperand(data);
2318 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
2319 }
else if (b2 == 0x10) {
2322 get_modrm(*data, &mod, ®op, &rm);
2323 AppendToBuffer(
"movsd %s,", NameOfXMMRegister(regop));
2324 data += PrintRightXMMOperand(data);
2325 }
else if (b2 == 0x5A) {
2328 get_modrm(*data, &mod, ®op, &rm);
2329 AppendToBuffer(
"cvtsd2ss %s,", NameOfXMMRegister(regop));
2330 data += PrintRightXMMOperand(data);
2331 }
else if (b2 == 0x70) {
2334 get_modrm(*data, &mod, ®op, &rm);
2335 AppendToBuffer(
"pshuflw %s,", NameOfXMMRegister(regop));
2336 data += PrintRightXMMOperand(data);
2337 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(data));
2340 const char* mnem =
"?";
2378 get_modrm(*data, &mod, ®op, &rm);
2380 AppendToBuffer(
"%s %s,", mnem, NameOfXMMRegister(regop));
2381 data += PrintRightOperand(data);
2382 }
else if (b2 == 0x2C || b2 == 0x2D) {
2383 AppendToBuffer(
"%s %s,", mnem, NameOfCPURegister(regop));
2384 data += PrintRightXMMOperand(data);
2385 }
else if (b2 == 0xC2) {
2387 const char*
const pseudo_op[] = {
2397 AppendToBuffer(
"%s %s,%s",
2399 NameOfXMMRegister(regop),
2400 NameOfXMMRegister(rm));
2403 AppendToBuffer(
"%s %s,", mnem, NameOfXMMRegister(regop));
2404 data += PrintRightXMMOperand(data);
2408 UnimplementedInstruction();
2413 if (*(data+1) == 0x0F) {
2414 byte b2 = *(data+2);
2416 AppendToBuffer(
"movss ");
2419 get_modrm(*data, &mod, ®op, &rm);
2420 data += PrintRightXMMOperand(data);
2421 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
2422 }
else if (b2 == 0x10) {
2425 get_modrm(*data, &mod, ®op, &rm);
2426 AppendToBuffer(
"movss %s,", NameOfXMMRegister(regop));
2427 data += PrintRightXMMOperand(data);
2428 }
else if (b2 == 0x5A) {
2431 get_modrm(*data, &mod, ®op, &rm);
2432 AppendToBuffer(
"cvtss2sd %s,", NameOfXMMRegister(regop));
2433 data += PrintRightXMMOperand(data);
2434 }
else if (b2 == 0x6F) {
2437 get_modrm(*data, &mod, ®op, &rm);
2438 AppendToBuffer(
"movdqu %s,", NameOfXMMRegister(regop));
2439 data += PrintRightXMMOperand(data);
2440 }
else if (b2 == 0x70) {
2443 get_modrm(*data, &mod, ®op, &rm);
2444 AppendToBuffer(
"pshufhw %s,", NameOfXMMRegister(regop));
2445 data += PrintRightXMMOperand(data);
2446 AppendToBuffer(
",%d", *reinterpret_cast<int8_t*>(data));
2448 }
else if (b2 == 0x7F) {
2449 AppendToBuffer(
"movdqu ");
2452 get_modrm(*data, &mod, ®op, &rm);
2453 data += PrintRightXMMOperand(data);
2454 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
2455 }
else if (b2 == 0xB8) {
2458 get_modrm(*data, &mod, ®op, &rm);
2459 AppendToBuffer(
"popcnt %s,", NameOfCPURegister(regop));
2460 data += PrintRightOperand(data);
2461 }
else if (b2 == 0xBC) {
2464 get_modrm(*data, &mod, ®op, &rm);
2465 AppendToBuffer(
"tzcnt %s,", NameOfCPURegister(regop));
2466 data += PrintRightOperand(data);
2467 }
else if (b2 == 0xBD) {
2470 get_modrm(*data, &mod, ®op, &rm);
2471 AppendToBuffer(
"lzcnt %s,", NameOfCPURegister(regop));
2472 data += PrintRightOperand(data);
2474 const char* mnem =
"?";
2515 get_modrm(*data, &mod, ®op, &rm);
2517 AppendToBuffer(
"%s %s,", mnem, NameOfXMMRegister(regop));
2518 data += PrintRightOperand(data);
2519 }
else if (b2 == 0x2C || b2 == 0x2D) {
2520 AppendToBuffer(
"%s %s,", mnem, NameOfCPURegister(regop));
2521 data += PrintRightXMMOperand(data);
2522 }
else if (b2 == 0xC2) {
2524 const char*
const pseudo_op[] = {
2525 "cmpeqss",
"cmpltss",
"cmpless",
"cmpunordss",
2526 "cmpneqss",
"cmpnltss",
"cmpnless",
"cmpordss"};
2527 AppendToBuffer(
"%s %s,%s", pseudo_op[data[1]],
2528 NameOfXMMRegister(regop), NameOfXMMRegister(rm));
2531 AppendToBuffer(
"%s %s,", mnem, NameOfXMMRegister(regop));
2532 data += PrintRightXMMOperand(data);
2535 }
else if (*(data+1) == 0xA5) {
2537 AppendToBuffer(
"rep_movs");
2538 }
else if (*(data+1) == 0xAB) {
2540 AppendToBuffer(
"rep_stos");
2541 }
else if (*(data + 1) == 0x90) {
2543 AppendToBuffer(
"pause");
2545 UnimplementedInstruction();
2550 data += F7Instruction(data);
2554 UnimplementedInstruction();
2558 if (tmp_buffer_pos_ <
sizeof tmp_buffer_) {
2559 tmp_buffer_[tmp_buffer_pos_] =
'\0';
2562 int instr_len = data - instr;
2563 if (instr_len == 0) {
2564 printf(
"%02x", *data);
2566 DCHECK_GT(instr_len, 0);
2570 for (byte* bp = instr; bp < data; bp++) {
2571 outp += v8::internal::SNPrintF(out_buffer + outp,
2575 for (
int i = 6 - instr_len;
i >= 0;
i--) {
2576 outp += v8::internal::SNPrintF(out_buffer + outp,
" ");
2579 outp += v8::internal::SNPrintF(out_buffer + outp,
2581 tmp_buffer_.start());
2589 static const char*
const cpu_regs[8] = {
2590 "eax",
"ecx",
"edx",
"ebx",
"esp",
"ebp",
"esi",
"edi" 2594 static const char*
const byte_cpu_regs[8] = {
2595 "al",
"cl",
"dl",
"bl",
"ah",
"ch",
"dh",
"bh" 2599 static const char*
const xmm_regs[8] = {
2600 "xmm0",
"xmm1",
"xmm2",
"xmm3",
"xmm4",
"xmm5",
"xmm6",
"xmm7" 2604 const char* NameConverter::NameOfAddress(byte* addr)
const {
2605 v8::internal::SNPrintF(tmp_buffer_,
"%p", static_cast<void*>(addr));
2606 return tmp_buffer_.start();
2610 const char* NameConverter::NameOfConstant(byte* addr)
const {
2611 return NameOfAddress(addr);
2615 const char* NameConverter::NameOfCPURegister(
int reg)
const {
2616 if (0 <= reg && reg < 8)
return cpu_regs[reg];
2621 const char* NameConverter::NameOfByteCPURegister(
int reg)
const {
2622 if (0 <= reg && reg < 8)
return byte_cpu_regs[reg];
2627 const char* NameConverter::NameOfXMMRegister(
int reg)
const {
2628 if (0 <= reg && reg < 8)
return xmm_regs[reg];
2633 const char* NameConverter::NameInCode(byte* addr)
const {
2642 byte* instruction) {
2643 DisassemblerIA32 d(converter_, unimplemented_opcode_action());
2644 return d.InstructionDecode(buffer, instruction);
2648 int Disassembler::ConstantPoolSizeAt(byte* instruction) {
return -1; }
2651 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end,
2652 UnimplementedOpcodeAction unimplemented_action) {
2653 NameConverter converter;
2654 Disassembler d(converter, unimplemented_action);
2655 for (byte* pc = begin; pc < end;) {
2659 pc += d.InstructionDecode(buffer, pc);
2660 fprintf(f,
"%p", static_cast<void*>(prev_pc));
2663 for (byte* bp = prev_pc; bp < pc; bp++) {
2664 fprintf(f,
"%02x", *bp);
2666 for (
int i = 6 - (pc - prev_pc);
i >= 0;
i--) {
2669 fprintf(f,
" %s\n", buffer.start());
2676 #endif // V8_TARGET_ARCH_IA32