| OLD | NEW |
| 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 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 | 366 |
| 367 const char* NameOfByteCPURegister(int reg) const { | 367 const char* NameOfByteCPURegister(int reg) const { |
| 368 return NameOfCPURegister(reg); | 368 return NameOfCPURegister(reg); |
| 369 } | 369 } |
| 370 | 370 |
| 371 const char* NameOfXMMRegister(int reg) const { | 371 const char* NameOfXMMRegister(int reg) const { |
| 372 ASSERT((0 <= reg) && (reg < kMaxXmmRegisters)); | 372 ASSERT((0 <= reg) && (reg < kMaxXmmRegisters)); |
| 373 return xmm_regs[reg]; | 373 return xmm_regs[reg]; |
| 374 } | 374 } |
| 375 | 375 |
| 376 void AppendToBuffer(const char* format, ...); | 376 void AppendToBuffer(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
| 377 void AppendAddressToBuffer(uint8_t* addr); | 377 void AppendAddressToBuffer(uint8_t* addr); |
| 378 | 378 |
| 379 int PrintOperands(const char* mnem, | 379 int PrintOperands(const char* mnem, |
| 380 OperandType op_order, | 380 OperandType op_order, |
| 381 uint8_t* data); | 381 uint8_t* data); |
| 382 | 382 |
| 383 typedef const char* (DisassemblerX64::*RegisterNameMapping)(int reg) const; | 383 typedef const char* (DisassemblerX64::*RegisterNameMapping)(int reg) const; |
| 384 | 384 |
| 385 int PrintRightOperandHelper(uint8_t* modrmp, | 385 int PrintRightOperandHelper(uint8_t* modrmp, |
| 386 RegisterNameMapping register_name); | 386 RegisterNameMapping register_name); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 uint8_t* modrmp, | 439 uint8_t* modrmp, |
| 440 RegisterNameMapping direct_register_name) { | 440 RegisterNameMapping direct_register_name) { |
| 441 int mod, regop, rm; | 441 int mod, regop, rm; |
| 442 get_modrm(*modrmp, &mod, ®op, &rm); | 442 get_modrm(*modrmp, &mod, ®op, &rm); |
| 443 RegisterNameMapping register_name = (mod == 3) ? direct_register_name : | 443 RegisterNameMapping register_name = (mod == 3) ? direct_register_name : |
| 444 &DisassemblerX64::NameOfCPURegister; | 444 &DisassemblerX64::NameOfCPURegister; |
| 445 switch (mod) { | 445 switch (mod) { |
| 446 case 0: | 446 case 0: |
| 447 if ((rm & 7) == 5) { | 447 if ((rm & 7) == 5) { |
| 448 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1); | 448 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1); |
| 449 AppendToBuffer("[0x%x]", disp); | 449 AppendToBuffer("[%#x]", disp); |
| 450 return 5; | 450 return 5; |
| 451 } else if ((rm & 7) == 4) { | 451 } else if ((rm & 7) == 4) { |
| 452 // Codes for SIB byte. | 452 // Codes for SIB byte. |
| 453 uint8_t sib = *(modrmp + 1); | 453 uint8_t sib = *(modrmp + 1); |
| 454 int scale, index, base; | 454 int scale, index, base; |
| 455 get_sib(sib, &scale, &index, &base); | 455 get_sib(sib, &scale, &index, &base); |
| 456 if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { | 456 if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { |
| 457 // index == rsp means no index. Only use sib byte with no index for | 457 // index == rsp means no index. Only use sib byte with no index for |
| 458 // rsp and r12 base. | 458 // rsp and r12 base. |
| 459 AppendToBuffer("[%s]", NameOfCPURegister(base)); | 459 AppendToBuffer("[%s]", NameOfCPURegister(base)); |
| 460 return 2; | 460 return 2; |
| 461 } else if (base == 5) { | 461 } else if (base == 5) { |
| 462 // base == rbp means no base register (when mod == 0). | 462 // base == rbp means no base register (when mod == 0). |
| 463 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); | 463 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); |
| 464 AppendToBuffer("[%s*%d+0x%x]", | 464 AppendToBuffer("[%s*%d+%#x]", |
| 465 NameOfCPURegister(index), | 465 NameOfCPURegister(index), |
| 466 1 << scale, disp); | 466 1 << scale, disp); |
| 467 return 6; | 467 return 6; |
| 468 } else if (index != 4 && base != 5) { | 468 } else if (index != 4 && base != 5) { |
| 469 // [base+index*scale] | 469 // [base+index*scale] |
| 470 AppendToBuffer("[%s+%s*%d]", | 470 AppendToBuffer("[%s+%s*%d]", |
| 471 NameOfCPURegister(base), | 471 NameOfCPURegister(base), |
| 472 NameOfCPURegister(index), | 472 NameOfCPURegister(index), |
| 473 1 << scale); | 473 1 << scale); |
| 474 return 2; | 474 return 2; |
| 475 } else { | 475 } else { |
| 476 UnimplementedInstruction(); | 476 UnimplementedInstruction(); |
| 477 return 1; | 477 return 1; |
| 478 } | 478 } |
| 479 } else { | 479 } else { |
| 480 AppendToBuffer("[%s]", NameOfCPURegister(rm)); | 480 AppendToBuffer("[%s]", NameOfCPURegister(rm)); |
| 481 return 1; | 481 return 1; |
| 482 } | 482 } |
| 483 break; | 483 break; |
| 484 case 1: // fall through | 484 case 1: // fall through |
| 485 case 2: | 485 case 2: |
| 486 if ((rm & 7) == 4) { | 486 if ((rm & 7) == 4) { |
| 487 uint8_t sib = *(modrmp + 1); | 487 uint8_t sib = *(modrmp + 1); |
| 488 int scale, index, base; | 488 int scale, index, base; |
| 489 get_sib(sib, &scale, &index, &base); | 489 get_sib(sib, &scale, &index, &base); |
| 490 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2) | 490 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2) |
| 491 : *reinterpret_cast<char*>(modrmp + 2); | 491 : *reinterpret_cast<char*>(modrmp + 2); |
| 492 if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { | 492 if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { |
| 493 if (-disp > 0) { | 493 if (-disp > 0) { |
| 494 AppendToBuffer("[%s-0x%x]", NameOfCPURegister(base), -disp); | 494 AppendToBuffer("[%s-%#x]", NameOfCPURegister(base), -disp); |
| 495 } else { | 495 } else { |
| 496 AppendToBuffer("[%s+0x%x]", NameOfCPURegister(base), disp); | 496 AppendToBuffer("[%s+%#x]", NameOfCPURegister(base), disp); |
| 497 } | 497 } |
| 498 } else { | 498 } else { |
| 499 if (-disp > 0) { | 499 if (-disp > 0) { |
| 500 AppendToBuffer("[%s+%s*%d-0x%x]", | 500 AppendToBuffer("[%s+%s*%d-%#x]", |
| 501 NameOfCPURegister(base), | 501 NameOfCPURegister(base), |
| 502 NameOfCPURegister(index), | 502 NameOfCPURegister(index), |
| 503 1 << scale, | 503 1 << scale, |
| 504 -disp); | 504 -disp); |
| 505 } else { | 505 } else { |
| 506 AppendToBuffer("[%s+%s*%d+0x%x]", | 506 AppendToBuffer("[%s+%s*%d+%#x]", |
| 507 NameOfCPURegister(base), | 507 NameOfCPURegister(base), |
| 508 NameOfCPURegister(index), | 508 NameOfCPURegister(index), |
| 509 1 << scale, | 509 1 << scale, |
| 510 disp); | 510 disp); |
| 511 } | 511 } |
| 512 } | 512 } |
| 513 return mod == 2 ? 6 : 3; | 513 return mod == 2 ? 6 : 3; |
| 514 } else { | 514 } else { |
| 515 // No sib. | 515 // No sib. |
| 516 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1) | 516 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1) |
| 517 : *reinterpret_cast<char*>(modrmp + 1); | 517 : *reinterpret_cast<char*>(modrmp + 1); |
| 518 if (-disp > 0) { | 518 if (-disp > 0) { |
| 519 AppendToBuffer("[%s-0x%x]", NameOfCPURegister(rm), -disp); | 519 AppendToBuffer("[%s-%#x]", NameOfCPURegister(rm), -disp); |
| 520 } else { | 520 } else { |
| 521 AppendToBuffer("[%s+0x%x]", NameOfCPURegister(rm), disp); | 521 AppendToBuffer("[%s+%#x]", NameOfCPURegister(rm), disp); |
| 522 } | 522 } |
| 523 return (mod == 2) ? 5 : 2; | 523 return (mod == 2) ? 5 : 2; |
| 524 } | 524 } |
| 525 break; | 525 break; |
| 526 case 3: | 526 case 3: |
| 527 AppendToBuffer("%s", (this->*register_name)(rm)); | 527 AppendToBuffer("%s", (this->*register_name)(rm)); |
| 528 return 1; | 528 return 1; |
| 529 default: | 529 default: |
| 530 UnimplementedInstruction(); | 530 UnimplementedInstruction(); |
| 531 return 1; | 531 return 1; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 552 break; | 552 break; |
| 553 case QUADWORD_SIZE: | 553 case QUADWORD_SIZE: |
| 554 value = *reinterpret_cast<int32_t*>(data); | 554 value = *reinterpret_cast<int32_t*>(data); |
| 555 count = 4; | 555 count = 4; |
| 556 break; | 556 break; |
| 557 default: | 557 default: |
| 558 UNREACHABLE(); | 558 UNREACHABLE(); |
| 559 value = 0; // Initialize variables on all paths to satisfy the compiler. | 559 value = 0; // Initialize variables on all paths to satisfy the compiler. |
| 560 count = 0; | 560 count = 0; |
| 561 } | 561 } |
| 562 AppendToBuffer("%"PRIxPTR, value); | 562 AppendToBuffer("%#"Px"", value); |
| 563 return count; | 563 return count; |
| 564 } | 564 } |
| 565 | 565 |
| 566 | 566 |
| 567 // Returns number of bytes used by machine instruction, including *data byte. | 567 // Returns number of bytes used by machine instruction, including *data byte. |
| 568 // Writes immediate instructions to 'tmp_buffer_'. | 568 // Writes immediate instructions to 'tmp_buffer_'. |
| 569 int DisassemblerX64::PrintImmediateOp(uint8_t* data) { | 569 int DisassemblerX64::PrintImmediateOp(uint8_t* data) { |
| 570 bool byte_size_immediate = (*data & 0x02) != 0; | 570 bool byte_size_immediate = (*data & 0x02) != 0; |
| 571 uint8_t modrm = *(data + 1); | 571 uint8_t modrm = *(data + 1); |
| 572 int mod, regop, rm; | 572 int mod, regop, rm; |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 790 intptr_t len = OS::SNPrint(NULL, 0, format, full_class_name) + 1; | 790 intptr_t len = OS::SNPrint(NULL, 0, format, full_class_name) + 1; |
| 791 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 791 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 792 OS::SNPrint(chars, len, format, full_class_name); | 792 OS::SNPrint(chars, len, format, full_class_name); |
| 793 return chars; | 793 return chars; |
| 794 } | 794 } |
| 795 | 795 |
| 796 | 796 |
| 797 void DisassemblerX64::AppendAddressToBuffer(uint8_t* addr_byte_ptr) { | 797 void DisassemblerX64::AppendAddressToBuffer(uint8_t* addr_byte_ptr) { |
| 798 NoGCScope no_gc; | 798 NoGCScope no_gc; |
| 799 uword addr = reinterpret_cast<uword>(addr_byte_ptr); | 799 uword addr = reinterpret_cast<uword>(addr_byte_ptr); |
| 800 AppendToBuffer("0x%0"PRIxPTR, addr); | 800 AppendToBuffer("%#"Px"", addr); |
| 801 // Try to print as heap object or stub name | 801 // Try to print as heap object or stub name |
| 802 if (!Isolate::Current()->heap()->CodeContains(addr) && | 802 if (!Isolate::Current()->heap()->CodeContains(addr) && |
| 803 Isolate::Current()->heap()->Contains(addr - kHeapObjectTag)) { | 803 Isolate::Current()->heap()->Contains(addr - kHeapObjectTag)) { |
| 804 Object& obj = Object::Handle(reinterpret_cast<RawObject*>(addr)); | 804 Object& obj = Object::Handle(reinterpret_cast<RawObject*>(addr)); |
| 805 if (obj.IsArray()) { | 805 if (obj.IsArray()) { |
| 806 const Array& arr = Array::CheckedHandle(obj.raw()); | 806 const Array& arr = Array::CheckedHandle(obj.raw()); |
| 807 intptr_t len = arr.Length(); | 807 intptr_t len = arr.Length(); |
| 808 if (len > 5) len = 5; // Print a max of 5 elements. | 808 if (len > 5) len = 5; // Print a max of 5 elements. |
| 809 AppendToBuffer(" Array["); | 809 AppendToBuffer(" Array["); |
| 810 int i = 0; | 810 int i = 0; |
| 811 while (i < len) { | 811 while (i < len) { |
| 812 obj = arr.At(i); | 812 obj = arr.At(i); |
| 813 if (i > 0) AppendToBuffer(", "); | 813 if (i > 0) AppendToBuffer(", "); |
| 814 AppendToBuffer(ObjectToCStringNoGC(obj)); | 814 AppendToBuffer("%s", ObjectToCStringNoGC(obj)); |
| 815 i++; | 815 i++; |
| 816 } | 816 } |
| 817 if (i < arr.Length()) AppendToBuffer(", ..."); | 817 if (i < arr.Length()) AppendToBuffer(", ..."); |
| 818 AppendToBuffer("]"); | 818 AppendToBuffer("]"); |
| 819 return; | 819 return; |
| 820 } | 820 } |
| 821 AppendToBuffer(" '%s'", ObjectToCStringNoGC(obj)); | 821 AppendToBuffer(" '%s'", ObjectToCStringNoGC(obj)); |
| 822 } else { | 822 } else { |
| 823 // 'addr' is not an object, but probably a code address. | 823 // 'addr' is not an object, but probably a code address. |
| 824 const char* name_of_stub = StubCode::NameOfStub(addr); | 824 const char* name_of_stub = StubCode::NameOfStub(addr); |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 if (current >= 0xA4 && current <= 0xA7) { | 1093 if (current >= 0xA4 && current <= 0xA7) { |
| 1094 // String move or compare operations. | 1094 // String move or compare operations. |
| 1095 if (group_1_prefix_ == REP_PREFIX) { | 1095 if (group_1_prefix_ == REP_PREFIX) { |
| 1096 // REP. | 1096 // REP. |
| 1097 AppendToBuffer("rep "); | 1097 AppendToBuffer("rep "); |
| 1098 } | 1098 } |
| 1099 // TODO(srdjan): Should we enable printing of REX.W? | 1099 // TODO(srdjan): Should we enable printing of REX.W? |
| 1100 // if (rex_w()) AppendToBuffer("REX.W "); | 1100 // if (rex_w()) AppendToBuffer("REX.W "); |
| 1101 AppendToBuffer("%s%c", idesc.mnem, operand_size_code()); | 1101 AppendToBuffer("%s%c", idesc.mnem, operand_size_code()); |
| 1102 } else { | 1102 } else { |
| 1103 AppendToBuffer("%s", idesc.mnem, operand_size_code()); | 1103 AppendToBuffer("%s%c", idesc.mnem, operand_size_code()); |
| 1104 } | 1104 } |
| 1105 (*data)++; | 1105 (*data)++; |
| 1106 break; | 1106 break; |
| 1107 | 1107 |
| 1108 case TWO_OPERANDS_INSTR: | 1108 case TWO_OPERANDS_INSTR: |
| 1109 (*data)++; | 1109 (*data)++; |
| 1110 (*data) += PrintOperands(idesc.mnem, idesc.op_order_, *data); | 1110 (*data) += PrintOperands(idesc.mnem, idesc.op_order_, *data); |
| 1111 break; | 1111 break; |
| 1112 | 1112 |
| 1113 case JUMP_CONDITIONAL_SHORT_INSTR: | 1113 case JUMP_CONDITIONAL_SHORT_INSTR: |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1489 | 1489 |
| 1490 | 1490 |
| 1491 int DisassemblerX64::InstructionDecode(uword pc) { | 1491 int DisassemblerX64::InstructionDecode(uword pc) { |
| 1492 uint8_t* data = reinterpret_cast<uint8_t*>(pc); | 1492 uint8_t* data = reinterpret_cast<uint8_t*>(pc); |
| 1493 | 1493 |
| 1494 const bool processed = DecodeInstructionType(&data); | 1494 const bool processed = DecodeInstructionType(&data); |
| 1495 | 1495 |
| 1496 if (!processed) { | 1496 if (!processed) { |
| 1497 switch (*data) { | 1497 switch (*data) { |
| 1498 case 0xC2: | 1498 case 0xC2: |
| 1499 AppendToBuffer("ret 0x%x", *reinterpret_cast<uint16_t*>(data + 1)); | 1499 AppendToBuffer("ret %#x", *reinterpret_cast<uint16_t*>(data + 1)); |
| 1500 data += 3; | 1500 data += 3; |
| 1501 break; | 1501 break; |
| 1502 | 1502 |
| 1503 case 0x69: // fall through | 1503 case 0x69: // fall through |
| 1504 case 0x6B: { | 1504 case 0x6B: { |
| 1505 int mod, regop, rm; | 1505 int mod, regop, rm; |
| 1506 get_modrm(*(data + 1), &mod, ®op, &rm); | 1506 get_modrm(*(data + 1), &mod, ®op, &rm); |
| 1507 int32_t imm = *data == 0x6B ? *(data + 2) | 1507 int32_t imm = *data == 0x6B ? *(data + 2) |
| 1508 : *reinterpret_cast<int32_t*>(data + 2); | 1508 : *reinterpret_cast<int32_t*>(data + 2); |
| 1509 AppendToBuffer("imul%c %s,%s,0x%x", | 1509 AppendToBuffer("imul%c %s,%s,%#x", |
| 1510 operand_size_code(), | 1510 operand_size_code(), |
| 1511 NameOfCPURegister(regop), | 1511 NameOfCPURegister(regop), |
| 1512 NameOfCPURegister(rm), imm); | 1512 NameOfCPURegister(rm), imm); |
| 1513 data += 2 + (*data == 0x6B ? 1 : 4); | 1513 data += 2 + (*data == 0x6B ? 1 : 4); |
| 1514 break; | 1514 break; |
| 1515 } | 1515 } |
| 1516 | 1516 |
| 1517 case 0x81: // fall through | 1517 case 0x81: // fall through |
| 1518 case 0x83: // 0x81 with sign extension bit set | 1518 case 0x83: // 0x81 with sign extension bit set |
| 1519 data += PrintImmediateOp(data); | 1519 data += PrintImmediateOp(data); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1567 | 1567 |
| 1568 case 0xC7: // imm32, fall through | 1568 case 0xC7: // imm32, fall through |
| 1569 case 0xC6: // imm8 | 1569 case 0xC6: // imm8 |
| 1570 { | 1570 { |
| 1571 bool is_byte = *data == 0xC6; | 1571 bool is_byte = *data == 0xC6; |
| 1572 data++; | 1572 data++; |
| 1573 if (is_byte) { | 1573 if (is_byte) { |
| 1574 AppendToBuffer("movb "); | 1574 AppendToBuffer("movb "); |
| 1575 data += PrintRightByteOperand(data); | 1575 data += PrintRightByteOperand(data); |
| 1576 int32_t imm = *data; | 1576 int32_t imm = *data; |
| 1577 AppendToBuffer(",0x%x", imm); | 1577 AppendToBuffer(",%#x", imm); |
| 1578 data++; | 1578 data++; |
| 1579 } else { | 1579 } else { |
| 1580 AppendToBuffer("mov%c ", operand_size_code()); | 1580 AppendToBuffer("mov%c ", operand_size_code()); |
| 1581 data += PrintRightOperand(data); | 1581 data += PrintRightOperand(data); |
| 1582 int32_t imm = *reinterpret_cast<int32_t*>(data); | 1582 int32_t imm = *reinterpret_cast<int32_t*>(data); |
| 1583 AppendToBuffer(",0x%x", imm); | 1583 AppendToBuffer(",%#x", imm); |
| 1584 data += 4; | 1584 data += 4; |
| 1585 } | 1585 } |
| 1586 } | 1586 } |
| 1587 break; | 1587 break; |
| 1588 | 1588 |
| 1589 case 0x80: { | 1589 case 0x80: { |
| 1590 data++; | 1590 data++; |
| 1591 AppendToBuffer("cmpb "); | 1591 AppendToBuffer("cmpb "); |
| 1592 data += PrintRightByteOperand(data); | 1592 data += PrintRightByteOperand(data); |
| 1593 int32_t imm = *data; | 1593 int32_t imm = *data; |
| 1594 AppendToBuffer(",0x%x", imm); | 1594 AppendToBuffer(",%#x", imm); |
| 1595 data++; | 1595 data++; |
| 1596 } | 1596 } |
| 1597 break; | 1597 break; |
| 1598 | 1598 |
| 1599 case 0x88: // 8bit, fall through | 1599 case 0x88: // 8bit, fall through |
| 1600 case 0x89: // 32bit | 1600 case 0x89: // 32bit |
| 1601 { | 1601 { |
| 1602 bool is_byte = *data == 0x88; | 1602 bool is_byte = *data == 0x88; |
| 1603 int mod, regop, rm; | 1603 int mod, regop, rm; |
| 1604 data++; | 1604 data++; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1673 get_modrm(*data, &mod, ®op, &rm); | 1673 get_modrm(*data, &mod, ®op, &rm); |
| 1674 if (regop == 1) { | 1674 if (regop == 1) { |
| 1675 AppendToBuffer("decb "); | 1675 AppendToBuffer("decb "); |
| 1676 data += PrintRightByteOperand(data); | 1676 data += PrintRightByteOperand(data); |
| 1677 } else { | 1677 } else { |
| 1678 UnimplementedInstruction(); | 1678 UnimplementedInstruction(); |
| 1679 } | 1679 } |
| 1680 break; | 1680 break; |
| 1681 } | 1681 } |
| 1682 case 0x68: | 1682 case 0x68: |
| 1683 AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data + 1)); | 1683 AppendToBuffer("push %#x", *reinterpret_cast<int32_t*>(data + 1)); |
| 1684 data += 5; | 1684 data += 5; |
| 1685 break; | 1685 break; |
| 1686 | 1686 |
| 1687 case 0x6A: | 1687 case 0x6A: |
| 1688 AppendToBuffer("push 0x%x", *reinterpret_cast<int8_t*>(data + 1)); | 1688 AppendToBuffer("push %#x", *reinterpret_cast<int8_t*>(data + 1)); |
| 1689 data += 2; | 1689 data += 2; |
| 1690 break; | 1690 break; |
| 1691 | 1691 |
| 1692 case 0xA1: // Fall through. | 1692 case 0xA1: // Fall through. |
| 1693 case 0xA3: | 1693 case 0xA3: |
| 1694 switch (operand_size()) { | 1694 switch (operand_size()) { |
| 1695 case DOUBLEWORD_SIZE: { | 1695 case DOUBLEWORD_SIZE: { |
| 1696 AppendAddressToBuffer( | 1696 AppendAddressToBuffer( |
| 1697 reinterpret_cast<uint8_t*>( | 1697 reinterpret_cast<uint8_t*>( |
| 1698 *reinterpret_cast<int32_t*>(data + 1))); | 1698 *reinterpret_cast<int32_t*>(data + 1))); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1726 data += 9; | 1726 data += 9; |
| 1727 break; | 1727 break; |
| 1728 } | 1728 } |
| 1729 default: | 1729 default: |
| 1730 UnimplementedInstruction(); | 1730 UnimplementedInstruction(); |
| 1731 data += 2; | 1731 data += 2; |
| 1732 } | 1732 } |
| 1733 break; | 1733 break; |
| 1734 | 1734 |
| 1735 case 0xA8: | 1735 case 0xA8: |
| 1736 AppendToBuffer("test al,0x%x", *reinterpret_cast<uint8_t*>(data + 1)); | 1736 AppendToBuffer("test al,%#x", *reinterpret_cast<uint8_t*>(data + 1)); |
| 1737 data += 2; | 1737 data += 2; |
| 1738 break; | 1738 break; |
| 1739 | 1739 |
| 1740 case 0xA9: { | 1740 case 0xA9: { |
| 1741 int64_t value = 0; | 1741 int64_t value = 0; |
| 1742 switch (operand_size()) { | 1742 switch (operand_size()) { |
| 1743 case WORD_SIZE: | 1743 case WORD_SIZE: |
| 1744 value = *reinterpret_cast<uint16_t*>(data + 1); | 1744 value = *reinterpret_cast<uint16_t*>(data + 1); |
| 1745 data += 3; | 1745 data += 3; |
| 1746 break; | 1746 break; |
| 1747 case DOUBLEWORD_SIZE: | 1747 case DOUBLEWORD_SIZE: |
| 1748 value = *reinterpret_cast<uint32_t*>(data + 1); | 1748 value = *reinterpret_cast<uint32_t*>(data + 1); |
| 1749 data += 5; | 1749 data += 5; |
| 1750 break; | 1750 break; |
| 1751 case QUADWORD_SIZE: | 1751 case QUADWORD_SIZE: |
| 1752 value = *reinterpret_cast<int32_t*>(data + 1); | 1752 value = *reinterpret_cast<int32_t*>(data + 1); |
| 1753 data += 5; | 1753 data += 5; |
| 1754 break; | 1754 break; |
| 1755 default: | 1755 default: |
| 1756 UNREACHABLE(); | 1756 UNREACHABLE(); |
| 1757 } | 1757 } |
| 1758 AppendToBuffer("test%c rax,0x%0"PRIxPTR, | 1758 AppendToBuffer("test%c rax,%#"Px"", |
| 1759 operand_size_code(), | 1759 operand_size_code(), |
| 1760 value); | 1760 value); |
| 1761 break; | 1761 break; |
| 1762 } | 1762 } |
| 1763 case 0xD1: // fall through | 1763 case 0xD1: // fall through |
| 1764 case 0xD3: // fall through | 1764 case 0xD3: // fall through |
| 1765 case 0xC1: | 1765 case 0xC1: |
| 1766 data += ShiftInstruction(data); | 1766 data += ShiftInstruction(data); |
| 1767 break; | 1767 break; |
| 1768 case 0xD0: // fall through | 1768 case 0xD0: // fall through |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1856 human_buffer, | 1856 human_buffer, |
| 1857 sizeof(human_buffer), | 1857 sizeof(human_buffer), |
| 1858 pc); | 1858 pc); |
| 1859 pc += instruction_length; | 1859 pc += instruction_length; |
| 1860 } | 1860 } |
| 1861 } | 1861 } |
| 1862 | 1862 |
| 1863 } // namespace dart | 1863 } // namespace dart |
| 1864 | 1864 |
| 1865 #endif // defined TARGET_ARCH_X64 | 1865 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |