1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2011 the V8 project authors. All rights reserved.
2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// found in the LICENSE file.
4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
5864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include <assert.h>
6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#include <stdarg.h>
74b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <stdio.h>
8864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
10864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
11864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#if V8_TARGET_ARCH_X87
12864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/disasm.h"
14864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
15864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace disasm {
16864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
17864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgenum OperandOrder {
18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  UNSET_OP_ORDER = 0,
19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  REG_OPER_OP_ORDER,
20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  OPER_REG_OP_ORDER
21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
22864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
23864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
24864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org//------------------------------------------------------------------
25864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Tables
26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org//------------------------------------------------------------------
27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstruct ByteMnemonic {
28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int b;  // -1 terminates, otherwise must be in range (0..255)
29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* mnem;
30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  OperandOrder op_order_;
31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
34864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const ByteMnemonic two_operands_instr[] = {
35864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x01, "add", OPER_REG_OP_ORDER},
36864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x03, "add", REG_OPER_OP_ORDER},
37864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x09, "or", OPER_REG_OP_ORDER},
38864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x0B, "or", REG_OPER_OP_ORDER},
39864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x1B, "sbb", REG_OPER_OP_ORDER},
40864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x21, "and", OPER_REG_OP_ORDER},
41864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x23, "and", REG_OPER_OP_ORDER},
42864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x29, "sub", OPER_REG_OP_ORDER},
43864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x2A, "subb", REG_OPER_OP_ORDER},
44864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x2B, "sub", REG_OPER_OP_ORDER},
45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x31, "xor", OPER_REG_OP_ORDER},
46864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x33, "xor", REG_OPER_OP_ORDER},
47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x38, "cmpb", OPER_REG_OP_ORDER},
48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x3A, "cmpb", REG_OPER_OP_ORDER},
49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x3B, "cmp", REG_OPER_OP_ORDER},
50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x84, "test_b", REG_OPER_OP_ORDER},
51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x85, "test", REG_OPER_OP_ORDER},
52864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x87, "xchg", REG_OPER_OP_ORDER},
53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x8A, "mov_b", REG_OPER_OP_ORDER},
54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x8B, "mov", REG_OPER_OP_ORDER},
55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x8D, "lea", REG_OPER_OP_ORDER},
56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {-1, "", UNSET_OP_ORDER}
57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const ByteMnemonic zero_operands_instr[] = {
61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0xC3, "ret", UNSET_OP_ORDER},
62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0xC9, "leave", UNSET_OP_ORDER},
63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x90, "nop", UNSET_OP_ORDER},
64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0xF4, "hlt", UNSET_OP_ORDER},
65864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0xCC, "int3", UNSET_OP_ORDER},
66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x60, "pushad", UNSET_OP_ORDER},
67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x61, "popad", UNSET_OP_ORDER},
68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x9C, "pushfd", UNSET_OP_ORDER},
69864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x9D, "popfd", UNSET_OP_ORDER},
70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x9E, "sahf", UNSET_OP_ORDER},
71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x99, "cdq", UNSET_OP_ORDER},
72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x9B, "fwait", UNSET_OP_ORDER},
73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0xFC, "cld", UNSET_OP_ORDER},
74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0xAB, "stos", UNSET_OP_ORDER},
75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {-1, "", UNSET_OP_ORDER}
76864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
78864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const ByteMnemonic call_jump_instr[] = {
80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0xE8, "call", UNSET_OP_ORDER},
81864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0xE9, "jmp", UNSET_OP_ORDER},
82864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {-1, "", UNSET_OP_ORDER}
83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
84864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const ByteMnemonic short_immediate_instr[] = {
87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x05, "add", UNSET_OP_ORDER},
88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x0D, "or", UNSET_OP_ORDER},
89864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x15, "adc", UNSET_OP_ORDER},
90864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x25, "and", UNSET_OP_ORDER},
91864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x2D, "sub", UNSET_OP_ORDER},
92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x35, "xor", UNSET_OP_ORDER},
93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x3D, "cmp", UNSET_OP_ORDER},
94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {-1, "", UNSET_OP_ORDER}
95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Generally we don't want to generate these because they are subject to partial
99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// register stalls.  They are included for completeness and because the cmp
100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// variant is used by the RecordWrite stub.  Because it does not update the
101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// register it is not subject to partial register stalls.
102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic ByteMnemonic byte_immediate_instr[] = {
103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x0c, "or", UNSET_OP_ORDER},
104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x24, "and", UNSET_OP_ORDER},
105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x34, "xor", UNSET_OP_ORDER},
106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {0x3c, "cmp", UNSET_OP_ORDER},
107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {-1, "", UNSET_OP_ORDER}
108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* const jump_conditional_mnem[] = {
112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  /*0*/ "jo", "jno", "jc", "jnc",
113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  /*4*/ "jz", "jnz", "jna", "ja",
114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  /*8*/ "js", "jns", "jpe", "jpo",
115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  /*12*/ "jl", "jnl", "jng", "jg"
116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* const set_conditional_mnem[] = {
120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  /*0*/ "seto", "setno", "setc", "setnc",
121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  /*4*/ "setz", "setnz", "setna", "seta",
122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  /*8*/ "sets", "setns", "setpe", "setpo",
123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  /*12*/ "setl", "setnl", "setng", "setg"
124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* const conditional_move_mnem[] = {
128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  /*0*/ "cmovo", "cmovno", "cmovc", "cmovnc",
129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  /*4*/ "cmovz", "cmovnz", "cmovna", "cmova",
130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  /*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo",
131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  /*12*/ "cmovl", "cmovnl", "cmovng", "cmovg"
132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgenum InstructionType {
136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  NO_INSTR,
137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  ZERO_OPERANDS_INSTR,
138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  TWO_OPERANDS_INSTR,
139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  JUMP_CONDITIONAL_SHORT_INSTR,
140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  REGISTER_INSTR,
141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  MOVE_REG_INSTR,
142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  CALL_JUMP_INSTR,
143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  SHORT_IMMEDIATE_INSTR,
144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  BYTE_IMMEDIATE_INSTR
145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstruct InstructionDesc {
149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* mnem;
150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  InstructionType type;
151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  OperandOrder op_order_;
152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass InstructionTable {
156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public:
157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  InstructionTable();
158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const InstructionDesc& Get(byte x) const { return instructions_[x]; }
159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  static InstructionTable* get_instance() {
160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    static InstructionTable table;
161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return &table;
162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private:
165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  InstructionDesc instructions_[256];
166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Clear();
167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void Init();
168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void CopyTable(const ByteMnemonic bm[], InstructionType type);
169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void SetTableRange(InstructionType type,
170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     byte start,
171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     byte end,
172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     const char* mnem);
173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AddJumpConditionalShort();
174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgInstructionTable::InstructionTable() {
178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Clear();
179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Init();
180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid InstructionTable::Clear() {
184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  for (int i = 0; i < 256; i++) {
185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    instructions_[i].mnem = "";
186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    instructions_[i].type = NO_INSTR;
187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    instructions_[i].op_order_ = UNSET_OP_ORDER;
188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid InstructionTable::Init() {
193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  CopyTable(two_operands_instr, TWO_OPERANDS_INSTR);
194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR);
195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  CopyTable(call_jump_instr, CALL_JUMP_INSTR);
196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  CopyTable(byte_immediate_instr, BYTE_IMMEDIATE_INSTR);
198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  AddJumpConditionalShort();
199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc");
200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec");
201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push");
202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop");
203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,");  // 0x90 is nop.
204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov");
205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid InstructionTable::CopyTable(const ByteMnemonic bm[],
209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                 InstructionType type) {
210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  for (int i = 0; bm[i].b >= 0; i++) {
211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    InstructionDesc* id = &instructions_[bm[i].b];
212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    id->mnem = bm[i].mnem;
213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    id->op_order_ = bm[i].op_order_;
214e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_EQ(NO_INSTR, id->type);  // Information not already entered.
215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    id->type = type;
216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid InstructionTable::SetTableRange(InstructionType type,
221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                     byte start,
222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                     byte end,
223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                     const char* mnem) {
224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  for (byte b = start; b <= end; b++) {
225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    InstructionDesc* id = &instructions_[b];
226e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_EQ(NO_INSTR, id->type);  // Information not already entered.
227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    id->mnem = mnem;
228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    id->type = type;
229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid InstructionTable::AddJumpConditionalShort() {
234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  for (byte b = 0x70; b <= 0x7F; b++) {
235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    InstructionDesc* id = &instructions_[b];
236e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_EQ(NO_INSTR, id->type);  // Information not already entered.
237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    id->mnem = jump_conditional_mnem[b & 0x0F];
238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    id->type = JUMP_CONDITIONAL_SHORT_INSTR;
239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// The X87 disassembler implementation.
244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass DisassemblerX87 {
245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public:
246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  DisassemblerX87(const NameConverter& converter,
247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                   bool abort_on_unimplemented = true)
248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      : converter_(converter),
249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        instruction_table_(InstructionTable::get_instance()),
250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        tmp_buffer_pos_(0),
251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        abort_on_unimplemented_(abort_on_unimplemented) {
252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    tmp_buffer_[0] = '\0';
253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  virtual ~DisassemblerX87() {}
256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Writes one disassembled instruction into 'buffer' (0-terminated).
258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Returns the length of the disassembled machine instruction in bytes.
259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int InstructionDecode(v8::internal::Vector<char> buffer, byte* instruction);
260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private:
262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const NameConverter& converter_;
263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  InstructionTable* instruction_table_;
264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  v8::internal::EmbeddedVector<char, 128> tmp_buffer_;
265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  unsigned int tmp_buffer_pos_;
266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  bool abort_on_unimplemented_;
267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  enum {
269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    eax = 0,
270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    ecx = 1,
271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    edx = 2,
272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    ebx = 3,
273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    esp = 4,
274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    ebp = 5,
275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    esi = 6,
276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    edi = 7
277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  };
278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  enum ShiftOpcodeExtension {
281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    kROL = 0,
282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    kROR = 1,
283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    kRCL = 2,
284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    kRCR = 3,
285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    kSHL = 4,
286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    KSHR = 5,
287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    kSAR = 7
288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  };
289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* NameOfCPURegister(int reg) const {
292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return converter_.NameOfCPURegister(reg);
293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* NameOfByteCPURegister(int reg) const {
297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return converter_.NameOfByteCPURegister(reg);
298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* NameOfXMMRegister(int reg) const {
302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return converter_.NameOfXMMRegister(reg);
303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* NameOfAddress(byte* addr) const {
307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return converter_.NameOfAddress(addr);
308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Disassembler helper functions.
312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  static void get_modrm(byte data, int* mod, int* regop, int* rm) {
313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    *mod = (data >> 6) & 3;
314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    *regop = (data & 0x38) >> 3;
315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    *rm = data & 7;
316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  static void get_sib(byte data, int* scale, int* index, int* base) {
320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    *scale = (data >> 6) & 3;
321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    *index = (data >> 3) & 7;
322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    *base = data & 7;
323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  typedef const char* (DisassemblerX87::*RegisterNameMapping)(int reg) const;
326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int PrintRightOperandHelper(byte* modrmp, RegisterNameMapping register_name);
328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int PrintRightOperand(byte* modrmp);
329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int PrintRightByteOperand(byte* modrmp);
330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int PrintRightXMMOperand(byte* modrmp);
331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int PrintOperands(const char* mnem, OperandOrder op_order, byte* data);
332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int PrintImmediateOp(byte* data);
333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int F7Instruction(byte* data);
334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int D1D3C1Instruction(byte* data);
335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int JumpShort(byte* data);
336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int JumpConditional(byte* data, const char* comment);
337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int JumpConditionalShort(byte* data, const char* comment);
338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int SetCC(byte* data);
339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int CMov(byte* data);
340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int FPUInstruction(byte* data);
341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start);
342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int RegisterFPUInstruction(int escape_opcode, byte modrm_byte);
343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void AppendToBuffer(const char* format, ...);
344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  void UnimplementedInstruction() {
347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    if (abort_on_unimplemented_) {
348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      UNIMPLEMENTED();
349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    } else {
350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      AppendToBuffer("'Unimplemented Instruction'");
351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid DisassemblerX87::AppendToBuffer(const char* format, ...) {
357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  v8::internal::Vector<char> buf = tmp_buffer_ + tmp_buffer_pos_;
358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  va_list args;
359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  va_start(args, format);
36070ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  int result = v8::internal::VSNPrintF(buf, format, args);
361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  va_end(args);
362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  tmp_buffer_pos_ += result;
363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::PrintRightOperandHelper(
366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    byte* modrmp,
367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    RegisterNameMapping direct_register_name) {
368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int mod, regop, rm;
369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  get_modrm(*modrmp, &mod, &regop, &rm);
370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  RegisterNameMapping register_name = (mod == 3) ? direct_register_name :
371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      &DisassemblerX87::NameOfCPURegister;
372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  switch (mod) {
373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0:
374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      if (rm == ebp) {
375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        int32_t disp = *reinterpret_cast<int32_t*>(modrmp+1);
376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        AppendToBuffer("[0x%x]", disp);
377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        return 5;
378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      } else if (rm == esp) {
379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        byte sib = *(modrmp + 1);
380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        int scale, index, base;
381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        get_sib(sib, &scale, &index, &base);
382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        if (index == esp && base == esp && scale == 0 /*times_1*/) {
383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("[%s]", (this->*register_name)(rm));
384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          return 2;
385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else if (base == ebp) {
386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2);
387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("[%s*%d%s0x%x]",
388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         (this->*register_name)(index),
389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         1 << scale,
390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         disp < 0 ? "-" : "+",
391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         disp < 0 ? -disp : disp);
392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          return 6;
393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else if (index != esp && base != ebp) {
394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          // [base+index*scale]
395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("[%s+%s*%d]",
396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         (this->*register_name)(base),
397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         (this->*register_name)(index),
398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         1 << scale);
399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          return 2;
400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else {
401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          UnimplementedInstruction();
402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          return 1;
403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      } else {
405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        AppendToBuffer("[%s]", (this->*register_name)(rm));
406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        return 1;
407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 1:  // fall through
410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 2:
411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      if (rm == esp) {
412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        byte sib = *(modrmp + 1);
413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        int scale, index, base;
414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        get_sib(sib, &scale, &index, &base);
415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        int disp = mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 2)
416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            : *reinterpret_cast<int8_t*>(modrmp + 2);
417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        if (index == base && index == rm /*esp*/ && scale == 0 /*times_1*/) {
418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("[%s%s0x%x]",
419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         (this->*register_name)(rm),
420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         disp < 0 ? "-" : "+",
421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         disp < 0 ? -disp : disp);
422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else {
423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("[%s+%s*%d%s0x%x]",
424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         (this->*register_name)(base),
425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         (this->*register_name)(index),
426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         1 << scale,
427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         disp < 0 ? "-" : "+",
428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                         disp < 0 ? -disp : disp);
429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        return mod == 2 ? 6 : 3;
431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      } else {
432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        // No sib.
433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        int disp = mod == 2 ? *reinterpret_cast<int32_t*>(modrmp + 1)
434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            : *reinterpret_cast<int8_t*>(modrmp + 1);
435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        AppendToBuffer("[%s%s0x%x]",
436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                       (this->*register_name)(rm),
437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                       disp < 0 ? "-" : "+",
438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                       disp < 0 ? -disp : disp);
439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        return mod == 2 ? 5 : 2;
440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 3:
443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      AppendToBuffer("%s", (this->*register_name)(rm));
444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      return 1;
445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    default:
446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      UnimplementedInstruction();
447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      return 1;
448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  UNREACHABLE();
450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::PrintRightOperand(byte* modrmp) {
454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return PrintRightOperandHelper(modrmp, &DisassemblerX87::NameOfCPURegister);
455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::PrintRightByteOperand(byte* modrmp) {
459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return PrintRightOperandHelper(modrmp,
460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                 &DisassemblerX87::NameOfByteCPURegister);
461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::PrintRightXMMOperand(byte* modrmp) {
465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return PrintRightOperandHelper(modrmp,
466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                 &DisassemblerX87::NameOfXMMRegister);
467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used including the current *data.
471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'.
472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::PrintOperands(const char* mnem,
473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                    OperandOrder op_order,
474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                    byte* data) {
475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte modrm = *data;
476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int mod, regop, rm;
477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  get_modrm(modrm, &mod, &regop, &rm);
478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int advance = 0;
479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  switch (op_order) {
480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case REG_OPER_OP_ORDER: {
481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      AppendToBuffer("%s %s,", mnem, NameOfCPURegister(regop));
482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      advance = PrintRightOperand(data);
483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case OPER_REG_OP_ORDER: {
486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      AppendToBuffer("%s ", mnem);
487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      advance = PrintRightOperand(data);
488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      AppendToBuffer(",%s", NameOfCPURegister(regop));
489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    default:
492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      UNREACHABLE();
493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return advance;
496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used by machine instruction, including *data byte.
500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Writes immediate instructions to 'tmp_buffer_'.
501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::PrintImmediateOp(byte* data) {
502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  bool sign_extension_bit = (*data & 0x02) != 0;
503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte modrm = *(data+1);
504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int mod, regop, rm;
505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  get_modrm(modrm, &mod, &regop, &rm);
506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* mnem = "Imm???";
507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  switch (regop) {
508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0: mnem = "add"; break;
509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 1: mnem = "or"; break;
510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 2: mnem = "adc"; break;
511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 4: mnem = "and"; break;
512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 5: mnem = "sub"; break;
513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 6: mnem = "xor"; break;
514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 7: mnem = "cmp"; break;
515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    default: UnimplementedInstruction();
516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  AppendToBuffer("%s ", mnem);
518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int count = PrintRightOperand(data+1);
519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (sign_extension_bit) {
520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    AppendToBuffer(",0x%x", *(data + 1 + count));
521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return 1 + count + 1 /*int8*/;
522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  } else {
523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + 1 + count));
524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return 1 + count + 4 /*int32_t*/;
525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data.
530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::F7Instruction(byte* data) {
531e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(0xF7, *data);
5325c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  byte modrm = *++data;
533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int mod, regop, rm;
534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  get_modrm(modrm, &mod, &regop, &rm);
5355c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  const char* mnem = NULL;
5365c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  switch (regop) {
5375c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case 0:
5385c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "test";
5395c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5405c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case 2:
5415c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "not";
5425c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5435c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case 3:
5445c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "neg";
5455c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5465c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case 4:
5475c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "mul";
5485c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5495c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case 5:
5505c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "imul";
5515c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5525c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case 6:
5535c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "div";
5545c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5555c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case 7:
5565c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "idiv";
5575c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5585c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    default:
5595c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      UnimplementedInstruction();
5605c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  }
5615c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  AppendToBuffer("%s ", mnem);
5625c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  int count = PrintRightOperand(data);
5635c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  if (regop == 0) {
5645c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    AppendToBuffer(",0x%x", *reinterpret_cast<int32_t*>(data + count));
5655c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    count += 4;
566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
5675c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  return 1 + count;
568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::D1D3C1Instruction(byte* data) {
572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte op = *data;
573e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(op == 0xD1 || op == 0xD3 || op == 0xC1);
5745c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  byte modrm = *++data;
575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int mod, regop, rm;
576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  get_modrm(modrm, &mod, &regop, &rm);
577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int imm8 = -1;
5785c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  const char* mnem = NULL;
5795c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  switch (regop) {
5805c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case kROL:
5815c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "rol";
5825c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5835c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case kROR:
5845c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "ror";
5855c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5865c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case kRCL:
5875c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "rcl";
5885c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5895c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case kRCR:
5905c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "rcr";
5915c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5925c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case kSHL:
5935c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "shl";
5945c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5955c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case KSHR:
5965c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "shr";
5975c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
5985c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    case kSAR:
5995c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      mnem = "sar";
6005c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      break;
6015c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    default:
6025c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      UnimplementedInstruction();
6035c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  }
6045c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  AppendToBuffer("%s ", mnem);
6055c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  int count = PrintRightOperand(data);
6065c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  if (op == 0xD1) {
6075c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    imm8 = 1;
6085c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  } else if (op == 0xC1) {
6099d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    imm8 = *(data + 1);
6105c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    count++;
6115c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  } else if (op == 0xD3) {
6125c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    // Shift/rotate by cl.
6135c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  }
6145c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  if (imm8 >= 0) {
6155c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    AppendToBuffer(",%d", imm8);
616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  } else {
6175c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org    AppendToBuffer(",cl");
618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
6195c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org  return 1 + count;
620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data.
624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::JumpShort(byte* data) {
625e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(0xEB, *data);
626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte b = *(data+1);
627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte* dest = data + static_cast<int8_t>(b) + 2;
628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  AppendToBuffer("jmp %s", NameOfAddress(dest));
629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return 2;
630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data.
634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::JumpConditional(byte* data, const char* comment) {
635e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(0x0F, *data);
636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte cond = *(data+1) & 0x0F;
637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte* dest = data + *reinterpret_cast<int32_t*>(data+2) + 6;
638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* mnem = jump_conditional_mnem[cond];
639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  AppendToBuffer("%s %s", mnem, NameOfAddress(dest));
640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (comment != NULL) {
641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    AppendToBuffer(", %s", comment);
642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return 6;  // includes 0x0F
644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data.
648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::JumpConditionalShort(byte* data, const char* comment) {
649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte cond = *data & 0x0F;
650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte b = *(data+1);
651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte* dest = data + static_cast<int8_t>(b) + 2;
652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* mnem = jump_conditional_mnem[cond];
653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  AppendToBuffer("%s %s", mnem, NameOfAddress(dest));
654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (comment != NULL) {
655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    AppendToBuffer(", %s", comment);
656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return 2;
658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data.
662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::SetCC(byte* data) {
663e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(0x0F, *data);
664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte cond = *(data+1) & 0x0F;
665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* mnem = set_conditional_mnem[cond];
666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  AppendToBuffer("%s ", mnem);
667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  PrintRightByteOperand(data+2);
668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return 3;  // Includes 0x0F.
669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data.
673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::CMov(byte* data) {
674e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(0x0F, *data);
675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte cond = *(data + 1) & 0x0F;
676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* mnem = conditional_move_mnem[cond];
677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2);
678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return 2 + op_size;  // includes 0x0F
679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns number of bytes used, including *data.
683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::FPUInstruction(byte* data) {
684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte escape_opcode = *data;
685e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(0xD8, escape_opcode & 0xF8);
686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte modrm_byte = *(data+1);
687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (modrm_byte >= 0xC0) {
689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return RegisterFPUInstruction(escape_opcode, modrm_byte);
690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  } else {
691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    return MemoryFPUInstruction(escape_opcode, modrm_byte, data+1);
692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::MemoryFPUInstruction(int escape_opcode,
696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                           int modrm_byte,
697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                           byte* modrm_start) {
698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* mnem = "?";
699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int regop = (modrm_byte >> 3) & 0x7;  // reg/op field of modrm byte.
700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  switch (escape_opcode) {
701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xD9: switch (regop) {
702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0: mnem = "fld_s"; break;
703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 2: mnem = "fst_s"; break;
704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 3: mnem = "fstp_s"; break;
70506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org        case 5:
70606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          mnem = "fldcw";
70706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          break;
70806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org        case 7:
70906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          mnem = "fnstcw";
71006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          break;
711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        default: UnimplementedInstruction();
712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xDB: switch (regop) {
716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0: mnem = "fild_s"; break;
717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 1: mnem = "fisttp_s"; break;
718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 2: mnem = "fist_s"; break;
719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 3: mnem = "fistp_s"; break;
720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        default: UnimplementedInstruction();
721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
72406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    case 0xDC:
72506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      switch (regop) {
72606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org        case 0:
72706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          mnem = "fadd_d";
72806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          break;
72906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org        default:
73006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          UnimplementedInstruction();
73106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      }
73206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      break;
73306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org
734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xDD: switch (regop) {
735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0: mnem = "fld_d"; break;
736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 1: mnem = "fisttp_d"; break;
737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 2: mnem = "fst_d"; break;
738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 3: mnem = "fstp_d"; break;
73906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org        case 4:
74006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          mnem = "frstor";
74106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          break;
74206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org        case 6:
74306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          mnem = "fnsave";
74406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org          break;
745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        default: UnimplementedInstruction();
746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xDF: switch (regop) {
750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 5: mnem = "fild_d"; break;
751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 7: mnem = "fistp_d"; break;
752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        default: UnimplementedInstruction();
753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    default: UnimplementedInstruction();
757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  AppendToBuffer("%s ", mnem);
759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int count = PrintRightOperand(modrm_start);
760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return count + 1;
761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::RegisterFPUInstruction(int escape_opcode,
764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                             byte modrm_byte) {
765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  bool has_register = false;  // Is the FPU register encoded in modrm_byte?
766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* mnem = "?";
767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  switch (escape_opcode) {
769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xD8:
770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      has_register = true;
771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      switch (modrm_byte & 0xF8) {
772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xC0: mnem = "fadd_i"; break;
773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xE0: mnem = "fsub_i"; break;
774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xC8: mnem = "fmul_i"; break;
775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xF0: mnem = "fdiv_i"; break;
776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        default: UnimplementedInstruction();
777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xD9:
781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      switch (modrm_byte & 0xF8) {
782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xC0:
783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          mnem = "fld";
784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          has_register = true;
785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          break;
786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xC8:
787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          mnem = "fxch";
788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          has_register = true;
789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          break;
790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        default:
791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          switch (modrm_byte) {
792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xE0: mnem = "fchs"; break;
793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xE1: mnem = "fabs"; break;
794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xE4: mnem = "ftst"; break;
795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xE8: mnem = "fld1"; break;
796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xEB: mnem = "fldpi"; break;
797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xED: mnem = "fldln2"; break;
798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xEE: mnem = "fldz"; break;
799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xF0: mnem = "f2xm1"; break;
800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xF1: mnem = "fyl2x"; break;
801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xF4: mnem = "fxtract"; break;
802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xF5: mnem = "fprem1"; break;
803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xF7: mnem = "fincstp"; break;
804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xF8: mnem = "fprem"; break;
805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xFC: mnem = "frndint"; break;
806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xFD: mnem = "fscale"; break;
807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xFE: mnem = "fsin"; break;
808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 0xFF: mnem = "fcos"; break;
809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            default: UnimplementedInstruction();
810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          }
811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xDA:
815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      if (modrm_byte == 0xE9) {
816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        mnem = "fucompp";
817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      } else {
818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        UnimplementedInstruction();
819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xDB:
823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      if ((modrm_byte & 0xF8) == 0xE8) {
824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        mnem = "fucomi";
825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        has_register = true;
826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      } else if (modrm_byte  == 0xE2) {
827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        mnem = "fclex";
828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      } else if (modrm_byte == 0xE3) {
829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        mnem = "fninit";
830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      } else {
831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        UnimplementedInstruction();
832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xDC:
836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      has_register = true;
837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      switch (modrm_byte & 0xF8) {
838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xC0: mnem = "fadd"; break;
839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xE8: mnem = "fsub"; break;
840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xC8: mnem = "fmul"; break;
841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xF8: mnem = "fdiv"; break;
842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        default: UnimplementedInstruction();
843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xDD:
847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      has_register = true;
848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      switch (modrm_byte & 0xF8) {
849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xC0: mnem = "ffree"; break;
850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xD0: mnem = "fst"; break;
851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        case 0xD8: mnem = "fstp"; break;
852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        default: UnimplementedInstruction();
853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xDE:
857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      if (modrm_byte  == 0xD9) {
858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        mnem = "fcompp";
859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      } else {
860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        has_register = true;
861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        switch (modrm_byte & 0xF8) {
862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          case 0xC0: mnem = "faddp"; break;
863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          case 0xE8: mnem = "fsubp"; break;
864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          case 0xC8: mnem = "fmulp"; break;
865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          case 0xF8: mnem = "fdivp"; break;
866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          default: UnimplementedInstruction();
867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xDF:
872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      if (modrm_byte == 0xE0) {
873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        mnem = "fnstsw_ax";
874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      } else if ((modrm_byte & 0xF8) == 0xE8) {
875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        mnem = "fucomip";
876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        has_register = true;
877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    default: UnimplementedInstruction();
881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (has_register) {
884864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    AppendToBuffer("%s st%d", mnem, modrm_byte & 0x7);
885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  } else {
886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    AppendToBuffer("%s", mnem);
887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return 2;
889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Mnemonics for instructions 0xF0 byte.
893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Returns NULL if the instruction is not handled here.
894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* F0Mnem(byte f0byte) {
895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  switch (f0byte) {
896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0x18: return "prefetch";
897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xA2: return "cpuid";
898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xBE: return "movsx_b";
899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xBF: return "movsx_w";
900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xB6: return "movzx_b";
901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xB7: return "movzx_w";
902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xAF: return "imul";
903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xA5: return "shld";
904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xAD: return "shrd";
905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xAC: return "shrd";  // 3-operand version.
906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xAB: return "bts";
907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case 0xBD: return "bsr";
908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    default: return NULL;
909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Disassembled instruction '*instr' and writes it into 'out_buffer'.
914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint DisassemblerX87::InstructionDecode(v8::internal::Vector<char> out_buffer,
915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                        byte* instr) {
916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  tmp_buffer_pos_ = 0;  // starting to write as position 0
917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  byte* data = instr;
918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check for hints.
919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const char* branch_hint = NULL;
920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // We use these two prefixes only with branch prediction
921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (*data == 0x3E /*ds*/) {
922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    branch_hint = "predicted taken";
923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    data++;
924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  } else if (*data == 0x2E /*cs*/) {
925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    branch_hint = "predicted not taken";
926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    data++;
927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  bool processed = true;  // Will be set to false if the current instruction
929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                          // is not in 'instructions' table.
930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  const InstructionDesc& idesc = instruction_table_->Get(*data);
931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  switch (idesc.type) {
932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case ZERO_OPERANDS_INSTR:
933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      AppendToBuffer(idesc.mnem);
934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      data++;
935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case TWO_OPERANDS_INSTR:
938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      data++;
939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      data += PrintOperands(idesc.mnem, idesc.op_order_, data);
940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case JUMP_CONDITIONAL_SHORT_INSTR:
943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      data += JumpConditionalShort(data, branch_hint);
944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case REGISTER_INSTR:
947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      data++;
949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case MOVE_REG_INSTR: {
952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));
953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      AppendToBuffer("mov %s,%s",
954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     NameOfCPURegister(*data & 0x07),
955864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     NameOfAddress(addr));
956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      data += 5;
957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case CALL_JUMP_INSTR: {
961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      byte* addr = data + *reinterpret_cast<int32_t*>(data+1) + 5;
962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr));
963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      data += 5;
964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case SHORT_IMMEDIATE_INSTR: {
968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));
969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      AppendToBuffer("%s eax,%s", idesc.mnem, NameOfAddress(addr));
970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      data += 5;
971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case BYTE_IMMEDIATE_INSTR: {
975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      AppendToBuffer("%s al,0x%x", idesc.mnem, data[1]);
976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      data += 2;
977864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    case NO_INSTR:
981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      processed = false;
982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      break;
983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    default:
985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      UNIMPLEMENTED();  // This type is not implemented.
986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //----------------------------
988864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (!processed) {
989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    switch (*data) {
990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xC2:
991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data+1));
992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        data += 3;
993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
9955c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      case 0x6B: {
9965c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org        data++;
9975c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org        data += PrintOperands("imul", REG_OPER_OP_ORDER, data);
9985c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org        AppendToBuffer(",%d", *data);
9995c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org        data++;
10005c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      } break;
10015c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org
10025c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org      case 0x69: {
10035c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org        data++;
10045c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org        data += PrintOperands("imul", REG_OPER_OP_ORDER, data);
10055c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org        AppendToBuffer(",%d", *reinterpret_cast<int32_t*>(data));
10065c0fd9bca25be110d9fb3e332075726b10c8b169machenbach@chromium.org        data += 4;
1007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
1008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xF6:
1011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        { data++;
1012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          int mod, regop, rm;
1013864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          get_modrm(*data, &mod, &regop, &rm);
1014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          if (regop == eax) {
1015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("test_b ");
1016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightByteOperand(data);
1017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int32_t imm = *data;
1018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer(",0x%x", imm);
1019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else {
1021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            UnimplementedInstruction();
1022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          }
1023864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
1024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1025864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0x81:  // fall through
1027864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0x83:  // 0x81 with sign extension bit set
1028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        data += PrintImmediateOp(data);
1029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0x0F:
1032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        { byte f0byte = data[1];
1033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          const char* f0mnem = F0Mnem(f0byte);
1034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          if (f0byte == 0x18) {
1035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 2;
1036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            const char* suffix[] = {"nta", "1", "2", "3"};
1039864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("%s%s ", f0mnem, suffix[regop & 0x03]);
1040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightOperand(data);
1041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte == 0x1F && data[2] == 0) {
1042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("nop");  // 3 byte nop.
1043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 3;
1044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte == 0x1F && data[2] == 0x40 && data[3] == 0) {
1045864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("nop");  // 4 byte nop.
1046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 4;
1047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte == 0x1F && data[2] == 0x44 && data[3] == 0 &&
1048864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     data[4] == 0) {
1049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("nop");  // 5 byte nop.
1050864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 5;
1051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte == 0x1F && data[2] == 0x80 && data[3] == 0 &&
1052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     data[4] == 0 && data[5] == 0 && data[6] == 0) {
1053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("nop");  // 7 byte nop.
1054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 7;
1055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte == 0x1F && data[2] == 0x84 && data[3] == 0 &&
1056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     data[4] == 0 && data[5] == 0 && data[6] == 0 &&
1057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     data[7] == 0) {
1058864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("nop");  // 8 byte nop.
1059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 8;
1060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte == 0xA2 || f0byte == 0x31) {
1061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("%s", f0mnem);
1062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 2;
1063864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte == 0x28) {
1064864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 2;
1065864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1066864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1067864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movaps %s,%s",
1068864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(regop),
1069864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm));
1070864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte >= 0x53 && f0byte <= 0x5F) {
1072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            const char* const pseudo_op[] = {
1073864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "rcpps",
1074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "andps",
1075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "andnps",
1076864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "orps",
1077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "xorps",
1078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "addps",
1079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "mulps",
1080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "cvtps2pd",
1081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "cvtdq2ps",
1082864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "subps",
1083864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "minps",
1084864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "divps",
1085864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              "maxps",
1086864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            };
1087864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1088864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 2;
1089864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1090864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1091864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("%s %s,",
1092864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           pseudo_op[f0byte - 0x53],
1093864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(regop));
1094864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightXMMOperand(data);
1095864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte == 0x50) {
1096864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 2;
1097864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1098864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1099864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movmskps %s,%s",
1100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfCPURegister(regop),
1101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm));
1102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte== 0xC6) {
1104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            // shufps xmm, xmm/m128, imm8
1105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 2;
1106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int8_t imm8 = static_cast<int8_t>(data[1]);
1109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("shufps %s,%s,%d",
1110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            NameOfXMMRegister(rm),
1111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            NameOfXMMRegister(regop),
1112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                            static_cast<int>(imm8));
1113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 2;
1114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if ((f0byte & 0xF0) == 0x80) {
1115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += JumpConditional(data, branch_hint);
1116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte == 0xBE || f0byte == 0xBF || f0byte == 0xB6 ||
1117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     f0byte == 0xB7 || f0byte == 0xAF) {
1118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 2;
1119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintOperands(f0mnem, REG_OPER_OP_ORDER, data);
1120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if ((f0byte & 0xF0) == 0x90) {
1121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += SetCC(data);
1122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if ((f0byte & 0xF0) == 0x40) {
1123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += CMov(data);
1124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte == 0xAB || f0byte == 0xA5 || f0byte == 0xAD) {
1125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            // shrd, shld, bts
1126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 2;
1127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("%s ", f0mnem);
1128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightOperand(data);
1131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            if (f0byte == 0xAB) {
1132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer(",%s", NameOfCPURegister(regop));
1133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            } else {
1134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer(",%s,cl", NameOfCPURegister(regop));
1135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            }
1136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (f0byte == 0xBD) {
1137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 2;
1138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("%s %s,", f0mnem, NameOfCPURegister(regop));
1141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightOperand(data);
1142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else {
1143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            UnimplementedInstruction();
1144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          }
1145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
1146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0x8F:
1149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        { data++;
1150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          int mod, regop, rm;
1151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          get_modrm(*data, &mod, &regop, &rm);
1152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          if (regop == eax) {
1153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("pop ");
1154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightOperand(data);
1155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          }
1156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
1157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xFF:
1160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        { data++;
1161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          int mod, regop, rm;
1162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          get_modrm(*data, &mod, &regop, &rm);
1163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          const char* mnem = NULL;
1164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          switch (regop) {
1165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case esi: mnem = "push"; break;
1166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case eax: mnem = "inc"; break;
1167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case ecx: mnem = "dec"; break;
1168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case edx: mnem = "call"; break;
1169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case esp: mnem = "jmp"; break;
1170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            default: mnem = "???";
1171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          }
1172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("%s ", mnem);
1173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data += PrintRightOperand(data);
1174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
1175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xC7:  // imm32, fall through
1178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xC6:  // imm8
1179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        { bool is_byte = *data == 0xC6;
1180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data++;
1181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          if (is_byte) {
1182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("%s ", "mov_b");
1183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightByteOperand(data);
1184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int32_t imm = *data;
1185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer(",0x%x", imm);
1186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else {
1188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("%s ", "mov");
1189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightOperand(data);
1190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int32_t imm = *reinterpret_cast<int32_t*>(data);
1191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer(",0x%x", imm);
1192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 4;
1193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          }
1194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
1195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0x80:
1198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        { data++;
1199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          int mod, regop, rm;
1200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          get_modrm(*data, &mod, &regop, &rm);
1201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          const char* mnem = NULL;
1202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          switch (regop) {
1203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 5:  mnem = "subb"; break;
1204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            case 7:  mnem = "cmpb"; break;
1205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            default: UnimplementedInstruction();
1206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          }
1207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("%s ", mnem);
1208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data += PrintRightByteOperand(data);
1209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          int32_t imm = *data;
1210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer(",0x%x", imm);
1211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data++;
1212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
1213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0x88:  // 8bit, fall through
1216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0x89:  // 32bit
1217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        { bool is_byte = *data == 0x88;
1218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          int mod, regop, rm;
1219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data++;
1220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          get_modrm(*data, &mod, &regop, &rm);
1221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          if (is_byte) {
1222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("%s ", "mov_b");
1223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightByteOperand(data);
1224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer(",%s", NameOfByteCPURegister(regop));
1225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else {
1226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("%s ", "mov");
1227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightOperand(data);
1228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer(",%s", NameOfCPURegister(regop));
1229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          }
1230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
1231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0x66:  // prefix
1234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        while (*data == 0x66) data++;
1235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        if (*data == 0xf && data[1] == 0x1f) {
1236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("nop");  // 0x66 prefix
1237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else if (*data == 0x90) {
1238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("nop");  // 0x66 prefix
1239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else if (*data == 0x8B) {
1240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data++;
1241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data += PrintOperands("mov_w", REG_OPER_OP_ORDER, data);
1242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else if (*data == 0x89) {
1243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data++;
1244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          int mod, regop, rm;
1245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          get_modrm(*data, &mod, &regop, &rm);
1246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("mov_w ");
1247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data += PrintRightOperand(data);
1248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer(",%s", NameOfCPURegister(regop));
1249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else if (*data == 0xC7) {
1250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data++;
1251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("%s ", "mov_w");
1252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data += PrintRightOperand(data);
1253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          int imm = *reinterpret_cast<int16_t*>(data);
1254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer(",0x%x", imm);
1255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data += 2;
1256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else if (*data == 0x0F) {
1257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data++;
1258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          if (*data == 0x38) {
1259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            if (*data == 0x17) {
1261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data++;
1262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              int mod, regop, rm;
1263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              get_modrm(*data, &mod, &regop, &rm);
1264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("ptest %s,%s",
1265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfXMMRegister(regop),
1266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfXMMRegister(rm));
1267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data++;
1268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            } else if (*data == 0x2A) {
1269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              // movntdqa
1270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data++;
1271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              int mod, regop, rm;
1272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              get_modrm(*data, &mod, &regop, &rm);
1273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("movntdqa %s,", NameOfXMMRegister(regop));
1274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data += PrintRightOperand(data);
1275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            } else {
1276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              UnimplementedInstruction();
1277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            }
1278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x3A) {
1279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            if (*data == 0x0B) {
1281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data++;
1282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              int mod, regop, rm;
1283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              get_modrm(*data, &mod, &regop, &rm);
1284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              int8_t imm8 = static_cast<int8_t>(data[1]);
1285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("roundsd %s,%s,%d",
1286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfXMMRegister(regop),
1287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfXMMRegister(rm),
1288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             static_cast<int>(imm8));
1289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data += 2;
1290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            } else if (*data == 0x16) {
1291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data++;
1292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              int mod, regop, rm;
1293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              get_modrm(*data, &mod, &regop, &rm);
1294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              int8_t imm8 = static_cast<int8_t>(data[1]);
1295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("pextrd %s,%s,%d",
1296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfCPURegister(regop),
1297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfXMMRegister(rm),
1298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             static_cast<int>(imm8));
1299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data += 2;
1300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            } else if (*data == 0x17) {
1301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data++;
1302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              int mod, regop, rm;
1303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              get_modrm(*data, &mod, &regop, &rm);
1304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              int8_t imm8 = static_cast<int8_t>(data[1]);
1305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("extractps %s,%s,%d",
1306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfCPURegister(rm),
1307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfXMMRegister(regop),
1308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             static_cast<int>(imm8));
1309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data += 2;
1310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            } else if (*data == 0x22) {
1311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data++;
1312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              int mod, regop, rm;
1313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              get_modrm(*data, &mod, &regop, &rm);
1314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              int8_t imm8 = static_cast<int8_t>(data[1]);
1315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("pinsrd %s,%s,%d",
1316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfXMMRegister(regop),
1317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfCPURegister(rm),
1318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             static_cast<int>(imm8));
1319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data += 2;
1320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            } else {
1321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              UnimplementedInstruction();
1322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            }
1323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x2E || *data == 0x2F) {
1324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            const char* mnem = (*data == 0x2E) ? "ucomisd" : "comisd";
1325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            if (mod == 0x3) {
1329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("%s %s,%s", mnem,
1330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfXMMRegister(regop),
1331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfXMMRegister(rm));
1332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data++;
1333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            } else {
1334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("%s %s,", mnem, NameOfXMMRegister(regop));
1335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data += PrintRightOperand(data);
1336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            }
1337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x50) {
1338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movmskpd %s,%s",
1342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfCPURegister(regop),
1343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm));
1344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x54) {
1346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("andpd %s,%s",
1350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(regop),
1351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm));
1352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x56) {
1354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("orpd %s,%s",
1358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(regop),
1359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm));
1360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x57) {
1362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("xorpd %s,%s",
1366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(regop),
1367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm));
1368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x6E) {
1370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movd %s,", NameOfXMMRegister(regop));
1374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightOperand(data);
1375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x6F) {
1376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movdqa %s,", NameOfXMMRegister(regop));
1380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightXMMOperand(data);
1381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x70) {
1382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int8_t imm8 = static_cast<int8_t>(data[1]);
1386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("pshufd %s,%s,%d",
1387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(regop),
1388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm),
1389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           static_cast<int>(imm8));
1390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 2;
1391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x76) {
1392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("pcmpeqd %s,%s",
1396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(regop),
1397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm));
1398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x90) {
1400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("nop");  // 2 byte nop.
1402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0xF3) {
1403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("psllq %s,%s",
1407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(regop),
1408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm));
1409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x73) {
1411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int8_t imm8 = static_cast<int8_t>(data[1]);
1415e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org            DCHECK(regop == esi || regop == edx);
1416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("%s %s,%d",
1417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           (regop == esi) ? "psllq" : "psrlq",
1418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm),
1419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           static_cast<int>(imm8));
1420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 2;
1421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0xD3) {
1422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("psrlq %s,%s",
1426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(regop),
1427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm));
1428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x7F) {
1430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movdqa ");
1431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightXMMOperand(data);
1435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer(",%s", NameOfXMMRegister(regop));
1436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0x7E) {
1437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movd ");
1441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightOperand(data);
1442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer(",%s", NameOfXMMRegister(regop));
1443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0xDB) {
1444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("pand %s,%s",
1448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(regop),
1449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm));
1450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0xE7) {
1452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            if (mod == 3) {
1456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("movntdq ");
1457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data += PrintRightOperand(data);
1458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer(",%s", NameOfXMMRegister(regop));
1459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            } else {
1460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              UnimplementedInstruction();
1461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            }
1462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0xEF) {
1463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("pxor %s,%s",
1467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(regop),
1468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm));
1469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (*data == 0xEB) {
1471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("por %s,%s",
1475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(regop),
1476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                           NameOfXMMRegister(rm));
1477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data++;
1478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else {
1479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            UnimplementedInstruction();
1480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          }
1481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else {
1482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          UnimplementedInstruction();
1483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
1484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xFE:
1487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        { data++;
1488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          int mod, regop, rm;
1489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          get_modrm(*data, &mod, &regop, &rm);
1490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          if (regop == ecx) {
1491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("dec_b ");
1492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightOperand(data);
1493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else {
1494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            UnimplementedInstruction();
1495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          }
1496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
1497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0x68:
1500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data+1));
1501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        data += 5;
1502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0x6A:
1505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1));
1506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        data += 2;
1507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xA8:
1510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data+1));
1511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        data += 2;
1512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xA9:
1515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        AppendToBuffer("test eax,0x%x", *reinterpret_cast<int32_t*>(data+1));
1516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        data += 5;
1517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xD1:  // fall through
1520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xD3:  // fall through
1521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xC1:
1522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        data += D1D3C1Instruction(data);
1523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xD8:  // fall through
1526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xD9:  // fall through
1527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xDA:  // fall through
1528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xDB:  // fall through
1529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xDC:  // fall through
1530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xDD:  // fall through
1531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xDE:  // fall through
1532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xDF:
1533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        data += FPUInstruction(data);
1534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xEB:
1537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        data += JumpShort(data);
1538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xF2:
1541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        if (*(data+1) == 0x0F) {
1542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          byte b2 = *(data+2);
1543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          if (b2 == 0x11) {
1544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movsd ");
1545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 3;
1546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightXMMOperand(data);
1549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer(",%s", NameOfXMMRegister(regop));
1550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (b2 == 0x10) {
1551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 3;
1552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movsd %s,", NameOfXMMRegister(regop));
1555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightXMMOperand(data);
1556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else  if (b2 == 0x5A) {
1557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 3;
1558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("cvtsd2ss %s,", NameOfXMMRegister(regop));
1561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightXMMOperand(data);
1562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else {
1563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            const char* mnem = "?";
1564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            switch (b2) {
1565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              case 0x2A: mnem = "cvtsi2sd"; break;
1566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              case 0x2C: mnem = "cvttsd2si"; break;
1567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              case 0x2D: mnem = "cvtsd2si"; break;
1568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              case 0x51: mnem = "sqrtsd"; break;
1569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              case 0x58: mnem = "addsd"; break;
1570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              case 0x59: mnem = "mulsd"; break;
1571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              case 0x5C: mnem = "subsd"; break;
1572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              case 0x5E: mnem = "divsd"; break;
1573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            }
1574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 3;
1575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            if (b2 == 0x2A) {
1578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("%s %s,", mnem, NameOfXMMRegister(regop));
1579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data += PrintRightOperand(data);
1580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            } else if (b2 == 0x2C || b2 == 0x2D) {
1581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("%s %s,", mnem, NameOfCPURegister(regop));
1582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data += PrintRightXMMOperand(data);
1583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            } else if (b2 == 0xC2) {
1584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              // Intel manual 2A, Table 3-18.
1585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              const char* const pseudo_op[] = {
1586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                "cmpeqsd",
1587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                "cmpltsd",
1588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                "cmplesd",
1589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                "cmpunordsd",
1590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                "cmpneqsd",
1591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                "cmpnltsd",
1592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                "cmpnlesd",
1593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                "cmpordsd"
1594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              };
1595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("%s %s,%s",
1596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             pseudo_op[data[1]],
1597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfXMMRegister(regop),
1598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                             NameOfXMMRegister(rm));
1599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data += 2;
1600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            } else {
1601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              AppendToBuffer("%s %s,", mnem, NameOfXMMRegister(regop));
1602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org              data += PrintRightXMMOperand(data);
1603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            }
1604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          }
1605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else {
1606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          UnimplementedInstruction();
1607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
1608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xF3:
1611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        if (*(data+1) == 0x0F) {
1612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          byte b2 = *(data+2);
1613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          if (b2 == 0x11) {
1614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movss ");
1615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 3;
1616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightXMMOperand(data);
1619864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer(",%s", NameOfXMMRegister(regop));
1620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (b2 == 0x10) {
1621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 3;
1622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movss %s,", NameOfXMMRegister(regop));
1625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightXMMOperand(data);
1626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (b2 == 0x2C) {
1627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 3;
1628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("cvttss2si %s,", NameOfCPURegister(regop));
1631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightXMMOperand(data);
1632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (b2 == 0x5A) {
1633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 3;
1634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop));
1637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightXMMOperand(data);
1638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (b2 == 0x6F) {
1639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 3;
1640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movdqu %s,", NameOfXMMRegister(regop));
1643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightXMMOperand(data);
1644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else if (b2 == 0x7F) {
1645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer("movdqu ");
1646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += 3;
1647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            int mod, regop, rm;
1648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            get_modrm(*data, &mod, &regop, &rm);
1649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            data += PrintRightXMMOperand(data);
1650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            AppendToBuffer(",%s", NameOfXMMRegister(regop));
1651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          } else {
1652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            UnimplementedInstruction();
1653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          }
1654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else if (*(data+1) == 0xA5) {
1655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data += 2;
1656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("rep_movs");
1657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else if (*(data+1) == 0xAB) {
1658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          data += 2;
1659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          AppendToBuffer("rep_stos");
1660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        } else {
1661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          UnimplementedInstruction();
1662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
1663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      case 0xF7:
1666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        data += F7Instruction(data);
1667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        break;
1668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      default:
1670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        UnimplementedInstruction();
1671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
1672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
1673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (tmp_buffer_pos_ < sizeof tmp_buffer_) {
1675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    tmp_buffer_[tmp_buffer_pos_] = '\0';
1676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
1677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int instr_len = data - instr;
1679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (instr_len == 0) {
1680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    printf("%02x", *data);
1681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
1682e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(instr_len > 0);  // Ensure progress.
1683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  int outp = 0;
1685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Instruction bytes.
1686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  for (byte* bp = instr; bp < data; bp++) {
168770ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org    outp += v8::internal::SNPrintF(out_buffer + outp, "%02x", *bp);
1688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
1689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  for (int i = 6 - instr_len; i >= 0; i--) {
169070ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org    outp += v8::internal::SNPrintF(out_buffer + outp, "  ");
1691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
1692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
169370ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  outp += v8::internal::SNPrintF(out_buffer + outp, " %s", tmp_buffer_.start());
1694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return instr_len;
1695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}  // NOLINT (function is too long)
1696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org//------------------------------------------------------------------------------
1699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* cpu_regs[8] = {
1702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
1703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
1704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* byte_cpu_regs[8] = {
1707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
1708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
1709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* xmm_regs[8] = {
1712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
1713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org};
1714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst char* NameConverter::NameOfAddress(byte* addr) const {
171770ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  v8::internal::SNPrintF(tmp_buffer_, "%p", addr);
1718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return tmp_buffer_.start();
1719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst char* NameConverter::NameOfConstant(byte* addr) const {
1723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return NameOfAddress(addr);
1724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst char* NameConverter::NameOfCPURegister(int reg) const {
1728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (0 <= reg && reg < 8) return cpu_regs[reg];
1729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return "noreg";
1730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst char* NameConverter::NameOfByteCPURegister(int reg) const {
1734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (0 <= reg && reg < 8) return byte_cpu_regs[reg];
1735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return "noreg";
1736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst char* NameConverter::NameOfXMMRegister(int reg) const {
1740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (0 <= reg && reg < 8) return xmm_regs[reg];
1741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return "noxmmreg";
1742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgconst char* NameConverter::NameInCode(byte* addr) const {
1746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // X87 does not embed debug strings at the moment.
1747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  UNREACHABLE();
1748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return "";
1749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org//------------------------------------------------------------------------------
1753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgDisassembler::Disassembler(const NameConverter& converter)
1755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    : converter_(converter) {}
1756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgDisassembler::~Disassembler() {}
1759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
1762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                    byte* instruction) {
1763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  DisassemblerX87 d(converter_, false /*do not crash if unimplemented*/);
1764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return d.InstructionDecode(buffer, instruction);
1765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// The IA-32 assembler does not currently use constant pools.
1769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; }
1770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org/*static*/ void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
1773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  NameConverter converter;
1774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Disassembler d(converter);
1775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  for (byte* pc = begin; pc < end;) {
1776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    v8::internal::EmbeddedVector<char, 128> buffer;
1777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    buffer[0] = '\0';
1778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    byte* prev_pc = pc;
1779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    pc += d.InstructionDecode(buffer, pc);
1780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    fprintf(f, "%p", prev_pc);
1781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    fprintf(f, "    ");
1782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    for (byte* bp = prev_pc; bp < pc; bp++) {
1784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      fprintf(f, "%02x",  *bp);
1785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
1786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    for (int i = 6 - (pc - prev_pc); i >= 0; i--) {
1787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      fprintf(f, "  ");
1788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
1789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    fprintf(f, "  %s\n", buffer.start());
1790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
1791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
1792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}  // namespace disasm
1795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
1796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif  // V8_TARGET_ARCH_X87
1797