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