v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
disasm-mips64.cc
Go to the documentation of this file.
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
3// found in the LICENSE file.
4
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
7// overriden to modify register names or to do symbol lookup on addresses.
8//
9// The example below will disassemble a block of code and print it to stdout.
10//
11// NameConverter converter;
12// Disassembler d(converter);
13// for (uint8_t* pc = begin; pc < end;) {
14// v8::base::EmbeddedVector<char, 256> buffer;
15// uint8_t* prev_pc = pc;
16// pc += d.InstructionDecode(buffer, pc);
17// printf("%p %08x %s\n",
18// prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
19// }
20//
21// The Disassembler class also has a convenience method to disassemble a block
22// of code into a FILE*, meaning that the above functionality could also be
23// achieved by just calling Disassembler::Disassemble(stdout, begin, end);
24
25#include <assert.h>
26#include <stdarg.h>
27#include <stdio.h>
28#include <string.h>
29
30#if V8_TARGET_ARCH_MIPS64
31
33#include "src/base/strings.h"
34#include "src/base/vector.h"
38
39namespace v8 {
40namespace internal {
41
42//------------------------------------------------------------------------------
43
44// Decoder decodes and disassembles instructions into an output buffer.
45// It uses the converter to convert register names and call destinations into
46// more informative description.
47class Decoder {
48 public:
49 Decoder(const disasm::NameConverter& converter,
50 v8::base::Vector<char> out_buffer)
51 : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) {
53 }
54
55 ~Decoder() {}
56
57 Decoder(const Decoder&) = delete;
58 Decoder& operator=(const Decoder&) = delete;
59
60 // Writes one disassembled instruction into 'buffer' (0-terminated).
61 // Returns the length of the disassembled machine instruction in bytes.
62 int InstructionDecode(uint8_t* instruction);
63
64 private:
65 // Bottleneck functions to print into the out_buffer.
66 void PrintChar(const char ch);
67 void Print(const char* str);
68
69 // Printing of common values.
70 void PrintRegister(int reg);
71 void PrintFPURegister(int freg);
72 void PrintMSARegister(int wreg);
73 void PrintFPUStatusRegister(int freg);
74 void PrintMSAControlRegister(int creg);
75 void PrintRs(Instruction* instr);
76 void PrintRt(Instruction* instr);
77 void PrintRd(Instruction* instr);
78 void PrintFs(Instruction* instr);
79 void PrintFt(Instruction* instr);
80 void PrintFd(Instruction* instr);
81 void PrintSa(Instruction* instr);
82 void PrintLsaSa(Instruction* instr);
83 void PrintSd(Instruction* instr);
84 void PrintSs1(Instruction* instr);
85 void PrintSs2(Instruction* instr);
86 void PrintSs3(Instruction* instr);
87 void PrintSs4(Instruction* instr);
88 void PrintSs5(Instruction* instr);
89 void PrintBc(Instruction* instr);
90 void PrintCc(Instruction* instr);
91 void PrintFunction(Instruction* instr);
92 void PrintSecondaryField(Instruction* instr);
93 void PrintUImm9(Instruction* instr);
94 void PrintSImm9(Instruction* instr);
95 void PrintUImm16(Instruction* instr);
96 void PrintSImm16(Instruction* instr);
97 void PrintXImm16(Instruction* instr);
98 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits);
99 void PrintXImm18(Instruction* instr);
100 void PrintSImm18(Instruction* instr);
101 void PrintXImm19(Instruction* instr);
102 void PrintSImm19(Instruction* instr);
103 void PrintXImm21(Instruction* instr);
104 void PrintSImm21(Instruction* instr);
105 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits);
106 void PrintXImm26(Instruction* instr);
107 void PrintSImm26(Instruction* instr);
108 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits);
109 void PrintPCImm26(Instruction* instr);
110 void PrintCode(Instruction* instr); // For break and trap instructions.
111 void PrintFormat(Instruction* instr); // For floating format postfix.
112 void PrintBp2(Instruction* instr);
113 void PrintBp3(Instruction* instr);
114 void PrintMsaDataFormat(Instruction* instr);
115 void PrintMsaXImm8(Instruction* instr);
116 void PrintMsaImm8(Instruction* instr);
117 void PrintMsaImm5(Instruction* instr);
118 void PrintMsaSImm5(Instruction* instr);
119 void PrintMsaSImm10(Instruction* instr, bool is_mi10 = false);
120 void PrintMsaImmBit(Instruction* instr);
121 void PrintMsaImmElm(Instruction* instr);
122 void PrintMsaCopy(Instruction* instr);
123 // Printing of instruction name.
124 void PrintInstructionName(Instruction* instr);
125
126 // Handle formatting of instructions and their options.
127 int FormatRegister(Instruction* instr, const char* option);
128 int FormatFPURegister(Instruction* instr, const char* option);
129 int FormatMSARegister(Instruction* instr, const char* option);
130 int FormatOption(Instruction* instr, const char* option);
131 void Format(Instruction* instr, const char* format);
132 void Unknown(Instruction* instr);
133 int DecodeBreakInstr(Instruction* instr);
134
135 // Each of these functions decodes one particular instruction type.
136 bool DecodeTypeRegisterRsType(Instruction* instr);
137 void DecodeTypeRegisterSRsType(Instruction* instr);
138 void DecodeTypeRegisterDRsType(Instruction* instr);
139 void DecodeTypeRegisterLRsType(Instruction* instr);
140 void DecodeTypeRegisterWRsType(Instruction* instr);
141 void DecodeTypeRegisterSPECIAL(Instruction* instr);
142 void DecodeTypeRegisterSPECIAL2(Instruction* instr);
143 void DecodeTypeRegisterSPECIAL3(Instruction* instr);
144 void DecodeTypeRegisterCOP1(Instruction* instr);
145 void DecodeTypeRegisterCOP1X(Instruction* instr);
146 int DecodeTypeRegister(Instruction* instr);
147
148 void DecodeTypeImmediateCOP1(Instruction* instr);
149 void DecodeTypeImmediateREGIMM(Instruction* instr);
150 void DecodeTypeImmediateSPECIAL3(Instruction* instr);
151 void DecodeTypeImmediate(Instruction* instr);
152
153 void DecodeTypeJump(Instruction* instr);
154
155 void DecodeTypeMsaI8(Instruction* instr);
156 void DecodeTypeMsaI5(Instruction* instr);
157 void DecodeTypeMsaI10(Instruction* instr);
158 void DecodeTypeMsaELM(Instruction* instr);
159 void DecodeTypeMsaBIT(Instruction* instr);
160 void DecodeTypeMsaMI10(Instruction* instr);
161 void DecodeTypeMsa3R(Instruction* instr);
162 void DecodeTypeMsa3RF(Instruction* instr);
163 void DecodeTypeMsaVec(Instruction* instr);
164 void DecodeTypeMsa2R(Instruction* instr);
165 void DecodeTypeMsa2RF(Instruction* instr);
166
169 int out_buffer_pos_;
170};
171
172// Support for assertions in the Decoder formatting functions.
173#define STRING_STARTS_WITH(string, compare_string) \
174 (strncmp(string, compare_string, strlen(compare_string)) == 0)
175
176// Append the ch to the output buffer.
177void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
178
179// Append the str to the output buffer.
180void Decoder::Print(const char* str) {
181 char cur = *str++;
182 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
183 PrintChar(cur);
184 cur = *str++;
185 }
187}
188
189// Print the register name according to the active name converter.
190void Decoder::PrintRegister(int reg) {
191 Print(converter_.NameOfCPURegister(reg));
192}
193
194void Decoder::PrintRs(Instruction* instr) {
195 int reg = instr->RsValue();
197}
198
199void Decoder::PrintRt(Instruction* instr) {
200 int reg = instr->RtValue();
202}
203
204void Decoder::PrintRd(Instruction* instr) {
205 int reg = instr->RdValue();
207}
208
209// Print the FPUregister name according to the active name converter.
210void Decoder::PrintFPURegister(int freg) {
211 Print(converter_.NameOfXMMRegister(freg));
212}
213
214void Decoder::PrintMSARegister(int wreg) { Print(MSARegisters::Name(wreg)); }
215
216void Decoder::PrintFPUStatusRegister(int freg) {
217 switch (freg) {
218 case kFCSRRegister:
219 Print("FCSR");
220 break;
221 default:
222 Print(converter_.NameOfXMMRegister(freg));
223 }
224}
225
226void Decoder::PrintMSAControlRegister(int creg) {
227 switch (creg) {
228 case kMSAIRRegister:
229 Print("MSAIR");
230 break;
231 case kMSACSRRegister:
232 Print("MSACSR");
233 break;
234 default:
235 Print("no_msacreg");
236 }
237}
238
239void Decoder::PrintFs(Instruction* instr) {
240 int freg = instr->RsValue();
241 PrintFPURegister(freg);
242}
243
244void Decoder::PrintFt(Instruction* instr) {
245 int freg = instr->RtValue();
246 PrintFPURegister(freg);
247}
248
249void Decoder::PrintFd(Instruction* instr) {
250 int freg = instr->RdValue();
251 PrintFPURegister(freg);
252}
253
254// Print the integer value of the sa field.
255void Decoder::PrintSa(Instruction* instr) {
256 int sa = instr->SaValue();
258}
259
260// Print the integer value of the sa field of a lsa instruction.
261void Decoder::PrintLsaSa(Instruction* instr) {
262 int sa = instr->LsaSaValue() + 1;
264}
265
266// Print the integer value of the rd field, when it is not used as reg.
267void Decoder::PrintSd(Instruction* instr) {
268 int sd = instr->RdValue();
270}
271
272// Print the integer value of ext/dext/dextu size from the msbd field.
273void Decoder::PrintSs1(Instruction* instr) {
274 int msbd = instr->RdValue();
276 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", msbd + 1);
277}
278
279// Print the integer value of ins/dins/dinsu size from the msb and lsb fields
280// (for dinsu it is msbminus32 and lsbminus32 fields).
281void Decoder::PrintSs2(Instruction* instr) {
282 int msb = instr->RdValue();
283 int lsb = instr->SaValue();
285 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", msb - lsb + 1);
286}
287
288// Print the integer value of dextm size from the msbdminus32 field.
289void Decoder::PrintSs3(Instruction* instr) {
290 int msbdminus32 = instr->RdValue();
292 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", msbdminus32 + 32 + 1);
293}
294
295// Print the integer value of dinsm size from the msbminus32 and lsb fields.
296void Decoder::PrintSs4(Instruction* instr) {
297 int msbminus32 = instr->RdValue();
298 int lsb = instr->SaValue();
300 msbminus32 + 32 - lsb + 1);
301}
302
303// Print the integer value of dextu/dinsu pos from the lsbminus32 field.
304void Decoder::PrintSs5(Instruction* instr) {
305 int lsbminus32 = instr->SaValue();
307 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", lsbminus32 + 32);
308}
309
310// Print the integer value of the cc field for the bc1t/f instructions.
311void Decoder::PrintBc(Instruction* instr) {
312 int cc = instr->FBccValue();
314}
315
316// Print the integer value of the cc field for the FP compare instructions.
317void Decoder::PrintCc(Instruction* instr) {
318 int cc = instr->FCccValue();
321}
322
323// Print 9-bit unsigned immediate value.
324void Decoder::PrintUImm9(Instruction* instr) {
325 int32_t imm = instr->Imm9Value();
327}
328
329// Print 9-bit signed immediate value.
330void Decoder::PrintSImm9(Instruction* instr) {
331 int32_t imm = ((instr->Imm9Value()) << 23) >> 23;
333}
334
335// Print 16-bit unsigned immediate value.
336void Decoder::PrintUImm16(Instruction* instr) {
337 int32_t imm = instr->Imm16Value();
339}
340
341// Print 16-bit signed immediate value.
342void Decoder::PrintSImm16(Instruction* instr) {
343 int32_t imm =
344 ((instr->Imm16Value()) << (32 - kImm16Bits)) >> (32 - kImm16Bits);
346}
347
348// Print 16-bit hexa immediate value.
349void Decoder::PrintXImm16(Instruction* instr) {
350 int32_t imm = instr->Imm16Value();
352}
353
354// Print absoulte address for 16-bit offset or immediate value.
355// The absolute address is calculated according following expression:
356// PC + delta_pc + (offset << n_bits)
357void Decoder::PrintPCImm16(Instruction* instr, int delta_pc, int n_bits) {
358 int16_t offset = instr->Imm16Value();
361 converter_.NameOfAddress(reinterpret_cast<uint8_t*>(instr) + delta_pc +
362 (offset << n_bits)));
363}
364
365// Print 18-bit signed immediate value.
366void Decoder::PrintSImm18(Instruction* instr) {
367 int32_t imm =
368 ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits);
370}
371
372// Print 18-bit hexa immediate value.
373void Decoder::PrintXImm18(Instruction* instr) {
374 int32_t imm = instr->Imm18Value();
376}
377
378// Print 19-bit hexa immediate value.
379void Decoder::PrintXImm19(Instruction* instr) {
380 int32_t imm = instr->Imm19Value();
382}
383
384// Print 19-bit signed immediate value.
385void Decoder::PrintSImm19(Instruction* instr) {
386 int32_t imm19 = instr->Imm19Value();
387 // set sign
388 imm19 <<= (32 - kImm19Bits);
389 imm19 >>= (32 - kImm19Bits);
391}
392
393// Print 21-bit immediate value.
394void Decoder::PrintXImm21(Instruction* instr) {
395 uint32_t imm = instr->Imm21Value();
397}
398
399// Print 21-bit signed immediate value.
400void Decoder::PrintSImm21(Instruction* instr) {
401 int32_t imm21 = instr->Imm21Value();
402 // set sign
403 imm21 <<= (32 - kImm21Bits);
404 imm21 >>= (32 - kImm21Bits);
406}
407
408// Print absoulte address for 21-bit offset or immediate value.
409// The absolute address is calculated according following expression:
410// PC + delta_pc + (offset << n_bits)
411void Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) {
412 int32_t imm21 = instr->Imm21Value();
413 // set sign
414 imm21 <<= (32 - kImm21Bits);
415 imm21 >>= (32 - kImm21Bits);
418 converter_.NameOfAddress(reinterpret_cast<uint8_t*>(instr) + delta_pc +
419 (imm21 << n_bits)));
420}
421
422// Print 26-bit hex immediate value.
423void Decoder::PrintXImm26(Instruction* instr) {
424 uint64_t target = static_cast<uint64_t>(instr->Imm26Value())
426 target = (reinterpret_cast<uint64_t>(instr) & ~0xFFFFFFF) | target;
428 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%" PRIx64, target);
429}
430
431// Print 26-bit signed immediate value.
432void Decoder::PrintSImm26(Instruction* instr) {
433 int32_t imm26 = instr->Imm26Value();
434 // set sign
435 imm26 <<= (32 - kImm26Bits);
436 imm26 >>= (32 - kImm26Bits);
438}
439
440// Print absoulte address for 26-bit offset or immediate value.
441// The absolute address is calculated according following expression:
442// PC + delta_pc + (offset << n_bits)
443void Decoder::PrintPCImm26(Instruction* instr, int delta_pc, int n_bits) {
444 int32_t imm26 = instr->Imm26Value();
445 // set sign
446 imm26 <<= (32 - kImm26Bits);
447 imm26 >>= (32 - kImm26Bits);
450 converter_.NameOfAddress(reinterpret_cast<uint8_t*>(instr) + delta_pc +
451 (imm26 << n_bits)));
452}
453
454// Print absoulte address for 26-bit offset or immediate value.
455// The absolute address is calculated according following expression:
456// PC[GPRLEN-1 .. 28] || instr_index26 || 00
457void Decoder::PrintPCImm26(Instruction* instr) {
458 int32_t imm26 = instr->Imm26Value();
459 uint64_t pc_mask = ~0xFFFFFFF;
460 uint64_t pc = ((uint64_t)(instr + 1) & pc_mask) | (imm26 << 2);
463 converter_.NameOfAddress((reinterpret_cast<uint8_t*>(pc))));
464}
465
466void Decoder::PrintBp2(Instruction* instr) {
467 int bp2 = instr->Bp2Value();
469}
470
471void Decoder::PrintBp3(Instruction* instr) {
472 int bp3 = instr->Bp3Value();
474}
475
476// Print 26-bit immediate value.
477void Decoder::PrintCode(Instruction* instr) {
478 if (instr->OpcodeFieldRaw() != SPECIAL)
479 return; // Not a break or trap instruction.
480 switch (instr->FunctionFieldRaw()) {
481 case BREAK: {
482 int32_t code = instr->Bits(25, 6);
484 "0x%05x (%d)", code, code);
485 break;
486 }
487 case TGE:
488 case TGEU:
489 case TLT:
490 case TLTU:
491 case TEQ:
492 case TNE: {
493 int32_t code = instr->Bits(15, 6);
495 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code);
496 break;
497 }
498 default: // Not a break or trap instruction.
499 break;
500 }
501}
502
503void Decoder::PrintMsaXImm8(Instruction* instr) {
504 int32_t imm = instr->MsaImm8Value();
506}
507
508void Decoder::PrintMsaImm8(Instruction* instr) {
509 int32_t imm = instr->MsaImm8Value();
511}
512
513void Decoder::PrintMsaImm5(Instruction* instr) {
514 int32_t imm = instr->MsaImm5Value();
516}
517
518void Decoder::PrintMsaSImm5(Instruction* instr) {
519 int32_t imm = instr->MsaImm5Value();
520 imm <<= (32 - kMsaImm5Bits);
521 imm >>= (32 - kMsaImm5Bits);
523}
524
525void Decoder::PrintMsaSImm10(Instruction* instr, bool is_mi10) {
526 int32_t imm = is_mi10 ? instr->MsaImmMI10Value() : instr->MsaImm10Value();
527 imm <<= (32 - kMsaImm10Bits);
528 imm >>= (32 - kMsaImm10Bits);
530}
531
532void Decoder::PrintMsaImmBit(Instruction* instr) {
533 int32_t m = instr->MsaBitMValue();
535}
536
537void Decoder::PrintMsaImmElm(Instruction* instr) {
538 int32_t n = instr->MsaElmNValue();
540}
541
542void Decoder::PrintMsaCopy(Instruction* instr) {
543 int32_t rd = instr->WdValue();
544 int32_t ws = instr->WsValue();
545 int32_t n = instr->MsaElmNValue();
547 converter_.NameOfCPURegister(rd),
548 MSARegisters::Name(ws), n);
549}
550
551void Decoder::PrintFormat(Instruction* instr) {
552 char formatLetter = ' ';
553 switch (instr->RsFieldRaw()) {
554 case S:
555 formatLetter = 's';
556 break;
557 case D:
558 formatLetter = 'd';
559 break;
560 case W:
561 formatLetter = 'w';
562 break;
563 case L:
564 formatLetter = 'l';
565 break;
566 default:
567 UNREACHABLE();
568 }
569 PrintChar(formatLetter);
570}
571
572void Decoder::PrintMsaDataFormat(Instruction* instr) {
573 DCHECK(instr->IsMSAInstr());
574 char df = ' ';
575 if (instr->IsMSABranchInstr()) {
576 switch (instr->RsFieldRaw()) {
577 case BZ_V:
578 case BNZ_V:
579 df = 'v';
580 break;
581 case BZ_B:
582 case BNZ_B:
583 df = 'b';
584 break;
585 case BZ_H:
586 case BNZ_H:
587 df = 'h';
588 break;
589 case BZ_W:
590 case BNZ_W:
591 df = 'w';
592 break;
593 case BZ_D:
594 case BNZ_D:
595 df = 'd';
596 break;
597 default:
598 UNREACHABLE();
599 }
600 } else {
601 char DF[] = {'b', 'h', 'w', 'd'};
602 switch (instr->MSAMinorOpcodeField()) {
603 case kMsaMinorI5:
604 case kMsaMinorI10:
605 case kMsaMinor3R:
606 df = DF[instr->Bits(22, 21)];
607 break;
608 case kMsaMinorMI10:
609 df = DF[instr->Bits(1, 0)];
610 break;
611 case kMsaMinorBIT:
612 df = DF[instr->MsaBitDf()];
613 break;
614 case kMsaMinorELM:
615 df = DF[instr->MsaElmDf()];
616 break;
617 case kMsaMinor3RF: {
618 uint32_t opcode = instr->InstructionBits() & kMsa3RFMask;
619 switch (opcode) {
620 case FEXDO:
621 case FTQ:
622 case MUL_Q:
623 case MADD_Q:
624 case MSUB_Q:
625 case MULR_Q:
626 case MADDR_Q:
627 case MSUBR_Q:
628 df = DF[1 + instr->Bit(21)];
629 break;
630 default:
631 df = DF[2 + instr->Bit(21)];
632 break;
633 }
634 } break;
635 case kMsaMinor2R:
636 df = DF[instr->Bits(17, 16)];
637 break;
638 case kMsaMinor2RF:
639 df = DF[2 + instr->Bit(16)];
640 break;
641 default:
642 UNREACHABLE();
643 }
644 }
645
646 PrintChar(df);
647}
648
649// Printing of instruction name.
650void Decoder::PrintInstructionName(Instruction* instr) {}
651
652// Handle all register based formatting in this function to reduce the
653// complexity of FormatOption.
654int Decoder::FormatRegister(Instruction* instr, const char* format) {
655 DCHECK_EQ(format[0], 'r');
656 if (format[1] == 's') { // 'rs: Rs register.
657 int reg = instr->RsValue();
659 return 2;
660 } else if (format[1] == 't') { // 'rt: rt register.
661 int reg = instr->RtValue();
663 return 2;
664 } else if (format[1] == 'd') { // 'rd: rd register.
665 int reg = instr->RdValue();
667 return 2;
668 }
669 UNREACHABLE();
670}
671
672// Handle all FPUregister based formatting in this function to reduce the
673// complexity of FormatOption.
674int Decoder::FormatFPURegister(Instruction* instr, const char* format) {
675 DCHECK_EQ(format[0], 'f');
676 if ((CTC1 == instr->RsFieldRaw()) || (CFC1 == instr->RsFieldRaw())) {
677 if (format[1] == 's') { // 'fs: fs register.
678 int reg = instr->FsValue();
680 return 2;
681 } else if (format[1] == 't') { // 'ft: ft register.
682 int reg = instr->FtValue();
684 return 2;
685 } else if (format[1] == 'd') { // 'fd: fd register.
686 int reg = instr->FdValue();
688 return 2;
689 } else if (format[1] == 'r') { // 'fr: fr register.
690 int reg = instr->FrValue();
692 return 2;
693 }
694 } else {
695 if (format[1] == 's') { // 'fs: fs register.
696 int reg = instr->FsValue();
698 return 2;
699 } else if (format[1] == 't') { // 'ft: ft register.
700 int reg = instr->FtValue();
702 return 2;
703 } else if (format[1] == 'd') { // 'fd: fd register.
704 int reg = instr->FdValue();
706 return 2;
707 } else if (format[1] == 'r') { // 'fr: fr register.
708 int reg = instr->FrValue();
710 return 2;
711 }
712 }
713 UNREACHABLE();
714}
715
716// Handle all MSARegister based formatting in this function to reduce the
717// complexity of FormatOption.
718int Decoder::FormatMSARegister(Instruction* instr, const char* format) {
719 DCHECK_EQ(format[0], 'w');
720 if (format[1] == 's') {
721 int reg = instr->WsValue();
722 PrintMSARegister(reg);
723 return 2;
724 } else if (format[1] == 't') {
725 int reg = instr->WtValue();
726 PrintMSARegister(reg);
727 return 2;
728 } else if (format[1] == 'd') {
729 int reg = instr->WdValue();
730 PrintMSARegister(reg);
731 return 2;
732 }
733
734 UNREACHABLE();
735}
736
737// FormatOption takes a formatting string and interprets it based on
738// the current instructions. The format string points to the first
739// character of the option string (the option escape has already been
740// consumed by the caller.) FormatOption returns the number of
741// characters that were consumed from the formatting string.
742int Decoder::FormatOption(Instruction* instr, const char* format) {
743 switch (format[0]) {
744 case 'c': { // 'code for break or trap instructions.
745 DCHECK(STRING_STARTS_WITH(format, "code"));
747 return 4;
748 }
749 case 'i': { // 'imm16u or 'imm26.
750 if (format[3] == '1') {
751 if (format[4] == '6') {
752 DCHECK(STRING_STARTS_WITH(format, "imm16"));
753 switch (format[5]) {
754 case 's':
755 DCHECK(STRING_STARTS_WITH(format, "imm16s"));
756 PrintSImm16(instr);
757 break;
758 case 'u':
759 DCHECK(STRING_STARTS_WITH(format, "imm16u"));
760 PrintSImm16(instr);
761 break;
762 case 'x':
763 DCHECK(STRING_STARTS_WITH(format, "imm16x"));
764 PrintXImm16(instr);
765 break;
766 case 'p': { // The PC relative address.
767 DCHECK(STRING_STARTS_WITH(format, "imm16p"));
768 int delta_pc = 0;
769 int n_bits = 0;
770 switch (format[6]) {
771 case '4': {
772 DCHECK(STRING_STARTS_WITH(format, "imm16p4"));
773 delta_pc = 4;
774 switch (format[8]) {
775 case '2':
776 DCHECK(STRING_STARTS_WITH(format, "imm16p4s2"));
777 n_bits = 2;
778 PrintPCImm16(instr, delta_pc, n_bits);
779 return 9;
780 }
781 }
782 }
783 }
784 }
785 return 6;
786 } else if (format[4] == '8') {
787 DCHECK(STRING_STARTS_WITH(format, "imm18"));
788 switch (format[5]) {
789 case 's':
790 DCHECK(STRING_STARTS_WITH(format, "imm18s"));
791 PrintSImm18(instr);
792 break;
793 case 'x':
794 DCHECK(STRING_STARTS_WITH(format, "imm18x"));
795 PrintXImm18(instr);
796 break;
797 }
798 return 6;
799 } else if (format[4] == '9') {
800 DCHECK(STRING_STARTS_WITH(format, "imm19"));
801 switch (format[5]) {
802 case 's':
803 DCHECK(STRING_STARTS_WITH(format, "imm19s"));
804 PrintSImm19(instr);
805 break;
806 case 'x':
807 DCHECK(STRING_STARTS_WITH(format, "imm19x"));
808 PrintXImm19(instr);
809 break;
810 }
811 return 6;
812 } else if (format[4] == '0' && format[5] == 's') {
813 DCHECK(STRING_STARTS_WITH(format, "imm10s"));
814 if (format[6] == '1') {
815 DCHECK(STRING_STARTS_WITH(format, "imm10s1"));
816 PrintMsaSImm10(instr, false);
817 } else if (format[6] == '2') {
818 DCHECK(STRING_STARTS_WITH(format, "imm10s2"));
819 PrintMsaSImm10(instr, true);
820 }
821 return 7;
822 }
823 } else if (format[3] == '2' && format[4] == '1') {
824 DCHECK(STRING_STARTS_WITH(format, "imm21"));
825 switch (format[5]) {
826 case 's':
827 DCHECK(STRING_STARTS_WITH(format, "imm21s"));
828 PrintSImm21(instr);
829 break;
830 case 'x':
831 DCHECK(STRING_STARTS_WITH(format, "imm21x"));
832 PrintXImm21(instr);
833 break;
834 case 'p': { // The PC relative address.
835 DCHECK(STRING_STARTS_WITH(format, "imm21p"));
836 int delta_pc = 0;
837 int n_bits = 0;
838 switch (format[6]) {
839 case '4': {
840 DCHECK(STRING_STARTS_WITH(format, "imm21p4"));
841 delta_pc = 4;
842 switch (format[8]) {
843 case '2':
844 DCHECK(STRING_STARTS_WITH(format, "imm21p4s2"));
845 n_bits = 2;
846 PrintPCImm21(instr, delta_pc, n_bits);
847 return 9;
848 }
849 }
850 }
851 }
852 }
853 return 6;
854 } else if (format[3] == '2' && format[4] == '6') {
855 DCHECK(STRING_STARTS_WITH(format, "imm26"));
856 switch (format[5]) {
857 case 's':
858 DCHECK(STRING_STARTS_WITH(format, "imm26s"));
859 PrintSImm26(instr);
860 break;
861 case 'x':
862 DCHECK(STRING_STARTS_WITH(format, "imm26x"));
863 PrintXImm26(instr);
864 break;
865 case 'p': { // The PC relative address.
866 DCHECK(STRING_STARTS_WITH(format, "imm26p"));
867 int delta_pc = 0;
868 int n_bits = 0;
869 switch (format[6]) {
870 case '4': {
871 DCHECK(STRING_STARTS_WITH(format, "imm26p4"));
872 delta_pc = 4;
873 switch (format[8]) {
874 case '2':
875 DCHECK(STRING_STARTS_WITH(format, "imm26p4s2"));
876 n_bits = 2;
877 PrintPCImm26(instr, delta_pc, n_bits);
878 return 9;
879 }
880 }
881 }
882 }
883 case 'j': { // Absolute address for jump instructions.
884 DCHECK(STRING_STARTS_WITH(format, "imm26j"));
885 PrintPCImm26(instr);
886 break;
887 }
888 }
889 return 6;
890 } else if (format[3] == '5') {
891 DCHECK(STRING_STARTS_WITH(format, "imm5"));
892 if (format[4] == 'u') {
893 DCHECK(STRING_STARTS_WITH(format, "imm5u"));
894 PrintMsaImm5(instr);
895 } else if (format[4] == 's') {
896 DCHECK(STRING_STARTS_WITH(format, "imm5s"));
897 PrintMsaSImm5(instr);
898 }
899 return 5;
900 } else if (format[3] == '8') {
901 DCHECK(STRING_STARTS_WITH(format, "imm8"));
902 PrintMsaImm8(instr);
903 return 4;
904 } else if (format[3] == '9') {
905 DCHECK(STRING_STARTS_WITH(format, "imm9"));
906 if (format[4] == 'u') {
907 DCHECK(STRING_STARTS_WITH(format, "imm9u"));
908 PrintUImm9(instr);
909 } else if (format[4] == 's') {
910 DCHECK(STRING_STARTS_WITH(format, "imm9s"));
911 PrintSImm9(instr);
912 }
913 return 5;
914 } else if (format[3] == 'b') {
915 DCHECK(STRING_STARTS_WITH(format, "immb"));
916 PrintMsaImmBit(instr);
917 return 4;
918 } else if (format[3] == 'e') {
919 DCHECK(STRING_STARTS_WITH(format, "imme"));
920 PrintMsaImmElm(instr);
921 return 4;
922 }
923 UNREACHABLE();
924 }
925 case 'r': { // 'r: registers.
926 return FormatRegister(instr, format);
927 }
928 case 'f': { // 'f: FPUregisters.
929 return FormatFPURegister(instr, format);
930 }
931 case 'w': { // 'w: MSA Register
932 return FormatMSARegister(instr, format);
933 }
934 case 's': { // 'sa.
935 switch (format[1]) {
936 case 'a':
937 if (format[2] == '2') {
938 DCHECK(STRING_STARTS_WITH(format, "sa2")); // 'sa2
939 PrintLsaSa(instr);
940 return 3;
941 } else {
942 DCHECK(STRING_STARTS_WITH(format, "sa"));
943 PrintSa(instr);
944 return 2;
945 }
946 case 'd': {
947 DCHECK(STRING_STARTS_WITH(format, "sd"));
948 PrintSd(instr);
949 return 2;
950 }
951 case 's': {
952 if (format[2] == '1') {
953 DCHECK(STRING_STARTS_WITH(format, "ss1")); // ext, dext, dextu size
954 PrintSs1(instr);
955 } else if (format[2] == '2') {
956 DCHECK(STRING_STARTS_WITH(format, "ss2")); // ins, dins, dinsu size
957 PrintSs2(instr);
958 } else if (format[2] == '3') {
959 DCHECK(STRING_STARTS_WITH(format, "ss3")); // dextm size
960 PrintSs3(instr);
961 } else if (format[2] == '4') {
962 DCHECK(STRING_STARTS_WITH(format, "ss4")); // dinsm size
963 PrintSs4(instr);
964 } else {
965 DCHECK(STRING_STARTS_WITH(format, "ss5")); // dextu, dinsu pos
966 PrintSs5(instr);
967 }
968 return 3;
969 }
970 }
971 }
972 case 'b': {
973 switch (format[1]) {
974 case 'c': { // 'bc - Special for bc1 cc field.
975 DCHECK(STRING_STARTS_WITH(format, "bc"));
976 PrintBc(instr);
977 return 2;
978 }
979 case 'p': {
980 switch (format[2]) {
981 case '2': { // 'bp2
982 DCHECK(STRING_STARTS_WITH(format, "bp2"));
983 PrintBp2(instr);
984 return 3;
985 }
986 case '3': { // 'bp3
987 DCHECK(STRING_STARTS_WITH(format, "bp3"));
988 PrintBp3(instr);
989 return 3;
990 }
991 }
992 }
993 }
994 }
995 case 'C': { // 'Cc - Special for c.xx.d cc field.
996 DCHECK(STRING_STARTS_WITH(format, "Cc"));
997 PrintCc(instr);
998 return 2;
999 }
1000 case 't':
1001 if (instr->IsMSAInstr()) {
1002 PrintMsaDataFormat(instr);
1003 } else {
1004 PrintFormat(instr);
1005 }
1006 return 1;
1007 }
1008 UNREACHABLE();
1009}
1010
1011// Format takes a formatting string for a whole instruction and prints it into
1012// the output buffer. All escaped options are handed to FormatOption to be
1013// parsed further.
1014void Decoder::Format(Instruction* instr, const char* format) {
1015 char cur = *format++;
1016 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
1017 if (cur == '\'') { // Single quote is used as the formatting escape.
1018 format += FormatOption(instr, format);
1019 } else {
1021 }
1022 cur = *format++;
1023 }
1025}
1026
1027// For currently unimplemented decodings the disassembler calls Unknown(instr)
1028// which will just print "unknown" of the instruction bits.
1029void Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); }
1030
1031int Decoder::DecodeBreakInstr(Instruction* instr) {
1032 // This is already known to be BREAK instr, just extract the code.
1033 if (instr->Bits(25, 6) == static_cast<int>(kMaxStopCode)) {
1034 // This is stop(msg).
1035 Format(instr, "break, code: 'code");
1037 out_buffer_ + out_buffer_pos_, "\n%p %08" PRIx64,
1038 static_cast<void*>(reinterpret_cast<int32_t*>(instr + kInstrSize)),
1039 reinterpret_cast<uint64_t>(
1040 *reinterpret_cast<char**>(instr + kInstrSize)));
1041 // Size 3: the break_ instr, plus embedded 64-bit char pointer.
1042 return 3 * kInstrSize;
1043 } else {
1044 Format(instr, "break, code: 'code");
1045 return kInstrSize;
1046 }
1047}
1048
1049bool Decoder::DecodeTypeRegisterRsType(Instruction* instr) {
1050 switch (instr->FunctionFieldRaw()) {
1051 case RINT:
1052 Format(instr, "rint.'t 'fd, 'fs");
1053 break;
1054 case SEL:
1055 Format(instr, "sel.'t 'fd, 'fs, 'ft");
1056 break;
1057 case SELEQZ_C:
1058 Format(instr, "seleqz.'t 'fd, 'fs, 'ft");
1059 break;
1060 case SELNEZ_C:
1061 Format(instr, "selnez.'t 'fd, 'fs, 'ft");
1062 break;
1063 case MOVZ_C:
1064 Format(instr, "movz.'t 'fd, 'fs, 'rt");
1065 break;
1066 case MOVN_C:
1067 Format(instr, "movn.'t 'fd, 'fs, 'rt");
1068 break;
1069 case MOVF:
1070 if (instr->Bit(16)) {
1071 Format(instr, "movt.'t 'fd, 'fs, 'Cc");
1072 } else {
1073 Format(instr, "movf.'t 'fd, 'fs, 'Cc");
1074 }
1075 break;
1076 case MIN:
1077 Format(instr, "min.'t 'fd, 'fs, 'ft");
1078 break;
1079 case MAX:
1080 Format(instr, "max.'t 'fd, 'fs, 'ft");
1081 break;
1082 case MINA:
1083 Format(instr, "mina.'t 'fd, 'fs, 'ft");
1084 break;
1085 case MAXA:
1086 Format(instr, "maxa.'t 'fd, 'fs, 'ft");
1087 break;
1088 case ADD_D:
1089 Format(instr, "add.'t 'fd, 'fs, 'ft");
1090 break;
1091 case SUB_D:
1092 Format(instr, "sub.'t 'fd, 'fs, 'ft");
1093 break;
1094 case MUL_D:
1095 Format(instr, "mul.'t 'fd, 'fs, 'ft");
1096 break;
1097 case DIV_D:
1098 Format(instr, "div.'t 'fd, 'fs, 'ft");
1099 break;
1100 case ABS_D:
1101 Format(instr, "abs.'t 'fd, 'fs");
1102 break;
1103 case MOV_D:
1104 Format(instr, "mov.'t 'fd, 'fs");
1105 break;
1106 case NEG_D:
1107 Format(instr, "neg.'t 'fd, 'fs");
1108 break;
1109 case SQRT_D:
1110 Format(instr, "sqrt.'t 'fd, 'fs");
1111 break;
1112 case RECIP_D:
1113 Format(instr, "recip.'t 'fd, 'fs");
1114 break;
1115 case RSQRT_D:
1116 Format(instr, "rsqrt.'t 'fd, 'fs");
1117 break;
1118 case CVT_W_D:
1119 Format(instr, "cvt.w.'t 'fd, 'fs");
1120 break;
1121 case CVT_L_D:
1122 Format(instr, "cvt.l.'t 'fd, 'fs");
1123 break;
1124 case TRUNC_W_D:
1125 Format(instr, "trunc.w.'t 'fd, 'fs");
1126 break;
1127 case TRUNC_L_D:
1128 Format(instr, "trunc.l.'t 'fd, 'fs");
1129 break;
1130 case ROUND_W_D:
1131 Format(instr, "round.w.'t 'fd, 'fs");
1132 break;
1133 case ROUND_L_D:
1134 Format(instr, "round.l.'t 'fd, 'fs");
1135 break;
1136 case FLOOR_W_D:
1137 Format(instr, "floor.w.'t 'fd, 'fs");
1138 break;
1139 case FLOOR_L_D:
1140 Format(instr, "floor.l.'t 'fd, 'fs");
1141 break;
1142 case CEIL_W_D:
1143 Format(instr, "ceil.w.'t 'fd, 'fs");
1144 break;
1145 case CEIL_L_D:
1146 Format(instr, "ceil.l.'t 'fd, 'fs");
1147 break;
1148 case CLASS_D:
1149 Format(instr, "class.'t 'fd, 'fs");
1150 break;
1151 case CVT_S_D:
1152 Format(instr, "cvt.s.'t 'fd, 'fs");
1153 break;
1154 case C_F_D:
1155 Format(instr, "c.f.'t 'fs, 'ft, 'Cc");
1156 break;
1157 case C_UN_D:
1158 Format(instr, "c.un.'t 'fs, 'ft, 'Cc");
1159 break;
1160 case C_EQ_D:
1161 Format(instr, "c.eq.'t 'fs, 'ft, 'Cc");
1162 break;
1163 case C_UEQ_D:
1164 Format(instr, "c.ueq.'t 'fs, 'ft, 'Cc");
1165 break;
1166 case C_OLT_D:
1167 Format(instr, "c.olt.'t 'fs, 'ft, 'Cc");
1168 break;
1169 case C_ULT_D:
1170 Format(instr, "c.ult.'t 'fs, 'ft, 'Cc");
1171 break;
1172 case C_OLE_D:
1173 Format(instr, "c.ole.'t 'fs, 'ft, 'Cc");
1174 break;
1175 case C_ULE_D:
1176 Format(instr, "c.ule.'t 'fs, 'ft, 'Cc");
1177 break;
1178 default:
1179 return false;
1180 }
1181 return true;
1182}
1183
1184void Decoder::DecodeTypeRegisterSRsType(Instruction* instr) {
1185 if (!DecodeTypeRegisterRsType(instr)) {
1186 switch (instr->FunctionFieldRaw()) {
1187 case CVT_D_S:
1188 Format(instr, "cvt.d.'t 'fd, 'fs");
1189 break;
1190 case MADDF_S:
1191 Format(instr, "maddf.s 'fd, 'fs, 'ft");
1192 break;
1193 case MSUBF_S:
1194 Format(instr, "msubf.s 'fd, 'fs, 'ft");
1195 break;
1196 default:
1197 Format(instr, "unknown.cop1.'t");
1198 break;
1199 }
1200 }
1201}
1202
1203void Decoder::DecodeTypeRegisterDRsType(Instruction* instr) {
1204 if (!DecodeTypeRegisterRsType(instr)) {
1205 switch (instr->FunctionFieldRaw()) {
1206 case MADDF_D:
1207 Format(instr, "maddf.d 'fd, 'fs, 'ft");
1208 break;
1209 case MSUBF_D:
1210 Format(instr, "msubf.d 'fd, 'fs, 'ft");
1211 break;
1212 default:
1213 Format(instr, "unknown.cop1.'t");
1214 break;
1215 }
1216 }
1217}
1218
1219void Decoder::DecodeTypeRegisterLRsType(Instruction* instr) {
1220 switch (instr->FunctionFieldRaw()) {
1221 case CVT_D_L:
1222 Format(instr, "cvt.d.l 'fd, 'fs");
1223 break;
1224 case CVT_S_L:
1225 Format(instr, "cvt.s.l 'fd, 'fs");
1226 break;
1227 case CMP_AF:
1228 Format(instr, "cmp.af.d 'fd, 'fs, 'ft");
1229 break;
1230 case CMP_UN:
1231 Format(instr, "cmp.un.d 'fd, 'fs, 'ft");
1232 break;
1233 case CMP_EQ:
1234 Format(instr, "cmp.eq.d 'fd, 'fs, 'ft");
1235 break;
1236 case CMP_UEQ:
1237 Format(instr, "cmp.ueq.d 'fd, 'fs, 'ft");
1238 break;
1239 case CMP_LT:
1240 Format(instr, "cmp.lt.d 'fd, 'fs, 'ft");
1241 break;
1242 case CMP_ULT:
1243 Format(instr, "cmp.ult.d 'fd, 'fs, 'ft");
1244 break;
1245 case CMP_LE:
1246 Format(instr, "cmp.le.d 'fd, 'fs, 'ft");
1247 break;
1248 case CMP_ULE:
1249 Format(instr, "cmp.ule.d 'fd, 'fs, 'ft");
1250 break;
1251 case CMP_OR:
1252 Format(instr, "cmp.or.d 'fd, 'fs, 'ft");
1253 break;
1254 case CMP_UNE:
1255 Format(instr, "cmp.une.d 'fd, 'fs, 'ft");
1256 break;
1257 case CMP_NE:
1258 Format(instr, "cmp.ne.d 'fd, 'fs, 'ft");
1259 break;
1260 default:
1261 UNREACHABLE();
1262 }
1263}
1264
1265void Decoder::DecodeTypeRegisterWRsType(Instruction* instr) {
1266 switch (instr->FunctionValue()) {
1267 case CVT_S_W: // Convert word to float (single).
1268 Format(instr, "cvt.s.w 'fd, 'fs");
1269 break;
1270 case CVT_D_W: // Convert word to double.
1271 Format(instr, "cvt.d.w 'fd, 'fs");
1272 break;
1273 case CMP_AF:
1274 Format(instr, "cmp.af.s 'fd, 'fs, 'ft");
1275 break;
1276 case CMP_UN:
1277 Format(instr, "cmp.un.s 'fd, 'fs, 'ft");
1278 break;
1279 case CMP_EQ:
1280 Format(instr, "cmp.eq.s 'fd, 'fs, 'ft");
1281 break;
1282 case CMP_UEQ:
1283 Format(instr, "cmp.ueq.s 'fd, 'fs, 'ft");
1284 break;
1285 case CMP_LT:
1286 Format(instr, "cmp.lt.s 'fd, 'fs, 'ft");
1287 break;
1288 case CMP_ULT:
1289 Format(instr, "cmp.ult.s 'fd, 'fs, 'ft");
1290 break;
1291 case CMP_LE:
1292 Format(instr, "cmp.le.s 'fd, 'fs, 'ft");
1293 break;
1294 case CMP_ULE:
1295 Format(instr, "cmp.ule.s 'fd, 'fs, 'ft");
1296 break;
1297 case CMP_OR:
1298 Format(instr, "cmp.or.s 'fd, 'fs, 'ft");
1299 break;
1300 case CMP_UNE:
1301 Format(instr, "cmp.une.s 'fd, 'fs, 'ft");
1302 break;
1303 case CMP_NE:
1304 Format(instr, "cmp.ne.s 'fd, 'fs, 'ft");
1305 break;
1306 default:
1307 UNREACHABLE();
1308 }
1309}
1310
1311void Decoder::DecodeTypeRegisterCOP1(Instruction* instr) {
1312 switch (instr->RsFieldRaw()) {
1313 case MFC1:
1314 Format(instr, "mfc1 'rt, 'fs");
1315 break;
1316 case DMFC1:
1317 Format(instr, "dmfc1 'rt, 'fs");
1318 break;
1319 case MFHC1:
1320 Format(instr, "mfhc1 'rt, 'fs");
1321 break;
1322 case MTC1:
1323 Format(instr, "mtc1 'rt, 'fs");
1324 break;
1325 case DMTC1:
1326 Format(instr, "dmtc1 'rt, 'fs");
1327 break;
1328 // These are called "fs" too, although they are not FPU registers.
1329 case CTC1:
1330 Format(instr, "ctc1 'rt, 'fs");
1331 break;
1332 case CFC1:
1333 Format(instr, "cfc1 'rt, 'fs");
1334 break;
1335 case MTHC1:
1336 Format(instr, "mthc1 'rt, 'fs");
1337 break;
1338 case S:
1339 DecodeTypeRegisterSRsType(instr);
1340 break;
1341 case D:
1342 DecodeTypeRegisterDRsType(instr);
1343 break;
1344 case W:
1345 DecodeTypeRegisterWRsType(instr);
1346 break;
1347 case L:
1348 DecodeTypeRegisterLRsType(instr);
1349 break;
1350 default:
1351 UNREACHABLE();
1352 }
1353}
1354
1355void Decoder::DecodeTypeRegisterCOP1X(Instruction* instr) {
1356 switch (instr->FunctionFieldRaw()) {
1357 case MADD_S:
1358 Format(instr, "madd.s 'fd, 'fr, 'fs, 'ft");
1359 break;
1360 case MADD_D:
1361 Format(instr, "madd.d 'fd, 'fr, 'fs, 'ft");
1362 break;
1363 case MSUB_S:
1364 Format(instr, "msub.s 'fd, 'fr, 'fs, 'ft");
1365 break;
1366 case MSUB_D:
1367 Format(instr, "msub.d 'fd, 'fr, 'fs, 'ft");
1368 break;
1369 default:
1370 UNREACHABLE();
1371 }
1372}
1373
1374void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) {
1375 switch (instr->FunctionFieldRaw()) {
1376 case JR:
1377 Format(instr, "jr 'rs");
1378 break;
1379 case JALR:
1380 Format(instr, "jalr 'rs, 'rd");
1381 break;
1382 case SLL:
1383 if (0x0 == static_cast<int>(instr->InstructionBits()))
1384 Format(instr, "nop");
1385 else
1386 Format(instr, "sll 'rd, 'rt, 'sa");
1387 break;
1388 case DSLL:
1389 Format(instr, "dsll 'rd, 'rt, 'sa");
1390 break;
1391 case D_MUL_MUH: // Equals to DMUL.
1392 if (kArchVariant != kMips64r6) {
1393 Format(instr, "dmult 'rs, 'rt");
1394 } else {
1395 if (instr->SaValue() == MUL_OP) {
1396 Format(instr, "dmul 'rd, 'rs, 'rt");
1397 } else {
1398 Format(instr, "dmuh 'rd, 'rs, 'rt");
1399 }
1400 }
1401 break;
1402 case DSLL32:
1403 Format(instr, "dsll32 'rd, 'rt, 'sa");
1404 break;
1405 case SRL:
1406 if (instr->RsValue() == 0) {
1407 Format(instr, "srl 'rd, 'rt, 'sa");
1408 } else {
1409 Format(instr, "rotr 'rd, 'rt, 'sa");
1410 }
1411 break;
1412 case DSRL:
1413 if (instr->RsValue() == 0) {
1414 Format(instr, "dsrl 'rd, 'rt, 'sa");
1415 } else {
1416 Format(instr, "drotr 'rd, 'rt, 'sa");
1417 }
1418 break;
1419 case DSRL32:
1420 if (instr->RsValue() == 0) {
1421 Format(instr, "dsrl32 'rd, 'rt, 'sa");
1422 } else {
1423 Format(instr, "drotr32 'rd, 'rt, 'sa");
1424 }
1425 break;
1426 case SRA:
1427 Format(instr, "sra 'rd, 'rt, 'sa");
1428 break;
1429 case DSRA:
1430 Format(instr, "dsra 'rd, 'rt, 'sa");
1431 break;
1432 case DSRA32:
1433 Format(instr, "dsra32 'rd, 'rt, 'sa");
1434 break;
1435 case SLLV:
1436 Format(instr, "sllv 'rd, 'rt, 'rs");
1437 break;
1438 case DSLLV:
1439 Format(instr, "dsllv 'rd, 'rt, 'rs");
1440 break;
1441 case SRLV:
1442 if (instr->SaValue() == 0) {
1443 Format(instr, "srlv 'rd, 'rt, 'rs");
1444 } else {
1445 Format(instr, "rotrv 'rd, 'rt, 'rs");
1446 }
1447 break;
1448 case DSRLV:
1449 if (instr->SaValue() == 0) {
1450 Format(instr, "dsrlv 'rd, 'rt, 'rs");
1451 } else {
1452 Format(instr, "drotrv 'rd, 'rt, 'rs");
1453 }
1454 break;
1455 case SRAV:
1456 Format(instr, "srav 'rd, 'rt, 'rs");
1457 break;
1458 case DSRAV:
1459 Format(instr, "dsrav 'rd, 'rt, 'rs");
1460 break;
1461 case LSA:
1462 Format(instr, "lsa 'rd, 'rt, 'rs, 'sa2");
1463 break;
1464 case DLSA:
1465 Format(instr, "dlsa 'rd, 'rt, 'rs, 'sa2");
1466 break;
1467 case MFHI:
1468 if (instr->Bits(25, 16) == 0) {
1469 Format(instr, "mfhi 'rd");
1470 } else {
1471 if ((instr->FunctionFieldRaw() == CLZ_R6) && (instr->FdValue() == 1)) {
1472 Format(instr, "clz 'rd, 'rs");
1473 } else if ((instr->FunctionFieldRaw() == CLO_R6) &&
1474 (instr->FdValue() == 1)) {
1475 Format(instr, "clo 'rd, 'rs");
1476 }
1477 }
1478 break;
1479 case MFLO:
1480 if (instr->Bits(25, 16) == 0) {
1481 Format(instr, "mflo 'rd");
1482 } else {
1483 if ((instr->FunctionFieldRaw() == DCLZ_R6) && (instr->FdValue() == 1)) {
1484 Format(instr, "dclz 'rd, 'rs");
1485 } else if ((instr->FunctionFieldRaw() == DCLO_R6) &&
1486 (instr->FdValue() == 1)) {
1487 Format(instr, "dclo 'rd, 'rs");
1488 }
1489 }
1490 break;
1491 case D_MUL_MUH_U: // Equals to DMULTU.
1492 if (kArchVariant != kMips64r6) {
1493 Format(instr, "dmultu 'rs, 'rt");
1494 } else {
1495 if (instr->SaValue() == MUL_OP) {
1496 Format(instr, "dmulu 'rd, 'rs, 'rt");
1497 } else {
1498 Format(instr, "dmuhu 'rd, 'rs, 'rt");
1499 }
1500 }
1501 break;
1502 case MULT: // @Mips64r6 == MUL_MUH.
1503 if (kArchVariant != kMips64r6) {
1504 Format(instr, "mult 'rs, 'rt");
1505 } else {
1506 if (instr->SaValue() == MUL_OP) {
1507 Format(instr, "mul 'rd, 'rs, 'rt");
1508 } else {
1509 Format(instr, "muh 'rd, 'rs, 'rt");
1510 }
1511 }
1512 break;
1513 case MULTU: // @Mips64r6 == MUL_MUH_U.
1514 if (kArchVariant != kMips64r6) {
1515 Format(instr, "multu 'rs, 'rt");
1516 } else {
1517 if (instr->SaValue() == MUL_OP) {
1518 Format(instr, "mulu 'rd, 'rs, 'rt");
1519 } else {
1520 Format(instr, "muhu 'rd, 'rs, 'rt");
1521 }
1522 }
1523
1524 break;
1525 case DIV: // @Mips64r6 == DIV_MOD.
1526 if (kArchVariant != kMips64r6) {
1527 Format(instr, "div 'rs, 'rt");
1528 } else {
1529 if (instr->SaValue() == DIV_OP) {
1530 Format(instr, "div 'rd, 'rs, 'rt");
1531 } else {
1532 Format(instr, "mod 'rd, 'rs, 'rt");
1533 }
1534 }
1535 break;
1536 case DDIV: // @Mips64r6 == D_DIV_MOD.
1537 if (kArchVariant != kMips64r6) {
1538 Format(instr, "ddiv 'rs, 'rt");
1539 } else {
1540 if (instr->SaValue() == DIV_OP) {
1541 Format(instr, "ddiv 'rd, 'rs, 'rt");
1542 } else {
1543 Format(instr, "dmod 'rd, 'rs, 'rt");
1544 }
1545 }
1546 break;
1547 case DIVU: // @Mips64r6 == DIV_MOD_U.
1548 if (kArchVariant != kMips64r6) {
1549 Format(instr, "divu 'rs, 'rt");
1550 } else {
1551 if (instr->SaValue() == DIV_OP) {
1552 Format(instr, "divu 'rd, 'rs, 'rt");
1553 } else {
1554 Format(instr, "modu 'rd, 'rs, 'rt");
1555 }
1556 }
1557 break;
1558 case DDIVU: // @Mips64r6 == D_DIV_MOD_U.
1559 if (kArchVariant != kMips64r6) {
1560 Format(instr, "ddivu 'rs, 'rt");
1561 } else {
1562 if (instr->SaValue() == DIV_OP) {
1563 Format(instr, "ddivu 'rd, 'rs, 'rt");
1564 } else {
1565 Format(instr, "dmodu 'rd, 'rs, 'rt");
1566 }
1567 }
1568 break;
1569 case ADD:
1570 Format(instr, "add 'rd, 'rs, 'rt");
1571 break;
1572 case DADD:
1573 Format(instr, "dadd 'rd, 'rs, 'rt");
1574 break;
1575 case ADDU:
1576 Format(instr, "addu 'rd, 'rs, 'rt");
1577 break;
1578 case DADDU:
1579 Format(instr, "daddu 'rd, 'rs, 'rt");
1580 break;
1581 case SUB:
1582 Format(instr, "sub 'rd, 'rs, 'rt");
1583 break;
1584 case DSUB:
1585 Format(instr, "dsub 'rd, 'rs, 'rt");
1586 break;
1587 case SUBU:
1588 Format(instr, "subu 'rd, 'rs, 'rt");
1589 break;
1590 case DSUBU:
1591 Format(instr, "dsubu 'rd, 'rs, 'rt");
1592 break;
1593 case AND:
1594 Format(instr, "and 'rd, 'rs, 'rt");
1595 break;
1596 case OR:
1597 if (0 == instr->RsValue()) {
1598 Format(instr, "mov 'rd, 'rt");
1599 } else if (0 == instr->RtValue()) {
1600 Format(instr, "mov 'rd, 'rs");
1601 } else {
1602 Format(instr, "or 'rd, 'rs, 'rt");
1603 }
1604 break;
1605 case XOR:
1606 Format(instr, "xor 'rd, 'rs, 'rt");
1607 break;
1608 case NOR:
1609 Format(instr, "nor 'rd, 'rs, 'rt");
1610 break;
1611 case SLT:
1612 Format(instr, "slt 'rd, 'rs, 'rt");
1613 break;
1614 case SLTU:
1615 Format(instr, "sltu 'rd, 'rs, 'rt");
1616 break;
1617 case TGE:
1618 Format(instr, "tge 'rs, 'rt, code: 'code");
1619 break;
1620 case TGEU:
1621 Format(instr, "tgeu 'rs, 'rt, code: 'code");
1622 break;
1623 case TLT:
1624 Format(instr, "tlt 'rs, 'rt, code: 'code");
1625 break;
1626 case TLTU:
1627 Format(instr, "tltu 'rs, 'rt, code: 'code");
1628 break;
1629 case TEQ:
1630 Format(instr, "teq 'rs, 'rt, code: 'code");
1631 break;
1632 case TNE:
1633 Format(instr, "tne 'rs, 'rt, code: 'code");
1634 break;
1635 case SYNC:
1636 Format(instr, "sync");
1637 break;
1638 case MOVZ:
1639 Format(instr, "movz 'rd, 'rs, 'rt");
1640 break;
1641 case MOVN:
1642 Format(instr, "movn 'rd, 'rs, 'rt");
1643 break;
1644 case MOVCI:
1645 if (instr->Bit(16)) {
1646 Format(instr, "movt 'rd, 'rs, 'bc");
1647 } else {
1648 Format(instr, "movf 'rd, 'rs, 'bc");
1649 }
1650 break;
1651 case SELEQZ_S:
1652 Format(instr, "seleqz 'rd, 'rs, 'rt");
1653 break;
1654 case SELNEZ_S:
1655 Format(instr, "selnez 'rd, 'rs, 'rt");
1656 break;
1657 default:
1658 UNREACHABLE();
1659 }
1660}
1661
1662void Decoder::DecodeTypeRegisterSPECIAL2(Instruction* instr) {
1663 switch (instr->FunctionFieldRaw()) {
1664 case MUL:
1665 Format(instr, "mul 'rd, 'rs, 'rt");
1666 break;
1667 case CLZ:
1668 if (kArchVariant != kMips64r6) {
1669 Format(instr, "clz 'rd, 'rs");
1670 }
1671 break;
1672 case DCLZ:
1673 if (kArchVariant != kMips64r6) {
1674 Format(instr, "dclz 'rd, 'rs");
1675 }
1676 break;
1677 default:
1678 UNREACHABLE();
1679 }
1680}
1681
1682void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) {
1683 switch (instr->FunctionFieldRaw()) {
1684 case EXT: {
1685 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1");
1686 break;
1687 }
1688 case DEXT: {
1689 Format(instr, "dext 'rt, 'rs, 'sa, 'ss1");
1690 break;
1691 }
1692 case DEXTM: {
1693 Format(instr, "dextm 'rt, 'rs, 'sa, 'ss3");
1694 break;
1695 }
1696 case DEXTU: {
1697 Format(instr, "dextu 'rt, 'rs, 'ss5, 'ss1");
1698 break;
1699 }
1700 case INS: {
1701 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2");
1702 break;
1703 }
1704 case DINS: {
1705 Format(instr, "dins 'rt, 'rs, 'sa, 'ss2");
1706 break;
1707 }
1708 case DINSM: {
1709 Format(instr, "dinsm 'rt, 'rs, 'sa, 'ss4");
1710 break;
1711 }
1712 case DINSU: {
1713 Format(instr, "dinsu 'rt, 'rs, 'ss5, 'ss2");
1714 break;
1715 }
1716 case BSHFL: {
1717 int sa = instr->SaFieldRaw() >> kSaShift;
1718 switch (sa) {
1719 case BITSWAP: {
1720 Format(instr, "bitswap 'rd, 'rt");
1721 break;
1722 }
1723 case SEB: {
1724 Format(instr, "seb 'rd, 'rt");
1725 break;
1726 }
1727 case SEH: {
1728 Format(instr, "seh 'rd, 'rt");
1729 break;
1730 }
1731 case WSBH: {
1732 Format(instr, "wsbh 'rd, 'rt");
1733 break;
1734 }
1735 default: {
1736 sa >>= kBp2Bits;
1737 switch (sa) {
1738 case ALIGN: {
1739 Format(instr, "align 'rd, 'rs, 'rt, 'bp2");
1740 break;
1741 }
1742 default:
1743 UNREACHABLE();
1744 }
1745 break;
1746 }
1747 }
1748 break;
1749 }
1750 case DBSHFL: {
1751 int sa = instr->SaFieldRaw() >> kSaShift;
1752 switch (sa) {
1753 case DBITSWAP: {
1754 switch (instr->SaFieldRaw() >> kSaShift) {
1755 case DBITSWAP_SA:
1756 Format(instr, "dbitswap 'rd, 'rt");
1757 break;
1758 default:
1759 UNREACHABLE();
1760 }
1761 break;
1762 }
1763 case DSBH: {
1764 Format(instr, "dsbh 'rd, 'rt");
1765 break;
1766 }
1767 case DSHD: {
1768 Format(instr, "dshd 'rd, 'rt");
1769 break;
1770 }
1771 default: {
1772 sa >>= kBp3Bits;
1773 switch (sa) {
1774 case DALIGN: {
1775 Format(instr, "dalign 'rd, 'rs, 'rt, 'bp3");
1776 break;
1777 }
1778 default:
1779 UNREACHABLE();
1780 }
1781 break;
1782 }
1783 }
1784 break;
1785 }
1786 default:
1787 UNREACHABLE();
1788 }
1789}
1790
1791int Decoder::DecodeTypeRegister(Instruction* instr) {
1792 switch (instr->OpcodeFieldRaw()) {
1793 case COP1: // Coprocessor instructions.
1794 DecodeTypeRegisterCOP1(instr);
1795 break;
1796 case COP1X:
1797 DecodeTypeRegisterCOP1X(instr);
1798 break;
1799 case SPECIAL:
1800 switch (instr->FunctionFieldRaw()) {
1801 case BREAK:
1802 return DecodeBreakInstr(instr);
1803 default:
1804 DecodeTypeRegisterSPECIAL(instr);
1805 break;
1806 }
1807 break;
1808 case SPECIAL2:
1809 DecodeTypeRegisterSPECIAL2(instr);
1810 break;
1811 case SPECIAL3:
1812 DecodeTypeRegisterSPECIAL3(instr);
1813 break;
1814 case MSA:
1815 switch (instr->MSAMinorOpcodeField()) {
1816 case kMsaMinor3R:
1817 DecodeTypeMsa3R(instr);
1818 break;
1819 case kMsaMinor3RF:
1820 DecodeTypeMsa3RF(instr);
1821 break;
1822 case kMsaMinorVEC:
1823 DecodeTypeMsaVec(instr);
1824 break;
1825 case kMsaMinor2R:
1826 DecodeTypeMsa2R(instr);
1827 break;
1828 case kMsaMinor2RF:
1829 DecodeTypeMsa2RF(instr);
1830 break;
1831 case kMsaMinorELM:
1832 DecodeTypeMsaELM(instr);
1833 break;
1834 default:
1835 UNREACHABLE();
1836 }
1837 break;
1838 default:
1839 UNREACHABLE();
1840 }
1841 return kInstrSize;
1842}
1843
1844void Decoder::DecodeTypeImmediateCOP1(Instruction* instr) {
1845 switch (instr->RsFieldRaw()) {
1846 case BC1:
1847 if (instr->FBtrueValue()) {
1848 Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2");
1849 } else {
1850 Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2");
1851 }
1852 break;
1853 case BC1EQZ:
1854 Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2");
1855 break;
1856 case BC1NEZ:
1857 Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2");
1858 break;
1859 case BZ_V:
1860 case BZ_B:
1861 case BZ_H:
1862 case BZ_W:
1863 case BZ_D:
1864 Format(instr, "bz.'t 'wt, 'imm16s -> 'imm16p4s2");
1865 break;
1866 case BNZ_V:
1867 case BNZ_B:
1868 case BNZ_H:
1869 case BNZ_W:
1870 case BNZ_D:
1871 Format(instr, "bnz.'t 'wt, 'imm16s -> 'imm16p4s2");
1872 break;
1873 default:
1874 UNREACHABLE();
1875 }
1876}
1877
1878void Decoder::DecodeTypeImmediateREGIMM(Instruction* instr) {
1879 switch (instr->RtFieldRaw()) {
1880 case BLTZ:
1881 Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2");
1882 break;
1883 case BLTZAL:
1884 Format(instr, "bltzal 'rs, 'imm16u -> 'imm16p4s2");
1885 break;
1886 case BGEZ:
1887 Format(instr, "bgez 'rs, 'imm16u -> 'imm16p4s2");
1888 break;
1889 case BGEZAL: {
1890 if (instr->RsValue() == 0)
1891 Format(instr, "bal 'imm16s -> 'imm16p4s2");
1892 else
1893 Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2");
1894 break;
1895 }
1896 case BGEZALL:
1897 Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2");
1898 break;
1899 case DAHI:
1900 Format(instr, "dahi 'rs, 'imm16x");
1901 break;
1902 case DATI:
1903 Format(instr, "dati 'rs, 'imm16x");
1904 break;
1905 default:
1906 UNREACHABLE();
1907 }
1908}
1909
1910void Decoder::DecodeTypeImmediateSPECIAL3(Instruction* instr) {
1911 switch (instr->FunctionFieldRaw()) {
1912 case LL_R6: {
1913 if (kArchVariant == kMips64r6) {
1914 Format(instr, "ll 'rt, 'imm9s('rs)");
1915 } else {
1916 Unknown(instr);
1917 }
1918 break;
1919 }
1920 case LLD_R6: {
1921 if (kArchVariant == kMips64r6) {
1922 Format(instr, "lld 'rt, 'imm9s('rs)");
1923 } else {
1924 Unknown(instr);
1925 }
1926 break;
1927 }
1928 case SC_R6: {
1929 if (kArchVariant == kMips64r6) {
1930 Format(instr, "sc 'rt, 'imm9s('rs)");
1931 } else {
1932 Unknown(instr);
1933 }
1934 break;
1935 }
1936 case SCD_R6: {
1937 if (kArchVariant == kMips64r6) {
1938 Format(instr, "scd 'rt, 'imm9s('rs)");
1939 } else {
1940 Unknown(instr);
1941 }
1942 break;
1943 }
1944 default:
1945 UNREACHABLE();
1946 }
1947}
1948
1949void Decoder::DecodeTypeImmediate(Instruction* instr) {
1950 switch (instr->OpcodeFieldRaw()) {
1951 case COP1:
1952 DecodeTypeImmediateCOP1(instr);
1953 break; // Case COP1.
1954 // ------------- REGIMM class.
1955 case REGIMM:
1956 DecodeTypeImmediateREGIMM(instr);
1957 break; // Case REGIMM.
1958 // ------------- Branch instructions.
1959 case BEQ:
1960 Format(instr, "beq 'rs, 'rt, 'imm16u -> 'imm16p4s2");
1961 break;
1962 case BC:
1963 Format(instr, "bc 'imm26s -> 'imm26p4s2");
1964 break;
1965 case BALC:
1966 Format(instr, "balc 'imm26s -> 'imm26p4s2");
1967 break;
1968 case BNE:
1969 Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2");
1970 break;
1971 case BLEZ:
1972 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) {
1973 Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2");
1974 } else if ((instr->RtValue() != instr->RsValue()) &&
1975 (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
1976 Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2");
1977 } else if ((instr->RtValue() == instr->RsValue()) &&
1978 (instr->RtValue() != 0)) {
1979 Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2");
1980 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
1981 Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2");
1982 } else {
1983 UNREACHABLE();
1984 }
1985 break;
1986 case BGTZ:
1987 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) {
1988 Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2");
1989 } else if ((instr->RtValue() != instr->RsValue()) &&
1990 (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
1991 Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2");
1992 } else if ((instr->RtValue() == instr->RsValue()) &&
1993 (instr->RtValue() != 0)) {
1994 Format(instr, "bltzalc 'rt, 'imm16u -> 'imm16p4s2");
1995 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
1996 Format(instr, "bgtzalc 'rt, 'imm16u -> 'imm16p4s2");
1997 } else {
1998 UNREACHABLE();
1999 }
2000 break;
2001 case BLEZL:
2002 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) {
2003 Format(instr, "bgezc 'rt, 'imm16u -> 'imm16p4s2");
2004 } else if ((instr->RtValue() != instr->RsValue()) &&
2005 (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
2006 Format(instr, "bgec 'rs, 'rt, 'imm16u -> 'imm16p4s2");
2007 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
2008 Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2");
2009 } else {
2010 UNREACHABLE();
2011 }
2012 break;
2013 case BGTZL:
2014 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) {
2015 Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2");
2016 } else if ((instr->RtValue() != instr->RsValue()) &&
2017 (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
2018 Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2");
2019 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
2020 Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2");
2021 } else {
2022 UNREACHABLE();
2023 }
2024 break;
2025 case POP66:
2026 if (instr->RsValue() == JIC) {
2027 Format(instr, "jic 'rt, 'imm16s");
2028 } else {
2029 Format(instr, "beqzc 'rs, 'imm21s -> 'imm21p4s2");
2030 }
2031 break;
2032 case POP76:
2033 if (instr->RsValue() == JIALC) {
2034 Format(instr, "jialc 'rt, 'imm16s");
2035 } else {
2036 Format(instr, "bnezc 'rs, 'imm21s -> 'imm21p4s2");
2037 }
2038 break;
2039 // ------------- Arithmetic instructions.
2040 case ADDI:
2041 if (kArchVariant != kMips64r6) {
2042 Format(instr, "addi 'rt, 'rs, 'imm16s");
2043 } else {
2044 int rs_reg = instr->RsValue();
2045 int rt_reg = instr->RtValue();
2046 // Check if BOVC, BEQZALC or BEQC instruction.
2047 if (rs_reg >= rt_reg) {
2048 Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2");
2049 } else {
2050 DCHECK_GT(rt_reg, 0);
2051 if (rs_reg == 0) {
2052 Format(instr, "beqzalc 'rt, 'imm16s -> 'imm16p4s2");
2053 } else {
2054 Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2");
2055 }
2056 }
2057 }
2058 break;
2059 case DADDI:
2060 if (kArchVariant != kMips64r6) {
2061 Format(instr, "daddi 'rt, 'rs, 'imm16s");
2062 } else {
2063 int rs_reg = instr->RsValue();
2064 int rt_reg = instr->RtValue();
2065 // Check if BNVC, BNEZALC or BNEC instruction.
2066 if (rs_reg >= rt_reg) {
2067 Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2");
2068 } else {
2069 DCHECK_GT(rt_reg, 0);
2070 if (rs_reg == 0) {
2071 Format(instr, "bnezalc 'rt, 'imm16s -> 'imm16p4s2");
2072 } else {
2073 Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2");
2074 }
2075 }
2076 }
2077 break;
2078 case ADDIU:
2079 Format(instr, "addiu 'rt, 'rs, 'imm16s");
2080 break;
2081 case DADDIU:
2082 Format(instr, "daddiu 'rt, 'rs, 'imm16s");
2083 break;
2084 case SLTI:
2085 Format(instr, "slti 'rt, 'rs, 'imm16s");
2086 break;
2087 case SLTIU:
2088 Format(instr, "sltiu 'rt, 'rs, 'imm16u");
2089 break;
2090 case ANDI:
2091 Format(instr, "andi 'rt, 'rs, 'imm16x");
2092 break;
2093 case ORI:
2094 Format(instr, "ori 'rt, 'rs, 'imm16x");
2095 break;
2096 case XORI:
2097 Format(instr, "xori 'rt, 'rs, 'imm16x");
2098 break;
2099 case LUI:
2100 if (kArchVariant != kMips64r6) {
2101 Format(instr, "lui 'rt, 'imm16x");
2102 } else {
2103 if (instr->RsValue() != 0) {
2104 Format(instr, "aui 'rt, 'rs, 'imm16x");
2105 } else {
2106 Format(instr, "lui 'rt, 'imm16x");
2107 }
2108 }
2109 break;
2110 case DAUI:
2111 Format(instr, "daui 'rt, 'rs, 'imm16x");
2112 break;
2113 // ------------- Memory instructions.
2114 case LB:
2115 Format(instr, "lb 'rt, 'imm16s('rs)");
2116 break;
2117 case LH:
2118 Format(instr, "lh 'rt, 'imm16s('rs)");
2119 break;
2120 case LWL:
2121 Format(instr, "lwl 'rt, 'imm16s('rs)");
2122 break;
2123 case LDL:
2124 Format(instr, "ldl 'rt, 'imm16s('rs)");
2125 break;
2126 case LW:
2127 Format(instr, "lw 'rt, 'imm16s('rs)");
2128 break;
2129 case LWU:
2130 Format(instr, "lwu 'rt, 'imm16s('rs)");
2131 break;
2132 case LD:
2133 Format(instr, "ld 'rt, 'imm16s('rs)");
2134 break;
2135 case LBU:
2136 Format(instr, "lbu 'rt, 'imm16s('rs)");
2137 break;
2138 case LHU:
2139 Format(instr, "lhu 'rt, 'imm16s('rs)");
2140 break;
2141 case LWR:
2142 Format(instr, "lwr 'rt, 'imm16s('rs)");
2143 break;
2144 case LDR:
2145 Format(instr, "ldr 'rt, 'imm16s('rs)");
2146 break;
2147 case PREF:
2148 Format(instr, "pref 'rt, 'imm16s('rs)");
2149 break;
2150 case SB:
2151 Format(instr, "sb 'rt, 'imm16s('rs)");
2152 break;
2153 case SH:
2154 Format(instr, "sh 'rt, 'imm16s('rs)");
2155 break;
2156 case SWL:
2157 Format(instr, "swl 'rt, 'imm16s('rs)");
2158 break;
2159 case SW:
2160 Format(instr, "sw 'rt, 'imm16s('rs)");
2161 break;
2162 case SD:
2163 Format(instr, "sd 'rt, 'imm16s('rs)");
2164 break;
2165 case SWR:
2166 Format(instr, "swr 'rt, 'imm16s('rs)");
2167 break;
2168 case SDR:
2169 Format(instr, "sdr 'rt, 'imm16s('rs)");
2170 break;
2171 case SDL:
2172 Format(instr, "sdl 'rt, 'imm16s('rs)");
2173 break;
2174 case LL:
2175 if (kArchVariant == kMips64r6) {
2176 Unknown(instr);
2177 } else {
2178 Format(instr, "ll 'rt, 'imm16s('rs)");
2179 }
2180 break;
2181 case LLD:
2182 if (kArchVariant == kMips64r6) {
2183 Unknown(instr);
2184 } else {
2185 Format(instr, "lld 'rt, 'imm16s('rs)");
2186 }
2187 break;
2188 case SC:
2189 if (kArchVariant == kMips64r6) {
2190 Unknown(instr);
2191 } else {
2192 Format(instr, "sc 'rt, 'imm16s('rs)");
2193 }
2194 break;
2195 case SCD:
2196 if (kArchVariant == kMips64r6) {
2197 Unknown(instr);
2198 } else {
2199 Format(instr, "scd 'rt, 'imm16s('rs)");
2200 }
2201 break;
2202 case LWC1:
2203 Format(instr, "lwc1 'ft, 'imm16s('rs)");
2204 break;
2205 case LDC1:
2206 Format(instr, "ldc1 'ft, 'imm16s('rs)");
2207 break;
2208 case SWC1:
2209 Format(instr, "swc1 'ft, 'imm16s('rs)");
2210 break;
2211 case SDC1:
2212 Format(instr, "sdc1 'ft, 'imm16s('rs)");
2213 break;
2214 case PCREL: {
2215 int32_t imm21 = instr->Imm21Value();
2216 // rt field: 5-bits checking
2217 uint8_t rt = (imm21 >> kImm16Bits);
2218 switch (rt) {
2219 case ALUIPC:
2220 Format(instr, "aluipc 'rs, 'imm16s");
2221 break;
2222 case AUIPC:
2223 Format(instr, "auipc 'rs, 'imm16s");
2224 break;
2225 default: {
2226 // rt field: checking of the most significant 3-bits
2227 rt = (imm21 >> kImm18Bits);
2228 switch (rt) {
2229 case LDPC:
2230 Format(instr, "ldpc 'rs, 'imm18s");
2231 break;
2232 default: {
2233 // rt field: checking of the most significant 2-bits
2234 rt = (imm21 >> kImm19Bits);
2235 switch (rt) {
2236 case LWUPC:
2237 Format(instr, "lwupc 'rs, 'imm19s");
2238 break;
2239 case LWPC:
2240 Format(instr, "lwpc 'rs, 'imm19s");
2241 break;
2242 case ADDIUPC:
2243 Format(instr, "addiupc 'rs, 'imm19s");
2244 break;
2245 default:
2246 UNREACHABLE();
2247 }
2248 break;
2249 }
2250 }
2251 break;
2252 }
2253 }
2254 break;
2255 }
2256 case SPECIAL3:
2257 DecodeTypeImmediateSPECIAL3(instr);
2258 break;
2259 case MSA:
2260 switch (instr->MSAMinorOpcodeField()) {
2261 case kMsaMinorI8:
2262 DecodeTypeMsaI8(instr);
2263 break;
2264 case kMsaMinorI5:
2265 DecodeTypeMsaI5(instr);
2266 break;
2267 case kMsaMinorI10:
2268 DecodeTypeMsaI10(instr);
2269 break;
2270 case kMsaMinorELM:
2271 DecodeTypeMsaELM(instr);
2272 break;
2273 case kMsaMinorBIT:
2274 DecodeTypeMsaBIT(instr);
2275 break;
2276 case kMsaMinorMI10:
2277 DecodeTypeMsaMI10(instr);
2278 break;
2279 default:
2280 UNREACHABLE();
2281 }
2282 break;
2283 default:
2284 printf("a 0x%x \n", instr->OpcodeFieldRaw());
2285 UNREACHABLE();
2286 }
2287}
2288
2289void Decoder::DecodeTypeJump(Instruction* instr) {
2290 switch (instr->OpcodeFieldRaw()) {
2291 case J:
2292 Format(instr, "j 'imm26x -> 'imm26j");
2293 break;
2294 case JAL:
2295 Format(instr, "jal 'imm26x -> 'imm26j");
2296 break;
2297 default:
2298 UNREACHABLE();
2299 }
2300}
2301
2302void Decoder::DecodeTypeMsaI8(Instruction* instr) {
2303 uint32_t opcode = instr->InstructionBits() & kMsaI8Mask;
2304
2305 switch (opcode) {
2306 case ANDI_B:
2307 Format(instr, "andi.b 'wd, 'ws, 'imm8");
2308 break;
2309 case ORI_B:
2310 Format(instr, "ori.b 'wd, 'ws, 'imm8");
2311 break;
2312 case NORI_B:
2313 Format(instr, "nori.b 'wd, 'ws, 'imm8");
2314 break;
2315 case XORI_B:
2316 Format(instr, "xori.b 'wd, 'ws, 'imm8");
2317 break;
2318 case BMNZI_B:
2319 Format(instr, "bmnzi.b 'wd, 'ws, 'imm8");
2320 break;
2321 case BMZI_B:
2322 Format(instr, "bmzi.b 'wd, 'ws, 'imm8");
2323 break;
2324 case BSELI_B:
2325 Format(instr, "bseli.b 'wd, 'ws, 'imm8");
2326 break;
2327 case SHF_B:
2328 Format(instr, "shf.b 'wd, 'ws, 'imm8");
2329 break;
2330 case SHF_H:
2331 Format(instr, "shf.h 'wd, 'ws, 'imm8");
2332 break;
2333 case SHF_W:
2334 Format(instr, "shf.w 'wd, 'ws, 'imm8");
2335 break;
2336 default:
2337 UNREACHABLE();
2338 }
2339}
2340
2341void Decoder::DecodeTypeMsaI5(Instruction* instr) {
2342 uint32_t opcode = instr->InstructionBits() & kMsaI5Mask;
2343
2344 switch (opcode) {
2345 case ADDVI:
2346 Format(instr, "addvi.'t 'wd, 'ws, 'imm5u");
2347 break;
2348 case SUBVI:
2349 Format(instr, "subvi.'t 'wd, 'ws, 'imm5u");
2350 break;
2351 case MAXI_S:
2352 Format(instr, "maxi_s.'t 'wd, 'ws, 'imm5s");
2353 break;
2354 case MAXI_U:
2355 Format(instr, "maxi_u.'t 'wd, 'ws, 'imm5u");
2356 break;
2357 case MINI_S:
2358 Format(instr, "mini_s.'t 'wd, 'ws, 'imm5s");
2359 break;
2360 case MINI_U:
2361 Format(instr, "mini_u.'t 'wd, 'ws, 'imm5u");
2362 break;
2363 case CEQI:
2364 Format(instr, "ceqi.'t 'wd, 'ws, 'imm5s");
2365 break;
2366 case CLTI_S:
2367 Format(instr, "clti_s.'t 'wd, 'ws, 'imm5s");
2368 break;
2369 case CLTI_U:
2370 Format(instr, "clti_u.'t 'wd, 'ws, 'imm5u");
2371 break;
2372 case CLEI_S:
2373 Format(instr, "clei_s.'t 'wd, 'ws, 'imm5s");
2374 break;
2375 case CLEI_U:
2376 Format(instr, "clei_u.'t 'wd, 'ws, 'imm5u");
2377 break;
2378 default:
2379 UNREACHABLE();
2380 }
2381}
2382
2383void Decoder::DecodeTypeMsaI10(Instruction* instr) {
2384 uint32_t opcode = instr->InstructionBits() & kMsaI5Mask;
2385 if (opcode == LDI) {
2386 Format(instr, "ldi.'t 'wd, 'imm10s1");
2387 } else {
2388 UNREACHABLE();
2389 }
2390}
2391
2392void Decoder::DecodeTypeMsaELM(Instruction* instr) {
2393 uint32_t opcode = instr->InstructionBits() & kMsaELMMask;
2394 switch (opcode) {
2395 case SLDI:
2396 if (instr->Bits(21, 16) == 0x3E) {
2397 Format(instr, "ctcmsa ");
2398 PrintMSAControlRegister(instr->WdValue());
2399 Print(", ");
2400 PrintRegister(instr->WsValue());
2401 } else {
2402 Format(instr, "sldi.'t 'wd, 'ws['imme]");
2403 }
2404 break;
2405 case SPLATI:
2406 if (instr->Bits(21, 16) == 0x3E) {
2407 Format(instr, "cfcmsa ");
2408 PrintRegister(instr->WdValue());
2409 Print(", ");
2410 PrintMSAControlRegister(instr->WsValue());
2411 } else {
2412 Format(instr, "splati.'t 'wd, 'ws['imme]");
2413 }
2414 break;
2415 case COPY_S:
2416 if (instr->Bits(21, 16) == 0x3E) {
2417 Format(instr, "move.v 'wd, 'ws");
2418 } else {
2419 Format(instr, "copy_s.'t ");
2420 PrintMsaCopy(instr);
2421 }
2422 break;
2423 case COPY_U:
2424 Format(instr, "copy_u.'t ");
2425 PrintMsaCopy(instr);
2426 break;
2427 case INSERT:
2428 Format(instr, "insert.'t 'wd['imme], ");
2429 PrintRegister(instr->WsValue());
2430 break;
2431 case INSVE:
2432 Format(instr, "insve.'t 'wd['imme], 'ws[0]");
2433 break;
2434 default:
2435 UNREACHABLE();
2436 }
2437}
2438
2439void Decoder::DecodeTypeMsaBIT(Instruction* instr) {
2440 uint32_t opcode = instr->InstructionBits() & kMsaBITMask;
2441
2442 switch (opcode) {
2443 case SLLI:
2444 Format(instr, "slli.'t 'wd, 'ws, 'immb");
2445 break;
2446 case SRAI:
2447 Format(instr, "srai.'t 'wd, 'ws, 'immb");
2448 break;
2449 case SRLI:
2450 Format(instr, "srli.'t 'wd, 'ws, 'immb");
2451 break;
2452 case BCLRI:
2453 Format(instr, "bclri.'t 'wd, 'ws, 'immb");
2454 break;
2455 case BSETI:
2456 Format(instr, "bseti.'t 'wd, 'ws, 'immb");
2457 break;
2458 case BNEGI:
2459 Format(instr, "bnegi.'t 'wd, 'ws, 'immb");
2460 break;
2461 case BINSLI:
2462 Format(instr, "binsli.'t 'wd, 'ws, 'immb");
2463 break;
2464 case BINSRI:
2465 Format(instr, "binsri.'t 'wd, 'ws, 'immb");
2466 break;
2467 case SAT_S:
2468 Format(instr, "sat_s.'t 'wd, 'ws, 'immb");
2469 break;
2470 case SAT_U:
2471 Format(instr, "sat_u.'t 'wd, 'ws, 'immb");
2472 break;
2473 case SRARI:
2474 Format(instr, "srari.'t 'wd, 'ws, 'immb");
2475 break;
2476 case SRLRI:
2477 Format(instr, "srlri.'t 'wd, 'ws, 'immb");
2478 break;
2479 default:
2480 UNREACHABLE();
2481 }
2482}
2483
2484void Decoder::DecodeTypeMsaMI10(Instruction* instr) {
2485 uint32_t opcode = instr->InstructionBits() & kMsaMI10Mask;
2486 if (opcode == MSA_LD) {
2487 Format(instr, "ld.'t 'wd, 'imm10s2(");
2488 PrintRegister(instr->WsValue());
2489 Print(")");
2490 } else if (opcode == MSA_ST) {
2491 Format(instr, "st.'t 'wd, 'imm10s2(");
2492 PrintRegister(instr->WsValue());
2493 Print(")");
2494 } else {
2495 UNREACHABLE();
2496 }
2497}
2498
2499void Decoder::DecodeTypeMsa3R(Instruction* instr) {
2500 uint32_t opcode = instr->InstructionBits() & kMsa3RMask;
2501 switch (opcode) {
2502 case SLL_MSA:
2503 Format(instr, "sll.'t 'wd, 'ws, 'wt");
2504 break;
2505 case SRA_MSA:
2506 Format(instr, "sra.'t 'wd, 'ws, 'wt");
2507 break;
2508 case SRL_MSA:
2509 Format(instr, "srl.'t 'wd, 'ws, 'wt");
2510 break;
2511 case BCLR:
2512 Format(instr, "bclr.'t 'wd, 'ws, 'wt");
2513 break;
2514 case BSET:
2515 Format(instr, "bset.'t 'wd, 'ws, 'wt");
2516 break;
2517 case BNEG:
2518 Format(instr, "bneg.'t 'wd, 'ws, 'wt");
2519 break;
2520 case BINSL:
2521 Format(instr, "binsl.'t 'wd, 'ws, 'wt");
2522 break;
2523 case BINSR:
2524 Format(instr, "binsr.'t 'wd, 'ws, 'wt");
2525 break;
2526 case ADDV:
2527 Format(instr, "addv.'t 'wd, 'ws, 'wt");
2528 break;
2529 case SUBV:
2530 Format(instr, "subv.'t 'wd, 'ws, 'wt");
2531 break;
2532 case MAX_S:
2533 Format(instr, "max_s.'t 'wd, 'ws, 'wt");
2534 break;
2535 case MAX_U:
2536 Format(instr, "max_u.'t 'wd, 'ws, 'wt");
2537 break;
2538 case MIN_S:
2539 Format(instr, "min_s.'t 'wd, 'ws, 'wt");
2540 break;
2541 case MIN_U:
2542 Format(instr, "min_u.'t 'wd, 'ws, 'wt");
2543 break;
2544 case MAX_A:
2545 Format(instr, "max_a.'t 'wd, 'ws, 'wt");
2546 break;
2547 case MIN_A:
2548 Format(instr, "min_a.'t 'wd, 'ws, 'wt");
2549 break;
2550 case CEQ:
2551 Format(instr, "ceq.'t 'wd, 'ws, 'wt");
2552 break;
2553 case CLT_S:
2554 Format(instr, "clt_s.'t 'wd, 'ws, 'wt");
2555 break;
2556 case CLT_U:
2557 Format(instr, "clt_u.'t 'wd, 'ws, 'wt");
2558 break;
2559 case CLE_S:
2560 Format(instr, "cle_s.'t 'wd, 'ws, 'wt");
2561 break;
2562 case CLE_U:
2563 Format(instr, "cle_u.'t 'wd, 'ws, 'wt");
2564 break;
2565 case ADD_A:
2566 Format(instr, "add_a.'t 'wd, 'ws, 'wt");
2567 break;
2568 case ADDS_A:
2569 Format(instr, "adds_a.'t 'wd, 'ws, 'wt");
2570 break;
2571 case ADDS_S:
2572 Format(instr, "adds_s.'t 'wd, 'ws, 'wt");
2573 break;
2574 case ADDS_U:
2575 Format(instr, "adds_u.'t 'wd, 'ws, 'wt");
2576 break;
2577 case AVE_S:
2578 Format(instr, "ave_s.'t 'wd, 'ws, 'wt");
2579 break;
2580 case AVE_U:
2581 Format(instr, "ave_u.'t 'wd, 'ws, 'wt");
2582 break;
2583 case AVER_S:
2584 Format(instr, "aver_s.'t 'wd, 'ws, 'wt");
2585 break;
2586 case AVER_U:
2587 Format(instr, "aver_u.'t 'wd, 'ws, 'wt");
2588 break;
2589 case SUBS_S:
2590 Format(instr, "subs_s.'t 'wd, 'ws, 'wt");
2591 break;
2592 case SUBS_U:
2593 Format(instr, "subs_u.'t 'wd, 'ws, 'wt");
2594 break;
2595 case SUBSUS_U:
2596 Format(instr, "subsus_u.'t 'wd, 'ws, 'wt");
2597 break;
2598 case SUBSUU_S:
2599 Format(instr, "subsuu_s.'t 'wd, 'ws, 'wt");
2600 break;
2601 case ASUB_S:
2602 Format(instr, "asub_s.'t 'wd, 'ws, 'wt");
2603 break;
2604 case ASUB_U:
2605 Format(instr, "asub_u.'t 'wd, 'ws, 'wt");
2606 break;
2607 case MULV:
2608 Format(instr, "mulv.'t 'wd, 'ws, 'wt");
2609 break;
2610 case MADDV:
2611 Format(instr, "maddv.'t 'wd, 'ws, 'wt");
2612 break;
2613 case MSUBV:
2614 Format(instr, "msubv.'t 'wd, 'ws, 'wt");
2615 break;
2616 case DIV_S_MSA:
2617 Format(instr, "div_s.'t 'wd, 'ws, 'wt");
2618 break;
2619 case DIV_U:
2620 Format(instr, "div_u.'t 'wd, 'ws, 'wt");
2621 break;
2622 case MOD_S:
2623 Format(instr, "mod_s.'t 'wd, 'ws, 'wt");
2624 break;
2625 case MOD_U:
2626 Format(instr, "mod_u.'t 'wd, 'ws, 'wt");
2627 break;
2628 case DOTP_S:
2629 Format(instr, "dotp_s.'t 'wd, 'ws, 'wt");
2630 break;
2631 case DOTP_U:
2632 Format(instr, "dotp_u.'t 'wd, 'ws, 'wt");
2633 break;
2634 case DPADD_S:
2635 Format(instr, "dpadd_s.'t 'wd, 'ws, 'wt");
2636 break;
2637 case DPADD_U:
2638 Format(instr, "dpadd_u.'t 'wd, 'ws, 'wt");
2639 break;
2640 case DPSUB_S:
2641 Format(instr, "dpsub_s.'t 'wd, 'ws, 'wt");
2642 break;
2643 case DPSUB_U:
2644 Format(instr, "dpsub_u.'t 'wd, 'ws, 'wt");
2645 break;
2646 case SLD:
2647 Format(instr, "sld.'t 'wd, 'ws['rt]");
2648 break;
2649 case SPLAT:
2650 Format(instr, "splat.'t 'wd, 'ws['rt]");
2651 break;
2652 case PCKEV:
2653 Format(instr, "pckev.'t 'wd, 'ws, 'wt");
2654 break;
2655 case PCKOD:
2656 Format(instr, "pckod.'t 'wd, 'ws, 'wt");
2657 break;
2658 case ILVL:
2659 Format(instr, "ilvl.'t 'wd, 'ws, 'wt");
2660 break;
2661 case ILVR:
2662 Format(instr, "ilvr.'t 'wd, 'ws, 'wt");
2663 break;
2664 case ILVEV:
2665 Format(instr, "ilvev.'t 'wd, 'ws, 'wt");
2666 break;
2667 case ILVOD:
2668 Format(instr, "ilvod.'t 'wd, 'ws, 'wt");
2669 break;
2670 case VSHF:
2671 Format(instr, "vshf.'t 'wd, 'ws, 'wt");
2672 break;
2673 case SRAR:
2674 Format(instr, "srar.'t 'wd, 'ws, 'wt");
2675 break;
2676 case SRLR:
2677 Format(instr, "srlr.'t 'wd, 'ws, 'wt");
2678 break;
2679 case HADD_S:
2680 Format(instr, "hadd_s.'t 'wd, 'ws, 'wt");
2681 break;
2682 case HADD_U:
2683 Format(instr, "hadd_u.'t 'wd, 'ws, 'wt");
2684 break;
2685 case HSUB_S:
2686 Format(instr, "hsub_s.'t 'wd, 'ws, 'wt");
2687 break;
2688 case HSUB_U:
2689 Format(instr, "hsub_u.'t 'wd, 'ws, 'wt");
2690 break;
2691 default:
2692 UNREACHABLE();
2693 }
2694}
2695
2696void Decoder::DecodeTypeMsa3RF(Instruction* instr) {
2697 uint32_t opcode = instr->InstructionBits() & kMsa3RFMask;
2698 switch (opcode) {
2699 case FCAF:
2700 Format(instr, "fcaf.'t 'wd, 'ws, 'wt");
2701 break;
2702 case FCUN:
2703 Format(instr, "fcun.'t 'wd, 'ws, 'wt");
2704 break;
2705 case FCEQ:
2706 Format(instr, "fceq.'t 'wd, 'ws, 'wt");
2707 break;
2708 case FCUEQ:
2709 Format(instr, "fcueq.'t 'wd, 'ws, 'wt");
2710 break;
2711 case FCLT:
2712 Format(instr, "fclt.'t 'wd, 'ws, 'wt");
2713 break;
2714 case FCULT:
2715 Format(instr, "fcult.'t 'wd, 'ws, 'wt");
2716 break;
2717 case FCLE:
2718 Format(instr, "fcle.'t 'wd, 'ws, 'wt");
2719 break;
2720 case FCULE:
2721 Format(instr, "fcule.'t 'wd, 'ws, 'wt");
2722 break;
2723 case FSAF:
2724 Format(instr, "fsaf.'t 'wd, 'ws, 'wt");
2725 break;
2726 case FSUN:
2727 Format(instr, "fsun.'t 'wd, 'ws, 'wt");
2728 break;
2729 case FSEQ:
2730 Format(instr, "fseq.'t 'wd, 'ws, 'wt");
2731 break;
2732 case FSUEQ:
2733 Format(instr, "fsueq.'t 'wd, 'ws, 'wt");
2734 break;
2735 case FSLT:
2736 Format(instr, "fslt.'t 'wd, 'ws, 'wt");
2737 break;
2738 case FSULT:
2739 Format(instr, "fsult.'t 'wd, 'ws, 'wt");
2740 break;
2741 case FSLE:
2742 Format(instr, "fsle.'t 'wd, 'ws, 'wt");
2743 break;
2744 case FSULE:
2745 Format(instr, "fsule.'t 'wd, 'ws, 'wt");
2746 break;
2747 case FADD:
2748 Format(instr, "fadd.'t 'wd, 'ws, 'wt");
2749 break;
2750 case FSUB:
2751 Format(instr, "fsub.'t 'wd, 'ws, 'wt");
2752 break;
2753 case FMUL:
2754 Format(instr, "fmul.'t 'wd, 'ws, 'wt");
2755 break;
2756 case FDIV:
2757 Format(instr, "fdiv.'t 'wd, 'ws, 'wt");
2758 break;
2759 case FMADD:
2760 Format(instr, "fmadd.'t 'wd, 'ws, 'wt");
2761 break;
2762 case FMSUB:
2763 Format(instr, "fmsub.'t 'wd, 'ws, 'wt");
2764 break;
2765 case FEXP2:
2766 Format(instr, "fexp2.'t 'wd, 'ws, 'wt");
2767 break;
2768 case FEXDO:
2769 Format(instr, "fexdo.'t 'wd, 'ws, 'wt");
2770 break;
2771 case FTQ:
2772 Format(instr, "ftq.'t 'wd, 'ws, 'wt");
2773 break;
2774 case FMIN:
2775 Format(instr, "fmin.'t 'wd, 'ws, 'wt");
2776 break;
2777 case FMIN_A:
2778 Format(instr, "fmin_a.'t 'wd, 'ws, 'wt");
2779 break;
2780 case FMAX:
2781 Format(instr, "fmax.'t 'wd, 'ws, 'wt");
2782 break;
2783 case FMAX_A:
2784 Format(instr, "fmax_a.'t 'wd, 'ws, 'wt");
2785 break;
2786 case FCOR:
2787 Format(instr, "fcor.'t 'wd, 'ws, 'wt");
2788 break;
2789 case FCUNE:
2790 Format(instr, "fcune.'t 'wd, 'ws, 'wt");
2791 break;
2792 case FCNE:
2793 Format(instr, "fcne.'t 'wd, 'ws, 'wt");
2794 break;
2795 case MUL_Q:
2796 Format(instr, "mul_q.'t 'wd, 'ws, 'wt");
2797 break;
2798 case MADD_Q:
2799 Format(instr, "madd_q.'t 'wd, 'ws, 'wt");
2800 break;
2801 case MSUB_Q:
2802 Format(instr, "msub_q.'t 'wd, 'ws, 'wt");
2803 break;
2804 case FSOR:
2805 Format(instr, "fsor.'t 'wd, 'ws, 'wt");
2806 break;
2807 case FSUNE:
2808 Format(instr, "fsune.'t 'wd, 'ws, 'wt");
2809 break;
2810 case FSNE:
2811 Format(instr, "fsne.'t 'wd, 'ws, 'wt");
2812 break;
2813 case MULR_Q:
2814 Format(instr, "mulr_q.'t 'wd, 'ws, 'wt");
2815 break;
2816 case MADDR_Q:
2817 Format(instr, "maddr_q.'t 'wd, 'ws, 'wt");
2818 break;
2819 case MSUBR_Q:
2820 Format(instr, "msubr_q.'t 'wd, 'ws, 'wt");
2821 break;
2822 default:
2823 UNREACHABLE();
2824 }
2825}
2826
2827void Decoder::DecodeTypeMsaVec(Instruction* instr) {
2828 uint32_t opcode = instr->InstructionBits() & kMsaVECMask;
2829 switch (opcode) {
2830 case AND_V:
2831 Format(instr, "and.v 'wd, 'ws, 'wt");
2832 break;
2833 case OR_V:
2834 Format(instr, "or.v 'wd, 'ws, 'wt");
2835 break;
2836 case NOR_V:
2837 Format(instr, "nor.v 'wd, 'ws, 'wt");
2838 break;
2839 case XOR_V:
2840 Format(instr, "xor.v 'wd, 'ws, 'wt");
2841 break;
2842 case BMNZ_V:
2843 Format(instr, "bmnz.v 'wd, 'ws, 'wt");
2844 break;
2845 case BMZ_V:
2846 Format(instr, "bmz.v 'wd, 'ws, 'wt");
2847 break;
2848 case BSEL_V:
2849 Format(instr, "bsel.v 'wd, 'ws, 'wt");
2850 break;
2851 default:
2852 UNREACHABLE();
2853 }
2854}
2855
2856void Decoder::DecodeTypeMsa2R(Instruction* instr) {
2857 uint32_t opcode = instr->InstructionBits() & kMsa2RMask;
2858 switch (opcode) {
2859 case FILL: {
2860 Format(instr, "fill.'t 'wd, ");
2861 PrintRegister(instr->WsValue()); // rs value is in ws field
2862 } break;
2863 case PCNT:
2864 Format(instr, "pcnt.'t 'wd, 'ws");
2865 break;
2866 case NLOC:
2867 Format(instr, "nloc.'t 'wd, 'ws");
2868 break;
2869 case NLZC:
2870 Format(instr, "nlzc.'t 'wd, 'ws");
2871 break;
2872 default:
2873 UNREACHABLE();
2874 }
2875}
2876
2877void Decoder::DecodeTypeMsa2RF(Instruction* instr) {
2878 uint32_t opcode = instr->InstructionBits() & kMsa2RFMask;
2879 switch (opcode) {
2880 case FCLASS:
2881 Format(instr, "fclass.'t 'wd, 'ws");
2882 break;
2883 case FTRUNC_S:
2884 Format(instr, "ftrunc_s.'t 'wd, 'ws");
2885 break;
2886 case FTRUNC_U:
2887 Format(instr, "ftrunc_u.'t 'wd, 'ws");
2888 break;
2889 case FSQRT:
2890 Format(instr, "fsqrt.'t 'wd, 'ws");
2891 break;
2892 case FRSQRT:
2893 Format(instr, "frsqrt.'t 'wd, 'ws");
2894 break;
2895 case FRCP:
2896 Format(instr, "frcp.'t 'wd, 'ws");
2897 break;
2898 case FRINT:
2899 Format(instr, "frint.'t 'wd, 'ws");
2900 break;
2901 case FLOG2:
2902 Format(instr, "flog2.'t 'wd, 'ws");
2903 break;
2904 case FEXUPL:
2905 Format(instr, "fexupl.'t 'wd, 'ws");
2906 break;
2907 case FEXUPR:
2908 Format(instr, "fexupr.'t 'wd, 'ws");
2909 break;
2910 case FFQL:
2911 Format(instr, "ffql.'t 'wd, 'ws");
2912 break;
2913 case FFQR:
2914 Format(instr, "ffqr.'t 'wd, 'ws");
2915 break;
2916 case FTINT_S:
2917 Format(instr, "ftint_s.'t 'wd, 'ws");
2918 break;
2919 case FTINT_U:
2920 Format(instr, "ftint_u.'t 'wd, 'ws");
2921 break;
2922 case FFINT_S:
2923 Format(instr, "ffint_s.'t 'wd, 'ws");
2924 break;
2925 case FFINT_U:
2926 Format(instr, "ffint_u.'t 'wd, 'ws");
2927 break;
2928 default:
2929 UNREACHABLE();
2930 }
2931}
2932
2933// Disassemble the instruction at *instr_ptr into the output buffer.
2934// All instructions are one word long, except for the simulator
2935// pseudo-instruction stop(msg). For that one special case, we return
2936// size larger than one kInstrSize.
2937int Decoder::InstructionDecode(uint8_t* instr_ptr) {
2938 Instruction* instr = Instruction::At(instr_ptr);
2939 // Print raw instruction bytes.
2941 "%08x ", instr->InstructionBits());
2942 switch (instr->InstructionType()) {
2944 return DecodeTypeRegister(instr);
2945 }
2947 DecodeTypeImmediate(instr);
2948 break;
2949 }
2951 DecodeTypeJump(instr);
2952 break;
2953 }
2954 default: {
2955 Format(instr, "UNSUPPORTED");
2957 }
2958 }
2959 return kInstrSize;
2960}
2961
2962} // namespace internal
2963} // namespace v8
2964
2965//------------------------------------------------------------------------------
2966
2967namespace disasm {
2968
2969const char* NameConverter::NameOfAddress(uint8_t* addr) const {
2970 v8::base::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
2971 return tmp_buffer_.begin();
2972}
2973
2974const char* NameConverter::NameOfConstant(uint8_t* addr) const {
2975 return NameOfAddress(addr);
2976}
2977
2978const char* NameConverter::NameOfCPURegister(int reg) const {
2980}
2981
2982const char* NameConverter::NameOfXMMRegister(int reg) const {
2984}
2985
2986const char* NameConverter::NameOfByteCPURegister(int reg) const {
2987 UNREACHABLE(); // MIPS does not have the concept of a byte register.
2988}
2989
2990const char* NameConverter::NameInCode(uint8_t* addr) const {
2991 // The default name converter is called for unknown code. So we will not try
2992 // to access any memory.
2993 return "";
2994}
2995
2996//------------------------------------------------------------------------------
2997
2999 uint8_t* instruction) {
3001 return d.InstructionDecode(instruction);
3002}
3003
3004// The MIPS assembler does not currently use constant pools.
3005int Disassembler::ConstantPoolSizeAt(uint8_t* instruction) { return -1; }
3006
3007void Disassembler::Disassemble(FILE* f, uint8_t* begin, uint8_t* end,
3008 UnimplementedOpcodeAction unimplemented_action) {
3009 NameConverter converter;
3010 Disassembler d(converter, unimplemented_action);
3011 for (uint8_t* pc = begin; pc < end;) {
3013 buffer[0] = '\0';
3014 uint8_t* prev_pc = pc;
3015 pc += d.InstructionDecode(buffer, pc);
3016 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc),
3017 *reinterpret_cast<int32_t*>(prev_pc), buffer.begin());
3018 }
3019}
3020
3021#undef STRING_STARTS_WITH
3022
3023} // namespace disasm
3024
3025#endif // V8_TARGET_ARCH_MIPS64
static V8_EXPORT_PRIVATE void Disassemble(FILE *f, uint8_t *begin, uint8_t *end, UnimplementedOpcodeAction unimplemented_action=kAbortOnUnimplementedOpcode)
V8_EXPORT_PRIVATE int InstructionDecode(v8::base::Vector< char > buffer, uint8_t *instruction)
int ConstantPoolSizeAt(uint8_t *instruction)
Disassembler(const NameConverter &converter, UnimplementedOpcodeAction unimplemented_opcode_action=kAbortOnUnimplementedOpcode)
Definition disasm.h:44
const NameConverter & converter_
Definition disasm.h:71
virtual const char * NameOfAddress(uint8_t *addr) const
virtual const char * NameOfXMMRegister(int reg) const
virtual const char * NameInCode(uint8_t *addr) const
virtual const char * NameOfConstant(uint8_t *addr) const
v8::base::EmbeddedVector< char, 128 > tmp_buffer_
Definition disasm.h:32
virtual const char * NameOfByteCPURegister(int reg) const
virtual const char * NameOfCPURegister(int reg) const
int length() const
Definition vector.h:64
constexpr T * begin() const
Definition vector.h:96
void Format(Instruction *instr, const char *format)
void PrintFPUStatusRegister(int freg)
void PrintFPURegister(int freg)
int InstructionDecode(uint8_t *instruction)
void Unknown(Instruction *instr)
const disasm::NameConverter & converter_
void PrintRegister(int reg)
void PrintRd(Instruction *instr)
void PrintChar(const char ch)
v8::base::Vector< char > out_buffer_
void PrintInstructionName(Instruction *instr)
int FormatOption(Instruction *instr, const char *option)
int FormatRegister(Instruction *instr, const char *option)
void Print(const char *str)
Decoder & operator=(const Decoder &)=delete
static const char * Name(int reg)
static Instruction * At(Address pc)
static const char * Name(int reg)
static const char * Name(int reg)
#define UNSUPPORTED_MIPS()
@ kMips64r6
static const ArchVariants kArchVariant
int end
#define STRING_STARTS_WITH(string, compare_string)
Instruction * instr
LiftoffRegister reg
int m
Definition mul-fft.cc:294
int int32_t
Definition unicode.cc:40
signed short int16_t
Definition unicode.cc:38
int SNPrintF(Vector< char > str, const char *format,...)
Definition strings.cc:20
void PrintCode(Isolate *isolate, DirectHandle< Code > code, OptimizedCompilationInfo *info)
Definition pipeline.cc:588
constexpr Opcode ADDI
constexpr Opcode ADD
constexpr MiscInstructionsBits74 CLZ
const int kMsaMI10Mask
constexpr Opcode SLTIU
constexpr int W
constexpr Opcode LBU
constexpr Opcode LDR
constexpr Opcode SW
constexpr Opcode SPECIAL
constexpr Opcode AND
constexpr Opcode LHU
constexpr Opcode BGTZ
const int kFCSRRegister
constexpr MoveWideImmediateOp MOVZ
constexpr MoveWideImmediateOp MOVN
constexpr Opcode LH
const int kMsaBITMask
const int kMsa2RFMask
const int kMsaImm5Bits
const int kMsa3RFMask
constexpr BarrierOption LD
void PrintF(const char *format,...)
Definition utils.cc:39
constexpr Opcode SD
constexpr uint32_t kMaxStopCode
constexpr FPDataProcessing2SourceOp FSUB
constexpr Opcode BGTZL
constexpr Opcode POP66
const int kImm18Bits
constexpr Opcode LW
constexpr Opcode LDL
constexpr Opcode SH
constexpr Opcode LL
constexpr Opcode PREF
const int kMsaI5Mask
constexpr Opcode LWU
constexpr FPDataProcessing2SourceOp FMAX
constexpr int L
constexpr Opcode SB
constexpr Opcode JAL
constexpr Opcode DAUI
constexpr Opcode SPECIAL2
constexpr Opcode J
constexpr Opcode REGIMM
constexpr Opcode SWL
constexpr FPDataProcessing2SourceOp FDIV
constexpr int S
constexpr Opcode MSA
const int kMSAIRRegister
constexpr Opcode LUI
const int kImm19Bits
constexpr Opcode SDL
const int kImm21Bits
constexpr Opcode POP76
const int kMsaVECMask
constexpr Opcode LDC1
constexpr FPDataProcessing2SourceOp FADD
constexpr Opcode TEQ
constexpr Opcode PCREL
constexpr Opcode BLEZ
constexpr Opcode LB
constexpr Opcode SUB
constexpr Opcode LWR
constexpr Opcode BALC
constexpr Opcode LLD
constexpr Opcode SC
constexpr Opcode DADDIU
constexpr Opcode SDR
constexpr FPDataProcessing2SourceOp FMIN
const int kMsa3RMask
constexpr uint8_t kInstrSize
constexpr Opcode DADDI
constexpr Opcode SWR
constexpr Opcode SDC1
const int kMsaELMMask
const int kImmFieldShift
constexpr Opcode BLEZL
constexpr Opcode SPECIAL3
constexpr Opcode SWC1
constexpr Opcode ADDIU
const int kMSACSRRegister
constexpr FPDataProcessing2SourceOp FMUL
constexpr Opcode LWC1
const int kMsa2RMask
const int kMsaI8Mask
constexpr Opcode BC
constexpr Opcode COP1
constexpr FPDataProcessing1SourceOp FSQRT
constexpr Opcode LWL
const int kMsaImm10Bits
constexpr Opcode COP1X
constexpr Opcode SCD
#define UNREACHABLE()
Definition logging.h:67
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define DCHECK_GT(v1, v2)
Definition logging.h:487