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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 out_buffer_[out_buffer_pos_] = '\0'; | 53 out_buffer_[out_buffer_pos_] = '\0'; |
54 } | 54 } |
55 | 55 |
56 ~Decoder() {} | 56 ~Decoder() {} |
57 | 57 |
58 // Writes one disassembled instruction into 'buffer' (0-terminated). | 58 // Writes one disassembled instruction into 'buffer' (0-terminated). |
59 // Returns the length of the disassembled machine instruction in bytes. | 59 // Returns the length of the disassembled machine instruction in bytes. |
60 int InstructionDecode(byte* instruction); | 60 int InstructionDecode(byte* instruction); |
61 | 61 |
62 private: | 62 private: |
| 63 const uint32_t kMsaI8Mask = ((3U << 24) | ((1 << 6) - 1)); |
| 64 const uint32_t kMsaI5Mask = ((7U << 23) | ((1 << 6) - 1)); |
| 65 const uint32_t kMsaMI10Mask = (15U << 2); |
| 66 const uint32_t kMsaBITMask = ((7U << 23) | ((1 << 6) - 1)); |
| 67 const uint32_t kMsaELMMask = (15U << 22); |
| 68 const uint32_t kMsa3RMask = ((7U << 23) | ((1 << 6) - 1)); |
| 69 const uint32_t kMsa3RFMask = ((15U << 22) | ((1 << 6) - 1)); |
| 70 const uint32_t kMsaVECMask = (23U << 21); |
| 71 const uint32_t kMsa2RMask = (7U << 18); |
| 72 const uint32_t kMsa2RFMask = (15U << 17); |
| 73 |
63 // Bottleneck functions to print into the out_buffer. | 74 // Bottleneck functions to print into the out_buffer. |
64 void PrintChar(const char ch); | 75 void PrintChar(const char ch); |
65 void Print(const char* str); | 76 void Print(const char* str); |
66 | 77 |
67 // Printing of common values. | 78 // Printing of common values. |
68 void PrintRegister(int reg); | 79 void PrintRegister(int reg); |
69 void PrintFPURegister(int freg); | 80 void PrintFPURegister(int freg); |
| 81 void PrintMSARegister(int wreg); |
70 void PrintFPUStatusRegister(int freg); | 82 void PrintFPUStatusRegister(int freg); |
| 83 void PrintMSAControlRegister(int creg); |
71 void PrintRs(Instruction* instr); | 84 void PrintRs(Instruction* instr); |
72 void PrintRt(Instruction* instr); | 85 void PrintRt(Instruction* instr); |
73 void PrintRd(Instruction* instr); | 86 void PrintRd(Instruction* instr); |
74 void PrintFs(Instruction* instr); | 87 void PrintFs(Instruction* instr); |
75 void PrintFt(Instruction* instr); | 88 void PrintFt(Instruction* instr); |
76 void PrintFd(Instruction* instr); | 89 void PrintFd(Instruction* instr); |
77 void PrintSa(Instruction* instr); | 90 void PrintSa(Instruction* instr); |
78 void PrintLsaSa(Instruction* instr); | 91 void PrintLsaSa(Instruction* instr); |
79 void PrintSd(Instruction* instr); | 92 void PrintSd(Instruction* instr); |
80 void PrintSs1(Instruction* instr); | 93 void PrintSs1(Instruction* instr); |
(...skipping 14 matching lines...) Expand all Loading... |
95 void PrintSImm21(Instruction* instr); | 108 void PrintSImm21(Instruction* instr); |
96 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits); | 109 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits); |
97 void PrintXImm26(Instruction* instr); | 110 void PrintXImm26(Instruction* instr); |
98 void PrintSImm26(Instruction* instr); | 111 void PrintSImm26(Instruction* instr); |
99 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits); | 112 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits); |
100 void PrintPCImm26(Instruction* instr); | 113 void PrintPCImm26(Instruction* instr); |
101 void PrintCode(Instruction* instr); // For break and trap instructions. | 114 void PrintCode(Instruction* instr); // For break and trap instructions. |
102 void PrintFormat(Instruction* instr); // For floating format postfix. | 115 void PrintFormat(Instruction* instr); // For floating format postfix. |
103 void PrintBp2(Instruction* instr); | 116 void PrintBp2(Instruction* instr); |
104 void PrintBp3(Instruction* instr); | 117 void PrintBp3(Instruction* instr); |
| 118 void PrintMsaDataFormat(Instruction* instr); |
| 119 void PrintMsaXImm8(Instruction* instr); |
| 120 void PrintMsaImm8(Instruction* instr); |
| 121 void PrintMsaImm5(Instruction* instr); |
| 122 void PrintMsaSImm5(Instruction* instr); |
| 123 void PrintMsaSImm10(Instruction* instr, bool is_mi10 = false); |
| 124 void PrintMsaImmBit(Instruction* instr); |
| 125 void PrintMsaImmElm(Instruction* instr); |
| 126 void PrintMsaCopy(Instruction* instr); |
105 // Printing of instruction name. | 127 // Printing of instruction name. |
106 void PrintInstructionName(Instruction* instr); | 128 void PrintInstructionName(Instruction* instr); |
107 | 129 |
108 // Handle formatting of instructions and their options. | 130 // Handle formatting of instructions and their options. |
109 int FormatRegister(Instruction* instr, const char* option); | 131 int FormatRegister(Instruction* instr, const char* option); |
110 int FormatFPURegister(Instruction* instr, const char* option); | 132 int FormatFPURegister(Instruction* instr, const char* option); |
| 133 int FormatMSARegister(Instruction* instr, const char* option); |
111 int FormatOption(Instruction* instr, const char* option); | 134 int FormatOption(Instruction* instr, const char* option); |
112 void Format(Instruction* instr, const char* format); | 135 void Format(Instruction* instr, const char* format); |
113 void Unknown(Instruction* instr); | 136 void Unknown(Instruction* instr); |
114 int DecodeBreakInstr(Instruction* instr); | 137 int DecodeBreakInstr(Instruction* instr); |
115 | 138 |
116 // Each of these functions decodes one particular instruction type. | 139 // Each of these functions decodes one particular instruction type. |
117 bool DecodeTypeRegisterRsType(Instruction* instr); | 140 bool DecodeTypeRegisterRsType(Instruction* instr); |
118 void DecodeTypeRegisterSRsType(Instruction* instr); | 141 void DecodeTypeRegisterSRsType(Instruction* instr); |
119 void DecodeTypeRegisterDRsType(Instruction* instr); | 142 void DecodeTypeRegisterDRsType(Instruction* instr); |
120 void DecodeTypeRegisterLRsType(Instruction* instr); | 143 void DecodeTypeRegisterLRsType(Instruction* instr); |
121 void DecodeTypeRegisterWRsType(Instruction* instr); | 144 void DecodeTypeRegisterWRsType(Instruction* instr); |
122 void DecodeTypeRegisterSPECIAL(Instruction* instr); | 145 void DecodeTypeRegisterSPECIAL(Instruction* instr); |
123 void DecodeTypeRegisterSPECIAL2(Instruction* instr); | 146 void DecodeTypeRegisterSPECIAL2(Instruction* instr); |
124 void DecodeTypeRegisterSPECIAL3(Instruction* instr); | 147 void DecodeTypeRegisterSPECIAL3(Instruction* instr); |
125 void DecodeTypeRegisterCOP1(Instruction* instr); | 148 void DecodeTypeRegisterCOP1(Instruction* instr); |
126 void DecodeTypeRegisterCOP1X(Instruction* instr); | 149 void DecodeTypeRegisterCOP1X(Instruction* instr); |
127 int DecodeTypeRegister(Instruction* instr); | 150 int DecodeTypeRegister(Instruction* instr); |
128 | 151 |
129 void DecodeTypeImmediateCOP1(Instruction* instr); | 152 void DecodeTypeImmediateCOP1(Instruction* instr); |
130 void DecodeTypeImmediateREGIMM(Instruction* instr); | 153 void DecodeTypeImmediateREGIMM(Instruction* instr); |
131 void DecodeTypeImmediate(Instruction* instr); | 154 void DecodeTypeImmediate(Instruction* instr); |
132 | 155 |
133 void DecodeTypeJump(Instruction* instr); | 156 void DecodeTypeJump(Instruction* instr); |
134 | 157 |
| 158 void DecodeTypeMsaI8(Instruction* instr); |
| 159 void DecodeTypeMsaI5(Instruction* instr); |
| 160 void DecodeTypeMsaI10(Instruction* instr); |
| 161 void DecodeTypeMsaELM(Instruction* instr); |
| 162 void DecodeTypeMsaBIT(Instruction* instr); |
| 163 void DecodeTypeMsaMI10(Instruction* instr); |
| 164 void DecodeTypeMsa3R(Instruction* instr); |
| 165 void DecodeTypeMsa3RF(Instruction* instr); |
| 166 void DecodeTypeMsaVec(Instruction* instr); |
| 167 void DecodeTypeMsa2R(Instruction* instr); |
| 168 void DecodeTypeMsa2RF(Instruction* instr); |
| 169 |
135 const disasm::NameConverter& converter_; | 170 const disasm::NameConverter& converter_; |
136 v8::internal::Vector<char> out_buffer_; | 171 v8::internal::Vector<char> out_buffer_; |
137 int out_buffer_pos_; | 172 int out_buffer_pos_; |
138 | 173 |
139 DISALLOW_COPY_AND_ASSIGN(Decoder); | 174 DISALLOW_COPY_AND_ASSIGN(Decoder); |
140 }; | 175 }; |
141 | 176 |
142 | 177 |
143 // Support for assertions in the Decoder formatting functions. | 178 // Support for assertions in the Decoder formatting functions. |
144 #define STRING_STARTS_WITH(string, compare_string) \ | 179 #define STRING_STARTS_WITH(string, compare_string) \ |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 int reg = instr->RdValue(); | 219 int reg = instr->RdValue(); |
185 PrintRegister(reg); | 220 PrintRegister(reg); |
186 } | 221 } |
187 | 222 |
188 | 223 |
189 // Print the FPUregister name according to the active name converter. | 224 // Print the FPUregister name according to the active name converter. |
190 void Decoder::PrintFPURegister(int freg) { | 225 void Decoder::PrintFPURegister(int freg) { |
191 Print(converter_.NameOfXMMRegister(freg)); | 226 Print(converter_.NameOfXMMRegister(freg)); |
192 } | 227 } |
193 | 228 |
| 229 void Decoder::PrintMSARegister(int wreg) { Print(MSARegisters::Name(wreg)); } |
194 | 230 |
195 void Decoder::PrintFPUStatusRegister(int freg) { | 231 void Decoder::PrintFPUStatusRegister(int freg) { |
196 switch (freg) { | 232 switch (freg) { |
197 case kFCSRRegister: | 233 case kFCSRRegister: |
198 Print("FCSR"); | 234 Print("FCSR"); |
199 break; | 235 break; |
200 default: | 236 default: |
201 Print(converter_.NameOfXMMRegister(freg)); | 237 Print(converter_.NameOfXMMRegister(freg)); |
202 } | 238 } |
203 } | 239 } |
204 | 240 |
| 241 void Decoder::PrintMSAControlRegister(int creg) { |
| 242 switch (creg) { |
| 243 case kMSAIRRegister: |
| 244 Print("MSAIR"); |
| 245 break; |
| 246 case kMSACSRRegister: |
| 247 Print("MSACSR"); |
| 248 break; |
| 249 default: |
| 250 Print("no_msacreg"); |
| 251 } |
| 252 } |
205 | 253 |
206 void Decoder::PrintFs(Instruction* instr) { | 254 void Decoder::PrintFs(Instruction* instr) { |
207 int freg = instr->RsValue(); | 255 int freg = instr->RsValue(); |
208 PrintFPURegister(freg); | 256 PrintFPURegister(freg); |
209 } | 257 } |
210 | 258 |
211 | 259 |
212 void Decoder::PrintFt(Instruction* instr) { | 260 void Decoder::PrintFt(Instruction* instr) { |
213 int freg = instr->RtValue(); | 261 int freg = instr->RtValue(); |
214 PrintFPURegister(freg); | 262 PrintFPURegister(freg); |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 int32_t code = instr->Bits(15, 6); | 498 int32_t code = instr->Bits(15, 6); |
451 out_buffer_pos_ += | 499 out_buffer_pos_ += |
452 SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code); | 500 SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code); |
453 break; | 501 break; |
454 } | 502 } |
455 default: // Not a break or trap instruction. | 503 default: // Not a break or trap instruction. |
456 break; | 504 break; |
457 } | 505 } |
458 } | 506 } |
459 | 507 |
| 508 void Decoder::PrintMsaXImm8(Instruction* instr) { |
| 509 int32_t imm = instr->MsaImm8Value(); |
| 510 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
| 511 } |
| 512 |
| 513 void Decoder::PrintMsaImm8(Instruction* instr) { |
| 514 int32_t imm = instr->MsaImm8Value(); |
| 515 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); |
| 516 } |
| 517 |
| 518 void Decoder::PrintMsaImm5(Instruction* instr) { |
| 519 int32_t imm = instr->MsaImm5Value(); |
| 520 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); |
| 521 } |
| 522 |
| 523 void Decoder::PrintMsaSImm5(Instruction* instr) { |
| 524 int32_t imm = instr->MsaImm5Value(); |
| 525 imm <<= (32 - kMsaImm5Bits); |
| 526 imm >>= (32 - kMsaImm5Bits); |
| 527 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); |
| 528 } |
| 529 |
| 530 void Decoder::PrintMsaSImm10(Instruction* instr, bool is_mi10) { |
| 531 int32_t imm = is_mi10 ? instr->MsaImmMI10Value() : instr->MsaImm10Value(); |
| 532 imm <<= (32 - kMsaImm10Bits); |
| 533 imm >>= (32 - kMsaImm10Bits); |
| 534 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); |
| 535 } |
| 536 |
| 537 void Decoder::PrintMsaImmBit(Instruction* instr) { |
| 538 int32_t m = instr->MsaBitMValue(); |
| 539 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", m); |
| 540 } |
| 541 |
| 542 void Decoder::PrintMsaImmElm(Instruction* instr) { |
| 543 int32_t n = instr->MsaElmNValue(); |
| 544 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", n); |
| 545 } |
| 546 |
| 547 void Decoder::PrintMsaCopy(Instruction* instr) { |
| 548 int32_t rd = instr->WdValue(); |
| 549 int32_t ws = instr->WsValue(); |
| 550 int32_t n = instr->MsaElmNValue(); |
| 551 out_buffer_pos_ += |
| 552 SNPrintF(out_buffer_ + out_buffer_pos_, "%s, %s[%u]", |
| 553 converter_.NameOfCPURegister(rd), MSARegisters::Name(ws), n); |
| 554 } |
460 | 555 |
461 void Decoder::PrintFormat(Instruction* instr) { | 556 void Decoder::PrintFormat(Instruction* instr) { |
462 char formatLetter = ' '; | 557 char formatLetter = ' '; |
463 switch (instr->RsFieldRaw()) { | 558 switch (instr->RsFieldRaw()) { |
464 case S: | 559 case S: |
465 formatLetter = 's'; | 560 formatLetter = 's'; |
466 break; | 561 break; |
467 case D: | 562 case D: |
468 formatLetter = 'd'; | 563 formatLetter = 'd'; |
469 break; | 564 break; |
470 case W: | 565 case W: |
471 formatLetter = 'w'; | 566 formatLetter = 'w'; |
472 break; | 567 break; |
473 case L: | 568 case L: |
474 formatLetter = 'l'; | 569 formatLetter = 'l'; |
475 break; | 570 break; |
476 default: | 571 default: |
477 UNREACHABLE(); | 572 UNREACHABLE(); |
478 break; | 573 break; |
479 } | 574 } |
480 PrintChar(formatLetter); | 575 PrintChar(formatLetter); |
481 } | 576 } |
482 | 577 |
| 578 void Decoder::PrintMsaDataFormat(Instruction* instr) { |
| 579 DCHECK(instr->IsMSAInstr()); |
| 580 char df = ' '; |
| 581 if (instr->IsMSABranchInstr()) { |
| 582 switch (instr->RsFieldRaw()) { |
| 583 case BZ_V: |
| 584 case BNZ_V: |
| 585 df = 'v'; |
| 586 break; |
| 587 case BZ_B: |
| 588 case BNZ_B: |
| 589 df = 'b'; |
| 590 break; |
| 591 case BZ_H: |
| 592 case BNZ_H: |
| 593 df = 'h'; |
| 594 break; |
| 595 case BZ_W: |
| 596 case BNZ_W: |
| 597 df = 'w'; |
| 598 break; |
| 599 case BZ_D: |
| 600 case BNZ_D: |
| 601 df = 'd'; |
| 602 break; |
| 603 default: |
| 604 UNREACHABLE(); |
| 605 break; |
| 606 } |
| 607 } else { |
| 608 char DF[] = {'b', 'h', 'w', 'd'}; |
| 609 switch (instr->MSAMinorOpcodeField()) { |
| 610 case kMsaMinorI5: |
| 611 case kMsaMinorI10: |
| 612 case kMsaMinor3R: |
| 613 df = DF[instr->Bits(22, 21)]; |
| 614 break; |
| 615 case kMsaMinorMI10: |
| 616 df = DF[instr->Bits(1, 0)]; |
| 617 break; |
| 618 case kMsaMinorBIT: |
| 619 df = DF[instr->MsaBitDf()]; |
| 620 break; |
| 621 case kMsaMinorELM: |
| 622 df = DF[instr->MsaElmDf()]; |
| 623 break; |
| 624 case kMsaMinor3RF: { |
| 625 uint32_t opcode = instr->InstructionBits() & kMsa3RFMask; |
| 626 switch (opcode) { |
| 627 case FEXDO: |
| 628 case FTQ: |
| 629 case MUL_Q: |
| 630 case MADD_Q: |
| 631 case MSUB_Q: |
| 632 case MULR_Q: |
| 633 case MADDR_Q: |
| 634 case MSUBR_Q: |
| 635 df = DF[1 + instr->Bit(21)]; |
| 636 break; |
| 637 default: |
| 638 df = DF[2 + instr->Bit(21)]; |
| 639 break; |
| 640 } |
| 641 } break; |
| 642 case kMsaMinor2R: |
| 643 df = DF[instr->Bits(17, 16)]; |
| 644 break; |
| 645 case kMsaMinor2RF: |
| 646 df = DF[2 + instr->Bit(16)]; |
| 647 break; |
| 648 default: |
| 649 UNREACHABLE(); |
| 650 break; |
| 651 } |
| 652 } |
| 653 |
| 654 PrintChar(df); |
| 655 } |
483 | 656 |
484 // Printing of instruction name. | 657 // Printing of instruction name. |
485 void Decoder::PrintInstructionName(Instruction* instr) { | 658 void Decoder::PrintInstructionName(Instruction* instr) { |
486 } | 659 } |
487 | 660 |
488 | 661 |
489 // Handle all register based formatting in this function to reduce the | 662 // Handle all register based formatting in this function to reduce the |
490 // complexity of FormatOption. | 663 // complexity of FormatOption. |
491 int Decoder::FormatRegister(Instruction* instr, const char* format) { | 664 int Decoder::FormatRegister(Instruction* instr, const char* format) { |
492 DCHECK(format[0] == 'r'); | 665 DCHECK(format[0] == 'r'); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 } else if (format[1] == 'r') { // 'fr: fr register. | 719 } else if (format[1] == 'r') { // 'fr: fr register. |
547 int reg = instr->FrValue(); | 720 int reg = instr->FrValue(); |
548 PrintFPURegister(reg); | 721 PrintFPURegister(reg); |
549 return 2; | 722 return 2; |
550 } | 723 } |
551 } | 724 } |
552 UNREACHABLE(); | 725 UNREACHABLE(); |
553 return -1; | 726 return -1; |
554 } | 727 } |
555 | 728 |
| 729 // Handle all MSARegister based formatting in this function to reduce the |
| 730 // complexity of FormatOption. |
| 731 int Decoder::FormatMSARegister(Instruction* instr, const char* format) { |
| 732 DCHECK(format[0] == 'w'); |
| 733 if (format[1] == 's') { |
| 734 int reg = instr->WsValue(); |
| 735 PrintMSARegister(reg); |
| 736 return 2; |
| 737 } else if (format[1] == 't') { |
| 738 int reg = instr->WtValue(); |
| 739 PrintMSARegister(reg); |
| 740 return 2; |
| 741 } else if (format[1] == 'd') { |
| 742 int reg = instr->WdValue(); |
| 743 PrintMSARegister(reg); |
| 744 return 2; |
| 745 } |
| 746 |
| 747 UNREACHABLE(); |
| 748 return -1; |
| 749 } |
556 | 750 |
557 // FormatOption takes a formatting string and interprets it based on | 751 // FormatOption takes a formatting string and interprets it based on |
558 // the current instructions. The format string points to the first | 752 // the current instructions. The format string points to the first |
559 // character of the option string (the option escape has already been | 753 // character of the option string (the option escape has already been |
560 // consumed by the caller.) FormatOption returns the number of | 754 // consumed by the caller.) FormatOption returns the number of |
561 // characters that were consumed from the formatting string. | 755 // characters that were consumed from the formatting string. |
562 int Decoder::FormatOption(Instruction* instr, const char* format) { | 756 int Decoder::FormatOption(Instruction* instr, const char* format) { |
563 switch (format[0]) { | 757 switch (format[0]) { |
564 case 'c': { // 'code for break or trap instructions. | 758 case 'c': { // 'code for break or trap instructions. |
565 DCHECK(STRING_STARTS_WITH(format, "code")); | 759 DCHECK(STRING_STARTS_WITH(format, "code")); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 case 's': | 816 case 's': |
623 DCHECK(STRING_STARTS_WITH(format, "imm19s")); | 817 DCHECK(STRING_STARTS_WITH(format, "imm19s")); |
624 PrintSImm19(instr); | 818 PrintSImm19(instr); |
625 break; | 819 break; |
626 case 'x': | 820 case 'x': |
627 DCHECK(STRING_STARTS_WITH(format, "imm19x")); | 821 DCHECK(STRING_STARTS_WITH(format, "imm19x")); |
628 PrintXImm19(instr); | 822 PrintXImm19(instr); |
629 break; | 823 break; |
630 } | 824 } |
631 return 6; | 825 return 6; |
| 826 } else if (format[4] == '0' && format[5] == 's') { |
| 827 DCHECK(STRING_STARTS_WITH(format, "imm10s")); |
| 828 if (format[6] == '1') { |
| 829 DCHECK(STRING_STARTS_WITH(format, "imm10s1")); |
| 830 PrintMsaSImm10(instr, false); |
| 831 } else if (format[6] == '2') { |
| 832 DCHECK(STRING_STARTS_WITH(format, "imm10s2")); |
| 833 PrintMsaSImm10(instr, true); |
| 834 } |
| 835 return 7; |
632 } | 836 } |
633 } else if (format[3] == '2' && format[4] == '1') { | 837 } else if (format[3] == '2' && format[4] == '1') { |
634 DCHECK(STRING_STARTS_WITH(format, "imm21")); | 838 DCHECK(STRING_STARTS_WITH(format, "imm21")); |
635 switch (format[5]) { | 839 switch (format[5]) { |
636 case 's': | 840 case 's': |
637 DCHECK(STRING_STARTS_WITH(format, "imm21s")); | 841 DCHECK(STRING_STARTS_WITH(format, "imm21s")); |
638 PrintSImm21(instr); | 842 PrintSImm21(instr); |
639 break; | 843 break; |
640 case 'x': | 844 case 'x': |
641 DCHECK(STRING_STARTS_WITH(format, "imm21x")); | 845 DCHECK(STRING_STARTS_WITH(format, "imm21x")); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 } | 894 } |
691 } | 895 } |
692 } | 896 } |
693 case 'j': { // Absolute address for jump instructions. | 897 case 'j': { // Absolute address for jump instructions. |
694 DCHECK(STRING_STARTS_WITH(format, "imm26j")); | 898 DCHECK(STRING_STARTS_WITH(format, "imm26j")); |
695 PrintPCImm26(instr); | 899 PrintPCImm26(instr); |
696 break; | 900 break; |
697 } | 901 } |
698 } | 902 } |
699 return 6; | 903 return 6; |
| 904 } else if (format[3] == '5') { |
| 905 DCHECK(STRING_STARTS_WITH(format, "imm5")); |
| 906 if (format[4] == 'u') { |
| 907 DCHECK(STRING_STARTS_WITH(format, "imm5u")); |
| 908 PrintMsaImm5(instr); |
| 909 } else if (format[4] == 's') { |
| 910 DCHECK(STRING_STARTS_WITH(format, "imm5s")); |
| 911 PrintMsaSImm5(instr); |
| 912 } |
| 913 return 5; |
| 914 } else if (format[3] == '8') { |
| 915 DCHECK(STRING_STARTS_WITH(format, "imm8")); |
| 916 PrintMsaImm8(instr); |
| 917 return 4; |
| 918 } else if (format[3] == 'b') { |
| 919 DCHECK(STRING_STARTS_WITH(format, "immb")); |
| 920 PrintMsaImmBit(instr); |
| 921 return 4; |
| 922 } else if (format[3] == 'e') { |
| 923 DCHECK(STRING_STARTS_WITH(format, "imme")); |
| 924 PrintMsaImmElm(instr); |
| 925 return 4; |
700 } | 926 } |
701 } | 927 } |
702 case 'r': { // 'r: registers. | 928 case 'r': { // 'r: registers. |
703 return FormatRegister(instr, format); | 929 return FormatRegister(instr, format); |
704 } | 930 } |
705 case 'f': { // 'f: FPUregisters. | 931 case 'f': { // 'f: FPUregisters. |
706 return FormatFPURegister(instr, format); | 932 return FormatFPURegister(instr, format); |
707 } | 933 } |
| 934 case 'w': { // 'w: MSA Register |
| 935 return FormatMSARegister(instr, format); |
| 936 } |
708 case 's': { // 'sa. | 937 case 's': { // 'sa. |
709 switch (format[1]) { | 938 switch (format[1]) { |
710 case 'a': | 939 case 'a': |
711 if (format[2] == '2') { | 940 if (format[2] == '2') { |
712 DCHECK(STRING_STARTS_WITH(format, "sa2")); // 'sa2 | 941 DCHECK(STRING_STARTS_WITH(format, "sa2")); // 'sa2 |
713 PrintLsaSa(instr); | 942 PrintLsaSa(instr); |
714 return 3; | 943 return 3; |
715 } else { | 944 } else { |
716 DCHECK(STRING_STARTS_WITH(format, "sa")); | 945 DCHECK(STRING_STARTS_WITH(format, "sa")); |
717 PrintSa(instr); | 946 PrintSa(instr); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 } | 987 } |
759 } | 988 } |
760 } | 989 } |
761 } | 990 } |
762 case 'C': { // 'Cc - Special for c.xx.d cc field. | 991 case 'C': { // 'Cc - Special for c.xx.d cc field. |
763 DCHECK(STRING_STARTS_WITH(format, "Cc")); | 992 DCHECK(STRING_STARTS_WITH(format, "Cc")); |
764 PrintCc(instr); | 993 PrintCc(instr); |
765 return 2; | 994 return 2; |
766 } | 995 } |
767 case 't': | 996 case 't': |
768 PrintFormat(instr); | 997 if (instr->IsMSAInstr()) { |
| 998 PrintMsaDataFormat(instr); |
| 999 } else { |
| 1000 PrintFormat(instr); |
| 1001 } |
769 return 1; | 1002 return 1; |
770 } | 1003 } |
771 UNREACHABLE(); | 1004 UNREACHABLE(); |
772 return -1; | 1005 return -1; |
773 } | 1006 } |
774 | 1007 |
775 | 1008 |
776 // Format takes a formatting string for a whole instruction and prints it into | 1009 // Format takes a formatting string for a whole instruction and prints it into |
777 // the output buffer. All escaped options are handed to FormatOption to be | 1010 // the output buffer. All escaped options are handed to FormatOption to be |
778 // parsed further. | 1011 // parsed further. |
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1572 DecodeTypeRegisterSPECIAL(instr); | 1805 DecodeTypeRegisterSPECIAL(instr); |
1573 break; | 1806 break; |
1574 } | 1807 } |
1575 break; | 1808 break; |
1576 case SPECIAL2: | 1809 case SPECIAL2: |
1577 DecodeTypeRegisterSPECIAL2(instr); | 1810 DecodeTypeRegisterSPECIAL2(instr); |
1578 break; | 1811 break; |
1579 case SPECIAL3: | 1812 case SPECIAL3: |
1580 DecodeTypeRegisterSPECIAL3(instr); | 1813 DecodeTypeRegisterSPECIAL3(instr); |
1581 break; | 1814 break; |
| 1815 case MSA: |
| 1816 switch (instr->MSAMinorOpcodeField()) { |
| 1817 case kMsaMinor3R: |
| 1818 DecodeTypeMsa3R(instr); |
| 1819 break; |
| 1820 case kMsaMinor3RF: |
| 1821 DecodeTypeMsa3RF(instr); |
| 1822 break; |
| 1823 case kMsaMinorVEC: |
| 1824 DecodeTypeMsaVec(instr); |
| 1825 break; |
| 1826 case kMsaMinor2R: |
| 1827 DecodeTypeMsa2R(instr); |
| 1828 break; |
| 1829 case kMsaMinor2RF: |
| 1830 DecodeTypeMsa2RF(instr); |
| 1831 break; |
| 1832 default: |
| 1833 UNREACHABLE(); |
| 1834 } |
| 1835 break; |
1582 default: | 1836 default: |
1583 UNREACHABLE(); | 1837 UNREACHABLE(); |
1584 } | 1838 } |
1585 return Instruction::kInstrSize; | 1839 return Instruction::kInstrSize; |
1586 } | 1840 } |
1587 | 1841 |
1588 | 1842 |
1589 void Decoder::DecodeTypeImmediateCOP1(Instruction* instr) { | 1843 void Decoder::DecodeTypeImmediateCOP1(Instruction* instr) { |
1590 switch (instr->RsFieldRaw()) { | 1844 switch (instr->RsFieldRaw()) { |
1591 case BC1: | 1845 case BC1: |
1592 if (instr->FBtrueValue()) { | 1846 if (instr->FBtrueValue()) { |
1593 Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2"); | 1847 Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2"); |
1594 } else { | 1848 } else { |
1595 Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2"); | 1849 Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2"); |
1596 } | 1850 } |
1597 break; | 1851 break; |
1598 case BC1EQZ: | 1852 case BC1EQZ: |
1599 Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2"); | 1853 Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2"); |
1600 break; | 1854 break; |
1601 case BC1NEZ: | 1855 case BC1NEZ: |
1602 Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2"); | 1856 Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2"); |
1603 break; | 1857 break; |
| 1858 case BZ_V: |
| 1859 case BZ_B: |
| 1860 case BZ_H: |
| 1861 case BZ_W: |
| 1862 case BZ_D: |
| 1863 Format(instr, "bz.'t 'wt, 'imm16s -> 'imm16p4s2"); |
| 1864 break; |
| 1865 case BNZ_V: |
| 1866 case BNZ_B: |
| 1867 case BNZ_H: |
| 1868 case BNZ_W: |
| 1869 case BNZ_D: |
| 1870 Format(instr, "bnz.'t 'wt, 'imm16s -> 'imm16p4s2"); |
| 1871 break; |
1604 default: | 1872 default: |
1605 UNREACHABLE(); | 1873 UNREACHABLE(); |
1606 } | 1874 } |
1607 } | 1875 } |
1608 | 1876 |
1609 | 1877 |
1610 void Decoder::DecodeTypeImmediateREGIMM(Instruction* instr) { | 1878 void Decoder::DecodeTypeImmediateREGIMM(Instruction* instr) { |
1611 switch (instr->RtFieldRaw()) { | 1879 switch (instr->RtFieldRaw()) { |
1612 case BLTZ: | 1880 case BLTZ: |
1613 Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2"); | 1881 Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2"); |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1907 break; | 2175 break; |
1908 } | 2176 } |
1909 break; | 2177 break; |
1910 } | 2178 } |
1911 } | 2179 } |
1912 break; | 2180 break; |
1913 } | 2181 } |
1914 } | 2182 } |
1915 break; | 2183 break; |
1916 } | 2184 } |
| 2185 case MSA: |
| 2186 switch (instr->MSAMinorOpcodeField()) { |
| 2187 case kMsaMinorI8: |
| 2188 DecodeTypeMsaI8(instr); |
| 2189 break; |
| 2190 case kMsaMinorI5: |
| 2191 DecodeTypeMsaI5(instr); |
| 2192 break; |
| 2193 case kMsaMinorI10: |
| 2194 DecodeTypeMsaI10(instr); |
| 2195 break; |
| 2196 case kMsaMinorELM: |
| 2197 DecodeTypeMsaELM(instr); |
| 2198 break; |
| 2199 case kMsaMinorBIT: |
| 2200 DecodeTypeMsaBIT(instr); |
| 2201 break; |
| 2202 case kMsaMinorMI10: |
| 2203 DecodeTypeMsaMI10(instr); |
| 2204 break; |
| 2205 default: |
| 2206 UNREACHABLE(); |
| 2207 break; |
| 2208 } |
| 2209 break; |
1917 default: | 2210 default: |
1918 printf("a 0x%x \n", instr->OpcodeFieldRaw()); | 2211 printf("a 0x%x \n", instr->OpcodeFieldRaw()); |
1919 UNREACHABLE(); | 2212 UNREACHABLE(); |
1920 break; | 2213 break; |
1921 } | 2214 } |
1922 } | 2215 } |
1923 | 2216 |
1924 | 2217 |
1925 void Decoder::DecodeTypeJump(Instruction* instr) { | 2218 void Decoder::DecodeTypeJump(Instruction* instr) { |
1926 switch (instr->OpcodeFieldRaw()) { | 2219 switch (instr->OpcodeFieldRaw()) { |
1927 case J: | 2220 case J: |
1928 Format(instr, "j 'imm26x -> 'imm26j"); | 2221 Format(instr, "j 'imm26x -> 'imm26j"); |
1929 break; | 2222 break; |
1930 case JAL: | 2223 case JAL: |
1931 Format(instr, "jal 'imm26x -> 'imm26j"); | 2224 Format(instr, "jal 'imm26x -> 'imm26j"); |
1932 break; | 2225 break; |
1933 default: | 2226 default: |
1934 UNREACHABLE(); | 2227 UNREACHABLE(); |
1935 } | 2228 } |
1936 } | 2229 } |
1937 | 2230 |
| 2231 void Decoder::DecodeTypeMsaI8(Instruction* instr) { |
| 2232 uint32_t opcode = instr->InstructionBits() & kMsaI8Mask; |
| 2233 |
| 2234 switch (opcode) { |
| 2235 case ANDI_B: |
| 2236 Format(instr, "andi.b 'wd, 'ws, 'imm8"); |
| 2237 break; |
| 2238 case ORI_B: |
| 2239 Format(instr, "ori.b 'wd, 'ws, 'imm8"); |
| 2240 break; |
| 2241 case NORI_B: |
| 2242 Format(instr, "nori.b 'wd, 'ws, 'imm8"); |
| 2243 break; |
| 2244 case XORI_B: |
| 2245 Format(instr, "xori.b 'wd, 'ws, 'imm8"); |
| 2246 break; |
| 2247 case BMNZI_B: |
| 2248 Format(instr, "bmnzi.b 'wd, 'ws, 'imm8"); |
| 2249 break; |
| 2250 case BMZI_B: |
| 2251 Format(instr, "bmzi.b 'wd, 'ws, 'imm8"); |
| 2252 break; |
| 2253 case BSELI_B: |
| 2254 Format(instr, "bseli.b 'wd, 'ws, 'imm8"); |
| 2255 break; |
| 2256 case SHF_B: |
| 2257 Format(instr, "shf.b 'wd, 'ws, 'imm8"); |
| 2258 break; |
| 2259 case SHF_H: |
| 2260 Format(instr, "shf.h 'wd, 'ws, 'imm8"); |
| 2261 break; |
| 2262 case SHF_W: |
| 2263 Format(instr, "shf.w 'wd, 'ws, 'imm8"); |
| 2264 break; |
| 2265 default: |
| 2266 UNREACHABLE(); |
| 2267 } |
| 2268 } |
| 2269 |
| 2270 void Decoder::DecodeTypeMsaI5(Instruction* instr) { |
| 2271 uint32_t opcode = instr->InstructionBits() & kMsaI5Mask; |
| 2272 |
| 2273 switch (opcode) { |
| 2274 case ADDVI: |
| 2275 Format(instr, "addvi.'t 'wd, 'ws, 'imm5u"); |
| 2276 break; |
| 2277 case SUBVI: |
| 2278 Format(instr, "subvi.'t 'wd, 'ws, 'imm5u"); |
| 2279 break; |
| 2280 case MAXI_S: |
| 2281 Format(instr, "maxi_s.'t 'wd, 'ws, 'imm5s"); |
| 2282 break; |
| 2283 case MAXI_U: |
| 2284 Format(instr, "maxi_u.'t 'wd, 'ws, 'imm5u"); |
| 2285 break; |
| 2286 case MINI_S: |
| 2287 Format(instr, "mini_s.'t 'wd, 'ws, 'imm5s"); |
| 2288 break; |
| 2289 case MINI_U: |
| 2290 Format(instr, "mini_u.'t 'wd, 'ws, 'imm5u"); |
| 2291 break; |
| 2292 case CEQI: |
| 2293 Format(instr, "ceqi.'t 'wd, 'ws, 'imm5s"); |
| 2294 break; |
| 2295 case CLTI_S: |
| 2296 Format(instr, "clti_s.'t 'wd, 'ws, 'imm5s"); |
| 2297 break; |
| 2298 case CLTI_U: |
| 2299 Format(instr, "clti_u.'t 'wd, 'ws, 'imm5u"); |
| 2300 break; |
| 2301 case CLEI_S: |
| 2302 Format(instr, "clei_s.'t 'wd, 'ws, 'imm5s"); |
| 2303 break; |
| 2304 case CLEI_U: |
| 2305 Format(instr, "clei_u.'t 'wd, 'ws, 'imm5u"); |
| 2306 break; |
| 2307 default: |
| 2308 UNREACHABLE(); |
| 2309 } |
| 2310 } |
| 2311 |
| 2312 void Decoder::DecodeTypeMsaI10(Instruction* instr) { |
| 2313 uint32_t opcode = instr->InstructionBits() & kMsaI5Mask; |
| 2314 if (opcode == LDI) { |
| 2315 Format(instr, "ldi.'t 'wd, 'imm10s1"); |
| 2316 } else { |
| 2317 UNREACHABLE(); |
| 2318 } |
| 2319 } |
| 2320 |
| 2321 void Decoder::DecodeTypeMsaELM(Instruction* instr) { |
| 2322 uint32_t opcode = instr->InstructionBits() & kMsaELMMask; |
| 2323 switch (opcode) { |
| 2324 case SLDI: |
| 2325 if (instr->Bits(21, 16) == 0x3E) { |
| 2326 Format(instr, "ctcmsa "); |
| 2327 PrintMSAControlRegister(instr->WdValue()); |
| 2328 Print(", "); |
| 2329 PrintRegister(instr->WsValue()); |
| 2330 } else { |
| 2331 Format(instr, "sldi.'t 'wd, 'ws['imme]"); |
| 2332 } |
| 2333 break; |
| 2334 case SPLATI: |
| 2335 if (instr->Bits(21, 16) == 0x3E) { |
| 2336 Format(instr, "cfcmsa "); |
| 2337 PrintRegister(instr->WdValue()); |
| 2338 Print(", "); |
| 2339 PrintMSAControlRegister(instr->WsValue()); |
| 2340 } else { |
| 2341 Format(instr, "splati.'t 'wd, 'ws['imme]"); |
| 2342 } |
| 2343 break; |
| 2344 case COPY_S: |
| 2345 if (instr->Bits(21, 16) == 0x3E) { |
| 2346 Format(instr, "move.v 'wd, 'ws"); |
| 2347 } else { |
| 2348 Format(instr, "copy_s.'t "); |
| 2349 PrintMsaCopy(instr); |
| 2350 } |
| 2351 break; |
| 2352 case COPY_U: |
| 2353 Format(instr, "copy_u.'t "); |
| 2354 PrintMsaCopy(instr); |
| 2355 break; |
| 2356 case INSERT: |
| 2357 Format(instr, "insert.'t 'wd['imme], "); |
| 2358 PrintRegister(instr->WsValue()); |
| 2359 break; |
| 2360 case INSVE: |
| 2361 Format(instr, "insve.'t 'wd['imme], 'ws[0]"); |
| 2362 break; |
| 2363 default: |
| 2364 UNREACHABLE(); |
| 2365 } |
| 2366 } |
| 2367 |
| 2368 void Decoder::DecodeTypeMsaBIT(Instruction* instr) { |
| 2369 uint32_t opcode = instr->InstructionBits() & kMsaBITMask; |
| 2370 |
| 2371 switch (opcode) { |
| 2372 case SLLI: |
| 2373 Format(instr, "slli.'t 'wd, 'ws, 'immb"); |
| 2374 break; |
| 2375 case SRAI: |
| 2376 Format(instr, "srai.'t 'wd, 'ws, 'immb"); |
| 2377 break; |
| 2378 case SRLI: |
| 2379 Format(instr, "srli.'t 'wd, 'ws, 'immb"); |
| 2380 break; |
| 2381 case BCLRI: |
| 2382 Format(instr, "bclri.'t 'wd, 'ws, 'immb"); |
| 2383 break; |
| 2384 case BSETI: |
| 2385 Format(instr, "bseti.'t 'wd, 'ws, 'immb"); |
| 2386 break; |
| 2387 case BNEGI: |
| 2388 Format(instr, "bnegi.'t 'wd, 'ws, 'immb"); |
| 2389 break; |
| 2390 case BINSLI: |
| 2391 Format(instr, "binsli.'t 'wd, 'ws, 'immb"); |
| 2392 break; |
| 2393 case BINSRI: |
| 2394 Format(instr, "binsri.'t 'wd, 'ws, 'immb"); |
| 2395 break; |
| 2396 case SAT_S: |
| 2397 Format(instr, "sat_s.'t 'wd, 'ws, 'immb"); |
| 2398 break; |
| 2399 case SAT_U: |
| 2400 Format(instr, "sat_u.'t 'wd, 'ws, 'immb"); |
| 2401 break; |
| 2402 case SRARI: |
| 2403 Format(instr, "srari.'t 'wd, 'ws, 'immb"); |
| 2404 break; |
| 2405 case SRLRI: |
| 2406 Format(instr, "srlri.'t 'wd, 'ws, 'immb"); |
| 2407 break; |
| 2408 default: |
| 2409 UNREACHABLE(); |
| 2410 } |
| 2411 } |
| 2412 |
| 2413 void Decoder::DecodeTypeMsaMI10(Instruction* instr) { |
| 2414 uint32_t opcode = instr->InstructionBits() & kMsaMI10Mask; |
| 2415 if (opcode == MSA_LD) { |
| 2416 Format(instr, "ld.'t 'wd, 'imm10s2("); |
| 2417 PrintRegister(instr->WsValue()); |
| 2418 Print(")"); |
| 2419 } else if (opcode == MSA_ST) { |
| 2420 Format(instr, "st.'t 'wd, 'imm10s2("); |
| 2421 PrintRegister(instr->WsValue()); |
| 2422 Print(")"); |
| 2423 } else { |
| 2424 UNREACHABLE(); |
| 2425 } |
| 2426 } |
| 2427 |
| 2428 void Decoder::DecodeTypeMsa3R(Instruction* instr) { |
| 2429 uint32_t opcode = instr->InstructionBits() & kMsa3RMask; |
| 2430 switch (opcode) { |
| 2431 case SLL_MSA: |
| 2432 Format(instr, "sll.'t 'wd, 'ws, 'wt"); |
| 2433 break; |
| 2434 case SRA_MSA: |
| 2435 Format(instr, "sra.'t 'wd, 'ws, 'wt"); |
| 2436 break; |
| 2437 case SRL_MSA: |
| 2438 Format(instr, "srl.'t 'wd, 'ws, 'wt"); |
| 2439 break; |
| 2440 case BCLR: |
| 2441 Format(instr, "bclr.'t 'wd, 'ws, 'wt"); |
| 2442 break; |
| 2443 case BSET: |
| 2444 Format(instr, "bset.'t 'wd, 'ws, 'wt"); |
| 2445 break; |
| 2446 case BNEG: |
| 2447 Format(instr, "bneg.'t 'wd, 'ws, 'wt"); |
| 2448 break; |
| 2449 case BINSL: |
| 2450 Format(instr, "binsl.'t 'wd, 'ws, 'wt"); |
| 2451 break; |
| 2452 case BINSR: |
| 2453 Format(instr, "binsr.'t 'wd, 'ws, 'wt"); |
| 2454 break; |
| 2455 case ADDV: |
| 2456 Format(instr, "addv.'t 'wd, 'ws, 'wt"); |
| 2457 break; |
| 2458 case SUBV: |
| 2459 Format(instr, "subv.'t 'wd, 'ws, 'wt"); |
| 2460 break; |
| 2461 case MAX_S: |
| 2462 Format(instr, "max_s.'t 'wd, 'ws, 'wt"); |
| 2463 break; |
| 2464 case MAX_U: |
| 2465 Format(instr, "max_u.'t 'wd, 'ws, 'wt"); |
| 2466 break; |
| 2467 case MIN_S: |
| 2468 Format(instr, "min_s.'t 'wd, 'ws, 'wt"); |
| 2469 break; |
| 2470 case MIN_U: |
| 2471 Format(instr, "min_u.'t 'wd, 'ws, 'wt"); |
| 2472 break; |
| 2473 case MAX_A: |
| 2474 Format(instr, "max_a.'t 'wd, 'ws, 'wt"); |
| 2475 break; |
| 2476 case MIN_A: |
| 2477 Format(instr, "min_a.'t 'wd, 'ws, 'wt"); |
| 2478 break; |
| 2479 case CEQ: |
| 2480 Format(instr, "ceq.'t 'wd, 'ws, 'wt"); |
| 2481 break; |
| 2482 case CLT_S: |
| 2483 Format(instr, "clt_s.'t 'wd, 'ws, 'wt"); |
| 2484 break; |
| 2485 case CLT_U: |
| 2486 Format(instr, "clt_u.'t 'wd, 'ws, 'wt"); |
| 2487 break; |
| 2488 case CLE_S: |
| 2489 Format(instr, "cle_s.'t 'wd, 'ws, 'wt"); |
| 2490 break; |
| 2491 case CLE_U: |
| 2492 Format(instr, "cle_u.'t 'wd, 'ws, 'wt"); |
| 2493 break; |
| 2494 case ADD_A: |
| 2495 Format(instr, "add_a.'t 'wd, 'ws, 'wt"); |
| 2496 break; |
| 2497 case ADDS_A: |
| 2498 Format(instr, "adds_a.'t 'wd, 'ws, 'wt"); |
| 2499 break; |
| 2500 case ADDS_S: |
| 2501 Format(instr, "adds_s.'t 'wd, 'ws, 'wt"); |
| 2502 break; |
| 2503 case ADDS_U: |
| 2504 Format(instr, "adds_u.'t 'wd, 'ws, 'wt"); |
| 2505 break; |
| 2506 case AVE_S: |
| 2507 Format(instr, "ave_s.'t 'wd, 'ws, 'wt"); |
| 2508 break; |
| 2509 case AVE_U: |
| 2510 Format(instr, "ave_u.'t 'wd, 'ws, 'wt"); |
| 2511 break; |
| 2512 case AVER_S: |
| 2513 Format(instr, "aver_s.'t 'wd, 'ws, 'wt"); |
| 2514 break; |
| 2515 case AVER_U: |
| 2516 Format(instr, "aver_u.'t 'wd, 'ws, 'wt"); |
| 2517 break; |
| 2518 case SUBS_S: |
| 2519 Format(instr, "subs_s.'t 'wd, 'ws, 'wt"); |
| 2520 break; |
| 2521 case SUBS_U: |
| 2522 Format(instr, "subs_u.'t 'wd, 'ws, 'wt"); |
| 2523 break; |
| 2524 case SUBSUS_U: |
| 2525 Format(instr, "subsus_u.'t 'wd, 'ws, 'wt"); |
| 2526 break; |
| 2527 case SUBSUU_S: |
| 2528 Format(instr, "subsuu_s.'t 'wd, 'ws, 'wt"); |
| 2529 break; |
| 2530 case ASUB_S: |
| 2531 Format(instr, "asub_s.'t 'wd, 'ws, 'wt"); |
| 2532 break; |
| 2533 case ASUB_U: |
| 2534 Format(instr, "asub_u.'t 'wd, 'ws, 'wt"); |
| 2535 break; |
| 2536 case MULV: |
| 2537 Format(instr, "mulv.'t 'wd, 'ws, 'wt"); |
| 2538 break; |
| 2539 case MADDV: |
| 2540 Format(instr, "maddv.'t 'wd, 'ws, 'wt"); |
| 2541 break; |
| 2542 case MSUBV: |
| 2543 Format(instr, "msubv.'t 'wd, 'ws, 'wt"); |
| 2544 break; |
| 2545 case DIV_S_MSA: |
| 2546 Format(instr, "div_s.'t 'wd, 'ws, 'wt"); |
| 2547 break; |
| 2548 case DIV_U: |
| 2549 Format(instr, "div_u.'t 'wd, 'ws, 'wt"); |
| 2550 break; |
| 2551 case MOD_S: |
| 2552 Format(instr, "mod_s.'t 'wd, 'ws, 'wt"); |
| 2553 break; |
| 2554 case MOD_U: |
| 2555 Format(instr, "mod_u.'t 'wd, 'ws, 'wt"); |
| 2556 break; |
| 2557 case DOTP_S: |
| 2558 Format(instr, "dotp_s.'t 'wd, 'ws, 'wt"); |
| 2559 break; |
| 2560 case DOTP_U: |
| 2561 Format(instr, "dotp_u.'t 'wd, 'ws, 'wt"); |
| 2562 break; |
| 2563 case DPADD_S: |
| 2564 Format(instr, "dpadd_s.'t 'wd, 'ws, 'wt"); |
| 2565 break; |
| 2566 case DPADD_U: |
| 2567 Format(instr, "dpadd_u.'t 'wd, 'ws, 'wt"); |
| 2568 break; |
| 2569 case DPSUB_S: |
| 2570 Format(instr, "dpsub_s.'t 'wd, 'ws, 'wt"); |
| 2571 break; |
| 2572 case DPSUB_U: |
| 2573 Format(instr, "dpsub_u.'t 'wd, 'ws, 'wt"); |
| 2574 break; |
| 2575 case SLD: |
| 2576 Format(instr, "sld.'t 'wd, 'ws['rt]"); |
| 2577 break; |
| 2578 case SPLAT: |
| 2579 Format(instr, "splat.'t 'wd, 'ws['rt]"); |
| 2580 break; |
| 2581 case PCKEV: |
| 2582 Format(instr, "pckev.'t 'wd, 'ws, 'wt"); |
| 2583 break; |
| 2584 case PCKOD: |
| 2585 Format(instr, "pckod.'t 'wd, 'ws, 'wt"); |
| 2586 break; |
| 2587 case ILVL: |
| 2588 Format(instr, "ilvl.'t 'wd, 'ws, 'wt"); |
| 2589 break; |
| 2590 case ILVR: |
| 2591 Format(instr, "ilvr.'t 'wd, 'ws, 'wt"); |
| 2592 break; |
| 2593 case ILVEV: |
| 2594 Format(instr, "ilvev.'t 'wd, 'ws, 'wt"); |
| 2595 break; |
| 2596 case ILVOD: |
| 2597 Format(instr, "ilvod.'t 'wd, 'ws, 'wt"); |
| 2598 break; |
| 2599 case VSHF: |
| 2600 Format(instr, "vshf.'t 'wd, 'ws, 'wt"); |
| 2601 break; |
| 2602 case SRAR: |
| 2603 Format(instr, "srar.'t 'wd, 'ws, 'wt"); |
| 2604 break; |
| 2605 case SRLR: |
| 2606 Format(instr, "srlr.'t 'wd, 'ws, 'wt"); |
| 2607 break; |
| 2608 case HADD_S: |
| 2609 Format(instr, "hadd_s.'t 'wd, 'ws, 'wt"); |
| 2610 break; |
| 2611 case HADD_U: |
| 2612 Format(instr, "hadd_u.'t 'wd, 'ws, 'wt"); |
| 2613 break; |
| 2614 case HSUB_S: |
| 2615 Format(instr, "hsub_s.'t 'wd, 'ws, 'wt"); |
| 2616 break; |
| 2617 case HSUB_U: |
| 2618 Format(instr, "hsub_u.'t 'wd, 'ws, 'wt"); |
| 2619 break; |
| 2620 default: |
| 2621 UNREACHABLE(); |
| 2622 } |
| 2623 } |
| 2624 |
| 2625 void Decoder::DecodeTypeMsa3RF(Instruction* instr) { |
| 2626 uint32_t opcode = instr->InstructionBits() & kMsa3RFMask; |
| 2627 switch (opcode) { |
| 2628 case FCAF: |
| 2629 Format(instr, "fcaf.'t 'wd, 'ws, 'wt"); |
| 2630 break; |
| 2631 case FCUN: |
| 2632 Format(instr, "fcun.'t 'wd, 'ws, 'wt"); |
| 2633 break; |
| 2634 case FCEQ: |
| 2635 Format(instr, "fceq.'t 'wd, 'ws, 'wt"); |
| 2636 break; |
| 2637 case FCUEQ: |
| 2638 Format(instr, "fcueq.'t 'wd, 'ws, 'wt"); |
| 2639 break; |
| 2640 case FCLT: |
| 2641 Format(instr, "fclt.'t 'wd, 'ws, 'wt"); |
| 2642 break; |
| 2643 case FCULT: |
| 2644 Format(instr, "fcult.'t 'wd, 'ws, 'wt"); |
| 2645 break; |
| 2646 case FCLE: |
| 2647 Format(instr, "fcle.'t 'wd, 'ws, 'wt"); |
| 2648 break; |
| 2649 case FCULE: |
| 2650 Format(instr, "fcule.'t 'wd, 'ws, 'wt"); |
| 2651 break; |
| 2652 case FSAF: |
| 2653 Format(instr, "fsaf.'t 'wd, 'ws, 'wt"); |
| 2654 break; |
| 2655 case FSUN: |
| 2656 Format(instr, "fsun.'t 'wd, 'ws, 'wt"); |
| 2657 break; |
| 2658 case FSEQ: |
| 2659 Format(instr, "fseq.'t 'wd, 'ws, 'wt"); |
| 2660 break; |
| 2661 case FSUEQ: |
| 2662 Format(instr, "fsueq.'t 'wd, 'ws, 'wt"); |
| 2663 break; |
| 2664 case FSLT: |
| 2665 Format(instr, "fslt.'t 'wd, 'ws, 'wt"); |
| 2666 break; |
| 2667 case FSULT: |
| 2668 Format(instr, "fsult.'t 'wd, 'ws, 'wt"); |
| 2669 break; |
| 2670 case FSLE: |
| 2671 Format(instr, "fsle.'t 'wd, 'ws, 'wt"); |
| 2672 break; |
| 2673 case FSULE: |
| 2674 Format(instr, "fsule.'t 'wd, 'ws, 'wt"); |
| 2675 break; |
| 2676 case FADD: |
| 2677 Format(instr, "fadd.'t 'wd, 'ws, 'wt"); |
| 2678 break; |
| 2679 case FSUB: |
| 2680 Format(instr, "fsub.'t 'wd, 'ws, 'wt"); |
| 2681 break; |
| 2682 case FMUL: |
| 2683 Format(instr, "fmul.'t 'wd, 'ws, 'wt"); |
| 2684 break; |
| 2685 case FDIV: |
| 2686 Format(instr, "fdiv.'t 'wd, 'ws, 'wt"); |
| 2687 break; |
| 2688 case FMADD: |
| 2689 Format(instr, "fmadd.'t 'wd, 'ws, 'wt"); |
| 2690 break; |
| 2691 case FMSUB: |
| 2692 Format(instr, "fmsub.'t 'wd, 'ws, 'wt"); |
| 2693 break; |
| 2694 case FEXP2: |
| 2695 Format(instr, "fexp2.'t 'wd, 'ws, 'wt"); |
| 2696 break; |
| 2697 case FEXDO: |
| 2698 Format(instr, "fexdo.'t 'wd, 'ws, 'wt"); |
| 2699 break; |
| 2700 case FTQ: |
| 2701 Format(instr, "ftq.'t 'wd, 'ws, 'wt"); |
| 2702 break; |
| 2703 case FMIN: |
| 2704 Format(instr, "fmin.'t 'wd, 'ws, 'wt"); |
| 2705 break; |
| 2706 case FMIN_A: |
| 2707 Format(instr, "fmin_a.'t 'wd, 'ws, 'wt"); |
| 2708 break; |
| 2709 case FMAX: |
| 2710 Format(instr, "fmax.'t 'wd, 'ws, 'wt"); |
| 2711 break; |
| 2712 case FMAX_A: |
| 2713 Format(instr, "fmax_a.'t 'wd, 'ws, 'wt"); |
| 2714 break; |
| 2715 case FCOR: |
| 2716 Format(instr, "fcor.'t 'wd, 'ws, 'wt"); |
| 2717 break; |
| 2718 case FCUNE: |
| 2719 Format(instr, "fcune.'t 'wd, 'ws, 'wt"); |
| 2720 break; |
| 2721 case FCNE: |
| 2722 Format(instr, "fcne.'t 'wd, 'ws, 'wt"); |
| 2723 break; |
| 2724 case MUL_Q: |
| 2725 Format(instr, "mul_q.'t 'wd, 'ws, 'wt"); |
| 2726 break; |
| 2727 case MADD_Q: |
| 2728 Format(instr, "madd_q.'t 'wd, 'ws, 'wt"); |
| 2729 break; |
| 2730 case MSUB_Q: |
| 2731 Format(instr, "msub_q.'t 'wd, 'ws, 'wt"); |
| 2732 break; |
| 2733 case FSOR: |
| 2734 Format(instr, "fsor.'t 'wd, 'ws, 'wt"); |
| 2735 break; |
| 2736 case FSUNE: |
| 2737 Format(instr, "fsune.'t 'wd, 'ws, 'wt"); |
| 2738 break; |
| 2739 case FSNE: |
| 2740 Format(instr, "fsne.'t 'wd, 'ws, 'wt"); |
| 2741 break; |
| 2742 case MULR_Q: |
| 2743 Format(instr, "mulr_q.'t 'wd, 'ws, 'wt"); |
| 2744 break; |
| 2745 case MADDR_Q: |
| 2746 Format(instr, "maddr_q.'t 'wd, 'ws, 'wt"); |
| 2747 break; |
| 2748 case MSUBR_Q: |
| 2749 Format(instr, "msubr_q.'t 'wd, 'ws, 'wt"); |
| 2750 break; |
| 2751 default: |
| 2752 UNREACHABLE(); |
| 2753 } |
| 2754 } |
| 2755 |
| 2756 void Decoder::DecodeTypeMsaVec(Instruction* instr) { |
| 2757 uint32_t opcode = instr->InstructionBits() & kMsaVECMask; |
| 2758 switch (opcode) { |
| 2759 case AND_V: |
| 2760 Format(instr, "and.v 'wd, 'ws, 'wt"); |
| 2761 break; |
| 2762 case OR_V: |
| 2763 Format(instr, "or.v 'wd, 'ws, 'wt"); |
| 2764 break; |
| 2765 case NOR_V: |
| 2766 Format(instr, "nor.v 'wd, 'ws, 'wt"); |
| 2767 break; |
| 2768 case XOR_V: |
| 2769 Format(instr, "xor.v 'wd, 'ws, 'wt"); |
| 2770 break; |
| 2771 case BMNZ_V: |
| 2772 Format(instr, "bmnz.v 'wd, 'ws, 'wt"); |
| 2773 break; |
| 2774 case BMZ_V: |
| 2775 Format(instr, "bmz.v 'wd, 'ws, 'wt"); |
| 2776 break; |
| 2777 case BSEL_V: |
| 2778 Format(instr, "bsel.v 'wd, 'ws, 'wt"); |
| 2779 break; |
| 2780 default: |
| 2781 UNREACHABLE(); |
| 2782 } |
| 2783 } |
| 2784 |
| 2785 void Decoder::DecodeTypeMsa2R(Instruction* instr) { |
| 2786 uint32_t opcode = instr->InstructionBits() & kMsa2RMask; |
| 2787 switch (opcode) { |
| 2788 case FILL: { |
| 2789 Format(instr, "fill.'t 'wd, "); |
| 2790 PrintRegister(instr->WsValue()); // rs value is in ws field |
| 2791 } break; |
| 2792 case PCNT: |
| 2793 Format(instr, "pcnt.'t 'wd, 'ws"); |
| 2794 break; |
| 2795 case NLOC: |
| 2796 Format(instr, "nloc.'t 'wd, 'ws"); |
| 2797 break; |
| 2798 case NLZC: |
| 2799 Format(instr, "nlzc.'t 'wd, 'ws"); |
| 2800 break; |
| 2801 default: |
| 2802 UNREACHABLE(); |
| 2803 } |
| 2804 } |
| 2805 |
| 2806 void Decoder::DecodeTypeMsa2RF(Instruction* instr) { |
| 2807 uint32_t opcode = instr->InstructionBits() & kMsa2RFMask; |
| 2808 switch (opcode) { |
| 2809 case FCLASS: |
| 2810 Format(instr, "fclass.'t 'wd, 'ws"); |
| 2811 break; |
| 2812 case FTRUNC_S: |
| 2813 Format(instr, "ftrunc_s.'t 'wd, 'ws"); |
| 2814 break; |
| 2815 case FTRUNC_U: |
| 2816 Format(instr, "ftrunc_u.'t 'wd, 'ws"); |
| 2817 break; |
| 2818 case FSQRT: |
| 2819 Format(instr, "fsqrt.'t 'wd, 'ws"); |
| 2820 break; |
| 2821 case FRSQRT: |
| 2822 Format(instr, "frsqrt.'t 'wd, 'ws"); |
| 2823 break; |
| 2824 case FRCP: |
| 2825 Format(instr, "frcp.'t 'wd, 'ws"); |
| 2826 break; |
| 2827 case FRINT: |
| 2828 Format(instr, "frint.'t 'wd, 'ws"); |
| 2829 break; |
| 2830 case FLOG2: |
| 2831 Format(instr, "flog2.'t 'wd, 'ws"); |
| 2832 break; |
| 2833 case FEXUPL: |
| 2834 Format(instr, "fexupl.'t 'wd, 'ws"); |
| 2835 break; |
| 2836 case FEXUPR: |
| 2837 Format(instr, "fexupr.'t 'wd, 'ws"); |
| 2838 break; |
| 2839 case FFQL: |
| 2840 Format(instr, "ffql.'t 'wd, 'ws"); |
| 2841 break; |
| 2842 case FFQR: |
| 2843 Format(instr, "ffqr.'t 'wd, 'ws"); |
| 2844 break; |
| 2845 case FTINT_S: |
| 2846 Format(instr, "ftint_s.'t 'wd, 'ws"); |
| 2847 break; |
| 2848 case FTINT_U: |
| 2849 Format(instr, "ftint_u.'t 'wd, 'ws"); |
| 2850 break; |
| 2851 case FFINT_S: |
| 2852 Format(instr, "ffint_s.'t 'wd, 'ws"); |
| 2853 break; |
| 2854 case FFINT_U: |
| 2855 Format(instr, "ffint_u.'t 'wd, 'ws"); |
| 2856 break; |
| 2857 default: |
| 2858 UNREACHABLE(); |
| 2859 } |
| 2860 } |
| 2861 |
1938 | 2862 |
1939 // Disassemble the instruction at *instr_ptr into the output buffer. | 2863 // Disassemble the instruction at *instr_ptr into the output buffer. |
1940 // All instructions are one word long, except for the simulator | 2864 // All instructions are one word long, except for the simulator |
1941 // psuedo-instruction stop(msg). For that one special case, we return | 2865 // psuedo-instruction stop(msg). For that one special case, we return |
1942 // size larger than one kInstrSize. | 2866 // size larger than one kInstrSize. |
1943 int Decoder::InstructionDecode(byte* instr_ptr) { | 2867 int Decoder::InstructionDecode(byte* instr_ptr) { |
1944 Instruction* instr = Instruction::At(instr_ptr); | 2868 Instruction* instr = Instruction::At(instr_ptr); |
1945 // Print raw instruction bytes. | 2869 // Print raw instruction bytes. |
1946 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 2870 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
1947 "%08x ", | 2871 "%08x ", |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2043 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 2967 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
2044 } | 2968 } |
2045 } | 2969 } |
2046 | 2970 |
2047 | 2971 |
2048 #undef UNSUPPORTED | 2972 #undef UNSUPPORTED |
2049 | 2973 |
2050 } // namespace disasm | 2974 } // namespace disasm |
2051 | 2975 |
2052 #endif // V8_TARGET_ARCH_MIPS64 | 2976 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |