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 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
381 OperandType op_order, | 381 OperandType op_order, |
382 uint8_t* data); | 382 uint8_t* data); |
383 | 383 |
384 typedef const char* (DisassemblerX64::*RegisterNameMapping)(int reg) const; | 384 typedef const char* (DisassemblerX64::*RegisterNameMapping)(int reg) const; |
385 | 385 |
386 int PrintRightOperandHelper(uint8_t* modrmp, | 386 int PrintRightOperandHelper(uint8_t* modrmp, |
387 RegisterNameMapping register_name); | 387 RegisterNameMapping register_name); |
388 int PrintRightOperand(uint8_t* modrmp); | 388 int PrintRightOperand(uint8_t* modrmp); |
389 int PrintRightByteOperand(uint8_t* modrmp); | 389 int PrintRightByteOperand(uint8_t* modrmp); |
390 int PrintRightXMMOperand(uint8_t* modrmp); | 390 int PrintRightXMMOperand(uint8_t* modrmp); |
391 void PrintDisp(int disp, const char* after); | |
391 int PrintImmediate(uint8_t* data, OperandSize size); | 392 int PrintImmediate(uint8_t* data, OperandSize size); |
393 void PrintImmediateValue(int64_t value); | |
392 int PrintImmediateOp(uint8_t* data); | 394 int PrintImmediateOp(uint8_t* data); |
393 const char* TwoByteMnemonic(uint8_t opcode); | 395 const char* TwoByteMnemonic(uint8_t opcode); |
394 int TwoByteOpcodeInstruction(uint8_t* data); | 396 int TwoByteOpcodeInstruction(uint8_t* data); |
395 | 397 |
396 int F6F7Instruction(uint8_t* data); | 398 int F6F7Instruction(uint8_t* data); |
397 int ShiftInstruction(uint8_t* data); | 399 int ShiftInstruction(uint8_t* data); |
398 int JumpShort(uint8_t* data); | 400 int JumpShort(uint8_t* data); |
399 int JumpConditional(uint8_t* data); | 401 int JumpConditional(uint8_t* data); |
400 int JumpConditionalShort(uint8_t* data); | 402 int JumpConditionalShort(uint8_t* data); |
401 int SetCC(uint8_t* data); | 403 int SetCC(uint8_t* data); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 uint8_t* modrmp, | 449 uint8_t* modrmp, |
448 RegisterNameMapping direct_register_name) { | 450 RegisterNameMapping direct_register_name) { |
449 int mod, regop, rm; | 451 int mod, regop, rm; |
450 get_modrm(*modrmp, &mod, ®op, &rm); | 452 get_modrm(*modrmp, &mod, ®op, &rm); |
451 RegisterNameMapping register_name = (mod == 3) ? direct_register_name : | 453 RegisterNameMapping register_name = (mod == 3) ? direct_register_name : |
452 &DisassemblerX64::NameOfCPURegister; | 454 &DisassemblerX64::NameOfCPURegister; |
453 switch (mod) { | 455 switch (mod) { |
454 case 0: | 456 case 0: |
455 if ((rm & 7) == 5) { | 457 if ((rm & 7) == 5) { |
456 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1); | 458 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1); |
457 AppendToBuffer("[rip%s%#x]", disp < 0 ? "-" : "+", Utils::Abs(disp)); | 459 AppendToBuffer("[rip"); |
460 PrintDisp(disp, "]"); | |
458 return 5; | 461 return 5; |
459 } else if ((rm & 7) == 4) { | 462 } else if ((rm & 7) == 4) { |
460 // Codes for SIB byte. | 463 // Codes for SIB byte. |
461 uint8_t sib = *(modrmp + 1); | 464 uint8_t sib = *(modrmp + 1); |
462 int scale, index, base; | 465 int scale, index, base; |
463 get_sib(sib, &scale, &index, &base); | 466 get_sib(sib, &scale, &index, &base); |
464 if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { | 467 if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { |
465 // index == rsp means no index. Only use sib byte with no index for | 468 // index == rsp means no index. Only use sib byte with no index for |
466 // rsp and r12 base. | 469 // rsp and r12 base. |
467 AppendToBuffer("[%s]", NameOfCPURegister(base)); | 470 AppendToBuffer("[%s]", NameOfCPURegister(base)); |
468 return 2; | 471 return 2; |
469 } else if (base == 5) { | 472 } else if (base == 5) { |
470 // base == rbp means no base register (when mod == 0). | 473 // base == rbp means no base register (when mod == 0). |
471 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); | 474 int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); |
472 AppendToBuffer("[%s*%d+%#x]", | 475 AppendToBuffer("[%s*%d", NameOfCPURegister(index), 1 << scale); |
473 NameOfCPURegister(index), | 476 PrintDisp(disp, "]"); |
474 1 << scale, disp); | |
475 return 6; | 477 return 6; |
476 } else if (index != 4 && base != 5) { | 478 } else if (index != 4 && base != 5) { |
477 // [base+index*scale] | 479 // [base+index*scale] |
478 AppendToBuffer("[%s+%s*%d]", | 480 AppendToBuffer("[%s+%s*%d]", |
479 NameOfCPURegister(base), | 481 NameOfCPURegister(base), |
480 NameOfCPURegister(index), | 482 NameOfCPURegister(index), |
481 1 << scale); | 483 1 << scale); |
482 return 2; | 484 return 2; |
483 } else { | 485 } else { |
484 UnimplementedInstruction(); | 486 UnimplementedInstruction(); |
485 return 1; | 487 return 1; |
486 } | 488 } |
487 } else { | 489 } else { |
488 AppendToBuffer("[%s]", NameOfCPURegister(rm)); | 490 AppendToBuffer("[%s]", NameOfCPURegister(rm)); |
489 return 1; | 491 return 1; |
490 } | 492 } |
491 break; | 493 break; |
492 case 1: // fall through | 494 case 1: // fall through |
493 case 2: | 495 case 2: |
494 if ((rm & 7) == 4) { | 496 if ((rm & 7) == 4) { |
495 uint8_t sib = *(modrmp + 1); | 497 uint8_t sib = *(modrmp + 1); |
496 int scale, index, base; | 498 int scale, index, base; |
497 get_sib(sib, &scale, &index, &base); | 499 get_sib(sib, &scale, &index, &base); |
498 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2) | 500 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2) |
499 : *reinterpret_cast<char*>(modrmp + 2); | 501 : *reinterpret_cast<char*>(modrmp + 2); |
500 if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { | 502 if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { |
501 if (-disp > 0) { | 503 AppendToBuffer("[%s", NameOfCPURegister(base)); |
502 AppendToBuffer("[%s-%#x]", NameOfCPURegister(base), -disp); | 504 PrintDisp(disp, "]"); |
503 } else { | |
504 AppendToBuffer("[%s+%#x]", NameOfCPURegister(base), disp); | |
505 } | |
506 } else { | 505 } else { |
507 if (-disp > 0) { | 506 AppendToBuffer("[%s+%s*%d", |
508 AppendToBuffer("[%s+%s*%d-%#x]", | 507 NameOfCPURegister(base), |
509 NameOfCPURegister(base), | 508 NameOfCPURegister(index), |
510 NameOfCPURegister(index), | 509 1 << scale); |
511 1 << scale, | 510 PrintDisp(disp, "]"); |
512 -disp); | |
513 } else { | |
514 AppendToBuffer("[%s+%s*%d+%#x]", | |
515 NameOfCPURegister(base), | |
516 NameOfCPURegister(index), | |
517 1 << scale, | |
518 disp); | |
519 } | |
520 } | 511 } |
521 return mod == 2 ? 6 : 3; | 512 return mod == 2 ? 6 : 3; |
522 } else { | 513 } else { |
523 // No sib. | 514 // No sib. |
524 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1) | 515 int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1) |
525 : *reinterpret_cast<char*>(modrmp + 1); | 516 : *reinterpret_cast<char*>(modrmp + 1); |
526 if (-disp > 0) { | 517 AppendToBuffer("[%s", NameOfCPURegister(rm)); |
527 AppendToBuffer("[%s-%#x]", NameOfCPURegister(rm), -disp); | 518 PrintDisp(disp, "]"); |
528 } else { | |
529 AppendToBuffer("[%s+%#x]", NameOfCPURegister(rm), disp); | |
530 } | |
531 return (mod == 2) ? 5 : 2; | 519 return (mod == 2) ? 5 : 2; |
532 } | 520 } |
533 break; | 521 break; |
534 case 3: | 522 case 3: |
535 AppendToBuffer("%s", (this->*register_name)(rm)); | 523 AppendToBuffer("%s", (this->*register_name)(rm)); |
536 return 1; | 524 return 1; |
537 default: | 525 default: |
538 UnimplementedInstruction(); | 526 UnimplementedInstruction(); |
539 return 1; | 527 return 1; |
540 } | 528 } |
(...skipping 19 matching lines...) Expand all Loading... | |
560 break; | 548 break; |
561 case QUADWORD_SIZE: | 549 case QUADWORD_SIZE: |
562 value = *reinterpret_cast<int32_t*>(data); | 550 value = *reinterpret_cast<int32_t*>(data); |
563 count = 4; | 551 count = 4; |
564 break; | 552 break; |
565 default: | 553 default: |
566 UNREACHABLE(); | 554 UNREACHABLE(); |
567 value = 0; // Initialize variables on all paths to satisfy the compiler. | 555 value = 0; // Initialize variables on all paths to satisfy the compiler. |
568 count = 0; | 556 count = 0; |
569 } | 557 } |
570 AppendToBuffer("%#" Px64 "", value); | 558 PrintImmediateValue(value); |
571 return count; | 559 return count; |
572 } | 560 } |
573 | 561 |
562 void DisassemblerX64::PrintImmediateValue(int64_t value) { | |
563 if (value >= 0 && value <= 9) { | |
regis
2016/04/19 20:59:22
((value >= 0) && (value <= 9))
sra1
2016/04/19 23:32:39
Done.
| |
564 AppendToBuffer("%" Pd64 "", value); | |
565 } else { | |
566 AppendToBuffer("%#" Px64 "", value); | |
567 } | |
568 } | |
569 | |
570 void DisassemblerX64::PrintDisp(int disp, const char* after) { | |
571 if (-disp > 0) { | |
572 AppendToBuffer("-%#x", -disp); | |
573 } else { | |
574 AppendToBuffer("+%#x", disp); | |
575 } | |
576 if (after != NULL) AppendToBuffer("%s", after); | |
577 } | |
578 | |
579 | |
580 | |
574 | 581 |
575 // Returns number of bytes used by machine instruction, including *data byte. | 582 // Returns number of bytes used by machine instruction, including *data byte. |
576 // Writes immediate instructions to 'tmp_buffer_'. | 583 // Writes immediate instructions to 'tmp_buffer_'. |
577 int DisassemblerX64::PrintImmediateOp(uint8_t* data) { | 584 int DisassemblerX64::PrintImmediateOp(uint8_t* data) { |
578 bool byte_size_immediate = (*data & 0x02) != 0; | 585 bool byte_size_immediate = (*data & 0x02) != 0; |
579 uint8_t modrm = *(data + 1); | 586 uint8_t modrm = *(data + 1); |
580 int mod, regop, rm; | 587 int mod, regop, rm; |
581 get_modrm(modrm, &mod, ®op, &rm); | 588 get_modrm(modrm, &mod, ®op, &rm); |
582 const char* mnem = "Imm???"; | 589 const char* mnem = "Imm???"; |
583 switch (regop) { | 590 switch (regop) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
645 UnimplementedInstruction(); | 652 UnimplementedInstruction(); |
646 } | 653 } |
647 AppendToBuffer("%s%c %s", | 654 AppendToBuffer("%s%c %s", |
648 mnem, | 655 mnem, |
649 operand_size_code(), | 656 operand_size_code(), |
650 NameOfCPURegister(rm)); | 657 NameOfCPURegister(rm)); |
651 return 2; | 658 return 2; |
652 } else if (regop == 0) { | 659 } else if (regop == 0) { |
653 AppendToBuffer("test%c ", operand_size_code()); | 660 AppendToBuffer("test%c ", operand_size_code()); |
654 int count = PrintRightOperand(data + 1); // Use name of 64-bit register. | 661 int count = PrintRightOperand(data + 1); // Use name of 64-bit register. |
655 AppendToBuffer(",0x"); | 662 AppendToBuffer(","); |
656 count += PrintImmediate(data + 1 + count, operand_size()); | 663 count += PrintImmediate(data + 1 + count, operand_size()); |
657 return 1 + count; | 664 return 1 + count; |
658 } else { | 665 } else { |
659 UnimplementedInstruction(); | 666 UnimplementedInstruction(); |
660 return 2; | 667 return 2; |
661 } | 668 } |
662 } | 669 } |
663 | 670 |
664 | 671 |
665 int DisassemblerX64::ShiftInstruction(uint8_t* data) { | 672 int DisassemblerX64::ShiftInstruction(uint8_t* data) { |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1600 | 1607 |
1601 | 1608 |
1602 int DisassemblerX64::InstructionDecode(uword pc) { | 1609 int DisassemblerX64::InstructionDecode(uword pc) { |
1603 uint8_t* data = reinterpret_cast<uint8_t*>(pc); | 1610 uint8_t* data = reinterpret_cast<uint8_t*>(pc); |
1604 | 1611 |
1605 const bool processed = DecodeInstructionType(&data); | 1612 const bool processed = DecodeInstructionType(&data); |
1606 | 1613 |
1607 if (!processed) { | 1614 if (!processed) { |
1608 switch (*data) { | 1615 switch (*data) { |
1609 case 0xC2: | 1616 case 0xC2: |
1610 AppendToBuffer("ret %#x", *reinterpret_cast<uint16_t*>(data + 1)); | 1617 AppendToBuffer("ret "); |
1618 PrintImmediateValue(*reinterpret_cast<uint16_t*>(data + 1)); | |
1611 data += 3; | 1619 data += 3; |
1612 break; | 1620 break; |
1613 | 1621 |
1614 case 0xC8: | 1622 case 0xC8: |
1615 AppendToBuffer("enter %d, %d", | 1623 AppendToBuffer("enter %d, %d", |
1616 *reinterpret_cast<uint16_t*>(data + 1), | 1624 *reinterpret_cast<uint16_t*>(data + 1), |
1617 data[3]); | 1625 data[3]); |
1618 data += 4; | 1626 data += 4; |
1619 break; | 1627 break; |
1620 | 1628 |
1621 case 0x69: // fall through | 1629 case 0x69: // fall through |
1622 case 0x6B: { | 1630 case 0x6B: { |
1623 int mod, regop, rm; | 1631 int mod, regop, rm; |
1624 get_modrm(*(data + 1), &mod, ®op, &rm); | 1632 get_modrm(*(data + 1), &mod, ®op, &rm); |
1625 int32_t imm = *data == 0x6B ? *(data + 2) | 1633 int32_t imm = *data == 0x6B ? *(data + 2) |
1626 : *reinterpret_cast<int32_t*>(data + 2); | 1634 : *reinterpret_cast<int32_t*>(data + 2); |
1627 AppendToBuffer("imul%c %s,%s,%#x", | 1635 AppendToBuffer("imul%c %s,%s,", |
1628 operand_size_code(), | 1636 operand_size_code(), |
1629 NameOfCPURegister(regop), | 1637 NameOfCPURegister(regop), |
1630 NameOfCPURegister(rm), imm); | 1638 NameOfCPURegister(rm)); |
1639 PrintImmediateValue(imm); | |
1631 data += 2 + (*data == 0x6B ? 1 : 4); | 1640 data += 2 + (*data == 0x6B ? 1 : 4); |
1632 break; | 1641 break; |
1633 } | 1642 } |
1634 | 1643 |
1635 case 0x81: // fall through | 1644 case 0x81: // fall through |
1636 case 0x83: // 0x81 with sign extension bit set | 1645 case 0x83: // 0x81 with sign extension bit set |
1637 data += PrintImmediateOp(data); | 1646 data += PrintImmediateOp(data); |
1638 break; | 1647 break; |
1639 | 1648 |
1640 case 0x0F: | 1649 case 0x0F: |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1687 | 1696 |
1688 case 0xC7: // imm32, fall through | 1697 case 0xC7: // imm32, fall through |
1689 case 0xC6: // imm8 | 1698 case 0xC6: // imm8 |
1690 { | 1699 { |
1691 bool is_byte = *data == 0xC6; | 1700 bool is_byte = *data == 0xC6; |
1692 data++; | 1701 data++; |
1693 if (is_byte) { | 1702 if (is_byte) { |
1694 AppendToBuffer("movb "); | 1703 AppendToBuffer("movb "); |
1695 data += PrintRightByteOperand(data); | 1704 data += PrintRightByteOperand(data); |
1696 int32_t imm = *data; | 1705 int32_t imm = *data; |
1697 AppendToBuffer(",%#x", imm); | 1706 AppendToBuffer(","); |
1707 PrintImmediateValue(imm); | |
1698 data++; | 1708 data++; |
1699 } else { | 1709 } else { |
1700 AppendToBuffer("mov%c ", operand_size_code()); | 1710 AppendToBuffer("mov%c ", operand_size_code()); |
1701 data += PrintRightOperand(data); | 1711 data += PrintRightOperand(data); |
1702 int32_t imm = *reinterpret_cast<int32_t*>(data); | 1712 int32_t imm = *reinterpret_cast<int32_t*>(data); |
1703 AppendToBuffer(",%#x", imm); | 1713 AppendToBuffer(","); |
1714 PrintImmediateValue(imm); | |
1704 data += 4; | 1715 data += 4; |
1705 } | 1716 } |
1706 } | 1717 } |
1707 break; | 1718 break; |
1708 | 1719 |
1709 case 0x80: { | 1720 case 0x80: { |
1710 data++; | 1721 data++; |
1711 AppendToBuffer("cmpb "); | 1722 AppendToBuffer("cmpb "); |
1712 data += PrintRightByteOperand(data); | 1723 data += PrintRightByteOperand(data); |
1713 int32_t imm = *data; | 1724 int32_t imm = *data; |
1714 AppendToBuffer(",%#x", imm); | 1725 AppendToBuffer(","); |
1726 PrintImmediateValue(imm); | |
1715 data++; | 1727 data++; |
1716 } | 1728 } |
1717 break; | 1729 break; |
1718 | 1730 |
1719 case 0x88: // 8bit, fall through | 1731 case 0x88: // 8bit, fall through |
1720 case 0x89: // 32bit | 1732 case 0x89: // 32bit |
1721 { | 1733 { |
1722 bool is_byte = *data == 0x88; | 1734 bool is_byte = *data == 0x88; |
1723 int mod, regop, rm; | 1735 int mod, regop, rm; |
1724 data++; | 1736 data++; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1769 case 0xBC: | 1781 case 0xBC: |
1770 case 0xBD: | 1782 case 0xBD: |
1771 case 0xBE: | 1783 case 0xBE: |
1772 case 0xBF: { | 1784 case 0xBF: { |
1773 // mov reg8,imm8 or mov reg32,imm32 | 1785 // mov reg8,imm8 or mov reg32,imm32 |
1774 uint8_t opcode = *data; | 1786 uint8_t opcode = *data; |
1775 data++; | 1787 data++; |
1776 uint8_t is_32bit = (opcode >= 0xB8); | 1788 uint8_t is_32bit = (opcode >= 0xB8); |
1777 int reg = (opcode & 0x7) | (rex_b() ? 8 : 0); | 1789 int reg = (opcode & 0x7) | (rex_b() ? 8 : 0); |
1778 if (is_32bit) { | 1790 if (is_32bit) { |
1779 AppendToBuffer("mov%c %s, ", | 1791 AppendToBuffer("mov%c %s,", |
1780 operand_size_code(), | 1792 operand_size_code(), |
1781 NameOfCPURegister(reg)); | 1793 NameOfCPURegister(reg)); |
1782 data += PrintImmediate(data, DOUBLEWORD_SIZE); | 1794 data += PrintImmediate(data, DOUBLEWORD_SIZE); |
1783 } else { | 1795 } else { |
1784 AppendToBuffer("movb %s, ", | 1796 AppendToBuffer("movb %s,", |
1785 NameOfByteCPURegister(reg)); | 1797 NameOfByteCPURegister(reg)); |
1786 data += PrintImmediate(data, BYTE_SIZE); | 1798 data += PrintImmediate(data, BYTE_SIZE); |
1787 } | 1799 } |
1788 break; | 1800 break; |
1789 } | 1801 } |
1790 case 0xFE: { | 1802 case 0xFE: { |
1791 data++; | 1803 data++; |
1792 int mod, regop, rm; | 1804 int mod, regop, rm; |
1793 get_modrm(*data, &mod, ®op, &rm); | 1805 get_modrm(*data, &mod, ®op, &rm); |
1794 if (regop == 1) { | 1806 if (regop == 1) { |
1795 AppendToBuffer("decb "); | 1807 AppendToBuffer("decb "); |
1796 data += PrintRightByteOperand(data); | 1808 data += PrintRightByteOperand(data); |
1797 } else { | 1809 } else { |
1798 UnimplementedInstruction(); | 1810 UnimplementedInstruction(); |
1799 } | 1811 } |
1800 break; | 1812 break; |
1801 } | 1813 } |
1802 case 0x68: | 1814 case 0x68: |
1803 AppendToBuffer("push %#x", *reinterpret_cast<int32_t*>(data + 1)); | 1815 AppendToBuffer("push "); |
1816 PrintImmediateValue(*reinterpret_cast<int32_t*>(data + 1)); | |
1804 data += 5; | 1817 data += 5; |
1805 break; | 1818 break; |
1806 | 1819 |
1807 case 0x6A: | 1820 case 0x6A: |
1808 AppendToBuffer("push %#x", *reinterpret_cast<int8_t*>(data + 1)); | 1821 AppendToBuffer("push "); |
1822 PrintImmediateValue(*reinterpret_cast<int8_t*>(data + 1)); | |
1809 data += 2; | 1823 data += 2; |
1810 break; | 1824 break; |
1811 | 1825 |
1812 case 0xA1: // Fall through. | 1826 case 0xA1: // Fall through. |
1813 case 0xA3: | 1827 case 0xA3: |
1814 switch (operand_size()) { | 1828 switch (operand_size()) { |
1815 case DOUBLEWORD_SIZE: { | 1829 case DOUBLEWORD_SIZE: { |
1816 AppendAddressToBuffer( | 1830 AppendAddressToBuffer( |
1817 reinterpret_cast<uint8_t*>( | 1831 reinterpret_cast<uint8_t*>( |
1818 *reinterpret_cast<int32_t*>(data + 1))); | 1832 *reinterpret_cast<int32_t*>(data + 1))); |
(...skipping 27 matching lines...) Expand all Loading... | |
1846 data += 9; | 1860 data += 9; |
1847 break; | 1861 break; |
1848 } | 1862 } |
1849 default: | 1863 default: |
1850 UnimplementedInstruction(); | 1864 UnimplementedInstruction(); |
1851 data += 2; | 1865 data += 2; |
1852 } | 1866 } |
1853 break; | 1867 break; |
1854 | 1868 |
1855 case 0xA8: | 1869 case 0xA8: |
1856 AppendToBuffer("test al,%#x", *reinterpret_cast<uint8_t*>(data + 1)); | 1870 AppendToBuffer("test al,"); |
1871 PrintImmediateValue(*reinterpret_cast<uint8_t*>(data + 1)); | |
1857 data += 2; | 1872 data += 2; |
1858 break; | 1873 break; |
1859 | 1874 |
1860 case 0xA9: { | 1875 case 0xA9: { |
1861 int64_t value = 0; | 1876 int64_t value = 0; |
1862 switch (operand_size()) { | 1877 switch (operand_size()) { |
1863 case WORD_SIZE: | 1878 case WORD_SIZE: |
1864 value = *reinterpret_cast<uint16_t*>(data + 1); | 1879 value = *reinterpret_cast<uint16_t*>(data + 1); |
1865 data += 3; | 1880 data += 3; |
1866 break; | 1881 break; |
1867 case DOUBLEWORD_SIZE: | 1882 case DOUBLEWORD_SIZE: |
1868 value = *reinterpret_cast<uint32_t*>(data + 1); | 1883 value = *reinterpret_cast<uint32_t*>(data + 1); |
1869 data += 5; | 1884 data += 5; |
1870 break; | 1885 break; |
1871 case QUADWORD_SIZE: | 1886 case QUADWORD_SIZE: |
1872 value = *reinterpret_cast<int32_t*>(data + 1); | 1887 value = *reinterpret_cast<int32_t*>(data + 1); |
1873 data += 5; | 1888 data += 5; |
1874 break; | 1889 break; |
1875 default: | 1890 default: |
1876 UNREACHABLE(); | 1891 UNREACHABLE(); |
1877 } | 1892 } |
1878 AppendToBuffer("test%c rax,%#" Px64 "", | 1893 AppendToBuffer("test%c rax,", operand_size_code()); |
1879 operand_size_code(), | 1894 PrintImmediateValue(value); |
1880 value); | |
1881 break; | 1895 break; |
1882 } | 1896 } |
1883 case 0xD1: // fall through | 1897 case 0xD1: // fall through |
1884 case 0xD3: // fall through | 1898 case 0xD3: // fall through |
1885 case 0xC1: | 1899 case 0xC1: |
1886 data += ShiftInstruction(data); | 1900 data += ShiftInstruction(data); |
1887 break; | 1901 break; |
1888 case 0xD0: // fall through | 1902 case 0xD0: // fall through |
1889 case 0xD2: // fall through | 1903 case 0xD2: // fall through |
1890 case 0xC0: | 1904 case 0xC0: |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1946 if (out_instr_len) { | 1960 if (out_instr_len) { |
1947 *out_instr_len = instruction_length; | 1961 *out_instr_len = instruction_length; |
1948 } | 1962 } |
1949 } | 1963 } |
1950 | 1964 |
1951 #endif // !PRODUCT | 1965 #endif // !PRODUCT |
1952 | 1966 |
1953 } // namespace dart | 1967 } // namespace dart |
1954 | 1968 |
1955 #endif // defined TARGET_ARCH_X64 | 1969 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |