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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 out_buffer_[out_buffer_pos_] = '\0'; | 52 out_buffer_[out_buffer_pos_] = '\0'; |
53 } | 53 } |
54 | 54 |
55 ~Decoder() {} | 55 ~Decoder() {} |
56 | 56 |
57 // Writes one disassembled instruction into 'buffer' (0-terminated). | 57 // Writes one disassembled instruction into 'buffer' (0-terminated). |
58 // Returns the length of the disassembled machine instruction in bytes. | 58 // Returns the length of the disassembled machine instruction in bytes. |
59 int InstructionDecode(byte* instruction); | 59 int InstructionDecode(byte* instruction); |
60 | 60 |
61 private: | 61 private: |
| 62 const uint32_t kMsaI8Mask = ((3U << 24) | ((1 << 6) - 1)); |
| 63 const uint32_t kMsaI5Mask = ((7U << 23) | ((1 << 6) - 1)); |
| 64 const uint32_t kMsaMI10Mask = (15U << 2); |
| 65 const uint32_t kMsaBITMask = ((7U << 23) | ((1 << 6) - 1)); |
| 66 const uint32_t kMsaELMMask = (15U << 22); |
| 67 const uint32_t kMsa3RMask = ((7U << 23) | ((1 << 6) - 1)); |
| 68 const uint32_t kMsa3RFMask = ((15U << 22) | ((1 << 6) - 1)); |
| 69 const uint32_t kMsaVECMask = (23U << 21); |
| 70 const uint32_t kMsa2RMask = (7U << 18); |
| 71 const uint32_t kMsa2RFMask = (15U << 17); |
| 72 |
62 // Bottleneck functions to print into the out_buffer. | 73 // Bottleneck functions to print into the out_buffer. |
63 void PrintChar(const char ch); | 74 void PrintChar(const char ch); |
64 void Print(const char* str); | 75 void Print(const char* str); |
65 | 76 |
66 // Printing of common values. | 77 // Printing of common values. |
67 void PrintRegister(int reg); | 78 void PrintRegister(int reg); |
68 void PrintFPURegister(int freg); | 79 void PrintFPURegister(int freg); |
| 80 void PrintMSARegister(int wreg); |
69 void PrintFPUStatusRegister(int freg); | 81 void PrintFPUStatusRegister(int freg); |
| 82 void PrintMSAControlRegister(int creg); |
70 void PrintRs(Instruction* instr); | 83 void PrintRs(Instruction* instr); |
71 void PrintRt(Instruction* instr); | 84 void PrintRt(Instruction* instr); |
72 void PrintRd(Instruction* instr); | 85 void PrintRd(Instruction* instr); |
73 void PrintFs(Instruction* instr); | 86 void PrintFs(Instruction* instr); |
74 void PrintFt(Instruction* instr); | 87 void PrintFt(Instruction* instr); |
75 void PrintFd(Instruction* instr); | 88 void PrintFd(Instruction* instr); |
76 void PrintSa(Instruction* instr); | 89 void PrintSa(Instruction* instr); |
77 void PrintLsaSa(Instruction* instr); | 90 void PrintLsaSa(Instruction* instr); |
78 void PrintSd(Instruction* instr); | 91 void PrintSd(Instruction* instr); |
79 void PrintSs1(Instruction* instr); | 92 void PrintSs1(Instruction* instr); |
(...skipping 13 matching lines...) Expand all Loading... |
93 void PrintSImm19(Instruction* instr); | 106 void PrintSImm19(Instruction* instr); |
94 void PrintXImm21(Instruction* instr); | 107 void PrintXImm21(Instruction* instr); |
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. |
| 116 void PrintMsaDataFormat(Instruction* instr); |
| 117 void PrintMsaXImm8(Instruction* instr); |
| 118 void PrintMsaImm8(Instruction* instr); |
| 119 void PrintMsaImm5(Instruction* instr); |
| 120 void PrintMsaSImm5(Instruction* instr); |
| 121 void PrintMsaSImm10(Instruction* instr, bool is_mi10 = false); |
| 122 void PrintMsaImmBit(Instruction* instr); |
| 123 void PrintMsaImmElm(Instruction* instr); |
| 124 void PrintMsaCopy(Instruction* instr); |
103 // Printing of instruction name. | 125 // Printing of instruction name. |
104 void PrintInstructionName(Instruction* instr); | 126 void PrintInstructionName(Instruction* instr); |
105 | 127 |
106 // Handle formatting of instructions and their options. | 128 // Handle formatting of instructions and their options. |
107 int FormatRegister(Instruction* instr, const char* option); | 129 int FormatRegister(Instruction* instr, const char* option); |
108 int FormatFPURegister(Instruction* instr, const char* option); | 130 int FormatFPURegister(Instruction* instr, const char* option); |
| 131 int FormatMSARegister(Instruction* instr, const char* option); |
109 int FormatOption(Instruction* instr, const char* option); | 132 int FormatOption(Instruction* instr, const char* option); |
110 void Format(Instruction* instr, const char* format); | 133 void Format(Instruction* instr, const char* format); |
111 void Unknown(Instruction* instr); | 134 void Unknown(Instruction* instr); |
112 | 135 |
113 | 136 |
114 // Each of these functions decodes one particular instruction type. | 137 // Each of these functions decodes one particular instruction type. |
115 bool DecodeTypeRegisterRsType(Instruction* instr); | 138 bool DecodeTypeRegisterRsType(Instruction* instr); |
116 void DecodeTypeRegisterSRsType(Instruction* instr); | 139 void DecodeTypeRegisterSRsType(Instruction* instr); |
117 void DecodeTypeRegisterDRsType(Instruction* instr); | 140 void DecodeTypeRegisterDRsType(Instruction* instr); |
118 void DecodeTypeRegisterLRsType(Instruction* instr); | 141 void DecodeTypeRegisterLRsType(Instruction* instr); |
119 void DecodeTypeRegisterWRsType(Instruction* instr); | 142 void DecodeTypeRegisterWRsType(Instruction* instr); |
120 void DecodeTypeRegisterSPECIAL(Instruction* instr); | 143 void DecodeTypeRegisterSPECIAL(Instruction* instr); |
121 void DecodeTypeRegisterSPECIAL2(Instruction* instr); | 144 void DecodeTypeRegisterSPECIAL2(Instruction* instr); |
122 void DecodeTypeRegisterSPECIAL3(Instruction* instr); | 145 void DecodeTypeRegisterSPECIAL3(Instruction* instr); |
123 void DecodeTypeRegister(Instruction* instr); | 146 void DecodeTypeRegister(Instruction* instr); |
124 void DecodeTypeImmediate(Instruction* instr); | 147 void DecodeTypeImmediate(Instruction* instr); |
125 void DecodeTypeJump(Instruction* instr); | 148 void DecodeTypeJump(Instruction* instr); |
| 149 void DecodeTypeMsaI8(Instruction* instr); |
| 150 void DecodeTypeMsaI5(Instruction* instr); |
| 151 void DecodeTypeMsaI10(Instruction* instr); |
| 152 void DecodeTypeMsaELM(Instruction* instr); |
| 153 void DecodeTypeMsaBIT(Instruction* instr); |
| 154 void DecodeTypeMsaMI10(Instruction* instr); |
| 155 void DecodeTypeMsa3R(Instruction* instr); |
| 156 void DecodeTypeMsa3RF(Instruction* instr); |
| 157 void DecodeTypeMsaVec(Instruction* instr); |
| 158 void DecodeTypeMsa2R(Instruction* instr); |
| 159 void DecodeTypeMsa2RF(Instruction* instr); |
126 | 160 |
127 const disasm::NameConverter& converter_; | 161 const disasm::NameConverter& converter_; |
128 v8::internal::Vector<char> out_buffer_; | 162 v8::internal::Vector<char> out_buffer_; |
129 int out_buffer_pos_; | 163 int out_buffer_pos_; |
130 | 164 |
131 DISALLOW_COPY_AND_ASSIGN(Decoder); | 165 DISALLOW_COPY_AND_ASSIGN(Decoder); |
132 }; | 166 }; |
133 | 167 |
134 | 168 |
135 // Support for assertions in the Decoder formatting functions. | 169 // Support for assertions in the Decoder formatting functions. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 int reg = instr->RdValue(); | 210 int reg = instr->RdValue(); |
177 PrintRegister(reg); | 211 PrintRegister(reg); |
178 } | 212 } |
179 | 213 |
180 | 214 |
181 // Print the FPUregister name according to the active name converter. | 215 // Print the FPUregister name according to the active name converter. |
182 void Decoder::PrintFPURegister(int freg) { | 216 void Decoder::PrintFPURegister(int freg) { |
183 Print(converter_.NameOfXMMRegister(freg)); | 217 Print(converter_.NameOfXMMRegister(freg)); |
184 } | 218 } |
185 | 219 |
| 220 void Decoder::PrintMSARegister(int wreg) { Print(MSARegisters::Name(wreg)); } |
186 | 221 |
187 void Decoder::PrintFPUStatusRegister(int freg) { | 222 void Decoder::PrintFPUStatusRegister(int freg) { |
188 switch (freg) { | 223 switch (freg) { |
189 case kFCSRRegister: | 224 case kFCSRRegister: |
190 Print("FCSR"); | 225 Print("FCSR"); |
191 break; | 226 break; |
192 default: | 227 default: |
193 Print(converter_.NameOfXMMRegister(freg)); | 228 Print(converter_.NameOfXMMRegister(freg)); |
194 } | 229 } |
195 } | 230 } |
196 | 231 |
| 232 void Decoder::PrintMSAControlRegister(int creg) { |
| 233 switch (creg) { |
| 234 case kMSAIRRegister: |
| 235 Print("MSAIR"); |
| 236 break; |
| 237 case kMSACSRRegister: |
| 238 Print("MSACSR"); |
| 239 break; |
| 240 default: |
| 241 Print("no_msacreg"); |
| 242 } |
| 243 } |
197 | 244 |
198 void Decoder::PrintFs(Instruction* instr) { | 245 void Decoder::PrintFs(Instruction* instr) { |
199 int freg = instr->RsValue(); | 246 int freg = instr->RsValue(); |
200 PrintFPURegister(freg); | 247 PrintFPURegister(freg); |
201 } | 248 } |
202 | 249 |
203 | 250 |
204 void Decoder::PrintFt(Instruction* instr) { | 251 void Decoder::PrintFt(Instruction* instr) { |
205 int freg = instr->RtValue(); | 252 int freg = instr->RtValue(); |
206 PrintFPURegister(freg); | 253 PrintFPURegister(freg); |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 int32_t code = instr->Bits(15, 6); | 481 int32_t code = instr->Bits(15, 6); |
435 out_buffer_pos_ += | 482 out_buffer_pos_ += |
436 SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code); | 483 SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code); |
437 break; | 484 break; |
438 } | 485 } |
439 default: // Not a break or trap instruction. | 486 default: // Not a break or trap instruction. |
440 break; | 487 break; |
441 } | 488 } |
442 } | 489 } |
443 | 490 |
| 491 void Decoder::PrintMsaXImm8(Instruction* instr) { |
| 492 int32_t imm = instr->MsaImm8Value(); |
| 493 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
| 494 } |
| 495 |
| 496 void Decoder::PrintMsaImm8(Instruction* instr) { |
| 497 int32_t imm = instr->MsaImm8Value(); |
| 498 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); |
| 499 } |
| 500 |
| 501 void Decoder::PrintMsaImm5(Instruction* instr) { |
| 502 int32_t imm = instr->MsaImm5Value(); |
| 503 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); |
| 504 } |
| 505 |
| 506 void Decoder::PrintMsaSImm5(Instruction* instr) { |
| 507 int32_t imm = instr->MsaImm5Value(); |
| 508 imm <<= (32 - kMsaImm5Bits); |
| 509 imm >>= (32 - kMsaImm5Bits); |
| 510 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); |
| 511 } |
| 512 |
| 513 void Decoder::PrintMsaSImm10(Instruction* instr, bool is_mi10) { |
| 514 int32_t imm = is_mi10 ? instr->MsaImmMI10Value() : instr->MsaImm10Value(); |
| 515 imm <<= (32 - kMsaImm10Bits); |
| 516 imm >>= (32 - kMsaImm10Bits); |
| 517 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); |
| 518 } |
| 519 |
| 520 void Decoder::PrintMsaImmBit(Instruction* instr) { |
| 521 int32_t m = instr->MsaBitMValue(); |
| 522 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", m); |
| 523 } |
| 524 |
| 525 void Decoder::PrintMsaImmElm(Instruction* instr) { |
| 526 int32_t n = instr->MsaElmNValue(); |
| 527 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", n); |
| 528 } |
| 529 |
| 530 void Decoder::PrintMsaCopy(Instruction* instr) { |
| 531 int32_t rd = instr->WdValue(); |
| 532 int32_t ws = instr->WsValue(); |
| 533 int32_t n = instr->MsaElmNValue(); |
| 534 out_buffer_pos_ += |
| 535 SNPrintF(out_buffer_ + out_buffer_pos_, "%s, %s[%u]", |
| 536 converter_.NameOfCPURegister(rd), MSARegisters::Name(ws), n); |
| 537 } |
444 | 538 |
445 void Decoder::PrintFormat(Instruction* instr) { | 539 void Decoder::PrintFormat(Instruction* instr) { |
446 char formatLetter = ' '; | 540 char formatLetter = ' '; |
447 switch (instr->RsFieldRaw()) { | 541 switch (instr->RsFieldRaw()) { |
448 case S: | 542 case S: |
449 formatLetter = 's'; | 543 formatLetter = 's'; |
450 break; | 544 break; |
451 case D: | 545 case D: |
452 formatLetter = 'd'; | 546 formatLetter = 'd'; |
453 break; | 547 break; |
454 case W: | 548 case W: |
455 formatLetter = 'w'; | 549 formatLetter = 'w'; |
456 break; | 550 break; |
457 case L: | 551 case L: |
458 formatLetter = 'l'; | 552 formatLetter = 'l'; |
459 break; | 553 break; |
460 default: | 554 default: |
461 UNREACHABLE(); | 555 UNREACHABLE(); |
462 break; | 556 break; |
463 } | 557 } |
464 PrintChar(formatLetter); | 558 PrintChar(formatLetter); |
465 } | 559 } |
466 | 560 |
| 561 void Decoder::PrintMsaDataFormat(Instruction* instr) { |
| 562 DCHECK(instr->IsMSAInstr()); |
| 563 char df = ' '; |
| 564 if (instr->IsMSABranchInstr()) { |
| 565 switch (instr->RsFieldRaw()) { |
| 566 case BZ_V: |
| 567 case BNZ_V: |
| 568 df = 'v'; |
| 569 break; |
| 570 case BZ_B: |
| 571 case BNZ_B: |
| 572 df = 'b'; |
| 573 break; |
| 574 case BZ_H: |
| 575 case BNZ_H: |
| 576 df = 'h'; |
| 577 break; |
| 578 case BZ_W: |
| 579 case BNZ_W: |
| 580 df = 'w'; |
| 581 break; |
| 582 case BZ_D: |
| 583 case BNZ_D: |
| 584 df = 'd'; |
| 585 break; |
| 586 default: |
| 587 UNREACHABLE(); |
| 588 break; |
| 589 } |
| 590 } else { |
| 591 char DF[] = {'b', 'h', 'w', 'd'}; |
| 592 switch (instr->MSAMinorOpcodeField()) { |
| 593 case kMsaMinorI5: |
| 594 case kMsaMinorI10: |
| 595 case kMsaMinor3R: |
| 596 df = DF[instr->Bits(22, 21)]; |
| 597 break; |
| 598 case kMsaMinorMI10: |
| 599 df = DF[instr->Bits(1, 0)]; |
| 600 break; |
| 601 case kMsaMinorBIT: |
| 602 df = DF[instr->MsaBitDf()]; |
| 603 break; |
| 604 case kMsaMinorELM: |
| 605 df = DF[instr->MsaElmDf()]; |
| 606 break; |
| 607 case kMsaMinor3RF: { |
| 608 uint32_t opcode = instr->InstructionBits() & kMsa3RFMask; |
| 609 switch (opcode) { |
| 610 case FEXDO: |
| 611 case FTQ: |
| 612 case MUL_Q: |
| 613 case MADD_Q: |
| 614 case MSUB_Q: |
| 615 case MULR_Q: |
| 616 case MADDR_Q: |
| 617 case MSUBR_Q: |
| 618 df = DF[1 + instr->Bit(21)]; |
| 619 break; |
| 620 default: |
| 621 df = DF[2 + instr->Bit(21)]; |
| 622 break; |
| 623 } |
| 624 } break; |
| 625 case kMsaMinor2R: |
| 626 df = DF[instr->Bits(17, 16)]; |
| 627 break; |
| 628 case kMsaMinor2RF: |
| 629 df = DF[2 + instr->Bit(16)]; |
| 630 break; |
| 631 default: |
| 632 UNREACHABLE(); |
| 633 break; |
| 634 } |
| 635 } |
| 636 |
| 637 PrintChar(df); |
| 638 } |
467 | 639 |
468 // Printing of instruction name. | 640 // Printing of instruction name. |
469 void Decoder::PrintInstructionName(Instruction* instr) { | 641 void Decoder::PrintInstructionName(Instruction* instr) { |
470 } | 642 } |
471 | 643 |
472 | 644 |
473 // Handle all register based formatting in this function to reduce the | 645 // Handle all register based formatting in this function to reduce the |
474 // complexity of FormatOption. | 646 // complexity of FormatOption. |
475 int Decoder::FormatRegister(Instruction* instr, const char* format) { | 647 int Decoder::FormatRegister(Instruction* instr, const char* format) { |
476 DCHECK(format[0] == 'r'); | 648 DCHECK(format[0] == 'r'); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 } else if (format[1] == 'r') { // 'fr: fr register. | 702 } else if (format[1] == 'r') { // 'fr: fr register. |
531 int reg = instr->FrValue(); | 703 int reg = instr->FrValue(); |
532 PrintFPURegister(reg); | 704 PrintFPURegister(reg); |
533 return 2; | 705 return 2; |
534 } | 706 } |
535 } | 707 } |
536 UNREACHABLE(); | 708 UNREACHABLE(); |
537 return -1; | 709 return -1; |
538 } | 710 } |
539 | 711 |
| 712 // Handle all MSARegister based formatting in this function to reduce the |
| 713 // complexity of FormatOption. |
| 714 int Decoder::FormatMSARegister(Instruction* instr, const char* format) { |
| 715 DCHECK(format[0] == 'w'); |
| 716 if (format[1] == 's') { |
| 717 int reg = instr->WsValue(); |
| 718 PrintMSARegister(reg); |
| 719 return 2; |
| 720 } else if (format[1] == 't') { |
| 721 int reg = instr->WtValue(); |
| 722 PrintMSARegister(reg); |
| 723 return 2; |
| 724 } else if (format[1] == 'd') { |
| 725 int reg = instr->WdValue(); |
| 726 PrintMSARegister(reg); |
| 727 return 2; |
| 728 } |
| 729 |
| 730 UNREACHABLE(); |
| 731 return -1; |
| 732 } |
540 | 733 |
541 // FormatOption takes a formatting string and interprets it based on | 734 // FormatOption takes a formatting string and interprets it based on |
542 // the current instructions. The format string points to the first | 735 // the current instructions. The format string points to the first |
543 // character of the option string (the option escape has already been | 736 // character of the option string (the option escape has already been |
544 // consumed by the caller.) FormatOption returns the number of | 737 // consumed by the caller.) FormatOption returns the number of |
545 // characters that were consumed from the formatting string. | 738 // characters that were consumed from the formatting string. |
546 int Decoder::FormatOption(Instruction* instr, const char* format) { | 739 int Decoder::FormatOption(Instruction* instr, const char* format) { |
547 switch (format[0]) { | 740 switch (format[0]) { |
548 case 'c': { // 'code for break or trap instructions. | 741 case 'c': { // 'code for break or trap instructions. |
549 DCHECK(STRING_STARTS_WITH(format, "code")); | 742 DCHECK(STRING_STARTS_WITH(format, "code")); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 case 's': | 799 case 's': |
607 DCHECK(STRING_STARTS_WITH(format, "imm19s")); | 800 DCHECK(STRING_STARTS_WITH(format, "imm19s")); |
608 PrintSImm19(instr); | 801 PrintSImm19(instr); |
609 break; | 802 break; |
610 case 'x': | 803 case 'x': |
611 DCHECK(STRING_STARTS_WITH(format, "imm19x")); | 804 DCHECK(STRING_STARTS_WITH(format, "imm19x")); |
612 PrintXImm19(instr); | 805 PrintXImm19(instr); |
613 break; | 806 break; |
614 } | 807 } |
615 return 6; | 808 return 6; |
| 809 } else if (format[4] == '0' && format[5] == 's') { |
| 810 DCHECK(STRING_STARTS_WITH(format, "imm10s")); |
| 811 if (format[6] == '1') { |
| 812 DCHECK(STRING_STARTS_WITH(format, "imm10s1")); |
| 813 PrintMsaSImm10(instr, false); |
| 814 } else if (format[6] == '2') { |
| 815 DCHECK(STRING_STARTS_WITH(format, "imm10s2")); |
| 816 PrintMsaSImm10(instr, true); |
| 817 } |
| 818 return 7; |
616 } | 819 } |
617 } else if (format[3] == '2' && format[4] == '1') { | 820 } else if (format[3] == '2' && format[4] == '1') { |
618 DCHECK(STRING_STARTS_WITH(format, "imm21")); | 821 DCHECK(STRING_STARTS_WITH(format, "imm21")); |
619 switch (format[5]) { | 822 switch (format[5]) { |
620 case 's': | 823 case 's': |
621 DCHECK(STRING_STARTS_WITH(format, "imm21s")); | 824 DCHECK(STRING_STARTS_WITH(format, "imm21s")); |
622 PrintSImm21(instr); | 825 PrintSImm21(instr); |
623 break; | 826 break; |
624 case 'x': | 827 case 'x': |
625 DCHECK(STRING_STARTS_WITH(format, "imm21x")); | 828 DCHECK(STRING_STARTS_WITH(format, "imm21x")); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 } | 877 } |
675 } | 878 } |
676 } | 879 } |
677 case 'j': { // Absolute address for jump instructions. | 880 case 'j': { // Absolute address for jump instructions. |
678 DCHECK(STRING_STARTS_WITH(format, "imm26j")); | 881 DCHECK(STRING_STARTS_WITH(format, "imm26j")); |
679 PrintPCImm26(instr); | 882 PrintPCImm26(instr); |
680 break; | 883 break; |
681 } | 884 } |
682 } | 885 } |
683 return 6; | 886 return 6; |
| 887 } else if (format[3] == '5') { |
| 888 DCHECK(STRING_STARTS_WITH(format, "imm5")); |
| 889 if (format[4] == 'u') { |
| 890 DCHECK(STRING_STARTS_WITH(format, "imm5u")); |
| 891 PrintMsaImm5(instr); |
| 892 } else if (format[4] == 's') { |
| 893 DCHECK(STRING_STARTS_WITH(format, "imm5s")); |
| 894 PrintMsaSImm5(instr); |
| 895 } |
| 896 return 5; |
| 897 } else if (format[3] == '8') { |
| 898 DCHECK(STRING_STARTS_WITH(format, "imm8")); |
| 899 PrintMsaImm8(instr); |
| 900 return 4; |
| 901 } else if (format[3] == 'b') { |
| 902 DCHECK(STRING_STARTS_WITH(format, "immb")); |
| 903 PrintMsaImmBit(instr); |
| 904 return 4; |
| 905 } else if (format[3] == 'e') { |
| 906 DCHECK(STRING_STARTS_WITH(format, "imme")); |
| 907 PrintMsaImmElm(instr); |
| 908 return 4; |
684 } | 909 } |
685 } | 910 } |
686 case 'r': { // 'r: registers. | 911 case 'r': { // 'r: registers. |
687 return FormatRegister(instr, format); | 912 return FormatRegister(instr, format); |
688 } | 913 } |
689 case 'f': { // 'f: FPUregisters. | 914 case 'f': { // 'f: FPUregisters. |
690 return FormatFPURegister(instr, format); | 915 return FormatFPURegister(instr, format); |
691 } | 916 } |
| 917 case 'w': { // 'w: MSA Register |
| 918 return FormatMSARegister(instr, format); |
| 919 } |
692 case 's': { // 'sa. | 920 case 's': { // 'sa. |
693 switch (format[1]) { | 921 switch (format[1]) { |
694 case 'a': | 922 case 'a': |
695 if (format[2] == '2') { | 923 if (format[2] == '2') { |
696 DCHECK(STRING_STARTS_WITH(format, "sa2")); // 'sa2 | 924 DCHECK(STRING_STARTS_WITH(format, "sa2")); // 'sa2 |
697 PrintLsaSa(instr); | 925 PrintLsaSa(instr); |
698 return 3; | 926 return 3; |
699 } else { | 927 } else { |
700 DCHECK(STRING_STARTS_WITH(format, "sa")); | 928 DCHECK(STRING_STARTS_WITH(format, "sa")); |
701 PrintSa(instr); | 929 PrintSa(instr); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 } | 965 } |
738 } | 966 } |
739 } | 967 } |
740 } | 968 } |
741 case 'C': { // 'Cc - Special for c.xx.d cc field. | 969 case 'C': { // 'Cc - Special for c.xx.d cc field. |
742 DCHECK(STRING_STARTS_WITH(format, "Cc")); | 970 DCHECK(STRING_STARTS_WITH(format, "Cc")); |
743 PrintCc(instr); | 971 PrintCc(instr); |
744 return 2; | 972 return 2; |
745 } | 973 } |
746 case 't': | 974 case 't': |
747 PrintFormat(instr); | 975 if (instr->IsMSAInstr()) { |
| 976 PrintMsaDataFormat(instr); |
| 977 } else { |
| 978 PrintFormat(instr); |
| 979 } |
748 return 1; | 980 return 1; |
749 } | 981 } |
750 UNREACHABLE(); | 982 UNREACHABLE(); |
751 return -1; | 983 return -1; |
752 } | 984 } |
753 | 985 |
754 | 986 |
755 // Format takes a formatting string for a whole instruction and prints it into | 987 // Format takes a formatting string for a whole instruction and prints it into |
756 // the output buffer. All escaped options are handed to FormatOption to be | 988 // the output buffer. All escaped options are handed to FormatOption to be |
757 // parsed further. | 989 // parsed further. |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1394 break; | 1626 break; |
1395 case SPECIAL: | 1627 case SPECIAL: |
1396 DecodeTypeRegisterSPECIAL(instr); | 1628 DecodeTypeRegisterSPECIAL(instr); |
1397 break; | 1629 break; |
1398 case SPECIAL2: | 1630 case SPECIAL2: |
1399 DecodeTypeRegisterSPECIAL2(instr); | 1631 DecodeTypeRegisterSPECIAL2(instr); |
1400 break; | 1632 break; |
1401 case SPECIAL3: | 1633 case SPECIAL3: |
1402 DecodeTypeRegisterSPECIAL3(instr); | 1634 DecodeTypeRegisterSPECIAL3(instr); |
1403 break; | 1635 break; |
| 1636 case MSA: |
| 1637 switch (instr->MSAMinorOpcodeField()) { |
| 1638 case kMsaMinor3R: |
| 1639 DecodeTypeMsa3R(instr); |
| 1640 break; |
| 1641 case kMsaMinor3RF: |
| 1642 DecodeTypeMsa3RF(instr); |
| 1643 break; |
| 1644 case kMsaMinorVEC: |
| 1645 DecodeTypeMsaVec(instr); |
| 1646 break; |
| 1647 case kMsaMinor2R: |
| 1648 DecodeTypeMsa2R(instr); |
| 1649 break; |
| 1650 case kMsaMinor2RF: |
| 1651 DecodeTypeMsa2RF(instr); |
| 1652 break; |
| 1653 default: |
| 1654 UNREACHABLE(); |
| 1655 } |
| 1656 break; |
1404 default: | 1657 default: |
1405 UNREACHABLE(); | 1658 UNREACHABLE(); |
1406 } | 1659 } |
1407 } | 1660 } |
1408 | 1661 |
1409 | 1662 |
1410 void Decoder::DecodeTypeImmediate(Instruction* instr) { | 1663 void Decoder::DecodeTypeImmediate(Instruction* instr) { |
1411 switch (instr->OpcodeFieldRaw()) { | 1664 switch (instr->OpcodeFieldRaw()) { |
1412 case COP1: | 1665 case COP1: |
1413 switch (instr->RsFieldRaw()) { | 1666 switch (instr->RsFieldRaw()) { |
1414 case BC1: | 1667 case BC1: |
1415 if (instr->FBtrueValue()) { | 1668 if (instr->FBtrueValue()) { |
1416 Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2"); | 1669 Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2"); |
1417 } else { | 1670 } else { |
1418 Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2"); | 1671 Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2"); |
1419 } | 1672 } |
1420 break; | 1673 break; |
1421 case BC1EQZ: | 1674 case BC1EQZ: |
1422 Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2"); | 1675 Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2"); |
1423 break; | 1676 break; |
1424 case BC1NEZ: | 1677 case BC1NEZ: |
1425 Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2"); | 1678 Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2"); |
1426 break; | 1679 break; |
| 1680 case BZ_V: |
| 1681 case BZ_B: |
| 1682 case BZ_H: |
| 1683 case BZ_W: |
| 1684 case BZ_D: |
| 1685 Format(instr, "bz.'t 'wt, 'imm16s -> 'imm16p4s2"); |
| 1686 break; |
| 1687 case BNZ_V: |
| 1688 case BNZ_B: |
| 1689 case BNZ_H: |
| 1690 case BNZ_W: |
| 1691 case BNZ_D: |
| 1692 Format(instr, "bnz.'t 'wt, 'imm16s -> 'imm16p4s2"); |
| 1693 break; |
1427 default: | 1694 default: |
1428 UNREACHABLE(); | 1695 UNREACHABLE(); |
1429 } | 1696 } |
1430 | 1697 |
1431 break; // Case COP1. | 1698 break; // Case COP1. |
1432 // ------------- REGIMM class. | 1699 // ------------- REGIMM class. |
1433 case REGIMM: | 1700 case REGIMM: |
1434 switch (instr->RtFieldRaw()) { | 1701 switch (instr->RtFieldRaw()) { |
1435 case BLTZ: | 1702 case BLTZ: |
1436 Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2"); | 1703 Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2"); |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1676 Format(instr, "addiupc 'rs, 'imm19s"); | 1943 Format(instr, "addiupc 'rs, 'imm19s"); |
1677 break; | 1944 break; |
1678 default: | 1945 default: |
1679 UNREACHABLE(); | 1946 UNREACHABLE(); |
1680 break; | 1947 break; |
1681 } | 1948 } |
1682 } | 1949 } |
1683 } | 1950 } |
1684 break; | 1951 break; |
1685 } | 1952 } |
| 1953 case MSA: |
| 1954 switch (instr->MSAMinorOpcodeField()) { |
| 1955 case kMsaMinorI8: |
| 1956 DecodeTypeMsaI8(instr); |
| 1957 break; |
| 1958 case kMsaMinorI5: |
| 1959 DecodeTypeMsaI5(instr); |
| 1960 break; |
| 1961 case kMsaMinorI10: |
| 1962 DecodeTypeMsaI10(instr); |
| 1963 break; |
| 1964 case kMsaMinorELM: |
| 1965 DecodeTypeMsaELM(instr); |
| 1966 break; |
| 1967 case kMsaMinorBIT: |
| 1968 DecodeTypeMsaBIT(instr); |
| 1969 break; |
| 1970 case kMsaMinorMI10: |
| 1971 DecodeTypeMsaMI10(instr); |
| 1972 break; |
| 1973 default: |
| 1974 UNREACHABLE(); |
| 1975 break; |
| 1976 } |
| 1977 break; |
1686 default: | 1978 default: |
1687 printf("a 0x%x \n", instr->OpcodeFieldRaw()); | 1979 printf("a 0x%x \n", instr->OpcodeFieldRaw()); |
1688 UNREACHABLE(); | 1980 UNREACHABLE(); |
1689 break; | 1981 break; |
1690 } | 1982 } |
1691 } | 1983 } |
1692 | 1984 |
1693 | 1985 |
1694 void Decoder::DecodeTypeJump(Instruction* instr) { | 1986 void Decoder::DecodeTypeJump(Instruction* instr) { |
1695 switch (instr->OpcodeFieldRaw()) { | 1987 switch (instr->OpcodeFieldRaw()) { |
1696 case J: | 1988 case J: |
1697 Format(instr, "j 'imm26x -> 'imm26j"); | 1989 Format(instr, "j 'imm26x -> 'imm26j"); |
1698 break; | 1990 break; |
1699 case JAL: | 1991 case JAL: |
1700 Format(instr, "jal 'imm26x -> 'imm26j"); | 1992 Format(instr, "jal 'imm26x -> 'imm26j"); |
1701 break; | 1993 break; |
1702 default: | 1994 default: |
1703 UNREACHABLE(); | 1995 UNREACHABLE(); |
1704 } | 1996 } |
1705 } | 1997 } |
1706 | 1998 |
| 1999 void Decoder::DecodeTypeMsaI8(Instruction* instr) { |
| 2000 uint32_t opcode = instr->InstructionBits() & kMsaI8Mask; |
| 2001 |
| 2002 switch (opcode) { |
| 2003 case ANDI_B: |
| 2004 Format(instr, "andi.b 'wd, 'ws, 'imm8"); |
| 2005 break; |
| 2006 case ORI_B: |
| 2007 Format(instr, "ori.b 'wd, 'ws, 'imm8"); |
| 2008 break; |
| 2009 case NORI_B: |
| 2010 Format(instr, "nori.b 'wd, 'ws, 'imm8"); |
| 2011 break; |
| 2012 case XORI_B: |
| 2013 Format(instr, "xori.b 'wd, 'ws, 'imm8"); |
| 2014 break; |
| 2015 case BMNZI_B: |
| 2016 Format(instr, "bmnzi.b 'wd, 'ws, 'imm8"); |
| 2017 break; |
| 2018 case BMZI_B: |
| 2019 Format(instr, "bmzi.b 'wd, 'ws, 'imm8"); |
| 2020 break; |
| 2021 case BSELI_B: |
| 2022 Format(instr, "bseli.b 'wd, 'ws, 'imm8"); |
| 2023 break; |
| 2024 case SHF_B: |
| 2025 Format(instr, "shf.b 'wd, 'ws, 'imm8"); |
| 2026 break; |
| 2027 case SHF_H: |
| 2028 Format(instr, "shf.h 'wd, 'ws, 'imm8"); |
| 2029 break; |
| 2030 case SHF_W: |
| 2031 Format(instr, "shf.w 'wd, 'ws, 'imm8"); |
| 2032 break; |
| 2033 default: |
| 2034 UNREACHABLE(); |
| 2035 } |
| 2036 } |
| 2037 |
| 2038 void Decoder::DecodeTypeMsaI5(Instruction* instr) { |
| 2039 uint32_t opcode = instr->InstructionBits() & kMsaI5Mask; |
| 2040 |
| 2041 switch (opcode) { |
| 2042 case ADDVI: |
| 2043 Format(instr, "addvi.'t 'wd, 'ws, 'imm5u"); |
| 2044 break; |
| 2045 case SUBVI: |
| 2046 Format(instr, "subvi.'t 'wd, 'ws, 'imm5u"); |
| 2047 break; |
| 2048 case MAXI_S: |
| 2049 Format(instr, "maxi_s.'t 'wd, 'ws, 'imm5s"); |
| 2050 break; |
| 2051 case MAXI_U: |
| 2052 Format(instr, "maxi_u.'t 'wd, 'ws, 'imm5u"); |
| 2053 break; |
| 2054 case MINI_S: |
| 2055 Format(instr, "mini_s.'t 'wd, 'ws, 'imm5s"); |
| 2056 break; |
| 2057 case MINI_U: |
| 2058 Format(instr, "mini_u.'t 'wd, 'ws, 'imm5u"); |
| 2059 break; |
| 2060 case CEQI: |
| 2061 Format(instr, "ceqi.'t 'wd, 'ws, 'imm5s"); |
| 2062 break; |
| 2063 case CLTI_S: |
| 2064 Format(instr, "clti_s.'t 'wd, 'ws, 'imm5s"); |
| 2065 break; |
| 2066 case CLTI_U: |
| 2067 Format(instr, "clti_u.'t 'wd, 'ws, 'imm5u"); |
| 2068 break; |
| 2069 case CLEI_S: |
| 2070 Format(instr, "clei_s.'t 'wd, 'ws, 'imm5s"); |
| 2071 break; |
| 2072 case CLEI_U: |
| 2073 Format(instr, "clei_u.'t 'wd, 'ws, 'imm5u"); |
| 2074 break; |
| 2075 default: |
| 2076 UNREACHABLE(); |
| 2077 } |
| 2078 } |
| 2079 |
| 2080 void Decoder::DecodeTypeMsaI10(Instruction* instr) { |
| 2081 uint32_t opcode = instr->InstructionBits() & kMsaI5Mask; |
| 2082 if (opcode == LDI) { |
| 2083 Format(instr, "ldi.'t 'wd, 'imm10s1"); |
| 2084 } else { |
| 2085 UNREACHABLE(); |
| 2086 } |
| 2087 } |
| 2088 |
| 2089 void Decoder::DecodeTypeMsaELM(Instruction* instr) { |
| 2090 uint32_t opcode = instr->InstructionBits() & kMsaELMMask; |
| 2091 switch (opcode) { |
| 2092 case SLDI: |
| 2093 if (instr->Bits(21, 16) == 0x3E) { |
| 2094 Format(instr, "ctcmsa "); |
| 2095 PrintMSAControlRegister(instr->WdValue()); |
| 2096 Print(", "); |
| 2097 PrintRegister(instr->WsValue()); |
| 2098 } else { |
| 2099 Format(instr, "sldi.'t 'wd, 'ws['imme]"); |
| 2100 } |
| 2101 break; |
| 2102 case SPLATI: |
| 2103 if (instr->Bits(21, 16) == 0x3E) { |
| 2104 Format(instr, "cfcmsa "); |
| 2105 PrintRegister(instr->WdValue()); |
| 2106 Print(", "); |
| 2107 PrintMSAControlRegister(instr->WsValue()); |
| 2108 } else { |
| 2109 Format(instr, "splati.'t 'wd, 'ws['imme]"); |
| 2110 } |
| 2111 break; |
| 2112 case COPY_S: |
| 2113 if (instr->Bits(21, 16) == 0x3E) { |
| 2114 Format(instr, "move.v 'wd, 'ws"); |
| 2115 } else { |
| 2116 Format(instr, "copy_s.'t "); |
| 2117 PrintMsaCopy(instr); |
| 2118 } |
| 2119 break; |
| 2120 case COPY_U: |
| 2121 Format(instr, "copy_u.'t "); |
| 2122 PrintMsaCopy(instr); |
| 2123 break; |
| 2124 case INSERT: |
| 2125 Format(instr, "insert.'t 'wd['imme], "); |
| 2126 PrintRegister(instr->WsValue()); |
| 2127 break; |
| 2128 case INSVE: |
| 2129 Format(instr, "insve.'t 'wd['imme], 'ws[0]"); |
| 2130 break; |
| 2131 default: |
| 2132 UNREACHABLE(); |
| 2133 } |
| 2134 } |
| 2135 |
| 2136 void Decoder::DecodeTypeMsaBIT(Instruction* instr) { |
| 2137 uint32_t opcode = instr->InstructionBits() & kMsaBITMask; |
| 2138 |
| 2139 switch (opcode) { |
| 2140 case SLLI: |
| 2141 Format(instr, "slli.'t 'wd, 'ws, 'immb"); |
| 2142 break; |
| 2143 case SRAI: |
| 2144 Format(instr, "srai.'t 'wd, 'ws, 'immb"); |
| 2145 break; |
| 2146 case SRLI: |
| 2147 Format(instr, "srli.'t 'wd, 'ws, 'immb"); |
| 2148 break; |
| 2149 case BCLRI: |
| 2150 Format(instr, "bclri.'t 'wd, 'ws, 'immb"); |
| 2151 break; |
| 2152 case BSETI: |
| 2153 Format(instr, "bseti.'t 'wd, 'ws, 'immb"); |
| 2154 break; |
| 2155 case BNEGI: |
| 2156 Format(instr, "bnegi.'t 'wd, 'ws, 'immb"); |
| 2157 break; |
| 2158 case BINSLI: |
| 2159 Format(instr, "binsli.'t 'wd, 'ws, 'immb"); |
| 2160 break; |
| 2161 case BINSRI: |
| 2162 Format(instr, "binsri.'t 'wd, 'ws, 'immb"); |
| 2163 break; |
| 2164 case SAT_S: |
| 2165 Format(instr, "sat_s.'t 'wd, 'ws, 'immb"); |
| 2166 break; |
| 2167 case SAT_U: |
| 2168 Format(instr, "sat_u.'t 'wd, 'ws, 'immb"); |
| 2169 break; |
| 2170 case SRARI: |
| 2171 Format(instr, "srari.'t 'wd, 'ws, 'immb"); |
| 2172 break; |
| 2173 case SRLRI: |
| 2174 Format(instr, "srlri.'t 'wd, 'ws, 'immb"); |
| 2175 break; |
| 2176 default: |
| 2177 UNREACHABLE(); |
| 2178 } |
| 2179 } |
| 2180 |
| 2181 void Decoder::DecodeTypeMsaMI10(Instruction* instr) { |
| 2182 uint32_t opcode = instr->InstructionBits() & kMsaMI10Mask; |
| 2183 if (opcode == MSA_LD) { |
| 2184 Format(instr, "ld.'t 'wd, 'imm10s2("); |
| 2185 PrintRegister(instr->WsValue()); |
| 2186 Print(")"); |
| 2187 } else if (opcode == MSA_ST) { |
| 2188 Format(instr, "st.'t 'wd, 'imm10s2("); |
| 2189 PrintRegister(instr->WsValue()); |
| 2190 Print(")"); |
| 2191 } else { |
| 2192 UNREACHABLE(); |
| 2193 } |
| 2194 } |
| 2195 |
| 2196 void Decoder::DecodeTypeMsa3R(Instruction* instr) { |
| 2197 uint32_t opcode = instr->InstructionBits() & kMsa3RMask; |
| 2198 switch (opcode) { |
| 2199 case SLL_MSA: |
| 2200 Format(instr, "sll.'t 'wd, 'ws, 'wt"); |
| 2201 break; |
| 2202 case SRA_MSA: |
| 2203 Format(instr, "sra.'t 'wd, 'ws, 'wt"); |
| 2204 break; |
| 2205 case SRL_MSA: |
| 2206 Format(instr, "srl.'t 'wd, 'ws, 'wt"); |
| 2207 break; |
| 2208 case BCLR: |
| 2209 Format(instr, "bclr.'t 'wd, 'ws, 'wt"); |
| 2210 break; |
| 2211 case BSET: |
| 2212 Format(instr, "bset.'t 'wd, 'ws, 'wt"); |
| 2213 break; |
| 2214 case BNEG: |
| 2215 Format(instr, "bneg.'t 'wd, 'ws, 'wt"); |
| 2216 break; |
| 2217 case BINSL: |
| 2218 Format(instr, "binsl.'t 'wd, 'ws, 'wt"); |
| 2219 break; |
| 2220 case BINSR: |
| 2221 Format(instr, "binsr.'t 'wd, 'ws, 'wt"); |
| 2222 break; |
| 2223 case ADDV: |
| 2224 Format(instr, "addv.'t 'wd, 'ws, 'wt"); |
| 2225 break; |
| 2226 case SUBV: |
| 2227 Format(instr, "subv.'t 'wd, 'ws, 'wt"); |
| 2228 break; |
| 2229 case MAX_S: |
| 2230 Format(instr, "max_s.'t 'wd, 'ws, 'wt"); |
| 2231 break; |
| 2232 case MAX_U: |
| 2233 Format(instr, "max_u.'t 'wd, 'ws, 'wt"); |
| 2234 break; |
| 2235 case MIN_S: |
| 2236 Format(instr, "min_s.'t 'wd, 'ws, 'wt"); |
| 2237 break; |
| 2238 case MIN_U: |
| 2239 Format(instr, "min_u.'t 'wd, 'ws, 'wt"); |
| 2240 break; |
| 2241 case MAX_A: |
| 2242 Format(instr, "max_a.'t 'wd, 'ws, 'wt"); |
| 2243 break; |
| 2244 case MIN_A: |
| 2245 Format(instr, "min_a.'t 'wd, 'ws, 'wt"); |
| 2246 break; |
| 2247 case CEQ: |
| 2248 Format(instr, "ceq.'t 'wd, 'ws, 'wt"); |
| 2249 break; |
| 2250 case CLT_S: |
| 2251 Format(instr, "clt_s.'t 'wd, 'ws, 'wt"); |
| 2252 break; |
| 2253 case CLT_U: |
| 2254 Format(instr, "clt_u.'t 'wd, 'ws, 'wt"); |
| 2255 break; |
| 2256 case CLE_S: |
| 2257 Format(instr, "cle_s.'t 'wd, 'ws, 'wt"); |
| 2258 break; |
| 2259 case CLE_U: |
| 2260 Format(instr, "cle_u.'t 'wd, 'ws, 'wt"); |
| 2261 break; |
| 2262 case ADD_A: |
| 2263 Format(instr, "add_a.'t 'wd, 'ws, 'wt"); |
| 2264 break; |
| 2265 case ADDS_A: |
| 2266 Format(instr, "adds_a.'t 'wd, 'ws, 'wt"); |
| 2267 break; |
| 2268 case ADDS_S: |
| 2269 Format(instr, "adds_s.'t 'wd, 'ws, 'wt"); |
| 2270 break; |
| 2271 case ADDS_U: |
| 2272 Format(instr, "adds_u.'t 'wd, 'ws, 'wt"); |
| 2273 break; |
| 2274 case AVE_S: |
| 2275 Format(instr, "ave_s.'t 'wd, 'ws, 'wt"); |
| 2276 break; |
| 2277 case AVE_U: |
| 2278 Format(instr, "ave_u.'t 'wd, 'ws, 'wt"); |
| 2279 break; |
| 2280 case AVER_S: |
| 2281 Format(instr, "aver_s.'t 'wd, 'ws, 'wt"); |
| 2282 break; |
| 2283 case AVER_U: |
| 2284 Format(instr, "aver_u.'t 'wd, 'ws, 'wt"); |
| 2285 break; |
| 2286 case SUBS_S: |
| 2287 Format(instr, "subs_s.'t 'wd, 'ws, 'wt"); |
| 2288 break; |
| 2289 case SUBS_U: |
| 2290 Format(instr, "subs_u.'t 'wd, 'ws, 'wt"); |
| 2291 break; |
| 2292 case SUBSUS_U: |
| 2293 Format(instr, "subsus_u.'t 'wd, 'ws, 'wt"); |
| 2294 break; |
| 2295 case SUBSUU_S: |
| 2296 Format(instr, "subsuu_s.'t 'wd, 'ws, 'wt"); |
| 2297 break; |
| 2298 case ASUB_S: |
| 2299 Format(instr, "asub_s.'t 'wd, 'ws, 'wt"); |
| 2300 break; |
| 2301 case ASUB_U: |
| 2302 Format(instr, "asub_u.'t 'wd, 'ws, 'wt"); |
| 2303 break; |
| 2304 case MULV: |
| 2305 Format(instr, "mulv.'t 'wd, 'ws, 'wt"); |
| 2306 break; |
| 2307 case MADDV: |
| 2308 Format(instr, "maddv.'t 'wd, 'ws, 'wt"); |
| 2309 break; |
| 2310 case MSUBV: |
| 2311 Format(instr, "msubv.'t 'wd, 'ws, 'wt"); |
| 2312 break; |
| 2313 case DIV_S_MSA: |
| 2314 Format(instr, "div_s.'t 'wd, 'ws, 'wt"); |
| 2315 break; |
| 2316 case DIV_U: |
| 2317 Format(instr, "div_u.'t 'wd, 'ws, 'wt"); |
| 2318 break; |
| 2319 case MOD_S: |
| 2320 Format(instr, "mod_s.'t 'wd, 'ws, 'wt"); |
| 2321 break; |
| 2322 case MOD_U: |
| 2323 Format(instr, "mod_u.'t 'wd, 'ws, 'wt"); |
| 2324 break; |
| 2325 case DOTP_S: |
| 2326 Format(instr, "dotp_s.'t 'wd, 'ws, 'wt"); |
| 2327 break; |
| 2328 case DOTP_U: |
| 2329 Format(instr, "dotp_u.'t 'wd, 'ws, 'wt"); |
| 2330 break; |
| 2331 case DPADD_S: |
| 2332 Format(instr, "dpadd_s.'t 'wd, 'ws, 'wt"); |
| 2333 break; |
| 2334 case DPADD_U: |
| 2335 Format(instr, "dpadd_u.'t 'wd, 'ws, 'wt"); |
| 2336 break; |
| 2337 case DPSUB_S: |
| 2338 Format(instr, "dpsub_s.'t 'wd, 'ws, 'wt"); |
| 2339 break; |
| 2340 case DPSUB_U: |
| 2341 Format(instr, "dpsub_u.'t 'wd, 'ws, 'wt"); |
| 2342 break; |
| 2343 case SLD: |
| 2344 Format(instr, "sld.'t 'wd, 'ws['rt]"); |
| 2345 break; |
| 2346 case SPLAT: |
| 2347 Format(instr, "splat.'t 'wd, 'ws['rt]"); |
| 2348 break; |
| 2349 case PCKEV: |
| 2350 Format(instr, "pckev.'t 'wd, 'ws, 'wt"); |
| 2351 break; |
| 2352 case PCKOD: |
| 2353 Format(instr, "pckod.'t 'wd, 'ws, 'wt"); |
| 2354 break; |
| 2355 case ILVL: |
| 2356 Format(instr, "ilvl.'t 'wd, 'ws, 'wt"); |
| 2357 break; |
| 2358 case ILVR: |
| 2359 Format(instr, "ilvr.'t 'wd, 'ws, 'wt"); |
| 2360 break; |
| 2361 case ILVEV: |
| 2362 Format(instr, "ilvev.'t 'wd, 'ws, 'wt"); |
| 2363 break; |
| 2364 case ILVOD: |
| 2365 Format(instr, "ilvod.'t 'wd, 'ws, 'wt"); |
| 2366 break; |
| 2367 case VSHF: |
| 2368 Format(instr, "vshf.'t 'wd, 'ws, 'wt"); |
| 2369 break; |
| 2370 case SRAR: |
| 2371 Format(instr, "srar.'t 'wd, 'ws, 'wt"); |
| 2372 break; |
| 2373 case SRLR: |
| 2374 Format(instr, "srlr.'t 'wd, 'ws, 'wt"); |
| 2375 break; |
| 2376 case HADD_S: |
| 2377 Format(instr, "hadd_s.'t 'wd, 'ws, 'wt"); |
| 2378 break; |
| 2379 case HADD_U: |
| 2380 Format(instr, "hadd_u.'t 'wd, 'ws, 'wt"); |
| 2381 break; |
| 2382 case HSUB_S: |
| 2383 Format(instr, "hsub_s.'t 'wd, 'ws, 'wt"); |
| 2384 break; |
| 2385 case HSUB_U: |
| 2386 Format(instr, "hsub_u.'t 'wd, 'ws, 'wt"); |
| 2387 break; |
| 2388 default: |
| 2389 UNREACHABLE(); |
| 2390 } |
| 2391 } |
| 2392 |
| 2393 void Decoder::DecodeTypeMsa3RF(Instruction* instr) { |
| 2394 uint32_t opcode = instr->InstructionBits() & kMsa3RFMask; |
| 2395 switch (opcode) { |
| 2396 case FCAF: |
| 2397 Format(instr, "fcaf.'t 'wd, 'ws, 'wt"); |
| 2398 break; |
| 2399 case FCUN: |
| 2400 Format(instr, "fcun.'t 'wd, 'ws, 'wt"); |
| 2401 break; |
| 2402 case FCEQ: |
| 2403 Format(instr, "fceq.'t 'wd, 'ws, 'wt"); |
| 2404 break; |
| 2405 case FCUEQ: |
| 2406 Format(instr, "fcueq.'t 'wd, 'ws, 'wt"); |
| 2407 break; |
| 2408 case FCLT: |
| 2409 Format(instr, "fclt.'t 'wd, 'ws, 'wt"); |
| 2410 break; |
| 2411 case FCULT: |
| 2412 Format(instr, "fcult.'t 'wd, 'ws, 'wt"); |
| 2413 break; |
| 2414 case FCLE: |
| 2415 Format(instr, "fcle.'t 'wd, 'ws, 'wt"); |
| 2416 break; |
| 2417 case FCULE: |
| 2418 Format(instr, "fcule.'t 'wd, 'ws, 'wt"); |
| 2419 break; |
| 2420 case FSAF: |
| 2421 Format(instr, "fsaf.'t 'wd, 'ws, 'wt"); |
| 2422 break; |
| 2423 case FSUN: |
| 2424 Format(instr, "fsun.'t 'wd, 'ws, 'wt"); |
| 2425 break; |
| 2426 case FSEQ: |
| 2427 Format(instr, "fseq.'t 'wd, 'ws, 'wt"); |
| 2428 break; |
| 2429 case FSUEQ: |
| 2430 Format(instr, "fsueq.'t 'wd, 'ws, 'wt"); |
| 2431 break; |
| 2432 case FSLT: |
| 2433 Format(instr, "fslt.'t 'wd, 'ws, 'wt"); |
| 2434 break; |
| 2435 case FSULT: |
| 2436 Format(instr, "fsult.'t 'wd, 'ws, 'wt"); |
| 2437 break; |
| 2438 case FSLE: |
| 2439 Format(instr, "fsle.'t 'wd, 'ws, 'wt"); |
| 2440 break; |
| 2441 case FSULE: |
| 2442 Format(instr, "fsule.'t 'wd, 'ws, 'wt"); |
| 2443 break; |
| 2444 case FADD: |
| 2445 Format(instr, "fadd.'t 'wd, 'ws, 'wt"); |
| 2446 break; |
| 2447 case FSUB: |
| 2448 Format(instr, "fsub.'t 'wd, 'ws, 'wt"); |
| 2449 break; |
| 2450 case FMUL: |
| 2451 Format(instr, "fmul.'t 'wd, 'ws, 'wt"); |
| 2452 break; |
| 2453 case FDIV: |
| 2454 Format(instr, "fdiv.'t 'wd, 'ws, 'wt"); |
| 2455 break; |
| 2456 case FMADD: |
| 2457 Format(instr, "fmadd.'t 'wd, 'ws, 'wt"); |
| 2458 break; |
| 2459 case FMSUB: |
| 2460 Format(instr, "fmsub.'t 'wd, 'ws, 'wt"); |
| 2461 break; |
| 2462 case FEXP2: |
| 2463 Format(instr, "fexp2.'t 'wd, 'ws, 'wt"); |
| 2464 break; |
| 2465 case FEXDO: |
| 2466 Format(instr, "fexdo.'t 'wd, 'ws, 'wt"); |
| 2467 break; |
| 2468 case FTQ: |
| 2469 Format(instr, "ftq.'t 'wd, 'ws, 'wt"); |
| 2470 break; |
| 2471 case FMIN: |
| 2472 Format(instr, "fmin.'t 'wd, 'ws, 'wt"); |
| 2473 break; |
| 2474 case FMIN_A: |
| 2475 Format(instr, "fmin_a.'t 'wd, 'ws, 'wt"); |
| 2476 break; |
| 2477 case FMAX: |
| 2478 Format(instr, "fmax.'t 'wd, 'ws, 'wt"); |
| 2479 break; |
| 2480 case FMAX_A: |
| 2481 Format(instr, "fmax_a.'t 'wd, 'ws, 'wt"); |
| 2482 break; |
| 2483 case FCOR: |
| 2484 Format(instr, "fcor.'t 'wd, 'ws, 'wt"); |
| 2485 break; |
| 2486 case FCUNE: |
| 2487 Format(instr, "fcune.'t 'wd, 'ws, 'wt"); |
| 2488 break; |
| 2489 case FCNE: |
| 2490 Format(instr, "fcne.'t 'wd, 'ws, 'wt"); |
| 2491 break; |
| 2492 case MUL_Q: |
| 2493 Format(instr, "mul_q.'t 'wd, 'ws, 'wt"); |
| 2494 break; |
| 2495 case MADD_Q: |
| 2496 Format(instr, "madd_q.'t 'wd, 'ws, 'wt"); |
| 2497 break; |
| 2498 case MSUB_Q: |
| 2499 Format(instr, "msub_q.'t 'wd, 'ws, 'wt"); |
| 2500 break; |
| 2501 case FSOR: |
| 2502 Format(instr, "fsor.'t 'wd, 'ws, 'wt"); |
| 2503 break; |
| 2504 case FSUNE: |
| 2505 Format(instr, "fsune.'t 'wd, 'ws, 'wt"); |
| 2506 break; |
| 2507 case FSNE: |
| 2508 Format(instr, "fsne.'t 'wd, 'ws, 'wt"); |
| 2509 break; |
| 2510 case MULR_Q: |
| 2511 Format(instr, "mulr_q.'t 'wd, 'ws, 'wt"); |
| 2512 break; |
| 2513 case MADDR_Q: |
| 2514 Format(instr, "maddr_q.'t 'wd, 'ws, 'wt"); |
| 2515 break; |
| 2516 case MSUBR_Q: |
| 2517 Format(instr, "msubr_q.'t 'wd, 'ws, 'wt"); |
| 2518 break; |
| 2519 default: |
| 2520 UNREACHABLE(); |
| 2521 } |
| 2522 } |
| 2523 |
| 2524 void Decoder::DecodeTypeMsaVec(Instruction* instr) { |
| 2525 uint32_t opcode = instr->InstructionBits() & kMsaVECMask; |
| 2526 switch (opcode) { |
| 2527 case AND_V: |
| 2528 Format(instr, "and.v 'wd, 'ws, 'wt"); |
| 2529 break; |
| 2530 case OR_V: |
| 2531 Format(instr, "or.v 'wd, 'ws, 'wt"); |
| 2532 break; |
| 2533 case NOR_V: |
| 2534 Format(instr, "nor.v 'wd, 'ws, 'wt"); |
| 2535 break; |
| 2536 case XOR_V: |
| 2537 Format(instr, "xor.v 'wd, 'ws, 'wt"); |
| 2538 break; |
| 2539 case BMNZ_V: |
| 2540 Format(instr, "bmnz.v 'wd, 'ws, 'wt"); |
| 2541 break; |
| 2542 case BMZ_V: |
| 2543 Format(instr, "bmz.v 'wd, 'ws, 'wt"); |
| 2544 break; |
| 2545 case BSEL_V: |
| 2546 Format(instr, "bsel.v 'wd, 'ws, 'wt"); |
| 2547 break; |
| 2548 default: |
| 2549 UNREACHABLE(); |
| 2550 } |
| 2551 } |
| 2552 |
| 2553 void Decoder::DecodeTypeMsa2R(Instruction* instr) { |
| 2554 uint32_t opcode = instr->InstructionBits() & kMsa2RMask; |
| 2555 switch (opcode) { |
| 2556 case FILL: { |
| 2557 Format(instr, "fill.'t 'wd, "); |
| 2558 PrintRegister(instr->WsValue()); // rs value is in ws field |
| 2559 } break; |
| 2560 case PCNT: |
| 2561 Format(instr, "pcnt.'t 'wd, 'ws"); |
| 2562 break; |
| 2563 case NLOC: |
| 2564 Format(instr, "nloc.'t 'wd, 'ws"); |
| 2565 break; |
| 2566 case NLZC: |
| 2567 Format(instr, "nlzc.'t 'wd, 'ws"); |
| 2568 break; |
| 2569 default: |
| 2570 UNREACHABLE(); |
| 2571 } |
| 2572 } |
| 2573 |
| 2574 void Decoder::DecodeTypeMsa2RF(Instruction* instr) { |
| 2575 uint32_t opcode = instr->InstructionBits() & kMsa2RFMask; |
| 2576 switch (opcode) { |
| 2577 case FCLASS: |
| 2578 Format(instr, "fclass.'t 'wd, 'ws"); |
| 2579 break; |
| 2580 case FTRUNC_S: |
| 2581 Format(instr, "ftrunc_s.'t 'wd, 'ws"); |
| 2582 break; |
| 2583 case FTRUNC_U: |
| 2584 Format(instr, "ftrunc_u.'t 'wd, 'ws"); |
| 2585 break; |
| 2586 case FSQRT: |
| 2587 Format(instr, "fsqrt.'t 'wd, 'ws"); |
| 2588 break; |
| 2589 case FRSQRT: |
| 2590 Format(instr, "frsqrt.'t 'wd, 'ws"); |
| 2591 break; |
| 2592 case FRCP: |
| 2593 Format(instr, "frcp.'t 'wd, 'ws"); |
| 2594 break; |
| 2595 case FRINT: |
| 2596 Format(instr, "frint.'t 'wd, 'ws"); |
| 2597 break; |
| 2598 case FLOG2: |
| 2599 Format(instr, "flog2.'t 'wd, 'ws"); |
| 2600 break; |
| 2601 case FEXUPL: |
| 2602 Format(instr, "fexupl.'t 'wd, 'ws"); |
| 2603 break; |
| 2604 case FEXUPR: |
| 2605 Format(instr, "fexupr.'t 'wd, 'ws"); |
| 2606 break; |
| 2607 case FFQL: |
| 2608 Format(instr, "ffql.'t 'wd, 'ws"); |
| 2609 break; |
| 2610 case FFQR: |
| 2611 Format(instr, "ffqr.'t 'wd, 'ws"); |
| 2612 break; |
| 2613 case FTINT_S: |
| 2614 Format(instr, "ftint_s.'t 'wd, 'ws"); |
| 2615 break; |
| 2616 case FTINT_U: |
| 2617 Format(instr, "ftint_u.'t 'wd, 'ws"); |
| 2618 break; |
| 2619 case FFINT_S: |
| 2620 Format(instr, "ffint_s.'t 'wd, 'ws"); |
| 2621 break; |
| 2622 case FFINT_U: |
| 2623 Format(instr, "ffint_u.'t 'wd, 'ws"); |
| 2624 break; |
| 2625 default: |
| 2626 UNREACHABLE(); |
| 2627 } |
| 2628 } |
1707 | 2629 |
1708 // Disassemble the instruction at *instr_ptr into the output buffer. | 2630 // Disassemble the instruction at *instr_ptr into the output buffer. |
1709 int Decoder::InstructionDecode(byte* instr_ptr) { | 2631 int Decoder::InstructionDecode(byte* instr_ptr) { |
1710 Instruction* instr = Instruction::At(instr_ptr); | 2632 Instruction* instr = Instruction::At(instr_ptr); |
1711 // Print raw instruction bytes. | 2633 // Print raw instruction bytes. |
1712 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 2634 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
1713 "%08x ", | 2635 "%08x ", |
1714 instr->InstructionBits()); | 2636 instr->InstructionBits()); |
1715 switch (instr->InstructionType()) { | 2637 switch (instr->InstructionType()) { |
1716 case Instruction::kRegisterType: { | 2638 case Instruction::kRegisterType: { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1810 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 2732 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1811 } | 2733 } |
1812 } | 2734 } |
1813 | 2735 |
1814 | 2736 |
1815 #undef UNSUPPORTED | 2737 #undef UNSUPPORTED |
1816 | 2738 |
1817 } // namespace disasm | 2739 } // namespace disasm |
1818 | 2740 |
1819 #endif // V8_TARGET_ARCH_MIPS | 2741 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |