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 #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 
     66 namespace v8 {
     67 namespace 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.
     74 class 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.
    146 void Decoder::PrintChar(const char ch) {
    147   out_buffer_[out_buffer_pos_++] = ch;
    148 }
    149 
    150 
    151 // Append the str to the output buffer.
    152 void 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.
    163 void Decoder::PrintRegister(int reg) {
    164   Print(converter_.NameOfCPURegister(reg));
    165 }
    166 
    167 
    168 void Decoder::PrintRs(Instruction* instr) {
    169   int reg = instr->RsValue();
    170   PrintRegister(reg);
    171 }
    172 
    173 
    174 void Decoder::PrintRt(Instruction* instr) {
    175   int reg = instr->RtValue();
    176   PrintRegister(reg);
    177 }
    178 
    179 
    180 void 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.
    187 void Decoder::PrintFPURegister(int freg) {
    188   Print(converter_.NameOfXMMRegister(freg));
    189 }
    190 
    191 
    192 void Decoder::PrintFs(Instruction* instr) {
    193   int freg = instr->RsValue();
    194   PrintFPURegister(freg);
    195 }
    196 
    197 
    198 void Decoder::PrintFt(Instruction* instr) {
    199   int freg = instr->RtValue();
    200   PrintFPURegister(freg);
    201 }
    202 
    203 
    204 void Decoder::PrintFd(Instruction* instr) {
    205   int freg = instr->RdValue();
    206   PrintFPURegister(freg);
    207 }
    208 
    209 
    210 // Print the integer value of the sa field.
    211 void 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.
    218 void 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.
    225 void 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.
    232 void 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.
    241 void 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.
    248 void 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.
    255 void 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.
    262 void 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.
    269 void 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.
    276 void 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.
    283 void 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.
    311 void Decoder::PrintInstructionName(Instruction* instr) {
    312 }
    313 
    314 
    315 // Handle all register based formatting in this function to reduce the
    316 // complexity of FormatOption.
    317 int 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.
    339 int 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.
    364 int 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.
    441 void 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.
    457 void Decoder::Unknown(Instruction* instr) {
    458   Format(instr, "unknown");
    459 }
    460 
    461 
    462 void 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 
    798 void 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 
    926 void 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.
    941 int 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 
    975 namespace disasm {
    976 
    977 const char* NameConverter::NameOfAddress(byte* addr) const {
    978   v8::internal::OS::SNPrintF(tmp_buffer_, "%p", addr);
    979   return tmp_buffer_.start();
    980 }
    981 
    982 
    983 const char* NameConverter::NameOfConstant(byte* addr) const {
    984   return NameOfAddress(addr);
    985 }
    986 
    987 
    988 const char* NameConverter::NameOfCPURegister(int reg) const {
    989   return v8::internal::Registers::Name(reg);
    990 }
    991 
    992 
    993 const char* NameConverter::NameOfXMMRegister(int reg) const {
    994   return v8::internal::FPURegisters::Name(reg);
    995 }
    996 
    997 
    998 const char* NameConverter::NameOfByteCPURegister(int reg) const {
    999   UNREACHABLE();  // MIPS does not have the concept of a byte register.
   1000   return "nobytereg";
   1001 }
   1002 
   1003 
   1004 const 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 
   1013 Disassembler::Disassembler(const NameConverter& converter)
   1014     : converter_(converter) {}
   1015 
   1016 
   1017 Disassembler::~Disassembler() {}
   1018 
   1019 
   1020 int 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.
   1028 int Disassembler::ConstantPoolSizeAt(byte* instruction) {
   1029   return -1;
   1030 }
   1031 
   1032 
   1033 void 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