34 #if V8_TARGET_ARCH_X64 
   44   REG_OPER_OP_ORDER = 1,  
 
   45   OPER_REG_OP_ORDER = 2,  
 
   47   BYTE_SIZE_OPERAND_FLAG = 4,
 
   48   BYTE_REG_OPER_OP_ORDER = REG_OPER_OP_ORDER | BYTE_SIZE_OPERAND_FLAG,
 
   49   BYTE_OPER_REG_OP_ORDER = OPER_REG_OP_ORDER | BYTE_SIZE_OPERAND_FLAG
 
   58   OperandType op_order_;
 
   63 static const ByteMnemonic two_operands_instr[] = {
 
   64   { 0x00, BYTE_OPER_REG_OP_ORDER, 
"add" },
 
   65   { 0x01, OPER_REG_OP_ORDER,      
"add" },
 
   66   { 0x02, BYTE_REG_OPER_OP_ORDER, 
"add" },
 
   67   { 0x03, REG_OPER_OP_ORDER,      
"add" },
 
   68   { 0x08, BYTE_OPER_REG_OP_ORDER, 
"or" },
 
   69   { 0x09, OPER_REG_OP_ORDER,      
"or" },
 
   70   { 0x0A, BYTE_REG_OPER_OP_ORDER, 
"or" },
 
   71   { 0x0B, REG_OPER_OP_ORDER,      
"or" },
 
   72   { 0x10, BYTE_OPER_REG_OP_ORDER, 
"adc" },
 
   73   { 0x11, OPER_REG_OP_ORDER,      
"adc" },
 
   74   { 0x12, BYTE_REG_OPER_OP_ORDER, 
"adc" },
 
   75   { 0x13, REG_OPER_OP_ORDER,      
"adc" },
 
   76   { 0x18, BYTE_OPER_REG_OP_ORDER, 
"sbb" },
 
   77   { 0x19, OPER_REG_OP_ORDER,      
"sbb" },
 
   78   { 0x1A, BYTE_REG_OPER_OP_ORDER, 
"sbb" },
 
   79   { 0x1B, REG_OPER_OP_ORDER,      
"sbb" },
 
   80   { 0x20, BYTE_OPER_REG_OP_ORDER, 
"and" },
 
   81   { 0x21, OPER_REG_OP_ORDER,      
"and" },
 
   82   { 0x22, BYTE_REG_OPER_OP_ORDER, 
"and" },
 
   83   { 0x23, REG_OPER_OP_ORDER,      
"and" },
 
   84   { 0x28, BYTE_OPER_REG_OP_ORDER, 
"sub" },
 
   85   { 0x29, OPER_REG_OP_ORDER,      
"sub" },
 
   86   { 0x2A, BYTE_REG_OPER_OP_ORDER, 
"sub" },
 
   87   { 0x2B, REG_OPER_OP_ORDER,      
"sub" },
 
   88   { 0x30, BYTE_OPER_REG_OP_ORDER, 
"xor" },
 
   89   { 0x31, OPER_REG_OP_ORDER,      
"xor" },
 
   90   { 0x32, BYTE_REG_OPER_OP_ORDER, 
"xor" },
 
   91   { 0x33, REG_OPER_OP_ORDER,      
"xor" },
 
   92   { 0x38, BYTE_OPER_REG_OP_ORDER, 
"cmp" },
 
   93   { 0x39, OPER_REG_OP_ORDER,      
"cmp" },
 
   94   { 0x3A, BYTE_REG_OPER_OP_ORDER, 
"cmp" },
 
   95   { 0x3B, REG_OPER_OP_ORDER,      
"cmp" },
 
   96   { 0x63, REG_OPER_OP_ORDER,      
"movsxl" },
 
   97   { 0x84, BYTE_REG_OPER_OP_ORDER, 
"test" },
 
   98   { 0x85, REG_OPER_OP_ORDER,      
"test" },
 
   99   { 0x86, BYTE_REG_OPER_OP_ORDER, 
"xchg" },
 
  100   { 0x87, REG_OPER_OP_ORDER,      
"xchg" },
 
  101   { 0x88, BYTE_OPER_REG_OP_ORDER, 
"mov" },
 
  102   { 0x89, OPER_REG_OP_ORDER,      
"mov" },
 
  103   { 0x8A, BYTE_REG_OPER_OP_ORDER, 
"mov" },
 
  104   { 0x8B, REG_OPER_OP_ORDER,      
"mov" },
 
  105   { 0x8D, REG_OPER_OP_ORDER,      
"lea" },
 
  106   { -1, UNSET_OP_ORDER, 
"" }
 
  110 static const ByteMnemonic zero_operands_instr[] = {
 
  111   { 0xC3, UNSET_OP_ORDER, 
"ret" },
 
  112   { 0xC9, UNSET_OP_ORDER, 
"leave" },
 
  113   { 0xF4, UNSET_OP_ORDER, 
"hlt" },
 
  114   { 0xFC, UNSET_OP_ORDER, 
"cld" },
 
  115   { 0xCC, UNSET_OP_ORDER, 
"int3" },
 
  116   { 0x60, UNSET_OP_ORDER, 
"pushad" },
 
  117   { 0x61, UNSET_OP_ORDER, 
"popad" },
 
  118   { 0x9C, UNSET_OP_ORDER, 
"pushfd" },
 
  119   { 0x9D, UNSET_OP_ORDER, 
"popfd" },
 
  120   { 0x9E, UNSET_OP_ORDER, 
"sahf" },
 
  121   { 0x99, UNSET_OP_ORDER, 
"cdq" },
 
  122   { 0x9B, UNSET_OP_ORDER, 
"fwait" },
 
  123   { 0xA4, UNSET_OP_ORDER, 
"movs" },
 
  124   { 0xA5, UNSET_OP_ORDER, 
"movs" },
 
  125   { 0xA6, UNSET_OP_ORDER, 
"cmps" },
 
  126   { 0xA7, UNSET_OP_ORDER, 
"cmps" },
 
  127   { -1, UNSET_OP_ORDER, 
"" }
 
  131 static const ByteMnemonic call_jump_instr[] = {
 
  132   { 0xE8, UNSET_OP_ORDER, 
"call" },
 
  133   { 0xE9, UNSET_OP_ORDER, 
"jmp" },
 
  134   { -1, UNSET_OP_ORDER, 
"" }
 
  138 static const ByteMnemonic short_immediate_instr[] = {
 
  139   { 0x05, UNSET_OP_ORDER, 
"add" },
 
  140   { 0x0D, UNSET_OP_ORDER, 
"or" },
 
  141   { 0x15, UNSET_OP_ORDER, 
"adc" },
 
  142   { 0x1D, UNSET_OP_ORDER, 
"sbb" },
 
  143   { 0x25, UNSET_OP_ORDER, 
"and" },
 
  144   { 0x2D, UNSET_OP_ORDER, 
"sub" },
 
  145   { 0x35, UNSET_OP_ORDER, 
"xor" },
 
  146   { 0x3D, UNSET_OP_ORDER, 
"cmp" },
 
  147   { -1, UNSET_OP_ORDER, 
"" }
 
  151 static const char* 
const conditional_code_suffix[] = {
 
  152   "o", 
"no", 
"c", 
"nc", 
"z", 
"nz", 
"na", 
"a",
 
  153   "s", 
"ns", 
"pe", 
"po", 
"l", 
"ge", 
"le", 
"g" 
  157 enum InstructionType {
 
  161   JUMP_CONDITIONAL_SHORT_INSTR,
 
  166   SHORT_IMMEDIATE_INSTR
 
  171   ESCAPE_PREFIX = 0x0F,
 
  172   OPERAND_SIZE_OVERRIDE_PREFIX = 0x66,
 
  173   ADDRESS_SIZE_OVERRIDE_PREFIX = 0x67,
 
  176   REPEQ_PREFIX = REP_PREFIX
 
  180 struct InstructionDesc {
 
  182   InstructionType type;
 
  183   OperandType op_order_;
 
  184   bool byte_size_operation;  
 
  188 class InstructionTable {
 
  191   const InstructionDesc& Get(
byte x)
 const {
 
  192     return instructions_[x];
 
  196   InstructionDesc instructions_[256];
 
  199   void CopyTable(
const ByteMnemonic bm[], InstructionType type);
 
  200   void SetTableRange(InstructionType type, 
byte start, 
byte end, 
bool byte_size,
 
  202   void AddJumpConditionalShort();
 
  206 InstructionTable::InstructionTable() {
 
  212 void InstructionTable::Clear() {
 
  213   for (
int i = 0; i < 256; i++) {
 
  214     instructions_[i].mnem = 
"(bad)";
 
  215     instructions_[i].type = NO_INSTR;
 
  216     instructions_[i].op_order_ = UNSET_OP_ORDER;
 
  217     instructions_[i].byte_size_operation = 
false;
 
  222 void InstructionTable::Init() {
 
  223   CopyTable(two_operands_instr, TWO_OPERANDS_INSTR);
 
  224   CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR);
 
  225   CopyTable(call_jump_instr, CALL_JUMP_INSTR);
 
  226   CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
 
  227   AddJumpConditionalShort();
 
  228   SetTableRange(PUSHPOP_INSTR, 0x50, 0x57, 
false, 
"push");
 
  229   SetTableRange(PUSHPOP_INSTR, 0x58, 0x5F, 
false, 
"pop");
 
  230   SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, 
false, 
"mov");
 
  234 void InstructionTable::CopyTable(
const ByteMnemonic bm[],
 
  235                                  InstructionType type) {
 
  236   for (
int i = 0; bm[i].b >= 0; i++) {
 
  237     InstructionDesc* 
id = &instructions_[bm[i].b];
 
  238     id->mnem = bm[i].mnem;
 
  239     OperandType op_order = bm[i].op_order_;
 
  241         static_cast<OperandType
>(op_order & ~BYTE_SIZE_OPERAND_FLAG);
 
  244     id->byte_size_operation = ((op_order & BYTE_SIZE_OPERAND_FLAG) != 0);
 
  249 void InstructionTable::SetTableRange(InstructionType type,
 
  254   for (
byte b = start; b <= end; b++) {
 
  255     InstructionDesc* 
id = &instructions_[b];
 
  259     id->byte_size_operation = byte_size;
 
  264 void InstructionTable::AddJumpConditionalShort() {
 
  265   for (
byte b = 0x70; b <= 0x7F; b++) {
 
  266     InstructionDesc* 
id = &instructions_[b];
 
  269     id->type = JUMP_CONDITIONAL_SHORT_INSTR;
 
  278 static InstructionDesc cmov_instructions[16] = {
 
  279   {
"cmovo", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  280   {
"cmovno", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  281   {
"cmovc", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  282   {
"cmovnc", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  283   {
"cmovz", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  284   {
"cmovnz", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  285   {
"cmovna", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  286   {
"cmova", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  287   {
"cmovs", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  288   {
"cmovns", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  289   {
"cmovpe", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  290   {
"cmovpo", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  291   {
"cmovl", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  292   {
"cmovge", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  293   {
"cmovle", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false},
 
  294   {
"cmovg", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, 
false}
 
  301 enum UnimplementedOpcodeAction {
 
  302   CONTINUE_ON_UNIMPLEMENTED_OPCODE,
 
  303   ABORT_ON_UNIMPLEMENTED_OPCODE
 
  309 class DisassemblerX64 {
 
  311   DisassemblerX64(
const NameConverter& converter,
 
  312                   UnimplementedOpcodeAction unimplemented_action =
 
  313                       ABORT_ON_UNIMPLEMENTED_OPCODE)
 
  314       : converter_(converter),
 
  316         abort_on_unimplemented_(
 
  317             unimplemented_action == ABORT_ON_UNIMPLEMENTED_OPCODE),
 
  321         byte_size_operand_(
false),
 
  322         instruction_table_(instruction_table.Pointer()) {
 
  323     tmp_buffer_[0] = 
'\0';
 
  326   virtual ~DisassemblerX64() {
 
  335     OPERAND_BYTE_SIZE = 0,
 
  336     OPERAND_WORD_SIZE = 1,
 
  337     OPERAND_DOUBLEWORD_SIZE = 2,
 
  338     OPERAND_QUADWORD_SIZE = 3
 
  341   const NameConverter& converter_;
 
  343   unsigned int tmp_buffer_pos_;
 
  344   bool abort_on_unimplemented_;
 
  348   byte group_1_prefix_;  
 
  350   bool byte_size_operand_;
 
  351   const InstructionTable* 
const instruction_table_;
 
  353   void setRex(
byte rex) {
 
  358   bool rex() { 
return rex_ != 0; }
 
  360   bool rex_b() { 
return (rex_ & 0x01) != 0; }
 
  363   int base_reg(
int low_bits) { 
return low_bits | ((rex_ & 0x01) << 3); }
 
  365   bool rex_x() { 
return (rex_ & 0x02) != 0; }
 
  367   bool rex_r() { 
return (rex_ & 0x04) != 0; }
 
  369   bool rex_w() { 
return (rex_ & 0x08) != 0; }
 
  371   OperandSize operand_size() {
 
  372     if (byte_size_operand_) 
return OPERAND_BYTE_SIZE;
 
  373     if (rex_w()) 
return OPERAND_QUADWORD_SIZE;
 
  374     if (operand_size_ != 0) 
return OPERAND_WORD_SIZE;
 
  375     return OPERAND_DOUBLEWORD_SIZE;
 
  378   char operand_size_code() {
 
  379     return "bwlq"[operand_size()];
 
  382   const char* NameOfCPURegister(
int reg)
 const {
 
  383     return converter_.NameOfCPURegister(reg);
 
  386   const char* NameOfByteCPURegister(
int reg)
 const {
 
  387     return converter_.NameOfByteCPURegister(reg);
 
  390   const char* NameOfXMMRegister(
int reg)
 const {
 
  391     return converter_.NameOfXMMRegister(reg);
 
  394   const char* NameOfAddress(
byte* addr)
 const {
 
  395     return converter_.NameOfAddress(addr);
 
  399   void get_modrm(
byte data,
 
  403     *mod = (data >> 6) & 3;
 
  404     *regop = ((data & 0x38) >> 3) | (rex_r() ? 8 : 0);
 
  405     *rm = (data & 7) | (rex_b() ? 8 : 0);
 
  408   void get_sib(
byte data,
 
  412     *scale = (data >> 6) & 3;
 
  413     *index = ((data >> 3) & 7) | (rex_x() ? 8 : 0);
 
  414     *base = (data & 7) | (rex_b() ? 8 : 0);
 
  417   typedef const char* (DisassemblerX64::*RegisterNameMapping)(
int reg) 
const;
 
  419   int PrintRightOperandHelper(
byte* modrmp,
 
  420                               RegisterNameMapping register_name);
 
  421   int PrintRightOperand(
byte* modrmp);
 
  422   int PrintRightByteOperand(
byte* modrmp);
 
  423   int PrintRightXMMOperand(
byte* modrmp);
 
  424   int PrintOperands(
const char* mnem,
 
  425                     OperandType op_order,
 
  427   int PrintImmediate(
byte* data, OperandSize 
size);
 
  428   int PrintImmediateOp(
byte* data);
 
  429   const char* TwoByteMnemonic(
byte opcode);
 
  430   int TwoByteOpcodeInstruction(
byte* data);
 
  431   int F6F7Instruction(
byte* data);
 
  432   int ShiftInstruction(
byte* data);
 
  433   int JumpShort(
byte* data);
 
  434   int JumpConditional(
byte* data);
 
  435   int JumpConditionalShort(
byte* data);
 
  437   int FPUInstruction(
byte* data);
 
  438   int MemoryFPUInstruction(
int escape_opcode, 
int regop, 
byte* modrm_start);
 
  439   int RegisterFPUInstruction(
int escape_opcode, 
byte modrm_byte);
 
  440   void AppendToBuffer(
const char* format, ...);
 
  442   void UnimplementedInstruction() {
 
  443     if (abort_on_unimplemented_) {
 
  446       AppendToBuffer(
"'Unimplemented Instruction'");
 
  452 void DisassemblerX64::AppendToBuffer(
const char* format, ...) {
 
  455   va_start(args, format);
 
  458   tmp_buffer_pos_ += result;
 
  462 int DisassemblerX64::PrintRightOperandHelper(
 
  464     RegisterNameMapping direct_register_name) {
 
  466   get_modrm(*modrmp, &mod, ®op, &rm);
 
  467   RegisterNameMapping register_name = (mod == 3) ? direct_register_name :
 
  468       &DisassemblerX64::NameOfCPURegister;
 
  473         AppendToBuffer(
"[0x%x]", disp);
 
  475       } 
else if ((rm & 7) == 4) {
 
  477         byte sib = *(modrmp + 1);
 
  478         int scale, index, base;
 
  479         get_sib(sib, &scale, &index, &base);
 
  480         if (index == 4 && (base & 7) == 4 && scale == 0 ) {
 
  483           AppendToBuffer(
"[%s]", NameOfCPURegister(base));
 
  485         } 
else if (base == 5) {
 
  488           AppendToBuffer(
"[%s*%d%s0x%x]",
 
  489                          NameOfCPURegister(index),
 
  491                          disp < 0 ? 
"-" : 
"+",
 
  492                          disp < 0 ? -disp : disp);
 
  494         } 
else if (index != 4 && base != 5) {
 
  496           AppendToBuffer(
"[%s+%s*%d]",
 
  497                          NameOfCPURegister(base),
 
  498                          NameOfCPURegister(index),
 
  502           UnimplementedInstruction();
 
  506         AppendToBuffer(
"[%s]", NameOfCPURegister(rm));
 
  513         byte sib = *(modrmp + 1);
 
  514         int scale, index, base;
 
  515         get_sib(sib, &scale, &index, &base);
 
  516         int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2)
 
  517                               : *
reinterpret_cast<int8_t*
>(modrmp + 2);
 
  518         if (index == 4 && (base & 7) == 4 && scale == 0 ) {
 
  519           AppendToBuffer(
"[%s%s0x%x]",
 
  520                          NameOfCPURegister(base),
 
  521                          disp < 0 ? 
"-" : 
"+",
 
  522                          disp < 0 ? -disp : disp);
 
  524           AppendToBuffer(
"[%s+%s*%d%s0x%x]",
 
  525                          NameOfCPURegister(base),
 
  526                          NameOfCPURegister(index),
 
  528                          disp < 0 ? 
"-" : 
"+",
 
  529                          disp < 0 ? -disp : disp);
 
  531         return mod == 2 ? 6 : 3;
 
  534         int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1)
 
  535                               : *
reinterpret_cast<int8_t*
>(modrmp + 1);
 
  536         AppendToBuffer(
"[%s%s0x%x]",
 
  537                        NameOfCPURegister(rm),
 
  538                        disp < 0 ? 
"-" : 
"+",
 
  539                        disp < 0 ? -disp : disp);
 
  540         return (mod == 2) ? 5 : 2;
 
  544       AppendToBuffer(
"%s", (this->*register_name)(rm));
 
  547       UnimplementedInstruction();
 
  554 int DisassemblerX64::PrintImmediate(
byte* data, OperandSize 
size) {
 
  558     case OPERAND_BYTE_SIZE:
 
  562     case OPERAND_WORD_SIZE:
 
  563       value = *
reinterpret_cast<int16_t*
>(data);
 
  566     case OPERAND_DOUBLEWORD_SIZE:
 
  567       value = *
reinterpret_cast<uint32_t*
>(data);
 
  570     case OPERAND_QUADWORD_SIZE:
 
  571       value = *
reinterpret_cast<int32_t*
>(data);
 
  584 int DisassemblerX64::PrintRightOperand(
byte* modrmp) {
 
  585   return PrintRightOperandHelper(modrmp,
 
  586                                  &DisassemblerX64::NameOfCPURegister);
 
  590 int DisassemblerX64::PrintRightByteOperand(
byte* modrmp) {
 
  591   return PrintRightOperandHelper(modrmp,
 
  592                                  &DisassemblerX64::NameOfByteCPURegister);
 
  596 int DisassemblerX64::PrintRightXMMOperand(
byte* modrmp) {
 
  597   return PrintRightOperandHelper(modrmp,
 
  598                                  &DisassemblerX64::NameOfXMMRegister);
 
  604 int DisassemblerX64::PrintOperands(
const char* mnem,
 
  605                                    OperandType op_order,
 
  609   get_modrm(modrm, &mod, ®op, &rm);
 
  611   const char* register_name =
 
  612       byte_size_operand_ ? NameOfByteCPURegister(regop)
 
  613                          : NameOfCPURegister(regop);
 
  615     case REG_OPER_OP_ORDER: {
 
  616       AppendToBuffer(
"%s%c %s,",
 
  620       advance = byte_size_operand_ ? PrintRightByteOperand(data)
 
  621                                    : PrintRightOperand(data);
 
  624     case OPER_REG_OP_ORDER: {
 
  625       AppendToBuffer(
"%s%c ", mnem, operand_size_code());
 
  626       advance = byte_size_operand_ ? PrintRightByteOperand(data)
 
  627                                    : PrintRightOperand(data);
 
  628       AppendToBuffer(
",%s", register_name);
 
  641 int DisassemblerX64::PrintImmediateOp(
byte* data) {
 
  642   bool byte_size_immediate = (*data & 0x02) != 0;
 
  643   byte modrm = *(data + 1);
 
  645   get_modrm(modrm, &mod, ®op, &rm);
 
  646   const char* mnem = 
"Imm???";
 
  673       UnimplementedInstruction();
 
  675   AppendToBuffer(
"%s%c ", mnem, operand_size_code());
 
  676   int count = PrintRightOperand(data + 1);
 
  677   AppendToBuffer(
",0x");
 
  678   OperandSize immediate_size =
 
  679       byte_size_immediate ? OPERAND_BYTE_SIZE : operand_size();
 
  680   count += PrintImmediate(data + 1 + count, immediate_size);
 
  686 int DisassemblerX64::F6F7Instruction(
byte* data) {
 
  687   ASSERT(*data == 0xF7 || *data == 0xF6);
 
  688   byte modrm = *(data + 1);
 
  690   get_modrm(modrm, &mod, ®op, &rm);
 
  691   if (mod == 3 && regop != 0) {
 
  692     const char* mnem = 
NULL;
 
  710         UnimplementedInstruction();
 
  712     AppendToBuffer(
"%s%c %s",
 
  715                    NameOfCPURegister(rm));
 
  717   } 
else if (regop == 0) {
 
  718     AppendToBuffer(
"test%c ", operand_size_code());
 
  719     int count = PrintRightOperand(data + 1);  
 
  720     AppendToBuffer(
",0x");
 
  721     count += PrintImmediate(data + 1 + count, operand_size());
 
  724     UnimplementedInstruction();
 
  730 int DisassemblerX64::ShiftInstruction(
byte* data) {
 
  731   byte op = *data & (~1);
 
  732   if (op != 0xD0 && op != 0xD2 && op != 0xC0) {
 
  733     UnimplementedInstruction();
 
  736   byte modrm = *(data + 1);
 
  738   get_modrm(modrm, &mod, ®op, &rm);
 
  743     UnimplementedInstruction();
 
  746   const char* mnem = 
NULL;
 
  770       UnimplementedInstruction();
 
  776   } 
else if (op == 0xC0) {
 
  780   AppendToBuffer(
"%s%c %s,",
 
  783                  byte_size_operand_ ? NameOfByteCPURegister(rm)
 
  784                                     : NameOfCPURegister(rm));
 
  786     AppendToBuffer(
"cl");
 
  788     AppendToBuffer(
"%d", imm8);
 
  795 int DisassemblerX64::JumpShort(
byte* data) {
 
  797   byte b = *(data + 1);
 
  798   byte* dest = data + 
static_cast<int8_t
>(b) + 2;
 
  799   AppendToBuffer(
"jmp %s", NameOfAddress(dest));
 
  805 int DisassemblerX64::JumpConditional(
byte* data) {
 
  807   byte cond = *(data + 1) & 0x0F;
 
  808   byte* dest = data + *
reinterpret_cast<int32_t*
>(data + 2) + 6;
 
  809   const char* mnem = conditional_code_suffix[cond];
 
  810   AppendToBuffer(
"j%s %s", mnem, NameOfAddress(dest));
 
  816 int DisassemblerX64::JumpConditionalShort(
byte* data) {
 
  817   byte cond = *data & 0x0F;
 
  818   byte b = *(data + 1);
 
  819   byte* dest = data + 
static_cast<int8_t
>(b) + 2;
 
  820   const char* mnem = conditional_code_suffix[cond];
 
  821   AppendToBuffer(
"j%s %s", mnem, NameOfAddress(dest));
 
  829   byte cond = *(data + 1) & 0x0F;
 
  830   const char* mnem = conditional_code_suffix[cond];
 
  831   AppendToBuffer(
"set%s%c ", mnem, operand_size_code());
 
  832   PrintRightByteOperand(data + 2);
 
  838 int DisassemblerX64::FPUInstruction(
byte* data) {
 
  839   byte escape_opcode = *data;
 
  841   byte modrm_byte = *(data+1);
 
  843   if (modrm_byte >= 0xC0) {
 
  844     return RegisterFPUInstruction(escape_opcode, modrm_byte);
 
  846     return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1);
 
  850 int DisassemblerX64::MemoryFPUInstruction(
int escape_opcode,
 
  853   const char* mnem = 
"?";
 
  854   int regop = (modrm_byte >> 3) & 0x7;  
 
  855   switch (escape_opcode) {
 
  856     case 0xD9: 
switch (regop) {
 
  857         case 0: mnem = 
"fld_s"; 
break;
 
  858         case 3: mnem = 
"fstp_s"; 
break;
 
  859         case 7: mnem = 
"fstcw"; 
break;
 
  860         default: UnimplementedInstruction();
 
  864     case 0xDB: 
switch (regop) {
 
  865         case 0: mnem = 
"fild_s"; 
break;
 
  866         case 1: mnem = 
"fisttp_s"; 
break;
 
  867         case 2: mnem = 
"fist_s"; 
break;
 
  868         case 3: mnem = 
"fistp_s"; 
break;
 
  869         default: UnimplementedInstruction();
 
  873     case 0xDD: 
switch (regop) {
 
  874         case 0: mnem = 
"fld_d"; 
break;
 
  875         case 3: mnem = 
"fstp_d"; 
break;
 
  876         default: UnimplementedInstruction();
 
  880     case 0xDF: 
switch (regop) {
 
  881         case 5: mnem = 
"fild_d"; 
break;
 
  882         case 7: mnem = 
"fistp_d"; 
break;
 
  883         default: UnimplementedInstruction();
 
  887     default: UnimplementedInstruction();
 
  889   AppendToBuffer(
"%s ", mnem);
 
  890   int count = PrintRightOperand(modrm_start);
 
  894 int DisassemblerX64::RegisterFPUInstruction(
int escape_opcode,
 
  896   bool has_register = 
false;  
 
  897   const char* mnem = 
"?";
 
  899   switch (escape_opcode) {
 
  901       UnimplementedInstruction();
 
  905       switch (modrm_byte & 0xF8) {
 
  915           switch (modrm_byte) {
 
  916             case 0xE0: mnem = 
"fchs"; 
break;
 
  917             case 0xE1: mnem = 
"fabs"; 
break;
 
  918             case 0xE3: mnem = 
"fninit"; 
break;
 
  919             case 0xE4: mnem = 
"ftst"; 
break;
 
  920             case 0xE8: mnem = 
"fld1"; 
break;
 
  921             case 0xEB: mnem = 
"fldpi"; 
break;
 
  922             case 0xED: mnem = 
"fldln2"; 
break;
 
  923             case 0xEE: mnem = 
"fldz"; 
break;
 
  924             case 0xF0: mnem = 
"f2xm1"; 
break;
 
  925             case 0xF1: mnem = 
"fyl2x"; 
break;
 
  926             case 0xF2: mnem = 
"fptan"; 
break;
 
  927             case 0xF5: mnem = 
"fprem1"; 
break;
 
  928             case 0xF7: mnem = 
"fincstp"; 
break;
 
  929             case 0xF8: mnem = 
"fprem"; 
break;
 
  930             case 0xFC: mnem = 
"frndint"; 
break;
 
  931             case 0xFD: mnem = 
"fscale"; 
break;
 
  932             case 0xFE: mnem = 
"fsin"; 
break;
 
  933             case 0xFF: mnem = 
"fcos"; 
break;
 
  934             default: UnimplementedInstruction();
 
  940       if (modrm_byte == 0xE9) {
 
  943         UnimplementedInstruction();
 
  948       if ((modrm_byte & 0xF8) == 0xE8) {
 
  951       } 
else if (modrm_byte  == 0xE2) {
 
  953       } 
else if (modrm_byte == 0xE3) {
 
  956         UnimplementedInstruction();
 
  962       switch (modrm_byte & 0xF8) {
 
  963         case 0xC0: mnem = 
"fadd"; 
break;
 
  964         case 0xE8: mnem = 
"fsub"; 
break;
 
  965         case 0xC8: mnem = 
"fmul"; 
break;
 
  966         case 0xF8: mnem = 
"fdiv"; 
break;
 
  967         default: UnimplementedInstruction();
 
  973       switch (modrm_byte & 0xF8) {
 
  974         case 0xC0: mnem = 
"ffree"; 
break;
 
  975         case 0xD8: mnem = 
"fstp"; 
break;
 
  976         default: UnimplementedInstruction();
 
  981       if (modrm_byte  == 0xD9) {
 
  985         switch (modrm_byte & 0xF8) {
 
  986           case 0xC0: mnem = 
"faddp"; 
break;
 
  987           case 0xE8: mnem = 
"fsubp"; 
break;
 
  988           case 0xC8: mnem = 
"fmulp"; 
break;
 
  989           case 0xF8: mnem = 
"fdivp"; 
break;
 
  990           default: UnimplementedInstruction();
 
  996       if (modrm_byte == 0xE0) {
 
  998       } 
else if ((modrm_byte & 0xF8) == 0xE8) {
 
 1000         has_register = 
true;
 
 1004     default: UnimplementedInstruction();
 
 1008     AppendToBuffer(
"%s st%d", mnem, modrm_byte & 0x7);
 
 1010     AppendToBuffer(
"%s", mnem);
 
 1020 int DisassemblerX64::TwoByteOpcodeInstruction(
byte* data) {
 
 1021   byte opcode = *(data + 1);
 
 1022   byte* current = data + 2;
 
 1024   const char* mnemonic = TwoByteMnemonic(opcode);
 
 1025   if (operand_size_ == 0x66) {
 
 1028     if (opcode == 0x3A) {
 
 1029       byte third_byte = *current;
 
 1031       if (third_byte == 0x17) {
 
 1032         get_modrm(*current, &mod, ®op, &rm);
 
 1033         AppendToBuffer(
"extractps ");  
 
 1034         current += PrintRightOperand(current);
 
 1035         AppendToBuffer(
",%s,%d", NameOfXMMRegister(regop), (*current) & 3);
 
 1037       } 
else if (third_byte == 0x0b) {
 
 1038         get_modrm(*current, &mod, ®op, &rm);
 
 1040         AppendToBuffer(
"roundsd %s,", NameOfXMMRegister(regop));
 
 1041         current += PrintRightXMMOperand(current);
 
 1042         AppendToBuffer(
",%d", (*current) & 3);
 
 1045         UnimplementedInstruction();
 
 1048       get_modrm(*current, &mod, ®op, &rm);
 
 1049       if (opcode == 0x1f) {
 
 1056         } 
else if (mod == 2) {  
 
 1059         AppendToBuffer(
"nop");
 
 1060       } 
else if (opcode == 0x28) {
 
 1061         AppendToBuffer(
"movapd %s,", NameOfXMMRegister(regop));
 
 1062         current += PrintRightXMMOperand(current);
 
 1063       } 
else if (opcode == 0x29) {
 
 1064         AppendToBuffer(
"movapd ");
 
 1065         current += PrintRightXMMOperand(current);
 
 1066         AppendToBuffer(
",%s", NameOfXMMRegister(regop));
 
 1067       } 
else if (opcode == 0x6E) {
 
 1068         AppendToBuffer(
"mov%c %s,",
 
 1069                        rex_w() ? 
'q' : 
'd',
 
 1070                        NameOfXMMRegister(regop));
 
 1071         current += PrintRightOperand(current);
 
 1072       } 
else if (opcode == 0x6F) {
 
 1073         AppendToBuffer(
"movdqa %s,",
 
 1074                        NameOfXMMRegister(regop));
 
 1075         current += PrintRightXMMOperand(current);
 
 1076       } 
else if (opcode == 0x7E) {
 
 1077         AppendToBuffer(
"mov%c ",
 
 1078                        rex_w() ? 
'q' : 
'd');
 
 1079         current += PrintRightOperand(current);
 
 1080         AppendToBuffer(
",%s", NameOfXMMRegister(regop));
 
 1081       } 
else if (opcode == 0x7F) {
 
 1082         AppendToBuffer(
"movdqa ");
 
 1083         current += PrintRightXMMOperand(current);
 
 1084         AppendToBuffer(
",%s", NameOfXMMRegister(regop));
 
 1085       } 
else if (opcode == 0xD6) {
 
 1086         AppendToBuffer(
"movq ");
 
 1087         current += PrintRightXMMOperand(current);
 
 1088         AppendToBuffer(
",%s", NameOfXMMRegister(regop));
 
 1089       } 
else if (opcode == 0x50) {
 
 1090         AppendToBuffer(
"movmskpd %s,", NameOfCPURegister(regop));
 
 1091         current += PrintRightXMMOperand(current);
 
 1092       } 
else if (opcode == 0x73) {
 
 1095         AppendToBuffer(
"psllq,%s,%d", NameOfXMMRegister(rm), *current & 0x7f);
 
 1098         const char* mnemonic = 
"?";
 
 1099         if (opcode == 0x54) {
 
 1101         } 
else  if (opcode == 0x56) {
 
 1103         } 
else  if (opcode == 0x57) {
 
 1105         } 
else if (opcode == 0x2E) {
 
 1106           mnemonic = 
"ucomisd";
 
 1107         } 
else if (opcode == 0x2F) {
 
 1108           mnemonic = 
"comisd";
 
 1110           UnimplementedInstruction();
 
 1112         AppendToBuffer(
"%s %s,", mnemonic, NameOfXMMRegister(regop));
 
 1113         current += PrintRightXMMOperand(current);
 
 1116   } 
else if (group_1_prefix_ == 0xF2) {
 
 1119     if (opcode == 0x11 || opcode == 0x10) {
 
 1121       AppendToBuffer(
"movsd ");
 
 1123       get_modrm(*current, &mod, ®op, &rm);
 
 1124       if (opcode == 0x11) {
 
 1125         current += PrintRightXMMOperand(current);
 
 1126         AppendToBuffer(
",%s", NameOfXMMRegister(regop));
 
 1128         AppendToBuffer(
"%s,", NameOfXMMRegister(regop));
 
 1129         current += PrintRightXMMOperand(current);
 
 1131     } 
else if (opcode == 0x2A) {
 
 1134       get_modrm(*current, &mod, ®op, &rm);
 
 1135       AppendToBuffer(
"%sd %s,", mnemonic, NameOfXMMRegister(regop));
 
 1136       current += PrintRightOperand(current);
 
 1137     } 
else if (opcode == 0x2C) {
 
 1141       get_modrm(*current, &mod, ®op, &rm);
 
 1142       AppendToBuffer(
"cvttsd2si%c %s,",
 
 1143           operand_size_code(), NameOfCPURegister(regop));
 
 1144       current += PrintRightXMMOperand(current);
 
 1145     } 
else if (opcode == 0x2D) {
 
 1148       get_modrm(*current, &mod, ®op, &rm);
 
 1149       AppendToBuffer(
"cvtsd2si%c %s,",
 
 1150           operand_size_code(), NameOfCPURegister(regop));
 
 1151       current += PrintRightXMMOperand(current);
 
 1152     } 
else if ((opcode & 0xF8) == 0x58 || opcode == 0x51) {
 
 1155       get_modrm(*current, &mod, ®op, &rm);
 
 1156       AppendToBuffer(
"%s %s,", mnemonic, NameOfXMMRegister(regop));
 
 1157       current += PrintRightXMMOperand(current);
 
 1158     } 
else if (opcode == 0xC2) {
 
 1161       get_modrm(*current, &mod, ®op, &rm);
 
 1162       const char* 
const pseudo_op[] = {
 
 1172       AppendToBuffer(
"%s %s,%s",
 
 1173                      pseudo_op[current[1]],
 
 1174                      NameOfXMMRegister(regop),
 
 1175                      NameOfXMMRegister(rm));
 
 1178       UnimplementedInstruction();
 
 1180   } 
else if (group_1_prefix_ == 0xF3) {
 
 1182     if (opcode == 0x11 || opcode == 0x10) {
 
 1184       AppendToBuffer(
"movss ");
 
 1186       get_modrm(*current, &mod, ®op, &rm);
 
 1187       if (opcode == 0x11) {
 
 1188         current += PrintRightOperand(current);
 
 1189         AppendToBuffer(
",%s", NameOfXMMRegister(regop));
 
 1191         AppendToBuffer(
"%s,", NameOfXMMRegister(regop));
 
 1192         current += PrintRightOperand(current);
 
 1194     } 
else if (opcode == 0x2A) {
 
 1197       get_modrm(*current, &mod, ®op, &rm);
 
 1198       AppendToBuffer(
"%ss %s,", mnemonic, NameOfXMMRegister(regop));
 
 1199       current += PrintRightOperand(current);
 
 1200     } 
else if (opcode == 0x2C) {
 
 1204       get_modrm(*current, &mod, ®op, &rm);
 
 1205       AppendToBuffer(
"cvttss2si%c %s,",
 
 1206           operand_size_code(), NameOfCPURegister(regop));
 
 1207       current += PrintRightXMMOperand(current);
 
 1208     } 
else if (opcode == 0x5A) {
 
 1212       get_modrm(*current, &mod, ®op, &rm);
 
 1213       AppendToBuffer(
"cvtss2sd %s,", NameOfXMMRegister(regop));
 
 1214       current += PrintRightXMMOperand(current);
 
 1215     } 
else if (opcode == 0x7E) {
 
 1217       get_modrm(*current, &mod, ®op, &rm);
 
 1218       AppendToBuffer(
"movq %s,", NameOfXMMRegister(regop));
 
 1219       current += PrintRightXMMOperand(current);
 
 1221       UnimplementedInstruction();
 
 1223   } 
else if (opcode == 0x1F) {
 
 1226     get_modrm(*current, &mod, ®op, &rm);
 
 1233     } 
else if (mod == 2) {  
 
 1236     AppendToBuffer(
"nop");
 
 1238   } 
else if (opcode == 0x28) {
 
 1241     get_modrm(*current, &mod, ®op, &rm);
 
 1242     AppendToBuffer(
"movaps %s,", NameOfXMMRegister(regop));
 
 1243     current += PrintRightXMMOperand(current);
 
 1245   } 
else if (opcode == 0x29) {
 
 1248     get_modrm(*current, &mod, ®op, &rm);
 
 1249     AppendToBuffer(
"movaps ");
 
 1250     current += PrintRightXMMOperand(current);
 
 1251     AppendToBuffer(
",%s", NameOfXMMRegister(regop));
 
 1253   } 
else if (opcode == 0xA2) {
 
 1255     AppendToBuffer(
"%s", mnemonic);
 
 1257   } 
else if ((opcode & 0xF0) == 0x40) {
 
 1259     int condition = opcode & 0x0F;
 
 1260     const InstructionDesc& idesc = cmov_instructions[condition];
 
 1261     byte_size_operand_ = idesc.byte_size_operation;
 
 1262     current += PrintOperands(idesc.mnem, idesc.op_order_, current);
 
 1264   } 
else if (opcode >= 0x53 && opcode <= 0x5F) {
 
 1265     const char* 
const pseudo_op[] = {
 
 1281     get_modrm(*current, &mod, ®op, &rm);
 
 1282     AppendToBuffer(
"%s %s,",
 
 1283                    pseudo_op[opcode - 0x53],
 
 1284                    NameOfXMMRegister(regop));
 
 1285     current += PrintRightXMMOperand(current);
 
 1287   } 
else if (opcode == 0xC6) {
 
 1290     get_modrm(*current, &mod, ®op, &rm);
 
 1291     AppendToBuffer(
"shufps %s, ", NameOfXMMRegister(regop));
 
 1292     current += PrintRightXMMOperand(current);
 
 1293     AppendToBuffer(
", %d", (*current) & 3);
 
 1296   } 
else if (opcode == 0x50) {
 
 1299     get_modrm(*current, &mod, ®op, &rm);
 
 1300     AppendToBuffer(
"movmskps %s,", NameOfCPURegister(regop));
 
 1301     current += PrintRightXMMOperand(current);
 
 1303   } 
else if ((opcode & 0xF0) == 0x80) {
 
 1305     current = data + JumpConditional(data);
 
 1307   } 
else if (opcode == 0xBE || opcode == 0xBF || opcode == 0xB6 ||
 
 1308              opcode == 0xB7 || opcode == 0xAF) {
 
 1310     current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current);
 
 1312   } 
else if ((opcode & 0xF0) == 0x90) {
 
 1314     current = data + 
SetCC(data);
 
 1316   } 
else if (opcode == 0xAB || opcode == 0xA5 || opcode == 0xAD) {
 
 1318     AppendToBuffer(
"%s ", mnemonic);
 
 1320     get_modrm(*current, &mod, ®op, &rm);
 
 1321     current += PrintRightOperand(current);
 
 1322     if (opcode == 0xAB) {
 
 1323       AppendToBuffer(
",%s", NameOfCPURegister(regop));
 
 1325       AppendToBuffer(
",%s,cl", NameOfCPURegister(regop));
 
 1327   } 
else if (opcode == 0xBD) {
 
 1328     AppendToBuffer(
"%s%c ", mnemonic, operand_size_code());
 
 1330     get_modrm(*current, &mod, ®op, &rm);
 
 1331     AppendToBuffer(
"%s,", NameOfCPURegister(regop));
 
 1332     current += PrintRightOperand(current);
 
 1334     UnimplementedInstruction();
 
 1336   return static_cast<int>(current - data);
 
 1343 const char* DisassemblerX64::TwoByteMnemonic(
byte opcode) {
 
 1390   tmp_buffer_pos_ = 0;  
 
 1392   bool processed = 
true;  
 
 1399     if (current == OPERAND_SIZE_OVERRIDE_PREFIX) {  
 
 1400       operand_size_ = current;
 
 1401     } 
else if ((current & 0xF0) == 0x40) {  
 
 1403       if (rex_w()) AppendToBuffer(
"REX.W ");
 
 1404     } 
else if ((current & 0xFE) == 0xF2) {  
 
 1405       group_1_prefix_ = current;
 
 1412   const InstructionDesc& idesc = instruction_table_->Get(current);
 
 1413   byte_size_operand_ = idesc.byte_size_operation;
 
 1414   switch (idesc.type) {
 
 1415     case ZERO_OPERANDS_INSTR:
 
 1416       if (current >= 0xA4 && current <= 0xA7) {
 
 1418         if (group_1_prefix_ == REP_PREFIX) {
 
 1420           AppendToBuffer(
"rep ");
 
 1422         if (rex_w()) AppendToBuffer(
"REX.W ");
 
 1423         AppendToBuffer(
"%s%c", idesc.mnem, operand_size_code());
 
 1425         AppendToBuffer(
"%s", idesc.mnem, operand_size_code());
 
 1430     case TWO_OPERANDS_INSTR:
 
 1432       data += PrintOperands(idesc.mnem, idesc.op_order_, data);
 
 1435     case JUMP_CONDITIONAL_SHORT_INSTR:
 
 1436       data += JumpConditionalShort(data);
 
 1439     case REGISTER_INSTR:
 
 1440       AppendToBuffer(
"%s%c %s",
 
 1442                      operand_size_code(),
 
 1443                      NameOfCPURegister(base_reg(current & 0x07)));
 
 1447       AppendToBuffer(
"%s %s",
 
 1449                      NameOfCPURegister(base_reg(current & 0x07)));
 
 1452     case MOVE_REG_INSTR: {
 
 1454       switch (operand_size()) {
 
 1455         case OPERAND_WORD_SIZE:
 
 1456           addr = 
reinterpret_cast<byte*
>(*
reinterpret_cast<int16_t*
>(data + 1));
 
 1459         case OPERAND_DOUBLEWORD_SIZE:
 
 1461               reinterpret_cast<byte*
>(*
reinterpret_cast<uint32_t*
>(data + 1));
 
 1464         case OPERAND_QUADWORD_SIZE:
 
 1465           addr = 
reinterpret_cast<byte*
>(*
reinterpret_cast<int64_t*
>(data + 1));
 
 1471       AppendToBuffer(
"mov%c %s,%s",
 
 1472                      operand_size_code(),
 
 1473                      NameOfCPURegister(base_reg(current & 0x07)),
 
 1474                      NameOfAddress(addr));
 
 1478     case CALL_JUMP_INSTR: {
 
 1479       byte* addr = data + *
reinterpret_cast<int32_t*
>(data + 1) + 5;
 
 1480       AppendToBuffer(
"%s %s", idesc.mnem, NameOfAddress(addr));
 
 1485     case SHORT_IMMEDIATE_INSTR: {
 
 1487           reinterpret_cast<byte*
>(*
reinterpret_cast<int32_t*
>(data + 1));
 
 1488       AppendToBuffer(
"%s rax,%s", idesc.mnem, NameOfAddress(addr));
 
 1506         AppendToBuffer(
"ret 0x%x", *reinterpret_cast<uint16_t*>(data + 1));
 
 1513         get_modrm(*(data + 1), &mod, ®op, &rm);
 
 1514         int32_t imm = *data == 0x6B ? *(data + 2)
 
 1515             : *reinterpret_cast<int32_t*>(data + 2);
 
 1516         AppendToBuffer(
"imul%c %s,%s,0x%x",
 
 1517                        operand_size_code(),
 
 1518                        NameOfCPURegister(regop),
 
 1519                        NameOfCPURegister(rm), imm);
 
 1520         data += 2 + (*data == 0x6B ? 1 : 4);
 
 1526         data += PrintImmediateOp(data);
 
 1530         data += TwoByteOpcodeInstruction(data);
 
 1536         get_modrm(*data, &mod, ®op, &rm);
 
 1538           AppendToBuffer(
"pop ");
 
 1539           data += PrintRightOperand(data);
 
 1547         get_modrm(*data, &mod, ®op, &rm);
 
 1548         const char* mnem = 
NULL;
 
 1568         AppendToBuffer(((regop <= 1) ? 
"%s%c " : 
"%s "),
 
 1570                        operand_size_code());
 
 1571         data += PrintRightOperand(data);
 
 1578         bool is_byte = *data == 0xC6;
 
 1581           AppendToBuffer(
"movb ");
 
 1582           data += PrintRightByteOperand(data);
 
 1584           AppendToBuffer(
",0x%x", imm);
 
 1587           AppendToBuffer(
"mov%c ", operand_size_code());
 
 1588           data += PrintRightOperand(data);
 
 1589           if (operand_size() == OPERAND_WORD_SIZE) {
 
 1591             AppendToBuffer(
",0x%x", imm);
 
 1595             AppendToBuffer(
",0x%x", imm);
 
 1604         AppendToBuffer(
"cmpb ");
 
 1605         data += PrintRightByteOperand(data);
 
 1607         AppendToBuffer(
",0x%x", imm);
 
 1615         bool is_byte = *data == 0x88;
 
 1618         get_modrm(*data, &mod, ®op, &rm);
 
 1620           AppendToBuffer(
"movb ");
 
 1621           data += PrintRightByteOperand(data);
 
 1622           AppendToBuffer(
",%s", NameOfByteCPURegister(regop));
 
 1624           AppendToBuffer(
"mov%c ", operand_size_code());
 
 1625           data += PrintRightOperand(data);
 
 1626           AppendToBuffer(
",%s", NameOfCPURegister(regop));
 
 1639         int reg = (*data & 0x7) | (rex_b() ? 8 : 0);
 
 1641           AppendToBuffer(
"nop");  
 
 1643           AppendToBuffer(
"xchg%c rax,%s",
 
 1644                          operand_size_code(),
 
 1645                          NameOfCPURegister(reg));
 
 1667         byte opcode = *data;
 
 1669         bool is_32bit = (opcode >= 0xB8);
 
 1670         int reg = (opcode & 0x7) | (rex_b() ? 8 : 0);
 
 1672           AppendToBuffer(
"mov%c %s,",
 
 1673                          operand_size_code(),
 
 1674                          NameOfCPURegister(reg));
 
 1675           data += PrintImmediate(data, OPERAND_DOUBLEWORD_SIZE);
 
 1677           AppendToBuffer(
"movb %s,",
 
 1678                          NameOfByteCPURegister(reg));
 
 1679           data += PrintImmediate(data, OPERAND_BYTE_SIZE);
 
 1686         get_modrm(*data, &mod, ®op, &rm);
 
 1688           AppendToBuffer(
"decb ");
 
 1689           data += PrintRightByteOperand(data);
 
 1691           UnimplementedInstruction();
 
 1696         AppendToBuffer(
"push 0x%x", *reinterpret_cast<int32_t*>(data + 1));
 
 1701         AppendToBuffer(
"push 0x%x", *reinterpret_cast<int8_t*>(data + 1));
 
 1707         switch (operand_size()) {
 
 1708           case OPERAND_DOUBLEWORD_SIZE: {
 
 1709             const char* memory_location = NameOfAddress(
 
 1710                 reinterpret_cast<byte*>(
 
 1711                     *reinterpret_cast<int32_t*>(data + 1)));
 
 1712             if (*data == 0xA1) {  
 
 1713               AppendToBuffer(
"movzxlq rax,(%s)", memory_location);
 
 1715               AppendToBuffer(
"movzxlq (%s),rax", memory_location);
 
 1720           case OPERAND_QUADWORD_SIZE: {
 
 1722             const char* memory_location = NameOfAddress(
 
 1723                 *reinterpret_cast<byte**>(data + 1));
 
 1724             if (*data == 0xA1) {  
 
 1725               AppendToBuffer(
"movq rax,(%s)", memory_location);
 
 1727               AppendToBuffer(
"movq (%s),rax", memory_location);
 
 1733             UnimplementedInstruction();
 
 1739         AppendToBuffer(
"test al,0x%x", *reinterpret_cast<uint8_t*>(data + 1));
 
 1745         switch (operand_size()) {
 
 1746           case OPERAND_WORD_SIZE:
 
 1747             value = *
reinterpret_cast<uint16_t*
>(data + 1);
 
 1750           case OPERAND_DOUBLEWORD_SIZE:
 
 1751             value = *
reinterpret_cast<uint32_t*
>(data + 1);
 
 1754           case OPERAND_QUADWORD_SIZE:
 
 1755             value = *
reinterpret_cast<int32_t*
>(data + 1);
 
 1762                        operand_size_code(),
 
 1769         data += ShiftInstruction(data);
 
 1774         byte_size_operand_ = 
true;
 
 1775         data += ShiftInstruction(data);
 
 1785         data += FPUInstruction(data);
 
 1789         data += JumpShort(data);
 
 1793         byte_size_operand_ = 
true;  
 
 1795         data += F6F7Instruction(data);
 
 1799         AppendToBuffer(
"cmp al,0x%x", *reinterpret_cast<int8_t*>(data + 1));
 
 1804         UnimplementedInstruction();
 
 1809   if (tmp_buffer_pos_ < 
sizeof tmp_buffer_) {
 
 1810     tmp_buffer_[tmp_buffer_pos_] = 
'\0';
 
 1813   int instr_len = 
static_cast<int>(data - instr);
 
 1818   for (
byte* bp = instr; bp < data; bp++) {
 
 1821   for (
int i = 6 - instr_len; i >= 0; i--) {
 
 1826                                      tmp_buffer_.
start());
 
 1834 static const char* cpu_regs[16] = {
 
 1835   "rax", 
"rcx", 
"rdx", 
"rbx", 
"rsp", 
"rbp", 
"rsi", 
"rdi",
 
 1836   "r8", 
"r9", 
"r10", 
"r11", 
"r12", 
"r13", 
"r14", 
"r15" 
 1840 static const char* byte_cpu_regs[16] = {
 
 1841   "al", 
"cl", 
"dl", 
"bl", 
"spl", 
"bpl", 
"sil", 
"dil",
 
 1842   "r8l", 
"r9l", 
"r10l", 
"r11l", 
"r12l", 
"r13l", 
"r14l", 
"r15l" 
 1846 static const char* xmm_regs[16] = {
 
 1847   "xmm0", 
"xmm1", 
"xmm2", 
"xmm3", 
"xmm4", 
"xmm5", 
"xmm6", 
"xmm7",
 
 1848   "xmm8", 
"xmm9", 
"xmm10", 
"xmm11", 
"xmm12", 
"xmm13", 
"xmm14", 
"xmm15" 
 1864   if (0 <= reg && reg < 16)
 
 1865     return cpu_regs[reg];
 
 1871   if (0 <= reg && reg < 16)
 
 1872     return byte_cpu_regs[reg];
 
 1878   if (0 <= reg && reg < 16)
 
 1879     return xmm_regs[reg];
 
 1894     : converter_(converter) { }
 
 1900                                     byte* instruction) {
 
 1901   DisassemblerX64 d(converter_, CONTINUE_ON_UNIMPLEMENTED_OPCODE);
 
 1902   return d.InstructionDecode(buffer, instruction);
 
 1907 int Disassembler::ConstantPoolSizeAt(
byte* instruction) {
 
 1912 void Disassembler::Disassemble(FILE* f, 
byte* begin, 
byte* end) {
 
 1913   NameConverter converter;
 
 1915   for (
byte* 
pc = begin; 
pc < end;) {
 
 1919     pc += d.InstructionDecode(buffer, 
pc);
 
 1920     fprintf(f, 
"%p", prev_pc);
 
 1923     for (
byte* bp = prev_pc; bp < 
pc; bp++) {
 
 1924       fprintf(f, 
"%02x", *bp);
 
 1926     for (
int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) {
 
 1929     fprintf(f, 
"  %s\n", buffer.
start());
 
 1935 #endif  // V8_TARGET_ARCH_X64 
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Disassembler(const NameConverter &converter)
static int VSNPrintF(Vector< char > str, const char *format, va_list args)
virtual const char * NameOfXMMRegister(int reg) const 
v8::internal::EmbeddedVector< char, 128 > tmp_buffer_
virtual const char * NameOfConstant(byte *addr) const 
#define ASSERT(condition)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object size
virtual const char * NameInCode(byte *addr) const 
virtual const char * NameOfByteCPURegister(int reg) const 
virtual const char * NameOfCPURegister(int reg) const 
virtual const char * NameOfAddress(byte *addr) const 
static int SNPrintF(Vector< char > str, const char *format,...)
#define ASSERT_EQ(v1, v2)
#define ASSERT_NE(v1, v2)
#define LAZY_INSTANCE_INITIALIZER