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