1// Copyright 2012 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// A Disassembler object is used to disassemble a block of code instruction by
29// instruction. The default implementation of the NameConverter object can be
30// overriden to modify register names or to do symbol lookup on addresses.
31//
32// The example below will disassemble a block of code and print it to stdout.
33//
34//   NameConverter converter;
35//   Disassembler d(converter);
36//   for (byte* pc = begin; pc < end;) {
37//     v8::internal::EmbeddedVector<char, 256> buffer;
38//     byte* prev_pc = pc;
39//     pc += d.InstructionDecode(buffer, pc);
40//     printf("%p    %08x      %s\n",
41//            prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
42//   }
43//
44// The Disassembler class also has a convenience method to disassemble a block
45// of code into a FILE*, meaning that the above functionality could also be
46// achieved by just calling Disassembler::Disassemble(stdout, begin, end);
47
48
49#include <assert.h>
50#include <stdio.h>
51#include <stdarg.h>
52#include <string.h>
53#ifndef WIN32
54#include <stdint.h>
55#endif
56
57#include "v8.h"
58
59#if defined(V8_TARGET_ARCH_MIPS)
60
61#include "mips/constants-mips.h"
62#include "disasm.h"
63#include "macro-assembler.h"
64#include "platform.h"
65
66namespace v8 {
67namespace internal {
68
69//------------------------------------------------------------------------------
70
71// Decoder decodes and disassembles instructions into an output buffer.
72// It uses the converter to convert register names and call destinations into
73// more informative description.
74class Decoder {
75 public:
76  Decoder(const disasm::NameConverter& converter,
77          v8::internal::Vector<char> out_buffer)
78    : converter_(converter),
79      out_buffer_(out_buffer),
80      out_buffer_pos_(0) {
81    out_buffer_[out_buffer_pos_] = '\0';
82  }
83
84  ~Decoder() {}
85
86  // Writes one disassembled instruction into 'buffer' (0-terminated).
87  // Returns the length of the disassembled machine instruction in bytes.
88  int InstructionDecode(byte* instruction);
89
90 private:
91  // Bottleneck functions to print into the out_buffer.
92  void PrintChar(const char ch);
93  void Print(const char* str);
94
95  // Printing of common values.
96  void PrintRegister(int reg);
97  void PrintFPURegister(int freg);
98  void PrintRs(Instruction* instr);
99  void PrintRt(Instruction* instr);
100  void PrintRd(Instruction* instr);
101  void PrintFs(Instruction* instr);
102  void PrintFt(Instruction* instr);
103  void PrintFd(Instruction* instr);
104  void PrintSa(Instruction* instr);
105  void PrintSd(Instruction* instr);
106  void PrintSs1(Instruction* instr);
107  void PrintSs2(Instruction* instr);
108  void PrintBc(Instruction* instr);
109  void PrintCc(Instruction* instr);
110  void PrintFunction(Instruction* instr);
111  void PrintSecondaryField(Instruction* instr);
112  void PrintUImm16(Instruction* instr);
113  void PrintSImm16(Instruction* instr);
114  void PrintXImm16(Instruction* instr);
115  void PrintXImm26(Instruction* instr);
116  void PrintCode(Instruction* instr);   // For break and trap instructions.
117  // Printing of instruction name.
118  void PrintInstructionName(Instruction* instr);
119
120  // Handle formatting of instructions and their options.
121  int FormatRegister(Instruction* instr, const char* option);
122  int FormatFPURegister(Instruction* instr, const char* option);
123  int FormatOption(Instruction* instr, const char* option);
124  void Format(Instruction* instr, const char* format);
125  void Unknown(Instruction* instr);
126
127  // Each of these functions decodes one particular instruction type.
128  void DecodeTypeRegister(Instruction* instr);
129  void DecodeTypeImmediate(Instruction* instr);
130  void DecodeTypeJump(Instruction* instr);
131
132  const disasm::NameConverter& converter_;
133  v8::internal::Vector<char> out_buffer_;
134  int out_buffer_pos_;
135
136  DISALLOW_COPY_AND_ASSIGN(Decoder);
137};
138
139
140// Support for assertions in the Decoder formatting functions.
141#define STRING_STARTS_WITH(string, compare_string) \
142  (strncmp(string, compare_string, strlen(compare_string)) == 0)
143
144
145// Append the ch to the output buffer.
146void Decoder::PrintChar(const char ch) {
147  out_buffer_[out_buffer_pos_++] = ch;
148}
149
150
151// Append the str to the output buffer.
152void Decoder::Print(const char* str) {
153  char cur = *str++;
154  while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
155    PrintChar(cur);
156    cur = *str++;
157  }
158  out_buffer_[out_buffer_pos_] = 0;
159}
160
161
162// Print the register name according to the active name converter.
163void Decoder::PrintRegister(int reg) {
164  Print(converter_.NameOfCPURegister(reg));
165}
166
167
168void Decoder::PrintRs(Instruction* instr) {
169  int reg = instr->RsValue();
170  PrintRegister(reg);
171}
172
173
174void Decoder::PrintRt(Instruction* instr) {
175  int reg = instr->RtValue();
176  PrintRegister(reg);
177}
178
179
180void Decoder::PrintRd(Instruction* instr) {
181  int reg = instr->RdValue();
182  PrintRegister(reg);
183}
184
185
186// Print the FPUregister name according to the active name converter.
187void Decoder::PrintFPURegister(int freg) {
188  Print(converter_.NameOfXMMRegister(freg));
189}
190
191
192void Decoder::PrintFs(Instruction* instr) {
193  int freg = instr->RsValue();
194  PrintFPURegister(freg);
195}
196
197
198void Decoder::PrintFt(Instruction* instr) {
199  int freg = instr->RtValue();
200  PrintFPURegister(freg);
201}
202
203
204void Decoder::PrintFd(Instruction* instr) {
205  int freg = instr->RdValue();
206  PrintFPURegister(freg);
207}
208
209
210// Print the integer value of the sa field.
211void Decoder::PrintSa(Instruction* instr) {
212  int sa = instr->SaValue();
213  out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa);
214}
215
216
217// Print the integer value of the rd field, when it is not used as reg.
218void Decoder::PrintSd(Instruction* instr) {
219  int sd = instr->RdValue();
220  out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sd);
221}
222
223
224// Print the integer value of the rd field, when used as 'ext' size.
225void Decoder::PrintSs1(Instruction* instr) {
226  int ss = instr->RdValue();
227  out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss + 1);
228}
229
230
231// Print the integer value of the rd field, when used as 'ins' size.
232void Decoder::PrintSs2(Instruction* instr) {
233  int ss = instr->RdValue();
234  int pos = instr->SaValue();
235  out_buffer_pos_ +=
236      OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss - pos + 1);
237}
238
239
240// Print the integer value of the cc field for the bc1t/f instructions.
241void Decoder::PrintBc(Instruction* instr) {
242  int cc = instr->FBccValue();
243  out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", cc);
244}
245
246
247// Print the integer value of the cc field for the FP compare instructions.
248void Decoder::PrintCc(Instruction* instr) {
249  int cc = instr->FCccValue();
250  out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "cc(%d)", cc);
251}
252
253
254// Print 16-bit unsigned immediate value.
255void Decoder::PrintUImm16(Instruction* instr) {
256  int32_t imm = instr->Imm16Value();
257  out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm);
258}
259
260
261// Print 16-bit signed immediate value.
262void Decoder::PrintSImm16(Instruction* instr) {
263  int32_t imm = ((instr->Imm16Value()) << 16) >> 16;
264  out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
265}
266
267
268// Print 16-bit hexa immediate value.
269void Decoder::PrintXImm16(Instruction* instr) {
270  int32_t imm = instr->Imm16Value();
271  out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
272}
273
274
275// Print 26-bit immediate value.
276void Decoder::PrintXImm26(Instruction* instr) {
277  uint32_t imm = instr->Imm26Value() << kImmFieldShift;
278  out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
279}
280
281
282// Print 26-bit immediate value.
283void Decoder::PrintCode(Instruction* instr) {
284  if (instr->OpcodeFieldRaw() != SPECIAL)
285    return;  // Not a break or trap instruction.
286  switch (instr->FunctionFieldRaw()) {
287    case BREAK: {
288      int32_t code = instr->Bits(25, 6);
289      out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
290                                      "0x%05x (%d)", code, code);
291      break;
292                }
293    case TGE:
294    case TGEU:
295    case TLT:
296    case TLTU:
297    case TEQ:
298    case TNE: {
299      int32_t code = instr->Bits(15, 6);
300      out_buffer_pos_ +=
301          OS::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code);
302      break;
303    }
304    default:  // Not a break or trap instruction.
305    break;
306  };
307}
308
309
310// Printing of instruction name.
311void Decoder::PrintInstructionName(Instruction* instr) {
312}
313
314
315// Handle all register based formatting in this function to reduce the
316// complexity of FormatOption.
317int Decoder::FormatRegister(Instruction* instr, const char* format) {
318  ASSERT(format[0] == 'r');
319  if (format[1] == 's') {  // 'rs: Rs register.
320    int reg = instr->RsValue();
321    PrintRegister(reg);
322    return 2;
323  } else if (format[1] == 't') {  // 'rt: rt register.
324    int reg = instr->RtValue();
325    PrintRegister(reg);
326    return 2;
327  } else if (format[1] == 'd') {  // 'rd: rd register.
328    int reg = instr->RdValue();
329    PrintRegister(reg);
330    return 2;
331  }
332  UNREACHABLE();
333  return -1;
334}
335
336
337// Handle all FPUregister based formatting in this function to reduce the
338// complexity of FormatOption.
339int Decoder::FormatFPURegister(Instruction* instr, const char* format) {
340  ASSERT(format[0] == 'f');
341  if (format[1] == 's') {  // 'fs: fs register.
342    int reg = instr->FsValue();
343    PrintFPURegister(reg);
344    return 2;
345  } else if (format[1] == 't') {  // 'ft: ft register.
346    int reg = instr->FtValue();
347    PrintFPURegister(reg);
348    return 2;
349  } else if (format[1] == 'd') {  // 'fd: fd register.
350    int reg = instr->FdValue();
351    PrintFPURegister(reg);
352    return 2;
353  }
354  UNREACHABLE();
355  return -1;
356}
357
358
359// FormatOption takes a formatting string and interprets it based on
360// the current instructions. The format string points to the first
361// character of the option string (the option escape has already been
362// consumed by the caller.)  FormatOption returns the number of
363// characters that were consumed from the formatting string.
364int Decoder::FormatOption(Instruction* instr, const char* format) {
365  switch (format[0]) {
366    case 'c': {   // 'code for break or trap instructions.
367      ASSERT(STRING_STARTS_WITH(format, "code"));
368      PrintCode(instr);
369      return 4;
370    }
371    case 'i': {   // 'imm16u or 'imm26.
372      if (format[3] == '1') {
373        ASSERT(STRING_STARTS_WITH(format, "imm16"));
374        if (format[5] == 's') {
375          ASSERT(STRING_STARTS_WITH(format, "imm16s"));
376          PrintSImm16(instr);
377        } else if (format[5] == 'u') {
378          ASSERT(STRING_STARTS_WITH(format, "imm16u"));
379          PrintSImm16(instr);
380        } else {
381          ASSERT(STRING_STARTS_WITH(format, "imm16x"));
382          PrintXImm16(instr);
383        }
384        return 6;
385      } else {
386        ASSERT(STRING_STARTS_WITH(format, "imm26x"));
387        PrintXImm26(instr);
388        return 6;
389      }
390    }
391    case 'r': {   // 'r: registers.
392      return FormatRegister(instr, format);
393    }
394    case 'f': {   // 'f: FPUregisters.
395      return FormatFPURegister(instr, format);
396    }
397    case 's': {   // 'sa.
398      switch (format[1]) {
399        case 'a': {
400          ASSERT(STRING_STARTS_WITH(format, "sa"));
401          PrintSa(instr);
402          return 2;
403        }
404        case 'd': {
405          ASSERT(STRING_STARTS_WITH(format, "sd"));
406          PrintSd(instr);
407          return 2;
408        }
409        case 's': {
410          if (format[2] == '1') {
411              ASSERT(STRING_STARTS_WITH(format, "ss1"));  /* ext size */
412              PrintSs1(instr);
413              return 3;
414          } else {
415              ASSERT(STRING_STARTS_WITH(format, "ss2"));  /* ins size */
416              PrintSs2(instr);
417              return 3;
418          }
419        }
420      }
421    }
422    case 'b': {   // 'bc - Special for bc1 cc field.
423      ASSERT(STRING_STARTS_WITH(format, "bc"));
424      PrintBc(instr);
425      return 2;
426    }
427    case 'C': {   // 'Cc - Special for c.xx.d cc field.
428      ASSERT(STRING_STARTS_WITH(format, "Cc"));
429      PrintCc(instr);
430      return 2;
431    }
432  };
433  UNREACHABLE();
434  return -1;
435}
436
437
438// Format takes a formatting string for a whole instruction and prints it into
439// the output buffer. All escaped options are handed to FormatOption to be
440// parsed further.
441void Decoder::Format(Instruction* instr, const char* format) {
442  char cur = *format++;
443  while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
444    if (cur == '\'') {  // Single quote is used as the formatting escape.
445      format += FormatOption(instr, format);
446    } else {
447      out_buffer_[out_buffer_pos_++] = cur;
448    }
449    cur = *format++;
450  }
451  out_buffer_[out_buffer_pos_]  = '\0';
452}
453
454
455// For currently unimplemented decodings the disassembler calls Unknown(instr)
456// which will just print "unknown" of the instruction bits.
457void Decoder::Unknown(Instruction* instr) {
458  Format(instr, "unknown");
459}
460
461
462void Decoder::DecodeTypeRegister(Instruction* instr) {
463  switch (instr->OpcodeFieldRaw()) {
464    case COP1:    // Coprocessor instructions.
465      switch (instr->RsFieldRaw()) {
466        case BC1:   // bc1 handled in DecodeTypeImmediate.
467          UNREACHABLE();
468          break;
469        case MFC1:
470          Format(instr, "mfc1    'rt, 'fs");
471          break;
472        case MFHC1:
473          Format(instr, "mfhc1   'rt, 'fs");
474          break;
475        case MTC1:
476          Format(instr, "mtc1    'rt, 'fs");
477          break;
478        // These are called "fs" too, although they are not FPU registers.
479        case CTC1:
480          Format(instr, "ctc1    'rt, 'fs");
481          break;
482        case CFC1:
483          Format(instr, "cfc1    'rt, 'fs");
484          break;
485        case MTHC1:
486          Format(instr, "mthc1   'rt, 'fs");
487          break;
488        case D:
489          switch (instr->FunctionFieldRaw()) {
490            case ADD_D:
491              Format(instr, "add.d   'fd, 'fs, 'ft");
492              break;
493            case SUB_D:
494              Format(instr, "sub.d   'fd, 'fs, 'ft");
495              break;
496            case MUL_D:
497              Format(instr, "mul.d   'fd, 'fs, 'ft");
498              break;
499            case DIV_D:
500              Format(instr, "div.d   'fd, 'fs, 'ft");
501              break;
502            case ABS_D:
503              Format(instr, "abs.d   'fd, 'fs");
504              break;
505            case MOV_D:
506              Format(instr, "mov.d   'fd, 'fs");
507              break;
508            case NEG_D:
509              Format(instr, "neg.d   'fd, 'fs");
510              break;
511            case SQRT_D:
512              Format(instr, "sqrt.d  'fd, 'fs");
513              break;
514            case CVT_W_D:
515              Format(instr, "cvt.w.d 'fd, 'fs");
516              break;
517            case CVT_L_D: {
518              if (kArchVariant == kMips32r2) {
519                Format(instr, "cvt.l.d 'fd, 'fs");
520              } else {
521                Unknown(instr);
522              }
523              break;
524            }
525            case TRUNC_W_D:
526              Format(instr, "trunc.w.d 'fd, 'fs");
527              break;
528            case TRUNC_L_D: {
529              if (kArchVariant == kMips32r2) {
530                Format(instr, "trunc.l.d 'fd, 'fs");
531              } else {
532                Unknown(instr);
533              }
534              break;
535            }
536            case ROUND_W_D:
537              Format(instr, "round.w.d 'fd, 'fs");
538              break;
539            case FLOOR_W_D:
540              Format(instr, "floor.w.d 'fd, 'fs");
541              break;
542            case CEIL_W_D:
543              Format(instr, "ceil.w.d 'fd, 'fs");
544              break;
545            case CVT_S_D:
546              Format(instr, "cvt.s.d 'fd, 'fs");
547              break;
548            case C_F_D:
549              Format(instr, "c.f.d   'fs, 'ft, 'Cc");
550              break;
551            case C_UN_D:
552              Format(instr, "c.un.d  'fs, 'ft, 'Cc");
553              break;
554            case C_EQ_D:
555              Format(instr, "c.eq.d  'fs, 'ft, 'Cc");
556              break;
557            case C_UEQ_D:
558              Format(instr, "c.ueq.d 'fs, 'ft, 'Cc");
559              break;
560            case C_OLT_D:
561              Format(instr, "c.olt.d 'fs, 'ft, 'Cc");
562              break;
563            case C_ULT_D:
564              Format(instr, "c.ult.d 'fs, 'ft, 'Cc");
565              break;
566            case C_OLE_D:
567              Format(instr, "c.ole.d 'fs, 'ft, 'Cc");
568              break;
569            case C_ULE_D:
570              Format(instr, "c.ule.d 'fs, 'ft, 'Cc");
571              break;
572            default:
573              Format(instr, "unknown.cop1.d");
574              break;
575          }
576          break;
577        case S:
578          UNIMPLEMENTED_MIPS();
579          break;
580        case W:
581          switch (instr->FunctionFieldRaw()) {
582            case CVT_S_W:   // Convert word to float (single).
583              Format(instr, "cvt.s.w 'fd, 'fs");
584              break;
585            case CVT_D_W:   // Convert word to double.
586              Format(instr, "cvt.d.w 'fd, 'fs");
587              break;
588            default:
589              UNREACHABLE();
590          }
591          break;
592        case L:
593          switch (instr->FunctionFieldRaw()) {
594            case CVT_D_L: {
595              if (kArchVariant == kMips32r2) {
596                Format(instr, "cvt.d.l 'fd, 'fs");
597              } else {
598                Unknown(instr);
599              }
600              break;
601            }
602            case CVT_S_L: {
603              if (kArchVariant == kMips32r2) {
604                Format(instr, "cvt.s.l 'fd, 'fs");
605              } else {
606                Unknown(instr);
607              }
608              break;
609            }
610            default:
611              UNREACHABLE();
612          }
613          break;
614        case PS:
615          UNIMPLEMENTED_MIPS();
616          break;
617        default:
618          UNREACHABLE();
619      }
620      break;
621    case SPECIAL:
622      switch (instr->FunctionFieldRaw()) {
623        case JR:
624          Format(instr, "jr      'rs");
625          break;
626        case JALR:
627          Format(instr, "jalr    'rs");
628          break;
629        case SLL:
630          if ( 0x0 == static_cast<int>(instr->InstructionBits()))
631            Format(instr, "nop");
632          else
633            Format(instr, "sll     'rd, 'rt, 'sa");
634          break;
635        case SRL:
636          if (instr->RsValue() == 0) {
637            Format(instr, "srl     'rd, 'rt, 'sa");
638          } else {
639            if (kArchVariant == kMips32r2) {
640              Format(instr, "rotr    'rd, 'rt, 'sa");
641            } else {
642              Unknown(instr);
643            }
644          }
645          break;
646        case SRA:
647          Format(instr, "sra     'rd, 'rt, 'sa");
648          break;
649        case SLLV:
650          Format(instr, "sllv    'rd, 'rt, 'rs");
651          break;
652        case SRLV:
653          if (instr->SaValue() == 0) {
654            Format(instr, "srlv    'rd, 'rt, 'rs");
655          } else {
656            if (kArchVariant == kMips32r2) {
657              Format(instr, "rotrv   'rd, 'rt, 'rs");
658            } else {
659              Unknown(instr);
660            }
661          }
662          break;
663        case SRAV:
664          Format(instr, "srav    'rd, 'rt, 'rs");
665          break;
666        case MFHI:
667          Format(instr, "mfhi    'rd");
668          break;
669        case MFLO:
670          Format(instr, "mflo    'rd");
671          break;
672        case MULT:
673          Format(instr, "mult    'rs, 'rt");
674          break;
675        case MULTU:
676          Format(instr, "multu   'rs, 'rt");
677          break;
678        case DIV:
679          Format(instr, "div     'rs, 'rt");
680          break;
681        case DIVU:
682          Format(instr, "divu    'rs, 'rt");
683          break;
684        case ADD:
685          Format(instr, "add     'rd, 'rs, 'rt");
686          break;
687        case ADDU:
688          Format(instr, "addu    'rd, 'rs, 'rt");
689          break;
690        case SUB:
691          Format(instr, "sub     'rd, 'rs, 'rt");
692          break;
693        case SUBU:
694          Format(instr, "subu    'rd, 'rs, 'rt");
695          break;
696        case AND:
697          Format(instr, "and     'rd, 'rs, 'rt");
698          break;
699        case OR:
700          if (0 == instr->RsValue()) {
701            Format(instr, "mov     'rd, 'rt");
702          } else if (0 == instr->RtValue()) {
703            Format(instr, "mov     'rd, 'rs");
704          } else {
705            Format(instr, "or      'rd, 'rs, 'rt");
706          }
707          break;
708        case XOR:
709          Format(instr, "xor     'rd, 'rs, 'rt");
710          break;
711        case NOR:
712          Format(instr, "nor     'rd, 'rs, 'rt");
713          break;
714        case SLT:
715          Format(instr, "slt     'rd, 'rs, 'rt");
716          break;
717        case SLTU:
718          Format(instr, "sltu    'rd, 'rs, 'rt");
719          break;
720        case BREAK:
721          Format(instr, "break, code: 'code");
722          break;
723        case TGE:
724          Format(instr, "tge     'rs, 'rt, code: 'code");
725          break;
726        case TGEU:
727          Format(instr, "tgeu    'rs, 'rt, code: 'code");
728          break;
729        case TLT:
730          Format(instr, "tlt     'rs, 'rt, code: 'code");
731          break;
732        case TLTU:
733          Format(instr, "tltu    'rs, 'rt, code: 'code");
734          break;
735        case TEQ:
736          Format(instr, "teq     'rs, 'rt, code: 'code");
737          break;
738        case TNE:
739          Format(instr, "tne     'rs, 'rt, code: 'code");
740          break;
741        case MOVZ:
742          Format(instr, "movz    'rd, 'rs, 'rt");
743          break;
744        case MOVN:
745          Format(instr, "movn    'rd, 'rs, 'rt");
746          break;
747        case MOVCI:
748          if (instr->Bit(16)) {
749            Format(instr, "movt    'rd, 'rs, 'bc");
750          } else {
751            Format(instr, "movf    'rd, 'rs, 'bc");
752          }
753          break;
754        default:
755          UNREACHABLE();
756      }
757      break;
758    case SPECIAL2:
759      switch (instr->FunctionFieldRaw()) {
760        case MUL:
761          Format(instr, "mul     'rd, 'rs, 'rt");
762          break;
763        case CLZ:
764          Format(instr, "clz     'rd, 'rs");
765          break;
766        default:
767          UNREACHABLE();
768      }
769      break;
770    case SPECIAL3:
771      switch (instr->FunctionFieldRaw()) {
772        case INS: {
773          if (kArchVariant == kMips32r2) {
774            Format(instr, "ins     'rt, 'rs, 'sa, 'ss2");
775          } else {
776            Unknown(instr);
777          }
778          break;
779        }
780        case EXT: {
781          if (kArchVariant == kMips32r2) {
782            Format(instr, "ext     'rt, 'rs, 'sa, 'ss1");
783          } else {
784            Unknown(instr);
785          }
786          break;
787        }
788        default:
789          UNREACHABLE();
790      }
791      break;
792    default:
793      UNREACHABLE();
794  }
795}
796
797
798void Decoder::DecodeTypeImmediate(Instruction* instr) {
799  switch (instr->OpcodeFieldRaw()) {
800    // ------------- REGIMM class.
801    case COP1:
802      switch (instr->RsFieldRaw()) {
803        case BC1:
804          if (instr->FBtrueValue()) {
805            Format(instr, "bc1t    'bc, 'imm16u");
806          } else {
807            Format(instr, "bc1f    'bc, 'imm16u");
808          }
809          break;
810        default:
811          UNREACHABLE();
812      };
813      break;  // Case COP1.
814    case REGIMM:
815      switch (instr->RtFieldRaw()) {
816        case BLTZ:
817          Format(instr, "bltz    'rs, 'imm16u");
818          break;
819        case BLTZAL:
820          Format(instr, "bltzal  'rs, 'imm16u");
821          break;
822        case BGEZ:
823          Format(instr, "bgez    'rs, 'imm16u");
824          break;
825        case BGEZAL:
826          Format(instr, "bgezal  'rs, 'imm16u");
827          break;
828        default:
829          UNREACHABLE();
830      }
831    break;  // Case REGIMM.
832    // ------------- Branch instructions.
833    case BEQ:
834      Format(instr, "beq     'rs, 'rt, 'imm16u");
835      break;
836    case BNE:
837      Format(instr, "bne     'rs, 'rt, 'imm16u");
838      break;
839    case BLEZ:
840      Format(instr, "blez    'rs, 'imm16u");
841      break;
842    case BGTZ:
843      Format(instr, "bgtz    'rs, 'imm16u");
844      break;
845    // ------------- Arithmetic instructions.
846    case ADDI:
847      Format(instr, "addi    'rt, 'rs, 'imm16s");
848      break;
849    case ADDIU:
850      Format(instr, "addiu   'rt, 'rs, 'imm16s");
851      break;
852    case SLTI:
853      Format(instr, "slti    'rt, 'rs, 'imm16s");
854      break;
855    case SLTIU:
856      Format(instr, "sltiu   'rt, 'rs, 'imm16u");
857      break;
858    case ANDI:
859      Format(instr, "andi    'rt, 'rs, 'imm16x");
860      break;
861    case ORI:
862      Format(instr, "ori     'rt, 'rs, 'imm16x");
863      break;
864    case XORI:
865      Format(instr, "xori    'rt, 'rs, 'imm16x");
866      break;
867    case LUI:
868      Format(instr, "lui     'rt, 'imm16x");
869      break;
870    // ------------- Memory instructions.
871    case LB:
872      Format(instr, "lb      'rt, 'imm16s('rs)");
873      break;
874    case LH:
875      Format(instr, "lh      'rt, 'imm16s('rs)");
876      break;
877    case LWL:
878      Format(instr, "lwl     'rt, 'imm16s('rs)");
879      break;
880    case LW:
881      Format(instr, "lw      'rt, 'imm16s('rs)");
882      break;
883    case LBU:
884      Format(instr, "lbu     'rt, 'imm16s('rs)");
885      break;
886    case LHU:
887      Format(instr, "lhu     'rt, 'imm16s('rs)");
888      break;
889    case LWR:
890      Format(instr, "lwr     'rt, 'imm16s('rs)");
891      break;
892    case SB:
893      Format(instr, "sb      'rt, 'imm16s('rs)");
894      break;
895    case SH:
896      Format(instr, "sh      'rt, 'imm16s('rs)");
897      break;
898    case SWL:
899      Format(instr, "swl     'rt, 'imm16s('rs)");
900      break;
901    case SW:
902      Format(instr, "sw      'rt, 'imm16s('rs)");
903      break;
904    case SWR:
905      Format(instr, "swr     'rt, 'imm16s('rs)");
906      break;
907    case LWC1:
908      Format(instr, "lwc1    'ft, 'imm16s('rs)");
909      break;
910    case LDC1:
911      Format(instr, "ldc1    'ft, 'imm16s('rs)");
912      break;
913    case SWC1:
914      Format(instr, "swc1    'ft, 'imm16s('rs)");
915      break;
916    case SDC1:
917      Format(instr, "sdc1    'ft, 'imm16s('rs)");
918      break;
919    default:
920      UNREACHABLE();
921      break;
922  };
923}
924
925
926void Decoder::DecodeTypeJump(Instruction* instr) {
927  switch (instr->OpcodeFieldRaw()) {
928    case J:
929      Format(instr, "j       'imm26x");
930      break;
931    case JAL:
932      Format(instr, "jal     'imm26x");
933      break;
934    default:
935      UNREACHABLE();
936  }
937}
938
939
940// Disassemble the instruction at *instr_ptr into the output buffer.
941int Decoder::InstructionDecode(byte* instr_ptr) {
942  Instruction* instr = Instruction::At(instr_ptr);
943  // Print raw instruction bytes.
944  out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
945                                       "%08x       ",
946                                       instr->InstructionBits());
947  switch (instr->InstructionType()) {
948    case Instruction::kRegisterType: {
949      DecodeTypeRegister(instr);
950      break;
951    }
952    case Instruction::kImmediateType: {
953      DecodeTypeImmediate(instr);
954      break;
955    }
956    case Instruction::kJumpType: {
957      DecodeTypeJump(instr);
958      break;
959    }
960    default: {
961      Format(instr, "UNSUPPORTED");
962      UNSUPPORTED_MIPS();
963    }
964  }
965  return Instruction::kInstrSize;
966}
967
968
969} }  // namespace v8::internal
970
971
972
973//------------------------------------------------------------------------------
974
975namespace disasm {
976
977const char* NameConverter::NameOfAddress(byte* addr) const {
978  v8::internal::OS::SNPrintF(tmp_buffer_, "%p", addr);
979  return tmp_buffer_.start();
980}
981
982
983const char* NameConverter::NameOfConstant(byte* addr) const {
984  return NameOfAddress(addr);
985}
986
987
988const char* NameConverter::NameOfCPURegister(int reg) const {
989  return v8::internal::Registers::Name(reg);
990}
991
992
993const char* NameConverter::NameOfXMMRegister(int reg) const {
994  return v8::internal::FPURegisters::Name(reg);
995}
996
997
998const char* NameConverter::NameOfByteCPURegister(int reg) const {
999  UNREACHABLE();  // MIPS does not have the concept of a byte register.
1000  return "nobytereg";
1001}
1002
1003
1004const char* NameConverter::NameInCode(byte* addr) const {
1005  // The default name converter is called for unknown code. So we will not try
1006  // to access any memory.
1007  return "";
1008}
1009
1010
1011//------------------------------------------------------------------------------
1012
1013Disassembler::Disassembler(const NameConverter& converter)
1014    : converter_(converter) {}
1015
1016
1017Disassembler::~Disassembler() {}
1018
1019
1020int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
1021                                    byte* instruction) {
1022  v8::internal::Decoder d(converter_, buffer);
1023  return d.InstructionDecode(instruction);
1024}
1025
1026
1027// The MIPS assembler does not currently use constant pools.
1028int Disassembler::ConstantPoolSizeAt(byte* instruction) {
1029  return -1;
1030}
1031
1032
1033void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
1034  NameConverter converter;
1035  Disassembler d(converter);
1036  for (byte* pc = begin; pc < end;) {
1037    v8::internal::EmbeddedVector<char, 128> buffer;
1038    buffer[0] = '\0';
1039    byte* prev_pc = pc;
1040    pc += d.InstructionDecode(buffer, pc);
1041    fprintf(f, "%p    %08x      %s\n",
1042            prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
1043  }
1044}
1045
1046
1047#undef UNSUPPORTED
1048
1049}  // namespace disasm
1050
1051#endif  // V8_TARGET_ARCH_MIPS
1052