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