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