Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Side by Side Diff: runtime/vm/disassembler_ia32.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/disassembler_dbc.cc ('k') | runtime/vm/disassembler_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/disassembler.h" 5 #include "vm/disassembler.h"
6 6
7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
8 #if defined(TARGET_ARCH_IA32) 8 #if defined(TARGET_ARCH_IA32)
9 #include "platform/utils.h" 9 #include "platform/utils.h"
10 #include "vm/allocation.h" 10 #include "vm/allocation.h"
11 #include "vm/heap.h" 11 #include "vm/heap.h"
12 #include "vm/os.h" 12 #include "vm/os.h"
13 #include "vm/stack_frame.h" 13 #include "vm/stack_frame.h"
14 #include "vm/stub_code.h" 14 #include "vm/stub_code.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 #ifndef PRODUCT 18 #ifndef PRODUCT
19 19
20 // Tables used for decoding of x86 instructions. 20 // Tables used for decoding of x86 instructions.
21 enum OperandOrder { UNSET_OP_ORDER = 0, REG_OPER_OP_ORDER, OPER_REG_OP_ORDER }; 21 enum OperandOrder { UNSET_OP_ORDER = 0, REG_OPER_OP_ORDER, OPER_REG_OP_ORDER };
22 22
23
24 struct ByteMnemonic { 23 struct ByteMnemonic {
25 int b; // -1 terminates, otherwise must be in range (0..255) 24 int b; // -1 terminates, otherwise must be in range (0..255)
26 const char* mnem; 25 const char* mnem;
27 OperandOrder op_order_; 26 OperandOrder op_order_;
28 }; 27 };
29 28
30
31 static ByteMnemonic two_operands_instr[] = { 29 static ByteMnemonic two_operands_instr[] = {
32 {0x01, "add", OPER_REG_OP_ORDER}, {0x03, "add", REG_OPER_OP_ORDER}, 30 {0x01, "add", OPER_REG_OP_ORDER}, {0x03, "add", REG_OPER_OP_ORDER},
33 {0x09, "or", OPER_REG_OP_ORDER}, {0x0B, "or", REG_OPER_OP_ORDER}, 31 {0x09, "or", OPER_REG_OP_ORDER}, {0x0B, "or", REG_OPER_OP_ORDER},
34 {0x11, "adc", OPER_REG_OP_ORDER}, {0x13, "adc", REG_OPER_OP_ORDER}, 32 {0x11, "adc", OPER_REG_OP_ORDER}, {0x13, "adc", REG_OPER_OP_ORDER},
35 {0x19, "sbb", OPER_REG_OP_ORDER}, {0x1B, "sbb", REG_OPER_OP_ORDER}, 33 {0x19, "sbb", OPER_REG_OP_ORDER}, {0x1B, "sbb", REG_OPER_OP_ORDER},
36 {0x21, "and", OPER_REG_OP_ORDER}, {0x23, "and", REG_OPER_OP_ORDER}, 34 {0x21, "and", OPER_REG_OP_ORDER}, {0x23, "and", REG_OPER_OP_ORDER},
37 {0x29, "sub", OPER_REG_OP_ORDER}, {0x2B, "sub", REG_OPER_OP_ORDER}, 35 {0x29, "sub", OPER_REG_OP_ORDER}, {0x2B, "sub", REG_OPER_OP_ORDER},
38 {0x31, "xor", OPER_REG_OP_ORDER}, {0x33, "xor", REG_OPER_OP_ORDER}, 36 {0x31, "xor", OPER_REG_OP_ORDER}, {0x33, "xor", REG_OPER_OP_ORDER},
39 {0x39, "cmp", OPER_REG_OP_ORDER}, {0x3B, "cmp", REG_OPER_OP_ORDER}, 37 {0x39, "cmp", OPER_REG_OP_ORDER}, {0x3B, "cmp", REG_OPER_OP_ORDER},
40 {0x85, "test", REG_OPER_OP_ORDER}, {0x87, "xchg", REG_OPER_OP_ORDER}, 38 {0x85, "test", REG_OPER_OP_ORDER}, {0x87, "xchg", REG_OPER_OP_ORDER},
41 {0x8A, "mov_b", REG_OPER_OP_ORDER}, {0x8B, "mov", REG_OPER_OP_ORDER}, 39 {0x8A, "mov_b", REG_OPER_OP_ORDER}, {0x8B, "mov", REG_OPER_OP_ORDER},
42 {0x8D, "lea", REG_OPER_OP_ORDER}, {-1, "", UNSET_OP_ORDER}}; 40 {0x8D, "lea", REG_OPER_OP_ORDER}, {-1, "", UNSET_OP_ORDER}};
43 41
44
45 static ByteMnemonic zero_operands_instr[] = { 42 static ByteMnemonic zero_operands_instr[] = {
46 {0xC3, "ret", UNSET_OP_ORDER}, {0xC9, "leave", UNSET_OP_ORDER}, 43 {0xC3, "ret", UNSET_OP_ORDER}, {0xC9, "leave", UNSET_OP_ORDER},
47 {0x90, "nop", UNSET_OP_ORDER}, {0xF4, "hlt", UNSET_OP_ORDER}, 44 {0x90, "nop", UNSET_OP_ORDER}, {0xF4, "hlt", UNSET_OP_ORDER},
48 {0xCC, "int3", UNSET_OP_ORDER}, {0x60, "pushad", UNSET_OP_ORDER}, 45 {0xCC, "int3", UNSET_OP_ORDER}, {0x60, "pushad", UNSET_OP_ORDER},
49 {0x61, "popad", UNSET_OP_ORDER}, {0x9C, "pushfd", UNSET_OP_ORDER}, 46 {0x61, "popad", UNSET_OP_ORDER}, {0x9C, "pushfd", UNSET_OP_ORDER},
50 {0x9D, "popfd", UNSET_OP_ORDER}, {0x9E, "sahf", UNSET_OP_ORDER}, 47 {0x9D, "popfd", UNSET_OP_ORDER}, {0x9E, "sahf", UNSET_OP_ORDER},
51 {0x99, "cdq", UNSET_OP_ORDER}, {0x9B, "fwait", UNSET_OP_ORDER}, 48 {0x99, "cdq", UNSET_OP_ORDER}, {0x9B, "fwait", UNSET_OP_ORDER},
52 {-1, "", UNSET_OP_ORDER}}; 49 {-1, "", UNSET_OP_ORDER}};
53 50
54
55 static ByteMnemonic call_jump_instr[] = {{0xE8, "call", UNSET_OP_ORDER}, 51 static ByteMnemonic call_jump_instr[] = {{0xE8, "call", UNSET_OP_ORDER},
56 {0xE9, "jmp", UNSET_OP_ORDER}, 52 {0xE9, "jmp", UNSET_OP_ORDER},
57 {-1, "", UNSET_OP_ORDER}}; 53 {-1, "", UNSET_OP_ORDER}};
58 54
59
60 static ByteMnemonic short_immediate_instr[] = { 55 static ByteMnemonic short_immediate_instr[] = {
61 {0x05, "add", UNSET_OP_ORDER}, {0x0D, "or", UNSET_OP_ORDER}, 56 {0x05, "add", UNSET_OP_ORDER}, {0x0D, "or", UNSET_OP_ORDER},
62 {0x15, "adc", UNSET_OP_ORDER}, {0x25, "and", UNSET_OP_ORDER}, 57 {0x15, "adc", UNSET_OP_ORDER}, {0x25, "and", UNSET_OP_ORDER},
63 {0x2D, "sub", UNSET_OP_ORDER}, {0x35, "xor", UNSET_OP_ORDER}, 58 {0x2D, "sub", UNSET_OP_ORDER}, {0x35, "xor", UNSET_OP_ORDER},
64 {0x3D, "cmp", UNSET_OP_ORDER}, {-1, "", UNSET_OP_ORDER}}; 59 {0x3D, "cmp", UNSET_OP_ORDER}, {-1, "", UNSET_OP_ORDER}};
65 60
66
67 static const char* jump_conditional_mnem[] = { 61 static const char* jump_conditional_mnem[] = {
68 /*0*/ "jo", "jno", "jc", "jnc", 62 /*0*/ "jo", "jno", "jc", "jnc",
69 /*4*/ "jz", "jnz", "jna", "ja", 63 /*4*/ "jz", "jnz", "jna", "ja",
70 /*8*/ "js", "jns", "jpe", "jpo", 64 /*8*/ "js", "jns", "jpe", "jpo",
71 /*12*/ "jl", "jnl", "jng", "jg"}; 65 /*12*/ "jl", "jnl", "jng", "jg"};
72 66
73
74 static const char* set_conditional_mnem[] = { 67 static const char* set_conditional_mnem[] = {
75 /*0*/ "seto", "setno", "setc", "setnc", 68 /*0*/ "seto", "setno", "setc", "setnc",
76 /*4*/ "setz", "setnz", "setna", "seta", 69 /*4*/ "setz", "setnz", "setna", "seta",
77 /*8*/ "sets", "setns", "setpe", "setpo", 70 /*8*/ "sets", "setns", "setpe", "setpo",
78 /*12*/ "setl", "setnl", "setng", "setg"}; 71 /*12*/ "setl", "setnl", "setng", "setg"};
79 72
80
81 static const char* conditional_move_mnem[] = { 73 static const char* conditional_move_mnem[] = {
82 /*0*/ "cmovo", "cmovno", "cmovc", "cmovnc", 74 /*0*/ "cmovo", "cmovno", "cmovc", "cmovnc",
83 /*4*/ "cmovz", "cmovnz", "cmovna", "cmova", 75 /*4*/ "cmovz", "cmovnz", "cmovna", "cmova",
84 /*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo", 76 /*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo",
85 /*12*/ "cmovl", "cmovnl", "cmovng", "cmovg"}; 77 /*12*/ "cmovl", "cmovnl", "cmovng", "cmovg"};
86 78
87
88 enum InstructionType { 79 enum InstructionType {
89 NO_INSTR, 80 NO_INSTR,
90 ZERO_OPERANDS_INSTR, 81 ZERO_OPERANDS_INSTR,
91 TWO_OPERANDS_INSTR, 82 TWO_OPERANDS_INSTR,
92 JUMP_CONDITIONAL_SHORT_INSTR, 83 JUMP_CONDITIONAL_SHORT_INSTR,
93 REGISTER_INSTR, 84 REGISTER_INSTR,
94 MOVE_REG_INSTR, 85 MOVE_REG_INSTR,
95 CALL_JUMP_INSTR, 86 CALL_JUMP_INSTR,
96 SHORT_IMMEDIATE_INSTR 87 SHORT_IMMEDIATE_INSTR
97 }; 88 };
98 89
99
100 struct InstructionDesc { 90 struct InstructionDesc {
101 const char* mnem; 91 const char* mnem;
102 InstructionType type; 92 InstructionType type;
103 OperandOrder op_order_; 93 OperandOrder op_order_;
104 }; 94 };
105 95
106
107 class InstructionTable : public ValueObject { 96 class InstructionTable : public ValueObject {
108 public: 97 public:
109 InstructionTable(); 98 InstructionTable();
110 const InstructionDesc& Get(uint8_t x) const { return instructions_[x]; } 99 const InstructionDesc& Get(uint8_t x) const { return instructions_[x]; }
111 100
112 private: 101 private:
113 InstructionDesc instructions_[256]; 102 InstructionDesc instructions_[256];
114 void Clear(); 103 void Clear();
115 void Init(); 104 void Init();
116 void CopyTable(ByteMnemonic bm[], InstructionType type); 105 void CopyTable(ByteMnemonic bm[], InstructionType type);
117 void SetTableRange(InstructionType type, 106 void SetTableRange(InstructionType type,
118 uint8_t start, 107 uint8_t start,
119 uint8_t end, 108 uint8_t end,
120 const char* mnem); 109 const char* mnem);
121 void AddJumpConditionalShort(); 110 void AddJumpConditionalShort();
122 111
123 DISALLOW_COPY_AND_ASSIGN(InstructionTable); 112 DISALLOW_COPY_AND_ASSIGN(InstructionTable);
124 }; 113 };
125 114
126
127 InstructionTable::InstructionTable() { 115 InstructionTable::InstructionTable() {
128 Clear(); 116 Clear();
129 Init(); 117 Init();
130 } 118 }
131 119
132
133 void InstructionTable::Clear() { 120 void InstructionTable::Clear() {
134 for (int i = 0; i < 256; i++) { 121 for (int i = 0; i < 256; i++) {
135 instructions_[i].mnem = ""; 122 instructions_[i].mnem = "";
136 instructions_[i].type = NO_INSTR; 123 instructions_[i].type = NO_INSTR;
137 instructions_[i].op_order_ = UNSET_OP_ORDER; 124 instructions_[i].op_order_ = UNSET_OP_ORDER;
138 } 125 }
139 } 126 }
140 127
141
142 void InstructionTable::Init() { 128 void InstructionTable::Init() {
143 CopyTable(two_operands_instr, TWO_OPERANDS_INSTR); 129 CopyTable(two_operands_instr, TWO_OPERANDS_INSTR);
144 CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR); 130 CopyTable(zero_operands_instr, ZERO_OPERANDS_INSTR);
145 CopyTable(call_jump_instr, CALL_JUMP_INSTR); 131 CopyTable(call_jump_instr, CALL_JUMP_INSTR);
146 CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR); 132 CopyTable(short_immediate_instr, SHORT_IMMEDIATE_INSTR);
147 AddJumpConditionalShort(); 133 AddJumpConditionalShort();
148 SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc"); 134 SetTableRange(REGISTER_INSTR, 0x40, 0x47, "inc");
149 SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec"); 135 SetTableRange(REGISTER_INSTR, 0x48, 0x4F, "dec");
150 SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push"); 136 SetTableRange(REGISTER_INSTR, 0x50, 0x57, "push");
151 SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop"); 137 SetTableRange(REGISTER_INSTR, 0x58, 0x5F, "pop");
152 SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop. 138 SetTableRange(REGISTER_INSTR, 0x91, 0x97, "xchg eax,"); // 0x90 is nop.
153 SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov"); 139 SetTableRange(MOVE_REG_INSTR, 0xB8, 0xBF, "mov");
154 } 140 }
155 141
156
157 void InstructionTable::CopyTable(ByteMnemonic bm[], InstructionType type) { 142 void InstructionTable::CopyTable(ByteMnemonic bm[], InstructionType type) {
158 for (int i = 0; bm[i].b >= 0; i++) { 143 for (int i = 0; bm[i].b >= 0; i++) {
159 InstructionDesc* id = &instructions_[bm[i].b]; 144 InstructionDesc* id = &instructions_[bm[i].b];
160 id->mnem = bm[i].mnem; 145 id->mnem = bm[i].mnem;
161 id->op_order_ = bm[i].op_order_; 146 id->op_order_ = bm[i].op_order_;
162 ASSERT(id->type == NO_INSTR); // Information already entered 147 ASSERT(id->type == NO_INSTR); // Information already entered
163 id->type = type; 148 id->type = type;
164 } 149 }
165 } 150 }
166 151
167
168 void InstructionTable::SetTableRange(InstructionType type, 152 void InstructionTable::SetTableRange(InstructionType type,
169 uint8_t start, 153 uint8_t start,
170 uint8_t end, 154 uint8_t end,
171 const char* mnem) { 155 const char* mnem) {
172 for (uint8_t b = start; b <= end; b++) { 156 for (uint8_t b = start; b <= end; b++) {
173 InstructionDesc* id = &instructions_[b]; 157 InstructionDesc* id = &instructions_[b];
174 ASSERT(id->type == NO_INSTR); // Information already entered 158 ASSERT(id->type == NO_INSTR); // Information already entered
175 id->mnem = mnem; 159 id->mnem = mnem;
176 id->type = type; 160 id->type = type;
177 } 161 }
178 } 162 }
179 163
180
181 void InstructionTable::AddJumpConditionalShort() { 164 void InstructionTable::AddJumpConditionalShort() {
182 for (uint8_t b = 0x70; b <= 0x7F; b++) { 165 for (uint8_t b = 0x70; b <= 0x7F; b++) {
183 InstructionDesc* id = &instructions_[b]; 166 InstructionDesc* id = &instructions_[b];
184 ASSERT(id->type == NO_INSTR); // Information already entered 167 ASSERT(id->type == NO_INSTR); // Information already entered
185 id->mnem = jump_conditional_mnem[b & 0x0F]; 168 id->mnem = jump_conditional_mnem[b & 0x0F];
186 id->type = JUMP_CONDITIONAL_SHORT_INSTR; 169 id->type = JUMP_CONDITIONAL_SHORT_INSTR;
187 } 170 }
188 } 171 }
189 172
190
191 static InstructionTable instruction_table; 173 static InstructionTable instruction_table;
192 174
193
194 // Mnemonics for instructions 0xF0 byte. 175 // Mnemonics for instructions 0xF0 byte.
195 // Returns NULL if the instruction is not handled here. 176 // Returns NULL if the instruction is not handled here.
196 static const char* F0Mnem(uint8_t f0byte) { 177 static const char* F0Mnem(uint8_t f0byte) {
197 switch (f0byte) { 178 switch (f0byte) {
198 case 0x12: 179 case 0x12:
199 return "movhlps"; 180 return "movhlps";
200 case 0x14: 181 case 0x14:
201 return "unpcklps"; 182 return "unpcklps";
202 case 0x15: 183 case 0x15:
203 return "unpckhps"; 184 return "unpckhps";
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 if (data == 0x59) mnemonic = "mulpd "; 261 if (data == 0x59) mnemonic = "mulpd ";
281 if (data == 0x5E) mnemonic = "divpd "; 262 if (data == 0x5E) mnemonic = "divpd ";
282 if (data == 0x5D) mnemonic = "minpd "; 263 if (data == 0x5D) mnemonic = "minpd ";
283 if (data == 0x5F) mnemonic = "maxpd "; 264 if (data == 0x5F) mnemonic = "maxpd ";
284 if (data == 0x51) mnemonic = "sqrtpd "; 265 if (data == 0x51) mnemonic = "sqrtpd ";
285 if (data == 0x5A) mnemonic = "cvtpd2ps "; 266 if (data == 0x5A) mnemonic = "cvtpd2ps ";
286 ASSERT(mnemonic != NULL); 267 ASSERT(mnemonic != NULL);
287 return mnemonic; 268 return mnemonic;
288 } 269 }
289 270
290
291 static bool IsTwoXmmRegInstruction(uint8_t f0byte) { 271 static bool IsTwoXmmRegInstruction(uint8_t f0byte) {
292 return f0byte == 0x28 || f0byte == 0x11 || f0byte == 0x12 || f0byte == 0x14 || 272 return f0byte == 0x28 || f0byte == 0x11 || f0byte == 0x12 || f0byte == 0x14 ||
293 f0byte == 0x15 || f0byte == 0x16 || f0byte == 0x51 || f0byte == 0x52 || 273 f0byte == 0x15 || f0byte == 0x16 || f0byte == 0x51 || f0byte == 0x52 ||
294 f0byte == 0x53 || f0byte == 0x54 || f0byte == 0x56 || f0byte == 0x58 || 274 f0byte == 0x53 || f0byte == 0x54 || f0byte == 0x56 || f0byte == 0x58 ||
295 f0byte == 0x59 || f0byte == 0x5C || f0byte == 0x5D || f0byte == 0x5E || 275 f0byte == 0x59 || f0byte == 0x5C || f0byte == 0x5D || f0byte == 0x5E ||
296 f0byte == 0x5F || f0byte == 0x5A; 276 f0byte == 0x5F || f0byte == 0x5A;
297 } 277 }
298 278
299
300 // The implementation of x86 decoding based on the above tables. 279 // The implementation of x86 decoding based on the above tables.
301 class X86Decoder : public ValueObject { 280 class X86Decoder : public ValueObject {
302 public: 281 public:
303 X86Decoder(char* buffer, intptr_t buffer_size) 282 X86Decoder(char* buffer, intptr_t buffer_size)
304 : buffer_(buffer), buffer_size_(buffer_size), buffer_pos_(0) { 283 : buffer_(buffer), buffer_size_(buffer_size), buffer_pos_(0) {
305 buffer_[buffer_pos_] = '\0'; 284 buffer_[buffer_pos_] = '\0';
306 } 285 }
307 286
308 ~X86Decoder() {} 287 ~X86Decoder() {}
309 288
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 *regop = (data & 0x38) >> 3; 351 *regop = (data & 0x38) >> 3;
373 *rm = data & 7; 352 *rm = data & 7;
374 } 353 }
375 354
376 static void GetSib(uint8_t data, int* scale, int* index, int* base) { 355 static void GetSib(uint8_t data, int* scale, int* index, int* base) {
377 *scale = (data >> 6) & 3; 356 *scale = (data >> 6) & 3;
378 *index = (data >> 3) & 7; 357 *index = (data >> 3) & 7;
379 *base = data & 7; 358 *base = data & 7;
380 } 359 }
381 360
382
383 // Convenience functions. 361 // Convenience functions.
384 char* get_buffer() const { return buffer_; } 362 char* get_buffer() const { return buffer_; }
385 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } 363 char* current_position_in_buffer() { return buffer_ + buffer_pos_; }
386 intptr_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } 364 intptr_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; }
387 365
388 char* buffer_; // Decode instructions into this buffer. 366 char* buffer_; // Decode instructions into this buffer.
389 intptr_t buffer_size_; // The size of the buffer_. 367 intptr_t buffer_size_; // The size of the buffer_.
390 intptr_t buffer_pos_; // Current character position in the buffer_. 368 intptr_t buffer_pos_; // Current character position in the buffer_.
391 369
392 DISALLOW_COPY_AND_ASSIGN(X86Decoder); 370 DISALLOW_COPY_AND_ASSIGN(X86Decoder);
393 }; 371 };
394 372
395
396 void X86Decoder::PrintInt(int value) { 373 void X86Decoder::PrintInt(int value) {
397 char int_buffer[16]; 374 char int_buffer[16];
398 OS::SNPrint(int_buffer, sizeof(int_buffer), "%#x", value); 375 OS::SNPrint(int_buffer, sizeof(int_buffer), "%#x", value);
399 Print(int_buffer); 376 Print(int_buffer);
400 } 377 }
401 378
402
403 // Append the int value (printed in hex) to the output buffer. 379 // Append the int value (printed in hex) to the output buffer.
404 void X86Decoder::PrintHex(int value, bool signed_value) { 380 void X86Decoder::PrintHex(int value, bool signed_value) {
405 char hex_buffer[16]; 381 char hex_buffer[16];
406 if (signed_value && value < 0) { 382 if (signed_value && value < 0) {
407 OS::SNPrint(hex_buffer, sizeof(hex_buffer), "-%#x", -value); 383 OS::SNPrint(hex_buffer, sizeof(hex_buffer), "-%#x", -value);
408 } else { 384 } else {
409 OS::SNPrint(hex_buffer, sizeof(hex_buffer), "%#x", value); 385 OS::SNPrint(hex_buffer, sizeof(hex_buffer), "%#x", value);
410 } 386 }
411 Print(hex_buffer); 387 Print(hex_buffer);
412 } 388 }
413 389
414
415 // Append the str to the output buffer. 390 // Append the str to the output buffer.
416 void X86Decoder::Print(const char* str) { 391 void X86Decoder::Print(const char* str) {
417 char cur = *str++; 392 char cur = *str++;
418 while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) { 393 while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) {
419 buffer_[buffer_pos_++] = cur; 394 buffer_[buffer_pos_++] = cur;
420 cur = *str++; 395 cur = *str++;
421 } 396 }
422 buffer_[buffer_pos_] = '\0'; 397 buffer_[buffer_pos_] = '\0';
423 } 398 }
424 399
425
426 static const int kMaxCPURegisters = 8; 400 static const int kMaxCPURegisters = 8;
427 static const char* cpu_regs[kMaxCPURegisters] = {"eax", "ecx", "edx", "ebx", 401 static const char* cpu_regs[kMaxCPURegisters] = {"eax", "ecx", "edx", "ebx",
428 "esp", "ebp", "esi", "edi"}; 402 "esp", "ebp", "esi", "edi"};
429 403
430 static const int kMaxByteCPURegisters = 8; 404 static const int kMaxByteCPURegisters = 8;
431 static const char* byte_cpu_regs[kMaxByteCPURegisters] = { 405 static const char* byte_cpu_regs[kMaxByteCPURegisters] = {
432 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"}; 406 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"};
433 407
434 static const int kMaxXmmRegisters = 8; 408 static const int kMaxXmmRegisters = 8;
435 static const char* xmm_regs[kMaxXmmRegisters] = { 409 static const char* xmm_regs[kMaxXmmRegisters] = {
436 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"}; 410 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"};
437 411
438 void X86Decoder::PrintCPURegister(int reg) { 412 void X86Decoder::PrintCPURegister(int reg) {
439 ASSERT(0 <= reg); 413 ASSERT(0 <= reg);
440 ASSERT(reg < kMaxCPURegisters); 414 ASSERT(reg < kMaxCPURegisters);
441 Print(cpu_regs[reg]); 415 Print(cpu_regs[reg]);
442 } 416 }
443 417
444
445 void X86Decoder::PrintCPUByteRegister(int reg) { 418 void X86Decoder::PrintCPUByteRegister(int reg) {
446 ASSERT(0 <= reg); 419 ASSERT(0 <= reg);
447 ASSERT(reg < kMaxByteCPURegisters); 420 ASSERT(reg < kMaxByteCPURegisters);
448 Print(byte_cpu_regs[reg]); 421 Print(byte_cpu_regs[reg]);
449 } 422 }
450 423
451
452 void X86Decoder::PrintXmmRegister(int reg) { 424 void X86Decoder::PrintXmmRegister(int reg) {
453 ASSERT(0 <= reg); 425 ASSERT(0 <= reg);
454 ASSERT(reg < kMaxXmmRegisters); 426 ASSERT(reg < kMaxXmmRegisters);
455 Print(xmm_regs[reg]); 427 Print(xmm_regs[reg]);
456 } 428 }
457 429
458 void X86Decoder::PrintXmmComparison(int comparison) { 430 void X86Decoder::PrintXmmComparison(int comparison) {
459 ASSERT(0 <= comparison); 431 ASSERT(0 <= comparison);
460 ASSERT(comparison < 8); 432 ASSERT(comparison < 8);
461 static const char* comparisons[8] = { 433 static const char* comparisons[8] = {
462 "eq", "lt", "le", "unordered", "not eq", "not lt", "not le", "ordered"}; 434 "eq", "lt", "le", "unordered", "not eq", "not lt", "not le", "ordered"};
463 Print(comparisons[comparison]); 435 Print(comparisons[comparison]);
464 } 436 }
465 437
466
467 void X86Decoder::PrintAddress(uword addr) { 438 void X86Decoder::PrintAddress(uword addr) {
468 char addr_buffer[32]; 439 char addr_buffer[32];
469 OS::SNPrint(addr_buffer, sizeof(addr_buffer), "%#" Px "", addr); 440 OS::SNPrint(addr_buffer, sizeof(addr_buffer), "%#" Px "", addr);
470 Print(addr_buffer); 441 Print(addr_buffer);
471 442
472 // Try to print as stub name. 443 // Try to print as stub name.
473 const char* name_of_stub = StubCode::NameOfStub(addr); 444 const char* name_of_stub = StubCode::NameOfStub(addr);
474 if (name_of_stub != NULL) { 445 if (name_of_stub != NULL) {
475 Print(" [stub: "); 446 Print(" [stub: ");
476 Print(name_of_stub); 447 Print(name_of_stub);
477 Print("]"); 448 Print("]");
478 } 449 }
479 } 450 }
480 451
481
482 int X86Decoder::PrintRightOperandHelper(uint8_t* modrmp, 452 int X86Decoder::PrintRightOperandHelper(uint8_t* modrmp,
483 RegisterNamePrinter register_printer) { 453 RegisterNamePrinter register_printer) {
484 int mod, regop, rm; 454 int mod, regop, rm;
485 GetModRm(*modrmp, &mod, &regop, &rm); 455 GetModRm(*modrmp, &mod, &regop, &rm);
486 switch (mod) { 456 switch (mod) {
487 case 0: 457 case 0:
488 if (rm == ebp) { 458 if (rm == ebp) {
489 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1); 459 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1);
490 Print("["); 460 Print("[");
491 PrintHex(disp); 461 PrintHex(disp);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 case 3: 562 case 3:
593 (this->*register_printer)(rm); 563 (this->*register_printer)(rm);
594 return 1; 564 return 1;
595 default: 565 default:
596 UNIMPLEMENTED(); 566 UNIMPLEMENTED();
597 return 1; 567 return 1;
598 } 568 }
599 UNREACHABLE(); 569 UNREACHABLE();
600 } 570 }
601 571
602
603 int X86Decoder::PrintRightOperand(uint8_t* modrmp) { 572 int X86Decoder::PrintRightOperand(uint8_t* modrmp) {
604 return PrintRightOperandHelper(modrmp, &X86Decoder::PrintCPURegister); 573 return PrintRightOperandHelper(modrmp, &X86Decoder::PrintCPURegister);
605 } 574 }
606 575
607
608 int X86Decoder::PrintRightXmmOperand(uint8_t* modrmp) { 576 int X86Decoder::PrintRightXmmOperand(uint8_t* modrmp) {
609 return PrintRightOperandHelper(modrmp, &X86Decoder::PrintXmmRegister); 577 return PrintRightOperandHelper(modrmp, &X86Decoder::PrintXmmRegister);
610 } 578 }
611 579
612
613 int X86Decoder::PrintRightByteOperand(uint8_t* modrmp) { 580 int X86Decoder::PrintRightByteOperand(uint8_t* modrmp) {
614 return PrintRightOperandHelper(modrmp, &X86Decoder::PrintCPUByteRegister); 581 return PrintRightOperandHelper(modrmp, &X86Decoder::PrintCPUByteRegister);
615 } 582 }
616 583
617
618 int X86Decoder::PrintOperands(const char* mnem, 584 int X86Decoder::PrintOperands(const char* mnem,
619 OperandOrder op_order, 585 OperandOrder op_order,
620 uint8_t* data) { 586 uint8_t* data) {
621 uint8_t modrm = *data; 587 uint8_t modrm = *data;
622 int mod, regop, rm; 588 int mod, regop, rm;
623 GetModRm(modrm, &mod, &regop, &rm); 589 GetModRm(modrm, &mod, &regop, &rm);
624 int advance = 0; 590 int advance = 0;
625 switch (op_order) { 591 switch (op_order) {
626 case REG_OPER_OP_ORDER: { 592 case REG_OPER_OP_ORDER: {
627 Print(mnem); 593 Print(mnem);
(...skipping 11 matching lines...) Expand all
639 PrintCPURegister(regop); 605 PrintCPURegister(regop);
640 break; 606 break;
641 } 607 }
642 default: 608 default:
643 UNREACHABLE(); 609 UNREACHABLE();
644 break; 610 break;
645 } 611 }
646 return advance; 612 return advance;
647 } 613 }
648 614
649
650 int X86Decoder::PrintImmediateOp(uint8_t* data, bool size_override) { 615 int X86Decoder::PrintImmediateOp(uint8_t* data, bool size_override) {
651 bool sign_extension_bit = (*data & 0x02) != 0; 616 bool sign_extension_bit = (*data & 0x02) != 0;
652 uint8_t modrm = *(data + 1); 617 uint8_t modrm = *(data + 1);
653 int mod, regop, rm; 618 int mod, regop, rm;
654 GetModRm(modrm, &mod, &regop, &rm); 619 GetModRm(modrm, &mod, &regop, &rm);
655 const char* mnem = "Imm???"; 620 const char* mnem = "Imm???";
656 switch (regop) { 621 switch (regop) {
657 case 0: 622 case 0:
658 mnem = "add"; 623 mnem = "add";
659 break; 624 break;
(...skipping 30 matching lines...) Expand all
690 return 1 + count + 2 /*int16_t*/; 655 return 1 + count + 2 /*int16_t*/;
691 } else if (sign_extension_bit) { 656 } else if (sign_extension_bit) {
692 PrintHex(*reinterpret_cast<int8_t*>(data + 1 + count), sign_extension_bit); 657 PrintHex(*reinterpret_cast<int8_t*>(data + 1 + count), sign_extension_bit);
693 return 1 + count + 1 /*int8_t*/; 658 return 1 + count + 1 /*int8_t*/;
694 } else { 659 } else {
695 PrintHex(*reinterpret_cast<int32_t*>(data + 1 + count)); 660 PrintHex(*reinterpret_cast<int32_t*>(data + 1 + count));
696 return 1 + count + 4 /*int32_t*/; 661 return 1 + count + 4 /*int32_t*/;
697 } 662 }
698 } 663 }
699 664
700
701 int X86Decoder::DecodeEnter(uint8_t* data) { 665 int X86Decoder::DecodeEnter(uint8_t* data) {
702 uint16_t size = *reinterpret_cast<uint16_t*>(data + 1); 666 uint16_t size = *reinterpret_cast<uint16_t*>(data + 1);
703 uint8_t level = *reinterpret_cast<uint8_t*>(data + 3); 667 uint8_t level = *reinterpret_cast<uint8_t*>(data + 3);
704 Print("enter "); 668 Print("enter ");
705 PrintInt(size); 669 PrintInt(size);
706 Print(", "); 670 Print(", ");
707 PrintInt(level); 671 PrintInt(level);
708 return 4; 672 return 4;
709 } 673 }
710 674
711
712 // Returns number of bytes used, including *data. 675 // Returns number of bytes used, including *data.
713 int X86Decoder::JumpShort(uint8_t* data) { 676 int X86Decoder::JumpShort(uint8_t* data) {
714 ASSERT(*data == 0xEB); 677 ASSERT(*data == 0xEB);
715 uint8_t b = *(data + 1); 678 uint8_t b = *(data + 1);
716 uword dest = reinterpret_cast<uword>(data) + static_cast<int8_t>(b) + 2; 679 uword dest = reinterpret_cast<uword>(data) + static_cast<int8_t>(b) + 2;
717 Print("jmp "); 680 Print("jmp ");
718 PrintAddress(dest); 681 PrintAddress(dest);
719 return 2; 682 return 2;
720 } 683 }
721 684
722
723 // Returns number of bytes used, including *data. 685 // Returns number of bytes used, including *data.
724 int X86Decoder::JumpConditional(uint8_t* data, const char* comment) { 686 int X86Decoder::JumpConditional(uint8_t* data, const char* comment) {
725 ASSERT(*data == 0x0F); 687 ASSERT(*data == 0x0F);
726 uint8_t cond = *(data + 1) & 0x0F; 688 uint8_t cond = *(data + 1) & 0x0F;
727 uword dest = 689 uword dest =
728 reinterpret_cast<uword>(data) + *reinterpret_cast<int32_t*>(data + 2) + 6; 690 reinterpret_cast<uword>(data) + *reinterpret_cast<int32_t*>(data + 2) + 6;
729 const char* mnem = jump_conditional_mnem[cond]; 691 const char* mnem = jump_conditional_mnem[cond];
730 Print(mnem); 692 Print(mnem);
731 Print(" "); 693 Print(" ");
732 PrintAddress(dest); 694 PrintAddress(dest);
733 if (comment != NULL) { 695 if (comment != NULL) {
734 Print(", "); 696 Print(", ");
735 Print(comment); 697 Print(comment);
736 } 698 }
737 return 6; // includes 0x0F 699 return 6; // includes 0x0F
738 } 700 }
739 701
740
741 // Returns number of bytes used, including *data. 702 // Returns number of bytes used, including *data.
742 int X86Decoder::JumpConditionalShort(uint8_t* data, const char* comment) { 703 int X86Decoder::JumpConditionalShort(uint8_t* data, const char* comment) {
743 uint8_t cond = *data & 0x0F; 704 uint8_t cond = *data & 0x0F;
744 uint8_t b = *(data + 1); 705 uint8_t b = *(data + 1);
745 uword dest = reinterpret_cast<uword>(data) + static_cast<int8_t>(b) + 2; 706 uword dest = reinterpret_cast<uword>(data) + static_cast<int8_t>(b) + 2;
746 const char* mnem = jump_conditional_mnem[cond]; 707 const char* mnem = jump_conditional_mnem[cond];
747 Print(mnem); 708 Print(mnem);
748 Print(" "); 709 Print(" ");
749 PrintAddress(dest); 710 PrintAddress(dest);
750 if (comment != NULL) { 711 if (comment != NULL) {
751 Print(", "); 712 Print(", ");
752 Print(comment); 713 Print(comment);
753 } 714 }
754 return 2; 715 return 2;
755 } 716 }
756 717
757
758 // Returns number of bytes used, including *data. 718 // Returns number of bytes used, including *data.
759 int X86Decoder::SetCC(uint8_t* data) { 719 int X86Decoder::SetCC(uint8_t* data) {
760 ASSERT(*data == 0x0F); 720 ASSERT(*data == 0x0F);
761 uint8_t cond = *(data + 1) & 0x0F; 721 uint8_t cond = *(data + 1) & 0x0F;
762 const char* mnem = set_conditional_mnem[cond]; 722 const char* mnem = set_conditional_mnem[cond];
763 Print(mnem); 723 Print(mnem);
764 Print(" "); 724 Print(" ");
765 PrintRightByteOperand(data + 2); 725 PrintRightByteOperand(data + 2);
766 return 3; // includes 0x0F 726 return 3; // includes 0x0F
767 } 727 }
768 728
769
770 // Returns number of bytes used, including *data. 729 // Returns number of bytes used, including *data.
771 int X86Decoder::CMov(uint8_t* data) { 730 int X86Decoder::CMov(uint8_t* data) {
772 ASSERT(*data == 0x0F); 731 ASSERT(*data == 0x0F);
773 uint8_t cond = *(data + 1) & 0x0F; 732 uint8_t cond = *(data + 1) & 0x0F;
774 const char* mnem = conditional_move_mnem[cond]; 733 const char* mnem = conditional_move_mnem[cond];
775 int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2); 734 int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2);
776 return 2 + op_size; // includes 0x0F 735 return 2 + op_size; // includes 0x0F
777 } 736 }
778 737
779
780 int X86Decoder::D1D3C1Instruction(uint8_t* data) { 738 int X86Decoder::D1D3C1Instruction(uint8_t* data) {
781 uint8_t op = *data; 739 uint8_t op = *data;
782 ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1); 740 ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1);
783 int mod, regop, rm; 741 int mod, regop, rm;
784 GetModRm(*(data + 1), &mod, &regop, &rm); 742 GetModRm(*(data + 1), &mod, &regop, &rm);
785 int num_bytes = 1; 743 int num_bytes = 1;
786 const char* mnem = NULL; 744 const char* mnem = NULL;
787 switch (regop) { 745 switch (regop) {
788 case 2: 746 case 2:
789 mnem = "rcl"; 747 mnem = "rcl";
(...skipping 23 matching lines...) Expand all
813 PrintInt(*(data + 2)); 771 PrintInt(*(data + 2));
814 num_bytes++; 772 num_bytes++;
815 } else { 773 } else {
816 ASSERT(op == 0xD3); 774 ASSERT(op == 0xD3);
817 num_bytes += PrintRightOperand(data + 1); 775 num_bytes += PrintRightOperand(data + 1);
818 Print(", cl"); 776 Print(", cl");
819 } 777 }
820 return num_bytes; 778 return num_bytes;
821 } 779 }
822 780
823
824 uint8_t* X86Decoder::F3Instruction(uint8_t* data) { 781 uint8_t* X86Decoder::F3Instruction(uint8_t* data) {
825 if (*(data + 1) == 0x0F) { 782 if (*(data + 1) == 0x0F) {
826 uint8_t b2 = *(data + 2); 783 uint8_t b2 = *(data + 2);
827 switch (b2) { 784 switch (b2) {
828 case 0x2C: { 785 case 0x2C: {
829 data += 3; 786 data += 3;
830 data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data); 787 data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data);
831 break; 788 break;
832 } 789 }
833 case 0x2A: { 790 case 0x2A: {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 } 887 }
931 } else if (*(data + 1) == 0xA4) { 888 } else if (*(data + 1) == 0xA4) {
932 Print("rep_movsb"); 889 Print("rep_movsb");
933 data += 2; 890 data += 2;
934 } else { 891 } else {
935 UNIMPLEMENTED(); 892 UNIMPLEMENTED();
936 } 893 }
937 return data; 894 return data;
938 } 895 }
939 896
940
941 // Returns number of bytes used, including *data. 897 // Returns number of bytes used, including *data.
942 int X86Decoder::F7Instruction(uint8_t* data) { 898 int X86Decoder::F7Instruction(uint8_t* data) {
943 ASSERT(*data == 0xF7); 899 ASSERT(*data == 0xF7);
944 uint8_t modrm = *(data + 1); 900 uint8_t modrm = *(data + 1);
945 int mod, regop, rm; 901 int mod, regop, rm;
946 GetModRm(modrm, &mod, &regop, &rm); 902 GetModRm(modrm, &mod, &regop, &rm);
947 if (mod == 3 && regop != 0) { 903 if (mod == 3 && regop != 0) {
948 const char* mnem = NULL; 904 const char* mnem = NULL;
949 switch (regop) { 905 switch (regop) {
950 case 2: 906 case 2:
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 return 2; 1130 return 2;
1175 } else if (b1 == 0xDA && b2 == 0xE9) { 1131 } else if (b1 == 0xDA && b2 == 0xE9) {
1176 const char* mnem = "fucompp"; 1132 const char* mnem = "fucompp";
1177 Print(mnem); 1133 Print(mnem);
1178 return 2; 1134 return 2;
1179 } 1135 }
1180 Print("Unknown FP instruction"); 1136 Print("Unknown FP instruction");
1181 return 2; 1137 return 2;
1182 } 1138 }
1183 1139
1184
1185 uint8_t* X86Decoder::SSEInstruction(uint8_t prefix, 1140 uint8_t* X86Decoder::SSEInstruction(uint8_t prefix,
1186 uint8_t primary, 1141 uint8_t primary,
1187 uint8_t* data) { 1142 uint8_t* data) {
1188 ASSERT(prefix == 0x0F); 1143 ASSERT(prefix == 0x0F);
1189 int mod, regop, rm; 1144 int mod, regop, rm;
1190 if (primary == 0x10) { 1145 if (primary == 0x10) {
1191 GetModRm(*data, &mod, &regop, &rm); 1146 GetModRm(*data, &mod, &regop, &rm);
1192 Print("movups "); 1147 Print("movups ");
1193 PrintXmmRegister(regop); 1148 PrintXmmRegister(regop);
1194 Print(","); 1149 Print(",");
(...skipping 11 matching lines...) Expand all
1206 GetModRm(*data, &mod, &regop, &rm); 1161 GetModRm(*data, &mod, &regop, &rm);
1207 Print(f0mnem); 1162 Print(f0mnem);
1208 Print(" "); 1163 Print(" ");
1209 PrintXmmRegister(regop); 1164 PrintXmmRegister(regop);
1210 Print(","); 1165 Print(",");
1211 data += PrintRightXmmOperand(data); 1166 data += PrintRightXmmOperand(data);
1212 } 1167 }
1213 return data; 1168 return data;
1214 } 1169 }
1215 1170
1216
1217 int X86Decoder::BitwisePDInstruction(uint8_t* data) { 1171 int X86Decoder::BitwisePDInstruction(uint8_t* data) {
1218 const char* mnem = 1172 const char* mnem =
1219 (*data == 0x57) ? "xorpd" : (*data == 0x56) ? "orpd" : "andpd"; 1173 (*data == 0x57) ? "xorpd" : (*data == 0x56) ? "orpd" : "andpd";
1220 int mod, regop, rm; 1174 int mod, regop, rm;
1221 GetModRm(*(data + 1), &mod, &regop, &rm); 1175 GetModRm(*(data + 1), &mod, &regop, &rm);
1222 Print(mnem); 1176 Print(mnem);
1223 Print(" "); 1177 Print(" ");
1224 PrintXmmRegister(regop); 1178 PrintXmmRegister(regop);
1225 Print(","); 1179 Print(",");
1226 return 1 + PrintRightXmmOperand(data + 1); 1180 return 1 + PrintRightXmmOperand(data + 1);
1227 } 1181 }
1228 1182
1229
1230 int X86Decoder::Packed660F38Instruction(uint8_t* data) { 1183 int X86Decoder::Packed660F38Instruction(uint8_t* data) {
1231 if (*(data + 1) == 0x25) { 1184 if (*(data + 1) == 0x25) {
1232 Print("pmovsxdq "); 1185 Print("pmovsxdq ");
1233 int mod, regop, rm; 1186 int mod, regop, rm;
1234 GetModRm(*(data + 2), &mod, &regop, &rm); 1187 GetModRm(*(data + 2), &mod, &regop, &rm);
1235 PrintXmmRegister(regop); 1188 PrintXmmRegister(regop);
1236 Print(","); 1189 Print(",");
1237 return 2 + PrintRightXmmOperand(data + 2); 1190 return 2 + PrintRightXmmOperand(data + 2);
1238 } else if (*(data + 1) == 0x29) { 1191 } else if (*(data + 1) == 0x29) {
1239 Print("pcmpeqq "); 1192 Print("pcmpeqq ");
1240 int mod, regop, rm; 1193 int mod, regop, rm;
1241 GetModRm(*(data + 2), &mod, &regop, &rm); 1194 GetModRm(*(data + 2), &mod, &regop, &rm);
1242 PrintXmmRegister(regop); 1195 PrintXmmRegister(regop);
1243 Print(","); 1196 Print(",");
1244 return 2 + PrintRightXmmOperand(data + 2); 1197 return 2 + PrintRightXmmOperand(data + 2);
1245 } 1198 }
1246 UNREACHABLE(); 1199 UNREACHABLE();
1247 return 1; 1200 return 1;
1248 } 1201 }
1249 1202
1250
1251 // Called when disassembling test eax, 0xXXXXX. 1203 // Called when disassembling test eax, 0xXXXXX.
1252 void X86Decoder::CheckPrintStop(uint8_t* data) { 1204 void X86Decoder::CheckPrintStop(uint8_t* data) {
1253 // Recognize stop pattern. 1205 // Recognize stop pattern.
1254 if (*reinterpret_cast<uint8_t*>(data + 5) == 0xCC) { 1206 if (*reinterpret_cast<uint8_t*>(data + 5) == 0xCC) {
1255 Print(" STOP:'"); 1207 Print(" STOP:'");
1256 const char* text = *reinterpret_cast<const char**>(data + 1); 1208 const char* text = *reinterpret_cast<const char**>(data + 1);
1257 Print(text); 1209 Print(text);
1258 Print("'"); 1210 Print("'");
1259 } 1211 }
1260 } 1212 }
1261 1213
1262 const char* X86Decoder::GetBranchPrefix(uint8_t** data) { 1214 const char* X86Decoder::GetBranchPrefix(uint8_t** data) {
1263 // We use these two prefixes only with branch prediction 1215 // We use these two prefixes only with branch prediction
1264 switch (**data) { 1216 switch (**data) {
1265 case 0x3E: // ds 1217 case 0x3E: // ds
1266 (*data)++; 1218 (*data)++;
1267 return "predicted taken"; 1219 return "predicted taken";
1268 case 0x2E: // cs 1220 case 0x2E: // cs
1269 (*data)++; 1221 (*data)++;
1270 return "predicted not taken"; 1222 return "predicted not taken";
1271 case 0xF0: // lock 1223 case 0xF0: // lock
1272 Print("lock "); 1224 Print("lock ");
1273 (*data)++; 1225 (*data)++;
1274 return NULL; 1226 return NULL;
1275 default: // Ignore all other instructions. 1227 default: // Ignore all other instructions.
1276 return NULL; 1228 return NULL;
1277 } 1229 }
1278 } 1230 }
1279 1231
1280
1281 bool X86Decoder::DecodeInstructionType(const InstructionDesc& idesc, 1232 bool X86Decoder::DecodeInstructionType(const InstructionDesc& idesc,
1282 const char* branch_hint, 1233 const char* branch_hint,
1283 uint8_t** data) { 1234 uint8_t** data) {
1284 switch (idesc.type) { 1235 switch (idesc.type) {
1285 case ZERO_OPERANDS_INSTR: 1236 case ZERO_OPERANDS_INSTR:
1286 Print(idesc.mnem); 1237 Print(idesc.mnem);
1287 (*data)++; 1238 (*data)++;
1288 return true; 1239 return true;
1289 1240
1290 case TWO_OPERANDS_INSTR: 1241 case TWO_OPERANDS_INSTR:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1333 1284
1334 case NO_INSTR: 1285 case NO_INSTR:
1335 return false; 1286 return false;
1336 1287
1337 default: 1288 default:
1338 UNIMPLEMENTED(); // This type is not implemented. 1289 UNIMPLEMENTED(); // This type is not implemented.
1339 return false; 1290 return false;
1340 } 1291 }
1341 } 1292 }
1342 1293
1343
1344 int X86Decoder::InstructionDecode(uword pc) { 1294 int X86Decoder::InstructionDecode(uword pc) {
1345 uint8_t* data = reinterpret_cast<uint8_t*>(pc); 1295 uint8_t* data = reinterpret_cast<uint8_t*>(pc);
1346 // Check for hints. 1296 // Check for hints.
1347 const char* branch_hint = GetBranchPrefix(&data); 1297 const char* branch_hint = GetBranchPrefix(&data);
1348 const InstructionDesc& idesc = instruction_table.Get(*data); 1298 const InstructionDesc& idesc = instruction_table.Get(*data);
1349 // Will be set to false if the current instruction 1299 // Will be set to false if the current instruction
1350 // is not in 'instructions' table. 1300 // is not in 'instructions' table.
1351 bool processed = DecodeInstructionType(idesc, branch_hint, &data); 1301 bool processed = DecodeInstructionType(idesc, branch_hint, &data);
1352 //---------------------------- 1302 //----------------------------
1353 if (!processed) { 1303 if (!processed) {
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 UNIMPLEMENTED(); 1855 UNIMPLEMENTED();
1906 } 1856 }
1907 } 1857 }
1908 1858
1909 int instr_len = data - reinterpret_cast<uint8_t*>(pc); 1859 int instr_len = data - reinterpret_cast<uint8_t*>(pc);
1910 ASSERT(instr_len > 0); // Ensure progress. 1860 ASSERT(instr_len > 0); // Ensure progress.
1911 1861
1912 return instr_len; 1862 return instr_len;
1913 } // NOLINT 1863 } // NOLINT
1914 1864
1915
1916 void Disassembler::DecodeInstruction(char* hex_buffer, 1865 void Disassembler::DecodeInstruction(char* hex_buffer,
1917 intptr_t hex_size, 1866 intptr_t hex_size,
1918 char* human_buffer, 1867 char* human_buffer,
1919 intptr_t human_size, 1868 intptr_t human_size,
1920 int* out_instr_len, 1869 int* out_instr_len,
1921 const Code& code, 1870 const Code& code,
1922 Object** object, 1871 Object** object,
1923 uword pc) { 1872 uword pc) {
1924 ASSERT(hex_size > 0); 1873 ASSERT(hex_size > 0);
1925 ASSERT(human_size > 0); 1874 ASSERT(human_size > 0);
(...skipping 23 matching lines...) Expand all
1949 } 1898 }
1950 } 1899 }
1951 } 1900 }
1952 } 1901 }
1953 1902
1954 #endif // !PRODUCT 1903 #endif // !PRODUCT
1955 1904
1956 } // namespace dart 1905 } // namespace dart
1957 1906
1958 #endif // defined TARGET_ARCH_IA32 1907 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/disassembler_dbc.cc ('k') | runtime/vm/disassembler_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698