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