OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // A Disassembler object is used to disassemble a block of code instruction by | 5 // A Disassembler object is used to disassemble a block of code instruction by |
6 // instruction. The default implementation of the NameConverter object can be | 6 // instruction. The default implementation of the NameConverter object can be |
7 // overriden to modify register names or to do symbol lookup on addresses. | 7 // overriden to modify register names or to do symbol lookup on addresses. |
8 // | 8 // |
9 // The example below will disassemble a block of code and print it to stdout. | 9 // The example below will disassemble a block of code and print it to stdout. |
10 // | 10 // |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 void PrintSecondaryField(Instruction* instr); | 85 void PrintSecondaryField(Instruction* instr); |
86 void PrintUImm16(Instruction* instr); | 86 void PrintUImm16(Instruction* instr); |
87 void PrintSImm16(Instruction* instr); | 87 void PrintSImm16(Instruction* instr); |
88 void PrintXImm16(Instruction* instr); | 88 void PrintXImm16(Instruction* instr); |
89 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits); | 89 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits); |
90 void PrintXImm18(Instruction* instr); | 90 void PrintXImm18(Instruction* instr); |
91 void PrintSImm18(Instruction* instr); | 91 void PrintSImm18(Instruction* instr); |
92 void PrintXImm19(Instruction* instr); | 92 void PrintXImm19(Instruction* instr); |
93 void PrintSImm19(Instruction* instr); | 93 void PrintSImm19(Instruction* instr); |
94 void PrintXImm21(Instruction* instr); | 94 void PrintXImm21(Instruction* instr); |
95 | 95 void PrintSImm21(Instruction* instr); |
96 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits); | 96 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits); |
97 void PrintXImm26(Instruction* instr); | 97 void PrintXImm26(Instruction* instr); |
98 void PrintSImm26(Instruction* instr); | 98 void PrintSImm26(Instruction* instr); |
99 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits); | 99 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits); |
100 void PrintPCImm26(Instruction* instr); | 100 void PrintPCImm26(Instruction* instr); |
101 void PrintCode(Instruction* instr); // For break and trap instructions. | 101 void PrintCode(Instruction* instr); // For break and trap instructions. |
102 void PrintFormat(Instruction* instr); // For floating format postfix. | 102 void PrintFormat(Instruction* instr); // For floating format postfix. |
103 void PrintBp2(Instruction* instr); | 103 void PrintBp2(Instruction* instr); |
104 void PrintBp3(Instruction* instr); | 104 void PrintBp3(Instruction* instr); |
105 // Printing of instruction name. | 105 // Printing of instruction name. |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 } | 338 } |
339 | 339 |
340 | 340 |
341 // Print 21-bit immediate value. | 341 // Print 21-bit immediate value. |
342 void Decoder::PrintXImm21(Instruction* instr) { | 342 void Decoder::PrintXImm21(Instruction* instr) { |
343 uint32_t imm = instr->Imm21Value(); | 343 uint32_t imm = instr->Imm21Value(); |
344 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 344 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
345 } | 345 } |
346 | 346 |
347 | 347 |
| 348 // Print 21-bit signed immediate value. |
| 349 void Decoder::PrintSImm21(Instruction* instr) { |
| 350 int32_t imm21 = instr->Imm21Value(); |
| 351 // set sign |
| 352 imm21 <<= (32 - kImm21Bits); |
| 353 imm21 >>= (32 - kImm21Bits); |
| 354 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm21); |
| 355 } |
| 356 |
| 357 |
348 // Print absoulte address for 21-bit offset or immediate value. | 358 // Print absoulte address for 21-bit offset or immediate value. |
349 // The absolute address is calculated according following expression: | 359 // The absolute address is calculated according following expression: |
350 // PC + delta_pc + (offset << n_bits) | 360 // PC + delta_pc + (offset << n_bits) |
351 void Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) { | 361 void Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) { |
352 int32_t imm21 = instr->Imm21Value(); | 362 int32_t imm21 = instr->Imm21Value(); |
353 // set sign | 363 // set sign |
354 imm21 <<= (32 - kImm21Bits); | 364 imm21 <<= (32 - kImm21Bits); |
355 imm21 >>= (32 - kImm21Bits); | 365 imm21 >>= (32 - kImm21Bits); |
356 out_buffer_pos_ += | 366 out_buffer_pos_ += |
357 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", | 367 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 case 'x': | 625 case 'x': |
616 DCHECK(STRING_STARTS_WITH(format, "imm19x")); | 626 DCHECK(STRING_STARTS_WITH(format, "imm19x")); |
617 PrintXImm19(instr); | 627 PrintXImm19(instr); |
618 break; | 628 break; |
619 } | 629 } |
620 return 6; | 630 return 6; |
621 } | 631 } |
622 } else if (format[3] == '2' && format[4] == '1') { | 632 } else if (format[3] == '2' && format[4] == '1') { |
623 DCHECK(STRING_STARTS_WITH(format, "imm21")); | 633 DCHECK(STRING_STARTS_WITH(format, "imm21")); |
624 switch (format[5]) { | 634 switch (format[5]) { |
| 635 case 's': |
| 636 DCHECK(STRING_STARTS_WITH(format, "imm21s")); |
| 637 PrintSImm21(instr); |
| 638 break; |
625 case 'x': | 639 case 'x': |
626 DCHECK(STRING_STARTS_WITH(format, "imm21x")); | 640 DCHECK(STRING_STARTS_WITH(format, "imm21x")); |
627 PrintXImm21(instr); | 641 PrintXImm21(instr); |
628 break; | 642 break; |
629 case 'p': { // The PC relative address. | 643 case 'p': { // The PC relative address. |
630 DCHECK(STRING_STARTS_WITH(format, "imm21p")); | 644 DCHECK(STRING_STARTS_WITH(format, "imm21p")); |
631 int delta_pc = 0; | 645 int delta_pc = 0; |
632 int n_bits = 0; | 646 int n_bits = 0; |
633 switch (format[6]) { | 647 switch (format[6]) { |
634 case '4': { | 648 case '4': { |
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1618 Format(instr, "balc 'imm26s -> 'imm26p4s2"); | 1632 Format(instr, "balc 'imm26s -> 'imm26p4s2"); |
1619 break; | 1633 break; |
1620 case BNE: | 1634 case BNE: |
1621 Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2"); | 1635 Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1622 break; | 1636 break; |
1623 case BLEZ: | 1637 case BLEZ: |
1624 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { | 1638 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { |
1625 Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2"); | 1639 Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2"); |
1626 } else if ((instr->RtValue() != instr->RsValue()) && | 1640 } else if ((instr->RtValue() != instr->RsValue()) && |
1627 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { | 1641 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1628 Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); | 1642 Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1629 } else if ((instr->RtValue() == instr->RsValue()) && | 1643 } else if ((instr->RtValue() == instr->RsValue()) && |
1630 (instr->RtValue() != 0)) { | 1644 (instr->RtValue() != 0)) { |
1631 Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2"); | 1645 Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2"); |
1632 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { | 1646 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
1633 Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2"); | 1647 Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2"); |
1634 } else { | 1648 } else { |
1635 UNREACHABLE(); | 1649 UNREACHABLE(); |
1636 } | 1650 } |
1637 break; | 1651 break; |
1638 case BGTZ: | 1652 case BGTZ: |
1639 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { | 1653 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { |
1640 Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2"); | 1654 Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2"); |
1641 } else if ((instr->RtValue() != instr->RsValue()) && | 1655 } else if ((instr->RtValue() != instr->RsValue()) && |
1642 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { | 1656 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1643 Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); | 1657 Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
(...skipping 16 matching lines...) Expand all Loading... |
1660 Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2"); | 1674 Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2"); |
1661 } else { | 1675 } else { |
1662 UNREACHABLE(); | 1676 UNREACHABLE(); |
1663 } | 1677 } |
1664 break; | 1678 break; |
1665 case BGTZL: | 1679 case BGTZL: |
1666 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { | 1680 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { |
1667 Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2"); | 1681 Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2"); |
1668 } else if ((instr->RtValue() != instr->RsValue()) && | 1682 } else if ((instr->RtValue() != instr->RsValue()) && |
1669 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { | 1683 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1670 Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); | 1684 Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1671 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { | 1685 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
1672 Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2"); | 1686 Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2"); |
1673 } else { | 1687 } else { |
1674 UNREACHABLE(); | 1688 UNREACHABLE(); |
1675 } | 1689 } |
1676 break; | 1690 break; |
1677 case POP66: | 1691 case POP66: |
1678 if (instr->RsValue() == JIC) { | 1692 if (instr->RsValue() == JIC) { |
1679 Format(instr, "jic 'rt, 'imm16s"); | 1693 Format(instr, "jic 'rt, 'imm16s"); |
1680 } else { | 1694 } else { |
1681 Format(instr, "beqzc 'rs, 'imm21x -> 'imm21p4s2"); | 1695 Format(instr, "beqzc 'rs, 'imm21s -> 'imm21p4s2"); |
1682 } | 1696 } |
1683 break; | 1697 break; |
1684 case POP76: | 1698 case POP76: |
1685 if (instr->RsValue() == JIALC) { | 1699 if (instr->RsValue() == JIALC) { |
1686 Format(instr, "jialc 'rt, 'imm16x"); | 1700 Format(instr, "jialc 'rt, 'imm16s"); |
1687 } else { | 1701 } else { |
1688 Format(instr, "bnezc 'rs, 'imm21x -> 'imm21p4s2"); | 1702 Format(instr, "bnezc 'rs, 'imm21s -> 'imm21p4s2"); |
1689 } | 1703 } |
1690 break; | 1704 break; |
1691 // ------------- Arithmetic instructions. | 1705 // ------------- Arithmetic instructions. |
1692 case ADDI: | 1706 case ADDI: |
1693 if (kArchVariant != kMips64r6) { | 1707 if (kArchVariant != kMips64r6) { |
1694 Format(instr, "addi 'rt, 'rs, 'imm16s"); | 1708 Format(instr, "addi 'rt, 'rs, 'imm16s"); |
1695 } else { | 1709 } else { |
1696 // Check if BOVC or BEQC instruction. | 1710 int rs_reg = instr->RsValue(); |
1697 if (instr->RsValue() >= instr->RtValue()) { | 1711 int rt_reg = instr->RtValue(); |
| 1712 // Check if BOVC, BEQZALC or BEQC instruction. |
| 1713 if (rs_reg >= rt_reg) { |
1698 Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); | 1714 Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
1699 } else if (instr->RsValue() < instr->RtValue()) { | |
1700 Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); | |
1701 } else { | 1715 } else { |
1702 UNREACHABLE(); | 1716 DCHECK(rt_reg > 0); |
| 1717 if (rs_reg == 0) { |
| 1718 Format(instr, "beqzalc 'rt, 'imm16s -> 'imm16p4s2"); |
| 1719 } else { |
| 1720 Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
| 1721 } |
1703 } | 1722 } |
1704 } | 1723 } |
1705 break; | 1724 break; |
1706 case DADDI: | 1725 case DADDI: |
1707 if (kArchVariant != kMips64r6) { | 1726 if (kArchVariant != kMips64r6) { |
1708 Format(instr, "daddi 'rt, 'rs, 'imm16s"); | 1727 Format(instr, "daddi 'rt, 'rs, 'imm16s"); |
1709 } else { | 1728 } else { |
1710 // Check if BNVC or BNEC instruction. | 1729 int rs_reg = instr->RsValue(); |
1711 if (instr->RsValue() >= instr->RtValue()) { | 1730 int rt_reg = instr->RtValue(); |
| 1731 // Check if BNVC, BNEZALC or BNEC instruction. |
| 1732 if (rs_reg >= rt_reg) { |
1712 Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); | 1733 Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
1713 } else if (instr->RsValue() < instr->RtValue()) { | |
1714 Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2"); | |
1715 } else { | 1734 } else { |
1716 UNREACHABLE(); | 1735 DCHECK(rt_reg > 0); |
| 1736 if (rs_reg == 0) { |
| 1737 Format(instr, "bnezalc 'rt, 'imm16s -> 'imm16p4s2"); |
| 1738 } else { |
| 1739 Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
| 1740 } |
1717 } | 1741 } |
1718 } | 1742 } |
1719 break; | 1743 break; |
1720 case ADDIU: | 1744 case ADDIU: |
1721 Format(instr, "addiu 'rt, 'rs, 'imm16s"); | 1745 Format(instr, "addiu 'rt, 'rs, 'imm16s"); |
1722 break; | 1746 break; |
1723 case DADDIU: | 1747 case DADDIU: |
1724 Format(instr, "daddiu 'rt, 'rs, 'imm16s"); | 1748 Format(instr, "daddiu 'rt, 'rs, 'imm16s"); |
1725 break; | 1749 break; |
1726 case SLTI: | 1750 case SLTI: |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1991 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 2015 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1992 } | 2016 } |
1993 } | 2017 } |
1994 | 2018 |
1995 | 2019 |
1996 #undef UNSUPPORTED | 2020 #undef UNSUPPORTED |
1997 | 2021 |
1998 } // namespace disasm | 2022 } // namespace disasm |
1999 | 2023 |
2000 #endif // V8_TARGET_ARCH_MIPS64 | 2024 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |