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 PrintRt(Instruction* instr); | 85 void PrintRt(Instruction* instr); |
86 void PrintRd(Instruction* instr); | 86 void PrintRd(Instruction* instr); |
87 void PrintFs(Instruction* instr); | 87 void PrintFs(Instruction* instr); |
88 void PrintFt(Instruction* instr); | 88 void PrintFt(Instruction* instr); |
89 void PrintFd(Instruction* instr); | 89 void PrintFd(Instruction* instr); |
90 void PrintSa(Instruction* instr); | 90 void PrintSa(Instruction* instr); |
91 void PrintLsaSa(Instruction* instr); | 91 void PrintLsaSa(Instruction* instr); |
92 void PrintSd(Instruction* instr); | 92 void PrintSd(Instruction* instr); |
93 void PrintSs1(Instruction* instr); | 93 void PrintSs1(Instruction* instr); |
94 void PrintSs2(Instruction* instr); | 94 void PrintSs2(Instruction* instr); |
| 95 void PrintSs3(Instruction* instr); |
| 96 void PrintSs4(Instruction* instr); |
| 97 void PrintSs5(Instruction* instr); |
95 void PrintBc(Instruction* instr); | 98 void PrintBc(Instruction* instr); |
96 void PrintCc(Instruction* instr); | 99 void PrintCc(Instruction* instr); |
97 void PrintFunction(Instruction* instr); | 100 void PrintFunction(Instruction* instr); |
98 void PrintSecondaryField(Instruction* instr); | 101 void PrintSecondaryField(Instruction* instr); |
99 void PrintUImm16(Instruction* instr); | 102 void PrintUImm16(Instruction* instr); |
100 void PrintSImm16(Instruction* instr); | 103 void PrintSImm16(Instruction* instr); |
101 void PrintXImm16(Instruction* instr); | 104 void PrintXImm16(Instruction* instr); |
102 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits); | 105 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits); |
103 void PrintXImm18(Instruction* instr); | 106 void PrintXImm18(Instruction* instr); |
104 void PrintSImm18(Instruction* instr); | 107 void PrintSImm18(Instruction* instr); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa); | 285 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa); |
283 } | 286 } |
284 | 287 |
285 | 288 |
286 // Print the integer value of the rd field, when it is not used as reg. | 289 // Print the integer value of the rd field, when it is not used as reg. |
287 void Decoder::PrintSd(Instruction* instr) { | 290 void Decoder::PrintSd(Instruction* instr) { |
288 int sd = instr->RdValue(); | 291 int sd = instr->RdValue(); |
289 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sd); | 292 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sd); |
290 } | 293 } |
291 | 294 |
| 295 // Print the integer value of ext/dext/dextu size from the msbd field. |
| 296 void Decoder::PrintSs1(Instruction* instr) { |
| 297 int msbd = instr->RdValue(); |
| 298 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", msbd + 1); |
| 299 } |
292 | 300 |
293 // Print the integer value of the rd field, when used as 'ext' size. | 301 // Print the integer value of ins/dins/dinsu size from the msb and lsb fields |
294 void Decoder::PrintSs1(Instruction* instr) { | 302 // (for dinsu it is msbminus32 and lsbminus32 fields). |
295 int ss = instr->RdValue(); | 303 void Decoder::PrintSs2(Instruction* instr) { |
296 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss + 1); | 304 int msb = instr->RdValue(); |
| 305 int lsb = instr->SaValue(); |
| 306 out_buffer_pos_ += |
| 307 SNPrintF(out_buffer_ + out_buffer_pos_, "%d", msb - lsb + 1); |
| 308 } |
| 309 |
| 310 // Print the integer value of dextm size from the msbdminus32 field. |
| 311 void Decoder::PrintSs3(Instruction* instr) { |
| 312 int msbdminus32 = instr->RdValue(); |
| 313 out_buffer_pos_ += |
| 314 SNPrintF(out_buffer_ + out_buffer_pos_, "%d", msbdminus32 + 32 + 1); |
| 315 } |
| 316 |
| 317 // Print the integer value of dinsm size from the msbminus32 and lsb fields. |
| 318 void Decoder::PrintSs4(Instruction* instr) { |
| 319 int msbminus32 = instr->RdValue(); |
| 320 int lsb = instr->SaValue(); |
| 321 out_buffer_pos_ += |
| 322 SNPrintF(out_buffer_ + out_buffer_pos_, "%d", msbminus32 + 32 - lsb + 1); |
| 323 } |
| 324 |
| 325 // Print the integer value of dextu/dinsu pos from the lsbminus32 field. |
| 326 void Decoder::PrintSs5(Instruction* instr) { |
| 327 int lsbminus32 = instr->SaValue(); |
| 328 out_buffer_pos_ += |
| 329 SNPrintF(out_buffer_ + out_buffer_pos_, "%d", lsbminus32 + 32); |
297 } | 330 } |
298 | 331 |
299 | 332 |
300 // Print the integer value of the rd field, when used as 'ins' size. | |
301 void Decoder::PrintSs2(Instruction* instr) { | |
302 int ss = instr->RdValue(); | |
303 int pos = instr->SaValue(); | |
304 out_buffer_pos_ += | |
305 SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss - pos + 1); | |
306 } | |
307 | |
308 | |
309 // Print the integer value of the cc field for the bc1t/f instructions. | 333 // Print the integer value of the cc field for the bc1t/f instructions. |
310 void Decoder::PrintBc(Instruction* instr) { | 334 void Decoder::PrintBc(Instruction* instr) { |
311 int cc = instr->FBccValue(); | 335 int cc = instr->FBccValue(); |
312 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", cc); | 336 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", cc); |
313 } | 337 } |
314 | 338 |
315 | 339 |
316 // Print the integer value of the cc field for the FP compare instructions. | 340 // Print the integer value of the cc field for the FP compare instructions. |
317 void Decoder::PrintCc(Instruction* instr) { | 341 void Decoder::PrintCc(Instruction* instr) { |
318 int cc = instr->FCccValue(); | 342 int cc = instr->FCccValue(); |
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 return 2; | 971 return 2; |
948 } | 972 } |
949 break; | 973 break; |
950 case 'd': { | 974 case 'd': { |
951 DCHECK(STRING_STARTS_WITH(format, "sd")); | 975 DCHECK(STRING_STARTS_WITH(format, "sd")); |
952 PrintSd(instr); | 976 PrintSd(instr); |
953 return 2; | 977 return 2; |
954 } | 978 } |
955 case 's': { | 979 case 's': { |
956 if (format[2] == '1') { | 980 if (format[2] == '1') { |
957 DCHECK(STRING_STARTS_WITH(format, "ss1")); /* ext size */ | 981 DCHECK(STRING_STARTS_WITH(format, "ss1")); // ext, dext, dextu size |
958 PrintSs1(instr); | 982 PrintSs1(instr); |
959 return 3; | 983 } else if (format[2] == '2') { |
| 984 DCHECK(STRING_STARTS_WITH(format, "ss2")); // ins, dins, dinsu size |
| 985 PrintSs2(instr); |
| 986 } else if (format[2] == '3') { |
| 987 DCHECK(STRING_STARTS_WITH(format, "ss3")); // dextm size |
| 988 PrintSs3(instr); |
| 989 } else if (format[2] == '4') { |
| 990 DCHECK(STRING_STARTS_WITH(format, "ss4")); // dinsm size |
| 991 PrintSs4(instr); |
960 } else { | 992 } else { |
961 DCHECK(STRING_STARTS_WITH(format, "ss2")); /* ins size */ | 993 DCHECK(STRING_STARTS_WITH(format, "ss5")); // dextu, dinsu pos |
962 PrintSs2(instr); | 994 PrintSs5(instr); |
963 return 3; | |
964 } | 995 } |
| 996 return 3; |
965 } | 997 } |
966 } | 998 } |
967 } | 999 } |
968 case 'b': { | 1000 case 'b': { |
969 switch (format[1]) { | 1001 switch (format[1]) { |
970 case 'c': { // 'bc - Special for bc1 cc field. | 1002 case 'c': { // 'bc - Special for bc1 cc field. |
971 DCHECK(STRING_STARTS_WITH(format, "bc")); | 1003 DCHECK(STRING_STARTS_WITH(format, "bc")); |
972 PrintBc(instr); | 1004 PrintBc(instr); |
973 return 2; | 1005 return 2; |
974 } | 1006 } |
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1687 } | 1719 } |
1688 break; | 1720 break; |
1689 default: | 1721 default: |
1690 UNREACHABLE(); | 1722 UNREACHABLE(); |
1691 } | 1723 } |
1692 } | 1724 } |
1693 | 1725 |
1694 | 1726 |
1695 void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) { | 1727 void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) { |
1696 switch (instr->FunctionFieldRaw()) { | 1728 switch (instr->FunctionFieldRaw()) { |
1697 case INS: { | |
1698 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); | |
1699 break; | |
1700 } | |
1701 case EXT: { | 1729 case EXT: { |
1702 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); | 1730 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); |
1703 break; | 1731 break; |
1704 } | 1732 } |
1705 case DEXT: { | 1733 case DEXT: { |
1706 Format(instr, "dext 'rt, 'rs, 'sa, 'ss1"); | 1734 Format(instr, "dext 'rt, 'rs, 'sa, 'ss1"); |
1707 break; | 1735 break; |
1708 } | 1736 } |
1709 case DEXTM: { | 1737 case DEXTM: { |
1710 Format(instr, "dextm 'rt, 'rs, 'sa, 'ss1"); | 1738 Format(instr, "dextm 'rt, 'rs, 'sa, 'ss3"); |
1711 break; | 1739 break; |
1712 } | 1740 } |
1713 case DEXTU: { | 1741 case DEXTU: { |
1714 Format(instr, "dextu 'rt, 'rs, 'sa, 'ss1"); | 1742 Format(instr, "dextu 'rt, 'rs, 'ss5, 'ss1"); |
| 1743 break; |
| 1744 } |
| 1745 case INS: { |
| 1746 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); |
| 1747 break; |
| 1748 } |
| 1749 case DINS: { |
| 1750 Format(instr, "dins 'rt, 'rs, 'sa, 'ss2"); |
| 1751 break; |
| 1752 } |
| 1753 case DINSM: { |
| 1754 Format(instr, "dinsm 'rt, 'rs, 'sa, 'ss4"); |
| 1755 break; |
| 1756 } |
| 1757 case DINSU: { |
| 1758 Format(instr, "dinsu 'rt, 'rs, 'ss5, 'ss2"); |
1715 break; | 1759 break; |
1716 } | 1760 } |
1717 case BSHFL: { | 1761 case BSHFL: { |
1718 int sa = instr->SaFieldRaw() >> kSaShift; | 1762 int sa = instr->SaFieldRaw() >> kSaShift; |
1719 switch (sa) { | 1763 switch (sa) { |
1720 case BITSWAP: { | 1764 case BITSWAP: { |
1721 Format(instr, "bitswap 'rd, 'rt"); | 1765 Format(instr, "bitswap 'rd, 'rt"); |
1722 break; | 1766 break; |
1723 } | 1767 } |
1724 case SEB: { | 1768 case SEB: { |
(...skipping 17 matching lines...) Expand all Loading... |
1742 } | 1786 } |
1743 default: | 1787 default: |
1744 UNREACHABLE(); | 1788 UNREACHABLE(); |
1745 break; | 1789 break; |
1746 } | 1790 } |
1747 break; | 1791 break; |
1748 } | 1792 } |
1749 } | 1793 } |
1750 break; | 1794 break; |
1751 } | 1795 } |
1752 case DINS: { | |
1753 Format(instr, "dins 'rt, 'rs, 'sa, 'ss2"); | |
1754 break; | |
1755 } | |
1756 case DBSHFL: { | 1796 case DBSHFL: { |
1757 int sa = instr->SaFieldRaw() >> kSaShift; | 1797 int sa = instr->SaFieldRaw() >> kSaShift; |
1758 switch (sa) { | 1798 switch (sa) { |
1759 case DBITSWAP: { | 1799 case DBITSWAP: { |
1760 switch (instr->SaFieldRaw() >> kSaShift) { | 1800 switch (instr->SaFieldRaw() >> kSaShift) { |
1761 case DBITSWAP_SA: | 1801 case DBITSWAP_SA: |
1762 Format(instr, "dbitswap 'rd, 'rt"); | 1802 Format(instr, "dbitswap 'rd, 'rt"); |
1763 break; | 1803 break; |
1764 default: | 1804 default: |
1765 UNREACHABLE(); | 1805 UNREACHABLE(); |
(...skipping 1209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2975 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 3015 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
2976 } | 3016 } |
2977 } | 3017 } |
2978 | 3018 |
2979 | 3019 |
2980 #undef UNSUPPORTED | 3020 #undef UNSUPPORTED |
2981 | 3021 |
2982 } // namespace disasm | 3022 } // namespace disasm |
2983 | 3023 |
2984 #endif // V8_TARGET_ARCH_MIPS64 | 3024 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |