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
26 #include <assert.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #if V8_TARGET_ARCH_MIPS64
32
33 #include "src/base/platform/platform.h"
34 #include "src/disasm.h"
35 #include "src/macro-assembler.h"
36 #include "src/mips64/constants-mips64.h"
37
38 namespace v8 {
39 namespace internal {
40
41 //------------------------------------------------------------------------------
42
43 // Decoder decodes and disassembles instructions into an output buffer.
44 // It uses the converter to convert register names and call destinations into
45 // more informative description.
46 class Decoder {
47 public:
Decoder(const disasm::NameConverter & converter,v8::internal::Vector<char> out_buffer)48 Decoder(const disasm::NameConverter& converter,
49 v8::internal::Vector<char> out_buffer)
50 : converter_(converter),
51 out_buffer_(out_buffer),
52 out_buffer_pos_(0) {
53 out_buffer_[out_buffer_pos_] = '\0';
54 }
55
~Decoder()56 ~Decoder() {}
57
58 // Writes one disassembled instruction into 'buffer' (0-terminated).
59 // Returns the length of the disassembled machine instruction in bytes.
60 int InstructionDecode(byte* instruction);
61
62 private:
63 // Bottleneck functions to print into the out_buffer.
64 void PrintChar(const char ch);
65 void Print(const char* str);
66
67 // Printing of common values.
68 void PrintRegister(int reg);
69 void PrintFPURegister(int freg);
70 void PrintFPUStatusRegister(int freg);
71 void PrintRs(Instruction* instr);
72 void PrintRt(Instruction* instr);
73 void PrintRd(Instruction* instr);
74 void PrintFs(Instruction* instr);
75 void PrintFt(Instruction* instr);
76 void PrintFd(Instruction* instr);
77 void PrintSa(Instruction* instr);
78 void PrintLsaSa(Instruction* instr);
79 void PrintSd(Instruction* instr);
80 void PrintSs1(Instruction* instr);
81 void PrintSs2(Instruction* instr);
82 void PrintBc(Instruction* instr);
83 void PrintCc(Instruction* instr);
84 void PrintFunction(Instruction* instr);
85 void PrintSecondaryField(Instruction* instr);
86 void PrintUImm16(Instruction* instr);
87 void PrintSImm16(Instruction* instr);
88 void PrintXImm16(Instruction* instr);
89 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits);
90 void PrintXImm18(Instruction* instr);
91 void PrintSImm18(Instruction* instr);
92 void PrintXImm19(Instruction* instr);
93 void PrintSImm19(Instruction* instr);
94 void PrintXImm21(Instruction* instr);
95 void PrintSImm21(Instruction* instr);
96 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits);
97 void PrintXImm26(Instruction* instr);
98 void PrintSImm26(Instruction* instr);
99 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits);
100 void PrintPCImm26(Instruction* instr);
101 void PrintCode(Instruction* instr); // For break and trap instructions.
102 void PrintFormat(Instruction* instr); // For floating format postfix.
103 void PrintBp2(Instruction* instr);
104 void PrintBp3(Instruction* instr);
105 // Printing of instruction name.
106 void PrintInstructionName(Instruction* instr);
107
108 // Handle formatting of instructions and their options.
109 int FormatRegister(Instruction* instr, const char* option);
110 int FormatFPURegister(Instruction* instr, const char* option);
111 int FormatOption(Instruction* instr, const char* option);
112 void Format(Instruction* instr, const char* format);
113 void Unknown(Instruction* instr);
114 int DecodeBreakInstr(Instruction* instr);
115
116 // Each of these functions decodes one particular instruction type.
117 bool DecodeTypeRegisterRsType(Instruction* instr);
118 void DecodeTypeRegisterSRsType(Instruction* instr);
119 void DecodeTypeRegisterDRsType(Instruction* instr);
120 void DecodeTypeRegisterLRsType(Instruction* instr);
121 void DecodeTypeRegisterWRsType(Instruction* instr);
122 void DecodeTypeRegisterSPECIAL(Instruction* instr);
123 void DecodeTypeRegisterSPECIAL2(Instruction* instr);
124 void DecodeTypeRegisterSPECIAL3(Instruction* instr);
125 void DecodeTypeRegisterCOP1(Instruction* instr);
126 void DecodeTypeRegisterCOP1X(Instruction* instr);
127 int DecodeTypeRegister(Instruction* instr);
128
129 void DecodeTypeImmediateCOP1(Instruction* instr);
130 void DecodeTypeImmediateREGIMM(Instruction* instr);
131 void DecodeTypeImmediate(Instruction* instr);
132
133 void DecodeTypeJump(Instruction* instr);
134
135 const disasm::NameConverter& converter_;
136 v8::internal::Vector<char> out_buffer_;
137 int out_buffer_pos_;
138
139 DISALLOW_COPY_AND_ASSIGN(Decoder);
140 };
141
142
143 // Support for assertions in the Decoder formatting functions.
144 #define STRING_STARTS_WITH(string, compare_string) \
145 (strncmp(string, compare_string, strlen(compare_string)) == 0)
146
147
148 // Append the ch to the output buffer.
PrintChar(const char ch)149 void Decoder::PrintChar(const char ch) {
150 out_buffer_[out_buffer_pos_++] = ch;
151 }
152
153
154 // Append the str to the output buffer.
Print(const char * str)155 void Decoder::Print(const char* str) {
156 char cur = *str++;
157 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
158 PrintChar(cur);
159 cur = *str++;
160 }
161 out_buffer_[out_buffer_pos_] = 0;
162 }
163
164
165 // Print the register name according to the active name converter.
PrintRegister(int reg)166 void Decoder::PrintRegister(int reg) {
167 Print(converter_.NameOfCPURegister(reg));
168 }
169
170
PrintRs(Instruction * instr)171 void Decoder::PrintRs(Instruction* instr) {
172 int reg = instr->RsValue();
173 PrintRegister(reg);
174 }
175
176
PrintRt(Instruction * instr)177 void Decoder::PrintRt(Instruction* instr) {
178 int reg = instr->RtValue();
179 PrintRegister(reg);
180 }
181
182
PrintRd(Instruction * instr)183 void Decoder::PrintRd(Instruction* instr) {
184 int reg = instr->RdValue();
185 PrintRegister(reg);
186 }
187
188
189 // Print the FPUregister name according to the active name converter.
PrintFPURegister(int freg)190 void Decoder::PrintFPURegister(int freg) {
191 Print(converter_.NameOfXMMRegister(freg));
192 }
193
194
PrintFPUStatusRegister(int freg)195 void Decoder::PrintFPUStatusRegister(int freg) {
196 switch (freg) {
197 case kFCSRRegister:
198 Print("FCSR");
199 break;
200 default:
201 Print(converter_.NameOfXMMRegister(freg));
202 }
203 }
204
205
PrintFs(Instruction * instr)206 void Decoder::PrintFs(Instruction* instr) {
207 int freg = instr->RsValue();
208 PrintFPURegister(freg);
209 }
210
211
PrintFt(Instruction * instr)212 void Decoder::PrintFt(Instruction* instr) {
213 int freg = instr->RtValue();
214 PrintFPURegister(freg);
215 }
216
217
PrintFd(Instruction * instr)218 void Decoder::PrintFd(Instruction* instr) {
219 int freg = instr->RdValue();
220 PrintFPURegister(freg);
221 }
222
223
224 // Print the integer value of the sa field.
PrintSa(Instruction * instr)225 void Decoder::PrintSa(Instruction* instr) {
226 int sa = instr->SaValue();
227 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa);
228 }
229
230
231 // Print the integer value of the sa field of a lsa instruction.
PrintLsaSa(Instruction * instr)232 void Decoder::PrintLsaSa(Instruction* instr) {
233 int sa = instr->LsaSaValue() + 1;
234 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa);
235 }
236
237
238 // Print the integer value of the rd field, when it is not used as reg.
PrintSd(Instruction * instr)239 void Decoder::PrintSd(Instruction* instr) {
240 int sd = instr->RdValue();
241 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sd);
242 }
243
244
245 // Print the integer value of the rd field, when used as 'ext' size.
PrintSs1(Instruction * instr)246 void Decoder::PrintSs1(Instruction* instr) {
247 int ss = instr->RdValue();
248 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss + 1);
249 }
250
251
252 // Print the integer value of the rd field, when used as 'ins' size.
PrintSs2(Instruction * instr)253 void Decoder::PrintSs2(Instruction* instr) {
254 int ss = instr->RdValue();
255 int pos = instr->SaValue();
256 out_buffer_pos_ +=
257 SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss - pos + 1);
258 }
259
260
261 // Print the integer value of the cc field for the bc1t/f instructions.
PrintBc(Instruction * instr)262 void Decoder::PrintBc(Instruction* instr) {
263 int cc = instr->FBccValue();
264 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", cc);
265 }
266
267
268 // Print the integer value of the cc field for the FP compare instructions.
PrintCc(Instruction * instr)269 void Decoder::PrintCc(Instruction* instr) {
270 int cc = instr->FCccValue();
271 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "cc(%d)", cc);
272 }
273
274
275 // Print 16-bit unsigned immediate value.
PrintUImm16(Instruction * instr)276 void Decoder::PrintUImm16(Instruction* instr) {
277 int32_t imm = instr->Imm16Value();
278 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm);
279 }
280
281
282 // Print 16-bit signed immediate value.
PrintSImm16(Instruction * instr)283 void Decoder::PrintSImm16(Instruction* instr) {
284 int32_t imm =
285 ((instr->Imm16Value()) << (32 - kImm16Bits)) >> (32 - kImm16Bits);
286 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
287 }
288
289
290 // Print 16-bit hexa immediate value.
PrintXImm16(Instruction * instr)291 void Decoder::PrintXImm16(Instruction* instr) {
292 int32_t imm = instr->Imm16Value();
293 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
294 }
295
296
297 // Print absoulte address for 16-bit offset or immediate value.
298 // The absolute address is calculated according following expression:
299 // PC + delta_pc + (offset << n_bits)
PrintPCImm16(Instruction * instr,int delta_pc,int n_bits)300 void Decoder::PrintPCImm16(Instruction* instr, int delta_pc, int n_bits) {
301 int16_t offset = instr->Imm16Value();
302 out_buffer_pos_ +=
303 SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
304 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) +
305 delta_pc + (offset << n_bits)));
306 }
307
308
309 // Print 18-bit signed immediate value.
PrintSImm18(Instruction * instr)310 void Decoder::PrintSImm18(Instruction* instr) {
311 int32_t imm =
312 ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits);
313 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
314 }
315
316
317 // Print 18-bit hexa immediate value.
PrintXImm18(Instruction * instr)318 void Decoder::PrintXImm18(Instruction* instr) {
319 int32_t imm = instr->Imm18Value();
320 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
321 }
322
323
324 // Print 19-bit hexa immediate value.
PrintXImm19(Instruction * instr)325 void Decoder::PrintXImm19(Instruction* instr) {
326 int32_t imm = instr->Imm19Value();
327 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
328 }
329
330
331 // Print 19-bit signed immediate value.
PrintSImm19(Instruction * instr)332 void Decoder::PrintSImm19(Instruction* instr) {
333 int32_t imm19 = instr->Imm19Value();
334 // set sign
335 imm19 <<= (32 - kImm19Bits);
336 imm19 >>= (32 - kImm19Bits);
337 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm19);
338 }
339
340
341 // Print 21-bit immediate value.
PrintXImm21(Instruction * instr)342 void Decoder::PrintXImm21(Instruction* instr) {
343 uint32_t imm = instr->Imm21Value();
344 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
345 }
346
347
348 // Print 21-bit signed immediate value.
PrintSImm21(Instruction * instr)349 void Decoder::PrintSImm21(Instruction* instr) {
350 int32_t imm21 = instr->Imm21Value();
351 // set sign
352 imm21 <<= (32 - kImm21Bits);
353 imm21 >>= (32 - kImm21Bits);
354 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm21);
355 }
356
357
358 // Print absoulte address for 21-bit offset or immediate value.
359 // The absolute address is calculated according following expression:
360 // PC + delta_pc + (offset << n_bits)
PrintPCImm21(Instruction * instr,int delta_pc,int n_bits)361 void Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) {
362 int32_t imm21 = instr->Imm21Value();
363 // set sign
364 imm21 <<= (32 - kImm21Bits);
365 imm21 >>= (32 - kImm21Bits);
366 out_buffer_pos_ +=
367 SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
368 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) +
369 delta_pc + (imm21 << n_bits)));
370 }
371
372
373 // Print 26-bit hex immediate value.
PrintXImm26(Instruction * instr)374 void Decoder::PrintXImm26(Instruction* instr) {
375 uint64_t target = static_cast<uint64_t>(instr->Imm26Value())
376 << kImmFieldShift;
377 target = (reinterpret_cast<uint64_t>(instr) & ~0xfffffff) | target;
378 out_buffer_pos_ +=
379 SNPrintF(out_buffer_ + out_buffer_pos_, "0x%" PRIx64, target);
380 }
381
382
383 // Print 26-bit signed immediate value.
PrintSImm26(Instruction * instr)384 void Decoder::PrintSImm26(Instruction* instr) {
385 int32_t imm26 = instr->Imm26Value();
386 // set sign
387 imm26 <<= (32 - kImm26Bits);
388 imm26 >>= (32 - kImm26Bits);
389 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26);
390 }
391
392
393 // Print absoulte address for 26-bit offset or immediate value.
394 // The absolute address is calculated according following expression:
395 // PC + delta_pc + (offset << n_bits)
PrintPCImm26(Instruction * instr,int delta_pc,int n_bits)396 void Decoder::PrintPCImm26(Instruction* instr, int delta_pc, int n_bits) {
397 int32_t imm26 = instr->Imm26Value();
398 // set sign
399 imm26 <<= (32 - kImm26Bits);
400 imm26 >>= (32 - kImm26Bits);
401 out_buffer_pos_ +=
402 SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
403 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) +
404 delta_pc + (imm26 << n_bits)));
405 }
406
407
408 // Print absoulte address for 26-bit offset or immediate value.
409 // The absolute address is calculated according following expression:
410 // PC[GPRLEN-1 .. 28] || instr_index26 || 00
PrintPCImm26(Instruction * instr)411 void Decoder::PrintPCImm26(Instruction* instr) {
412 int32_t imm26 = instr->Imm26Value();
413 uint64_t pc_mask = ~0xfffffff;
414 uint64_t pc = ((uint64_t)(instr + 1) & pc_mask) | (imm26 << 2);
415 out_buffer_pos_ +=
416 SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
417 converter_.NameOfAddress((reinterpret_cast<byte*>(pc))));
418 }
419
420
PrintBp2(Instruction * instr)421 void Decoder::PrintBp2(Instruction* instr) {
422 int bp2 = instr->Bp2Value();
423 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp2);
424 }
425
426
PrintBp3(Instruction * instr)427 void Decoder::PrintBp3(Instruction* instr) {
428 int bp3 = instr->Bp3Value();
429 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp3);
430 }
431
432
433 // Print 26-bit immediate value.
PrintCode(Instruction * instr)434 void Decoder::PrintCode(Instruction* instr) {
435 if (instr->OpcodeFieldRaw() != SPECIAL)
436 return; // Not a break or trap instruction.
437 switch (instr->FunctionFieldRaw()) {
438 case BREAK: {
439 int32_t code = instr->Bits(25, 6);
440 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
441 "0x%05x (%d)", code, code);
442 break;
443 }
444 case TGE:
445 case TGEU:
446 case TLT:
447 case TLTU:
448 case TEQ:
449 case TNE: {
450 int32_t code = instr->Bits(15, 6);
451 out_buffer_pos_ +=
452 SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code);
453 break;
454 }
455 default: // Not a break or trap instruction.
456 break;
457 }
458 }
459
460
PrintFormat(Instruction * instr)461 void Decoder::PrintFormat(Instruction* instr) {
462 char formatLetter = ' ';
463 switch (instr->RsFieldRaw()) {
464 case S:
465 formatLetter = 's';
466 break;
467 case D:
468 formatLetter = 'd';
469 break;
470 case W:
471 formatLetter = 'w';
472 break;
473 case L:
474 formatLetter = 'l';
475 break;
476 default:
477 UNREACHABLE();
478 break;
479 }
480 PrintChar(formatLetter);
481 }
482
483
484 // Printing of instruction name.
PrintInstructionName(Instruction * instr)485 void Decoder::PrintInstructionName(Instruction* instr) {
486 }
487
488
489 // Handle all register based formatting in this function to reduce the
490 // complexity of FormatOption.
FormatRegister(Instruction * instr,const char * format)491 int Decoder::FormatRegister(Instruction* instr, const char* format) {
492 DCHECK(format[0] == 'r');
493 if (format[1] == 's') { // 'rs: Rs register.
494 int reg = instr->RsValue();
495 PrintRegister(reg);
496 return 2;
497 } else if (format[1] == 't') { // 'rt: rt register.
498 int reg = instr->RtValue();
499 PrintRegister(reg);
500 return 2;
501 } else if (format[1] == 'd') { // 'rd: rd register.
502 int reg = instr->RdValue();
503 PrintRegister(reg);
504 return 2;
505 }
506 UNREACHABLE();
507 return -1;
508 }
509
510
511 // Handle all FPUregister based formatting in this function to reduce the
512 // complexity of FormatOption.
FormatFPURegister(Instruction * instr,const char * format)513 int Decoder::FormatFPURegister(Instruction* instr, const char* format) {
514 DCHECK(format[0] == 'f');
515 if ((CTC1 == instr->RsFieldRaw()) || (CFC1 == instr->RsFieldRaw())) {
516 if (format[1] == 's') { // 'fs: fs register.
517 int reg = instr->FsValue();
518 PrintFPUStatusRegister(reg);
519 return 2;
520 } else if (format[1] == 't') { // 'ft: ft register.
521 int reg = instr->FtValue();
522 PrintFPUStatusRegister(reg);
523 return 2;
524 } else if (format[1] == 'd') { // 'fd: fd register.
525 int reg = instr->FdValue();
526 PrintFPUStatusRegister(reg);
527 return 2;
528 } else if (format[1] == 'r') { // 'fr: fr register.
529 int reg = instr->FrValue();
530 PrintFPUStatusRegister(reg);
531 return 2;
532 }
533 } else {
534 if (format[1] == 's') { // 'fs: fs register.
535 int reg = instr->FsValue();
536 PrintFPURegister(reg);
537 return 2;
538 } else if (format[1] == 't') { // 'ft: ft register.
539 int reg = instr->FtValue();
540 PrintFPURegister(reg);
541 return 2;
542 } else if (format[1] == 'd') { // 'fd: fd register.
543 int reg = instr->FdValue();
544 PrintFPURegister(reg);
545 return 2;
546 } else if (format[1] == 'r') { // 'fr: fr register.
547 int reg = instr->FrValue();
548 PrintFPURegister(reg);
549 return 2;
550 }
551 }
552 UNREACHABLE();
553 return -1;
554 }
555
556
557 // FormatOption takes a formatting string and interprets it based on
558 // the current instructions. The format string points to the first
559 // character of the option string (the option escape has already been
560 // consumed by the caller.) FormatOption returns the number of
561 // characters that were consumed from the formatting string.
FormatOption(Instruction * instr,const char * format)562 int Decoder::FormatOption(Instruction* instr, const char* format) {
563 switch (format[0]) {
564 case 'c': { // 'code for break or trap instructions.
565 DCHECK(STRING_STARTS_WITH(format, "code"));
566 PrintCode(instr);
567 return 4;
568 }
569 case 'i': { // 'imm16u or 'imm26.
570 if (format[3] == '1') {
571 if (format[4] == '6') {
572 DCHECK(STRING_STARTS_WITH(format, "imm16"));
573 switch (format[5]) {
574 case 's':
575 DCHECK(STRING_STARTS_WITH(format, "imm16s"));
576 PrintSImm16(instr);
577 break;
578 case 'u':
579 DCHECK(STRING_STARTS_WITH(format, "imm16u"));
580 PrintSImm16(instr);
581 break;
582 case 'x':
583 DCHECK(STRING_STARTS_WITH(format, "imm16x"));
584 PrintXImm16(instr);
585 break;
586 case 'p': { // The PC relative address.
587 DCHECK(STRING_STARTS_WITH(format, "imm16p"));
588 int delta_pc = 0;
589 int n_bits = 0;
590 switch (format[6]) {
591 case '4': {
592 DCHECK(STRING_STARTS_WITH(format, "imm16p4"));
593 delta_pc = 4;
594 switch (format[8]) {
595 case '2':
596 DCHECK(STRING_STARTS_WITH(format, "imm16p4s2"));
597 n_bits = 2;
598 PrintPCImm16(instr, delta_pc, n_bits);
599 return 9;
600 }
601 }
602 }
603 }
604 }
605 return 6;
606 } else if (format[4] == '8') {
607 DCHECK(STRING_STARTS_WITH(format, "imm18"));
608 switch (format[5]) {
609 case 's':
610 DCHECK(STRING_STARTS_WITH(format, "imm18s"));
611 PrintSImm18(instr);
612 break;
613 case 'x':
614 DCHECK(STRING_STARTS_WITH(format, "imm18x"));
615 PrintXImm18(instr);
616 break;
617 }
618 return 6;
619 } else if (format[4] == '9') {
620 DCHECK(STRING_STARTS_WITH(format, "imm19"));
621 switch (format[5]) {
622 case 's':
623 DCHECK(STRING_STARTS_WITH(format, "imm19s"));
624 PrintSImm19(instr);
625 break;
626 case 'x':
627 DCHECK(STRING_STARTS_WITH(format, "imm19x"));
628 PrintXImm19(instr);
629 break;
630 }
631 return 6;
632 }
633 } else if (format[3] == '2' && format[4] == '1') {
634 DCHECK(STRING_STARTS_WITH(format, "imm21"));
635 switch (format[5]) {
636 case 's':
637 DCHECK(STRING_STARTS_WITH(format, "imm21s"));
638 PrintSImm21(instr);
639 break;
640 case 'x':
641 DCHECK(STRING_STARTS_WITH(format, "imm21x"));
642 PrintXImm21(instr);
643 break;
644 case 'p': { // The PC relative address.
645 DCHECK(STRING_STARTS_WITH(format, "imm21p"));
646 int delta_pc = 0;
647 int n_bits = 0;
648 switch (format[6]) {
649 case '4': {
650 DCHECK(STRING_STARTS_WITH(format, "imm21p4"));
651 delta_pc = 4;
652 switch (format[8]) {
653 case '2':
654 DCHECK(STRING_STARTS_WITH(format, "imm21p4s2"));
655 n_bits = 2;
656 PrintPCImm21(instr, delta_pc, n_bits);
657 return 9;
658 }
659 }
660 }
661 }
662 }
663 return 6;
664 } else if (format[3] == '2' && format[4] == '6') {
665 DCHECK(STRING_STARTS_WITH(format, "imm26"));
666 switch (format[5]) {
667 case 's':
668 DCHECK(STRING_STARTS_WITH(format, "imm26s"));
669 PrintSImm26(instr);
670 break;
671 case 'x':
672 DCHECK(STRING_STARTS_WITH(format, "imm26x"));
673 PrintXImm26(instr);
674 break;
675 case 'p': { // The PC relative address.
676 DCHECK(STRING_STARTS_WITH(format, "imm26p"));
677 int delta_pc = 0;
678 int n_bits = 0;
679 switch (format[6]) {
680 case '4': {
681 DCHECK(STRING_STARTS_WITH(format, "imm26p4"));
682 delta_pc = 4;
683 switch (format[8]) {
684 case '2':
685 DCHECK(STRING_STARTS_WITH(format, "imm26p4s2"));
686 n_bits = 2;
687 PrintPCImm26(instr, delta_pc, n_bits);
688 return 9;
689 }
690 }
691 }
692 }
693 case 'j': { // Absolute address for jump instructions.
694 DCHECK(STRING_STARTS_WITH(format, "imm26j"));
695 PrintPCImm26(instr);
696 break;
697 }
698 }
699 return 6;
700 }
701 }
702 case 'r': { // 'r: registers.
703 return FormatRegister(instr, format);
704 }
705 case 'f': { // 'f: FPUregisters.
706 return FormatFPURegister(instr, format);
707 }
708 case 's': { // 'sa.
709 switch (format[1]) {
710 case 'a':
711 if (format[2] == '2') {
712 DCHECK(STRING_STARTS_WITH(format, "sa2")); // 'sa2
713 PrintLsaSa(instr);
714 return 3;
715 } else {
716 DCHECK(STRING_STARTS_WITH(format, "sa"));
717 PrintSa(instr);
718 return 2;
719 }
720 break;
721 case 'd': {
722 DCHECK(STRING_STARTS_WITH(format, "sd"));
723 PrintSd(instr);
724 return 2;
725 }
726 case 's': {
727 if (format[2] == '1') {
728 DCHECK(STRING_STARTS_WITH(format, "ss1")); /* ext size */
729 PrintSs1(instr);
730 return 3;
731 } else {
732 DCHECK(STRING_STARTS_WITH(format, "ss2")); /* ins size */
733 PrintSs2(instr);
734 return 3;
735 }
736 }
737 }
738 }
739 case 'b': {
740 switch (format[1]) {
741 case 'c': { // 'bc - Special for bc1 cc field.
742 DCHECK(STRING_STARTS_WITH(format, "bc"));
743 PrintBc(instr);
744 return 2;
745 }
746 case 'p': {
747 switch (format[2]) {
748 case '2': { // 'bp2
749 DCHECK(STRING_STARTS_WITH(format, "bp2"));
750 PrintBp2(instr);
751 return 3;
752 }
753 case '3': { // 'bp3
754 DCHECK(STRING_STARTS_WITH(format, "bp3"));
755 PrintBp3(instr);
756 return 3;
757 }
758 }
759 }
760 }
761 }
762 case 'C': { // 'Cc - Special for c.xx.d cc field.
763 DCHECK(STRING_STARTS_WITH(format, "Cc"));
764 PrintCc(instr);
765 return 2;
766 }
767 case 't':
768 PrintFormat(instr);
769 return 1;
770 }
771 UNREACHABLE();
772 return -1;
773 }
774
775
776 // Format takes a formatting string for a whole instruction and prints it into
777 // the output buffer. All escaped options are handed to FormatOption to be
778 // parsed further.
Format(Instruction * instr,const char * format)779 void Decoder::Format(Instruction* instr, const char* format) {
780 char cur = *format++;
781 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
782 if (cur == '\'') { // Single quote is used as the formatting escape.
783 format += FormatOption(instr, format);
784 } else {
785 out_buffer_[out_buffer_pos_++] = cur;
786 }
787 cur = *format++;
788 }
789 out_buffer_[out_buffer_pos_] = '\0';
790 }
791
792
793 // For currently unimplemented decodings the disassembler calls Unknown(instr)
794 // which will just print "unknown" of the instruction bits.
Unknown(Instruction * instr)795 void Decoder::Unknown(Instruction* instr) {
796 Format(instr, "unknown");
797 }
798
799
DecodeBreakInstr(Instruction * instr)800 int Decoder::DecodeBreakInstr(Instruction* instr) {
801 // This is already known to be BREAK instr, just extract the code.
802 if (instr->Bits(25, 6) == static_cast<int>(kMaxStopCode)) {
803 // This is stop(msg).
804 Format(instr, "break, code: 'code");
805 out_buffer_pos_ += SNPrintF(
806 out_buffer_ + out_buffer_pos_, "\n%p %08" PRIx64,
807 static_cast<void*>(
808 reinterpret_cast<int32_t*>(instr + Instruction::kInstrSize)),
809 reinterpret_cast<uint64_t>(
810 *reinterpret_cast<char**>(instr + Instruction::kInstrSize)));
811 // Size 3: the break_ instr, plus embedded 64-bit char pointer.
812 return 3 * Instruction::kInstrSize;
813 } else {
814 Format(instr, "break, code: 'code");
815 return Instruction::kInstrSize;
816 }
817 }
818
819
DecodeTypeRegisterRsType(Instruction * instr)820 bool Decoder::DecodeTypeRegisterRsType(Instruction* instr) {
821 switch (instr->FunctionFieldRaw()) {
822 case RINT:
823 Format(instr, "rint.'t 'fd, 'fs");
824 break;
825 case SEL:
826 Format(instr, "sel.'t 'fd, 'fs, 'ft");
827 break;
828 case SELEQZ_C:
829 Format(instr, "seleqz.'t 'fd, 'fs, 'ft");
830 break;
831 case SELNEZ_C:
832 Format(instr, "selnez.'t 'fd, 'fs, 'ft");
833 break;
834 case MOVZ_C:
835 Format(instr, "movz.'t 'fd, 'fs, 'rt");
836 break;
837 case MOVN_C:
838 Format(instr, "movn.'t 'fd, 'fs, 'rt");
839 break;
840 case MOVF:
841 if (instr->Bit(16)) {
842 Format(instr, "movt.'t 'fd, 'fs, 'Cc");
843 } else {
844 Format(instr, "movf.'t 'fd, 'fs, 'Cc");
845 }
846 break;
847 case MIN:
848 Format(instr, "min.'t 'fd, 'fs, 'ft");
849 break;
850 case MAX:
851 Format(instr, "max.'t 'fd, 'fs, 'ft");
852 break;
853 case MINA:
854 Format(instr, "mina.'t 'fd, 'fs, 'ft");
855 break;
856 case MAXA:
857 Format(instr, "maxa.'t 'fd, 'fs, 'ft");
858 break;
859 case ADD_D:
860 Format(instr, "add.'t 'fd, 'fs, 'ft");
861 break;
862 case SUB_D:
863 Format(instr, "sub.'t 'fd, 'fs, 'ft");
864 break;
865 case MUL_D:
866 Format(instr, "mul.'t 'fd, 'fs, 'ft");
867 break;
868 case DIV_D:
869 Format(instr, "div.'t 'fd, 'fs, 'ft");
870 break;
871 case ABS_D:
872 Format(instr, "abs.'t 'fd, 'fs");
873 break;
874 case MOV_D:
875 Format(instr, "mov.'t 'fd, 'fs");
876 break;
877 case NEG_D:
878 Format(instr, "neg.'t 'fd, 'fs");
879 break;
880 case SQRT_D:
881 Format(instr, "sqrt.'t 'fd, 'fs");
882 break;
883 case RECIP_D:
884 Format(instr, "recip.'t 'fd, 'fs");
885 break;
886 case RSQRT_D:
887 Format(instr, "rsqrt.'t 'fd, 'fs");
888 break;
889 case CVT_W_D:
890 Format(instr, "cvt.w.'t 'fd, 'fs");
891 break;
892 case CVT_L_D:
893 Format(instr, "cvt.l.'t 'fd, 'fs");
894 break;
895 case TRUNC_W_D:
896 Format(instr, "trunc.w.'t 'fd, 'fs");
897 break;
898 case TRUNC_L_D:
899 Format(instr, "trunc.l.'t 'fd, 'fs");
900 break;
901 case ROUND_W_D:
902 Format(instr, "round.w.'t 'fd, 'fs");
903 break;
904 case ROUND_L_D:
905 Format(instr, "round.l.'t 'fd, 'fs");
906 break;
907 case FLOOR_W_D:
908 Format(instr, "floor.w.'t 'fd, 'fs");
909 break;
910 case FLOOR_L_D:
911 Format(instr, "floor.l.'t 'fd, 'fs");
912 break;
913 case CEIL_W_D:
914 Format(instr, "ceil.w.'t 'fd, 'fs");
915 break;
916 case CEIL_L_D:
917 Format(instr, "ceil.l.'t 'fd, 'fs");
918 break;
919 case CLASS_D:
920 Format(instr, "class.'t 'fd, 'fs");
921 break;
922 case CVT_S_D:
923 Format(instr, "cvt.s.'t 'fd, 'fs");
924 break;
925 case C_F_D:
926 Format(instr, "c.f.'t 'fs, 'ft, 'Cc");
927 break;
928 case C_UN_D:
929 Format(instr, "c.un.'t 'fs, 'ft, 'Cc");
930 break;
931 case C_EQ_D:
932 Format(instr, "c.eq.'t 'fs, 'ft, 'Cc");
933 break;
934 case C_UEQ_D:
935 Format(instr, "c.ueq.'t 'fs, 'ft, 'Cc");
936 break;
937 case C_OLT_D:
938 Format(instr, "c.olt.'t 'fs, 'ft, 'Cc");
939 break;
940 case C_ULT_D:
941 Format(instr, "c.ult.'t 'fs, 'ft, 'Cc");
942 break;
943 case C_OLE_D:
944 Format(instr, "c.ole.'t 'fs, 'ft, 'Cc");
945 break;
946 case C_ULE_D:
947 Format(instr, "c.ule.'t 'fs, 'ft, 'Cc");
948 break;
949 default:
950 return false;
951 }
952 return true;
953 }
954
955
DecodeTypeRegisterSRsType(Instruction * instr)956 void Decoder::DecodeTypeRegisterSRsType(Instruction* instr) {
957 if (!DecodeTypeRegisterRsType(instr)) {
958 switch (instr->FunctionFieldRaw()) {
959 case CVT_D_S:
960 Format(instr, "cvt.d.'t 'fd, 'fs");
961 break;
962 case MADDF_S:
963 Format(instr, "maddf.s 'fd, 'fs, 'ft");
964 break;
965 case MSUBF_S:
966 Format(instr, "msubf.s 'fd, 'fs, 'ft");
967 break;
968 default:
969 Format(instr, "unknown.cop1.'t");
970 break;
971 }
972 }
973 }
974
975
DecodeTypeRegisterDRsType(Instruction * instr)976 void Decoder::DecodeTypeRegisterDRsType(Instruction* instr) {
977 if (!DecodeTypeRegisterRsType(instr)) {
978 switch (instr->FunctionFieldRaw()) {
979 case MADDF_D:
980 Format(instr, "maddf.d 'fd, 'fs, 'ft");
981 break;
982 case MSUBF_D:
983 Format(instr, "msubf.d 'fd, 'fs, 'ft");
984 break;
985 default:
986 Format(instr, "unknown.cop1.'t");
987 break;
988 }
989 }
990 }
991
992
DecodeTypeRegisterLRsType(Instruction * instr)993 void Decoder::DecodeTypeRegisterLRsType(Instruction* instr) {
994 switch (instr->FunctionFieldRaw()) {
995 case CVT_D_L:
996 Format(instr, "cvt.d.l 'fd, 'fs");
997 break;
998 case CVT_S_L:
999 Format(instr, "cvt.s.l 'fd, 'fs");
1000 break;
1001 case CMP_AF:
1002 Format(instr, "cmp.af.d 'fd, 'fs, 'ft");
1003 break;
1004 case CMP_UN:
1005 Format(instr, "cmp.un.d 'fd, 'fs, 'ft");
1006 break;
1007 case CMP_EQ:
1008 Format(instr, "cmp.eq.d 'fd, 'fs, 'ft");
1009 break;
1010 case CMP_UEQ:
1011 Format(instr, "cmp.ueq.d 'fd, 'fs, 'ft");
1012 break;
1013 case CMP_LT:
1014 Format(instr, "cmp.lt.d 'fd, 'fs, 'ft");
1015 break;
1016 case CMP_ULT:
1017 Format(instr, "cmp.ult.d 'fd, 'fs, 'ft");
1018 break;
1019 case CMP_LE:
1020 Format(instr, "cmp.le.d 'fd, 'fs, 'ft");
1021 break;
1022 case CMP_ULE:
1023 Format(instr, "cmp.ule.d 'fd, 'fs, 'ft");
1024 break;
1025 case CMP_OR:
1026 Format(instr, "cmp.or.d 'fd, 'fs, 'ft");
1027 break;
1028 case CMP_UNE:
1029 Format(instr, "cmp.une.d 'fd, 'fs, 'ft");
1030 break;
1031 case CMP_NE:
1032 Format(instr, "cmp.ne.d 'fd, 'fs, 'ft");
1033 break;
1034 default:
1035 UNREACHABLE();
1036 }
1037 }
1038
1039
DecodeTypeRegisterWRsType(Instruction * instr)1040 void Decoder::DecodeTypeRegisterWRsType(Instruction* instr) {
1041 switch (instr->FunctionValue()) {
1042 case CVT_S_W: // Convert word to float (single).
1043 Format(instr, "cvt.s.w 'fd, 'fs");
1044 break;
1045 case CVT_D_W: // Convert word to double.
1046 Format(instr, "cvt.d.w 'fd, 'fs");
1047 break;
1048 case CMP_AF:
1049 Format(instr, "cmp.af.s 'fd, 'fs, 'ft");
1050 break;
1051 case CMP_UN:
1052 Format(instr, "cmp.un.s 'fd, 'fs, 'ft");
1053 break;
1054 case CMP_EQ:
1055 Format(instr, "cmp.eq.s 'fd, 'fs, 'ft");
1056 break;
1057 case CMP_UEQ:
1058 Format(instr, "cmp.ueq.s 'fd, 'fs, 'ft");
1059 break;
1060 case CMP_LT:
1061 Format(instr, "cmp.lt.s 'fd, 'fs, 'ft");
1062 break;
1063 case CMP_ULT:
1064 Format(instr, "cmp.ult.s 'fd, 'fs, 'ft");
1065 break;
1066 case CMP_LE:
1067 Format(instr, "cmp.le.s 'fd, 'fs, 'ft");
1068 break;
1069 case CMP_ULE:
1070 Format(instr, "cmp.ule.s 'fd, 'fs, 'ft");
1071 break;
1072 case CMP_OR:
1073 Format(instr, "cmp.or.s 'fd, 'fs, 'ft");
1074 break;
1075 case CMP_UNE:
1076 Format(instr, "cmp.une.s 'fd, 'fs, 'ft");
1077 break;
1078 case CMP_NE:
1079 Format(instr, "cmp.ne.s 'fd, 'fs, 'ft");
1080 break;
1081 default:
1082 UNREACHABLE();
1083 }
1084 }
1085
1086
DecodeTypeRegisterCOP1(Instruction * instr)1087 void Decoder::DecodeTypeRegisterCOP1(Instruction* instr) {
1088 switch (instr->RsFieldRaw()) {
1089 case MFC1:
1090 Format(instr, "mfc1 'rt, 'fs");
1091 break;
1092 case DMFC1:
1093 Format(instr, "dmfc1 'rt, 'fs");
1094 break;
1095 case MFHC1:
1096 Format(instr, "mfhc1 'rt, 'fs");
1097 break;
1098 case MTC1:
1099 Format(instr, "mtc1 'rt, 'fs");
1100 break;
1101 case DMTC1:
1102 Format(instr, "dmtc1 'rt, 'fs");
1103 break;
1104 // These are called "fs" too, although they are not FPU registers.
1105 case CTC1:
1106 Format(instr, "ctc1 'rt, 'fs");
1107 break;
1108 case CFC1:
1109 Format(instr, "cfc1 'rt, 'fs");
1110 break;
1111 case MTHC1:
1112 Format(instr, "mthc1 'rt, 'fs");
1113 break;
1114 case S:
1115 DecodeTypeRegisterSRsType(instr);
1116 break;
1117 case D:
1118 DecodeTypeRegisterDRsType(instr);
1119 break;
1120 case W:
1121 DecodeTypeRegisterWRsType(instr);
1122 break;
1123 case L:
1124 DecodeTypeRegisterLRsType(instr);
1125 break;
1126 default:
1127 UNREACHABLE();
1128 }
1129 }
1130
1131
DecodeTypeRegisterCOP1X(Instruction * instr)1132 void Decoder::DecodeTypeRegisterCOP1X(Instruction* instr) {
1133 switch (instr->FunctionFieldRaw()) {
1134 case MADD_S:
1135 Format(instr, "madd.s 'fd, 'fr, 'fs, 'ft");
1136 break;
1137 case MADD_D:
1138 Format(instr, "madd.d 'fd, 'fr, 'fs, 'ft");
1139 break;
1140 case MSUB_S:
1141 Format(instr, "msub.s 'fd, 'fr, 'fs, 'ft");
1142 break;
1143 case MSUB_D:
1144 Format(instr, "msub.d 'fd, 'fr, 'fs, 'ft");
1145 break;
1146 default:
1147 UNREACHABLE();
1148 }
1149 }
1150
1151
DecodeTypeRegisterSPECIAL(Instruction * instr)1152 void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) {
1153 switch (instr->FunctionFieldRaw()) {
1154 case JR:
1155 Format(instr, "jr 'rs");
1156 break;
1157 case JALR:
1158 Format(instr, "jalr 'rs, 'rd");
1159 break;
1160 case SLL:
1161 if (0x0 == static_cast<int>(instr->InstructionBits()))
1162 Format(instr, "nop");
1163 else
1164 Format(instr, "sll 'rd, 'rt, 'sa");
1165 break;
1166 case DSLL:
1167 Format(instr, "dsll 'rd, 'rt, 'sa");
1168 break;
1169 case D_MUL_MUH: // Equals to DMUL.
1170 if (kArchVariant != kMips64r6) {
1171 Format(instr, "dmult 'rs, 'rt");
1172 } else {
1173 if (instr->SaValue() == MUL_OP) {
1174 Format(instr, "dmul 'rd, 'rs, 'rt");
1175 } else {
1176 Format(instr, "dmuh 'rd, 'rs, 'rt");
1177 }
1178 }
1179 break;
1180 case DSLL32:
1181 Format(instr, "dsll32 'rd, 'rt, 'sa");
1182 break;
1183 case SRL:
1184 if (instr->RsValue() == 0) {
1185 Format(instr, "srl 'rd, 'rt, 'sa");
1186 } else {
1187 Format(instr, "rotr 'rd, 'rt, 'sa");
1188 }
1189 break;
1190 case DSRL:
1191 if (instr->RsValue() == 0) {
1192 Format(instr, "dsrl 'rd, 'rt, 'sa");
1193 } else {
1194 Format(instr, "drotr 'rd, 'rt, 'sa");
1195 }
1196 break;
1197 case DSRL32:
1198 if (instr->RsValue() == 0) {
1199 Format(instr, "dsrl32 'rd, 'rt, 'sa");
1200 } else {
1201 Format(instr, "drotr32 'rd, 'rt, 'sa");
1202 }
1203 break;
1204 case SRA:
1205 Format(instr, "sra 'rd, 'rt, 'sa");
1206 break;
1207 case DSRA:
1208 Format(instr, "dsra 'rd, 'rt, 'sa");
1209 break;
1210 case DSRA32:
1211 Format(instr, "dsra32 'rd, 'rt, 'sa");
1212 break;
1213 case SLLV:
1214 Format(instr, "sllv 'rd, 'rt, 'rs");
1215 break;
1216 case DSLLV:
1217 Format(instr, "dsllv 'rd, 'rt, 'rs");
1218 break;
1219 case SRLV:
1220 if (instr->SaValue() == 0) {
1221 Format(instr, "srlv 'rd, 'rt, 'rs");
1222 } else {
1223 Format(instr, "rotrv 'rd, 'rt, 'rs");
1224 }
1225 break;
1226 case DSRLV:
1227 if (instr->SaValue() == 0) {
1228 Format(instr, "dsrlv 'rd, 'rt, 'rs");
1229 } else {
1230 Format(instr, "drotrv 'rd, 'rt, 'rs");
1231 }
1232 break;
1233 case SRAV:
1234 Format(instr, "srav 'rd, 'rt, 'rs");
1235 break;
1236 case DSRAV:
1237 Format(instr, "dsrav 'rd, 'rt, 'rs");
1238 break;
1239 case LSA:
1240 Format(instr, "lsa 'rd, 'rt, 'rs, 'sa2");
1241 break;
1242 case DLSA:
1243 Format(instr, "dlsa 'rd, 'rt, 'rs, 'sa2");
1244 break;
1245 case MFHI:
1246 if (instr->Bits(25, 16) == 0) {
1247 Format(instr, "mfhi 'rd");
1248 } else {
1249 if ((instr->FunctionFieldRaw() == CLZ_R6) && (instr->FdValue() == 1)) {
1250 Format(instr, "clz 'rd, 'rs");
1251 } else if ((instr->FunctionFieldRaw() == CLO_R6) &&
1252 (instr->FdValue() == 1)) {
1253 Format(instr, "clo 'rd, 'rs");
1254 }
1255 }
1256 break;
1257 case MFLO:
1258 if (instr->Bits(25, 16) == 0) {
1259 Format(instr, "mflo 'rd");
1260 } else {
1261 if ((instr->FunctionFieldRaw() == DCLZ_R6) && (instr->FdValue() == 1)) {
1262 Format(instr, "dclz 'rd, 'rs");
1263 } else if ((instr->FunctionFieldRaw() == DCLO_R6) &&
1264 (instr->FdValue() == 1)) {
1265 Format(instr, "dclo 'rd, 'rs");
1266 }
1267 }
1268 break;
1269 case D_MUL_MUH_U: // Equals to DMULTU.
1270 if (kArchVariant != kMips64r6) {
1271 Format(instr, "dmultu 'rs, 'rt");
1272 } else {
1273 if (instr->SaValue() == MUL_OP) {
1274 Format(instr, "dmulu 'rd, 'rs, 'rt");
1275 } else {
1276 Format(instr, "dmuhu 'rd, 'rs, 'rt");
1277 }
1278 }
1279 break;
1280 case MULT: // @Mips64r6 == MUL_MUH.
1281 if (kArchVariant != kMips64r6) {
1282 Format(instr, "mult 'rs, 'rt");
1283 } else {
1284 if (instr->SaValue() == MUL_OP) {
1285 Format(instr, "mul 'rd, 'rs, 'rt");
1286 } else {
1287 Format(instr, "muh 'rd, 'rs, 'rt");
1288 }
1289 }
1290 break;
1291 case MULTU: // @Mips64r6 == MUL_MUH_U.
1292 if (kArchVariant != kMips64r6) {
1293 Format(instr, "multu 'rs, 'rt");
1294 } else {
1295 if (instr->SaValue() == MUL_OP) {
1296 Format(instr, "mulu 'rd, 'rs, 'rt");
1297 } else {
1298 Format(instr, "muhu 'rd, 'rs, 'rt");
1299 }
1300 }
1301
1302 break;
1303 case DIV: // @Mips64r6 == DIV_MOD.
1304 if (kArchVariant != kMips64r6) {
1305 Format(instr, "div 'rs, 'rt");
1306 } else {
1307 if (instr->SaValue() == DIV_OP) {
1308 Format(instr, "div 'rd, 'rs, 'rt");
1309 } else {
1310 Format(instr, "mod 'rd, 'rs, 'rt");
1311 }
1312 }
1313 break;
1314 case DDIV: // @Mips64r6 == D_DIV_MOD.
1315 if (kArchVariant != kMips64r6) {
1316 Format(instr, "ddiv 'rs, 'rt");
1317 } else {
1318 if (instr->SaValue() == DIV_OP) {
1319 Format(instr, "ddiv 'rd, 'rs, 'rt");
1320 } else {
1321 Format(instr, "dmod 'rd, 'rs, 'rt");
1322 }
1323 }
1324 break;
1325 case DIVU: // @Mips64r6 == DIV_MOD_U.
1326 if (kArchVariant != kMips64r6) {
1327 Format(instr, "divu 'rs, 'rt");
1328 } else {
1329 if (instr->SaValue() == DIV_OP) {
1330 Format(instr, "divu 'rd, 'rs, 'rt");
1331 } else {
1332 Format(instr, "modu 'rd, 'rs, 'rt");
1333 }
1334 }
1335 break;
1336 case DDIVU: // @Mips64r6 == D_DIV_MOD_U.
1337 if (kArchVariant != kMips64r6) {
1338 Format(instr, "ddivu 'rs, 'rt");
1339 } else {
1340 if (instr->SaValue() == DIV_OP) {
1341 Format(instr, "ddivu 'rd, 'rs, 'rt");
1342 } else {
1343 Format(instr, "dmodu 'rd, 'rs, 'rt");
1344 }
1345 }
1346 break;
1347 case ADD:
1348 Format(instr, "add 'rd, 'rs, 'rt");
1349 break;
1350 case DADD:
1351 Format(instr, "dadd 'rd, 'rs, 'rt");
1352 break;
1353 case ADDU:
1354 Format(instr, "addu 'rd, 'rs, 'rt");
1355 break;
1356 case DADDU:
1357 Format(instr, "daddu 'rd, 'rs, 'rt");
1358 break;
1359 case SUB:
1360 Format(instr, "sub 'rd, 'rs, 'rt");
1361 break;
1362 case DSUB:
1363 Format(instr, "dsub 'rd, 'rs, 'rt");
1364 break;
1365 case SUBU:
1366 Format(instr, "subu 'rd, 'rs, 'rt");
1367 break;
1368 case DSUBU:
1369 Format(instr, "dsubu 'rd, 'rs, 'rt");
1370 break;
1371 case AND:
1372 Format(instr, "and 'rd, 'rs, 'rt");
1373 break;
1374 case OR:
1375 if (0 == instr->RsValue()) {
1376 Format(instr, "mov 'rd, 'rt");
1377 } else if (0 == instr->RtValue()) {
1378 Format(instr, "mov 'rd, 'rs");
1379 } else {
1380 Format(instr, "or 'rd, 'rs, 'rt");
1381 }
1382 break;
1383 case XOR:
1384 Format(instr, "xor 'rd, 'rs, 'rt");
1385 break;
1386 case NOR:
1387 Format(instr, "nor 'rd, 'rs, 'rt");
1388 break;
1389 case SLT:
1390 Format(instr, "slt 'rd, 'rs, 'rt");
1391 break;
1392 case SLTU:
1393 Format(instr, "sltu 'rd, 'rs, 'rt");
1394 break;
1395 case TGE:
1396 Format(instr, "tge 'rs, 'rt, code: 'code");
1397 break;
1398 case TGEU:
1399 Format(instr, "tgeu 'rs, 'rt, code: 'code");
1400 break;
1401 case TLT:
1402 Format(instr, "tlt 'rs, 'rt, code: 'code");
1403 break;
1404 case TLTU:
1405 Format(instr, "tltu 'rs, 'rt, code: 'code");
1406 break;
1407 case TEQ:
1408 Format(instr, "teq 'rs, 'rt, code: 'code");
1409 break;
1410 case TNE:
1411 Format(instr, "tne 'rs, 'rt, code: 'code");
1412 break;
1413 case SYNC:
1414 Format(instr, "sync");
1415 break;
1416 case MOVZ:
1417 Format(instr, "movz 'rd, 'rs, 'rt");
1418 break;
1419 case MOVN:
1420 Format(instr, "movn 'rd, 'rs, 'rt");
1421 break;
1422 case MOVCI:
1423 if (instr->Bit(16)) {
1424 Format(instr, "movt 'rd, 'rs, 'bc");
1425 } else {
1426 Format(instr, "movf 'rd, 'rs, 'bc");
1427 }
1428 break;
1429 case SELEQZ_S:
1430 Format(instr, "seleqz 'rd, 'rs, 'rt");
1431 break;
1432 case SELNEZ_S:
1433 Format(instr, "selnez 'rd, 'rs, 'rt");
1434 break;
1435 default:
1436 UNREACHABLE();
1437 }
1438 }
1439
1440
DecodeTypeRegisterSPECIAL2(Instruction * instr)1441 void Decoder::DecodeTypeRegisterSPECIAL2(Instruction* instr) {
1442 switch (instr->FunctionFieldRaw()) {
1443 case MUL:
1444 Format(instr, "mul 'rd, 'rs, 'rt");
1445 break;
1446 case CLZ:
1447 if (kArchVariant != kMips64r6) {
1448 Format(instr, "clz 'rd, 'rs");
1449 }
1450 break;
1451 case DCLZ:
1452 if (kArchVariant != kMips64r6) {
1453 Format(instr, "dclz 'rd, 'rs");
1454 }
1455 break;
1456 default:
1457 UNREACHABLE();
1458 }
1459 }
1460
1461
DecodeTypeRegisterSPECIAL3(Instruction * instr)1462 void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) {
1463 switch (instr->FunctionFieldRaw()) {
1464 case INS: {
1465 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2");
1466 break;
1467 }
1468 case EXT: {
1469 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1");
1470 break;
1471 }
1472 case DEXT: {
1473 Format(instr, "dext 'rt, 'rs, 'sa, 'ss1");
1474 break;
1475 }
1476 case BSHFL: {
1477 int sa = instr->SaFieldRaw() >> kSaShift;
1478 switch (sa) {
1479 case BITSWAP: {
1480 Format(instr, "bitswap 'rd, 'rt");
1481 break;
1482 }
1483 case SEB: {
1484 Format(instr, "seb 'rd, 'rt");
1485 break;
1486 }
1487 case SEH: {
1488 Format(instr, "seh 'rd, 'rt");
1489 break;
1490 }
1491 case WSBH: {
1492 Format(instr, "wsbh 'rd, 'rt");
1493 break;
1494 }
1495 default: {
1496 sa >>= kBp2Bits;
1497 switch (sa) {
1498 case ALIGN: {
1499 Format(instr, "align 'rd, 'rs, 'rt, 'bp2");
1500 break;
1501 }
1502 default:
1503 UNREACHABLE();
1504 break;
1505 }
1506 break;
1507 }
1508 }
1509 break;
1510 }
1511 case DINS: {
1512 Format(instr, "dins 'rt, 'rs, 'sa, 'ss2");
1513 break;
1514 }
1515 case DBSHFL: {
1516 int sa = instr->SaFieldRaw() >> kSaShift;
1517 switch (sa) {
1518 case DBITSWAP: {
1519 switch (instr->SaFieldRaw() >> kSaShift) {
1520 case DBITSWAP_SA:
1521 Format(instr, "dbitswap 'rd, 'rt");
1522 break;
1523 default:
1524 UNREACHABLE();
1525 break;
1526 }
1527 break;
1528 }
1529 case DSBH: {
1530 Format(instr, "dsbh 'rd, 'rt");
1531 break;
1532 }
1533 case DSHD: {
1534 Format(instr, "dshd 'rd, 'rt");
1535 break;
1536 }
1537 default: {
1538 sa >>= kBp3Bits;
1539 switch (sa) {
1540 case DALIGN: {
1541 Format(instr, "dalign 'rd, 'rs, 'rt, 'bp3");
1542 break;
1543 }
1544 default:
1545 UNREACHABLE();
1546 break;
1547 }
1548 break;
1549 }
1550 }
1551 break;
1552 }
1553 default:
1554 UNREACHABLE();
1555 }
1556 }
1557
1558
DecodeTypeRegister(Instruction * instr)1559 int Decoder::DecodeTypeRegister(Instruction* instr) {
1560 switch (instr->OpcodeFieldRaw()) {
1561 case COP1: // Coprocessor instructions.
1562 DecodeTypeRegisterCOP1(instr);
1563 break;
1564 case COP1X:
1565 DecodeTypeRegisterCOP1X(instr);
1566 break;
1567 case SPECIAL:
1568 switch (instr->FunctionFieldRaw()) {
1569 case BREAK:
1570 return DecodeBreakInstr(instr);
1571 default:
1572 DecodeTypeRegisterSPECIAL(instr);
1573 break;
1574 }
1575 break;
1576 case SPECIAL2:
1577 DecodeTypeRegisterSPECIAL2(instr);
1578 break;
1579 case SPECIAL3:
1580 DecodeTypeRegisterSPECIAL3(instr);
1581 break;
1582 default:
1583 UNREACHABLE();
1584 }
1585 return Instruction::kInstrSize;
1586 }
1587
1588
DecodeTypeImmediateCOP1(Instruction * instr)1589 void Decoder::DecodeTypeImmediateCOP1(Instruction* instr) {
1590 switch (instr->RsFieldRaw()) {
1591 case BC1:
1592 if (instr->FBtrueValue()) {
1593 Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2");
1594 } else {
1595 Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2");
1596 }
1597 break;
1598 case BC1EQZ:
1599 Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2");
1600 break;
1601 case BC1NEZ:
1602 Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2");
1603 break;
1604 default:
1605 UNREACHABLE();
1606 }
1607 }
1608
1609
DecodeTypeImmediateREGIMM(Instruction * instr)1610 void Decoder::DecodeTypeImmediateREGIMM(Instruction* instr) {
1611 switch (instr->RtFieldRaw()) {
1612 case BLTZ:
1613 Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2");
1614 break;
1615 case BLTZAL:
1616 Format(instr, "bltzal 'rs, 'imm16u -> 'imm16p4s2");
1617 break;
1618 case BGEZ:
1619 Format(instr, "bgez 'rs, 'imm16u -> 'imm16p4s2");
1620 break;
1621 case BGEZAL: {
1622 if (instr->RsValue() == 0)
1623 Format(instr, "bal 'imm16s -> 'imm16p4s2");
1624 else
1625 Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2");
1626 break;
1627 }
1628 case BGEZALL:
1629 Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2");
1630 break;
1631 case DAHI:
1632 Format(instr, "dahi 'rs, 'imm16x");
1633 break;
1634 case DATI:
1635 Format(instr, "dati 'rs, 'imm16x");
1636 break;
1637 default:
1638 UNREACHABLE();
1639 }
1640 }
1641
1642
DecodeTypeImmediate(Instruction * instr)1643 void Decoder::DecodeTypeImmediate(Instruction* instr) {
1644 switch (instr->OpcodeFieldRaw()) {
1645 case COP1:
1646 DecodeTypeImmediateCOP1(instr);
1647 break; // Case COP1.
1648 // ------------- REGIMM class.
1649 case REGIMM:
1650 DecodeTypeImmediateREGIMM(instr);
1651 break; // Case REGIMM.
1652 // ------------- Branch instructions.
1653 case BEQ:
1654 Format(instr, "beq 'rs, 'rt, 'imm16u -> 'imm16p4s2");
1655 break;
1656 case BC:
1657 Format(instr, "bc 'imm26s -> 'imm26p4s2");
1658 break;
1659 case BALC:
1660 Format(instr, "balc 'imm26s -> 'imm26p4s2");
1661 break;
1662 case BNE:
1663 Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2");
1664 break;
1665 case BLEZ:
1666 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) {
1667 Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2");
1668 } else if ((instr->RtValue() != instr->RsValue()) &&
1669 (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
1670 Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2");
1671 } else if ((instr->RtValue() == instr->RsValue()) &&
1672 (instr->RtValue() != 0)) {
1673 Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2");
1674 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
1675 Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2");
1676 } else {
1677 UNREACHABLE();
1678 }
1679 break;
1680 case BGTZ:
1681 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) {
1682 Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2");
1683 } else if ((instr->RtValue() != instr->RsValue()) &&
1684 (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
1685 Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2");
1686 } else if ((instr->RtValue() == instr->RsValue()) &&
1687 (instr->RtValue() != 0)) {
1688 Format(instr, "bltzalc 'rt, 'imm16u -> 'imm16p4s2");
1689 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
1690 Format(instr, "bgtzalc 'rt, 'imm16u -> 'imm16p4s2");
1691 } else {
1692 UNREACHABLE();
1693 }
1694 break;
1695 case BLEZL:
1696 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) {
1697 Format(instr, "bgezc 'rt, 'imm16u -> 'imm16p4s2");
1698 } else if ((instr->RtValue() != instr->RsValue()) &&
1699 (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
1700 Format(instr, "bgec 'rs, 'rt, 'imm16u -> 'imm16p4s2");
1701 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
1702 Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2");
1703 } else {
1704 UNREACHABLE();
1705 }
1706 break;
1707 case BGTZL:
1708 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) {
1709 Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2");
1710 } else if ((instr->RtValue() != instr->RsValue()) &&
1711 (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
1712 Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2");
1713 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
1714 Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2");
1715 } else {
1716 UNREACHABLE();
1717 }
1718 break;
1719 case POP66:
1720 if (instr->RsValue() == JIC) {
1721 Format(instr, "jic 'rt, 'imm16s");
1722 } else {
1723 Format(instr, "beqzc 'rs, 'imm21s -> 'imm21p4s2");
1724 }
1725 break;
1726 case POP76:
1727 if (instr->RsValue() == JIALC) {
1728 Format(instr, "jialc 'rt, 'imm16s");
1729 } else {
1730 Format(instr, "bnezc 'rs, 'imm21s -> 'imm21p4s2");
1731 }
1732 break;
1733 // ------------- Arithmetic instructions.
1734 case ADDI:
1735 if (kArchVariant != kMips64r6) {
1736 Format(instr, "addi 'rt, 'rs, 'imm16s");
1737 } else {
1738 int rs_reg = instr->RsValue();
1739 int rt_reg = instr->RtValue();
1740 // Check if BOVC, BEQZALC or BEQC instruction.
1741 if (rs_reg >= rt_reg) {
1742 Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2");
1743 } else {
1744 DCHECK(rt_reg > 0);
1745 if (rs_reg == 0) {
1746 Format(instr, "beqzalc 'rt, 'imm16s -> 'imm16p4s2");
1747 } else {
1748 Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2");
1749 }
1750 }
1751 }
1752 break;
1753 case DADDI:
1754 if (kArchVariant != kMips64r6) {
1755 Format(instr, "daddi 'rt, 'rs, 'imm16s");
1756 } else {
1757 int rs_reg = instr->RsValue();
1758 int rt_reg = instr->RtValue();
1759 // Check if BNVC, BNEZALC or BNEC instruction.
1760 if (rs_reg >= rt_reg) {
1761 Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2");
1762 } else {
1763 DCHECK(rt_reg > 0);
1764 if (rs_reg == 0) {
1765 Format(instr, "bnezalc 'rt, 'imm16s -> 'imm16p4s2");
1766 } else {
1767 Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2");
1768 }
1769 }
1770 }
1771 break;
1772 case ADDIU:
1773 Format(instr, "addiu 'rt, 'rs, 'imm16s");
1774 break;
1775 case DADDIU:
1776 Format(instr, "daddiu 'rt, 'rs, 'imm16s");
1777 break;
1778 case SLTI:
1779 Format(instr, "slti 'rt, 'rs, 'imm16s");
1780 break;
1781 case SLTIU:
1782 Format(instr, "sltiu 'rt, 'rs, 'imm16u");
1783 break;
1784 case ANDI:
1785 Format(instr, "andi 'rt, 'rs, 'imm16x");
1786 break;
1787 case ORI:
1788 Format(instr, "ori 'rt, 'rs, 'imm16x");
1789 break;
1790 case XORI:
1791 Format(instr, "xori 'rt, 'rs, 'imm16x");
1792 break;
1793 case LUI:
1794 if (kArchVariant != kMips64r6) {
1795 Format(instr, "lui 'rt, 'imm16x");
1796 } else {
1797 if (instr->RsValue() != 0) {
1798 Format(instr, "aui 'rt, 'rs, 'imm16x");
1799 } else {
1800 Format(instr, "lui 'rt, 'imm16x");
1801 }
1802 }
1803 break;
1804 case DAUI:
1805 Format(instr, "daui 'rt, 'rs, 'imm16x");
1806 break;
1807 // ------------- Memory instructions.
1808 case LB:
1809 Format(instr, "lb 'rt, 'imm16s('rs)");
1810 break;
1811 case LH:
1812 Format(instr, "lh 'rt, 'imm16s('rs)");
1813 break;
1814 case LWL:
1815 Format(instr, "lwl 'rt, 'imm16s('rs)");
1816 break;
1817 case LDL:
1818 Format(instr, "ldl 'rt, 'imm16s('rs)");
1819 break;
1820 case LW:
1821 Format(instr, "lw 'rt, 'imm16s('rs)");
1822 break;
1823 case LWU:
1824 Format(instr, "lwu 'rt, 'imm16s('rs)");
1825 break;
1826 case LD:
1827 Format(instr, "ld 'rt, 'imm16s('rs)");
1828 break;
1829 case LBU:
1830 Format(instr, "lbu 'rt, 'imm16s('rs)");
1831 break;
1832 case LHU:
1833 Format(instr, "lhu 'rt, 'imm16s('rs)");
1834 break;
1835 case LWR:
1836 Format(instr, "lwr 'rt, 'imm16s('rs)");
1837 break;
1838 case LDR:
1839 Format(instr, "ldr 'rt, 'imm16s('rs)");
1840 break;
1841 case PREF:
1842 Format(instr, "pref 'rt, 'imm16s('rs)");
1843 break;
1844 case SB:
1845 Format(instr, "sb 'rt, 'imm16s('rs)");
1846 break;
1847 case SH:
1848 Format(instr, "sh 'rt, 'imm16s('rs)");
1849 break;
1850 case SWL:
1851 Format(instr, "swl 'rt, 'imm16s('rs)");
1852 break;
1853 case SW:
1854 Format(instr, "sw 'rt, 'imm16s('rs)");
1855 break;
1856 case SD:
1857 Format(instr, "sd 'rt, 'imm16s('rs)");
1858 break;
1859 case SWR:
1860 Format(instr, "swr 'rt, 'imm16s('rs)");
1861 break;
1862 case LWC1:
1863 Format(instr, "lwc1 'ft, 'imm16s('rs)");
1864 break;
1865 case LDC1:
1866 Format(instr, "ldc1 'ft, 'imm16s('rs)");
1867 break;
1868 case SWC1:
1869 Format(instr, "swc1 'ft, 'imm16s('rs)");
1870 break;
1871 case SDC1:
1872 Format(instr, "sdc1 'ft, 'imm16s('rs)");
1873 break;
1874 case PCREL: {
1875 int32_t imm21 = instr->Imm21Value();
1876 // rt field: 5-bits checking
1877 uint8_t rt = (imm21 >> kImm16Bits);
1878 switch (rt) {
1879 case ALUIPC:
1880 Format(instr, "aluipc 'rs, 'imm16s");
1881 break;
1882 case AUIPC:
1883 Format(instr, "auipc 'rs, 'imm16s");
1884 break;
1885 default: {
1886 // rt field: checking of the most significant 3-bits
1887 rt = (imm21 >> kImm18Bits);
1888 switch (rt) {
1889 case LDPC:
1890 Format(instr, "ldpc 'rs, 'imm18s");
1891 break;
1892 default: {
1893 // rt field: checking of the most significant 2-bits
1894 rt = (imm21 >> kImm19Bits);
1895 switch (rt) {
1896 case LWUPC:
1897 Format(instr, "lwupc 'rs, 'imm19s");
1898 break;
1899 case LWPC:
1900 Format(instr, "lwpc 'rs, 'imm19s");
1901 break;
1902 case ADDIUPC:
1903 Format(instr, "addiupc 'rs, 'imm19s");
1904 break;
1905 default:
1906 UNREACHABLE();
1907 break;
1908 }
1909 break;
1910 }
1911 }
1912 break;
1913 }
1914 }
1915 break;
1916 }
1917 default:
1918 printf("a 0x%x \n", instr->OpcodeFieldRaw());
1919 UNREACHABLE();
1920 break;
1921 }
1922 }
1923
1924
DecodeTypeJump(Instruction * instr)1925 void Decoder::DecodeTypeJump(Instruction* instr) {
1926 switch (instr->OpcodeFieldRaw()) {
1927 case J:
1928 Format(instr, "j 'imm26x -> 'imm26j");
1929 break;
1930 case JAL:
1931 Format(instr, "jal 'imm26x -> 'imm26j");
1932 break;
1933 default:
1934 UNREACHABLE();
1935 }
1936 }
1937
1938
1939 // Disassemble the instruction at *instr_ptr into the output buffer.
1940 // All instructions are one word long, except for the simulator
1941 // psuedo-instruction stop(msg). For that one special case, we return
1942 // size larger than one kInstrSize.
InstructionDecode(byte * instr_ptr)1943 int Decoder::InstructionDecode(byte* instr_ptr) {
1944 Instruction* instr = Instruction::At(instr_ptr);
1945 // Print raw instruction bytes.
1946 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1947 "%08x ",
1948 instr->InstructionBits());
1949 switch (instr->InstructionType()) {
1950 case Instruction::kRegisterType: {
1951 return DecodeTypeRegister(instr);
1952 }
1953 case Instruction::kImmediateType: {
1954 DecodeTypeImmediate(instr);
1955 break;
1956 }
1957 case Instruction::kJumpType: {
1958 DecodeTypeJump(instr);
1959 break;
1960 }
1961 default: {
1962 Format(instr, "UNSUPPORTED");
1963 UNSUPPORTED_MIPS();
1964 }
1965 }
1966 return Instruction::kInstrSize;
1967 }
1968
1969
1970 } // namespace internal
1971 } // namespace v8
1972
1973
1974 //------------------------------------------------------------------------------
1975
1976 namespace disasm {
1977
NameOfAddress(byte * addr) const1978 const char* NameConverter::NameOfAddress(byte* addr) const {
1979 v8::internal::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
1980 return tmp_buffer_.start();
1981 }
1982
1983
NameOfConstant(byte * addr) const1984 const char* NameConverter::NameOfConstant(byte* addr) const {
1985 return NameOfAddress(addr);
1986 }
1987
1988
NameOfCPURegister(int reg) const1989 const char* NameConverter::NameOfCPURegister(int reg) const {
1990 return v8::internal::Registers::Name(reg);
1991 }
1992
1993
NameOfXMMRegister(int reg) const1994 const char* NameConverter::NameOfXMMRegister(int reg) const {
1995 return v8::internal::FPURegisters::Name(reg);
1996 }
1997
1998
NameOfByteCPURegister(int reg) const1999 const char* NameConverter::NameOfByteCPURegister(int reg) const {
2000 UNREACHABLE(); // MIPS does not have the concept of a byte register.
2001 return "nobytereg";
2002 }
2003
2004
NameInCode(byte * addr) const2005 const char* NameConverter::NameInCode(byte* addr) const {
2006 // The default name converter is called for unknown code. So we will not try
2007 // to access any memory.
2008 return "";
2009 }
2010
2011
2012 //------------------------------------------------------------------------------
2013
Disassembler(const NameConverter & converter)2014 Disassembler::Disassembler(const NameConverter& converter)
2015 : converter_(converter) {}
2016
2017
~Disassembler()2018 Disassembler::~Disassembler() {}
2019
2020
InstructionDecode(v8::internal::Vector<char> buffer,byte * instruction)2021 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
2022 byte* instruction) {
2023 v8::internal::Decoder d(converter_, buffer);
2024 return d.InstructionDecode(instruction);
2025 }
2026
2027
2028 // The MIPS assembler does not currently use constant pools.
ConstantPoolSizeAt(byte * instruction)2029 int Disassembler::ConstantPoolSizeAt(byte* instruction) {
2030 return -1;
2031 }
2032
2033
Disassemble(FILE * f,byte * begin,byte * end)2034 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
2035 NameConverter converter;
2036 Disassembler d(converter);
2037 for (byte* pc = begin; pc < end;) {
2038 v8::internal::EmbeddedVector<char, 128> buffer;
2039 buffer[0] = '\0';
2040 byte* prev_pc = pc;
2041 pc += d.InstructionDecode(buffer, pc);
2042 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc),
2043 *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
2044 }
2045 }
2046
2047
2048 #undef UNSUPPORTED
2049
2050 } // namespace disasm
2051
2052 #endif // V8_TARGET_ARCH_MIPS64
2053