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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 void PrintSecondaryField(Instruction* instr); | 84 void PrintSecondaryField(Instruction* instr); |
85 void PrintUImm16(Instruction* instr); | 85 void PrintUImm16(Instruction* instr); |
86 void PrintSImm16(Instruction* instr); | 86 void PrintSImm16(Instruction* instr); |
87 void PrintXImm16(Instruction* instr); | 87 void PrintXImm16(Instruction* instr); |
88 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits); | 88 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits); |
89 void PrintXImm18(Instruction* instr); | 89 void PrintXImm18(Instruction* instr); |
90 void PrintSImm18(Instruction* instr); | 90 void PrintSImm18(Instruction* instr); |
91 void PrintXImm19(Instruction* instr); | 91 void PrintXImm19(Instruction* instr); |
92 void PrintSImm19(Instruction* instr); | 92 void PrintSImm19(Instruction* instr); |
93 void PrintXImm21(Instruction* instr); | 93 void PrintXImm21(Instruction* instr); |
94 | 94 void PrintSImm21(Instruction* instr); |
95 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits); | 95 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits); |
96 void PrintXImm26(Instruction* instr); | 96 void PrintXImm26(Instruction* instr); |
97 void PrintSImm26(Instruction* instr); | 97 void PrintSImm26(Instruction* instr); |
98 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits); | 98 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits); |
99 void PrintPCImm26(Instruction* instr); | 99 void PrintPCImm26(Instruction* instr); |
100 void PrintCode(Instruction* instr); // For break and trap instructions. | 100 void PrintCode(Instruction* instr); // For break and trap instructions. |
101 void PrintFormat(Instruction* instr); // For floating format postfix. | 101 void PrintFormat(Instruction* instr); // For floating format postfix. |
102 void PrintBp2(Instruction* instr); | 102 void PrintBp2(Instruction* instr); |
103 void PrintBp3(Instruction* instr); | 103 void PrintBp3(Instruction* instr); |
104 // Printing of instruction name. | 104 // Printing of instruction name. |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
330 } | 330 } |
331 | 331 |
332 | 332 |
333 // Print 21-bit immediate value. | 333 // Print 21-bit immediate value. |
334 void Decoder::PrintXImm21(Instruction* instr) { | 334 void Decoder::PrintXImm21(Instruction* instr) { |
335 uint32_t imm = instr->Imm21Value(); | 335 uint32_t imm = instr->Imm21Value(); |
336 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 336 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
337 } | 337 } |
338 | 338 |
339 | 339 |
340 // Print 21-bit signed immediate value. | |
341 void Decoder::PrintSImm21(Instruction* instr) { | |
342 int32_t imm21 = instr->Imm21Value(); | |
343 // set sign | |
344 imm21 <<= (32 - kImm21Bits); | |
345 imm21 >>= (32 - kImm21Bits); | |
346 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm21); | |
347 } | |
348 | |
349 | |
340 // Print absoulte address for 21-bit offset or immediate value. | 350 // Print absoulte address for 21-bit offset or immediate value. |
341 // The absolute address is calculated according following expression: | 351 // The absolute address is calculated according following expression: |
342 // PC + delta_pc + (offset << n_bits) | 352 // PC + delta_pc + (offset << n_bits) |
343 void Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) { | 353 void Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) { |
344 int32_t imm21 = instr->Imm21Value(); | 354 int32_t imm21 = instr->Imm21Value(); |
345 // set sign | 355 // set sign |
346 imm21 <<= (32 - kImm21Bits); | 356 imm21 <<= (32 - kImm21Bits); |
347 imm21 >>= (32 - kImm21Bits); | 357 imm21 >>= (32 - kImm21Bits); |
348 out_buffer_pos_ += | 358 out_buffer_pos_ += |
349 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", | 359 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
607 case 'x': | 617 case 'x': |
608 DCHECK(STRING_STARTS_WITH(format, "imm19x")); | 618 DCHECK(STRING_STARTS_WITH(format, "imm19x")); |
609 PrintXImm19(instr); | 619 PrintXImm19(instr); |
610 break; | 620 break; |
611 } | 621 } |
612 return 6; | 622 return 6; |
613 } | 623 } |
614 } else if (format[3] == '2' && format[4] == '1') { | 624 } else if (format[3] == '2' && format[4] == '1') { |
615 DCHECK(STRING_STARTS_WITH(format, "imm21")); | 625 DCHECK(STRING_STARTS_WITH(format, "imm21")); |
616 switch (format[5]) { | 626 switch (format[5]) { |
627 case 's': | |
628 DCHECK(STRING_STARTS_WITH(format, "imm21s")); | |
629 PrintSImm21(instr); | |
630 break; | |
617 case 'x': | 631 case 'x': |
618 DCHECK(STRING_STARTS_WITH(format, "imm21x")); | 632 DCHECK(STRING_STARTS_WITH(format, "imm21x")); |
619 PrintXImm21(instr); | 633 PrintXImm21(instr); |
620 break; | 634 break; |
621 case 'p': { // The PC relative address. | 635 case 'p': { // The PC relative address. |
622 DCHECK(STRING_STARTS_WITH(format, "imm21p")); | 636 DCHECK(STRING_STARTS_WITH(format, "imm21p")); |
623 int delta_pc = 0; | 637 int delta_pc = 0; |
624 int n_bits = 0; | 638 int n_bits = 0; |
625 switch (format[6]) { | 639 switch (format[6]) { |
626 case '4': { | 640 case '4': { |
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1598 Format(instr, "balc 'imm26s -> 'imm26p4s2"); | 1612 Format(instr, "balc 'imm26s -> 'imm26p4s2"); |
1599 break; | 1613 break; |
1600 case BNE: | 1614 case BNE: |
1601 Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2"); | 1615 Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1602 break; | 1616 break; |
1603 case BLEZ: | 1617 case BLEZ: |
1604 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { | 1618 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { |
1605 Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2"); | 1619 Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2"); |
1606 } else if ((instr->RtValue() != instr->RsValue()) && | 1620 } else if ((instr->RtValue() != instr->RsValue()) && |
1607 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { | 1621 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1608 Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); | 1622 Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1609 } else if ((instr->RtValue() == instr->RsValue()) && | 1623 } else if ((instr->RtValue() == instr->RsValue()) && |
1610 (instr->RtValue() != 0)) { | 1624 (instr->RtValue() != 0)) { |
1611 Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2"); | 1625 Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2"); |
1612 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { | 1626 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
1613 Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2"); | 1627 Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2"); |
1614 } else { | 1628 } else { |
1615 UNREACHABLE(); | 1629 UNREACHABLE(); |
1616 } | 1630 } |
1617 break; | 1631 break; |
1618 case BGTZ: | 1632 case BGTZ: |
1619 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { | 1633 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { |
1620 Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2"); | 1634 Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2"); |
1621 } else if ((instr->RtValue() != instr->RsValue()) && | 1635 } else if ((instr->RtValue() != instr->RsValue()) && |
1622 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { | 1636 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1623 Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); | 1637 Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
(...skipping 16 matching lines...) Expand all Loading... | |
1640 Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2"); | 1654 Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2"); |
1641 } else { | 1655 } else { |
1642 UNREACHABLE(); | 1656 UNREACHABLE(); |
1643 } | 1657 } |
1644 break; | 1658 break; |
1645 case BGTZL: | 1659 case BGTZL: |
1646 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { | 1660 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { |
1647 Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2"); | 1661 Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2"); |
1648 } else if ((instr->RtValue() != instr->RsValue()) && | 1662 } else if ((instr->RtValue() != instr->RsValue()) && |
1649 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { | 1663 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1650 Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); | 1664 Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1651 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { | 1665 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
1652 Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2"); | 1666 Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2"); |
1653 } else { | 1667 } else { |
1654 UNREACHABLE(); | 1668 UNREACHABLE(); |
1655 } | 1669 } |
1656 break; | 1670 break; |
1657 case POP66: | 1671 case POP66: |
1658 if (instr->RsValue() == JIC) { | 1672 if (instr->RsValue() == JIC) { |
1659 Format(instr, "jic 'rt, 'imm16s"); | 1673 Format(instr, "jic 'rt, 'imm16s"); |
1660 } else { | 1674 } else { |
1661 Format(instr, "beqzc 'rs, 'imm21x -> 'imm21p4s2"); | 1675 Format(instr, "beqzc 'rs, 'imm21s -> 'imm21p4s2"); |
1662 } | 1676 } |
1663 break; | 1677 break; |
1664 case POP76: | 1678 case POP76: |
1665 if (instr->RsValue() == JIALC) { | 1679 if (instr->RsValue() == JIALC) { |
1666 Format(instr, "jialc 'rt, 'imm16x"); | 1680 Format(instr, "jialc 'rt, 'imm16s"); |
1667 } else { | 1681 } else { |
1668 Format(instr, "bnezc 'rs, 'imm21x -> 'imm21p4s2"); | 1682 Format(instr, "bnezc 'rs, 'imm21s -> 'imm21p4s2"); |
1669 } | 1683 } |
1670 break; | 1684 break; |
1671 // ------------- Arithmetic instructions. | 1685 // ------------- Arithmetic instructions. |
1672 case ADDI: | 1686 case ADDI: |
1673 if (kArchVariant != kMips64r6) { | 1687 if (kArchVariant != kMips64r6) { |
1674 Format(instr, "addi 'rt, 'rs, 'imm16s"); | 1688 Format(instr, "addi 'rt, 'rs, 'imm16s"); |
1675 } else { | 1689 } else { |
1676 // Check if BOVC or BEQC instruction. | 1690 int rs_reg = instr->RsValue(); |
1677 if (instr->RsValue() >= instr->RtValue()) { | 1691 int rt_reg = instr->RtValue(); |
1692 // Check if BOVC, BEQZALC or BEQC instruction. | |
1693 if (rs_reg >= rt_reg) { | |
1678 Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); | 1694 Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
1679 } else if (instr->RsValue() < instr->RtValue()) { | |
1680 Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); | |
1681 } else { | 1695 } else { |
Ilija.Pavlovic1
2015/12/18 11:38:22
One of conditions is (rt_reg != 0):
if (rt_reg !=
balazs.kilvady
2015/12/18 19:18:05
One more thing to backport...
ivica.bogosavljevic
2015/12/22 10:22:40
I'll add DCHECK(rt_reg > 0) before if (rs_reg == 0
ivica.bogosavljevic
2015/12/22 10:22:40
Acknowledged.
| |
1682 UNREACHABLE(); | 1696 if (rs_reg == 0) { |
1697 Format(instr, "beqzalc 'rt, 'imm16s -> 'imm16p4s2"); | |
1698 } else { | |
1699 Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); | |
1700 } | |
1683 } | 1701 } |
1684 } | 1702 } |
1685 break; | 1703 break; |
1686 case DADDI: | 1704 case DADDI: |
1687 if (kArchVariant != kMips64r6) { | 1705 if (kArchVariant != kMips64r6) { |
1688 Format(instr, "daddi 'rt, 'rs, 'imm16s"); | 1706 Format(instr, "daddi 'rt, 'rs, 'imm16s"); |
1689 } else { | 1707 } else { |
1690 // Check if BNVC or BNEC instruction. | 1708 int rs_reg = instr->RsValue(); |
1691 if (instr->RsValue() >= instr->RtValue()) { | 1709 int rt_reg = instr->RtValue(); |
1710 // Check if BNVC, BNEZALC or BNEC instruction. | |
1711 if (rs_reg >= rt_reg) { | |
1692 Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); | 1712 Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
1693 } else if (instr->RsValue() < instr->RtValue()) { | |
1694 Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2"); | |
1695 } else { | 1713 } else { |
Ilija.Pavlovic1
2015/12/18 11:38:22
One of conditions is (rt_reg != 0):
if (rt_reg !=
ivica.bogosavljevic
2015/12/22 10:22:40
I'll add DCHECK(rt_reg > 0) before if (rs_reg == 0
| |
1696 UNREACHABLE(); | 1714 if (rs_reg == 0) { |
1715 Format(instr, "bnezalc 'rt, 'imm16s -> 'imm16p4s2"); | |
1716 } else { | |
1717 Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2"); | |
1718 } | |
1697 } | 1719 } |
1698 } | 1720 } |
1699 break; | 1721 break; |
1700 case ADDIU: | 1722 case ADDIU: |
1701 Format(instr, "addiu 'rt, 'rs, 'imm16s"); | 1723 Format(instr, "addiu 'rt, 'rs, 'imm16s"); |
1702 break; | 1724 break; |
1703 case DADDIU: | 1725 case DADDIU: |
1704 Format(instr, "daddiu 'rt, 'rs, 'imm16s"); | 1726 Format(instr, "daddiu 'rt, 'rs, 'imm16s"); |
1705 break; | 1727 break; |
1706 case SLTI: | 1728 case SLTI: |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1971 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1993 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1972 } | 1994 } |
1973 } | 1995 } |
1974 | 1996 |
1975 | 1997 |
1976 #undef UNSUPPORTED | 1998 #undef UNSUPPORTED |
1977 | 1999 |
1978 } // namespace disasm | 2000 } // namespace disasm |
1979 | 2001 |
1980 #endif // V8_TARGET_ARCH_MIPS64 | 2002 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |