// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <assert.h>
#include <stdio.h>
#include <stdarg.h>

#include "v8.h"

#if defined(V8_TARGET_ARCH_X64)

#include "disasm.h"
#include "lazy-instance.h"

namespace disasm {

enum OperandType {
  UNSET_OP_ORDER = 0,
  // Operand size decides between 16, 32 and 64 bit operands.
  REG_OPER_OP_ORDER = 1,  // Register destination, operand source.
  OPER_REG_OP_ORDER = 2,  // Operand destination, register source.
  // Fixed 8-bit operands.
  BYTE_SIZE_OPERAND_FLAG = 4,
  BYTE_REG_OPER_OP_ORDER = REG_OPER_OP_ORDER | BYTE_SIZE_OPERAND_FLAG,
  BYTE_OPER_REG_OP_ORDER = OPER_REG_OP_ORDER | BYTE_SIZE_OPERAND_FLAG
};

//------------------------------------------------------------------
// Tables
//------------------------------------------------------------------
struct ByteMnemonic {
  int b;  // -1 terminates, otherwise must be in range (0..255)
  OperandType op_order_;
  const char* mnem;
};


static const ByteMnemonic two_operands_instr[] = {
  { 0x00, BYTE_OPER_REG_OP_ORDER, "add" },
  { 0x01, OPER_REG_OP_ORDER,      "add" },
  { 0x02, BYTE_REG_OPER_OP_ORDER, "add" },
  { 0x03, REG_OPER_OP_ORDER,      "add" },
  { 0x08, BYTE_OPER_REG_OP_ORDER, "or" },
  { 0x09, OPER_REG_OP_ORDER,      "or" },
  { 0x0A, BYTE_REG_OPER_OP_ORDER, "or" },
  { 0x0B, REG_OPER_OP_ORDER,      "or" },
  { 0x10, BYTE_OPER_REG_OP_ORDER, "adc" },
  { 0x11, OPER_REG_OP_ORDER,      "adc" },
  { 0x12, BYTE_REG_OPER_OP_ORDER, "adc" },
  { 0x13, REG_OPER_OP_ORDER,      "adc" },
  { 0x18, BYTE_OPER_REG_OP_ORDER, "sbb" },
  { 0x19, OPER_REG_OP_ORDER,      "sbb" },
  { 0x1A, BYTE_REG_OPER_OP_ORDER, "sbb" },
  { 0x1B, REG_OPER_OP_ORDER,      "sbb" },
  { 0x20, BYTE_OPER_REG_OP_ORDER, "and" },
  { 0x21, OPER_REG_OP_ORDER,      "and" },
  { 0x22, BYTE_REG_OPER_OP_ORDER, "and" },
  { 0x23, REG_OPER_OP_ORDER,      "and" },
  { 0x28, BYTE_OPER_REG_OP_ORDER, "sub" },
  { 0x29, OPER_REG_OP_ORDER,      "sub" },
  { 0x2A, BYTE_REG_OPER_OP_ORDER, "sub" },
  { 0x2B, REG_OPER_OP_ORDER,      "sub" },
  { 0x30, BYTE_OPER_REG_OP_ORDER, "xor" },
  { 0x31, OPER_REG_OP_ORDER,      "xor" },
  { 0x32, BYTE_REG_OPER_OP_ORDER, "xor" },
  { 0x33, REG_OPER_OP_ORDER,      "xor" },
  { 0x38, BYTE_OPER_REG_OP_ORDER, "cmp" },
  { 0x39, OPER_REG_OP_ORDER,      "cmp" },
  { 0x3A, BYTE_REG_OPER_OP_ORDER, "cmp" },
  { 0x3B, REG_OPER_OP_ORDER,      "cmp" },
  { 0x63, REG_OPER_OP_ORDER,      "movsxlq" },
  { 0x84, BYTE_REG_OPER_OP_ORDER, "test" },
  { 0x85, REG_OPER_OP_ORDER,      "test" },
  { 0x86, BYTE_REG_OPER_OP_ORDER, "xchg" },
  { 0x87, REG_OPER_OP_ORDER,      "xchg" },
  { 0x88, BYTE_OPER_REG_OP_ORDER, "mov" },
  { 0x89, OPER_REG_OP_ORDER,      "mov" },
  { 0x8A, BYTE_REG_OPER_OP_ORDER, "mov" },
  { 0x8B, REG_OPER_OP_ORDER,      "mov" },
  { 0x8D, REG_OPER_OP_ORDER,      "lea" },
  { -1, UNSET_OP_ORDER, "" }
};


static const ByteMnemonic zero_operands_instr[] = {
  { 0xC3, UNSET_OP_ORDER, "ret" },
  { 0xC9, UNSET_OP_ORDER, "leave" },
  { 0xF4, UNSET_OP_ORDER, "hlt" },
  { 0xFC, UNSET_OP_ORDER, "cld" },
  { 0xCC, UNSET_OP_ORDER, "int3" },
  { 0x60, UNSET_OP_ORDER, "pushad" },
  { 0x61, UNSET_OP_ORDER, "popad" },
  { 0x9C, UNSET_OP_ORDER, "pushfd" },
  { 0x9D, UNSET_OP_ORDER, "popfd" },
  { 0x9E, UNSET_OP_ORDER, "sahf" },
  { 0x99, UNSET_OP_ORDER, "cdq" },
  { 0x9B, UNSET_OP_ORDER, "fwait" },
  { 0xA4, UNSET_OP_ORDER, "movs" },
  { 0xA5, UNSET_OP_ORDER, "movs" },
  { 0xA6, UNSET_OP_ORDER, "cmps" },
  { 0xA7, UNSET_OP_ORDER, "cmps" },
  { -1, UNSET_OP_ORDER, "" }
};


static const ByteMnemonic call_jump_instr[] = {
  { 0xE8, UNSET_OP_ORDER, "call" },
  { 0xE9, UNSET_OP_ORDER, "jmp" },
  { -1, UNSET_OP_ORDER, "" }
};


static const ByteMnemonic short_immediate_instr[] = {
  { 0x05, UNSET_OP_ORDER, "add" },
  { 0x0D, UNSET_OP_ORDER, "or" },
  { 0x15, UNSET_OP_ORDER, "adc" },
  { 0x1D, UNSET_OP_ORDER, "sbb" },
  { 0x25, UNSET_OP_ORDER, "and" },
  { 0x2D, UNSET_OP_ORDER, "sub" },
  { 0x35, UNSET_OP_ORDER, "xor" },
  { 0x3D, UNSET_OP_ORDER, "cmp" },
  { -1, UNSET_OP_ORDER, "" }
};


static const char* const conditional_code_suffix[] = {
  "o", "no", "c", "nc", "z", "nz", "na", "a",
  "s", "ns", "pe", "po", "l", "ge", "le", "g"
};


enum InstructionType {
  NO_INSTR,
  ZERO_OPERANDS_INSTR,
  TWO_OPERANDS_INSTR,
  JUMP_CONDITIONAL_SHORT_INSTR,
  REGISTER_INSTR,
  PUSHPOP_INSTR,  // Has implicit 64-bit operand size.
  MOVE_REG_INSTR,
  CALL_JUMP_INSTR,
  SHORT_IMMEDIATE_INSTR
};


enum Prefixes {
  ESCAPE_PREFIX = 0x0F,
  OPERAND_SIZE_OVERRIDE_PREFIX = 0x66,
  ADDRESS_SIZE_OVERRIDE_PREFIX = 0x67,
  REPNE_PREFIX = 0xF2,
  REP_PREFIX = 0xF3,
  REPEQ_PREFIX = REP_PREFIX
};


struct InstructionDesc {
  const char* mnem;
  InstructionType type;
  OperandType op_order_;
  bool byte_size_operation;  // Fixed 8-bit operation.
};


class InstructionTable {
 public:
  InstructionTable();
  const InstructionDesc& Get(byte x) const {
    return instructions_[x];
  }

 private:
  InstructionDesc instructions_[256];
  void Clear();
  void Init();
  void CopyTable(const ByteMnemonic bm[], InstructionType type);
  void SetTableRange(InstructionType type, byte start, byte end, bool byte_size,
                     const char* mnem);
  void AddJumpConditionalShort();
};


InstructionTable::InstructionTable() {
  Clear();
  Init();
}


void InstructionTable::Clear() {
  for (int i = 0; i < 256; i++) {
    instructions_[i].mnem = "(bad)";
    instructions_[i].type = NO_INSTR;
    instructions_[i].op_order_ = UNSET_OP_ORDER;
    instructions_[i].byte_size_operation = false;
  }
}


void InstructionTable::Init() {
  CopyTable(two_operands_instr, TWO_OPERANDS_INSTR);
  CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR);
  CopyTable(call_jump_instr, CALL_JUMP_INSTR);
  CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
  AddJumpConditionalShort();
  SetTableRange(PUSHPOP_INSTR, 0x50, 0x57, false, "push");
  SetTableRange(PUSHPOP_INSTR, 0x58, 0x5F, false, "pop");
  SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, false, "mov");
}


void InstructionTable::CopyTable(const ByteMnemonic bm[],
                                 InstructionType type) {
  for (int i = 0; bm[i].b >= 0; i++) {
    InstructionDesc* id = &instructions_[bm[i].b];
    id->mnem = bm[i].mnem;
    OperandType op_order = bm[i].op_order_;
    id->op_order_ =
        static_cast<OperandType>(op_order & ~BYTE_SIZE_OPERAND_FLAG);
    ASSERT_EQ(NO_INSTR, id->type);  // Information not already entered
    id->type = type;
    id->byte_size_operation = ((op_order & BYTE_SIZE_OPERAND_FLAG) != 0);
  }
}


void InstructionTable::SetTableRange(InstructionType type,
                                     byte start,
                                     byte end,
                                     bool byte_size,
                                     const char* mnem) {
  for (byte b = start; b <= end; b++) {
    InstructionDesc* id = &instructions_[b];
    ASSERT_EQ(NO_INSTR, id->type);  // Information not already entered
    id->mnem = mnem;
    id->type = type;
    id->byte_size_operation = byte_size;
  }
}


void InstructionTable::AddJumpConditionalShort() {
  for (byte b = 0x70; b <= 0x7F; b++) {
    InstructionDesc* id = &instructions_[b];
    ASSERT_EQ(NO_INSTR, id->type);  // Information not already entered
    id->mnem = NULL;  // Computed depending on condition code.
    id->type = JUMP_CONDITIONAL_SHORT_INSTR;
  }
}


static v8::internal::LazyInstance<InstructionTable>::type instruction_table =
    LAZY_INSTANCE_INITIALIZER;


static InstructionDesc cmov_instructions[16] = {
  {"cmovo", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovno", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovc", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovnc", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovz", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovnz", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovna", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmova", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovs", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovns", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovpe", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovpo", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovl", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovge", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovle", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
  {"cmovg", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false}
};

//------------------------------------------------------------------------------
// DisassemblerX64 implementation.

enum UnimplementedOpcodeAction {
  CONTINUE_ON_UNIMPLEMENTED_OPCODE,
  ABORT_ON_UNIMPLEMENTED_OPCODE
};

// A new DisassemblerX64 object is created to disassemble each instruction.
// The object can only disassemble a single instruction.
class DisassemblerX64 {
 public:
  DisassemblerX64(const NameConverter& converter,
                  UnimplementedOpcodeAction unimplemented_action =
                      ABORT_ON_UNIMPLEMENTED_OPCODE)
      : converter_(converter),
        tmp_buffer_pos_(0),
        abort_on_unimplemented_(
            unimplemented_action == ABORT_ON_UNIMPLEMENTED_OPCODE),
        rex_(0),
        operand_size_(0),
        group_1_prefix_(0),
        byte_size_operand_(false) {
    tmp_buffer_[0] = '\0';
  }

  virtual ~DisassemblerX64() {
  }

  // Writes one disassembled instruction into 'buffer' (0-terminated).
  // Returns the length of the disassembled machine instruction in bytes.
  int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction);

 private:
  enum OperandSize {
    BYTE_SIZE = 0,
    WORD_SIZE = 1,
    DOUBLEWORD_SIZE = 2,
    QUADWORD_SIZE = 3
  };

  const NameConverter& converter_;
  v8::internal::EmbeddedVector<char, 128> tmp_buffer_;
  unsigned int tmp_buffer_pos_;
  bool abort_on_unimplemented_;
  // Prefixes parsed
  byte rex_;
  byte operand_size_;  // 0x66 or (if no group 3 prefix is present) 0x0.
  byte group_1_prefix_;  // 0xF2, 0xF3, or (if no group 1 prefix is present) 0.
  // Byte size operand override.
  bool byte_size_operand_;

  void setRex(byte rex) {
    ASSERT_EQ(0x40, rex & 0xF0);
    rex_ = rex;
  }

  bool rex() { return rex_ != 0; }

  bool rex_b() { return (rex_ & 0x01) != 0; }

  // Actual number of base register given the low bits and the rex.b state.
  int base_reg(int low_bits) { return low_bits | ((rex_ & 0x01) << 3); }

  bool rex_x() { return (rex_ & 0x02) != 0; }

  bool rex_r() { return (rex_ & 0x04) != 0; }

  bool rex_w() { return (rex_ & 0x08) != 0; }

  OperandSize operand_size() {
    if (byte_size_operand_) return BYTE_SIZE;
    if (rex_w()) return QUADWORD_SIZE;
    if (operand_size_ != 0) return WORD_SIZE;
    return DOUBLEWORD_SIZE;
  }

  char operand_size_code() {
    return "bwlq"[operand_size()];
  }

  const char* NameOfCPURegister(int reg) const {
    return converter_.NameOfCPURegister(reg);
  }

  const char* NameOfByteCPURegister(int reg) const {
    return converter_.NameOfByteCPURegister(reg);
  }

  const char* NameOfXMMRegister(int reg) const {
    return converter_.NameOfXMMRegister(reg);
  }

  const char* NameOfAddress(byte* addr) const {
    return converter_.NameOfAddress(addr);
  }

  // Disassembler helper functions.
  void get_modrm(byte data,
                 int* mod,
                 int* regop,
                 int* rm) {
    *mod = (data >> 6) & 3;
    *regop = ((data & 0x38) >> 3) | (rex_r() ? 8 : 0);
    *rm = (data & 7) | (rex_b() ? 8 : 0);
  }

  void get_sib(byte data,
               int* scale,
               int* index,
               int* base) {
    *scale = (data >> 6) & 3;
    *index = ((data >> 3) & 7) | (rex_x() ? 8 : 0);
    *base = (data & 7) | (rex_b() ? 8 : 0);
  }

  typedef const char* (DisassemblerX64::*RegisterNameMapping)(int reg) const;

  int PrintRightOperandHelper(byte* modrmp,
                              RegisterNameMapping register_name);
  int PrintRightOperand(byte* modrmp);
  int PrintRightByteOperand(byte* modrmp);
  int PrintRightXMMOperand(byte* modrmp);
  int PrintOperands(const char* mnem,
                    OperandType op_order,
                    byte* data);
  int PrintImmediate(byte* data, OperandSize size);
  int PrintImmediateOp(byte* data);
  const char* TwoByteMnemonic(byte opcode);
  int TwoByteOpcodeInstruction(byte* data);
  int F6F7Instruction(byte* data);
  int ShiftInstruction(byte* data);
  int JumpShort(byte* data);
  int JumpConditional(byte* data);
  int JumpConditionalShort(byte* data);
  int SetCC(byte* data);
  int FPUInstruction(byte* data);
  int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start);
  int RegisterFPUInstruction(int escape_opcode, byte modrm_byte);
  void AppendToBuffer(const char* format, ...);

  void UnimplementedInstruction() {
    if (abort_on_unimplemented_) {
      CHECK(false);
    } else {
      AppendToBuffer("'Unimplemented Instruction'");
    }
  }
};


void DisassemblerX64::AppendToBuffer(const char* format, ...) {
  v8::internal::Vector<char> buf = tmp_buffer_ + tmp_buffer_pos_;
  va_list args;
  va_start(args, format);
  int result = v8::internal::OS::VSNPrintF(buf, format, args);
  va_end(args);
  tmp_buffer_pos_ += result;
}


int DisassemblerX64::PrintRightOperandHelper(
    byte* modrmp,
    RegisterNameMapping direct_register_name) {
  int mod, regop, rm;
  get_modrm(*modrmp, &mod, &regop, &rm);
  RegisterNameMapping register_name = (mod == 3) ? direct_register_name :
      &DisassemblerX64::NameOfCPURegister;
  switch (mod) {
    case 0:
      if ((rm & 7) == 5) {
        int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1);
        AppendToBuffer("[0x%x]", disp);
        return 5;
      } else if ((rm & 7) == 4) {
        // Codes for SIB byte.
        byte sib = *(modrmp + 1);
        int scale, index, base;
        get_sib(sib, &scale, &index, &base);
        if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) {
          // index == rsp means no index. Only use sib byte with no index for
          // rsp and r12 base.
          AppendToBuffer("[%s]", NameOfCPURegister(base));
          return 2;
        } else if (base == 5) {
          // base == rbp means no base register (when mod == 0).
          int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2);
          AppendToBuffer("[%s*%d+0x%x]",
                         NameOfCPURegister(index),
                         1 << scale, disp);
          return 6;
        } else if (index != 4 && base != 5) {
          // [base+index*scale]
          AppendToBuffer("[%s+%s*%d]",
                         NameOfCPURegister(base),
                         NameOfCPURegister(index),
                         1 << scale);
          return 2;
        } else {
          UnimplementedInstruction();
          return 1;
        }
      } else {
        AppendToBuffer("[%s]", NameOfCPURegister(rm));
        return 1;
      }
      break;
    case 1:  // fall through
    case 2:
      if ((rm & 7) == 4) {
        byte sib = *(modrmp + 1);
        int scale, index, base;
        get_sib(sib, &scale, &index, &base);
        int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2)
                              : *reinterpret_cast<char*>(modrmp + 2);
        if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) {
          if (-disp > 0) {
            AppendToBuffer("[%s-0x%x]", NameOfCPURegister(base), -disp);
          } else {
            AppendToBuffer("[%s+0x%x]", NameOfCPURegister(base), disp);
          }
        } else {
          if (-disp > 0) {
            AppendToBuffer("[%s+%s*%d-0x%x]",
                           NameOfCPURegister(base),
                           NameOfCPURegister(index),
                           1 << scale,
                           -disp);
          } else {
            AppendToBuffer("[%s+%s*%d+0x%x]",
                           NameOfCPURegister(base),
                           NameOfCPURegister(index),
                           1 << scale,
                           disp);
          }
        }
        return mod == 2 ? 6 : 3;
      } else {
        // No sib.
        int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1)
                              : *reinterpret_cast<char*>(modrmp + 1);
        if (-disp > 0) {
        AppendToBuffer("[%s-0x%x]", NameOfCPURegister(rm), -disp);
        } else {
        AppendToBuffer("[%s+0x%x]", NameOfCPURegister(rm), disp);
        }
        return (mod == 2) ? 5 : 2;
      }
      break;
    case 3:
      AppendToBuffer("%s", (this->*register_name)(rm));
      return 1;
    default:
      UnimplementedInstruction();
      return 1;
  }
  UNREACHABLE();
}


int DisassemblerX64::PrintImmediate(byte* data, OperandSize size) {
  int64_t value;
  int count;
  switch (size) {
    case BYTE_SIZE:
      value = *data;
      count = 1;
      break;
    case WORD_SIZE:
      value = *reinterpret_cast<int16_t*>(data);
      count = 2;
      break;
    case DOUBLEWORD_SIZE:
      value = *reinterpret_cast<uint32_t*>(data);
      count = 4;
      break;
    case QUADWORD_SIZE:
      value = *reinterpret_cast<int32_t*>(data);
      count = 4;
      break;
    default:
      UNREACHABLE();
      value = 0;  // Initialize variables on all paths to satisfy the compiler.
      count = 0;
  }
  AppendToBuffer("%" V8_PTR_PREFIX "x", value);
  return count;
}


int DisassemblerX64::PrintRightOperand(byte* modrmp) {
  return PrintRightOperandHelper(modrmp,
                                 &DisassemblerX64::NameOfCPURegister);
}


int DisassemblerX64::PrintRightByteOperand(byte* modrmp) {
  return PrintRightOperandHelper(modrmp,
                                 &DisassemblerX64::NameOfByteCPURegister);
}


int DisassemblerX64::PrintRightXMMOperand(byte* modrmp) {
  return PrintRightOperandHelper(modrmp,
                                 &DisassemblerX64::NameOfXMMRegister);
}


// Returns number of bytes used including the current *data.
// Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'.
int DisassemblerX64::PrintOperands(const char* mnem,
                                   OperandType op_order,
                                   byte* data) {
  byte modrm = *data;
  int mod, regop, rm;
  get_modrm(modrm, &mod, &regop, &rm);
  int advance = 0;
  const char* register_name =
      byte_size_operand_ ? NameOfByteCPURegister(regop)
                         : NameOfCPURegister(regop);
  switch (op_order) {
    case REG_OPER_OP_ORDER: {
      AppendToBuffer("%s%c %s,",
                     mnem,
                     operand_size_code(),
                     register_name);
      advance = byte_size_operand_ ? PrintRightByteOperand(data)
                                   : PrintRightOperand(data);
      break;
    }
    case OPER_REG_OP_ORDER: {
      AppendToBuffer("%s%c ", mnem, operand_size_code());
      advance = byte_size_operand_ ? PrintRightByteOperand(data)
                                   : PrintRightOperand(data);
      AppendToBuffer(",%s", register_name);
      break;
    }
    default:
      UNREACHABLE();
      break;
  }
  return advance;
}


// Returns number of bytes used by machine instruction, including *data byte.
// Writes immediate instructions to 'tmp_buffer_'.
int DisassemblerX64::PrintImmediateOp(byte* data) {
  bool byte_size_immediate = (*data & 0x02) != 0;
  byte modrm = *(data + 1);
  int mod, regop, rm;
  get_modrm(modrm, &mod, &regop, &rm);
  const char* mnem = "Imm???";
  switch (regop) {
    case 0:
      mnem = "add";
      break;
    case 1:
      mnem = "or";
      break;
    case 2:
      mnem = "adc";
      break;
    case 3:
      mnem = "sbb";
      break;
    case 4:
      mnem = "and";
      break;
    case 5:
      mnem = "sub";
      break;
    case 6:
      mnem = "xor";
      break;
    case 7:
      mnem = "cmp";
      break;
    default:
      UnimplementedInstruction();
  }
  AppendToBuffer("%s%c ", mnem, operand_size_code());
  int count = PrintRightOperand(data + 1);
  AppendToBuffer(",0x");
  OperandSize immediate_size = byte_size_immediate ? BYTE_SIZE : operand_size();
  count += PrintImmediate(data + 1 + count, immediate_size);
  return 1 + count;
}


// Returns number of bytes used, including *data.
int DisassemblerX64::F6F7Instruction(byte* data) {
  ASSERT(*data == 0xF7 || *data == 0xF6);
  byte modrm = *(data + 1);
  int mod, regop, rm;
  get_modrm(modrm, &mod, &regop, &rm);
  if (mod == 3 && regop != 0) {
    const char* mnem = NULL;
    switch (regop) {
      case 2:
        mnem = "not";
        break;
      case 3:
        mnem = "neg";
        break;
      case 4:
        mnem = "mul";
        break;
      case 7:
        mnem = "idiv";
        break;
      default:
        UnimplementedInstruction();
    }
    AppendToBuffer("%s%c %s",
                   mnem,
                   operand_size_code(),
                   NameOfCPURegister(rm));
    return 2;
  } else if (regop == 0) {
    AppendToBuffer("test%c ", operand_size_code());
    int count = PrintRightOperand(data + 1);  // Use name of 64-bit register.
    AppendToBuffer(",0x");
    count += PrintImmediate(data + 1 + count, operand_size());
    return 1 + count;
  } else {
    UnimplementedInstruction();
    return 2;
  }
}


int DisassemblerX64::ShiftInstruction(byte* data) {
  byte op = *data & (~1);
  if (op != 0xD0 && op != 0xD2 && op != 0xC0) {
    UnimplementedInstruction();
    return 1;
  }
  byte modrm = *(data + 1);
  int mod, regop, rm;
  get_modrm(modrm, &mod, &regop, &rm);
  regop &= 0x7;  // The REX.R bit does not affect the operation.
  int imm8 = -1;
  int num_bytes = 2;
  if (mod != 3) {
    UnimplementedInstruction();
    return num_bytes;
  }
  const char* mnem = NULL;
  switch (regop) {
    case 0:
      mnem = "rol";
      break;
    case 1:
      mnem = "ror";
      break;
    case 2:
      mnem = "rcl";
      break;
    case 3:
      mnem = "rcr";
      break;
    case 4:
      mnem = "shl";
      break;
    case 5:
      mnem = "shr";
      break;
    case 7:
      mnem = "sar";
      break;
    default:
      UnimplementedInstruction();
      return num_bytes;
  }
  ASSERT_NE(NULL, mnem);
  if (op == 0xD0) {
    imm8 = 1;
  } else if (op == 0xC0) {
    imm8 = *(data + 2);
    num_bytes = 3;
  }
  AppendToBuffer("%s%c %s,",
                 mnem,
                 operand_size_code(),
                 byte_size_operand_ ? NameOfByteCPURegister(rm)
                                    : NameOfCPURegister(rm));
  if (op == 0xD2) {
    AppendToBuffer("cl");
  } else {
    AppendToBuffer("%d", imm8);
  }
  return num_bytes;
}


// Returns number of bytes used, including *data.
int DisassemblerX64::JumpShort(byte* data) {
  ASSERT_EQ(0xEB, *data);
  byte b = *(data + 1);
  byte* dest = data + static_cast<int8_t>(b) + 2;
  AppendToBuffer("jmp %s", NameOfAddress(dest));
  return 2;
}


// Returns number of bytes used, including *data.
int DisassemblerX64::JumpConditional(byte* data) {
  ASSERT_EQ(0x0F, *data);
  byte cond = *(data + 1) & 0x0F;
  byte* dest = data + *reinterpret_cast<int32_t*>(data + 2) + 6;
  const char* mnem = conditional_code_suffix[cond];
  AppendToBuffer("j%s %s", mnem, NameOfAddress(dest));
  return 6;  // includes 0x0F
}


// Returns number of bytes used, including *data.
int DisassemblerX64::JumpConditionalShort(byte* data) {
  byte cond = *data & 0x0F;
  byte b = *(data + 1);
  byte* dest = data + static_cast<int8_t>(b) + 2;
  const char* mnem = conditional_code_suffix[cond];
  AppendToBuffer("j%s %s", mnem, NameOfAddress(dest));
  return 2;
}


// Returns number of bytes used, including *data.
int DisassemblerX64::SetCC(byte* data) {
  ASSERT_EQ(0x0F, *data);
  byte cond = *(data + 1) & 0x0F;
  const char* mnem = conditional_code_suffix[cond];
  AppendToBuffer("set%s%c ", mnem, operand_size_code());
  PrintRightByteOperand(data + 2);
  return 3;  // includes 0x0F
}


// Returns number of bytes used, including *data.
int DisassemblerX64::FPUInstruction(byte* data) {
  byte escape_opcode = *data;
  ASSERT_EQ(0xD8, escape_opcode & 0xF8);
  byte modrm_byte = *(data+1);

  if (modrm_byte >= 0xC0) {
    return RegisterFPUInstruction(escape_opcode, modrm_byte);
  } else {
    return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1);
  }
}

int DisassemblerX64::MemoryFPUInstruction(int escape_opcode,
                                           int modrm_byte,
                                           byte* modrm_start) {
  const char* mnem = "?";
  int regop = (modrm_byte >> 3) & 0x7;  // reg/op field of modrm byte.
  switch (escape_opcode) {
    case 0xD9: switch (regop) {
        case 0: mnem = "fld_s"; break;
        case 3: mnem = "fstp_s"; break;
        case 7: mnem = "fstcw"; break;
        default: UnimplementedInstruction();
      }
      break;

    case 0xDB: switch (regop) {
        case 0: mnem = "fild_s"; break;
        case 1: mnem = "fisttp_s"; break;
        case 2: mnem = "fist_s"; break;
        case 3: mnem = "fistp_s"; break;
        default: UnimplementedInstruction();
      }
      break;

    case 0xDD: switch (regop) {
        case 0: mnem = "fld_d"; break;
        case 3: mnem = "fstp_d"; break;
        default: UnimplementedInstruction();
      }
      break;

    case 0xDF: switch (regop) {
        case 5: mnem = "fild_d"; break;
        case 7: mnem = "fistp_d"; break;
        default: UnimplementedInstruction();
      }
      break;

    default: UnimplementedInstruction();
  }
  AppendToBuffer("%s ", mnem);
  int count = PrintRightOperand(modrm_start);
  return count + 1;
}

int DisassemblerX64::RegisterFPUInstruction(int escape_opcode,
                                             byte modrm_byte) {
  bool has_register = false;  // Is the FPU register encoded in modrm_byte?
  const char* mnem = "?";

  switch (escape_opcode) {
    case 0xD8:
      UnimplementedInstruction();
      break;

    case 0xD9:
      switch (modrm_byte & 0xF8) {
        case 0xC0:
          mnem = "fld";
          has_register = true;
          break;
        case 0xC8:
          mnem = "fxch";
          has_register = true;
          break;
        default:
          switch (modrm_byte) {
            case 0xE0: mnem = "fchs"; break;
            case 0xE1: mnem = "fabs"; break;
            case 0xE3: mnem = "fninit"; break;
            case 0xE4: mnem = "ftst"; break;
            case 0xE8: mnem = "fld1"; break;
            case 0xEB: mnem = "fldpi"; break;
            case 0xED: mnem = "fldln2"; break;
            case 0xEE: mnem = "fldz"; break;
            case 0xF0: mnem = "f2xm1"; break;
            case 0xF1: mnem = "fyl2x"; break;
            case 0xF2: mnem = "fptan"; break;
            case 0xF5: mnem = "fprem1"; break;
            case 0xF7: mnem = "fincstp"; break;
            case 0xF8: mnem = "fprem"; break;
            case 0xFD: mnem = "fscale"; break;
            case 0xFE: mnem = "fsin"; break;
            case 0xFF: mnem = "fcos"; break;
            default: UnimplementedInstruction();
          }
      }
      break;

    case 0xDA:
      if (modrm_byte == 0xE9) {
        mnem = "fucompp";
      } else {
        UnimplementedInstruction();
      }
      break;

    case 0xDB:
      if ((modrm_byte & 0xF8) == 0xE8) {
        mnem = "fucomi";
        has_register = true;
      } else if (modrm_byte  == 0xE2) {
        mnem = "fclex";
      } else {
        UnimplementedInstruction();
      }
      break;

    case 0xDC:
      has_register = true;
      switch (modrm_byte & 0xF8) {
        case 0xC0: mnem = "fadd"; break;
        case 0xE8: mnem = "fsub"; break;
        case 0xC8: mnem = "fmul"; break;
        case 0xF8: mnem = "fdiv"; break;
        default: UnimplementedInstruction();
      }
      break;

    case 0xDD:
      has_register = true;
      switch (modrm_byte & 0xF8) {
        case 0xC0: mnem = "ffree"; break;
        case 0xD8: mnem = "fstp"; break;
        default: UnimplementedInstruction();
      }
      break;

    case 0xDE:
      if (modrm_byte  == 0xD9) {
        mnem = "fcompp";
      } else {
        has_register = true;
        switch (modrm_byte & 0xF8) {
          case 0xC0: mnem = "faddp"; break;
          case 0xE8: mnem = "fsubp"; break;
          case 0xC8: mnem = "fmulp"; break;
          case 0xF8: mnem = "fdivp"; break;
          default: UnimplementedInstruction();
        }
      }
      break;

    case 0xDF:
      if (modrm_byte == 0xE0) {
        mnem = "fnstsw_ax";
      } else if ((modrm_byte & 0xF8) == 0xE8) {
        mnem = "fucomip";
        has_register = true;
      }
      break;

    default: UnimplementedInstruction();
  }

  if (has_register) {
    AppendToBuffer("%s st%d", mnem, modrm_byte & 0x7);
  } else {
    AppendToBuffer("%s", mnem);
  }
  return 2;
}



// Handle all two-byte opcodes, which start with 0x0F.
// These instructions may be affected by an 0x66, 0xF2, or 0xF3 prefix.
// We do not use any three-byte opcodes, which start with 0x0F38 or 0x0F3A.
int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
  byte opcode = *(data + 1);
  byte* current = data + 2;
  // At return, "current" points to the start of the next instruction.
  const char* mnemonic = TwoByteMnemonic(opcode);
  if (operand_size_ == 0x66) {
    // 0x66 0x0F prefix.
    int mod, regop, rm;
    if (opcode == 0x3A) {
      byte third_byte = *current;
      current = data + 3;
      if (third_byte == 0x17) {
        get_modrm(*current, &mod, &regop, &rm);
        AppendToBuffer("extractps ");  // reg/m32, xmm, imm8
        current += PrintRightOperand(current);
        AppendToBuffer(", %s, %d", NameOfCPURegister(regop), (*current) & 3);
        current += 1;
      } else if (third_byte == 0x0b) {
        get_modrm(*current, &mod, &regop, &rm);
         // roundsd xmm, xmm/m64, imm8
        AppendToBuffer("roundsd %s, ", NameOfCPURegister(regop));
        current += PrintRightOperand(current);
        AppendToBuffer(", %d", (*current) & 3);
        current += 1;
      } else {
        UnimplementedInstruction();
      }
    } else {
      get_modrm(*current, &mod, &regop, &rm);
      if (opcode == 0x1f) {
        current++;
        if (rm == 4) {  // SIB byte present.
          current++;
        }
        if (mod == 1) {  // Byte displacement.
          current += 1;
        } else if (mod == 2) {  // 32-bit displacement.
          current += 4;
        }  // else no immediate displacement.
        AppendToBuffer("nop");
      } else if (opcode == 0x28) {
        AppendToBuffer("movapd %s, ", NameOfXMMRegister(regop));
        current += PrintRightXMMOperand(current);
      } else if (opcode == 0x29) {
        AppendToBuffer("movapd ");
        current += PrintRightXMMOperand(current);
        AppendToBuffer(", %s", NameOfXMMRegister(regop));
      } else if (opcode == 0x6E) {
        AppendToBuffer("mov%c %s,",
                       rex_w() ? 'q' : 'd',
                       NameOfXMMRegister(regop));
        current += PrintRightOperand(current);
      } else if (opcode == 0x6F) {
        AppendToBuffer("movdqa %s,",
                       NameOfXMMRegister(regop));
        current += PrintRightXMMOperand(current);
      } else if (opcode == 0x7E) {
        AppendToBuffer("mov%c ",
                       rex_w() ? 'q' : 'd');
        current += PrintRightOperand(current);
        AppendToBuffer(", %s", NameOfXMMRegister(regop));
      } else if (opcode == 0x7F) {
        AppendToBuffer("movdqa ");
        current += PrintRightXMMOperand(current);
        AppendToBuffer(", %s", NameOfXMMRegister(regop));
      } else if (opcode == 0xD6) {
        AppendToBuffer("movq ");
        current += PrintRightXMMOperand(current);
        AppendToBuffer(", %s", NameOfXMMRegister(regop));
      } else if (opcode == 0x50) {
        AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop));
        current += PrintRightXMMOperand(current);
      } else {
        const char* mnemonic = "?";
        if (opcode == 0x54) {
          mnemonic = "andpd";
        } else  if (opcode == 0x56) {
          mnemonic = "orpd";
        } else  if (opcode == 0x57) {
          mnemonic = "xorpd";
        } else if (opcode == 0x2E) {
          mnemonic = "ucomisd";
        } else if (opcode == 0x2F) {
          mnemonic = "comisd";
        } else {
          UnimplementedInstruction();
        }
        AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop));
        current += PrintRightXMMOperand(current);
      }
    }
  } else if (group_1_prefix_ == 0xF2) {
    // Beginning of instructions with prefix 0xF2.

    if (opcode == 0x11 || opcode == 0x10) {
      // MOVSD: Move scalar double-precision fp to/from/between XMM registers.
      AppendToBuffer("movsd ");
      int mod, regop, rm;
      get_modrm(*current, &mod, &regop, &rm);
      if (opcode == 0x11) {
        current += PrintRightXMMOperand(current);
        AppendToBuffer(",%s", NameOfXMMRegister(regop));
      } else {
        AppendToBuffer("%s,", NameOfXMMRegister(regop));
        current += PrintRightXMMOperand(current);
      }
    } else if (opcode == 0x2A) {
      // CVTSI2SD: integer to XMM double conversion.
      int mod, regop, rm;
      get_modrm(*current, &mod, &regop, &rm);
      AppendToBuffer("%sd %s,", mnemonic, NameOfXMMRegister(regop));
      current += PrintRightOperand(current);
    } else if (opcode == 0x2C) {
      // CVTTSD2SI:
      // Convert with truncation scalar double-precision FP to integer.
      int mod, regop, rm;
      get_modrm(*current, &mod, &regop, &rm);
      AppendToBuffer("cvttsd2si%c %s,",
          operand_size_code(), NameOfCPURegister(regop));
      current += PrintRightXMMOperand(current);
    } else if (opcode == 0x2D) {
      // CVTSD2SI: Convert scalar double-precision FP to integer.
      int mod, regop, rm;
      get_modrm(*current, &mod, &regop, &rm);
      AppendToBuffer("cvtsd2si%c %s,",
          operand_size_code(), NameOfCPURegister(regop));
      current += PrintRightXMMOperand(current);
    } else if ((opcode & 0xF8) == 0x58 || opcode == 0x51) {
      // XMM arithmetic. Mnemonic was retrieved at the start of this function.
      int mod, regop, rm;
      get_modrm(*current, &mod, &regop, &rm);
      AppendToBuffer("%s %s,", mnemonic, NameOfXMMRegister(regop));
      current += PrintRightXMMOperand(current);
    } else {
      UnimplementedInstruction();
    }
  } else if (group_1_prefix_ == 0xF3) {
    // Instructions with prefix 0xF3.
    if (opcode == 0x11 || opcode == 0x10) {
      // MOVSS: Move scalar double-precision fp to/from/between XMM registers.
      AppendToBuffer("movss ");
      int mod, regop, rm;
      get_modrm(*current, &mod, &regop, &rm);
      if (opcode == 0x11) {
        current += PrintRightOperand(current);
        AppendToBuffer(",%s", NameOfXMMRegister(regop));
      } else {
        AppendToBuffer("%s,", NameOfXMMRegister(regop));
        current += PrintRightOperand(current);
      }
    } else if (opcode == 0x2A) {
      // CVTSI2SS: integer to XMM single conversion.
      int mod, regop, rm;
      get_modrm(*current, &mod, &regop, &rm);
      AppendToBuffer("%ss %s,", mnemonic, NameOfXMMRegister(regop));
      current += PrintRightOperand(current);
    } else if (opcode == 0x2C) {
      // CVTTSS2SI:
      // Convert with truncation scalar single-precision FP to dword integer.
      int mod, regop, rm;
      get_modrm(*current, &mod, &regop, &rm);
      AppendToBuffer("cvttss2si%c %s,",
          operand_size_code(), NameOfCPURegister(regop));
      current += PrintRightXMMOperand(current);
    } else if (opcode == 0x5A) {
      // CVTSS2SD:
      // Convert scalar single-precision FP to scalar double-precision FP.
      int mod, regop, rm;
      get_modrm(*current, &mod, &regop, &rm);
      AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop));
      current += PrintRightXMMOperand(current);
    } else if (opcode == 0x7E) {
      int mod, regop, rm;
      get_modrm(*current, &mod, &regop, &rm);
      AppendToBuffer("movq %s, ", NameOfXMMRegister(regop));
      current += PrintRightXMMOperand(current);
    } else {
      UnimplementedInstruction();
    }
  } else if (opcode == 0x1F) {
    // NOP
    int mod, regop, rm;
    get_modrm(*current, &mod, &regop, &rm);
    current++;
    if (rm == 4) {  // SIB byte present.
      current++;
    }
    if (mod == 1) {  // Byte displacement.
      current += 1;
    } else if (mod == 2) {  // 32-bit displacement.
      current += 4;
    }  // else no immediate displacement.
    AppendToBuffer("nop");

  } else if (opcode == 0x28) {
    // movaps xmm, xmm/m128
    int mod, regop, rm;
    get_modrm(*current, &mod, &regop, &rm);
    AppendToBuffer("movaps %s, ", NameOfXMMRegister(regop));
    current += PrintRightXMMOperand(current);

  } else if (opcode == 0x29) {
    // movaps xmm/m128, xmm
    int mod, regop, rm;
    get_modrm(*current, &mod, &regop, &rm);
    AppendToBuffer("movaps ");
    current += PrintRightXMMOperand(current);
    AppendToBuffer(", %s", NameOfXMMRegister(regop));

  } else if (opcode == 0xA2 || opcode == 0x31) {
    // RDTSC or CPUID
    AppendToBuffer("%s", mnemonic);

  } else if ((opcode & 0xF0) == 0x40) {
    // CMOVcc: conditional move.
    int condition = opcode & 0x0F;
    const InstructionDesc& idesc = cmov_instructions[condition];
    byte_size_operand_ = idesc.byte_size_operation;
    current += PrintOperands(idesc.mnem, idesc.op_order_, current);

  } else if (opcode == 0x57) {
    // xorps xmm, xmm/m128
    int mod, regop, rm;
    get_modrm(*current, &mod, &regop, &rm);
    AppendToBuffer("xorps %s, ", NameOfXMMRegister(regop));
    current += PrintRightXMMOperand(current);

  } else if ((opcode & 0xF0) == 0x80) {
    // Jcc: Conditional jump (branch).
    current = data + JumpConditional(data);

  } else if (opcode == 0xBE || opcode == 0xBF || opcode == 0xB6 ||
             opcode == 0xB7 || opcode == 0xAF) {
    // Size-extending moves, IMUL.
    current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current);

  } else if ((opcode & 0xF0) == 0x90) {
    // SETcc: Set byte on condition. Needs pointer to beginning of instruction.
    current = data + SetCC(data);

  } else if (opcode == 0xAB || opcode == 0xA5 || opcode == 0xAD) {
    // SHLD, SHRD (double-precision shift), BTS (bit set).
    AppendToBuffer("%s ", mnemonic);
    int mod, regop, rm;
    get_modrm(*current, &mod, &regop, &rm);
    current += PrintRightOperand(current);
    if (opcode == 0xAB) {
      AppendToBuffer(",%s", NameOfCPURegister(regop));
    } else {
      AppendToBuffer(",%s,cl", NameOfCPURegister(regop));
    }
  } else {
    UnimplementedInstruction();
  }
  return static_cast<int>(current - data);
}


// Mnemonics for two-byte opcode instructions starting with 0x0F.
// The argument is the second byte of the two-byte opcode.
// Returns NULL if the instruction is not handled here.
const char* DisassemblerX64::TwoByteMnemonic(byte opcode) {
  switch (opcode) {
    case 0x1F:
      return "nop";
    case 0x2A:  // F2/F3 prefix.
      return "cvtsi2s";
    case 0x31:
      return "rdtsc";
    case 0x51:  // F2 prefix.
      return "sqrtsd";
    case 0x58:  // F2 prefix.
      return "addsd";
    case 0x59:  // F2 prefix.
      return "mulsd";
    case 0x5C:  // F2 prefix.
      return "subsd";
    case 0x5E:  // F2 prefix.
      return "divsd";
    case 0xA2:
      return "cpuid";
    case 0xA5:
      return "shld";
    case 0xAB:
      return "bts";
    case 0xAD:
      return "shrd";
    case 0xAF:
      return "imul";
    case 0xB6:
      return "movzxb";
    case 0xB7:
      return "movzxw";
    case 0xBE:
      return "movsxb";
    case 0xBF:
      return "movsxw";
    default:
      return NULL;
  }
}


