19enum OperandOrder { UNSET_OP_ORDER = 0, REG_OPER_OP_ORDER, OPER_REG_OP_ORDER };
27 OperandOrder op_order_;
30static const ByteMnemonic two_operands_instr[] = {
31 {0x01,
"add", OPER_REG_OP_ORDER}, {0x03,
"add", REG_OPER_OP_ORDER},
32 {0x09,
"or", OPER_REG_OP_ORDER}, {0x0B,
"or", REG_OPER_OP_ORDER},
33 {0x13,
"adc", REG_OPER_OP_ORDER}, {0x1B,
"sbb", REG_OPER_OP_ORDER},
34 {0x21,
"and", OPER_REG_OP_ORDER}, {0x23,
"and", REG_OPER_OP_ORDER},
35 {0x29,
"sub", OPER_REG_OP_ORDER}, {0x2A,
"subb", REG_OPER_OP_ORDER},
36 {0x2B,
"sub", REG_OPER_OP_ORDER}, {0x31,
"xor", OPER_REG_OP_ORDER},
37 {0x33,
"xor", REG_OPER_OP_ORDER}, {0x38,
"cmpb", OPER_REG_OP_ORDER},
38 {0x39,
"cmp", OPER_REG_OP_ORDER}, {0x3A,
"cmpb", REG_OPER_OP_ORDER},
39 {0x3B,
"cmp", REG_OPER_OP_ORDER}, {0x84,
"test_b", REG_OPER_OP_ORDER},
40 {0x85,
"test", REG_OPER_OP_ORDER}, {0x86,
"xchg_b", REG_OPER_OP_ORDER},
41 {0x87,
"xchg", REG_OPER_OP_ORDER}, {0x8A,
"mov_b", REG_OPER_OP_ORDER},
42 {0x8B,
"mov", REG_OPER_OP_ORDER}, {0x8D,
"lea", REG_OPER_OP_ORDER},
43 {-1,
"", UNSET_OP_ORDER}};
45static const ByteMnemonic zero_operands_instr[] = {
46 {0xC3,
"ret", UNSET_OP_ORDER}, {0xC9,
"leave", UNSET_OP_ORDER},
47 {0x90,
"nop", UNSET_OP_ORDER}, {0xF4,
"hlt", UNSET_OP_ORDER},
48 {0xCC,
"int3", UNSET_OP_ORDER}, {0x60,
"pushad", UNSET_OP_ORDER},
49 {0x61,
"popad", UNSET_OP_ORDER}, {0x9C,
"pushfd", UNSET_OP_ORDER},
50 {0x9D,
"popfd", UNSET_OP_ORDER}, {0x9E,
"sahf", UNSET_OP_ORDER},
51 {0x99,
"cdq", UNSET_OP_ORDER}, {0x9B,
"fwait", UNSET_OP_ORDER},
52 {0xFC,
"cld", UNSET_OP_ORDER}, {0xAB,
"stos", UNSET_OP_ORDER},
53 {-1,
"", UNSET_OP_ORDER}};
55static const ByteMnemonic call_jump_instr[] = {{0xE8,
"call", UNSET_OP_ORDER},
56 {0xE9,
"jmp", UNSET_OP_ORDER},
57 {-1,
"", UNSET_OP_ORDER}};
59static const ByteMnemonic short_immediate_instr[] = {
60 {0x05,
"add", UNSET_OP_ORDER}, {0x0D,
"or", UNSET_OP_ORDER},
61 {0x15,
"adc", UNSET_OP_ORDER}, {0x25,
"and", UNSET_OP_ORDER},
62 {0x2D,
"sub", UNSET_OP_ORDER}, {0x35,
"xor", UNSET_OP_ORDER},
63 {0x3D,
"cmp", UNSET_OP_ORDER}, {-1,
"", UNSET_OP_ORDER}};
69static ByteMnemonic byte_immediate_instr[] = {{0x0C,
"or", UNSET_OP_ORDER},
70 {0x24,
"and", UNSET_OP_ORDER},
71 {0x34,
"xor", UNSET_OP_ORDER},
72 {0x3C,
"cmp", UNSET_OP_ORDER},
73 {-1,
"", UNSET_OP_ORDER}};
75static const char*
const jump_conditional_mnem[] = {
76 "jo",
"jno",
"jc",
"jnc",
77 "jz",
"jnz",
"jna",
"ja",
78 "js",
"jns",
"jpe",
"jpo",
79 "jl",
"jnl",
"jng",
"jg"};
81static const char*
const set_conditional_mnem[] = {
82 "seto",
"setno",
"setc",
"setnc",
83 "setz",
"setnz",
"setna",
"seta",
84 "sets",
"setns",
"setpe",
"setpo",
85 "setl",
"setnl",
"setng",
"setg"};
87static const char*
const conditional_move_mnem[] = {
88 "cmovo",
"cmovno",
"cmovc",
"cmovnc",
89 "cmovz",
"cmovnz",
"cmovna",
"cmova",
90 "cmovs",
"cmovns",
"cmovpe",
"cmovpo",
91 "cmovl",
"cmovnl",
"cmovng",
"cmovg"};
93static const char*
const cmp_pseudo_op[16] = {
94 "eq",
"lt",
"le",
"unord",
"neq",
"nlt",
"nle",
"ord",
95 "eq_uq",
"nge",
"ngt",
"false",
"neq_oq",
"ge",
"gt",
"true"};
101 JUMP_CONDITIONAL_SHORT_INSTR,
105 SHORT_IMMEDIATE_INSTR,
109struct InstructionDesc {
111 InstructionType
type;
112 OperandOrder op_order_;
115class InstructionTable {
118 const InstructionDesc&
Get(uint8_t
x)
const {
return instructions_[
x]; }
119 static InstructionTable* get_instance() {
120 static InstructionTable table;
125 InstructionDesc instructions_[256];
128 void CopyTable(
const ByteMnemonic bm[], InstructionType type);
129 void SetTableRange(InstructionType type, uint8_t
start, uint8_t
end,
131 void AddJumpConditionalShort();
134InstructionTable::InstructionTable() {
139void InstructionTable::Clear() {
140 for (
int i = 0;
i < 256;
i++) {
141 instructions_[
i].mnem =
"";
142 instructions_[
i].type = NO_INSTR;
143 instructions_[
i].op_order_ = UNSET_OP_ORDER;
147void InstructionTable::Init() {
148 CopyTable(two_operands_instr, TWO_OPERANDS_INSTR);
149 CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR);
150 CopyTable(call_jump_instr, CALL_JUMP_INSTR);
151 CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
152 CopyTable(byte_immediate_instr, BYTE_IMMEDIATE_INSTR);
153 AddJumpConditionalShort();
154 SetTableRange(REGISTER_INSTR, 0x40, 0x47,
"inc");
155 SetTableRange(REGISTER_INSTR, 0x48, 0x4F,
"dec");
156 SetTableRange(REGISTER_INSTR, 0x50, 0x57,
"push");
157 SetTableRange(REGISTER_INSTR, 0x58, 0x5F,
"pop");
158 SetTableRange(REGISTER_INSTR, 0x91, 0x97,
"xchg eax,");
159 SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF,
"mov");
162void InstructionTable::CopyTable(
const ByteMnemonic bm[],
163 InstructionType type) {
164 for (
int i = 0; bm[
i].b >= 0;
i++) {
165 InstructionDesc*
id = &instructions_[bm[
i].b];
166 id->mnem = bm[
i].mnem;
167 id->op_order_ = bm[
i].op_order_;
173void InstructionTable::SetTableRange(InstructionType type, uint8_t
start,
174 uint8_t
end,
const char* mnem) {
175 for (uint8_t b =
start; b <=
end; b++) {
176 InstructionDesc*
id = &instructions_[b];
183void InstructionTable::AddJumpConditionalShort() {
184 for (uint8_t b = 0x70; b <= 0x7F; b++) {
185 InstructionDesc*
id = &instructions_[b];
187 id->mnem = jump_conditional_mnem[b & 0x0F];
188 id->type = JUMP_CONDITIONAL_SHORT_INSTR;
193int8_t Imm8(
const uint8_t* data) {
194 return *
reinterpret_cast<const int8_t*
>(
data);
196uint8_t Imm8_U(
const uint8_t* data) {
197 return *
reinterpret_cast<const uint8_t*
>(
data);
199int16_t Imm16(
const uint8_t* data) {
202uint16_t Imm16_U(
const uint8_t* data) {
205int32_t Imm32(
const uint8_t* data) {
211class DisassemblerIA32 {
214 const NameConverter& converter,
215 Disassembler::UnimplementedOpcodeAction unimplemented_opcode_action)
216 : converter_(converter),
220 instruction_table_(InstructionTable::get_instance()),
222 unimplemented_opcode_action_(unimplemented_opcode_action) {
223 tmp_buffer_[0] =
'\0';
226 virtual ~DisassemblerIA32() {}
233 const NameConverter& converter_;
237 InstructionTable* instruction_table_;
239 unsigned int tmp_buffer_pos_;
240 Disassembler::UnimplementedOpcodeAction unimplemented_opcode_action_;
253 enum ShiftOpcodeExtension {
264 DCHECK(vex_byte0_ == 0xC4 || vex_byte0_ == 0xC5);
265 uint8_t checked = vex_byte0_ == 0xC4 ? vex_byte2_ : vex_byte1_;
266 return (checked & 4) == 0;
270 DCHECK(vex_byte0_ == 0xC4 || vex_byte0_ == 0xC5);
271 uint8_t checked = vex_byte0_ == 0xC4 ? vex_byte2_ : vex_byte1_;
272 return (checked & 3) == 0;
276 DCHECK(vex_byte0_ == 0xC4 || vex_byte0_ == 0xC5);
277 uint8_t checked = vex_byte0_ == 0xC4 ? vex_byte2_ : vex_byte1_;
278 return (checked & 3) == 1;
282 DCHECK(vex_byte0_ == 0xC4 || vex_byte0_ == 0xC5);
283 uint8_t checked = vex_byte0_ == 0xC4 ? vex_byte2_ : vex_byte1_;
284 return (checked & 3) == 2;
288 DCHECK(vex_byte0_ == 0xC4 || vex_byte0_ == 0xC5);
289 uint8_t checked = vex_byte0_ == 0xC4 ? vex_byte2_ : vex_byte1_;
290 return (checked & 3) == 3;
294 if (vex_byte0_ == 0xC5)
return false;
295 return (vex_byte2_ & 0x80) != 0;
299 if (vex_byte0_ == 0xC5)
return true;
300 return (vex_byte1_ & 3) == 1;
304 if (vex_byte0_ == 0xC5)
return false;
305 return (vex_byte1_ & 3) == 2;
309 if (vex_byte0_ == 0xC5)
return false;
310 return (vex_byte1_ & 3) == 3;
314 DCHECK(vex_byte0_ == 0xC4 || vex_byte0_ == 0xC5);
315 uint8_t checked = vex_byte0_ == 0xC4 ? vex_byte2_ : vex_byte1_;
316 return ~(checked >> 3) & 0xF;
319 char float_size_code() {
return "sd"[vex_w()]; }
321 const char* NameOfCPURegister(
int reg)
const {
322 return converter_.NameOfCPURegister(
reg);
325 const char* NameOfByteCPURegister(
int reg)
const {
326 return converter_.NameOfByteCPURegister(
reg);
329 const char* NameOfXMMRegister(
int reg)
const {
330 return converter_.NameOfXMMRegister(
reg);
333 const char* NameOfAddress(uint8_t* addr)
const {
334 return converter_.NameOfAddress(addr);
338 static void get_modrm(uint8_t data,
int* mod,
int* regop,
int* rm) {
339 *mod = (data >> 6) & 3;
340 *regop = (data & 0x38) >> 3;
344 static void get_sib(uint8_t data,
int*
scale,
int* index,
int*
base) {
345 *
scale = (data >> 6) & 3;
346 *index = (data >> 3) & 7;
350 using RegisterNameMapping =
const char* (DisassemblerIA32::*)(
int reg)
const;
352 int PrintRightOperandHelper(uint8_t* modrmp,
353 RegisterNameMapping register_name);
354 int PrintRightOperand(uint8_t* modrmp);
355 int PrintRightByteOperand(uint8_t* modrmp);
356 int PrintRightXMMOperand(uint8_t* modrmp);
357 int PrintOperands(
const char* mnem, OperandOrder op_order, uint8_t* data);
358 int PrintImmediateOp(uint8_t* data);
359 int F7Instruction(uint8_t* data);
360 int D1D3C1Instruction(uint8_t* data);
361 int JumpShort(uint8_t* data);
362 int JumpConditional(uint8_t* data,
const char* comment);
363 int JumpConditionalShort(uint8_t* data,
const char* comment);
364 int SetCC(uint8_t* data);
365 int CMov(uint8_t* data);
366 int FPUInstruction(uint8_t* data);
367 int MemoryFPUInstruction(
int escape_opcode,
int regop, uint8_t* modrm_start);
368 int RegisterFPUInstruction(
int escape_opcode, uint8_t modrm_byte);
369 int AVXInstruction(uint8_t* data);
370 PRINTF_FORMAT(2, 3) void AppendToBuffer(const
char* format, ...);
372 void UnimplementedInstruction() {
373 if (unimplemented_opcode_action_ ==
374 Disassembler::kAbortOnUnimplementedOpcode) {
375 FATAL(
"Unimplemented instruction in disassembler");
377 AppendToBuffer(
"'Unimplemented instruction'");
382void DisassemblerIA32::AppendToBuffer(
const char* format, ...) {
385 va_start(
args, format);
388 tmp_buffer_pos_ +=
result;
391int DisassemblerIA32::PrintRightOperandHelper(
392 uint8_t* modrmp, RegisterNameMapping direct_register_name) {
394 get_modrm(*modrmp, &mod, ®op, &rm);
395 RegisterNameMapping register_name =
396 (mod == 3) ? direct_register_name : &DisassemblerIA32::NameOfCPURegister;
400 AppendToBuffer(
"[0x%x]", Imm32(modrmp + 1));
402 }
else if (rm == esp) {
403 uint8_t sib = *(modrmp + 1);
406 if (index == esp &&
base == esp &&
scale == 0 ) {
407 AppendToBuffer(
"[%s]", (this->*register_name)(rm));
409 }
else if (
base == ebp) {
410 int32_t disp = Imm32(modrmp + 2);
411 AppendToBuffer(
"[%s*%d%s0x%x]", (this->*register_name)(index),
412 1 <<
scale, disp < 0 ?
"-" :
"+",
413 disp < 0 ? -disp : disp);
415 }
else if (index != esp &&
base != ebp) {
417 AppendToBuffer(
"[%s+%s*%d]", (this->*register_name)(
base),
418 (this->*register_name)(index), 1 <<
scale);
421 UnimplementedInstruction();
425 AppendToBuffer(
"[%s]", (this->*register_name)(rm));
430 uint8_t sib = *(modrmp + 1);
433 int disp = mod == 2 ? Imm32(modrmp + 2) : Imm8(modrmp + 2);
434 if (index ==
base && index == rm &&
scale == 0 ) {
435 AppendToBuffer(
"[%s%s0x%x]", (this->*register_name)(rm),
436 disp < 0 ?
"-" :
"+", disp < 0 ? -disp : disp);
438 AppendToBuffer(
"[%s+%s*%d%s0x%x]", (this->*register_name)(
base),
439 (this->*register_name)(index), 1 <<
scale,
440 disp < 0 ?
"-" :
"+", disp < 0 ? -disp : disp);
442 return mod == 2 ? 6 : 3;
445 int disp = mod == 2 ? Imm32(modrmp + 1) : Imm8(modrmp + 1);
446 AppendToBuffer(
"[%s%s0x%x]", (this->*register_name)(rm),
447 disp < 0 ?
"-" :
"+", disp < 0 ? -disp : disp);
448 return mod == 2 ? 5 : 2;
451 AppendToBuffer(
"%s", (this->*register_name)(rm));
454 UnimplementedInstruction();
460int DisassemblerIA32::PrintRightOperand(uint8_t* modrmp) {
461 return PrintRightOperandHelper(modrmp, &DisassemblerIA32::NameOfCPURegister);
464int DisassemblerIA32::PrintRightByteOperand(uint8_t* modrmp) {
465 return PrintRightOperandHelper(modrmp,
466 &DisassemblerIA32::NameOfByteCPURegister);
469int DisassemblerIA32::PrintRightXMMOperand(uint8_t* modrmp) {
470 return PrintRightOperandHelper(modrmp, &DisassemblerIA32::NameOfXMMRegister);
475int DisassemblerIA32::PrintOperands(
const char* mnem, OperandOrder op_order,
477 uint8_t modrm = *
data;
479 get_modrm(modrm, &mod, ®op, &rm);
482 case REG_OPER_OP_ORDER: {
483 AppendToBuffer(
"%s %s,", mnem, NameOfCPURegister(regop));
484 advance = PrintRightOperand(data);
487 case OPER_REG_OP_ORDER: {
488 AppendToBuffer(
"%s ", mnem);
489 advance = PrintRightOperand(data);
490 AppendToBuffer(
",%s", NameOfCPURegister(regop));
501int DisassemblerIA32::PrintImmediateOp(uint8_t* data) {
502 bool sign_extension_bit = (*data & 0x02) != 0;
503 uint8_t modrm = *(data + 1);
505 get_modrm(modrm, &mod, ®op, &rm);
506 const char* mnem =
"Imm???";
530 UnimplementedInstruction();
532 AppendToBuffer(
"%s ", mnem);
533 int count = PrintRightOperand(data + 1);
534 if (sign_extension_bit) {
535 AppendToBuffer(
",0x%x", *(data + 1 + count));
536 return 1 + count + 1 ;
538 AppendToBuffer(
",0x%x", Imm32(data + 1 + count));
539 return 1 + count + 4 ;
544int DisassemblerIA32::F7Instruction(uint8_t* data) {
546 uint8_t modrm = *++
data;
548 get_modrm(modrm, &mod, ®op, &rm);
549 const char* mnem =
"";
573 UnimplementedInstruction();
575 AppendToBuffer(
"%s ", mnem);
576 int count = PrintRightOperand(data);
578 AppendToBuffer(
",0x%x", Imm32(data + count));
584int DisassemblerIA32::D1D3C1Instruction(uint8_t* data) {
586 DCHECK(op == 0xD1 || op == 0xD3 || op == 0xC1);
587 uint8_t modrm = *++
data;
589 get_modrm(modrm, &mod, ®op, &rm);
591 const char* mnem =
"";
615 UnimplementedInstruction();
617 AppendToBuffer(
"%s ", mnem);
618 int count = PrintRightOperand(data);
621 }
else if (op == 0xC1) {
624 }
else if (op == 0xD3) {
628 AppendToBuffer(
",%d", imm8);
630 AppendToBuffer(
",cl");
636int DisassemblerIA32::JumpShort(uint8_t* data) {
638 uint8_t b = *(data + 1);
639 uint8_t* dest = data +
static_cast<int8_t
>(b) + 2;
640 AppendToBuffer(
"jmp %s", NameOfAddress(dest));
645int DisassemblerIA32::JumpConditional(uint8_t* data,
const char* comment) {
647 uint8_t cond = *(data + 1) & 0x0F;
648 uint8_t* dest = data + Imm32(data + 2) + 6;
649 const char* mnem = jump_conditional_mnem[cond];
650 AppendToBuffer(
"%s %s", mnem, NameOfAddress(dest));
651 if (comment !=
nullptr) {
652 AppendToBuffer(
", %s", comment);
658int DisassemblerIA32::JumpConditionalShort(uint8_t* data,
const char* comment) {
659 uint8_t cond = *data & 0x0F;
660 uint8_t b = *(data + 1);
661 uint8_t* dest = data +
static_cast<int8_t
>(b) + 2;
662 const char* mnem = jump_conditional_mnem[cond];
663 AppendToBuffer(
"%s %s", mnem, NameOfAddress(dest));
664 if (comment !=
nullptr) {
665 AppendToBuffer(
", %s", comment);
671int DisassemblerIA32::SetCC(uint8_t* data) {
673 uint8_t cond = *(data + 1) & 0x0F;
674 const char* mnem = set_conditional_mnem[cond];
675 AppendToBuffer(
"%s ", mnem);
676 PrintRightByteOperand(data + 2);
681int DisassemblerIA32::CMov(uint8_t* data) {
683 uint8_t cond = *(data + 1) & 0x0F;
684 const char* mnem = conditional_move_mnem[cond];
685 int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2);
689const char* sf_str[4] = {
"",
"rl",
"ra",
"ll"};
691int DisassemblerIA32::AVXInstruction(uint8_t* data) {
692 uint8_t opcode = *
data;
693 uint8_t* current = data + 1;
694 if (vex_66() && vex_0f38()) {
695 int mod, regop, rm, vvvv = vex_vreg();
696 get_modrm(*current, &mod, ®op, &rm);
699 AppendToBuffer(
"vbroadcastss %s,", NameOfXMMRegister(regop));
700 current += PrintRightXMMOperand(current);
703 AppendToBuffer(
"vpcmpgtq %s,%s,", NameOfXMMRegister(regop),
704 NameOfXMMRegister(vvvv));
705 current += PrintRightXMMOperand(current);
708 AppendToBuffer(
"shlx %s,", NameOfCPURegister(regop));
709 current += PrintRightOperand(current);
710 AppendToBuffer(
",%s", NameOfCPURegister(vvvv));
712#define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, notUsed3, \
715 AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \
716 NameOfXMMRegister(vvvv)); \
717 current += PrintRightXMMOperand(current); \
723#undef DECLARE_SSE_AVX_DIS_CASE
724#define DECLARE_SSE_AVX_RM_DIS_CASE(instruction, notUsed1, notUsed2, notUsed3, \
727 AppendToBuffer("v" #instruction " %s,", NameOfXMMRegister(regop)); \
728 current += PrintRightXMMOperand(current); \
734#undef DECLARE_SSE_AVX_RM_DIS_CASE
736#define DISASSEMBLE_AVX2_BROADCAST(instruction, _1, _2, _3, code) \
738 AppendToBuffer("" #instruction " %s,", NameOfXMMRegister(regop)); \
739 current += PrintRightXMMOperand(current); \
742#undef DISASSEMBLE_AVX2_BROADCAST
745#define DECLARE_FMA_DISASM(instruction, _1, _2, _3, _4, _5, code) \
747 AppendToBuffer(#instruction " %s,%s,", NameOfXMMRegister(regop), \
748 NameOfXMMRegister(vvvv)); \
749 current += PrintRightXMMOperand(current); \
759 UnimplementedInstruction();
767 UnimplementedInstruction();
771#undef DECLARE_FMA_DISASM
774 }
else if (vex_66() && vex_0f3a()) {
775 int mod, regop, rm, vvvv = vex_vreg();
776 get_modrm(*current, &mod, ®op, &rm);
779 AppendToBuffer(
"vroundps %s,", NameOfXMMRegister(regop));
780 current += PrintRightXMMOperand(current);
781 AppendToBuffer(
",%d", Imm8_U(current));
785 AppendToBuffer(
"vroundpd %s,", NameOfXMMRegister(regop));
786 current += PrintRightXMMOperand(current);
787 AppendToBuffer(
",%d", Imm8_U(current));
791 AppendToBuffer(
"vroundss %s,%s,", NameOfXMMRegister(regop),
792 NameOfXMMRegister(vvvv));
793 current += PrintRightXMMOperand(current);
794 AppendToBuffer(
",%d", Imm8_U(current));
798 AppendToBuffer(
"vroundsd %s,%s,", NameOfXMMRegister(regop),
799 NameOfXMMRegister(vvvv));
800 current += PrintRightXMMOperand(current);
801 AppendToBuffer(
",%d", Imm8_U(current));
805 AppendToBuffer(
"vpblendw %s,%s,", NameOfXMMRegister(regop),
806 NameOfXMMRegister(vvvv));
807 current += PrintRightXMMOperand(current);
808 AppendToBuffer(
",%d", Imm8_U(current));
812 AppendToBuffer(
"vpalignr %s,%s,", NameOfXMMRegister(regop),
813 NameOfXMMRegister(vvvv));
814 current += PrintRightXMMOperand(current);
815 AppendToBuffer(
",%d", Imm8_U(current));
819 AppendToBuffer(
"vpextrb ");
820 current += PrintRightOperand(current);
821 AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop), Imm8(current));
825 AppendToBuffer(
"vpextrw ");
826 current += PrintRightOperand(current);
827 AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop), Imm8(current));
831 AppendToBuffer(
"vpextrd ");
832 current += PrintRightOperand(current);
833 AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop), Imm8(current));
837 AppendToBuffer(
"vpinsrb %s,%s,", NameOfXMMRegister(regop),
838 NameOfXMMRegister(vvvv));
839 current += PrintRightOperand(current);
840 AppendToBuffer(
",%d", Imm8(current));
844 AppendToBuffer(
"vinsertps %s,%s,", NameOfXMMRegister(regop),
845 NameOfXMMRegister(vvvv));
846 current += PrintRightXMMOperand(current);
847 AppendToBuffer(
",%d", Imm8(current));
851 AppendToBuffer(
"vpinsrd %s,%s,", NameOfXMMRegister(regop),
852 NameOfXMMRegister(vvvv));
853 current += PrintRightOperand(current);
854 AppendToBuffer(
",%d", Imm8(current));
858 AppendToBuffer(
"vblendvps %s,%s,", NameOfXMMRegister(regop),
859 NameOfXMMRegister(vvvv));
860 current += PrintRightXMMOperand(current);
861 AppendToBuffer(
",%s", NameOfXMMRegister(*current >> 4));
864 AppendToBuffer(
"vblendvps %s,%s,", NameOfXMMRegister(regop),
865 NameOfXMMRegister(vvvv));
866 current += PrintRightXMMOperand(current);
867 AppendToBuffer(
",%s", NameOfXMMRegister(*current >> 4));
870 AppendToBuffer(
"vpblendvb %s,%s,", NameOfXMMRegister(regop),
871 NameOfXMMRegister(vvvv));
872 current += PrintRightXMMOperand(current);
873 AppendToBuffer(
",%s", NameOfXMMRegister(*current >> 4));
876 UnimplementedInstruction();
878 }
else if (vex_f2() && vex_0f()) {
879 int mod, regop, rm, vvvv = vex_vreg();
880 get_modrm(*current, &mod, ®op, &rm);
883 AppendToBuffer(
"vmovsd %s,%s,", NameOfXMMRegister(regop),
884 NameOfXMMRegister(vvvv));
885 current += PrintRightXMMOperand(current);
888 AppendToBuffer(
"vmovsd ");
889 current += PrintRightXMMOperand(current);
890 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
893 AppendToBuffer(
"vmovddup %s,", NameOfXMMRegister(regop));
894 current += PrintRightXMMOperand(current);
897 AppendToBuffer(
"vcvttsd2si %s,", NameOfXMMRegister(regop));
898 current += PrintRightXMMOperand(current);
901 AppendToBuffer(
"vpshuflw %s,", NameOfXMMRegister(regop));
902 current += PrintRightXMMOperand(current);
903 AppendToBuffer(
",%d", Imm8(current));
907 AppendToBuffer(
"vhaddps %s,%s,", NameOfXMMRegister(regop),
908 NameOfXMMRegister(vvvv));
909 current += PrintRightXMMOperand(current);
911#define DISASM_SSE2_INSTRUCTION_LIST_SD(instruction, _1, _2, opcode) \
913 AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \
914 NameOfXMMRegister(vvvv)); \
915 current += PrintRightXMMOperand(current); \
918#undef DISASM_SSE2_INSTRUCTION_LIST_SD
920 UnimplementedInstruction();
922 }
else if (vex_f3() && vex_0f()) {
923 int mod, regop, rm, vvvv = vex_vreg();
924 get_modrm(*current, &mod, ®op, &rm);
927 AppendToBuffer(
"vmovss %s,%s,", NameOfXMMRegister(regop),
928 NameOfXMMRegister(vvvv));
929 current += PrintRightXMMOperand(current);
932 AppendToBuffer(
"vmovss ");
933 current += PrintRightXMMOperand(current);
934 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
937 AppendToBuffer(
"vmovshdup %s,", NameOfXMMRegister(regop));
938 current += PrintRightXMMOperand(current);
941 AppendToBuffer(
"vcvttss2si %s,", NameOfXMMRegister(regop));
942 current += PrintRightXMMOperand(current);
945 AppendToBuffer(
"vsqrtss %s,%s,", NameOfXMMRegister(regop),
946 NameOfXMMRegister(vvvv));
947 current += PrintRightXMMOperand(current);
950 AppendToBuffer(
"vaddss %s,%s,", NameOfXMMRegister(regop),
951 NameOfXMMRegister(vvvv));
952 current += PrintRightXMMOperand(current);
955 AppendToBuffer(
"vmulss %s,%s,", NameOfXMMRegister(regop),
956 NameOfXMMRegister(vvvv));
957 current += PrintRightXMMOperand(current);
960 AppendToBuffer(
"vcvtss2sd %s,%s,", NameOfXMMRegister(regop),
961 NameOfXMMRegister(vvvv));
962 current += PrintRightXMMOperand(current);
965 AppendToBuffer(
"vcvttps2dq %s,", NameOfXMMRegister(regop));
966 current += PrintRightXMMOperand(current);
969 AppendToBuffer(
"vsubss %s,%s,", NameOfXMMRegister(regop),
970 NameOfXMMRegister(vvvv));
971 current += PrintRightXMMOperand(current);
974 AppendToBuffer(
"vminss %s,%s,", NameOfXMMRegister(regop),
975 NameOfXMMRegister(vvvv));
976 current += PrintRightXMMOperand(current);
979 AppendToBuffer(
"vdivss %s,%s,", NameOfXMMRegister(regop),
980 NameOfXMMRegister(vvvv));
981 current += PrintRightXMMOperand(current);
984 AppendToBuffer(
"vmaxss %s,%s,", NameOfXMMRegister(regop),
985 NameOfXMMRegister(vvvv));
986 current += PrintRightXMMOperand(current);
989 AppendToBuffer(
"vmovdqu %s,", NameOfXMMRegister(regop));
990 current += PrintRightOperand(current);
993 AppendToBuffer(
"vpshufhw %s,", NameOfXMMRegister(regop));
994 current += PrintRightXMMOperand(current);
995 AppendToBuffer(
",%d", Imm8(current));
999 AppendToBuffer(
"vmovdqu ");
1000 current += PrintRightOperand(current);
1001 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
1004 AppendToBuffer(
"vcvtdq2pd %s,", NameOfXMMRegister(regop));
1005 current += PrintRightXMMOperand(current);
1008 UnimplementedInstruction();
1010 }
else if (vex_none() && vex_0f38()) {
1011 int mod, regop, rm, vvvv = vex_vreg();
1012 get_modrm(*current, &mod, ®op, &rm);
1013 const char* mnem =
"?";
1016 AppendToBuffer(
"andn %s,%s,", NameOfCPURegister(regop),
1017 NameOfCPURegister(vvvv));
1018 current += PrintRightOperand(current);
1021 AppendToBuffer(
"bzhi %s,", NameOfCPURegister(regop));
1022 current += PrintRightOperand(current);
1023 AppendToBuffer(
",%s", NameOfCPURegister(vvvv));
1026 AppendToBuffer(
"bextr %s,", NameOfCPURegister(regop));
1027 current += PrintRightOperand(current);
1028 AppendToBuffer(
",%s", NameOfCPURegister(vvvv));
1042 UnimplementedInstruction();
1044 AppendToBuffer(
"%s %s,", mnem, NameOfCPURegister(vvvv));
1045 current += PrintRightOperand(current);
1049 UnimplementedInstruction();
1051 }
else if (vex_f2() && vex_0f38()) {
1052 int mod, regop, rm, vvvv = vex_vreg();
1053 get_modrm(*current, &mod, ®op, &rm);
1056 AppendToBuffer(
"pdep %s,%s,", NameOfCPURegister(regop),
1057 NameOfCPURegister(vvvv));
1058 current += PrintRightOperand(current);
1061 AppendToBuffer(
"mulx %s,%s,", NameOfCPURegister(regop),
1062 NameOfCPURegister(vvvv));
1063 current += PrintRightOperand(current);
1066 AppendToBuffer(
"shrx %s,", NameOfCPURegister(regop));
1067 current += PrintRightOperand(current);
1068 AppendToBuffer(
",%s", NameOfCPURegister(vvvv));
1071 UnimplementedInstruction();
1073 }
else if (vex_f3() && vex_0f38()) {
1074 int mod, regop, rm, vvvv = vex_vreg();
1075 get_modrm(*current, &mod, ®op, &rm);
1078 AppendToBuffer(
"pext %s,%s,", NameOfCPURegister(regop),
1079 NameOfCPURegister(vvvv));
1080 current += PrintRightOperand(current);
1083 AppendToBuffer(
"sarx %s,", NameOfCPURegister(regop));
1084 current += PrintRightOperand(current);
1085 AppendToBuffer(
",%s", NameOfCPURegister(vvvv));
1088 UnimplementedInstruction();
1090 }
else if (vex_f2() && vex_0f3a()) {
1092 get_modrm(*current, &mod, ®op, &rm);
1095 AppendToBuffer(
"rorx %s,", NameOfCPURegister(regop));
1096 current += PrintRightOperand(current);
1097 AppendToBuffer(
",%d", *current & 0x1F);
1101 UnimplementedInstruction();
1103 }
else if (vex_none() && vex_0f()) {
1104 int mod, regop, rm, vvvv = vex_vreg();
1105 get_modrm(*current, &mod, ®op, &rm);
1108 AppendToBuffer(
"vmovups %s,", NameOfXMMRegister(regop));
1109 current += PrintRightXMMOperand(current);
1112 AppendToBuffer(
"vmovups ");
1113 current += PrintRightXMMOperand(current);
1114 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
1118 AppendToBuffer(
"vmovhlps %s,%s,", NameOfXMMRegister(regop),
1119 NameOfXMMRegister(vvvv));
1121 AppendToBuffer(
"vmovlps %s,%s,", NameOfXMMRegister(regop),
1122 NameOfXMMRegister(vvvv));
1124 current += PrintRightXMMOperand(current);
1127 AppendToBuffer(
"vmovlps ");
1128 current += PrintRightXMMOperand(current);
1129 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
1132 AppendToBuffer(
"vunpcklps %s,%s,", NameOfXMMRegister(regop),
1133 NameOfXMMRegister(vvvv));
1134 current += PrintRightXMMOperand(current);
1137 AppendToBuffer(
"vmovhps %s,", NameOfXMMRegister(regop));
1138 current += PrintRightXMMOperand(current);
1141 AppendToBuffer(
"vmovhps ");
1142 current += PrintRightXMMOperand(current);
1143 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
1146 AppendToBuffer(
"vmovaps %s,", NameOfXMMRegister(regop));
1147 current += PrintRightXMMOperand(current);
1150 AppendToBuffer(
"vucomiss %s,", NameOfXMMRegister(regop));
1151 current += PrintRightXMMOperand(current);
1154 AppendToBuffer(
"vmovmskps %s,%s", NameOfCPURegister(regop),
1155 NameOfXMMRegister(rm));
1159 AppendToBuffer(
"vsqrtps %s,", NameOfXMMRegister(regop));
1160 current += PrintRightXMMOperand(current);
1163 AppendToBuffer(
"vrsqrtps %s,", NameOfXMMRegister(regop));
1164 current += PrintRightXMMOperand(current);
1167 AppendToBuffer(
"vrcpps %s,", NameOfXMMRegister(regop));
1168 current += PrintRightXMMOperand(current);
1171 AppendToBuffer(
"vandps %s,%s,", NameOfXMMRegister(regop),
1172 NameOfXMMRegister(vvvv));
1173 current += PrintRightXMMOperand(current);
1176 AppendToBuffer(
"vandnps %s,%s,", NameOfXMMRegister(regop),
1177 NameOfXMMRegister(vvvv));
1178 current += PrintRightXMMOperand(current);
1181 AppendToBuffer(
"vorps %s,%s,", NameOfXMMRegister(regop),
1182 NameOfXMMRegister(vvvv));
1183 current += PrintRightXMMOperand(current);
1186 AppendToBuffer(
"vxorps %s,%s,", NameOfXMMRegister(regop),
1187 NameOfXMMRegister(vvvv));
1188 current += PrintRightXMMOperand(current);
1191 AppendToBuffer(
"vaddps %s,%s,", NameOfXMMRegister(regop),
1192 NameOfXMMRegister(vvvv));
1193 current += PrintRightXMMOperand(current);
1196 AppendToBuffer(
"vmulps %s,%s,", NameOfXMMRegister(regop),
1197 NameOfXMMRegister(vvvv));
1198 current += PrintRightXMMOperand(current);
1201 AppendToBuffer(
"vcvtps2pd %s,", NameOfXMMRegister(regop));
1202 current += PrintRightXMMOperand(current);
1205 AppendToBuffer(
"vcvtdq2ps %s,", NameOfXMMRegister(regop));
1206 current += PrintRightXMMOperand(current);
1209 AppendToBuffer(
"vsubps %s,%s,", NameOfXMMRegister(regop),
1210 NameOfXMMRegister(vvvv));
1211 current += PrintRightXMMOperand(current);
1214 AppendToBuffer(
"vminps %s,%s,", NameOfXMMRegister(regop),
1215 NameOfXMMRegister(vvvv));
1216 current += PrintRightXMMOperand(current);
1219 AppendToBuffer(
"vdivps %s,%s,", NameOfXMMRegister(regop),
1220 NameOfXMMRegister(vvvv));
1221 current += PrintRightXMMOperand(current);
1224 AppendToBuffer(
"vmaxps %s,%s,", NameOfXMMRegister(regop),
1225 NameOfXMMRegister(vvvv));
1226 current += PrintRightXMMOperand(current);
1229 AppendToBuffer(
"vcmpps %s,%s,", NameOfXMMRegister(regop),
1230 NameOfXMMRegister(vvvv));
1231 current += PrintRightXMMOperand(current);
1232 AppendToBuffer(
", (%s)", cmp_pseudo_op[*current]);
1237 AppendToBuffer(
"vshufps %s,%s,", NameOfXMMRegister(regop),
1238 NameOfXMMRegister(vvvv));
1239 current += PrintRightXMMOperand(current);
1240 AppendToBuffer(
", %d", (*current) & 3);
1244 UnimplementedInstruction();
1246 }
else if (vex_66() && vex_0f()) {
1247 int mod, regop, rm, vvvv = vex_vreg();
1248 get_modrm(*current, &mod, ®op, &rm);
1251 AppendToBuffer(
"vmovupd %s,", NameOfXMMRegister(regop));
1252 current += PrintRightXMMOperand(current);
1255 AppendToBuffer(
"vmovapd %s,", NameOfXMMRegister(regop));
1256 current += PrintRightXMMOperand(current);
1259 AppendToBuffer(
"vucomisd %s,", NameOfXMMRegister(regop));
1260 current += PrintRightXMMOperand(current);
1263 AppendToBuffer(
"vmovmskpd %s,%s", NameOfCPURegister(regop),
1264 NameOfXMMRegister(rm));
1268 AppendToBuffer(
"vandpd %s,%s,", NameOfXMMRegister(regop),
1269 NameOfXMMRegister(vvvv));
1270 current += PrintRightXMMOperand(current);
1273 AppendToBuffer(
"vandnpd %s,%s,", NameOfXMMRegister(regop),
1274 NameOfXMMRegister(vvvv));
1275 current += PrintRightXMMOperand(current);
1278 AppendToBuffer(
"vorpd %s,%s,", NameOfXMMRegister(regop),
1279 NameOfXMMRegister(vvvv));
1280 current += PrintRightXMMOperand(current);
1283 AppendToBuffer(
"vxorpd %s,%s,", NameOfXMMRegister(regop),
1284 NameOfXMMRegister(vvvv));
1285 current += PrintRightXMMOperand(current);
1288 AppendToBuffer(
"vaddpd %s,%s,", NameOfXMMRegister(regop),
1289 NameOfXMMRegister(vvvv));
1290 current += PrintRightXMMOperand(current);
1293 AppendToBuffer(
"vmulpd %s,%s,", NameOfXMMRegister(regop),
1294 NameOfXMMRegister(vvvv));
1295 current += PrintRightXMMOperand(current);
1298 AppendToBuffer(
"vcvtpd2ps %s,", NameOfXMMRegister(regop));
1299 current += PrintRightXMMOperand(current);
1302 AppendToBuffer(
"vsubpd %s,%s,", NameOfXMMRegister(regop),
1303 NameOfXMMRegister(vvvv));
1304 current += PrintRightXMMOperand(current);
1307 AppendToBuffer(
"vminpd %s,%s,", NameOfXMMRegister(regop),
1308 NameOfXMMRegister(vvvv));
1309 current += PrintRightXMMOperand(current);
1312 AppendToBuffer(
"vdivpd %s,%s,", NameOfXMMRegister(regop),
1313 NameOfXMMRegister(vvvv));
1314 current += PrintRightXMMOperand(current);
1317 AppendToBuffer(
"vmaxpd %s,%s,", NameOfXMMRegister(regop),
1318 NameOfXMMRegister(vvvv));
1319 current += PrintRightXMMOperand(current);
1322 AppendToBuffer(
"vmovd %s,", NameOfXMMRegister(regop));
1323 current += PrintRightOperand(current);
1326 AppendToBuffer(
"vmovdqa %s,", NameOfXMMRegister(regop));
1327 current += PrintRightOperand(current);
1330 AppendToBuffer(
"vpshufd %s,", NameOfXMMRegister(regop));
1331 current += PrintRightXMMOperand(current);
1332 AppendToBuffer(
",%d", Imm8(current));
1336 AppendToBuffer(
"vps%sw %s,%s", sf_str[regop / 2],
1337 NameOfXMMRegister(vvvv), NameOfXMMRegister(rm));
1339 AppendToBuffer(
",%u", *current++);
1342 AppendToBuffer(
"vps%sd %s,%s", sf_str[regop / 2],
1343 NameOfXMMRegister(vvvv), NameOfXMMRegister(rm));
1345 AppendToBuffer(
",%u", *current++);
1348 AppendToBuffer(
"vps%sq %s,%s", sf_str[regop / 2],
1349 NameOfXMMRegister(vvvv), NameOfXMMRegister(rm));
1351 AppendToBuffer(
",%u", *current++);
1354 AppendToBuffer(
"vmovd ");
1355 current += PrintRightOperand(current);
1356 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
1359 AppendToBuffer(
"vcmppd %s,%s,", NameOfXMMRegister(regop),
1360 NameOfXMMRegister(vvvv));
1361 current += PrintRightXMMOperand(current);
1362 AppendToBuffer(
", (%s)", cmp_pseudo_op[*current]);
1367 AppendToBuffer(
"vpinsrw %s,%s,", NameOfXMMRegister(regop),
1368 NameOfXMMRegister(vvvv));
1369 current += PrintRightOperand(current);
1370 AppendToBuffer(
",%d", Imm8(current));
1374 AppendToBuffer(
"vshufpd %s,%s,", NameOfXMMRegister(regop),
1375 NameOfXMMRegister(vvvv));
1376 current += PrintRightXMMOperand(current);
1377 AppendToBuffer(
",%d", Imm8(current));
1381 AppendToBuffer(
"vpmovmskb %s,%s", NameOfCPURegister(regop),
1382 NameOfXMMRegister(rm));
1386 AppendToBuffer(
"vcvttpd2dq %s,", NameOfXMMRegister(regop));
1387 current += PrintRightXMMOperand(current);
1389#define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, opcode) \
1390 case 0x##opcode: { \
1391 AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \
1392 NameOfXMMRegister(vvvv)); \
1393 current += PrintRightXMMOperand(current); \
1398#undef DECLARE_SSE_AVX_DIS_CASE
1400 UnimplementedInstruction();
1403 UnimplementedInstruction();
1406 return static_cast<int>(current -
data);
1410int DisassemblerIA32::FPUInstruction(uint8_t* data) {
1411 uint8_t escape_opcode = *
data;
1413 uint8_t modrm_byte = *(data + 1);
1415 if (modrm_byte >= 0xC0) {
1416 return RegisterFPUInstruction(escape_opcode, modrm_byte);
1418 return MemoryFPUInstruction(escape_opcode, modrm_byte, data + 1);
1422int DisassemblerIA32::MemoryFPUInstruction(
int escape_opcode,
int modrm_byte,
1423 uint8_t* modrm_start) {
1424 const char* mnem =
"?";
1425 int regop = (modrm_byte >> 3) & 0x7;
1426 switch (escape_opcode) {
1442 UnimplementedInstruction();
1461 UnimplementedInstruction();
1480 UnimplementedInstruction();
1493 UnimplementedInstruction();
1498 UnimplementedInstruction();
1500 AppendToBuffer(
"%s ", mnem);
1501 int count = PrintRightOperand(modrm_start);
1505int DisassemblerIA32::RegisterFPUInstruction(
int escape_opcode,
1506 uint8_t modrm_byte) {
1507 bool has_register =
false;
1508 const char* mnem =
"?";
1510 switch (escape_opcode) {
1512 has_register =
true;
1513 switch (modrm_byte & 0xF8) {
1527 UnimplementedInstruction();
1532 switch (modrm_byte & 0xF8) {
1535 has_register =
true;
1539 has_register =
true;
1542 switch (modrm_byte) {
1595 UnimplementedInstruction();
1601 if (modrm_byte == 0xE9) {
1604 UnimplementedInstruction();
1609 if ((modrm_byte & 0xF8) == 0xE8) {
1611 has_register =
true;
1612 }
else if (modrm_byte == 0xE2) {
1614 }
else if (modrm_byte == 0xE3) {
1617 UnimplementedInstruction();
1622 has_register =
true;
1623 switch (modrm_byte & 0xF8) {
1637 UnimplementedInstruction();
1642 has_register =
true;
1643 switch (modrm_byte & 0xF8) {
1654 UnimplementedInstruction();
1659 if (modrm_byte == 0xD9) {
1662 has_register =
true;
1663 switch (modrm_byte & 0xF8) {
1677 UnimplementedInstruction();
1683 if (modrm_byte == 0xE0) {
1685 }
else if ((modrm_byte & 0xF8) == 0xE8) {
1687 has_register =
true;
1692 UnimplementedInstruction();
1696 AppendToBuffer(
"%s st%d", mnem, modrm_byte & 0x7);
1698 AppendToBuffer(
"%s", mnem);
1705static const char* F0Mnem(uint8_t f0byte) {
1751 tmp_buffer_pos_ = 0;
1752 uint8_t* data =
instr;
1754 const char* branch_hint =
nullptr;
1756 if (*data == 0x3E ) {
1757 branch_hint =
"predicted taken";
1759 }
else if (*data == 0x2E ) {
1760 branch_hint =
"predicted not taken";
1762 }
else if (*data == 0xC4 && *(data + 1) >= 0xC0) {
1764 vex_byte1_ = *(data + 1);
1765 vex_byte2_ = *(data + 2);
1767 }
else if (*data == 0xC5 && *(data + 1) >= 0xC0) {
1769 vex_byte1_ = *(data + 1);
1771 }
else if (*data == 0xF0 ) {
1772 AppendToBuffer(
"lock ");
1776 bool processed =
true;
1779 if (vex_byte0_ != 0) {
1780 data += AVXInstruction(data);
1782 const InstructionDesc& idesc = instruction_table_->Get(*data);
1783 switch (idesc.type) {
1784 case ZERO_OPERANDS_INSTR:
1785 AppendToBuffer(
"%s", idesc.mnem);
1789 case TWO_OPERANDS_INSTR:
1791 data += PrintOperands(idesc.mnem, idesc.op_order_, data);
1794 case JUMP_CONDITIONAL_SHORT_INSTR:
1795 data += JumpConditionalShort(data, branch_hint);
1798 case REGISTER_INSTR:
1799 AppendToBuffer(
"%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
1803 case MOVE_REG_INSTR: {
1804 uint8_t* addr =
reinterpret_cast<uint8_t*
>(Imm32(data + 1));
1805 AppendToBuffer(
"mov %s,%s", NameOfCPURegister(*data & 0x07),
1806 NameOfAddress(addr));
1811 case CALL_JUMP_INSTR: {
1812 uint8_t* addr = data + Imm32(data + 1) + 5;
1813 AppendToBuffer(
"%s %s", idesc.mnem, NameOfAddress(addr));
1818 case SHORT_IMMEDIATE_INSTR: {
1819 uint8_t* addr =
reinterpret_cast<uint8_t*
>(Imm32(data + 1));
1820 AppendToBuffer(
"%s eax,%s", idesc.mnem, NameOfAddress(addr));
1825 case BYTE_IMMEDIATE_INSTR: {
1826 AppendToBuffer(
"%s al,0x%x", idesc.mnem, data[1]);
1843 AppendToBuffer(
"ret 0x%x", Imm16_U(data + 1));
1849 data += PrintOperands(
"imul", REG_OPER_OP_ORDER, data);
1850 AppendToBuffer(
",%d", *data);
1856 data += PrintOperands(
"imul", REG_OPER_OP_ORDER, data);
1857 AppendToBuffer(
",%d", Imm32(data));
1864 get_modrm(*data, &mod, ®op, &rm);
1866 AppendToBuffer(
"test_b ");
1867 data += PrintRightByteOperand(data);
1869 AppendToBuffer(
",0x%x", imm);
1872 UnimplementedInstruction();
1878 data += PrintImmediateOp(data);
1882 uint8_t f0byte = data[1];
1883 const char* f0mnem = F0Mnem(f0byte);
1887 get_modrm(*(data + 2), &mod, ®op, &rm);
1888 if (f0byte == 0x12) {
1891 AppendToBuffer(
"movhlps %s,", NameOfXMMRegister(regop));
1893 AppendToBuffer(
"movlps %s,", NameOfXMMRegister(regop));
1895 data += PrintRightXMMOperand(data);
1896 }
else if (f0byte == 0x13) {
1898 AppendToBuffer(
"movlps ");
1899 data += PrintRightXMMOperand(data);
1900 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
1901 }
else if (f0byte == 0x14) {
1903 AppendToBuffer(
"unpcklps %s,", NameOfXMMRegister(regop));
1904 data += PrintRightXMMOperand(data);
1905 }
else if (f0byte == 0x16) {
1907 AppendToBuffer(
"movhps %s,", NameOfXMMRegister(regop));
1908 data += PrintRightXMMOperand(data);
1909 }
else if (f0byte == 0x17) {
1911 AppendToBuffer(
"movhps ");
1912 data += PrintRightXMMOperand(data);
1913 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
1914 }
else if (f0byte == 0x18) {
1916 const char* suffix[] = {
"nta",
"1",
"2",
"3"};
1917 AppendToBuffer(
"%s%s ", f0mnem, suffix[regop & 0x03]);
1918 data += PrintRightOperand(data);
1919 }
else if (f0byte == 0x1F && data[2] == 0) {
1920 AppendToBuffer(
"nop");
1922 }
else if (f0byte == 0x1F && data[2] == 0x40 && data[3] == 0) {
1923 AppendToBuffer(
"nop");
1925 }
else if (f0byte == 0x1F && data[2] == 0x44 && data[3] == 0 &&
1927 AppendToBuffer(
"nop");
1929 }
else if (f0byte == 0x1F && data[2] == 0x80 && data[3] == 0 &&
1930 data[4] == 0 && data[5] == 0 && data[6] == 0) {
1931 AppendToBuffer(
"nop");
1933 }
else if (f0byte == 0x1F && data[2] == 0x84 && data[3] == 0 &&
1934 data[4] == 0 && data[5] == 0 && data[6] == 0 &&
1936 AppendToBuffer(
"nop");
1938 }
else if (f0byte == 0x0B || f0byte == 0xA2 || f0byte == 0x31) {
1939 AppendToBuffer(
"%s", f0mnem);
1941 }
else if (f0byte == 0x28) {
1943 AppendToBuffer(
"movaps %s,%s", NameOfXMMRegister(regop),
1944 NameOfXMMRegister(rm));
1946 }
else if (f0byte == 0x10 || f0byte == 0x11) {
1950 AppendToBuffer(
"movups ");
1951 if (f0byte == 0x11) {
1952 data += PrintRightXMMOperand(data);
1953 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
1955 AppendToBuffer(
"%s,", NameOfXMMRegister(regop));
1956 data += PrintRightXMMOperand(data);
1958 }
else if (f0byte == 0x2E) {
1960 AppendToBuffer(
"ucomiss %s,", NameOfXMMRegister(regop));
1961 data += PrintRightXMMOperand(data);
1962 }
else if (f0byte >= 0x51 && f0byte <= 0x5F) {
1963 const char*
const pseudo_op[] = {
1964 "sqrtps",
"rsqrtps",
"rcpps",
"andps",
"andnps",
1965 "orps",
"xorps",
"addps",
"mulps",
"cvtps2pd",
1966 "cvtdq2ps",
"subps",
"minps",
"divps",
"maxps",
1970 AppendToBuffer(
"%s %s,", pseudo_op[f0byte - 0x51],
1971 NameOfXMMRegister(regop));
1972 data += PrintRightXMMOperand(data);
1973 }
else if (f0byte == 0x50) {
1975 AppendToBuffer(
"movmskps %s,%s", NameOfCPURegister(regop),
1976 NameOfXMMRegister(rm));
1978 }
else if (f0byte == 0xC0) {
1980 data += PrintOperands(
"xadd_b", OPER_REG_OP_ORDER, data);
1981 }
else if (f0byte == 0xC1) {
1983 data += PrintOperands(
"xadd", OPER_REG_OP_ORDER, data);
1984 }
else if (f0byte == 0xC2) {
1986 AppendToBuffer(
"cmpps %s, ", NameOfXMMRegister(regop));
1987 data += PrintRightXMMOperand(data);
1988 AppendToBuffer(
", (%s)", cmp_pseudo_op[*data]);
1990 }
else if (f0byte == 0xC6) {
1993 int8_t imm8 =
static_cast<int8_t
>(data[1]);
1994 AppendToBuffer(
"shufps %s,%s,%d", NameOfXMMRegister(rm),
1995 NameOfXMMRegister(regop),
static_cast<int>(imm8));
1997 }
else if (f0byte >= 0xC8 && f0byte <= 0xCF) {
2000 int reg = f0byte - 0xC8;
2001 AppendToBuffer(
"bswap %s", NameOfCPURegister(
reg));
2002 }
else if ((f0byte & 0xF0) == 0x80) {
2003 data += JumpConditional(data, branch_hint);
2004 }
else if (f0byte == 0xBE || f0byte == 0xBF || f0byte == 0xB6 ||
2005 f0byte == 0xB7 || f0byte == 0xAF) {
2007 data += PrintOperands(f0mnem, REG_OPER_OP_ORDER, data);
2008 }
else if ((f0byte & 0xF0) == 0x90) {
2009 data +=
SetCC(data);
2010 }
else if ((f0byte & 0xF0) == 0x40) {
2012 }
else if (f0byte == 0xA4 || f0byte == 0xAC) {
2015 AppendToBuffer(
"%s ", f0mnem);
2016 int8_t imm8 =
static_cast<int8_t
>(data[1]);
2018 AppendToBuffer(
"%s,%s,%d", NameOfCPURegister(rm),
2019 NameOfCPURegister(regop),
static_cast<int>(imm8));
2020 }
else if (f0byte == 0xAB || f0byte == 0xA5 || f0byte == 0xAD) {
2023 AppendToBuffer(
"%s ", f0mnem);
2024 data += PrintRightOperand(data);
2025 if (f0byte == 0xAB) {
2026 AppendToBuffer(
",%s", NameOfCPURegister(regop));
2028 AppendToBuffer(
",%s,cl", NameOfCPURegister(regop));
2030 }
else if (f0byte == 0xB0) {
2033 AppendToBuffer(
"%s ", f0mnem);
2034 data += PrintRightOperand(data);
2035 AppendToBuffer(
",%s", NameOfByteCPURegister(regop));
2036 }
else if (f0byte == 0xB1) {
2039 data += PrintOperands(f0mnem, OPER_REG_OP_ORDER, data);
2040 }
else if (f0byte == 0xBC) {
2042 AppendToBuffer(
"%s %s,", f0mnem, NameOfCPURegister(regop));
2043 data += PrintRightOperand(data);
2044 }
else if (f0byte == 0xBD) {
2046 AppendToBuffer(
"%s %s,", f0mnem, NameOfCPURegister(regop));
2047 data += PrintRightOperand(data);
2048 }
else if (f0byte == 0xC7) {
2051 AppendToBuffer(
"%s ", f0mnem);
2052 data += PrintRightOperand(data);
2053 }
else if (f0byte == 0xAE && (data[2] & 0xF8) == 0xF0) {
2054 AppendToBuffer(
"mfence");
2056 }
else if (f0byte == 0xAE && (data[2] & 0xF8) == 0xE8) {
2057 AppendToBuffer(
"lfence");
2060 UnimplementedInstruction();
2068 get_modrm(*data, &mod, ®op, &rm);
2070 AppendToBuffer(
"pop ");
2071 data += PrintRightOperand(data);
2078 get_modrm(*data, &mod, ®op, &rm);
2079 const char* mnem =
"";
2099 AppendToBuffer(
"%s ", mnem);
2100 data += PrintRightOperand(data);
2106 bool is_byte = *data == 0xC6;
2109 AppendToBuffer(
"%s ",
"mov_b");
2110 data += PrintRightByteOperand(data);
2112 AppendToBuffer(
",0x%x", imm);
2115 AppendToBuffer(
"%s ",
"mov");
2116 data += PrintRightOperand(data);
2117 AppendToBuffer(
",0x%x", Imm32(data));
2125 get_modrm(*data, &mod, ®op, &rm);
2126 const char* mnem =
"";
2135 UnimplementedInstruction();
2137 AppendToBuffer(
"%s ", mnem);
2138 data += PrintRightByteOperand(data);
2140 AppendToBuffer(
",0x%x", imm);
2147 bool is_byte = *data == 0x88;
2150 get_modrm(*data, &mod, ®op, &rm);
2152 AppendToBuffer(
"%s ",
"mov_b");
2153 data += PrintRightByteOperand(data);
2154 AppendToBuffer(
",%s", NameOfByteCPURegister(regop));
2156 AppendToBuffer(
"%s ",
"mov");
2157 data += PrintRightOperand(data);
2158 AppendToBuffer(
",%s", NameOfCPURegister(regop));
2163 while (*data == 0x66) data++;
2164 if (*data == 0xF && data[1] == 0x1F) {
2165 AppendToBuffer(
"nop");
2166 }
else if (*data == 0x39) {
2168 data += PrintOperands(
"cmpw", OPER_REG_OP_ORDER, data);
2169 }
else if (*data == 0x3B) {
2171 data += PrintOperands(
"cmpw", REG_OPER_OP_ORDER, data);
2172 }
else if (*data == 0x81) {
2174 AppendToBuffer(
"cmpw ");
2175 data += PrintRightOperand(data);
2176 AppendToBuffer(
",0x%x", Imm16(data));
2178 }
else if (*data == 0x87) {
2181 get_modrm(*data, &mod, ®op, &rm);
2182 AppendToBuffer(
"xchg_w %s,", NameOfCPURegister(regop));
2183 data += PrintRightOperand(data);
2184 }
else if (*data == 0x89) {
2187 get_modrm(*data, &mod, ®op, &rm);
2188 AppendToBuffer(
"mov_w ");
2189 data += PrintRightOperand(data);
2190 AppendToBuffer(
",%s", NameOfCPURegister(regop));
2191 }
else if (*data == 0x8B) {
2193 data += PrintOperands(
"mov_w", REG_OPER_OP_ORDER, data);
2194 }
else if (*data == 0x90) {
2195 AppendToBuffer(
"nop");
2196 }
else if (*data == 0xC7) {
2198 AppendToBuffer(
"%s ",
"mov_w");
2199 data += PrintRightOperand(data);
2200 AppendToBuffer(
",0x%x", Imm16(data));
2202 }
else if (*data == 0xF7) {
2204 AppendToBuffer(
"%s ",
"test_w");
2205 data += PrintRightOperand(data);
2206 AppendToBuffer(
",0x%x", Imm16(data));
2208 }
else if (*data == 0x0F) {
2210 if (*data == 0x10) {
2213 get_modrm(*data, &mod, ®op, &rm);
2214 AppendToBuffer(
"movupd %s,", NameOfXMMRegister(regop));
2215 data += PrintRightXMMOperand(data);
2216 }
else if (*data == 0x28) {
2219 get_modrm(*data, &mod, ®op, &rm);
2220 AppendToBuffer(
"movapd %s,", NameOfXMMRegister(regop));
2221 data += PrintRightXMMOperand(data);
2222 }
else if (*data == 0x38) {
2227 get_modrm(*data, &mod, ®op, &rm);
2229#define SSE34_DIS_CASE(instruction, notUsed1, notUsed2, notUsed3, opcode) \
2230 case 0x##opcode: { \
2231 AppendToBuffer(#instruction " %s,", NameOfXMMRegister(regop)); \
2232 data += PrintRightXMMOperand(data); \
2240#undef SSE34_DIS_CASE
2242 AppendToBuffer(
"pblendvb %s,", NameOfXMMRegister(regop));
2243 data += PrintRightXMMOperand(data);
2244 AppendToBuffer(
",xmm0");
2247 AppendToBuffer(
"blendvps %s,", NameOfXMMRegister(regop));
2248 data += PrintRightXMMOperand(data);
2249 AppendToBuffer(
",xmm0");
2252 AppendToBuffer(
"blendvps %s,", NameOfXMMRegister(regop));
2253 data += PrintRightXMMOperand(data);
2254 AppendToBuffer(
",xmm0");
2257 AppendToBuffer(
"pcmpgtq %s,", NameOfXMMRegister(regop));
2258 data += PrintRightXMMOperand(data);
2261 UnimplementedInstruction();
2263 }
else if (*data == 0x3A) {
2265 if (*data >= 0x08 && *data <= 0x0B) {
2266 const char*
const pseudo_op[] = {
2275 get_modrm(*data, &mod, ®op, &rm);
2276 int8_t imm8 =
static_cast<int8_t
>(data[1]);
2277 AppendToBuffer(
"%s %s,%s,%d", pseudo_op[op - 0x08],
2278 NameOfXMMRegister(regop), NameOfXMMRegister(rm),
2279 static_cast<int>(imm8));
2281 }
else if (*data == 0x0E) {
2284 get_modrm(*data, &mod, ®op, &rm);
2285 AppendToBuffer(
"pblendw %s,", NameOfXMMRegister(regop));
2286 data += PrintRightXMMOperand(data);
2287 AppendToBuffer(
",%d", Imm8_U(data));
2289 }
else if (*data == 0x0F) {
2292 get_modrm(*data, &mod, ®op, &rm);
2293 AppendToBuffer(
"palignr %s,", NameOfXMMRegister(regop));
2294 data += PrintRightXMMOperand(data);
2295 AppendToBuffer(
",%d", Imm8_U(data));
2297 }
else if (*data == 0x14) {
2300 get_modrm(*data, &mod, ®op, &rm);
2301 AppendToBuffer(
"pextrb ");
2302 data += PrintRightOperand(data);
2303 AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop), Imm8(data));
2305 }
else if (*data == 0x15) {
2308 get_modrm(*data, &mod, ®op, &rm);
2309 AppendToBuffer(
"pextrw ");
2310 data += PrintRightOperand(data);
2311 AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop), Imm8(data));
2313 }
else if (*data == 0x16) {
2316 get_modrm(*data, &mod, ®op, &rm);
2317 AppendToBuffer(
"pextrd ");
2318 data += PrintRightOperand(data);
2319 AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop), Imm8(data));
2321 }
else if (*data == 0x17) {
2324 get_modrm(*data, &mod, ®op, &rm);
2325 int8_t imm8 =
static_cast<int8_t
>(data[1]);
2326 AppendToBuffer(
"extractps %s,%s,%d", NameOfCPURegister(rm),
2327 NameOfXMMRegister(regop),
static_cast<int>(imm8));
2329 }
else if (*data == 0x20) {
2332 get_modrm(*data, &mod, ®op, &rm);
2333 AppendToBuffer(
"pinsrb %s,", NameOfXMMRegister(regop));
2334 data += PrintRightOperand(data);
2335 AppendToBuffer(
",%d", Imm8(data));
2337 }
else if (*data == 0x21) {
2340 get_modrm(*data, &mod, ®op, &rm);
2341 AppendToBuffer(
"insertps %s,", NameOfXMMRegister(regop));
2342 data += PrintRightXMMOperand(data);
2343 AppendToBuffer(
",%d", Imm8(data));
2345 }
else if (*data == 0x22) {
2348 get_modrm(*data, &mod, ®op, &rm);
2349 AppendToBuffer(
"pinsrd %s,", NameOfXMMRegister(regop));
2350 data += PrintRightOperand(data);
2351 AppendToBuffer(
",%d", Imm8(data));
2354 UnimplementedInstruction();
2356 }
else if (*data == 0x2E || *data == 0x2F) {
2357 const char* mnem = (*data == 0x2E) ?
"ucomisd" :
"comisd";
2360 get_modrm(*data, &mod, ®op, &rm);
2362 AppendToBuffer(
"%s %s,%s", mnem, NameOfXMMRegister(regop),
2363 NameOfXMMRegister(rm));
2366 AppendToBuffer(
"%s %s,", mnem, NameOfXMMRegister(regop));
2367 data += PrintRightOperand(data);
2369 }
else if (*data == 0x50) {
2372 get_modrm(*data, &mod, ®op, &rm);
2373 AppendToBuffer(
"movmskpd %s,%s", NameOfCPURegister(regop),
2374 NameOfXMMRegister(rm));
2376 }
else if (*data >= 0x54 && *data <= 0x5A) {
2377 const char*
const pseudo_op[] = {
"andpd",
"andnpd",
"orpd",
2378 "xorpd",
"addpd",
"mulpd",
2383 get_modrm(*data, &mod, ®op, &rm);
2384 AppendToBuffer(
"%s %s,", pseudo_op[op - 0x54],
2385 NameOfXMMRegister(regop));
2386 data += PrintRightXMMOperand(data);
2387 }
else if (*data >= 0x5c && *data <= 0x5f) {
2388 const char*
const pseudo_op[] = {
2397 get_modrm(*data, &mod, ®op, &rm);
2398 AppendToBuffer(
"%s %s,", pseudo_op[op - 0x5c],
2399 NameOfXMMRegister(regop));
2400 data += PrintRightXMMOperand(data);
2401 }
else if (*data == 0x6E) {
2404 get_modrm(*data, &mod, ®op, &rm);
2405 AppendToBuffer(
"movd %s,", NameOfXMMRegister(regop));
2406 data += PrintRightOperand(data);
2407 }
else if (*data == 0x6F) {
2410 get_modrm(*data, &mod, ®op, &rm);
2411 AppendToBuffer(
"movdqa %s,", NameOfXMMRegister(regop));
2412 data += PrintRightXMMOperand(data);
2413 }
else if (*data == 0x70) {
2416 get_modrm(*data, &mod, ®op, &rm);
2417 AppendToBuffer(
"pshufd %s,", NameOfXMMRegister(regop));
2418 data += PrintRightXMMOperand(data);
2419 AppendToBuffer(
",%d", Imm8(data));
2421 }
else if (*data == 0x90) {
2423 AppendToBuffer(
"nop");
2424 }
else if (*data == 0x71) {
2427 get_modrm(*data, &mod, ®op, &rm);
2428 int8_t imm8 =
static_cast<int8_t
>(data[1]);
2429 AppendToBuffer(
"ps%sw %s,%d", sf_str[regop / 2],
2430 NameOfXMMRegister(rm),
static_cast<int>(imm8));
2432 }
else if (*data == 0x72) {
2435 get_modrm(*data, &mod, ®op, &rm);
2436 int8_t imm8 =
static_cast<int8_t
>(data[1]);
2437 AppendToBuffer(
"ps%sd %s,%d", sf_str[regop / 2],
2438 NameOfXMMRegister(rm),
static_cast<int>(imm8));
2440 }
else if (*data == 0x73) {
2443 get_modrm(*data, &mod, ®op, &rm);
2444 int8_t imm8 =
static_cast<int8_t
>(data[1]);
2445 DCHECK(regop == esi || regop == edx);
2446 AppendToBuffer(
"ps%sq %s,%d", sf_str[regop / 2],
2447 NameOfXMMRegister(rm),
static_cast<int>(imm8));
2449 }
else if (*data == 0x7F) {
2450 AppendToBuffer(
"movdqa ");
2453 get_modrm(*data, &mod, ®op, &rm);
2454 data += PrintRightXMMOperand(data);
2455 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
2456 }
else if (*data == 0x7E) {
2459 get_modrm(*data, &mod, ®op, &rm);
2460 AppendToBuffer(
"movd ");
2461 data += PrintRightOperand(data);
2462 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
2463 }
else if (*data == 0xC1) {
2465 data += PrintOperands(
"xadd_w", OPER_REG_OP_ORDER, data);
2466 }
else if (*data == 0xC2) {
2469 get_modrm(*data, &mod, ®op, &rm);
2470 AppendToBuffer(
"cmppd %s, ", NameOfXMMRegister(regop));
2471 data += PrintRightXMMOperand(data);
2472 AppendToBuffer(
", (%s)", cmp_pseudo_op[*data]);
2474 }
else if (*data == 0xC4) {
2477 get_modrm(*data, &mod, ®op, &rm);
2478 AppendToBuffer(
"pinsrw %s,", NameOfXMMRegister(regop));
2479 data += PrintRightOperand(data);
2480 AppendToBuffer(
",%d", Imm8(data));
2482 }
else if (*data == 0xC6) {
2486 get_modrm(*data, &mod, ®op, &rm);
2487 AppendToBuffer(
"shufpd %s,", NameOfXMMRegister(regop));
2488 data += PrintRightXMMOperand(data);
2489 AppendToBuffer(
",%d", Imm8(data));
2491 }
else if (*data == 0xE6) {
2494 get_modrm(*data, &mod, ®op, &rm);
2495 AppendToBuffer(
"cvttpd2dq %s,", NameOfXMMRegister(regop));
2496 data += PrintRightXMMOperand(data);
2497 }
else if (*data == 0xE7) {
2500 get_modrm(*data, &mod, ®op, &rm);
2503 UnimplementedInstruction();
2505 UnimplementedInstruction();
2507 }
else if (*data == 0xB1) {
2509 data += PrintOperands(
"cmpxchg_w", OPER_REG_OP_ORDER, data);
2510 }
else if (*data == 0xD7) {
2513 get_modrm(*data, &mod, ®op, &rm);
2514 AppendToBuffer(
"pmovmskb %s,%s", NameOfCPURegister(regop),
2515 NameOfXMMRegister(rm));
2521 get_modrm(*data, &mod, ®op, &rm);
2523#define SSE2_DIS_CASE(instruction, notUsed1, notUsed2, opcode) \
2524 case 0x##opcode: { \
2525 AppendToBuffer(#instruction " %s,", NameOfXMMRegister(regop)); \
2526 data += PrintRightXMMOperand(data); \
2533 UnimplementedInstruction();
2537 UnimplementedInstruction();
2544 get_modrm(*data, &mod, ®op, &rm);
2546 AppendToBuffer(
"dec_b ");
2547 data += PrintRightOperand(data);
2549 UnimplementedInstruction();
2554 AppendToBuffer(
"push 0x%x", Imm32(data + 1));
2559 AppendToBuffer(
"push 0x%x", Imm8(data + 1));
2564 AppendToBuffer(
"test al,0x%x", Imm8_U(data + 1));
2569 AppendToBuffer(
"test eax,0x%x", Imm32(data + 1));
2576 data += D1D3C1Instruction(data);
2587 data += FPUInstruction(data);
2591 data += JumpShort(data);
2595 if (*(data + 1) == 0x0F) {
2596 uint8_t b2 = *(data + 2);
2598 AppendToBuffer(
"movsd ");
2601 get_modrm(*data, &mod, ®op, &rm);
2602 data += PrintRightXMMOperand(data);
2603 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
2604 }
else if (b2 == 0x10) {
2607 get_modrm(*data, &mod, ®op, &rm);
2608 AppendToBuffer(
"movsd %s,", NameOfXMMRegister(regop));
2609 data += PrintRightXMMOperand(data);
2610 }
else if (b2 == 0x12) {
2613 get_modrm(*data, &mod, ®op, &rm);
2614 AppendToBuffer(
"movddup %s,", NameOfXMMRegister(regop));
2615 data += PrintRightXMMOperand(data);
2616 }
else if (b2 == 0x5A) {
2619 get_modrm(*data, &mod, ®op, &rm);
2620 AppendToBuffer(
"cvtsd2ss %s,", NameOfXMMRegister(regop));
2621 data += PrintRightXMMOperand(data);
2622 }
else if (b2 == 0x70) {
2625 get_modrm(*data, &mod, ®op, &rm);
2626 AppendToBuffer(
"pshuflw %s,", NameOfXMMRegister(regop));
2627 data += PrintRightXMMOperand(data);
2628 AppendToBuffer(
",%d", Imm8(data));
2631 const char* mnem =
"?";
2645#define MNEM_FOR_SSE2_INSTRUCTION_LSIT_SD(instruction, _1, _2, opcode) \
2647 mnem = "" #instruction; \
2650#undef MNEM_FOR_SSE2_INSTRUCTION_LSIT_SD
2654 get_modrm(*data, &mod, ®op, &rm);
2656 AppendToBuffer(
"%s %s,", mnem, NameOfXMMRegister(regop));
2657 data += PrintRightOperand(data);
2658 }
else if (b2 == 0x2C || b2 == 0x2D) {
2659 AppendToBuffer(
"%s %s,", mnem, NameOfCPURegister(regop));
2660 data += PrintRightXMMOperand(data);
2661 }
else if (b2 == 0xC2) {
2663 AppendToBuffer(
"cmp%ssd %s,%s", cmp_pseudo_op[data[1]],
2664 NameOfXMMRegister(regop), NameOfXMMRegister(rm));
2667 AppendToBuffer(
"%s %s,", mnem, NameOfXMMRegister(regop));
2668 data += PrintRightXMMOperand(data);
2672 UnimplementedInstruction();
2678 if (*(data + 1) == 0x0F) {
2679 uint8_t b2 = *(data + 2);
2681 AppendToBuffer(
"movss ");
2684 get_modrm(*data, &mod, ®op, &rm);
2685 data += PrintRightXMMOperand(data);
2686 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
2687 }
else if (b2 == 0x10) {
2690 get_modrm(*data, &mod, ®op, &rm);
2691 AppendToBuffer(
"movss %s,", NameOfXMMRegister(regop));
2692 data += PrintRightXMMOperand(data);
2693 }
else if (b2 == 0x16) {
2696 get_modrm(*data, &mod, ®op, &rm);
2697 AppendToBuffer(
"movshdup %s,", NameOfXMMRegister(regop));
2698 data += PrintRightXMMOperand(data);
2699 }
else if (b2 == 0x5A) {
2702 get_modrm(*data, &mod, ®op, &rm);
2703 AppendToBuffer(
"cvtss2sd %s,", NameOfXMMRegister(regop));
2704 data += PrintRightXMMOperand(data);
2705 }
else if (b2 == 0x6F) {
2708 get_modrm(*data, &mod, ®op, &rm);
2709 AppendToBuffer(
"movdqu %s,", NameOfXMMRegister(regop));
2710 data += PrintRightXMMOperand(data);
2711 }
else if (b2 == 0x70) {
2714 get_modrm(*data, &mod, ®op, &rm);
2715 AppendToBuffer(
"pshufhw %s,", NameOfXMMRegister(regop));
2716 data += PrintRightXMMOperand(data);
2717 AppendToBuffer(
",%d", Imm8(data));
2719 }
else if (b2 == 0x7F) {
2720 AppendToBuffer(
"movdqu ");
2723 get_modrm(*data, &mod, ®op, &rm);
2724 data += PrintRightXMMOperand(data);
2725 AppendToBuffer(
",%s", NameOfXMMRegister(regop));
2726 }
else if (b2 == 0xB8) {
2729 get_modrm(*data, &mod, ®op, &rm);
2730 AppendToBuffer(
"popcnt %s,", NameOfCPURegister(regop));
2731 data += PrintRightOperand(data);
2732 }
else if (b2 == 0xBC) {
2735 get_modrm(*data, &mod, ®op, &rm);
2736 AppendToBuffer(
"tzcnt %s,", NameOfCPURegister(regop));
2737 data += PrintRightOperand(data);
2738 }
else if (b2 == 0xBD) {
2741 get_modrm(*data, &mod, ®op, &rm);
2742 AppendToBuffer(
"lzcnt %s,", NameOfCPURegister(regop));
2743 data += PrintRightOperand(data);
2744 }
else if (b2 == 0xE6) {
2747 get_modrm(*data, &mod, ®op, &rm);
2748 AppendToBuffer(
"cvtdq2pd %s", NameOfXMMRegister(regop));
2749 data += PrintRightXMMOperand(data);
2751 const char* mnem =
"?";
2792 get_modrm(*data, &mod, ®op, &rm);
2794 AppendToBuffer(
"%s %s,", mnem, NameOfXMMRegister(regop));
2795 data += PrintRightOperand(data);
2796 }
else if (b2 == 0x2C || b2 == 0x2D) {
2797 AppendToBuffer(
"%s %s,", mnem, NameOfCPURegister(regop));
2798 data += PrintRightXMMOperand(data);
2799 }
else if (b2 == 0xC2) {
2801 AppendToBuffer(
"cmp%sss %s,%s", cmp_pseudo_op[data[1]],
2802 NameOfXMMRegister(regop), NameOfXMMRegister(rm));
2805 AppendToBuffer(
"%s %s,", mnem, NameOfXMMRegister(regop));
2806 data += PrintRightXMMOperand(data);
2809 }
else if (*(data + 1) == 0xA5) {
2811 AppendToBuffer(
"rep_movs");
2812 }
else if (*(data + 1) == 0xAB) {
2814 AppendToBuffer(
"rep_stos");
2815 }
else if (*(data + 1) == 0x90) {
2817 AppendToBuffer(
"pause");
2819 UnimplementedInstruction();
2824 data += F7Instruction(data);
2828 UnimplementedInstruction();
2833 if (tmp_buffer_pos_ <
sizeof tmp_buffer_) {
2834 tmp_buffer_[tmp_buffer_pos_] =
'\0';
2837 int instr_len = data -
instr;
2838 if (instr_len == 0) {
2839 printf(
"%02x", *data);
2845 for (uint8_t* bp =
instr; bp <
data; bp++) {
2859static const char*
const cpu_regs[8] = {
"eax",
"ecx",
"edx",
"ebx",
2860 "esp",
"ebp",
"esi",
"edi"};
2862static const char*
const byte_cpu_regs[8] = {
"al",
"cl",
"dl",
"bl",
2863 "ah",
"ch",
"dh",
"bh"};
2865static const char*
const xmm_regs[8] = {
"xmm0",
"xmm1",
"xmm2",
"xmm3",
2866 "xmm4",
"xmm5",
"xmm6",
"xmm7"};
2878 if (0 <=
reg &&
reg < 8)
return cpu_regs[
reg];
2883 if (0 <=
reg &&
reg < 8)
return byte_cpu_regs[
reg];
2888 if (0 <=
reg &&
reg < 8)
return xmm_regs[
reg];
2900 uint8_t* instruction) {
2902 return d.InstructionDecode(buffer, instruction);
2910 UnimplementedOpcodeAction unimplemented_action) {
2911 NameConverter converter;
2913 for (uint8_t*
pc = begin;
pc <
end;) {
2916 uint8_t* prev_pc =
pc;
2917 pc += d.InstructionDecode(buffer,
pc);
2918 fprintf(f,
"%p",
static_cast<void*
>(prev_pc));
2921 for (uint8_t* bp = prev_pc; bp <
pc; bp++) {
2922 fprintf(f,
"%02x", *bp);
2924 for (
int i = 6 - (
pc - prev_pc);
i >= 0;
i--) {
2927 fprintf(f,
" %s\n", buffer.
begin());
interpreter::OperandScale scale
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
static V8_EXPORT_PRIVATE void Disassemble(FILE *f, uint8_t *begin, uint8_t *end, UnimplementedOpcodeAction unimplemented_action=kAbortOnUnimplementedOpcode)
V8_EXPORT_PRIVATE int InstructionDecode(v8::base::Vector< char > buffer, uint8_t *instruction)
int ConstantPoolSizeAt(uint8_t *instruction)
Disassembler(const NameConverter &converter, UnimplementedOpcodeAction unimplemented_opcode_action=kAbortOnUnimplementedOpcode)
UnimplementedOpcodeAction unimplemented_opcode_action() const
const NameConverter & converter_
virtual const char * NameOfAddress(uint8_t *addr) const
virtual const char * NameOfXMMRegister(int reg) const
virtual const char * NameInCode(uint8_t *addr) const
virtual const char * NameOfConstant(uint8_t *addr) const
v8::base::EmbeddedVector< char, 128 > tmp_buffer_
virtual const char * NameOfByteCPURegister(int reg) const
virtual const char * NameOfCPURegister(int reg) const
constexpr T * begin() const
base::Vector< const DirectHandle< Object > > args
#define FMA_SD_INSTRUCTION_LIST(V)
#define FMA_PD_INSTRUCTION_LIST(V)
#define FMA_SS_INSTRUCTION_LIST(V)
#define FMA_PS_INSTRUCTION_LIST(V)
#define SSSE3_UNOP_INSTRUCTION_LIST(V)
#define SSE4_INSTRUCTION_LIST(V)
#define SSE4_RM_INSTRUCTION_LIST(V)
#define SSE2_INSTRUCTION_LIST(V)
#define SSE2_INSTRUCTION_LIST_SD(V)
#define SSSE3_INSTRUCTION_LIST(V)
#define AVX2_BROADCAST_LIST(V)
ZoneVector< RpoNumber > & result
int SNPrintF(Vector< char > str, const char *format,...)
int VSNPrintF(Vector< char > str, const char *format, va_list args)
V8_INLINE const Operation & Get(const Graph &graph, OpIndex index)
#define PRINTF_FORMAT(format_param, dots_param)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)