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

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

Issue 10825418: Repair x64 disassembler: (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | 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_X64) 8 #if defined(TARGET_ARCH_X64)
9 #include "platform/utils.h" 9 #include "platform/utils.h"
10 #include "vm/allocation.h" 10 #include "vm/allocation.h"
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 static const char* xmm_regs[kMaxXmmRegisters] = { 284 static const char* xmm_regs[kMaxXmmRegisters] = {
285 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", 285 "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
286 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" 286 "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
287 }; 287 };
288 288
289 class DisassemblerX64 : public ValueObject { 289 class DisassemblerX64 : public ValueObject {
290 public: 290 public:
291 DisassemblerX64(char* buffer, intptr_t buffer_size) 291 DisassemblerX64(char* buffer, intptr_t buffer_size)
292 : buffer_(buffer), 292 : buffer_(buffer),
293 buffer_size_(buffer_size), 293 buffer_size_(buffer_size),
294 buffer_pos_(0) { 294 buffer_pos_(0),
295 rex_(0),
296 operand_size_(0),
297 group_1_prefix_(0),
298 byte_size_operand_(false) {
295 buffer_[buffer_pos_] = '\0'; 299 buffer_[buffer_pos_] = '\0';
296 } 300 }
297 301
298 virtual ~DisassemblerX64() { 302 virtual ~DisassemblerX64() {
299 } 303 }
300 304
301 int InstructionDecode(uword pc); 305 int InstructionDecode(uword pc);
302 306
303 private: 307 private:
304 enum OperandSize { 308 enum OperandSize {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 int F6F7Instruction(uint8_t* data); 395 int F6F7Instruction(uint8_t* data);
392 int ShiftInstruction(uint8_t* data); 396 int ShiftInstruction(uint8_t* data);
393 int JumpShort(uint8_t* data); 397 int JumpShort(uint8_t* data);
394 int JumpConditional(uint8_t* data); 398 int JumpConditional(uint8_t* data);
395 int JumpConditionalShort(uint8_t* data); 399 int JumpConditionalShort(uint8_t* data);
396 int SetCC(uint8_t* data); 400 int SetCC(uint8_t* data);
397 int FPUInstruction(uint8_t* data); 401 int FPUInstruction(uint8_t* data);
398 int MemoryFPUInstruction(int escape_opcode, int regop, uint8_t* modrm_start); 402 int MemoryFPUInstruction(int escape_opcode, int regop, uint8_t* modrm_start);
399 int RegisterFPUInstruction(int escape_opcode, uint8_t modrm_byte); 403 int RegisterFPUInstruction(int escape_opcode, uint8_t modrm_byte);
400 404
401 bool DecodeInstructionType(const InstructionDesc& idesc, uint8_t** data); 405 bool DecodeInstructionType(uint8_t** data);
402 406
403 void UnimplementedInstruction() { 407 void UnimplementedInstruction() {
404 AppendToBuffer("'Unimplemented Instruction'"); 408 AppendToBuffer("'Unimplemented Instruction'");
405 } 409 }
406 410
407 char* buffer_; // Decode instructions into this buffer. 411 char* buffer_; // Decode instructions into this buffer.
408 intptr_t buffer_size_; // The size of the buffer_. 412 intptr_t buffer_size_; // The size of the buffer_.
409 intptr_t buffer_pos_; // Current character position in the buffer_. 413 intptr_t buffer_pos_; // Current character position in the buffer_.
410 414
411 // Prefixes parsed 415 // Prefixes parsed
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 if (has_register) { 1034 if (has_register) {
1031 AppendToBuffer("%s st%d", mnem, modrm_byte & 0x7); 1035 AppendToBuffer("%s st%d", mnem, modrm_byte & 0x7);
1032 } else { 1036 } else {
1033 AppendToBuffer("%s", mnem); 1037 AppendToBuffer("%s", mnem);
1034 } 1038 }
1035 return 2; 1039 return 2;
1036 } 1040 }
1037 1041
1038 1042
1039 // TODO(srdjan): Should we add a branch hint argument? 1043 // TODO(srdjan): Should we add a branch hint argument?
1040 bool DisassemblerX64::DecodeInstructionType(const InstructionDesc& idesc, 1044 bool DisassemblerX64::DecodeInstructionType(uint8_t** data) {
1041 uint8_t** data) { 1045 uint8_t current;
1042 uint8_t current = **data; 1046
1047 // Scan for prefixes.
1048 while (true) {
1049 current = **data;
1050 if (current == OPERAND_SIZE_OVERRIDE_PREFIX) { // Group 3 prefix.
1051 operand_size_ = current;
1052 } else if ((current & 0xF0) == 0x40) { // REX prefix.
1053 setRex(current);
1054 // TODO(srdjan): Should we enable printing of REX.W?
1055 // if (rex_w()) AppendToBuffer("REX.W ");
1056 } else if ((current & 0xFE) == 0xF2) { // Group 1 prefix (0xF2 or 0xF3).
1057 group_1_prefix_ = current;
1058 } else { // Not a prefix - an opcode.
1059 break;
1060 }
1061 (*data)++;
1062 }
1063
1064 const InstructionDesc& idesc = instruction_table.Get(current);
1065 byte_size_operand_ = idesc.byte_size_operation;
1066
1043 switch (idesc.type) { 1067 switch (idesc.type) {
1044 case ZERO_OPERANDS_INSTR: 1068 case ZERO_OPERANDS_INSTR:
1045 if (current >= 0xA4 && current <= 0xA7) { 1069 if (current >= 0xA4 && current <= 0xA7) {
1046 // String move or compare operations. 1070 // String move or compare operations.
1047 if (group_1_prefix_ == REP_PREFIX) { 1071 if (group_1_prefix_ == REP_PREFIX) {
1048 // REP. 1072 // REP.
1049 AppendToBuffer("rep "); 1073 AppendToBuffer("rep ");
1050 } 1074 }
1051 // TODO(srdjan): Should we enable printing of REX.W? 1075 // TODO(srdjan): Should we enable printing of REX.W?
1052 // if (rex_w()) AppendToBuffer("REX.W "); 1076 // if (rex_w()) AppendToBuffer("REX.W ");
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 case 0xBF: 1459 case 0xBF:
1436 return "movsxw"; 1460 return "movsxw";
1437 default: 1461 default:
1438 return NULL; 1462 return NULL;
1439 } 1463 }
1440 } 1464 }
1441 1465
1442 1466
1443 int DisassemblerX64::InstructionDecode(uword pc) { 1467 int DisassemblerX64::InstructionDecode(uword pc) {
1444 uint8_t* data = reinterpret_cast<uint8_t*>(pc); 1468 uint8_t* data = reinterpret_cast<uint8_t*>(pc);
1445 uint8_t current;
1446 1469
1447 // Scan for prefixes. 1470 const bool processed = DecodeInstructionType(&data);
1448 while (true) {
1449 current = *data;
1450 if (current == OPERAND_SIZE_OVERRIDE_PREFIX) { // Group 3 prefix.
1451 operand_size_ = current;
1452 } else if ((current & 0xF0) == 0x40) { // REX prefix.
1453 setRex(current);
1454 // TODO(srdjan): Should we enable printing of REX.W?
1455 // if (rex_w()) AppendToBuffer("REX.W ");
1456 } else if ((current & 0xFE) == 0xF2) { // Group 1 prefix (0xF2 or 0xF3).
1457 group_1_prefix_ = current;
1458 } else { // Not a prefix - an opcode.
1459 break;
1460 }
1461 data++;
1462 }
1463
1464 const InstructionDesc& idesc = instruction_table.Get(current);
1465 byte_size_operand_ = idesc.byte_size_operation;
1466 bool processed = DecodeInstructionType(idesc, &data);
1467 1471
1468 if (!processed) { 1472 if (!processed) {
1469 switch (*data) { 1473 switch (*data) {
1470 case 0xC2: 1474 case 0xC2:
1471 AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data + 1)); 1475 AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data + 1));
1472 data += 3; 1476 data += 3;
1473 break; 1477 break;
1474 1478
1475 case 0x69: // fall through 1479 case 0x69: // fall through
1476 case 0x6B: { 1480 case 0x6B: {
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1828 human_buffer, 1832 human_buffer,
1829 sizeof(human_buffer), 1833 sizeof(human_buffer),
1830 pc); 1834 pc);
1831 pc += instruction_length; 1835 pc += instruction_length;
1832 } 1836 }
1833 } 1837 }
1834 1838
1835 } // namespace dart 1839 } // namespace dart
1836 1840
1837 #endif // defined TARGET_ARCH_X64 1841 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698