// Disassembles the instruction at instr, and writes it into out_buffer.
int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
                                       byte* instr) {
  tmp_buffer_pos_ = 0;  // starting to write as position 0
  byte* data = instr;
  bool processed = true;  // Will be set to false if the current instruction
                          // is not in 'instructions' table.
  byte current;

  // Scan for prefixes.
  while (true) {
    current = *data;
    if (current == OPERAND_SIZE_OVERRIDE_PREFIX) {  // Group 3 prefix.
      operand_size_ = current;
    } else if ((current & 0xF0) == 0x40) {  // REX prefix.
      setRex(current);
      if (rex_w()) AppendToBuffer("REX.W ");
    } else if ((current & 0xFE) == 0xF2) {  // Group 1 prefix (0xF2 or 0xF3).
      group_1_prefix_ = current;
    } else {  // Not a prefix - an opcode.
      break;
    }
    data++;
  }

  const InstructionDesc& idesc = instruction_table.Get().Get(current);
  byte_size_operand_ = idesc.byte_size_operation;
  switch (idesc.type) {
    case ZERO_OPERANDS_INSTR:
      if (current >= 0xA4 && current <= 0xA7) {
        // String move or compare operations.
        if (group_1_prefix_ == REP_PREFIX) {
          // REP.
          AppendToBuffer("rep ");
        }
        if (rex_w()) AppendToBuffer("REX.W ");
        AppendToBuffer("%s%c", idesc.mnem, operand_size_code());
      } else {
        AppendToBuffer("%s", idesc.mnem, operand_size_code());
      }
      data++;
      break;

    case TWO_OPERANDS_INSTR:
      data++;
      data += PrintOperands(idesc.mnem, idesc.op_order_, data);
      break;

    case JUMP_CONDITIONAL_SHORT_INSTR:
      data += JumpConditionalShort(data);
      break;

    case REGISTER_INSTR:
      AppendToBuffer("%s%c %s",
                     idesc.mnem,
                     operand_size_code(),
                     NameOfCPURegister(base_reg(current & 0x07)));
      data++;
      break;
    case PUSHPOP_INSTR:
      AppendToBuffer("%s %s",
                     idesc.mnem,
                     NameOfCPURegister(base_reg(current & 0x07)));
      data++;
      break;
    case MOVE_REG_INSTR: {
      byte* addr = NULL;
      switch (operand_size()) {
        case WORD_SIZE:
          addr = reinterpret_cast<byte*>(*reinterpret_cast<int16_t*>(data + 1));
          data += 3;
          break;
        case DOUBLEWORD_SIZE:
          addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
          data += 5;
          break;
        case QUADWORD_SIZE:
          addr = reinterpret_cast<byte*>(*reinterpret_cast<int64_t*>(data + 1));
          data += 9;
          break;
        default:
          UNREACHABLE();
      }
      AppendToBuffer("mov%c %s,%s",
                     operand_size_code(),
                     NameOfCPURegister(base_reg(current & 0x07)),
                     NameOfAddress(addr));
      break;
    }

    case CALL_JUMP_INSTR: {
      byte* addr = data + *reinterpret_cast<int32_t*>(data + 1) + 5;
      AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr));
      data += 5;
      break;
    }

    case SHORT_IMMEDIATE_INSTR: {
      byte* addr =
          reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
      AppendToBuffer("%s rax, %s", idesc.mnem, NameOfAddress(addr));
      data += 5;
      break;
    }

    case NO_INSTR:
      processed = false;
      break;

    default:
      UNIMPLEMENTED();  // This type is not implemented.
  }

  // The first byte didn't match any of the simple opcodes, so we
  // need to do special processing on it.
  if (!processed) {
    switch (*data) {
      case 0xC2:
        AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data + 1));
        data += 3;
        break;

      case 0x69:  // fall through
      case 0x6B: {
        int mod, regop, rm;
        get_modrm(*(data + 1), &mod, &regop, &rm);
        int32_t imm = *data == 0x6B ? *(data + 2)
            : *reinterpret_cast<int32_t*>(data + 2);
        AppendToBuffer("imul%c %s,%s,0x%x",
                       operand_size_code(),
                       NameOfCPURegister(regop),
                       NameOfCPURegister(rm), imm);
        data += 2 + (*data == 0x6B ? 1 : 4);
        break;
      }

      case 0x81:  // fall through
      case 0x83:  // 0x81 with sign extension bit set
        data += PrintImmediateOp(data);
        break;

      case 0x0F:
        data += TwoByteOpcodeInstruction(data);
        break;

      case 0x8F: {
        data++;
        int mod, regop, rm;
        get_modrm(*data, &mod, &regop, &rm);
        if (regop == 0) {
          AppendToBuffer("pop ");
          data += PrintRightOperand(data);
        }
      }
        break;

      case 0xFF: {
        data++;
        int mod, regop, rm;
        get_modrm(*data, &mod, &regop, &rm);
        const char* mnem = NULL;
        switch (regop) {
          case 0:
            mnem = "inc";
            break;
          case 1:
            mnem = "dec";
            break;
          case 2:
            mnem = "call";
            break;
          case 4:
            mnem = "jmp";
            break;
          case 6:
            mnem = "push";
            break;
          default:
            mnem = "???";
        }
        AppendToBuffer(((regop <= 1) ? "%s%c " : "%s "),
                       mnem,
                       operand_size_code());
        data += PrintRightOperand(data);
      }
        break;

      case 0xC7:  // imm32, fall through
      case 0xC6:  // imm8
      {
        bool is_byte = *data == 0xC6;
        data++;
        if (is_byte) {
          AppendToBuffer("movb ");
          data += PrintRightByteOperand(data);
          int32_t imm = *data;
          AppendToBuffer(",0x%x", imm);
          data++;
        } else {
          AppendToBuffer("mov%c ", operand_size_code());
          data += PrintRightOperand(data);
          int32_t imm = *reinterpret_cast<int32_t*>(data);
          AppendToBuffer(",0x%x", imm);
          data += 4;
        }
      }
        break;

      case 0x80: {
        data++;
        AppendToBuffer("cmpb ");
        data += PrintRightByteOperand(data);
        int32_t imm = *data;
        AppendToBuffer(",0x%x", imm);
        data++;
      }
        break;

      case 0x88:  // 8bit, fall through
      case 0x89:  // 32bit
      {
        bool is_byte = *data == 0x88;
        int mod, regop, rm;
        data++;
        get_modrm(*data, &mod, &regop, &rm);
        if (is_byte) {
          AppendToBuffer("movb ");
          data += PrintRightByteOperand(data);
          AppendToBuffer(",%s", NameOfByteCPURegister(regop));
        } else {
          AppendToBuffer("mov%c ", operand_size_code());
          data += PrintRightOperand(data);
          AppendToBuffer(",%s", NameOfCPURegister(regop));
        }
      }
        break;

      case 0x90:
      case 0x91:
      case 0x92:
      case 0x93:
      case 0x94:
      case 0x95:
      case 0x96:
      case 0x97: {
        int reg = (*data & 0x7) | (rex_b() ? 8 : 0);
        if (reg == 0) {
          AppendToBuffer("nop");  // Common name for xchg rax,rax.
        } else {
          AppendToBuffer("xchg%c rax, %s",
                         operand_size_code(),
                         NameOfCPURegister(reg));
        }
        data++;
      }
        break;
      case 0xB0:
      case 0xB1:
      case 0xB2:
      case 0xB3:
      case 0xB4:
      case 0xB5:
      case 0xB6:
      case 0xB7:
      case 0xB8:
      case 0xB9:
      case 0xBA:
      case 0xBB:
      case 0xBC:
      case 0xBD:
      case 0xBE:
      case 0xBF: {
        // mov reg8,imm8 or mov reg32,imm32
        byte opcode = *data;
        data++;
        bool is_32bit = (opcode >= 0xB8);
        int reg = (opcode & 0x7) | (rex_b() ? 8 : 0);
        if (is_32bit) {
          AppendToBuffer("mov%c %s, ",
                         operand_size_code(),
                         NameOfCPURegister(reg));
          data += PrintImmediate(data, DOUBLEWORD_SIZE);
        } else {
          AppendToBuffer("movb %s, ",
                         NameOfByteCPURegister(reg));
          data += PrintImmediate(data, BYTE_SIZE);
        }
        break;
      }
      case 0xFE: {
        data++;
        int mod, regop, rm;
        get_modrm(*data, &mod, &regop, &rm);
        if (regop == 1) {
          AppendToBuffer("decb ");
          data += PrintRightByteOperand(data);
        } else {
          UnimplementedInstruction();
        }
        break;
      }
      case 0x68:
        AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data + 1));
        data += 5;
        break;

      case 0x6A:
        AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1));
        data += 2;
        break;

      case 0xA1:  // Fall through.
      case 0xA3:
        switch (operand_size()) {
          case DOUBLEWORD_SIZE: {
            const char* memory_location = NameOfAddress(
                reinterpret_cast<byte*>(
                    *reinterpret_cast<int32_t*>(data + 1)));
            if (*data == 0xA1) {  // Opcode 0xA1
              AppendToBuffer("movzxlq rax,(%s)", memory_location);
            } else {  // Opcode 0xA3
              AppendToBuffer("movzxlq (%s),rax", memory_location);
            }
            data += 5;
            break;
          }
          case QUADWORD_SIZE: {
            // New x64 instruction mov rax,(imm_64).
            const char* memory_location = NameOfAddress(
                *reinterpret_cast<byte**>(data + 1));
            if (*data == 0xA1) {  // Opcode 0xA1
              AppendToBuffer("movq rax,(%s)", memory_location);
            } else {  // Opcode 0xA3
              AppendToBuffer("movq (%s),rax", memory_location);
            }
            data += 9;
            break;
          }
          default:
            UnimplementedInstruction();
            data += 2;
        }
        break;

      case 0xA8:
        AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data + 1));
        data += 2;
        break;

      case 0xA9: {
        int64_t value = 0;
        switch (operand_size()) {
          case WORD_SIZE:
            value = *reinterpret_cast<uint16_t*>(data + 1);
            data += 3;
            break;
          case DOUBLEWORD_SIZE:
            value = *reinterpret_cast<uint32_t*>(data + 1);
            data += 5;
            break;
          case QUADWORD_SIZE:
            value = *reinterpret_cast<int32_t*>(data + 1);
            data += 5;
            break;
          default:
            UNREACHABLE();
        }
        AppendToBuffer("test%c rax,0x%"V8_PTR_PREFIX"x",
                       operand_size_code(),
                       value);
        break;
      }
      case 0xD1:  // fall through
      case 0xD3:  // fall through
      case 0xC1:
        data += ShiftInstruction(data);
        break;
      case 0xD0:  // fall through
      case 0xD2:  // fall through
      case 0xC0:
        byte_size_operand_ = true;
        data += ShiftInstruction(data);
        break;

      case 0xD9:  // fall through
      case 0xDA:  // fall through
      case 0xDB:  // fall through
      case 0xDC:  // fall through
      case 0xDD:  // fall through
      case 0xDE:  // fall through
      case 0xDF:
        data += FPUInstruction(data);
        break;

      case 0xEB:
        data += JumpShort(data);
        break;

      case 0xF6:
        byte_size_operand_ = true;  // fall through
      case 0xF7:
        data += F6F7Instruction(data);
        break;

      default:
        UnimplementedInstruction();
        data += 1;
    }
  }  // !processed

  if (tmp_buffer_pos_ < sizeof tmp_buffer_) {
    tmp_buffer_[tmp_buffer_pos_] = '\0';
  }

  int instr_len = static_cast<int>(data - instr);
  ASSERT(instr_len > 0);  // Ensure progress.

  int outp = 0;
  // Instruction bytes.
  for (byte* bp = instr; bp < data; bp++) {
    outp += v8::internal::OS::SNPrintF(out_buffer + outp, "%02x", *bp);
  }
  for (int i = 6 - instr_len; i >= 0; i--) {
    outp += v8::internal::OS::SNPrintF(out_buffer + outp, "  ");
  }

  outp += v8::internal::OS::SNPrintF(out_buffer + outp, " %s",
                                     tmp_buffer_.start());
  return instr_len;
}

//------------------------------------------------------------------------------


static const char* cpu_regs[16] = {
  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
};


static const char* byte_cpu_regs[16] = {
  "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
  "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"
};


static const char* xmm_regs[16] = {
  "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
  "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
};


const char* NameConverter::NameOfAddress(byte* addr) const {
  v8::internal::OS::SNPrintF(tmp_buffer_, "%p", addr);
  return tmp_buffer_.start();
}


const char* NameConverter::NameOfConstant(byte* addr) const {
  return NameOfAddress(addr);
}


const char* NameConverter::NameOfCPURegister(int reg) const {
  if (0 <= reg && reg < 16)
    return cpu_regs[reg];
  return "noreg";
}


const char* NameConverter::NameOfByteCPURegister(int reg) const {
  if (0 <= reg && reg < 16)
    return byte_cpu_regs[reg];
  return "noreg";
}


const char* NameConverter::NameOfXMMRegister(int reg) const {
  if (0 <= reg && reg < 16)
    return xmm_regs[reg];
  return "noxmmreg";
}


const char* NameConverter::NameInCode(byte* addr) const {
  // X64 does not embed debug strings at the moment.
  UNREACHABLE();
  return "";
}

//------------------------------------------------------------------------------

Disassembler::Disassembler(const NameConverter& converter)
    : converter_(converter) { }

Disassembler::~Disassembler() { }


int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
                                    byte* instruction) {
  DisassemblerX64 d(converter_, CONTINUE_ON_UNIMPLEMENTED_OPCODE);
  return d.InstructionDecode(buffer, instruction);
}


// The X64 assembler does not use constant pools.
int Disassembler::ConstantPoolSizeAt(byte* instruction) {
  return -1;
}


void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
  NameConverter converter;
  Disassembler d(converter);
  for (byte* pc = begin; pc < end;) {
    v8::internal::EmbeddedVector<char, 128> buffer;
    buffer[0] = '\0';
    byte* prev_pc = pc;
    pc += d.InstructionDecode(buffer, pc);
    fprintf(f, "%p", prev_pc);
    fprintf(f, "    ");

    for (byte* bp = prev_pc; bp < pc; bp++) {
      fprintf(f, "%02x", *bp);
    }
    for (int i = 6 - static_cast<int>(pc - prev_pc); i >= 0; i--) {
      fprintf(f, "  ");
    }
    fprintf(f, "  %s\n", buffer.start());
  }
}

}  // namespace disasm

#endif  // V8_TARGET_ARCH_X64
