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