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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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_mips.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 { 21 enum OperandOrder { UNSET_OP_ORDER = 0, REG_OPER_OP_ORDER, OPER_REG_OP_ORDER };
22 UNSET_OP_ORDER = 0,
23 REG_OPER_OP_ORDER,
24 OPER_REG_OP_ORDER
25 };
26 22
27 23
28 struct ByteMnemonic { 24 struct ByteMnemonic {
29 int b; // -1 terminates, otherwise must be in range (0..255) 25 int b; // -1 terminates, otherwise must be in range (0..255)
30 const char* mnem; 26 const char* mnem;
31 OperandOrder op_order_; 27 OperandOrder op_order_;
32 }; 28 };
33 29
34 30
35 static ByteMnemonic two_operands_instr[] = { 31 static ByteMnemonic two_operands_instr[] = {
36 {0x01, "add", OPER_REG_OP_ORDER}, 32 {0x01, "add", OPER_REG_OP_ORDER}, {0x03, "add", REG_OPER_OP_ORDER},
37 {0x03, "add", REG_OPER_OP_ORDER}, 33 {0x09, "or", OPER_REG_OP_ORDER}, {0x0B, "or", REG_OPER_OP_ORDER},
38 {0x09, "or", OPER_REG_OP_ORDER}, 34 {0x11, "adc", OPER_REG_OP_ORDER}, {0x13, "adc", REG_OPER_OP_ORDER},
39 {0x0B, "or", REG_OPER_OP_ORDER}, 35 {0x19, "sbb", OPER_REG_OP_ORDER}, {0x1B, "sbb", REG_OPER_OP_ORDER},
40 {0x11, "adc", OPER_REG_OP_ORDER}, 36 {0x21, "and", OPER_REG_OP_ORDER}, {0x23, "and", REG_OPER_OP_ORDER},
41 {0x13, "adc", REG_OPER_OP_ORDER}, 37 {0x29, "sub", OPER_REG_OP_ORDER}, {0x2B, "sub", REG_OPER_OP_ORDER},
42 {0x19, "sbb", OPER_REG_OP_ORDER}, 38 {0x31, "xor", OPER_REG_OP_ORDER}, {0x33, "xor", REG_OPER_OP_ORDER},
43 {0x1B, "sbb", REG_OPER_OP_ORDER}, 39 {0x39, "cmp", OPER_REG_OP_ORDER}, {0x3B, "cmp", REG_OPER_OP_ORDER},
44 {0x21, "and", OPER_REG_OP_ORDER}, 40 {0x85, "test", REG_OPER_OP_ORDER}, {0x87, "xchg", REG_OPER_OP_ORDER},
45 {0x23, "and", REG_OPER_OP_ORDER}, 41 {0x8A, "mov_b", REG_OPER_OP_ORDER}, {0x8B, "mov", REG_OPER_OP_ORDER},
46 {0x29, "sub", OPER_REG_OP_ORDER}, 42 {0x8D, "lea", REG_OPER_OP_ORDER}, {-1, "", UNSET_OP_ORDER}};
47 {0x2B, "sub", REG_OPER_OP_ORDER},
48 {0x31, "xor", OPER_REG_OP_ORDER},
49 {0x33, "xor", REG_OPER_OP_ORDER},
50 {0x39, "cmp", OPER_REG_OP_ORDER},
51 {0x3B, "cmp", REG_OPER_OP_ORDER},
52 {0x85, "test", REG_OPER_OP_ORDER},
53 {0x87, "xchg", REG_OPER_OP_ORDER},
54 {0x8A, "mov_b", REG_OPER_OP_ORDER},
55 {0x8B, "mov", REG_OPER_OP_ORDER},
56 {0x8D, "lea", REG_OPER_OP_ORDER},
57 {-1, "", UNSET_OP_ORDER}
58 };
59 43
60 44
61 static ByteMnemonic zero_operands_instr[] = { 45 static ByteMnemonic zero_operands_instr[] = {
62 {0xC3, "ret", UNSET_OP_ORDER}, 46 {0xC3, "ret", UNSET_OP_ORDER}, {0xC9, "leave", UNSET_OP_ORDER},
63 {0xC9, "leave", UNSET_OP_ORDER}, 47 {0x90, "nop", UNSET_OP_ORDER}, {0xF4, "hlt", UNSET_OP_ORDER},
64 {0x90, "nop", UNSET_OP_ORDER}, 48 {0xCC, "int3", UNSET_OP_ORDER}, {0x60, "pushad", UNSET_OP_ORDER},
65 {0xF4, "hlt", UNSET_OP_ORDER}, 49 {0x61, "popad", UNSET_OP_ORDER}, {0x9C, "pushfd", UNSET_OP_ORDER},
66 {0xCC, "int3", UNSET_OP_ORDER}, 50 {0x9D, "popfd", UNSET_OP_ORDER}, {0x9E, "sahf", UNSET_OP_ORDER},
67 {0x60, "pushad", UNSET_OP_ORDER}, 51 {0x99, "cdq", UNSET_OP_ORDER}, {0x9B, "fwait", UNSET_OP_ORDER},
68 {0x61, "popad", UNSET_OP_ORDER}, 52 {-1, "", UNSET_OP_ORDER}};
69 {0x9C, "pushfd", UNSET_OP_ORDER},
70 {0x9D, "popfd", UNSET_OP_ORDER},
71 {0x9E, "sahf", UNSET_OP_ORDER},
72 {0x99, "cdq", UNSET_OP_ORDER},
73 {0x9B, "fwait", UNSET_OP_ORDER},
74 {-1, "", UNSET_OP_ORDER}
75 };
76 53
77 54
78 static ByteMnemonic call_jump_instr[] = { 55 static ByteMnemonic call_jump_instr[] = {{0xE8, "call", UNSET_OP_ORDER},
79 {0xE8, "call", UNSET_OP_ORDER}, 56 {0xE9, "jmp", UNSET_OP_ORDER},
80 {0xE9, "jmp", UNSET_OP_ORDER}, 57 {-1, "", UNSET_OP_ORDER}};
81 {-1, "", UNSET_OP_ORDER}
82 };
83 58
84 59
85 static ByteMnemonic short_immediate_instr[] = { 60 static ByteMnemonic short_immediate_instr[] = {
86 {0x05, "add", UNSET_OP_ORDER}, 61 {0x05, "add", UNSET_OP_ORDER}, {0x0D, "or", UNSET_OP_ORDER},
87 {0x0D, "or", UNSET_OP_ORDER}, 62 {0x15, "adc", UNSET_OP_ORDER}, {0x25, "and", UNSET_OP_ORDER},
88 {0x15, "adc", UNSET_OP_ORDER}, 63 {0x2D, "sub", UNSET_OP_ORDER}, {0x35, "xor", UNSET_OP_ORDER},
89 {0x25, "and", UNSET_OP_ORDER}, 64 {0x3D, "cmp", UNSET_OP_ORDER}, {-1, "", UNSET_OP_ORDER}};
90 {0x2D, "sub", UNSET_OP_ORDER},
91 {0x35, "xor", UNSET_OP_ORDER},
92 {0x3D, "cmp", UNSET_OP_ORDER},
93 {-1, "", UNSET_OP_ORDER}
94 };
95 65
96 66
97 static const char* jump_conditional_mnem[] = { 67 static const char* jump_conditional_mnem[] = {
98 /*0*/ "jo", "jno", "jc", "jnc", 68 /*0*/ "jo", "jno", "jc", "jnc",
99 /*4*/ "jz", "jnz", "jna", "ja", 69 /*4*/ "jz", "jnz", "jna", "ja",
100 /*8*/ "js", "jns", "jpe", "jpo", 70 /*8*/ "js", "jns", "jpe", "jpo",
101 /*12*/ "jl", "jnl", "jng", "jg" 71 /*12*/ "jl", "jnl", "jng", "jg"};
102 };
103 72
104 73
105 static const char* set_conditional_mnem[] = { 74 static const char* set_conditional_mnem[] = {
106 /*0*/ "seto", "setno", "setc", "setnc", 75 /*0*/ "seto", "setno", "setc", "setnc",
107 /*4*/ "setz", "setnz", "setna", "seta", 76 /*4*/ "setz", "setnz", "setna", "seta",
108 /*8*/ "sets", "setns", "setpe", "setpo", 77 /*8*/ "sets", "setns", "setpe", "setpo",
109 /*12*/ "setl", "setnl", "setng", "setg" 78 /*12*/ "setl", "setnl", "setng", "setg"};
110 };
111 79
112 80
113 static const char* conditional_move_mnem[] = { 81 static const char* conditional_move_mnem[] = {
114 /*0*/ "cmovo", "cmovno", "cmovc", "cmovnc", 82 /*0*/ "cmovo", "cmovno", "cmovc", "cmovnc",
115 /*4*/ "cmovz", "cmovnz", "cmovna", "cmova", 83 /*4*/ "cmovz", "cmovnz", "cmovna", "cmova",
116 /*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo", 84 /*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo",
117 /*12*/ "cmovl", "cmovnl", "cmovng", "cmovg" 85 /*12*/ "cmovl", "cmovnl", "cmovng", "cmovg"};
118 };
119 86
120 87
121 enum InstructionType { 88 enum InstructionType {
122 NO_INSTR, 89 NO_INSTR,
123 ZERO_OPERANDS_INSTR, 90 ZERO_OPERANDS_INSTR,
124 TWO_OPERANDS_INSTR, 91 TWO_OPERANDS_INSTR,
125 JUMP_CONDITIONAL_SHORT_INSTR, 92 JUMP_CONDITIONAL_SHORT_INSTR,
126 REGISTER_INSTR, 93 REGISTER_INSTR,
127 MOVE_REG_INSTR, 94 MOVE_REG_INSTR,
128 CALL_JUMP_INSTR, 95 CALL_JUMP_INSTR,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 } 188 }
222 189
223 190
224 static InstructionTable instruction_table; 191 static InstructionTable instruction_table;
225 192
226 193
227 // Mnemonics for instructions 0xF0 byte. 194 // Mnemonics for instructions 0xF0 byte.
228 // Returns NULL if the instruction is not handled here. 195 // Returns NULL if the instruction is not handled here.
229 static const char* F0Mnem(uint8_t f0byte) { 196 static const char* F0Mnem(uint8_t f0byte) {
230 switch (f0byte) { 197 switch (f0byte) {
231 case 0x12: return "movhlps"; 198 case 0x12:
232 case 0x14: return "unpcklps"; 199 return "movhlps";
233 case 0x15: return "unpckhps"; 200 case 0x14:
234 case 0x16: return "movlhps"; 201 return "unpcklps";
235 case 0xA2: return "cpuid"; 202 case 0x15:
236 case 0x31: return "rdtsc"; 203 return "unpckhps";
237 case 0xBE: return "movsx_b"; 204 case 0x16:
238 case 0xBF: return "movsx_w"; 205 return "movlhps";
239 case 0xB6: return "movzx_b"; 206 case 0xA2:
240 case 0xB7: return "movzx_w"; 207 return "cpuid";
241 case 0xAF: return "imul"; 208 case 0x31:
209 return "rdtsc";
210 case 0xBE:
211 return "movsx_b";
212 case 0xBF:
213 return "movsx_w";
214 case 0xB6:
215 return "movzx_b";
216 case 0xB7:
217 return "movzx_w";
218 case 0xAF:
219 return "imul";
242 case 0xA4: // Fall through. 220 case 0xA4: // Fall through.
243 case 0xA5: return "shld"; 221 case 0xA5:
222 return "shld";
244 case 0xAC: // Fall through. 223 case 0xAC: // Fall through.
245 case 0xAD: return "shrd"; 224 case 0xAD:
246 case 0xA3: return "bt"; 225 return "shrd";
247 case 0xAB: return "bts"; 226 case 0xA3:
248 case 0xBD: return "bsr"; 227 return "bt";
249 case 0xB1: return "cmpxchg"; 228 case 0xAB:
250 case 0x50: return "movmskps"; 229 return "bts";
251 case 0x51: return "sqrtps"; 230 case 0xBD:
252 case 0x52: return "rqstps"; 231 return "bsr";
253 case 0x53: return "rcpps"; 232 case 0xB1:
254 case 0x54: return "andps"; 233 return "cmpxchg";
255 case 0x56: return "orps"; 234 case 0x50:
256 case 0x57: return "xorps"; 235 return "movmskps";
257 case 0x58: return "addps"; 236 case 0x51:
258 case 0x59: return "mulps"; 237 return "sqrtps";
259 case 0x5A: return "cvtps2pd"; 238 case 0x52:
260 case 0x5C: return "subps"; 239 return "rqstps";
261 case 0x5D: return "minps"; 240 case 0x53:
262 case 0x5E: return "divps"; 241 return "rcpps";
263 case 0x5F: return "maxps"; 242 case 0x54:
264 case 0x28: return "movaps"; 243 return "andps";
265 case 0x10: return "movups"; 244 case 0x56:
266 case 0x11: return "movups"; 245 return "orps";
267 default: return NULL; 246 case 0x57:
247 return "xorps";
248 case 0x58:
249 return "addps";
250 case 0x59:
251 return "mulps";
252 case 0x5A:
253 return "cvtps2pd";
254 case 0x5C:
255 return "subps";
256 case 0x5D:
257 return "minps";
258 case 0x5E:
259 return "divps";
260 case 0x5F:
261 return "maxps";
262 case 0x28:
263 return "movaps";
264 case 0x10:
265 return "movups";
266 case 0x11:
267 return "movups";
268 default:
269 return NULL;
268 } 270 }
269 } 271 }
270 272
271 static const char* PackedDoubleMnemonic(uint8_t data) { 273 static const char* PackedDoubleMnemonic(uint8_t data) {
272 const char* mnemonic = NULL; 274 const char* mnemonic = NULL;
273 if (data == 0xFE) mnemonic = "paddd "; 275 if (data == 0xFE) mnemonic = "paddd ";
274 if (data == 0xFA) mnemonic = "psubd "; 276 if (data == 0xFA) mnemonic = "psubd ";
275 if (data == 0x2F) mnemonic = "comisd "; 277 if (data == 0x2F) mnemonic = "comisd ";
276 if (data == 0x58) mnemonic = "addpd "; 278 if (data == 0x58) mnemonic = "addpd ";
277 if (data == 0x5C) mnemonic = "subpd "; 279 if (data == 0x5C) mnemonic = "subpd ";
278 if (data == 0x59) mnemonic = "mulpd "; 280 if (data == 0x59) mnemonic = "mulpd ";
279 if (data == 0x5E) mnemonic = "divpd "; 281 if (data == 0x5E) mnemonic = "divpd ";
280 if (data == 0x5D) mnemonic = "minpd "; 282 if (data == 0x5D) mnemonic = "minpd ";
281 if (data == 0x5F) mnemonic = "maxpd "; 283 if (data == 0x5F) mnemonic = "maxpd ";
282 if (data == 0x51) mnemonic = "sqrtpd "; 284 if (data == 0x51) mnemonic = "sqrtpd ";
283 if (data == 0x5A) mnemonic = "cvtpd2ps "; 285 if (data == 0x5A) mnemonic = "cvtpd2ps ";
284 ASSERT(mnemonic != NULL); 286 ASSERT(mnemonic != NULL);
285 return mnemonic; 287 return mnemonic;
286 } 288 }
287 289
288 290
289 static bool IsTwoXmmRegInstruction(uint8_t f0byte) { 291 static bool IsTwoXmmRegInstruction(uint8_t f0byte) {
290 return f0byte == 0x28 || f0byte == 0x11 || f0byte == 0x12 || 292 return f0byte == 0x28 || f0byte == 0x11 || f0byte == 0x12 || f0byte == 0x14 ||
291 f0byte == 0x14 || f0byte == 0x15 || f0byte == 0x16 || 293 f0byte == 0x15 || f0byte == 0x16 || f0byte == 0x51 || f0byte == 0x52 ||
292 f0byte == 0x51 || f0byte == 0x52 || f0byte == 0x53 || 294 f0byte == 0x53 || f0byte == 0x54 || f0byte == 0x56 || f0byte == 0x58 ||
293 f0byte == 0x54 || f0byte == 0x56 || f0byte == 0x58 || 295 f0byte == 0x59 || f0byte == 0x5C || f0byte == 0x5D || f0byte == 0x5E ||
294 f0byte == 0x59 || f0byte == 0x5C || f0byte == 0x5D || 296 f0byte == 0x5F || f0byte == 0x5A;
295 f0byte == 0x5E || f0byte == 0x5F || f0byte == 0x5A;
296 } 297 }
297 298
298 299
299 // The implementation of x86 decoding based on the above tables. 300 // The implementation of x86 decoding based on the above tables.
300 class X86Decoder : public ValueObject { 301 class X86Decoder : public ValueObject {
301 public: 302 public:
302 X86Decoder(char* buffer, intptr_t buffer_size) 303 X86Decoder(char* buffer, intptr_t buffer_size)
303 : buffer_(buffer), 304 : buffer_(buffer), buffer_size_(buffer_size), buffer_pos_(0) {
304 buffer_size_(buffer_size),
305 buffer_pos_(0) {
306 buffer_[buffer_pos_] = '\0'; 305 buffer_[buffer_pos_] = '\0';
307 } 306 }
308 307
309 ~X86Decoder() {} 308 ~X86Decoder() {}
310 309
311 // Writes one disassembled instruction into the buffer (0-terminated). 310 // Writes one disassembled instruction into the buffer (0-terminated).
312 // Returns the length of the disassembled machine instruction in bytes. 311 // Returns the length of the disassembled machine instruction in bytes.
313 int InstructionDecode(uword pc); 312 int InstructionDecode(uword pc);
314 313
315 private: 314 private:
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 *index = (data >> 3) & 7; 378 *index = (data >> 3) & 7;
380 *base = data & 7; 379 *base = data & 7;
381 } 380 }
382 381
383 382
384 // Convenience functions. 383 // Convenience functions.
385 char* get_buffer() const { return buffer_; } 384 char* get_buffer() const { return buffer_; }
386 char* current_position_in_buffer() { return buffer_ + buffer_pos_; } 385 char* current_position_in_buffer() { return buffer_ + buffer_pos_; }
387 intptr_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; } 386 intptr_t remaining_size_in_buffer() { return buffer_size_ - buffer_pos_; }
388 387
389 char* buffer_; // Decode instructions into this buffer. 388 char* buffer_; // Decode instructions into this buffer.
390 intptr_t buffer_size_; // The size of the buffer_. 389 intptr_t buffer_size_; // The size of the buffer_.
391 intptr_t buffer_pos_; // Current character position in the buffer_. 390 intptr_t buffer_pos_; // Current character position in the buffer_.
392 391
393 DISALLOW_COPY_AND_ASSIGN(X86Decoder); 392 DISALLOW_COPY_AND_ASSIGN(X86Decoder);
394 }; 393 };
395 394
396 395
397 void X86Decoder::PrintInt(int value) { 396 void X86Decoder::PrintInt(int value) {
398 char int_buffer[16]; 397 char int_buffer[16];
399 OS::SNPrint(int_buffer, sizeof(int_buffer), "%#x", value); 398 OS::SNPrint(int_buffer, sizeof(int_buffer), "%#x", value);
400 Print(int_buffer); 399 Print(int_buffer);
401 } 400 }
(...skipping 12 matching lines...) Expand all
414 char cur = *str++; 413 char cur = *str++;
415 while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) { 414 while (cur != '\0' && (buffer_pos_ < (buffer_size_ - 1))) {
416 buffer_[buffer_pos_++] = cur; 415 buffer_[buffer_pos_++] = cur;
417 cur = *str++; 416 cur = *str++;
418 } 417 }
419 buffer_[buffer_pos_] = '\0'; 418 buffer_[buffer_pos_] = '\0';
420 } 419 }
421 420
422 421
423 static const int kMaxCPURegisters = 8; 422 static const int kMaxCPURegisters = 8;
424 static const char* cpu_regs[kMaxCPURegisters] = { 423 static const char* cpu_regs[kMaxCPURegisters] = {"eax", "ecx", "edx", "ebx",
425 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" 424 "esp", "ebp", "esi", "edi"};
426 };
427 425
428 static const int kMaxByteCPURegisters = 8; 426 static const int kMaxByteCPURegisters = 8;
429 static const char* byte_cpu_regs[kMaxByteCPURegisters] = { 427 static const char* byte_cpu_regs[kMaxByteCPURegisters] = {
430 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" 428 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"};
431 };
432 429
433 static const int kMaxXmmRegisters = 8; 430 static const int kMaxXmmRegisters = 8;
434 static const char* xmm_regs[kMaxXmmRegisters] = { 431 static const char* xmm_regs[kMaxXmmRegisters] = {
435 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" 432 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"};
436 };
437 433
438 void X86Decoder::PrintCPURegister(int reg) { 434 void X86Decoder::PrintCPURegister(int reg) {
439 ASSERT(0 <= reg); 435 ASSERT(0 <= reg);
440 ASSERT(reg < kMaxCPURegisters); 436 ASSERT(reg < kMaxCPURegisters);
441 Print(cpu_regs[reg]); 437 Print(cpu_regs[reg]);
442 } 438 }
443 439
444 440
445 void X86Decoder::PrintCPUByteRegister(int reg) { 441 void X86Decoder::PrintCPUByteRegister(int reg) {
446 ASSERT(0 <= reg); 442 ASSERT(0 <= reg);
447 ASSERT(reg < kMaxByteCPURegisters); 443 ASSERT(reg < kMaxByteCPURegisters);
448 Print(byte_cpu_regs[reg]); 444 Print(byte_cpu_regs[reg]);
449 } 445 }
450 446
451 447
452 void X86Decoder::PrintXmmRegister(int reg) { 448 void X86Decoder::PrintXmmRegister(int reg) {
453 ASSERT(0 <= reg); 449 ASSERT(0 <= reg);
454 ASSERT(reg < kMaxXmmRegisters); 450 ASSERT(reg < kMaxXmmRegisters);
455 Print(xmm_regs[reg]); 451 Print(xmm_regs[reg]);
456 } 452 }
457 453
458 void X86Decoder::PrintXmmComparison(int comparison) { 454 void X86Decoder::PrintXmmComparison(int comparison) {
459 ASSERT(0 <= comparison); 455 ASSERT(0 <= comparison);
460 ASSERT(comparison < 8); 456 ASSERT(comparison < 8);
461 static const char* comparisons[8] = { 457 static const char* comparisons[8] = {
462 "eq", "lt", "le", "unordered", "not eq", "not lt", "not le", "ordered" 458 "eq", "lt", "le", "unordered", "not eq", "not lt", "not le", "ordered"};
463 };
464 Print(comparisons[comparison]); 459 Print(comparisons[comparison]);
465 } 460 }
466 461
467 462
468 void X86Decoder::PrintAddress(uword addr) { 463 void X86Decoder::PrintAddress(uword addr) {
469 char addr_buffer[32]; 464 char addr_buffer[32];
470 OS::SNPrint(addr_buffer, sizeof(addr_buffer), "%#" Px "", addr); 465 OS::SNPrint(addr_buffer, sizeof(addr_buffer), "%#" Px "", addr);
471 Print(addr_buffer); 466 Print(addr_buffer);
472 467
473 // Try to print as stub name. 468 // Try to print as stub name.
474 const char* name_of_stub = StubCode::NameOfStub(addr); 469 const char* name_of_stub = StubCode::NameOfStub(addr);
475 if (name_of_stub != NULL) { 470 if (name_of_stub != NULL) {
476 Print(" [stub: "); 471 Print(" [stub: ");
477 Print(name_of_stub); 472 Print(name_of_stub);
478 Print("]"); 473 Print("]");
479 } 474 }
480 } 475 }
481 476
482 477
483 int X86Decoder::PrintRightOperandHelper(uint8_t* modrmp, 478 int X86Decoder::PrintRightOperandHelper(uint8_t* modrmp,
484 RegisterNamePrinter register_printer) { 479 RegisterNamePrinter register_printer) {
485 int mod, regop, rm; 480 int mod, regop, rm;
486 GetModRm(*modrmp, &mod, &regop, &rm); 481 GetModRm(*modrmp, &mod, &regop, &rm);
487 switch (mod) { 482 switch (mod) {
488 case 0: 483 case 0:
489 if (rm == ebp) { 484 if (rm == ebp) {
490 int32_t disp = *reinterpret_cast<int32_t*>(modrmp+1); 485 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1);
491 Print("["); 486 Print("[");
492 PrintHex(disp); 487 PrintHex(disp);
493 Print("]"); 488 Print("]");
494 return 5; 489 return 5;
495 } else if (rm == esp) { 490 } else if (rm == esp) {
496 uint8_t sib = *(modrmp + 1); 491 uint8_t sib = *(modrmp + 1);
497 int scale, index, base; 492 int scale, index, base;
498 GetSib(sib, &scale, &index, &base); 493 GetSib(sib, &scale, &index, &base);
499 if (index == esp && base == esp && scale == 0 /*times_1*/) { 494 if (index == esp && base == esp && scale == 0 /*times_1*/) {
500 Print("["); 495 Print("[");
501 PrintCPURegister(rm); 496 PrintCPURegister(rm);
502 Print("]"); 497 Print("]");
503 return 2; 498 return 2;
504 } else if (base == ebp) { 499 } else if (base == ebp) {
505 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); 500 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2);
506 Print("["); 501 Print("[");
507 PrintCPURegister(index); 502 PrintCPURegister(index);
508 Print("*"); 503 Print("*");
509 PrintInt(1 << scale); 504 PrintInt(1 << scale);
510 if (disp < 0) { 505 if (disp < 0) {
511 Print("-"); 506 Print("-");
512 disp = -disp; 507 disp = -disp;
513 } else { 508 } else {
514 Print("+"); 509 Print("+");
515 } 510 }
516 PrintHex(disp); 511 PrintHex(disp);
517 Print("]"); 512 Print("]");
518 return 6; 513 return 6;
519 } else if (index != esp && base != ebp) { 514 } else if (index != esp && base != ebp) {
520 // [base+index*scale] 515 // [base+index*scale]
521 Print("["); 516 Print("[");
522 PrintCPURegister(base); 517 PrintCPURegister(base);
523 Print("+"); 518 Print("+");
524 PrintCPURegister(index); 519 PrintCPURegister(index);
525 Print("*"); 520 Print("*");
526 PrintInt(1 << scale); 521 PrintInt(1 << scale);
527 Print("]"); 522 Print("]");
528 return 2; 523 return 2;
529 } else { 524 } else {
530 UNIMPLEMENTED(); 525 UNIMPLEMENTED();
531 return 1; 526 return 1;
532 } 527 }
533 } else { 528 } else {
534 Print("["); 529 Print("[");
535 PrintCPURegister(rm); 530 PrintCPURegister(rm);
536 Print("]"); 531 Print("]");
537 return 1; 532 return 1;
538 } 533 }
539 break; 534 break;
540 case 1: // fall through 535 case 1: // fall through
541 case 2: 536 case 2:
542 if (rm == esp) { 537 if (rm == esp) {
543 uint8_t sib = *(modrmp + 1); 538 uint8_t sib = *(modrmp + 1);
544 int scale, index, base; 539 int scale, index, base;
545 GetSib(sib, &scale, &index, &base); 540 GetSib(sib, &scale, &index, &base);
546 int disp = (mod == 2) ? 541 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2)
547 *reinterpret_cast<int32_t*>(modrmp + 2) : 542 : *reinterpret_cast<int8_t*>(modrmp + 2);
548 *reinterpret_cast<int8_t*>(modrmp + 2);
549 if (index == base && index == rm /*esp*/ && scale == 0 /*times_1*/) { 543 if (index == base && index == rm /*esp*/ && scale == 0 /*times_1*/) {
550 Print("["); 544 Print("[");
551 PrintCPURegister(rm); 545 PrintCPURegister(rm);
552 if (disp < 0) { 546 if (disp < 0) {
553 Print("-"); 547 Print("-");
554 disp = -disp; 548 disp = -disp;
555 } else { 549 } else {
556 Print("+"); 550 Print("+");
557 } 551 }
558 PrintHex(disp); 552 PrintHex(disp);
(...skipping 10 matching lines...) Expand all
569 disp = -disp; 563 disp = -disp;
570 } else { 564 } else {
571 Print("+"); 565 Print("+");
572 } 566 }
573 PrintHex(disp); 567 PrintHex(disp);
574 Print("]"); 568 Print("]");
575 } 569 }
576 return mod == 2 ? 6 : 3; 570 return mod == 2 ? 6 : 3;
577 } else { 571 } else {
578 // No sib. 572 // No sib.
579 int disp = (mod == 2) ? 573 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1)
580 *reinterpret_cast<int32_t*>(modrmp + 1) : 574 : *reinterpret_cast<int8_t*>(modrmp + 1);
581 *reinterpret_cast<int8_t*>(modrmp + 1);
582 Print("["); 575 Print("[");
583 PrintCPURegister(rm); 576 PrintCPURegister(rm);
584 if (disp < 0) { 577 if (disp < 0) {
585 Print("-"); 578 Print("-");
586 disp = -disp; 579 disp = -disp;
587 } else { 580 } else {
588 Print("+"); 581 Print("+");
589 } 582 }
590 PrintHex(disp); 583 PrintHex(disp);
591 Print("]"); 584 Print("]");
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 default: 638 default:
646 UNREACHABLE(); 639 UNREACHABLE();
647 break; 640 break;
648 } 641 }
649 return advance; 642 return advance;
650 } 643 }
651 644
652 645
653 int X86Decoder::PrintImmediateOp(uint8_t* data, bool size_override) { 646 int X86Decoder::PrintImmediateOp(uint8_t* data, bool size_override) {
654 bool sign_extension_bit = (*data & 0x02) != 0; 647 bool sign_extension_bit = (*data & 0x02) != 0;
655 uint8_t modrm = *(data+1); 648 uint8_t modrm = *(data + 1);
656 int mod, regop, rm; 649 int mod, regop, rm;
657 GetModRm(modrm, &mod, &regop, &rm); 650 GetModRm(modrm, &mod, &regop, &rm);
658 const char* mnem = "Imm???"; 651 const char* mnem = "Imm???";
659 switch (regop) { 652 switch (regop) {
660 case 0: mnem = "add"; break; 653 case 0:
661 case 1: mnem = "or"; break; 654 mnem = "add";
662 case 2: mnem = "adc"; break; 655 break;
663 case 3: mnem = "sbb"; break; 656 case 1:
664 case 4: mnem = "and"; break; 657 mnem = "or";
665 case 5: mnem = "sub"; break; 658 break;
666 case 6: mnem = "xor"; break; 659 case 2:
667 case 7: mnem = "cmp"; break; 660 mnem = "adc";
668 default: UNIMPLEMENTED(); 661 break;
662 case 3:
663 mnem = "sbb";
664 break;
665 case 4:
666 mnem = "and";
667 break;
668 case 5:
669 mnem = "sub";
670 break;
671 case 6:
672 mnem = "xor";
673 break;
674 case 7:
675 mnem = "cmp";
676 break;
677 default:
678 UNIMPLEMENTED();
669 } 679 }
670 Print(mnem); 680 Print(mnem);
671 Print(" "); 681 Print(" ");
672 int count = PrintRightOperand(data+1); 682 int count = PrintRightOperand(data + 1);
673 Print(","); 683 Print(",");
674 if (size_override) { 684 if (size_override) {
675 PrintHex(*reinterpret_cast<int16_t*>(data + 1 + count)); 685 PrintHex(*reinterpret_cast<int16_t*>(data + 1 + count));
676 return 1 + count + 2 /*int16_t*/; 686 return 1 + count + 2 /*int16_t*/;
677 } else if (sign_extension_bit) { 687 } else if (sign_extension_bit) {
678 PrintHex(*(data + 1 + count)); 688 PrintHex(*(data + 1 + count));
679 return 1 + count + 1 /*int8_t*/; 689 return 1 + count + 1 /*int8_t*/;
680 } else { 690 } else {
681 PrintHex(*reinterpret_cast<int32_t*>(data + 1 + count)); 691 PrintHex(*reinterpret_cast<int32_t*>(data + 1 + count));
682 return 1 + count + 4 /*int32_t*/; 692 return 1 + count + 4 /*int32_t*/;
683 } 693 }
684 } 694 }
685 695
686 696
687 int X86Decoder::DecodeEnter(uint8_t* data) { 697 int X86Decoder::DecodeEnter(uint8_t* data) {
688 uint16_t size = *reinterpret_cast<uint16_t*>(data + 1); 698 uint16_t size = *reinterpret_cast<uint16_t*>(data + 1);
689 uint8_t level = *reinterpret_cast<uint8_t*>(data + 3); 699 uint8_t level = *reinterpret_cast<uint8_t*>(data + 3);
690 Print("enter "); 700 Print("enter ");
691 PrintInt(size); 701 PrintInt(size);
692 Print(", "); 702 Print(", ");
693 PrintInt(level); 703 PrintInt(level);
694 return 4; 704 return 4;
695 } 705 }
696 706
697 707
698 // Returns number of bytes used, including *data. 708 // Returns number of bytes used, including *data.
699 int X86Decoder::JumpShort(uint8_t* data) { 709 int X86Decoder::JumpShort(uint8_t* data) {
700 ASSERT(*data == 0xEB); 710 ASSERT(*data == 0xEB);
701 uint8_t b = *(data+1); 711 uint8_t b = *(data + 1);
702 uword dest = reinterpret_cast<uword>(data) + static_cast<int8_t>(b) + 2; 712 uword dest = reinterpret_cast<uword>(data) + static_cast<int8_t>(b) + 2;
703 Print("jmp "); 713 Print("jmp ");
704 PrintAddress(dest); 714 PrintAddress(dest);
705 return 2; 715 return 2;
706 } 716 }
707 717
708 718
709 // Returns number of bytes used, including *data. 719 // Returns number of bytes used, including *data.
710 int X86Decoder::JumpConditional(uint8_t* data, const char* comment) { 720 int X86Decoder::JumpConditional(uint8_t* data, const char* comment) {
711 ASSERT(*data == 0x0F); 721 ASSERT(*data == 0x0F);
712 uint8_t cond = *(data+1) & 0x0F; 722 uint8_t cond = *(data + 1) & 0x0F;
713 uword dest = reinterpret_cast<uword>(data) + 723 uword dest =
714 *reinterpret_cast<int32_t*>(data+2) + 6; 724 reinterpret_cast<uword>(data) + *reinterpret_cast<int32_t*>(data + 2) + 6;
715 const char* mnem = jump_conditional_mnem[cond]; 725 const char* mnem = jump_conditional_mnem[cond];
716 Print(mnem); 726 Print(mnem);
717 Print(" "); 727 Print(" ");
718 PrintAddress(dest); 728 PrintAddress(dest);
719 if (comment != NULL) { 729 if (comment != NULL) {
720 Print(", "); 730 Print(", ");
721 Print(comment); 731 Print(comment);
722 } 732 }
723 return 6; // includes 0x0F 733 return 6; // includes 0x0F
724 } 734 }
725 735
726 736
727 // Returns number of bytes used, including *data. 737 // Returns number of bytes used, including *data.
728 int X86Decoder::JumpConditionalShort(uint8_t* data, const char* comment) { 738 int X86Decoder::JumpConditionalShort(uint8_t* data, const char* comment) {
729 uint8_t cond = *data & 0x0F; 739 uint8_t cond = *data & 0x0F;
730 uint8_t b = *(data+1); 740 uint8_t b = *(data + 1);
731 uword dest = reinterpret_cast<uword>(data) + static_cast<int8_t>(b) + 2; 741 uword dest = reinterpret_cast<uword>(data) + static_cast<int8_t>(b) + 2;
732 const char* mnem = jump_conditional_mnem[cond]; 742 const char* mnem = jump_conditional_mnem[cond];
733 Print(mnem); 743 Print(mnem);
734 Print(" "); 744 Print(" ");
735 PrintAddress(dest); 745 PrintAddress(dest);
736 if (comment != NULL) { 746 if (comment != NULL) {
737 Print(", "); 747 Print(", ");
738 Print(comment); 748 Print(comment);
739 } 749 }
740 return 2; 750 return 2;
741 } 751 }
742 752
743 753
744 // Returns number of bytes used, including *data. 754 // Returns number of bytes used, including *data.
745 int X86Decoder::SetCC(uint8_t* data) { 755 int X86Decoder::SetCC(uint8_t* data) {
746 ASSERT(*data == 0x0F); 756 ASSERT(*data == 0x0F);
747 uint8_t cond = *(data+1) & 0x0F; 757 uint8_t cond = *(data + 1) & 0x0F;
748 const char* mnem = set_conditional_mnem[cond]; 758 const char* mnem = set_conditional_mnem[cond];
749 Print(mnem); 759 Print(mnem);
750 Print(" "); 760 Print(" ");
751 PrintRightByteOperand(data+2); 761 PrintRightByteOperand(data + 2);
752 return 3; // includes 0x0F 762 return 3; // includes 0x0F
753 } 763 }
754 764
755 765
756 // Returns number of bytes used, including *data. 766 // Returns number of bytes used, including *data.
757 int X86Decoder::CMov(uint8_t* data) { 767 int X86Decoder::CMov(uint8_t* data) {
758 ASSERT(*data == 0x0F); 768 ASSERT(*data == 0x0F);
759 uint8_t cond = *(data + 1) & 0x0F; 769 uint8_t cond = *(data + 1) & 0x0F;
760 const char* mnem = conditional_move_mnem[cond]; 770 const char* mnem = conditional_move_mnem[cond];
761 int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2); 771 int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2);
762 return 2 + op_size; // includes 0x0F 772 return 2 + op_size; // includes 0x0F
763 } 773 }
764 774
765 775
766 int X86Decoder::D1D3C1Instruction(uint8_t* data) { 776 int X86Decoder::D1D3C1Instruction(uint8_t* data) {
767 uint8_t op = *data; 777 uint8_t op = *data;
768 ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1); 778 ASSERT(op == 0xD1 || op == 0xD3 || op == 0xC1);
769 int mod, regop, rm; 779 int mod, regop, rm;
770 GetModRm(*(data+1), &mod, &regop, &rm); 780 GetModRm(*(data + 1), &mod, &regop, &rm);
771 int num_bytes = 1; 781 int num_bytes = 1;
772 const char* mnem = NULL; 782 const char* mnem = NULL;
773 switch (regop) { 783 switch (regop) {
774 case 2: mnem = "rcl"; break; 784 case 2:
775 case 4: mnem = "shl"; break; 785 mnem = "rcl";
776 case 5: mnem = "shr"; break; 786 break;
777 case 7: mnem = "sar"; break; 787 case 4:
778 default: UNIMPLEMENTED(); 788 mnem = "shl";
789 break;
790 case 5:
791 mnem = "shr";
792 break;
793 case 7:
794 mnem = "sar";
795 break;
796 default:
797 UNIMPLEMENTED();
779 } 798 }
780 ASSERT(mnem != NULL); 799 ASSERT(mnem != NULL);
781 Print(mnem); 800 Print(mnem);
782 Print(" "); 801 Print(" ");
783 802
784 if (op == 0xD1) { 803 if (op == 0xD1) {
785 num_bytes += PrintRightOperand(data+1); 804 num_bytes += PrintRightOperand(data + 1);
786 Print(", 1"); 805 Print(", 1");
787 } else if (op == 0xC1) { 806 } else if (op == 0xC1) {
788 num_bytes += PrintRightOperand(data+1); 807 num_bytes += PrintRightOperand(data + 1);
789 Print(", "); 808 Print(", ");
790 PrintInt(*(data+2)); 809 PrintInt(*(data + 2));
791 num_bytes++; 810 num_bytes++;
792 } else { 811 } else {
793 ASSERT(op == 0xD3); 812 ASSERT(op == 0xD3);
794 num_bytes += PrintRightOperand(data+1); 813 num_bytes += PrintRightOperand(data + 1);
795 Print(", cl"); 814 Print(", cl");
796 } 815 }
797 return num_bytes; 816 return num_bytes;
798 } 817 }
799 818
800 819
801 uint8_t* X86Decoder::F3Instruction(uint8_t* data) { 820 uint8_t* X86Decoder::F3Instruction(uint8_t* data) {
802 if (*(data+1) == 0x0F) { 821 if (*(data + 1) == 0x0F) {
803 uint8_t b2 = *(data+2); 822 uint8_t b2 = *(data + 2);
804 switch (b2) { 823 switch (b2) {
805 case 0x2C: { 824 case 0x2C: {
806 data += 3; 825 data += 3;
807 data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data); 826 data += PrintOperands("cvttss2si", REG_OPER_OP_ORDER, data);
808 break; 827 break;
809 } 828 }
810 case 0x2A: { 829 case 0x2A: {
811 data += 3; 830 data += 3;
812 int mod, regop, rm; 831 int mod, regop, rm;
813 GetModRm(*data, &mod, &regop, &rm); 832 GetModRm(*data, &mod, &regop, &rm);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 case 0x59: // Fall through. 873 case 0x59: // Fall through.
855 case 0x5A: // Fall through. 874 case 0x5A: // Fall through.
856 case 0x5C: // Fall through. 875 case 0x5C: // Fall through.
857 case 0x5E: // Fall through. 876 case 0x5E: // Fall through.
858 case 0xE6: { 877 case 0xE6: {
859 data += 3; 878 data += 3;
860 int mod, regop, rm; 879 int mod, regop, rm;
861 GetModRm(*data, &mod, &regop, &rm); 880 GetModRm(*data, &mod, &regop, &rm);
862 const char* mnem = "?? 0xF3"; 881 const char* mnem = "?? 0xF3";
863 switch (b2) { 882 switch (b2) {
864 case 0x51: mnem = "sqrtss"; break; 883 case 0x51:
865 case 0x58: mnem = "addss"; break; 884 mnem = "sqrtss";
866 case 0x59: mnem = "mulss"; break; 885 break;
867 case 0x5A: mnem = "cvtss2sd"; break; 886 case 0x58:
868 case 0x5C: mnem = "subss"; break; 887 mnem = "addss";
869 case 0x5E: mnem = "divss"; break; 888 break;
870 case 0xE6: mnem = "cvtdq2pd"; break; 889 case 0x59:
871 default: UNIMPLEMENTED(); 890 mnem = "mulss";
891 break;
892 case 0x5A:
893 mnem = "cvtss2sd";
894 break;
895 case 0x5C:
896 mnem = "subss";
897 break;
898 case 0x5E:
899 mnem = "divss";
900 break;
901 case 0xE6:
902 mnem = "cvtdq2pd";
903 break;
904 default:
905 UNIMPLEMENTED();
872 } 906 }
873 Print(mnem); 907 Print(mnem);
874 Print(" "); 908 Print(" ");
875 PrintXmmRegister(regop); 909 PrintXmmRegister(regop);
876 Print(","); 910 Print(",");
877 data += PrintRightXmmOperand(data); 911 data += PrintRightXmmOperand(data);
878 break; 912 break;
879 } 913 }
880 case 0x7E: { 914 case 0x7E: {
881 data += 3; 915 data += 3;
882 int mod, regop, rm; 916 int mod, regop, rm;
883 GetModRm(*data, &mod, &regop, &rm); 917 GetModRm(*data, &mod, &regop, &rm);
884 Print("movq "); 918 Print("movq ");
885 PrintXmmRegister(regop); 919 PrintXmmRegister(regop);
886 Print(","); 920 Print(",");
887 data += PrintRightOperand(data); 921 data += PrintRightOperand(data);
888 break; 922 break;
889 } 923 }
890 default: 924 default:
891 UNIMPLEMENTED(); 925 UNIMPLEMENTED();
892 } 926 }
893 } else if (*(data+1) == 0xA4) { 927 } else if (*(data + 1) == 0xA4) {
894 Print("rep_movsb"); 928 Print("rep_movsb");
895 data += 2; 929 data += 2;
896 } else { 930 } else {
897 UNIMPLEMENTED(); 931 UNIMPLEMENTED();
898 } 932 }
899 return data; 933 return data;
900 } 934 }
901 935
902 936
903 // Returns number of bytes used, including *data. 937 // Returns number of bytes used, including *data.
904 int X86Decoder::F7Instruction(uint8_t* data) { 938 int X86Decoder::F7Instruction(uint8_t* data) {
905 ASSERT(*data == 0xF7); 939 ASSERT(*data == 0xF7);
906 uint8_t modrm = *(data+1); 940 uint8_t modrm = *(data + 1);
907 int mod, regop, rm; 941 int mod, regop, rm;
908 GetModRm(modrm, &mod, &regop, &rm); 942 GetModRm(modrm, &mod, &regop, &rm);
909 if (mod == 3 && regop != 0) { 943 if (mod == 3 && regop != 0) {
910 const char* mnem = NULL; 944 const char* mnem = NULL;
911 switch (regop) { 945 switch (regop) {
912 case 2: mnem = "not"; break; 946 case 2:
913 case 3: mnem = "neg"; break; 947 mnem = "not";
914 case 4: mnem = "mul"; break; 948 break;
915 case 5: mnem = "imul"; break; 949 case 3:
916 case 6: mnem = "div"; break; 950 mnem = "neg";
917 case 7: mnem = "idiv"; break; 951 break;
918 default: UNIMPLEMENTED(); 952 case 4:
953 mnem = "mul";
954 break;
955 case 5:
956 mnem = "imul";
957 break;
958 case 6:
959 mnem = "div";
960 break;
961 case 7:
962 mnem = "idiv";
963 break;
964 default:
965 UNIMPLEMENTED();
919 } 966 }
920 Print(mnem); 967 Print(mnem);
921 Print(" "); 968 Print(" ");
922 PrintCPURegister(rm); 969 PrintCPURegister(rm);
923 return 2; 970 return 2;
924 } else if (mod == 3 && regop == eax) { 971 } else if (mod == 3 && regop == eax) {
925 int32_t imm = *reinterpret_cast<int32_t*>(data+2); 972 int32_t imm = *reinterpret_cast<int32_t*>(data + 2);
926 Print("test "); 973 Print("test ");
927 PrintCPURegister(rm); 974 PrintCPURegister(rm);
928 Print(","); 975 Print(",");
929 PrintHex(imm); 976 PrintHex(imm);
930 return 6; 977 return 6;
931 } else if (regop == eax) { 978 } else if (regop == eax) {
932 Print("test "); 979 Print("test ");
933 int count = PrintRightOperand(data+1); 980 int count = PrintRightOperand(data + 1);
934 int32_t imm = *reinterpret_cast<int32_t*>(data+1+count); 981 int32_t imm = *reinterpret_cast<int32_t*>(data + 1 + count);
935 Print(","); 982 Print(",");
936 PrintHex(imm); 983 PrintHex(imm);
937 return 1+count+4 /*int32_t*/; 984 return 1 + count + 4 /*int32_t*/;
938 } else if (regop == 5) { 985 } else if (regop == 5) {
939 Print("imul "); 986 Print("imul ");
940 int count = PrintRightOperand(data + 1); 987 int count = PrintRightOperand(data + 1);
941 return 1 + count; 988 return 1 + count;
942 } else if (regop == 4) { 989 } else if (regop == 4) {
943 Print("mul "); 990 Print("mul ");
944 int count = PrintRightOperand(data + 1); 991 int count = PrintRightOperand(data + 1);
945 return 1 + count; 992 return 1 + count;
946 } else { 993 } else {
947 OS::Print("F7 Instr regop %d\n", regop); 994 OS::Print("F7 Instr regop %d\n", regop);
948 UNIMPLEMENTED(); 995 UNIMPLEMENTED();
949 return 2; 996 return 2;
950 } 997 }
951 } 998 }
952 999
953 // Returns number of bytes used, including *data. 1000 // Returns number of bytes used, including *data.
954 int X86Decoder::FPUInstruction(uint8_t* data) { 1001 int X86Decoder::FPUInstruction(uint8_t* data) {
955 uint8_t b1 = *data; 1002 uint8_t b1 = *data;
956 uint8_t b2 = *(data + 1); 1003 uint8_t b2 = *(data + 1);
957 if (b1 == 0xD9) { 1004 if (b1 == 0xD9) {
958 const char* mnem = NULL; 1005 const char* mnem = NULL;
959 switch (b2) { 1006 switch (b2) {
960 case 0xE0: mnem = "fchs"; break; 1007 case 0xE0:
961 case 0xE1: mnem = "fabs"; break; 1008 mnem = "fchs";
962 case 0xE4: mnem = "ftst"; break; 1009 break;
963 case 0xE8: mnem = "fld1"; break; 1010 case 0xE1:
964 case 0xEE: mnem = "fldz"; break; 1011 mnem = "fabs";
965 case 0xF2: mnem = "fptan"; break; 1012 break;
966 case 0xF5: mnem = "fprem1"; break; 1013 case 0xE4:
967 case 0xF8: mnem = "fprem"; break; 1014 mnem = "ftst";
968 case 0xF7: mnem = "fincstp"; break; 1015 break;
969 case 0xFB: mnem = "fsincos"; break; 1016 case 0xE8:
970 case 0xFE: mnem = "fsin"; break; 1017 mnem = "fld1";
971 case 0xFF: mnem = "fcos"; break; 1018 break;
1019 case 0xEE:
1020 mnem = "fldz";
1021 break;
1022 case 0xF2:
1023 mnem = "fptan";
1024 break;
1025 case 0xF5:
1026 mnem = "fprem1";
1027 break;
1028 case 0xF8:
1029 mnem = "fprem";
1030 break;
1031 case 0xF7:
1032 mnem = "fincstp";
1033 break;
1034 case 0xFB:
1035 mnem = "fsincos";
1036 break;
1037 case 0xFE:
1038 mnem = "fsin";
1039 break;
1040 case 0xFF:
1041 mnem = "fcos";
1042 break;
972 } 1043 }
973 if (mnem != NULL) { 1044 if (mnem != NULL) {
974 Print(mnem); 1045 Print(mnem);
975 return 2; 1046 return 2;
976 } else if ((b2 & 0xF8) == 0xC8) { 1047 } else if ((b2 & 0xF8) == 0xC8) {
977 Print("fxch st"); 1048 Print("fxch st");
978 PrintInt(b2 & 0x7); 1049 PrintInt(b2 & 0x7);
979 return 2; 1050 return 2;
980 } else { 1051 } else {
981 int mod, regop, rm; 1052 int mod, regop, rm;
982 GetModRm(*(data+1), &mod, &regop, &rm); 1053 GetModRm(*(data + 1), &mod, &regop, &rm);
983 const char* mnem = "? FPU 0xD9"; 1054 const char* mnem = "? FPU 0xD9";
984 switch (regop) { 1055 switch (regop) {
985 case 0: mnem = "fld_s"; break; 1056 case 0:
986 case 3: mnem = "fstp_s"; break; 1057 mnem = "fld_s";
987 case 5: mnem = "fldcw"; break; 1058 break;
988 case 7: mnem = "fnstcw"; break; 1059 case 3:
989 default: UNIMPLEMENTED(); 1060 mnem = "fstp_s";
1061 break;
1062 case 5:
1063 mnem = "fldcw";
1064 break;
1065 case 7:
1066 mnem = "fnstcw";
1067 break;
1068 default:
1069 UNIMPLEMENTED();
990 } 1070 }
991 Print(mnem); 1071 Print(mnem);
992 Print(" "); 1072 Print(" ");
993 int count = PrintRightOperand(data + 1); 1073 int count = PrintRightOperand(data + 1);
994 return count + 1; 1074 return count + 1;
995 } 1075 }
996 } else if (b1 == 0xDD) { 1076 } else if (b1 == 0xDD) {
997 if ((b2 & 0xF8) == 0xC0) { 1077 if ((b2 & 0xF8) == 0xC0) {
998 Print("ffree st"); 1078 Print("ffree st");
999 PrintInt(b2 & 0x7); 1079 PrintInt(b2 & 0x7);
1000 return 2; 1080 return 2;
1001 } else { 1081 } else {
1002 int mod, regop, rm; 1082 int mod, regop, rm;
1003 GetModRm(*(data+1), &mod, &regop, &rm); 1083 GetModRm(*(data + 1), &mod, &regop, &rm);
1004 const char* mnem = "? FPU 0xDD"; 1084 const char* mnem = "? FPU 0xDD";
1005 switch (regop) { 1085 switch (regop) {
1006 case 0: mnem = "fld_d"; break; 1086 case 0:
1007 case 3: mnem = "fstp_d"; break; 1087 mnem = "fld_d";
1008 default: UNIMPLEMENTED(); 1088 break;
1089 case 3:
1090 mnem = "fstp_d";
1091 break;
1092 default:
1093 UNIMPLEMENTED();
1009 } 1094 }
1010 Print(mnem); 1095 Print(mnem);
1011 Print(" "); 1096 Print(" ");
1012 int count = PrintRightOperand(data + 1); 1097 int count = PrintRightOperand(data + 1);
1013 return count + 1; 1098 return count + 1;
1014 } 1099 }
1015 } else if (b1 == 0xDB) { 1100 } else if (b1 == 0xDB) {
1016 int mod, regop, rm; 1101 int mod, regop, rm;
1017 GetModRm(*(data+1), &mod, &regop, &rm); 1102 GetModRm(*(data + 1), &mod, &regop, &rm);
1018 const char* mnem = "? FPU 0xDB"; 1103 const char* mnem = "? FPU 0xDB";
1019 switch (regop) { 1104 switch (regop) {
1020 case 0: mnem = "fild_s"; break; 1105 case 0:
1021 case 2: mnem = "fist_s"; break; 1106 mnem = "fild_s";
1022 case 3: mnem = "fistp_s"; break; 1107 break;
1023 default: UNIMPLEMENTED(); 1108 case 2:
1109 mnem = "fist_s";
1110 break;
1111 case 3:
1112 mnem = "fistp_s";
1113 break;
1114 default:
1115 UNIMPLEMENTED();
1024 } 1116 }
1025 Print(mnem); 1117 Print(mnem);
1026 Print(" "); 1118 Print(" ");
1027 int count = PrintRightOperand(data + 1); 1119 int count = PrintRightOperand(data + 1);
1028 return count + 1; 1120 return count + 1;
1029 } else if (b1 == 0xDF) { 1121 } else if (b1 == 0xDF) {
1030 if (b2 == 0xE0) { 1122 if (b2 == 0xE0) {
1031 Print("fnstsw_ax"); 1123 Print("fnstsw_ax");
1032 return 2; 1124 return 2;
1033 } 1125 }
1034 int mod, regop, rm; 1126 int mod, regop, rm;
1035 GetModRm(*(data+1), &mod, &regop, &rm); 1127 GetModRm(*(data + 1), &mod, &regop, &rm);
1036 const char* mnem = "? FPU 0xDF"; 1128 const char* mnem = "? FPU 0xDF";
1037 switch (regop) { 1129 switch (regop) {
1038 case 5: mnem = "fild_d"; break; 1130 case 5:
1039 case 7: mnem = "fistp_d"; break; 1131 mnem = "fild_d";
1040 default: UNIMPLEMENTED(); 1132 break;
1133 case 7:
1134 mnem = "fistp_d";
1135 break;
1136 default:
1137 UNIMPLEMENTED();
1041 } 1138 }
1042 Print(mnem); 1139 Print(mnem);
1043 Print(" "); 1140 Print(" ");
1044 int count = PrintRightOperand(data + 1); 1141 int count = PrintRightOperand(data + 1);
1045 return count + 1; 1142 return count + 1;
1046 } else if (b1 == 0xDC || b1 == 0xDE) { 1143 } else if (b1 == 0xDC || b1 == 0xDE) {
1047 bool is_pop = (b1 == 0xDE); 1144 bool is_pop = (b1 == 0xDE);
1048 if (is_pop && b2 == 0xD9) { 1145 if (is_pop && b2 == 0xD9) {
1049 Print("fcompp"); 1146 Print("fcompp");
1050 return 2; 1147 return 2;
1051 } 1148 }
1052 const char* mnem = "FP0xDC"; 1149 const char* mnem = "FP0xDC";
1053 switch (b2 & 0xF8) { 1150 switch (b2 & 0xF8) {
1054 case 0xC0: mnem = "fadd"; break; 1151 case 0xC0:
1055 case 0xE8: mnem = "fsub"; break; 1152 mnem = "fadd";
1056 case 0xC8: mnem = "fmul"; break; 1153 break;
1057 case 0xF8: mnem = "fdiv"; break; 1154 case 0xE8:
1058 default: UNIMPLEMENTED(); 1155 mnem = "fsub";
1156 break;
1157 case 0xC8:
1158 mnem = "fmul";
1159 break;
1160 case 0xF8:
1161 mnem = "fdiv";
1162 break;
1163 default:
1164 UNIMPLEMENTED();
1059 } 1165 }
1060 Print(mnem); 1166 Print(mnem);
1061 Print(is_pop ? "p" : ""); 1167 Print(is_pop ? "p" : "");
1062 Print(" st"); 1168 Print(" st");
1063 PrintInt(b2 & 0x7); 1169 PrintInt(b2 & 0x7);
1064 return 2; 1170 return 2;
1065 } else if (b1 == 0xDA && b2 == 0xE9) { 1171 } else if (b1 == 0xDA && b2 == 0xE9) {
1066 const char* mnem = "fucompp"; 1172 const char* mnem = "fucompp";
1067 Print(mnem); 1173 Print(mnem);
1068 return 2; 1174 return 2;
1069 } 1175 }
1070 Print("Unknown FP instruction"); 1176 Print("Unknown FP instruction");
1071 return 2; 1177 return 2;
1072 } 1178 }
1073 1179
1074 1180
1075 uint8_t* X86Decoder::SSEInstruction(uint8_t prefix, uint8_t primary, 1181 uint8_t* X86Decoder::SSEInstruction(uint8_t prefix,
1182 uint8_t primary,
1076 uint8_t* data) { 1183 uint8_t* data) {
1077 ASSERT(prefix == 0x0F); 1184 ASSERT(prefix == 0x0F);
1078 int mod, regop, rm; 1185 int mod, regop, rm;
1079 if (primary == 0x10) { 1186 if (primary == 0x10) {
1080 GetModRm(*data, &mod, &regop, &rm); 1187 GetModRm(*data, &mod, &regop, &rm);
1081 Print("movups "); 1188 Print("movups ");
1082 PrintXmmRegister(regop); 1189 PrintXmmRegister(regop);
1083 Print(","); 1190 Print(",");
1084 data += PrintRightOperand(data); 1191 data += PrintRightOperand(data);
1085 } else if (primary == 0x11) { 1192 } else if (primary == 0x11) {
(...skipping 11 matching lines...) Expand all
1097 Print(" "); 1204 Print(" ");
1098 PrintXmmRegister(regop); 1205 PrintXmmRegister(regop);
1099 Print(","); 1206 Print(",");
1100 data += PrintRightXmmOperand(data); 1207 data += PrintRightXmmOperand(data);
1101 } 1208 }
1102 return data; 1209 return data;
1103 } 1210 }
1104 1211
1105 1212
1106 int X86Decoder::BitwisePDInstruction(uint8_t* data) { 1213 int X86Decoder::BitwisePDInstruction(uint8_t* data) {
1107 const char* mnem = (*data == 0x57) 1214 const char* mnem =
1108 ? "xorpd" 1215 (*data == 0x57) ? "xorpd" : (*data == 0x56) ? "orpd" : "andpd";
1109 : (*data == 0x56)
1110 ? "orpd"
1111 : "andpd";
1112 int mod, regop, rm; 1216 int mod, regop, rm;
1113 GetModRm(*(data+1), &mod, &regop, &rm); 1217 GetModRm(*(data + 1), &mod, &regop, &rm);
1114 Print(mnem); 1218 Print(mnem);
1115 Print(" "); 1219 Print(" ");
1116 PrintXmmRegister(regop); 1220 PrintXmmRegister(regop);
1117 Print(","); 1221 Print(",");
1118 return 1 + PrintRightXmmOperand(data+1); 1222 return 1 + PrintRightXmmOperand(data + 1);
1119 } 1223 }
1120 1224
1121 1225
1122 int X86Decoder::Packed660F38Instruction(uint8_t* data) { 1226 int X86Decoder::Packed660F38Instruction(uint8_t* data) {
1123 if (*(data+1) == 0x25) { 1227 if (*(data + 1) == 0x25) {
1124 Print("pmovsxdq "); 1228 Print("pmovsxdq ");
1125 int mod, regop, rm; 1229 int mod, regop, rm;
1126 GetModRm(*(data+2), &mod, &regop, &rm); 1230 GetModRm(*(data + 2), &mod, &regop, &rm);
1127 PrintXmmRegister(regop); 1231 PrintXmmRegister(regop);
1128 Print(","); 1232 Print(",");
1129 return 2 + PrintRightXmmOperand(data+2); 1233 return 2 + PrintRightXmmOperand(data + 2);
1130 } else if (*(data+1) == 0x29) { 1234 } else if (*(data + 1) == 0x29) {
1131 Print("pcmpeqq "); 1235 Print("pcmpeqq ");
1132 int mod, regop, rm; 1236 int mod, regop, rm;
1133 GetModRm(*(data+2), &mod, &regop, &rm); 1237 GetModRm(*(data + 2), &mod, &regop, &rm);
1134 PrintXmmRegister(regop); 1238 PrintXmmRegister(regop);
1135 Print(","); 1239 Print(",");
1136 return 2 + PrintRightXmmOperand(data+2); 1240 return 2 + PrintRightXmmOperand(data + 2);
1137 } 1241 }
1138 UNREACHABLE(); 1242 UNREACHABLE();
1139 return 1; 1243 return 1;
1140 } 1244 }
1141 1245
1142 1246
1143 // Called when disassembling test eax, 0xXXXXX. 1247 // Called when disassembling test eax, 0xXXXXX.
1144 void X86Decoder::CheckPrintStop(uint8_t* data) { 1248 void X86Decoder::CheckPrintStop(uint8_t* data) {
1145 // Recognize stop pattern. 1249 // Recognize stop pattern.
1146 if (*reinterpret_cast<uint8_t*>(data + 5) == 0xCC) { 1250 if (*reinterpret_cast<uint8_t*>(data + 5) == 0xCC) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 return true; 1293 return true;
1190 1294
1191 case REGISTER_INSTR: 1295 case REGISTER_INSTR:
1192 Print(idesc.mnem); 1296 Print(idesc.mnem);
1193 Print(" "); 1297 Print(" ");
1194 PrintCPURegister(**data & 0x07); 1298 PrintCPURegister(**data & 0x07);
1195 (*data)++; 1299 (*data)++;
1196 return true; 1300 return true;
1197 1301
1198 case MOVE_REG_INSTR: { 1302 case MOVE_REG_INSTR: {
1199 uword addr = *reinterpret_cast<uword*>(*data+1); 1303 uword addr = *reinterpret_cast<uword*>(*data + 1);
1200 Print("mov "); 1304 Print("mov ");
1201 PrintCPURegister(**data & 0x07), 1305 PrintCPURegister(**data & 0x07), Print(",");
1202 Print(",");
1203 PrintAddress(addr); 1306 PrintAddress(addr);
1204 (*data) += 5; 1307 (*data) += 5;
1205 return true; 1308 return true;
1206 } 1309 }
1207 1310
1208 case CALL_JUMP_INSTR: { 1311 case CALL_JUMP_INSTR: {
1209 uword addr = reinterpret_cast<uword>(*data) + 1312 uword addr = reinterpret_cast<uword>(*data) +
1210 *reinterpret_cast<uword*>(*data+1) + 5; 1313 *reinterpret_cast<uword*>(*data + 1) + 5;
1211 Print(idesc.mnem); 1314 Print(idesc.mnem);
1212 Print(" "); 1315 Print(" ");
1213 PrintAddress(addr); 1316 PrintAddress(addr);
1214 (*data) += 5; 1317 (*data) += 5;
1215 return true; 1318 return true;
1216 } 1319 }
1217 1320
1218 case SHORT_IMMEDIATE_INSTR: { 1321 case SHORT_IMMEDIATE_INSTR: {
1219 uword addr = *reinterpret_cast<uword*>(*data+1); 1322 uword addr = *reinterpret_cast<uword*>(*data + 1);
1220 Print(idesc.mnem); 1323 Print(idesc.mnem);
1221 Print(" eax, "); 1324 Print(" eax, ");
1222 PrintAddress(addr); 1325 PrintAddress(addr);
1223 (*data) += 5; 1326 (*data) += 5;
1224 return true; 1327 return true;
1225 } 1328 }
1226 1329
1227 case NO_INSTR: 1330 case NO_INSTR:
1228 return false; 1331 return false;
1229 1332
(...skipping 10 matching lines...) Expand all
1240 const char* branch_hint = GetBranchPrefix(&data); 1343 const char* branch_hint = GetBranchPrefix(&data);
1241 const InstructionDesc& idesc = instruction_table.Get(*data); 1344 const InstructionDesc& idesc = instruction_table.Get(*data);
1242 // Will be set to false if the current instruction 1345 // Will be set to false if the current instruction
1243 // is not in 'instructions' table. 1346 // is not in 'instructions' table.
1244 bool processed = DecodeInstructionType(idesc, branch_hint, &data); 1347 bool processed = DecodeInstructionType(idesc, branch_hint, &data);
1245 //---------------------------- 1348 //----------------------------
1246 if (!processed) { 1349 if (!processed) {
1247 switch (*data) { 1350 switch (*data) {
1248 case 0xC2: 1351 case 0xC2:
1249 Print("ret "); 1352 Print("ret ");
1250 PrintHex(*reinterpret_cast<uint16_t*>(data+1)); 1353 PrintHex(*reinterpret_cast<uint16_t*>(data + 1));
1251 data += 3; 1354 data += 3;
1252 break; 1355 break;
1253 1356
1254 case 0x69: // fall through 1357 case 0x69: // fall through
1255 case 0x6B: 1358 case 0x6B: {
1256 { int mod, regop, rm; 1359 int mod, regop, rm;
1257 GetModRm(*(data+1), &mod, &regop, &rm); 1360 GetModRm(*(data + 1), &mod, &regop, &rm);
1258 int32_t imm = 1361 int32_t imm =
1259 *data == 0x6B ? *(data+2) : *reinterpret_cast<int32_t*>(data+2); 1362 *data == 0x6B ? *(data + 2) : *reinterpret_cast<int32_t*>(data + 2);
1260 Print("imul "); 1363 Print("imul ");
1261 PrintCPURegister(regop); 1364 PrintCPURegister(regop);
1262 Print(","); 1365 Print(",");
1263 PrintCPURegister(rm); 1366 PrintCPURegister(rm);
1264 Print(","); 1367 Print(",");
1265 PrintHex(imm); 1368 PrintHex(imm);
1266 data += 2 + (*data == 0x6B ? 1 : 4); 1369 data += 2 + (*data == 0x6B ? 1 : 4);
1267 } 1370 } break;
1268 break;
1269 1371
1270 case 0xF6: 1372 case 0xF6: {
1271 { int mod, regop, rm; 1373 int mod, regop, rm;
1272 GetModRm(*(data+1), &mod, &regop, &rm); 1374 GetModRm(*(data + 1), &mod, &regop, &rm);
1273 if ((mod == 3) && (regop == eax)) { 1375 if ((mod == 3) && (regop == eax)) {
1274 Print("test_b "); 1376 Print("test_b ");
1275 PrintCPURegister(rm); 1377 PrintCPURegister(rm);
1276 Print(","); 1378 Print(",");
1277 PrintHex(*(data+2)); 1379 PrintHex(*(data + 2));
1278 data += 3; 1380 data += 3;
1279 } else { 1381 } else {
1280 data++; 1382 data++;
1281 Print("test_b "); 1383 Print("test_b ");
1282 data += PrintRightOperand(data); 1384 data += PrintRightOperand(data);
1283 int32_t imm = *data; 1385 int32_t imm = *data;
1284 Print(","); 1386 Print(",");
1285 PrintHex(imm); 1387 PrintHex(imm);
1286 data++; 1388 data++;
1287 } 1389 }
1288 } 1390 } break;
1289 break;
1290 1391
1291 case 0x81: // fall through 1392 case 0x81: // fall through
1292 case 0x83: // 0x81 with sign extension bit set 1393 case 0x83: // 0x81 with sign extension bit set
1293 data += PrintImmediateOp(data); 1394 data += PrintImmediateOp(data);
1294 break; 1395 break;
1295 1396
1296 case 0x0F: 1397 case 0x0F: {
1297 { uint8_t f0byte = *(data+1); 1398 uint8_t f0byte = *(data + 1);
1298 const char* f0mnem = F0Mnem(f0byte); 1399 const char* f0mnem = F0Mnem(f0byte);
1299 if (f0byte == 0xA2 || f0byte == 0x31) { 1400 if (f0byte == 0xA2 || f0byte == 0x31) {
1300 Print(f0mnem); 1401 Print(f0mnem);
1301 data += 2; 1402 data += 2;
1302 } else if ((f0byte & 0xF0) == 0x80) { 1403 } else if ((f0byte & 0xF0) == 0x80) {
1303 data += JumpConditional(data, branch_hint); 1404 data += JumpConditional(data, branch_hint);
1304 } else if (f0byte == 0xBE || f0byte == 0xBF || f0byte == 0xB6 || 1405 } else if (f0byte == 0xBE || f0byte == 0xBF || f0byte == 0xB6 ||
1305 f0byte == 0xB7 || f0byte == 0xAF || f0byte == 0xBD) { 1406 f0byte == 0xB7 || f0byte == 0xAF || f0byte == 0xBD) {
1306 data += 2; 1407 data += 2;
1307 data += PrintOperands(f0mnem, REG_OPER_OP_ORDER, data); 1408 data += PrintOperands(f0mnem, REG_OPER_OP_ORDER, data);
(...skipping 16 matching lines...) Expand all
1324 } else if (f0byte == 0x2F) { 1425 } else if (f0byte == 0x2F) {
1325 data += 2; 1426 data += 2;
1326 int mod, regop, rm; 1427 int mod, regop, rm;
1327 GetModRm(*data, &mod, &regop, &rm); 1428 GetModRm(*data, &mod, &regop, &rm);
1328 Print("comiss "); 1429 Print("comiss ");
1329 PrintXmmRegister(regop); 1430 PrintXmmRegister(regop);
1330 Print(","); 1431 Print(",");
1331 PrintXmmRegister(rm); 1432 PrintXmmRegister(rm);
1332 data++; 1433 data++;
1333 } else if (f0byte == 0x1F) { 1434 } else if (f0byte == 0x1F) {
1334 if (*(data+2) == 0x00) { 1435 if (*(data + 2) == 0x00) {
1335 Print("nop"); 1436 Print("nop");
1336 data += 3; 1437 data += 3;
1337 } else if (*(data+2) == 0x40 && *(data+3) == 0x00) { 1438 } else if (*(data + 2) == 0x40 && *(data + 3) == 0x00) {
1338 Print("nop"); 1439 Print("nop");
1339 data += 4; 1440 data += 4;
1340 } else if (*(data+2) == 0x44 && 1441 } else if (*(data + 2) == 0x44 && *(data + 3) == 0x00 &&
1341 *(data+3) == 0x00 && 1442 *(data + 4) == 0x00) {
1342 *(data+4) == 0x00) {
1343 Print("nop"); 1443 Print("nop");
1344 data += 5; 1444 data += 5;
1345 } else if (*(data+2) == 0x80 && 1445 } else if (*(data + 2) == 0x80 && *(data + 3) == 0x00 &&
1346 *(data+3) == 0x00 && 1446 *(data + 4) == 0x00 && *(data + 5) == 0x00 &&
1347 *(data+4) == 0x00 && 1447 *(data + 6) == 0x00) {
1348 *(data+5) == 0x00 &&
1349 *(data+6) == 0x00) {
1350 Print("nop"); 1448 Print("nop");
1351 data += 7; 1449 data += 7;
1352 } else if (*(data+2) == 0x84 && 1450 } else if (*(data + 2) == 0x84 && *(data + 3) == 0x00 &&
1353 *(data+3) == 0x00 && 1451 *(data + 4) == 0x00 && *(data + 5) == 0x00 &&
1354 *(data+4) == 0x00 && 1452 *(data + 6) == 0x00 && *(data + 7) == 0x00) {
1355 *(data+5) == 0x00 &&
1356 *(data+6) == 0x00 &&
1357 *(data+7) == 0x00) {
1358 Print("nop"); 1453 Print("nop");
1359 data += 8; 1454 data += 8;
1360 } else { 1455 } else {
1361 UNIMPLEMENTED(); 1456 UNIMPLEMENTED();
1362 } 1457 }
1363 } else { 1458 } else {
1364 data += 2; 1459 data += 2;
1365 if (f0byte == 0xAB || f0byte == 0xA4 || f0byte == 0xA5 || 1460 if (f0byte == 0xAB || f0byte == 0xA4 || f0byte == 0xA5 ||
1366 f0byte == 0xAC || f0byte == 0xAD || f0byte == 0xA3) { 1461 f0byte == 0xAC || f0byte == 0xAD || f0byte == 0xA3) {
1367 // shrd, shld, bts, bt 1462 // shrd, shld, bts, bt
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 data += PrintRightXmmOperand(data); 1498 data += PrintRightXmmOperand(data);
1404 int comparison = *data; 1499 int comparison = *data;
1405 Print(" ["); 1500 Print(" [");
1406 PrintHex(comparison); 1501 PrintHex(comparison);
1407 Print("]"); 1502 Print("]");
1408 data++; 1503 data++;
1409 } else { 1504 } else {
1410 UNIMPLEMENTED(); 1505 UNIMPLEMENTED();
1411 } 1506 }
1412 } 1507 }
1413 } 1508 } break;
1414 break;
1415 1509
1416 case 0x8F: 1510 case 0x8F: {
1417 { data++; 1511 data++;
1418 int mod, regop, rm; 1512 int mod, regop, rm;
1419 GetModRm(*data, &mod, &regop, &rm); 1513 GetModRm(*data, &mod, &regop, &rm);
1420 if (regop == eax) { 1514 if (regop == eax) {
1421 Print("pop "); 1515 Print("pop ");
1422 data += PrintRightOperand(data); 1516 data += PrintRightOperand(data);
1423 } 1517 }
1424 } 1518 } break;
1425 break;
1426 1519
1427 case 0xFF: 1520 case 0xFF: {
1428 { data++; 1521 data++;
1429 int mod, regop, rm; 1522 int mod, regop, rm;
1430 GetModRm(*data, &mod, &regop, &rm); 1523 GetModRm(*data, &mod, &regop, &rm);
1431 const char* mnem = NULL; 1524 const char* mnem = NULL;
1432 switch (regop) { 1525 switch (regop) {
1433 case esi: mnem = "push"; break; 1526 case esi:
1434 case eax: mnem = "inc"; break; 1527 mnem = "push";
1435 case ecx: mnem = "dec"; break; 1528 break;
1436 case edx: mnem = "call"; break; 1529 case eax:
1437 case esp: mnem = "jmp"; break; 1530 mnem = "inc";
1438 default: mnem = "??? 0xFF"; 1531 break;
1532 case ecx:
1533 mnem = "dec";
1534 break;
1535 case edx:
1536 mnem = "call";
1537 break;
1538 case esp:
1539 mnem = "jmp";
1540 break;
1541 default:
1542 mnem = "??? 0xFF";
1439 } 1543 }
1440 Print(mnem); 1544 Print(mnem);
1441 Print(" "); 1545 Print(" ");
1442 data += PrintRightOperand(data); 1546 data += PrintRightOperand(data);
1443 } 1547 } break;
1444 break;
1445 1548
1446 case 0xC7: // imm32, fall through 1549 case 0xC7: // imm32, fall through
1447 case 0xC6: // imm8 1550 case 0xC6: // imm8
1448 { bool is_byte = *data == 0xC6; 1551 {
1552 bool is_byte = *data == 0xC6;
1449 data++; 1553 data++;
1450 Print(is_byte ? "mov_b" : "mov"); 1554 Print(is_byte ? "mov_b" : "mov");
1451 Print(" "); 1555 Print(" ");
1452 data += PrintRightOperand(data); 1556 data += PrintRightOperand(data);
1453 int32_t imm = is_byte ? *data : *reinterpret_cast<int32_t*>(data); 1557 int32_t imm = is_byte ? *data : *reinterpret_cast<int32_t*>(data);
1454 Print(","); 1558 Print(",");
1455 PrintHex(imm); 1559 PrintHex(imm);
1456 data += is_byte ? 1 : 4; 1560 data += is_byte ? 1 : 4;
1457 } 1561 } break;
1458 break;
1459 1562
1460 case 0x80: 1563 case 0x80: {
1461 { data++; 1564 data++;
1462 Print("cmpb "); 1565 Print("cmpb ");
1463 data += PrintRightOperand(data); 1566 data += PrintRightOperand(data);
1464 int32_t imm = *data; 1567 int32_t imm = *data;
1465 Print(","); 1568 Print(",");
1466 PrintHex(imm); 1569 PrintHex(imm);
1467 data++; 1570 data++;
1468 } 1571 } break;
1469 break;
1470 1572
1471 case 0x88: // 8bit, fall through 1573 case 0x88: // 8bit, fall through
1472 case 0x89: // 32bit 1574 case 0x89: // 32bit
1473 { bool is_byte = *data == 0x88; 1575 {
1576 bool is_byte = *data == 0x88;
1474 int mod, regop, rm; 1577 int mod, regop, rm;
1475 data++; 1578 data++;
1476 GetModRm(*data, &mod, &regop, &rm); 1579 GetModRm(*data, &mod, &regop, &rm);
1477 Print(is_byte ? "mov_b" : "mov"); 1580 Print(is_byte ? "mov_b" : "mov");
1478 Print(" "); 1581 Print(" ");
1479 data += PrintRightOperand(data); 1582 data += PrintRightOperand(data);
1480 Print(","); 1583 Print(",");
1481 PrintCPURegister(regop); 1584 PrintCPURegister(regop);
1482 } 1585 } break;
1483 break;
1484 1586
1485 case 0x66: // prefix 1587 case 0x66: // prefix
1486 data++; 1588 data++;
1487 if (*data == 0x8B) { 1589 if (*data == 0x8B) {
1488 data++; 1590 data++;
1489 data += PrintOperands("mov_w", REG_OPER_OP_ORDER, data); 1591 data += PrintOperands("mov_w", REG_OPER_OP_ORDER, data);
1490 } else if (*data == 0x89) { 1592 } else if (*data == 0x89) {
1491 data++; 1593 data++;
1492 int mod, regop, rm; 1594 int mod, regop, rm;
1493 GetModRm(*data, &mod, &regop, &rm); 1595 GetModRm(*data, &mod, &regop, &rm);
(...skipping 24 matching lines...) Expand all
1518 } else if (*data == 0xD6) { 1620 } else if (*data == 0xD6) {
1519 data++; 1621 data++;
1520 int mod, regop, rm; 1622 int mod, regop, rm;
1521 GetModRm(*data, &mod, &regop, &rm); 1623 GetModRm(*data, &mod, &regop, &rm);
1522 Print("movq "); 1624 Print("movq ");
1523 data += PrintRightOperand(data); 1625 data += PrintRightOperand(data);
1524 Print(","); 1626 Print(",");
1525 PrintXmmRegister(regop); 1627 PrintXmmRegister(regop);
1526 } else if (*data == 0x57 || *data == 0x56 || *data == 0x54) { 1628 } else if (*data == 0x57 || *data == 0x56 || *data == 0x54) {
1527 data += BitwisePDInstruction(data); 1629 data += BitwisePDInstruction(data);
1528 } else if (*data == 0x1F && 1630 } else if (*data == 0x1F && *(data + 1) == 0x44 &&
1529 *(data+1) == 0x44 && 1631 *(data + 2) == 0x00 && *(data + 3) == 0x00) {
1530 *(data+2) == 0x00 &&
1531 *(data+3) == 0x00) {
1532 data += 4; 1632 data += 4;
1533 Print("nop"); 1633 Print("nop");
1534 } else if (*data == 0x50) { 1634 } else if (*data == 0x50) {
1535 Print("movmskpd "); 1635 Print("movmskpd ");
1536 data++; 1636 data++;
1537 int mod, regop, rm; 1637 int mod, regop, rm;
1538 GetModRm(*data, &mod, &regop, &rm); 1638 GetModRm(*data, &mod, &regop, &rm);
1539 PrintCPURegister(regop); 1639 PrintCPURegister(regop);
1540 Print(","); 1640 Print(",");
1541 data += PrintRightXmmOperand(data); 1641 data += PrintRightXmmOperand(data);
1542 } else if (*data == 0x3A && *(data+1) == 0x16) { 1642 } else if (*data == 0x3A && *(data + 1) == 0x16) {
1543 Print("pextrd "); 1643 Print("pextrd ");
1544 data += 2; 1644 data += 2;
1545 int mod, regop, rm; 1645 int mod, regop, rm;
1546 GetModRm(*data, &mod, &regop, &rm); 1646 GetModRm(*data, &mod, &regop, &rm);
1547 PrintCPURegister(rm); 1647 PrintCPURegister(rm);
1548 Print(","); 1648 Print(",");
1549 PrintXmmRegister(regop); 1649 PrintXmmRegister(regop);
1550 Print(","); 1650 Print(",");
1551 PrintHex(*(data+1)); 1651 PrintHex(*(data + 1));
1552 data += 2; 1652 data += 2;
1553 } else if (*data == 0x38) { 1653 } else if (*data == 0x38) {
1554 data += Packed660F38Instruction(data); 1654 data += Packed660F38Instruction(data);
1555 } else if (*data == 0xEF) { 1655 } else if (*data == 0xEF) {
1556 int mod, regop, rm; 1656 int mod, regop, rm;
1557 GetModRm(*(data+1), &mod, &regop, &rm); 1657 GetModRm(*(data + 1), &mod, &regop, &rm);
1558 Print("pxor "); 1658 Print("pxor ");
1559 PrintXmmRegister(regop); 1659 PrintXmmRegister(regop);
1560 Print(","); 1660 Print(",");
1561 PrintXmmRegister(rm); 1661 PrintXmmRegister(rm);
1562 data += 2; 1662 data += 2;
1563 } else if (*data == 0x3A) { 1663 } else if (*data == 0x3A) {
1564 data++; 1664 data++;
1565 if (*data == 0x0B) { 1665 if (*data == 0x0B) {
1566 data++; 1666 data++;
1567 int mod, regop, rm; 1667 int mod, regop, rm;
1568 GetModRm(*data, &mod, &regop, &rm); 1668 GetModRm(*data, &mod, &regop, &rm);
1569 Print("roundsd "); 1669 Print("roundsd ");
1570 PrintXmmRegister(regop); 1670 PrintXmmRegister(regop);
1571 Print(", "); 1671 Print(", ");
1572 PrintXmmRegister(rm); 1672 PrintXmmRegister(rm);
1573 Print(", "); 1673 Print(", ");
1574 PrintInt(data[1] & 3); 1674 PrintInt(data[1] & 3);
1575 data += 2; 1675 data += 2;
1576 } else { 1676 } else {
1577 UNIMPLEMENTED(); 1677 UNIMPLEMENTED();
1578 } 1678 }
1579 } else if (*data == 0x14) { 1679 } else if (*data == 0x14) {
1580 int mod, regop, rm; 1680 int mod, regop, rm;
1581 GetModRm(*(data+1), &mod, &regop, &rm); 1681 GetModRm(*(data + 1), &mod, &regop, &rm);
1582 Print("unpcklpd "); 1682 Print("unpcklpd ");
1583 PrintXmmRegister(regop); 1683 PrintXmmRegister(regop);
1584 Print(","); 1684 Print(",");
1585 PrintXmmRegister(rm); 1685 PrintXmmRegister(rm);
1586 data += 2; 1686 data += 2;
1587 } else if (*data == 0x15) { 1687 } else if (*data == 0x15) {
1588 int mod, regop, rm; 1688 int mod, regop, rm;
1589 GetModRm(*(data+1), &mod, &regop, &rm); 1689 GetModRm(*(data + 1), &mod, &regop, &rm);
1590 Print("unpckhpd "); 1690 Print("unpckhpd ");
1591 PrintXmmRegister(regop); 1691 PrintXmmRegister(regop);
1592 Print(","); 1692 Print(",");
1593 PrintXmmRegister(rm); 1693 PrintXmmRegister(rm);
1594 data += 2; 1694 data += 2;
1595 } else if ((*data == 0xFE) || (*data == 0xFA) || (*data == 0x2F) || 1695 } else if ((*data == 0xFE) || (*data == 0xFA) || (*data == 0x2F) ||
1596 (*data == 0x58) || (*data == 0x5C) || (*data == 0x59) || 1696 (*data == 0x58) || (*data == 0x5C) || (*data == 0x59) ||
1597 (*data == 0x5E) || (*data == 0x5D) || (*data == 0x5F) || 1697 (*data == 0x5E) || (*data == 0x5D) || (*data == 0x5F) ||
1598 (*data == 0x51) || (*data == 0x5A)) { 1698 (*data == 0x51) || (*data == 0x5A)) {
1599 const char* mnemonic = PackedDoubleMnemonic(*data); 1699 const char* mnemonic = PackedDoubleMnemonic(*data);
1600 int mod, regop, rm; 1700 int mod, regop, rm;
1601 GetModRm(*(data+1), &mod, &regop, &rm); 1701 GetModRm(*(data + 1), &mod, &regop, &rm);
1602 Print(mnemonic); 1702 Print(mnemonic);
1603 PrintXmmRegister(regop); 1703 PrintXmmRegister(regop);
1604 Print(","); 1704 Print(",");
1605 PrintXmmRegister(rm); 1705 PrintXmmRegister(rm);
1606 data += 2; 1706 data += 2;
1607 } else if (*data == 0xC6) { 1707 } else if (*data == 0xC6) {
1608 int mod, regop, rm; 1708 int mod, regop, rm;
1609 data++; 1709 data++;
1610 GetModRm(*data, &mod, &regop, &rm); 1710 GetModRm(*data, &mod, &regop, &rm);
1611 Print("shufpd "); 1711 Print("shufpd ");
(...skipping 27 matching lines...) Expand all
1639 PrintHex(imm); 1739 PrintHex(imm);
1640 data += 2; 1740 data += 2;
1641 } else if (*data == 0x90) { 1741 } else if (*data == 0x90) {
1642 data++; 1742 data++;
1643 Print("nop"); 1743 Print("nop");
1644 } else { 1744 } else {
1645 UNIMPLEMENTED(); 1745 UNIMPLEMENTED();
1646 } 1746 }
1647 break; 1747 break;
1648 1748
1649 case 0xFE: 1749 case 0xFE: {
1650 { data++; 1750 data++;
1651 int mod, regop, rm; 1751 int mod, regop, rm;
1652 GetModRm(*data, &mod, &regop, &rm); 1752 GetModRm(*data, &mod, &regop, &rm);
1653 if (mod == 3 && regop == ecx) { 1753 if (mod == 3 && regop == ecx) {
1654 Print("dec_b "); 1754 Print("dec_b ");
1655 PrintCPURegister(rm); 1755 PrintCPURegister(rm);
1656 } else { 1756 } else {
1657 UNIMPLEMENTED(); 1757 UNIMPLEMENTED();
1658 } 1758 }
1659 data++; 1759 data++;
1660 } 1760 } break;
1661 break;
1662 1761
1663 case 0x68: 1762 case 0x68:
1664 Print("push "); 1763 Print("push ");
1665 PrintHex(*reinterpret_cast<int32_t*>(data+1)); 1764 PrintHex(*reinterpret_cast<int32_t*>(data + 1));
1666 data += 5; 1765 data += 5;
1667 break; 1766 break;
1668 1767
1669 case 0x6A: 1768 case 0x6A:
1670 Print("push "); 1769 Print("push ");
1671 PrintHex(*reinterpret_cast<int8_t*>(data + 1)); 1770 PrintHex(*reinterpret_cast<int8_t*>(data + 1));
1672 data += 2; 1771 data += 2;
1673 break; 1772 break;
1674 1773
1675 case 0xA8: 1774 case 0xA8:
1676 Print("test al,"); 1775 Print("test al,");
1677 PrintHex(*reinterpret_cast<uint8_t*>(data+1)); 1776 PrintHex(*reinterpret_cast<uint8_t*>(data + 1));
1678 data += 2; 1777 data += 2;
1679 break; 1778 break;
1680 1779
1681 case 0xA9: 1780 case 0xA9:
1682 Print("test eax,"); 1781 Print("test eax,");
1683 PrintHex(*reinterpret_cast<int32_t*>(data+1)); 1782 PrintHex(*reinterpret_cast<int32_t*>(data + 1));
1684 CheckPrintStop(data); 1783 CheckPrintStop(data);
1685 data += 5; 1784 data += 5;
1686 break; 1785 break;
1687 1786
1688 case 0xD1: // fall through 1787 case 0xD1: // fall through
1689 case 0xD3: // fall through 1788 case 0xD3: // fall through
1690 case 0xC1: 1789 case 0xC1:
1691 data += D1D3C1Instruction(data); 1790 data += D1D3C1Instruction(data);
1692 break; 1791 break;
1693 1792
1694 case 0xD9: // fall through 1793 case 0xD9: // fall through
1695 case 0xDA: // fall through 1794 case 0xDA: // fall through
1696 case 0xDB: // fall through 1795 case 0xDB: // fall through
1697 case 0xDC: // fall through 1796 case 0xDC: // fall through
1698 case 0xDD: // fall through 1797 case 0xDD: // fall through
1699 case 0xDE: // fall through 1798 case 0xDE: // fall through
1700 case 0xDF: 1799 case 0xDF:
1701 data += FPUInstruction(data); 1800 data += FPUInstruction(data);
1702 break; 1801 break;
1703 1802
1704 case 0xEB: 1803 case 0xEB:
1705 data += JumpShort(data); 1804 data += JumpShort(data);
1706 break; 1805 break;
1707 1806
1708 case 0xF3: 1807 case 0xF3:
1709 data = F3Instruction(data); 1808 data = F3Instruction(data);
1710 break; 1809 break;
1711 case 0xF2: { 1810 case 0xF2: {
1712 if (*(data+1) == 0x0F) { 1811 if (*(data + 1) == 0x0F) {
1713 uint8_t b2 = *(data+2); 1812 uint8_t b2 = *(data + 2);
1714 if (b2 == 0x11) { 1813 if (b2 == 0x11) {
1715 Print("movsd "); 1814 Print("movsd ");
1716 data += 3; 1815 data += 3;
1717 int mod, regop, rm; 1816 int mod, regop, rm;
1718 GetModRm(*data, &mod, &regop, &rm); 1817 GetModRm(*data, &mod, &regop, &rm);
1719 data += PrintRightXmmOperand(data); 1818 data += PrintRightXmmOperand(data);
1720 Print(","); 1819 Print(",");
1721 PrintXmmRegister(regop); 1820 PrintXmmRegister(regop);
1722 } else if (b2 == 0x10) { 1821 } else if (b2 == 0x10) {
1723 data += 3; 1822 data += 3;
1724 int mod, regop, rm; 1823 int mod, regop, rm;
1725 GetModRm(*data, &mod, &regop, &rm); 1824 GetModRm(*data, &mod, &regop, &rm);
1726 Print("movsd "); 1825 Print("movsd ");
1727 PrintXmmRegister(regop); 1826 PrintXmmRegister(regop);
1728 Print(","); 1827 Print(",");
1729 data += PrintRightOperand(data); 1828 data += PrintRightOperand(data);
1730 } else { 1829 } else {
1731 const char* mnem = "? 0xF2"; 1830 const char* mnem = "? 0xF2";
1732 switch (b2) { 1831 switch (b2) {
1733 case 0x2A: mnem = "cvtsi2sd"; break; 1832 case 0x2A:
1734 case 0x2C: mnem = "cvttsd2si"; break; 1833 mnem = "cvtsi2sd";
1735 case 0x2D: mnem = "cvtsd2i"; break; 1834 break;
1736 case 0x51: mnem = "sqrtsd"; break; 1835 case 0x2C:
1737 case 0x58: mnem = "addsd"; break; 1836 mnem = "cvttsd2si";
1738 case 0x59: mnem = "mulsd"; break; 1837 break;
1739 case 0x5A: mnem = "cvtsd2ss"; break; 1838 case 0x2D:
1740 case 0x5C: mnem = "subsd"; break; 1839 mnem = "cvtsd2i";
1741 case 0x5E: mnem = "divsd"; break; 1840 break;
1742 default: UNIMPLEMENTED(); 1841 case 0x51:
1842 mnem = "sqrtsd";
1843 break;
1844 case 0x58:
1845 mnem = "addsd";
1846 break;
1847 case 0x59:
1848 mnem = "mulsd";
1849 break;
1850 case 0x5A:
1851 mnem = "cvtsd2ss";
1852 break;
1853 case 0x5C:
1854 mnem = "subsd";
1855 break;
1856 case 0x5E:
1857 mnem = "divsd";
1858 break;
1859 default:
1860 UNIMPLEMENTED();
1743 } 1861 }
1744 data += 3; 1862 data += 3;
1745 int mod, regop, rm; 1863 int mod, regop, rm;
1746 GetModRm(*data, &mod, &regop, &rm); 1864 GetModRm(*data, &mod, &regop, &rm);
1747 if (b2 == 0x2A) { 1865 if (b2 == 0x2A) {
1748 Print(mnem); 1866 Print(mnem);
1749 Print(" "); 1867 Print(" ");
1750 PrintXmmRegister(regop); 1868 PrintXmmRegister(regop);
1751 Print(","); 1869 Print(",");
1752 data += PrintRightOperand(data); 1870 data += PrintRightOperand(data);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1784 } 1902 }
1785 } 1903 }
1786 1904
1787 int instr_len = data - reinterpret_cast<uint8_t*>(pc); 1905 int instr_len = data - reinterpret_cast<uint8_t*>(pc);
1788 ASSERT(instr_len > 0); // Ensure progress. 1906 ASSERT(instr_len > 0); // Ensure progress.
1789 1907
1790 return instr_len; 1908 return instr_len;
1791 } // NOLINT 1909 } // NOLINT
1792 1910
1793 1911
1794 void Disassembler::DecodeInstruction(char* hex_buffer, intptr_t hex_size, 1912 void Disassembler::DecodeInstruction(char* hex_buffer,
1795 char* human_buffer, intptr_t human_size, 1913 intptr_t hex_size,
1796 int* out_instr_len, const Code& code, 1914 char* human_buffer,
1797 Object** object, uword pc) { 1915 intptr_t human_size,
1916 int* out_instr_len,
1917 const Code& code,
1918 Object** object,
1919 uword pc) {
1798 ASSERT(hex_size > 0); 1920 ASSERT(hex_size > 0);
1799 ASSERT(human_size > 0); 1921 ASSERT(human_size > 0);
1800 X86Decoder decoder(human_buffer, human_size); 1922 X86Decoder decoder(human_buffer, human_size);
1801 int instruction_length = decoder.InstructionDecode(pc); 1923 int instruction_length = decoder.InstructionDecode(pc);
1802 uint8_t* pc_ptr = reinterpret_cast<uint8_t*>(pc); 1924 uint8_t* pc_ptr = reinterpret_cast<uint8_t*>(pc);
1803 int hex_index = 0; 1925 int hex_index = 0;
1804 int remaining_size = hex_size - hex_index; 1926 int remaining_size = hex_size - hex_index;
1805 for (int i = 0; (i < instruction_length) && (remaining_size > 2); ++i) { 1927 for (int i = 0; (i < instruction_length) && (remaining_size > 2); ++i) {
1806 OS::SNPrint(&hex_buffer[hex_index], remaining_size, "%02x", pc_ptr[i]); 1928 OS::SNPrint(&hex_buffer[hex_index], remaining_size, "%02x", pc_ptr[i]);
1807 hex_index += 2; 1929 hex_index += 2;
(...skipping 15 matching lines...) Expand all
1823 } 1945 }
1824 } 1946 }
1825 } 1947 }
1826 } 1948 }
1827 1949
1828 #endif // !PRODUCT 1950 #endif // !PRODUCT
1829 1951
1830 } // namespace dart 1952 } // namespace dart
1831 1953
1832 #endif // defined TARGET_ARCH_IA32 1954 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/disassembler_dbc.cc ('k') | runtime/vm/disassembler_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698