Home | History | Annotate | Download | only in arm
      1 // Copyright 2011 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 V8_TARGET_ARCH_ARM
     60 
     61 #include "constants-arm.h"
     62 #include "disasm.h"
     63 #include "macro-assembler.h"
     64 #include "platform.h"
     65 
     66 
     67 namespace v8 {
     68 namespace internal {
     69 
     70 
     71 //------------------------------------------------------------------------------
     72 
     73 // Decoder decodes and disassembles instructions into an output buffer.
     74 // It uses the converter to convert register names and call destinations into
     75 // more informative description.
     76 class Decoder {
     77  public:
     78   Decoder(const disasm::NameConverter& converter,
     79           Vector<char> out_buffer)
     80     : converter_(converter),
     81       out_buffer_(out_buffer),
     82       out_buffer_pos_(0) {
     83     out_buffer_[out_buffer_pos_] = '\0';
     84   }
     85 
     86   ~Decoder() {}
     87 
     88   // Writes one disassembled instruction into 'buffer' (0-terminated).
     89   // Returns the length of the disassembled machine instruction in bytes.
     90   int InstructionDecode(byte* instruction);
     91 
     92   static bool IsConstantPoolAt(byte* instr_ptr);
     93   static int ConstantPoolSizeAt(byte* instr_ptr);
     94 
     95  private:
     96   // Bottleneck functions to print into the out_buffer.
     97   void PrintChar(const char ch);
     98   void Print(const char* str);
     99 
    100   // Printing of common values.
    101   void PrintRegister(int reg);
    102   void PrintSRegister(int reg);
    103   void PrintDRegister(int reg);
    104   int FormatVFPRegister(Instruction* instr, const char* format);
    105   void PrintMovwMovt(Instruction* instr);
    106   int FormatVFPinstruction(Instruction* instr, const char* format);
    107   void PrintCondition(Instruction* instr);
    108   void PrintShiftRm(Instruction* instr);
    109   void PrintShiftImm(Instruction* instr);
    110   void PrintShiftSat(Instruction* instr);
    111   void PrintPU(Instruction* instr);
    112   void PrintSoftwareInterrupt(SoftwareInterruptCodes svc);
    113 
    114   // Handle formatting of instructions and their options.
    115   int FormatRegister(Instruction* instr, const char* option);
    116   void FormatNeonList(int Vd, int type);
    117   void FormatNeonMemory(int Rn, int align, int Rm);
    118   int FormatOption(Instruction* instr, const char* option);
    119   void Format(Instruction* instr, const char* format);
    120   void Unknown(Instruction* instr);
    121 
    122   // Each of these functions decodes one particular instruction type, a 3-bit
    123   // field in the instruction encoding.
    124   // Types 0 and 1 are combined as they are largely the same except for the way
    125   // they interpret the shifter operand.
    126   void DecodeType01(Instruction* instr);
    127   void DecodeType2(Instruction* instr);
    128   void DecodeType3(Instruction* instr);
    129   void DecodeType4(Instruction* instr);
    130   void DecodeType5(Instruction* instr);
    131   void DecodeType6(Instruction* instr);
    132   // Type 7 includes special Debugger instructions.
    133   int DecodeType7(Instruction* instr);
    134   // For VFP support.
    135   void DecodeTypeVFP(Instruction* instr);
    136   void DecodeType6CoprocessorIns(Instruction* instr);
    137 
    138   void DecodeSpecialCondition(Instruction* instr);
    139 
    140   void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr);
    141   void DecodeVCMP(Instruction* instr);
    142   void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr);
    143   void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr);
    144 
    145   const disasm::NameConverter& converter_;
    146   Vector<char> out_buffer_;
    147   int out_buffer_pos_;
    148 
    149   DISALLOW_COPY_AND_ASSIGN(Decoder);
    150 };
    151 
    152 
    153 // Support for assertions in the Decoder formatting functions.
    154 #define STRING_STARTS_WITH(string, compare_string) \
    155   (strncmp(string, compare_string, strlen(compare_string)) == 0)
    156 
    157 
    158 // Append the ch to the output buffer.
    159 void Decoder::PrintChar(const char ch) {
    160   out_buffer_[out_buffer_pos_++] = ch;
    161 }
    162 
    163 
    164 // Append the str to the output buffer.
    165 void Decoder::Print(const char* str) {
    166   char cur = *str++;
    167   while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
    168     PrintChar(cur);
    169     cur = *str++;
    170   }
    171   out_buffer_[out_buffer_pos_] = 0;
    172 }
    173 
    174 
    175 // These condition names are defined in a way to match the native disassembler
    176 // formatting. See for example the command "objdump -d <binary file>".
    177 static const char* cond_names[kNumberOfConditions] = {
    178   "eq", "ne", "cs" , "cc" , "mi" , "pl" , "vs" , "vc" ,
    179   "hi", "ls", "ge", "lt", "gt", "le", "", "invalid",
    180 };
    181 
    182 
    183 // Print the condition guarding the instruction.
    184 void Decoder::PrintCondition(Instruction* instr) {
    185   Print(cond_names[instr->ConditionValue()]);
    186 }
    187 
    188 
    189 // Print the register name according to the active name converter.
    190 void Decoder::PrintRegister(int reg) {
    191   Print(converter_.NameOfCPURegister(reg));
    192 }
    193 
    194 
    195 // Print the VFP S register name according to the active name converter.
    196 void Decoder::PrintSRegister(int reg) {
    197   Print(VFPRegisters::Name(reg, false));
    198 }
    199 
    200 
    201 // Print the VFP D register name according to the active name converter.
    202 void Decoder::PrintDRegister(int reg) {
    203   Print(VFPRegisters::Name(reg, true));
    204 }
    205 
    206 
    207 // These shift names are defined in a way to match the native disassembler
    208 // formatting. See for example the command "objdump -d <binary file>".
    209 static const char* const shift_names[kNumberOfShifts] = {
    210   "lsl", "lsr", "asr", "ror"
    211 };
    212 
    213 
    214 // Print the register shift operands for the instruction. Generally used for
    215 // data processing instructions.
    216 void Decoder::PrintShiftRm(Instruction* instr) {
    217   ShiftOp shift = instr->ShiftField();
    218   int shift_index = instr->ShiftValue();
    219   int shift_amount = instr->ShiftAmountValue();
    220   int rm = instr->RmValue();
    221 
    222   PrintRegister(rm);
    223 
    224   if ((instr->RegShiftValue() == 0) && (shift == LSL) && (shift_amount == 0)) {
    225     // Special case for using rm only.
    226     return;
    227   }
    228   if (instr->RegShiftValue() == 0) {
    229     // by immediate
    230     if ((shift == ROR) && (shift_amount == 0)) {
    231       Print(", RRX");
    232       return;
    233     } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
    234       shift_amount = 32;
    235     }
    236     out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    237                                     ", %s #%d",
    238                                     shift_names[shift_index],
    239                                     shift_amount);
    240   } else {
    241     // by register
    242     int rs = instr->RsValue();
    243     out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    244                                     ", %s ", shift_names[shift_index]);
    245     PrintRegister(rs);
    246   }
    247 }
    248 
    249 
    250 // Print the immediate operand for the instruction. Generally used for data
    251 // processing instructions.
    252 void Decoder::PrintShiftImm(Instruction* instr) {
    253   int rotate = instr->RotateValue() * 2;
    254   int immed8 = instr->Immed8Value();
    255   int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
    256   out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    257                                   "#%d", imm);
    258 }
    259 
    260 
    261 // Print the optional shift and immediate used by saturating instructions.
    262 void Decoder::PrintShiftSat(Instruction* instr) {
    263   int shift = instr->Bits(11, 7);
    264   if (shift > 0) {
    265     out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    266                                     ", %s #%d",
    267                                     shift_names[instr->Bit(6) * 2],
    268                                     instr->Bits(11, 7));
    269   }
    270 }
    271 
    272 
    273 // Print PU formatting to reduce complexity of FormatOption.
    274 void Decoder::PrintPU(Instruction* instr) {
    275   switch (instr->PUField()) {
    276     case da_x: {
    277       Print("da");
    278       break;
    279     }
    280     case ia_x: {
    281       Print("ia");
    282       break;
    283     }
    284     case db_x: {
    285       Print("db");
    286       break;
    287     }
    288     case ib_x: {
    289       Print("ib");
    290       break;
    291     }
    292     default: {
    293       UNREACHABLE();
    294       break;
    295     }
    296   }
    297 }
    298 
    299 
    300 // Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
    301 // the FormatOption method.
    302 void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) {
    303   switch (svc) {
    304     case kCallRtRedirected:
    305       Print("call rt redirected");
    306       return;
    307     case kBreakpoint:
    308       Print("breakpoint");
    309       return;
    310     default:
    311       if (svc >= kStopCode) {
    312         out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    313                                         "%d - 0x%x",
    314                                         svc & kStopCodeMask,
    315                                         svc & kStopCodeMask);
    316       } else {
    317         out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    318                                         "%d",
    319                                         svc);
    320       }
    321       return;
    322   }
    323 }
    324 
    325 
    326 // Handle all register based formatting in this function to reduce the
    327 // complexity of FormatOption.
    328 int Decoder::FormatRegister(Instruction* instr, const char* format) {
    329   ASSERT(format[0] == 'r');
    330   if (format[1] == 'n') {  // 'rn: Rn register
    331     int reg = instr->RnValue();
    332     PrintRegister(reg);
    333     return 2;
    334   } else if (format[1] == 'd') {  // 'rd: Rd register
    335     int reg = instr->RdValue();
    336     PrintRegister(reg);
    337     return 2;
    338   } else if (format[1] == 's') {  // 'rs: Rs register
    339     int reg = instr->RsValue();
    340     PrintRegister(reg);
    341     return 2;
    342   } else if (format[1] == 'm') {  // 'rm: Rm register
    343     int reg = instr->RmValue();
    344     PrintRegister(reg);
    345     return 2;
    346   } else if (format[1] == 't') {  // 'rt: Rt register
    347     int reg = instr->RtValue();
    348     PrintRegister(reg);
    349     return 2;
    350   } else if (format[1] == 'l') {
    351     // 'rlist: register list for load and store multiple instructions
    352     ASSERT(STRING_STARTS_WITH(format, "rlist"));
    353     int rlist = instr->RlistValue();
    354     int reg = 0;
    355     Print("{");
    356     // Print register list in ascending order, by scanning the bit mask.
    357     while (rlist != 0) {
    358       if ((rlist & 1) != 0) {
    359         PrintRegister(reg);
    360         if ((rlist >> 1) != 0) {
    361           Print(", ");
    362         }
    363       }
    364       reg++;
    365       rlist >>= 1;
    366     }
    367     Print("}");
    368     return 5;
    369   }
    370   UNREACHABLE();
    371   return -1;
    372 }
    373 
    374 
    375 // Handle all VFP register based formatting in this function to reduce the
    376 // complexity of FormatOption.
    377 int Decoder::FormatVFPRegister(Instruction* instr, const char* format) {
    378   ASSERT((format[0] == 'S') || (format[0] == 'D'));
    379 
    380   VFPRegPrecision precision =
    381       format[0] == 'D' ? kDoublePrecision : kSinglePrecision;
    382 
    383   int retval = 2;
    384   int reg = -1;
    385   if (format[1] == 'n') {
    386     reg = instr->VFPNRegValue(precision);
    387   } else if (format[1] == 'm') {
    388     reg = instr->VFPMRegValue(precision);
    389   } else if (format[1] == 'd') {
    390     if ((instr->TypeValue() == 7) &&
    391         (instr->Bit(24) == 0x0) &&
    392         (instr->Bits(11, 9) == 0x5) &&
    393         (instr->Bit(4) == 0x1)) {
    394       // vmov.32 has Vd in a different place.
    395       reg = instr->Bits(19, 16) | (instr->Bit(7) << 4);
    396     } else {
    397       reg = instr->VFPDRegValue(precision);
    398     }
    399 
    400     if (format[2] == '+') {
    401       int immed8 = instr->Immed8Value();
    402       if (format[0] == 'S') reg += immed8 - 1;
    403       if (format[0] == 'D') reg += (immed8 / 2 - 1);
    404     }
    405     if (format[2] == '+') retval = 3;
    406   } else {
    407     UNREACHABLE();
    408   }
    409 
    410   if (precision == kSinglePrecision) {
    411     PrintSRegister(reg);
    412   } else {
    413     PrintDRegister(reg);
    414   }
    415 
    416   return retval;
    417 }
    418 
    419 
    420 int Decoder::FormatVFPinstruction(Instruction* instr, const char* format) {
    421     Print(format);
    422     return 0;
    423 }
    424 
    425 
    426 void Decoder::FormatNeonList(int Vd, int type) {
    427   if (type == nlt_1) {
    428     out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    429                                     "{d%d}", Vd);
    430   } else if (type == nlt_2) {
    431     out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    432                                     "{d%d, d%d}", Vd, Vd + 1);
    433   } else if (type == nlt_3) {
    434     out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    435                                     "{d%d, d%d, d%d}", Vd, Vd + 1, Vd + 2);
    436   } else if (type == nlt_4) {
    437     out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    438                             "{d%d, d%d, d%d, d%d}", Vd, Vd + 1, Vd + 2, Vd + 3);
    439   }
    440 }
    441 
    442 
    443 void Decoder::FormatNeonMemory(int Rn, int align, int Rm) {
    444   out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    445                                   "[r%d", Rn);
    446   if (align != 0) {
    447     out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    448                                     ":%d", (1 << align) << 6);
    449   }
    450   if (Rm == 15) {
    451     Print("]");
    452   } else if (Rm == 13) {
    453     Print("]!");
    454   } else {
    455     out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    456                                     "], r%d", Rm);
    457   }
    458 }
    459 
    460 
    461 // Print the movw or movt instruction.
    462 void Decoder::PrintMovwMovt(Instruction* instr) {
    463   int imm = instr->ImmedMovwMovtValue();
    464   int rd = instr->RdValue();
    465   PrintRegister(rd);
    466   out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    467                                   ", #%d", imm);
    468 }
    469 
    470 
    471 // FormatOption takes a formatting string and interprets it based on
    472 // the current instructions. The format string points to the first
    473 // character of the option string (the option escape has already been
    474 // consumed by the caller.)  FormatOption returns the number of
    475 // characters that were consumed from the formatting string.
    476 int Decoder::FormatOption(Instruction* instr, const char* format) {
    477   switch (format[0]) {
    478     case 'a': {  // 'a: accumulate multiplies
    479       if (instr->Bit(21) == 0) {
    480         Print("ul");
    481       } else {
    482         Print("la");
    483       }
    484       return 1;
    485     }
    486     case 'b': {  // 'b: byte loads or stores
    487       if (instr->HasB()) {
    488         Print("b");
    489       }
    490       return 1;
    491     }
    492     case 'c': {  // 'cond: conditional execution
    493       ASSERT(STRING_STARTS_WITH(format, "cond"));
    494       PrintCondition(instr);
    495       return 4;
    496     }
    497     case 'd': {  // 'd: vmov double immediate.
    498       double d = instr->DoubleImmedVmov();
    499       out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    500                                       "#%g", d);
    501       return 1;
    502     }
    503     case 'f': {  // 'f: bitfield instructions - v7 and above.
    504       uint32_t lsbit = instr->Bits(11, 7);
    505       uint32_t width = instr->Bits(20, 16) + 1;
    506       if (instr->Bit(21) == 0) {
    507         // BFC/BFI:
    508         // Bits 20-16 represent most-significant bit. Covert to width.
    509         width -= lsbit;
    510         ASSERT(width > 0);
    511       }
    512       ASSERT((width + lsbit) <= 32);
    513       out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    514                                       "#%d, #%d", lsbit, width);
    515       return 1;
    516     }
    517     case 'h': {  // 'h: halfword operation for extra loads and stores
    518       if (instr->HasH()) {
    519         Print("h");
    520       } else {
    521         Print("b");
    522       }
    523       return 1;
    524     }
    525     case 'i': {  // 'i: immediate value from adjacent bits.
    526       // Expects tokens in the form imm%02d@%02d, i.e. imm05@07, imm10@16
    527       int width = (format[3] - '0') * 10 + (format[4] - '0');
    528       int lsb   = (format[6] - '0') * 10 + (format[7] - '0');
    529 
    530       ASSERT((width >= 1) && (width <= 32));
    531       ASSERT((lsb >= 0) && (lsb <= 31));
    532       ASSERT((width + lsb) <= 32);
    533 
    534       out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    535                                       "%d",
    536                                       instr->Bits(width + lsb - 1, lsb));
    537       return 8;
    538     }
    539     case 'l': {  // 'l: branch and link
    540       if (instr->HasLink()) {
    541         Print("l");
    542       }
    543       return 1;
    544     }
    545     case 'm': {
    546       if (format[1] == 'w') {
    547         // 'mw: movt/movw instructions.
    548         PrintMovwMovt(instr);
    549         return 2;
    550       }
    551       if (format[1] == 'e') {  // 'memop: load/store instructions.
    552         ASSERT(STRING_STARTS_WITH(format, "memop"));
    553         if (instr->HasL()) {
    554           Print("ldr");
    555         } else {
    556           if ((instr->Bits(27, 25) == 0) && (instr->Bit(20) == 0) &&
    557               (instr->Bits(7, 6) == 3) && (instr->Bit(4) == 1)) {
    558             if (instr->Bit(5) == 1) {
    559               Print("strd");
    560             } else {
    561               Print("ldrd");
    562             }
    563             return 5;
    564           }
    565           Print("str");
    566         }
    567         return 5;
    568       }
    569       // 'msg: for simulator break instructions
    570       ASSERT(STRING_STARTS_WITH(format, "msg"));
    571       byte* str =
    572           reinterpret_cast<byte*>(instr->InstructionBits() & 0x0fffffff);
    573       out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    574                                       "%s", converter_.NameInCode(str));
    575       return 3;
    576     }
    577     case 'o': {
    578       if ((format[3] == '1') && (format[4] == '2')) {
    579         // 'off12: 12-bit offset for load and store instructions
    580         ASSERT(STRING_STARTS_WITH(format, "off12"));
    581         out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    582                                         "%d", instr->Offset12Value());
    583         return 5;
    584       } else if (format[3] == '0') {
    585         // 'off0to3and8to19 16-bit immediate encoded in bits 19-8 and 3-0.
    586         ASSERT(STRING_STARTS_WITH(format, "off0to3and8to19"));
    587         out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    588                                         "%d",
    589                                         (instr->Bits(19, 8) << 4) +
    590                                         instr->Bits(3, 0));
    591         return 15;
    592       }
    593       // 'off8: 8-bit offset for extra load and store instructions
    594       ASSERT(STRING_STARTS_WITH(format, "off8"));
    595       int offs8 = (instr->ImmedHValue() << 4) | instr->ImmedLValue();
    596       out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    597                                       "%d", offs8);
    598       return 4;
    599     }
    600     case 'p': {  // 'pu: P and U bits for load and store instructions
    601       ASSERT(STRING_STARTS_WITH(format, "pu"));
    602       PrintPU(instr);
    603       return 2;
    604     }
    605     case 'r': {
    606       return FormatRegister(instr, format);
    607     }
    608     case 's': {
    609       if (format[1] == 'h') {  // 'shift_op or 'shift_rm or 'shift_sat.
    610         if (format[6] == 'o') {  // 'shift_op
    611           ASSERT(STRING_STARTS_WITH(format, "shift_op"));
    612           if (instr->TypeValue() == 0) {
    613             PrintShiftRm(instr);
    614           } else {
    615             ASSERT(instr->TypeValue() == 1);
    616             PrintShiftImm(instr);
    617           }
    618           return 8;
    619         } else if (format[6] == 's') {  // 'shift_sat.
    620           ASSERT(STRING_STARTS_WITH(format, "shift_sat"));
    621           PrintShiftSat(instr);
    622           return 9;
    623         } else {  // 'shift_rm
    624           ASSERT(STRING_STARTS_WITH(format, "shift_rm"));
    625           PrintShiftRm(instr);
    626           return 8;
    627         }
    628       } else if (format[1] == 'v') {  // 'svc
    629         ASSERT(STRING_STARTS_WITH(format, "svc"));
    630         PrintSoftwareInterrupt(instr->SvcValue());
    631         return 3;
    632       } else if (format[1] == 'i') {  // 'sign: signed extra loads and stores
    633         ASSERT(STRING_STARTS_WITH(format, "sign"));
    634         if (instr->HasSign()) {
    635           Print("s");
    636         }
    637         return 4;
    638       }
    639       // 's: S field of data processing instructions
    640       if (instr->HasS()) {
    641         Print("s");
    642       }
    643       return 1;
    644     }
    645     case 't': {  // 'target: target of branch instructions
    646       ASSERT(STRING_STARTS_WITH(format, "target"));
    647       int off = (instr->SImmed24Value() << 2) + 8;
    648       out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
    649                                       "%+d -> %s",
    650                                       off,
    651                                       converter_.NameOfAddress(
    652                                         reinterpret_cast<byte*>(instr) + off));
    653       return 6;
    654     }
    655     case 'u': {  // 'u: signed or unsigned multiplies
    656       // The manual gets the meaning of bit 22 backwards in the multiply
    657       // instruction overview on page A3.16.2.  The instructions that
    658       // exist in u and s variants are the following:
    659       // smull A4.1.87
    660       // umull A4.1.129
    661       // umlal A4.1.128
    662       // smlal A4.1.76
    663       // For these 0 means u and 1 means s.  As can be seen on their individual
    664       // pages.  The other 18 mul instructions have the bit set or unset in
    665       // arbitrary ways that are unrelated to the signedness of the instruction.
    666       // None of these 18 instructions exist in both a 'u' and an 's' variant.
    667 
    668       if (instr->Bit(22) == 0) {
    669         Print("u");
    670       } else {
    671         Print("s");
    672       }
    673       return 1;
    674     }
    675     case 'v': {
    676       return FormatVFPinstruction(instr, format);
    677     }
    678     case 'S':
    679     case 'D': {
    680       return FormatVFPRegister(instr, format);
    681     }
    682     case 'w': {  // 'w: W field of load and store instructions
    683       if (instr->HasW()) {
    684         Print("!");
    685       }
    686       return 1;
    687     }
    688     default: {
    689       UNREACHABLE();
    690       break;
    691     }
    692   }
    693   UNREACHABLE();
    694   return -1;
    695 }
    696 
    697 
    698 // Format takes a formatting string for a whole instruction and prints it into
    699 // the output buffer. All escaped options are handed to FormatOption to be
    700 // parsed further.
    701 void Decoder::Format(Instruction* instr, const char* format) {
    702   char cur = *format++;
    703   while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
    704     if (cur == '\'') {  // Single quote is used as the formatting escape.
    705       format += FormatOption(instr, format);
    706     } else {
    707       out_buffer_[out_buffer_pos_++] = cur;
    708     }
    709     cur = *format++;
    710   }
    711   out_buffer_[out_buffer_pos_]  = '\0';
    712 }
    713 
    714 
    715 // The disassembler may end up decoding data inlined in the code. We do not want
    716 // it to crash if the data does not ressemble any known instruction.
    717 #define VERIFY(condition) \
    718 if(!(condition)) {        \
    719   Unknown(instr);         \
    720   return;                 \
    721 }
    722 
    723 
    724 // For currently unimplemented decodings the disassembler calls Unknown(instr)
    725 // which will just print "unknown" of the instruction bits.
    726 void Decoder::Unknown(Instruction* instr) {
    727   Format(instr, "unknown");
    728 }
    729 
    730 
    731 void Decoder::DecodeType01(Instruction* instr) {
    732   int type = instr->TypeValue();
    733   if ((type == 0) && instr->IsSpecialType0()) {
    734     // multiply instruction or extra loads and stores
    735     if (instr->Bits(7, 4) == 9) {
    736       if (instr->Bit(24) == 0) {
    737         // multiply instructions
    738         if (instr->Bit(23) == 0) {
    739           if (instr->Bit(21) == 0) {
    740             // The MUL instruction description (A 4.1.33) refers to Rd as being
    741             // the destination for the operation, but it confusingly uses the
    742             // Rn field to encode it.
    743             Format(instr, "mul'cond's 'rn, 'rm, 'rs");
    744           } else {
    745             if (instr->Bit(22) == 0) {
    746               // The MLA instruction description (A 4.1.28) refers to the order
    747               // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
    748               // Rn field to encode the Rd register and the Rd field to encode
    749               // the Rn register.
    750               Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd");
    751             } else {
    752               // The MLS instruction description (A 4.1.29) refers to the order
    753               // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the
    754               // Rn field to encode the Rd register and the Rd field to encode
    755               // the Rn register.
    756               Format(instr, "mls'cond's 'rn, 'rm, 'rs, 'rd");
    757             }
    758           }
    759         } else {
    760           // The signed/long multiply instructions use the terms RdHi and RdLo
    761           // when referring to the target registers. They are mapped to the Rn
    762           // and Rd fields as follows:
    763           // RdLo == Rd field
    764           // RdHi == Rn field
    765           // The order of registers is: <RdLo>, <RdHi>, <Rm>, <Rs>
    766           Format(instr, "'um'al'cond's 'rd, 'rn, 'rm, 'rs");
    767         }
    768       } else {
    769         Unknown(instr);  // not used by V8
    770       }
    771     } else if ((instr->Bit(20) == 0) && ((instr->Bits(7, 4) & 0xd) == 0xd)) {
    772       // ldrd, strd
    773       switch (instr->PUField()) {
    774         case da_x: {
    775           if (instr->Bit(22) == 0) {
    776             Format(instr, "'memop'cond's 'rd, ['rn], -'rm");
    777           } else {
    778             Format(instr, "'memop'cond's 'rd, ['rn], #-'off8");
    779           }
    780           break;
    781         }
    782         case ia_x: {
    783           if (instr->Bit(22) == 0) {
    784             Format(instr, "'memop'cond's 'rd, ['rn], +'rm");
    785           } else {
    786             Format(instr, "'memop'cond's 'rd, ['rn], #+'off8");
    787           }
    788           break;
    789         }
    790         case db_x: {
    791           if (instr->Bit(22) == 0) {
    792             Format(instr, "'memop'cond's 'rd, ['rn, -'rm]'w");
    793           } else {
    794             Format(instr, "'memop'cond's 'rd, ['rn, #-'off8]'w");
    795           }
    796           break;
    797         }
    798         case ib_x: {
    799           if (instr->Bit(22) == 0) {
    800             Format(instr, "'memop'cond's 'rd, ['rn, +'rm]'w");
    801           } else {
    802             Format(instr, "'memop'cond's 'rd, ['rn, #+'off8]'w");
    803           }
    804           break;
    805         }
    806         default: {
    807           // The PU field is a 2-bit field.
    808           UNREACHABLE();
    809           break;
    810         }
    811       }
    812     } else {
    813       // extra load/store instructions
    814       switch (instr->PUField()) {
    815         case da_x: {
    816           if (instr->Bit(22) == 0) {
    817             Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm");
    818           } else {
    819             Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8");
    820           }
    821           break;
    822         }
    823         case ia_x: {
    824           if (instr->Bit(22) == 0) {
    825             Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm");
    826           } else {
    827             Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8");
    828           }
    829           break;
    830         }
    831         case db_x: {
    832           if (instr->Bit(22) == 0) {
    833             Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w");
    834           } else {
    835             Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w");
    836           }
    837           break;
    838         }
    839         case ib_x: {
    840           if (instr->Bit(22) == 0) {
    841             Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w");
    842           } else {
    843             Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w");
    844           }
    845           break;
    846         }
    847         default: {
    848           // The PU field is a 2-bit field.
    849           UNREACHABLE();
    850           break;
    851         }
    852       }
    853       return;
    854     }
    855   } else if ((type == 0) && instr->IsMiscType0()) {
    856     if (instr->Bits(22, 21) == 1) {
    857       switch (instr->BitField(7, 4)) {
    858         case BX:
    859           Format(instr, "bx'cond 'rm");
    860           break;
    861         case BLX:
    862           Format(instr, "blx'cond 'rm");
    863           break;
    864         case BKPT:
    865           Format(instr, "bkpt 'off0to3and8to19");
    866           break;
    867         default:
    868           Unknown(instr);  // not used by V8
    869           break;
    870       }
    871     } else if (instr->Bits(22, 21) == 3) {
    872       switch (instr->BitField(7, 4)) {
    873         case CLZ:
    874           Format(instr, "clz'cond 'rd, 'rm");
    875           break;
    876         default:
    877           Unknown(instr);  // not used by V8
    878           break;
    879       }
    880     } else {
    881       Unknown(instr);  // not used by V8
    882     }
    883   } else if ((type == 1) && instr->IsNopType1()) {
    884     Format(instr, "nop'cond");
    885   } else {
    886     switch (instr->OpcodeField()) {
    887       case AND: {
    888         Format(instr, "and'cond's 'rd, 'rn, 'shift_op");
    889         break;
    890       }
    891       case EOR: {
    892         Format(instr, "eor'cond's 'rd, 'rn, 'shift_op");
    893         break;
    894       }
    895       case SUB: {
    896         Format(instr, "sub'cond's 'rd, 'rn, 'shift_op");
    897         break;
    898       }
    899       case RSB: {
    900         Format(instr, "rsb'cond's 'rd, 'rn, 'shift_op");
    901         break;
    902       }
    903       case ADD: {
    904         Format(instr, "add'cond's 'rd, 'rn, 'shift_op");
    905         break;
    906       }
    907       case ADC: {
    908         Format(instr, "adc'cond's 'rd, 'rn, 'shift_op");
    909         break;
    910       }
    911       case SBC: {
    912         Format(instr, "sbc'cond's 'rd, 'rn, 'shift_op");
    913         break;
    914       }
    915       case RSC: {
    916         Format(instr, "rsc'cond's 'rd, 'rn, 'shift_op");
    917         break;
    918       }
    919       case TST: {
    920         if (instr->HasS()) {
    921           Format(instr, "tst'cond 'rn, 'shift_op");
    922         } else {
    923           Format(instr, "movw'cond 'mw");
    924         }
    925         break;
    926       }
    927       case TEQ: {
    928         if (instr->HasS()) {
    929           Format(instr, "teq'cond 'rn, 'shift_op");
    930         } else {
    931           // Other instructions matching this pattern are handled in the
    932           // miscellaneous instructions part above.
    933           UNREACHABLE();
    934         }
    935         break;
    936       }
    937       case CMP: {
    938         if (instr->HasS()) {
    939           Format(instr, "cmp'cond 'rn, 'shift_op");
    940         } else {
    941           Format(instr, "movt'cond 'mw");
    942         }
    943         break;
    944       }
    945       case CMN: {
    946         if (instr->HasS()) {
    947           Format(instr, "cmn'cond 'rn, 'shift_op");
    948         } else {
    949           // Other instructions matching this pattern are handled in the
    950           // miscellaneous instructions part above.
    951           UNREACHABLE();
    952         }
    953         break;
    954       }
    955       case ORR: {
    956         Format(instr, "orr'cond's 'rd, 'rn, 'shift_op");
    957         break;
    958       }
    959       case MOV: {
    960         Format(instr, "mov'cond's 'rd, 'shift_op");
    961         break;
    962       }
    963       case BIC: {
    964         Format(instr, "bic'cond's 'rd, 'rn, 'shift_op");
    965         break;
    966       }
    967       case MVN: {
    968         Format(instr, "mvn'cond's 'rd, 'shift_op");
    969         break;
    970       }
    971       default: {
    972         // The Opcode field is a 4-bit field.
    973         UNREACHABLE();
    974         break;
    975       }
    976     }
    977   }
    978 }
    979 
    980 
    981 void Decoder::DecodeType2(Instruction* instr) {
    982   switch (instr->PUField()) {
    983     case da_x: {
    984       if (instr->HasW()) {
    985         Unknown(instr);  // not used in V8
    986         return;
    987       }
    988       Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
    989       break;
    990     }
    991     case ia_x: {
    992       if (instr->HasW()) {
    993         Unknown(instr);  // not used in V8
    994         return;
    995       }
    996       Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
    997       break;
    998     }
    999     case db_x: {
   1000       Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");
   1001       break;
   1002     }
   1003     case ib_x: {
   1004       Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");
   1005       break;
   1006     }
   1007     default: {
   1008       // The PU field is a 2-bit field.
   1009       UNREACHABLE();
   1010       break;
   1011     }
   1012   }
   1013 }
   1014 
   1015 
   1016 void Decoder::DecodeType3(Instruction* instr) {
   1017   switch (instr->PUField()) {
   1018     case da_x: {
   1019       VERIFY(!instr->HasW());
   1020       Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
   1021       break;
   1022     }
   1023     case ia_x: {
   1024       if (instr->Bit(4) == 0) {
   1025         Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
   1026       } else {
   1027         if (instr->Bit(5) == 0) {
   1028           switch (instr->Bits(22, 21)) {
   1029             case 0:
   1030               if (instr->Bit(20) == 0) {
   1031                 if (instr->Bit(6) == 0) {
   1032                   Format(instr, "pkhbt'cond 'rd, 'rn, 'rm, lsl #'imm05@07");
   1033                 } else {
   1034                   if (instr->Bits(11, 7) == 0) {
   1035                     Format(instr, "pkhtb'cond 'rd, 'rn, 'rm, asr #32");
   1036                   } else {
   1037                     Format(instr, "pkhtb'cond 'rd, 'rn, 'rm, asr #'imm05@07");
   1038                   }
   1039                 }
   1040               } else {
   1041                 UNREACHABLE();
   1042               }
   1043               break;
   1044             case 1:
   1045               UNREACHABLE();
   1046               break;
   1047             case 2:
   1048               UNREACHABLE();
   1049               break;
   1050             case 3:
   1051               Format(instr, "usat 'rd, #'imm05@16, 'rm'shift_sat");
   1052               break;
   1053           }
   1054         } else {
   1055           switch (instr->Bits(22, 21)) {
   1056             case 0:
   1057               UNREACHABLE();
   1058               break;
   1059             case 1:
   1060               UNREACHABLE();
   1061               break;
   1062             case 2:
   1063               if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
   1064                 if (instr->Bits(19, 16) == 0xF) {
   1065                   switch (instr->Bits(11, 10)) {
   1066                     case 0:
   1067                       Format(instr, "uxtb16'cond 'rd, 'rm, ror #0");
   1068                       break;
   1069                     case 1:
   1070                       Format(instr, "uxtb16'cond 'rd, 'rm, ror #8");
   1071                       break;
   1072                     case 2:
   1073                       Format(instr, "uxtb16'cond 'rd, 'rm, ror #16");
   1074                       break;
   1075                     case 3:
   1076                       Format(instr, "uxtb16'cond 'rd, 'rm, ror #24");
   1077                       break;
   1078                   }
   1079                 } else {
   1080                   UNREACHABLE();
   1081                 }
   1082               } else {
   1083                 UNREACHABLE();
   1084               }
   1085               break;
   1086             case 3:
   1087               if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
   1088                 if (instr->Bits(19, 16) == 0xF) {
   1089                   switch (instr->Bits(11, 10)) {
   1090                     case 0:
   1091                       Format(instr, "uxtb'cond 'rd, 'rm, ror #0");
   1092                       break;
   1093                     case 1:
   1094                       Format(instr, "uxtb'cond 'rd, 'rm, ror #8");
   1095                       break;
   1096                     case 2:
   1097                       Format(instr, "uxtb'cond 'rd, 'rm, ror #16");
   1098                       break;
   1099                     case 3:
   1100                       Format(instr, "uxtb'cond 'rd, 'rm, ror #24");
   1101                       break;
   1102                   }
   1103                 } else {
   1104                   switch (instr->Bits(11, 10)) {
   1105                     case 0:
   1106                       Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #0");
   1107                       break;
   1108                     case 1:
   1109                       Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #8");
   1110                       break;
   1111                     case 2:
   1112                       Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #16");
   1113                       break;
   1114                     case 3:
   1115                       Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #24");
   1116                       break;
   1117                   }
   1118                 }
   1119               } else {
   1120                 UNREACHABLE();
   1121               }
   1122               break;
   1123           }
   1124         }
   1125       }
   1126       break;
   1127     }
   1128     case db_x: {
   1129       if (FLAG_enable_sudiv) {
   1130         if (!instr->HasW()) {
   1131           if (instr->Bits(5, 4) == 0x1) {
   1132             if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) {
   1133               // SDIV (in V8 notation matching ARM ISA format) rn = rm/rs
   1134               Format(instr, "sdiv'cond'b 'rn, 'rm, 'rs");
   1135               break;
   1136             }
   1137           }
   1138         }
   1139       }
   1140       Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
   1141       break;
   1142     }
   1143     case ib_x: {
   1144       if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) {
   1145         uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16));
   1146         uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
   1147         uint32_t msbit = widthminus1 + lsbit;
   1148         if (msbit <= 31) {
   1149           if (instr->Bit(22)) {
   1150             Format(instr, "ubfx'cond 'rd, 'rm, 'f");
   1151           } else {
   1152             Format(instr, "sbfx'cond 'rd, 'rm, 'f");
   1153           }
   1154         } else {
   1155           UNREACHABLE();
   1156         }
   1157       } else if (!instr->HasW() && (instr->Bits(6, 4) == 0x1)) {
   1158         uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7));
   1159         uint32_t msbit = static_cast<uint32_t>(instr->Bits(20, 16));
   1160         if (msbit >= lsbit) {
   1161           if (instr->RmValue() == 15) {
   1162             Format(instr, "bfc'cond 'rd, 'f");
   1163           } else {
   1164             Format(instr, "bfi'cond 'rd, 'rm, 'f");
   1165           }
   1166         } else {
   1167           UNREACHABLE();
   1168         }
   1169       } else {
   1170         Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
   1171       }
   1172       break;
   1173     }
   1174     default: {
   1175       // The PU field is a 2-bit field.
   1176       UNREACHABLE();
   1177       break;
   1178     }
   1179   }
   1180 }
   1181 
   1182 
   1183 void Decoder::DecodeType4(Instruction* instr) {
   1184   if (instr->Bit(22) != 0) {
   1185     // Privileged mode currently not supported.
   1186     Unknown(instr);
   1187   } else {
   1188     if (instr->HasL()) {
   1189       Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
   1190     } else {
   1191       Format(instr, "stm'cond'pu 'rn'w, 'rlist");
   1192     }
   1193   }
   1194 }
   1195 
   1196 
   1197 void Decoder::DecodeType5(Instruction* instr) {
   1198   Format(instr, "b'l'cond 'target");
   1199 }
   1200 
   1201 
   1202 void Decoder::DecodeType6(Instruction* instr) {
   1203   DecodeType6CoprocessorIns(instr);
   1204 }
   1205 
   1206 
   1207 int Decoder::DecodeType7(Instruction* instr) {
   1208   if (instr->Bit(24) == 1) {
   1209     if (instr->SvcValue() >= kStopCode) {
   1210       Format(instr, "stop'cond 'svc");
   1211       // Also print the stop message. Its address is encoded
   1212       // in the following 4 bytes.
   1213       out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
   1214                                       "\n  %p  %08x       stop message: %s",
   1215                                       reinterpret_cast<int32_t*>(instr
   1216                                                      + Instruction::kInstrSize),
   1217                                       *reinterpret_cast<char**>(instr
   1218                                                     + Instruction::kInstrSize),
   1219                                       *reinterpret_cast<char**>(instr
   1220                                                     + Instruction::kInstrSize));
   1221       // We have decoded 2 * Instruction::kInstrSize bytes.
   1222       return 2 * Instruction::kInstrSize;
   1223     } else {
   1224       Format(instr, "svc'cond 'svc");
   1225     }
   1226   } else {
   1227     DecodeTypeVFP(instr);
   1228   }
   1229   return Instruction::kInstrSize;
   1230 }
   1231 
   1232 
   1233 // void Decoder::DecodeTypeVFP(Instruction* instr)
   1234 // vmov: Sn = Rt
   1235 // vmov: Rt = Sn
   1236 // vcvt: Dd = Sm
   1237 // vcvt: Sd = Dm
   1238 // vcvt.f64.s32 Dd, Dd, #<fbits>
   1239 // Dd = vabs(Dm)
   1240 // Dd = vneg(Dm)
   1241 // Dd = vadd(Dn, Dm)
   1242 // Dd = vsub(Dn, Dm)
   1243 // Dd = vmul(Dn, Dm)
   1244 // Dd = vmla(Dn, Dm)
   1245 // Dd = vmls(Dn, Dm)
   1246 // Dd = vdiv(Dn, Dm)
   1247 // vcmp(Dd, Dm)
   1248 // vmrs
   1249 // vmsr
   1250 // Dd = vsqrt(Dm)
   1251 void Decoder::DecodeTypeVFP(Instruction* instr) {
   1252   VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
   1253   VERIFY(instr->Bits(11, 9) == 0x5);
   1254 
   1255   if (instr->Bit(4) == 0) {
   1256     if (instr->Opc1Value() == 0x7) {
   1257       // Other data processing instructions
   1258       if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) {
   1259         // vmov register to register.
   1260         if (instr->SzValue() == 0x1) {
   1261           Format(instr, "vmov'cond.f64 'Dd, 'Dm");
   1262         } else {
   1263           Format(instr, "vmov'cond.f32 'Sd, 'Sm");
   1264         }
   1265       } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) {
   1266         // vabs
   1267         Format(instr, "vabs'cond.f64 'Dd, 'Dm");
   1268       } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) {
   1269         // vneg
   1270         Format(instr, "vneg'cond.f64 'Dd, 'Dm");
   1271       } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) {
   1272         DecodeVCVTBetweenDoubleAndSingle(instr);
   1273       } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
   1274         DecodeVCVTBetweenFloatingPointAndInteger(instr);
   1275       } else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) &&
   1276                  (instr->Bit(8) == 1)) {
   1277         // vcvt.f64.s32 Dd, Dd, #<fbits>
   1278         int fraction_bits = 32 - ((instr->Bit(5) << 4) | instr->Bits(3, 0));
   1279         Format(instr, "vcvt'cond.f64.s32 'Dd, 'Dd");
   1280         out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
   1281                                         ", #%d", fraction_bits);
   1282       } else if (((instr->Opc2Value() >> 1) == 0x6) &&
   1283                  (instr->Opc3Value() & 0x1)) {
   1284         DecodeVCVTBetweenFloatingPointAndInteger(instr);
   1285       } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
   1286                  (instr->Opc3Value() & 0x1)) {
   1287         DecodeVCMP(instr);
   1288       } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) {
   1289         Format(instr, "vsqrt'cond.f64 'Dd, 'Dm");
   1290       } else if (instr->Opc3Value() == 0x0) {
   1291         if (instr->SzValue() == 0x1) {
   1292           Format(instr, "vmov'cond.f64 'Dd, 'd");
   1293         } else {
   1294           Unknown(instr);  // Not used by V8.
   1295         }
   1296       } else {
   1297         Unknown(instr);  // Not used by V8.
   1298       }
   1299     } else if (instr->Opc1Value() == 0x3) {
   1300       if (instr->SzValue() == 0x1) {
   1301         if (instr->Opc3Value() & 0x1) {
   1302           Format(instr, "vsub'cond.f64 'Dd, 'Dn, 'Dm");
   1303         } else {
   1304           Format(instr, "vadd'cond.f64 'Dd, 'Dn, 'Dm");
   1305         }
   1306       } else {
   1307         Unknown(instr);  // Not used by V8.
   1308       }
   1309     } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
   1310       if (instr->SzValue() == 0x1) {
   1311         Format(instr, "vmul'cond.f64 'Dd, 'Dn, 'Dm");
   1312       } else {
   1313         Unknown(instr);  // Not used by V8.
   1314       }
   1315     } else if ((instr->Opc1Value() == 0x0) && !(instr->Opc3Value() & 0x1)) {
   1316       if (instr->SzValue() == 0x1) {
   1317         Format(instr, "vmla'cond.f64 'Dd, 'Dn, 'Dm");
   1318       } else {
   1319         Unknown(instr);  // Not used by V8.
   1320       }
   1321     } else if ((instr->Opc1Value() == 0x0) && (instr->Opc3Value() & 0x1)) {
   1322       if (instr->SzValue() == 0x1) {
   1323         Format(instr, "vmls'cond.f64 'Dd, 'Dn, 'Dm");
   1324       } else {
   1325         Unknown(instr);  // Not used by V8.
   1326       }
   1327     } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) {
   1328       if (instr->SzValue() == 0x1) {
   1329         Format(instr, "vdiv'cond.f64 'Dd, 'Dn, 'Dm");
   1330       } else {
   1331         Unknown(instr);  // Not used by V8.
   1332       }
   1333     } else {
   1334       Unknown(instr);  // Not used by V8.
   1335     }
   1336   } else {
   1337     if ((instr->VCValue() == 0x0) &&
   1338         (instr->VAValue() == 0x0)) {
   1339       DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
   1340     } else if ((instr->VLValue() == 0x0) &&
   1341                (instr->VCValue() == 0x1) &&
   1342                (instr->Bit(23) == 0x0)) {
   1343       if (instr->Bit(21) == 0x0) {
   1344         Format(instr, "vmov'cond.32 'Dd[0], 'rt");
   1345       } else {
   1346         Format(instr, "vmov'cond.32 'Dd[1], 'rt");
   1347       }
   1348     } else if ((instr->VLValue() == 0x1) &&
   1349                (instr->VCValue() == 0x1) &&
   1350                (instr->Bit(23) == 0x0)) {
   1351       if (instr->Bit(21) == 0x0) {
   1352         Format(instr, "vmov'cond.32 'rt, 'Dd[0]");
   1353       } else {
   1354         Format(instr, "vmov'cond.32 'rt, 'Dd[1]");
   1355       }
   1356     } else if ((instr->VCValue() == 0x0) &&
   1357                (instr->VAValue() == 0x7) &&
   1358                (instr->Bits(19, 16) == 0x1)) {
   1359       if (instr->VLValue() == 0) {
   1360         if (instr->Bits(15, 12) == 0xF) {
   1361           Format(instr, "vmsr'cond FPSCR, APSR");
   1362         } else {
   1363           Format(instr, "vmsr'cond FPSCR, 'rt");
   1364         }
   1365       } else {
   1366         if (instr->Bits(15, 12) == 0xF) {
   1367           Format(instr, "vmrs'cond APSR, FPSCR");
   1368         } else {
   1369           Format(instr, "vmrs'cond 'rt, FPSCR");
   1370         }
   1371       }
   1372     }
   1373   }
   1374 }
   1375 
   1376 
   1377 void Decoder::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(
   1378     Instruction* instr) {
   1379   VERIFY((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) &&
   1380          (instr->VAValue() == 0x0));
   1381 
   1382   bool to_arm_register = (instr->VLValue() == 0x1);
   1383 
   1384   if (to_arm_register) {
   1385     Format(instr, "vmov'cond 'rt, 'Sn");
   1386   } else {
   1387     Format(instr, "vmov'cond 'Sn, 'rt");
   1388   }
   1389 }
   1390 
   1391 
   1392 void Decoder::DecodeVCMP(Instruction* instr) {
   1393   VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
   1394   VERIFY(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
   1395          (instr->Opc3Value() & 0x1));
   1396 
   1397   // Comparison.
   1398   bool dp_operation = (instr->SzValue() == 1);
   1399   bool raise_exception_for_qnan = (instr->Bit(7) == 0x1);
   1400 
   1401   if (dp_operation && !raise_exception_for_qnan) {
   1402     if (instr->Opc2Value() == 0x4) {
   1403       Format(instr, "vcmp'cond.f64 'Dd, 'Dm");
   1404     } else if (instr->Opc2Value() == 0x5) {
   1405       Format(instr, "vcmp'cond.f64 'Dd, #0.0");
   1406     } else {
   1407       Unknown(instr);  // invalid
   1408     }
   1409   } else {
   1410     Unknown(instr);  // Not used by V8.
   1411   }
   1412 }
   1413 
   1414 
   1415 void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) {
   1416   VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
   1417   VERIFY((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3));
   1418 
   1419   bool double_to_single = (instr->SzValue() == 1);
   1420 
   1421   if (double_to_single) {
   1422     Format(instr, "vcvt'cond.f32.f64 'Sd, 'Dm");
   1423   } else {
   1424     Format(instr, "vcvt'cond.f64.f32 'Dd, 'Sm");
   1425   }
   1426 }
   1427 
   1428 
   1429 void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
   1430   VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
   1431   VERIFY(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) ||
   1432          (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1)));
   1433 
   1434   bool to_integer = (instr->Bit(18) == 1);
   1435   bool dp_operation = (instr->SzValue() == 1);
   1436   if (to_integer) {
   1437     bool unsigned_integer = (instr->Bit(16) == 0);
   1438 
   1439     if (dp_operation) {
   1440       if (unsigned_integer) {
   1441         Format(instr, "vcvt'cond.u32.f64 'Sd, 'Dm");
   1442       } else {
   1443         Format(instr, "vcvt'cond.s32.f64 'Sd, 'Dm");
   1444       }
   1445     } else {
   1446       if (unsigned_integer) {
   1447         Format(instr, "vcvt'cond.u32.f32 'Sd, 'Sm");
   1448       } else {
   1449         Format(instr, "vcvt'cond.s32.f32 'Sd, 'Sm");
   1450       }
   1451     }
   1452   } else {
   1453     bool unsigned_integer = (instr->Bit(7) == 0);
   1454 
   1455     if (dp_operation) {
   1456       if (unsigned_integer) {
   1457         Format(instr, "vcvt'cond.f64.u32 'Dd, 'Sm");
   1458       } else {
   1459         Format(instr, "vcvt'cond.f64.s32 'Dd, 'Sm");
   1460       }
   1461     } else {
   1462       if (unsigned_integer) {
   1463         Format(instr, "vcvt'cond.f32.u32 'Sd, 'Sm");
   1464       } else {
   1465         Format(instr, "vcvt'cond.f32.s32 'Sd, 'Sm");
   1466       }
   1467     }
   1468   }
   1469 }
   1470 
   1471 
   1472 // Decode Type 6 coprocessor instructions.
   1473 // Dm = vmov(Rt, Rt2)
   1474 // <Rt, Rt2> = vmov(Dm)
   1475 // Ddst = MEM(Rbase + 4*offset).
   1476 // MEM(Rbase + 4*offset) = Dsrc.
   1477 void Decoder::DecodeType6CoprocessorIns(Instruction* instr) {
   1478   VERIFY(instr->TypeValue() == 6);
   1479 
   1480   if (instr->CoprocessorValue() == 0xA) {
   1481     switch (instr->OpcodeValue()) {
   1482       case 0x8:
   1483       case 0xA:
   1484         if (instr->HasL()) {
   1485           Format(instr, "vldr'cond 'Sd, ['rn - 4*'imm08@00]");
   1486         } else {
   1487           Format(instr, "vstr'cond 'Sd, ['rn - 4*'imm08@00]");
   1488         }
   1489         break;
   1490       case 0xC:
   1491       case 0xE:
   1492         if (instr->HasL()) {
   1493           Format(instr, "vldr'cond 'Sd, ['rn + 4*'imm08@00]");
   1494         } else {
   1495           Format(instr, "vstr'cond 'Sd, ['rn + 4*'imm08@00]");
   1496         }
   1497         break;
   1498       case 0x4:
   1499       case 0x5:
   1500       case 0x6:
   1501       case 0x7:
   1502       case 0x9:
   1503       case 0xB: {
   1504         bool to_vfp_register = (instr->VLValue() == 0x1);
   1505         if (to_vfp_register) {
   1506           Format(instr, "vldm'cond'pu 'rn'w, {'Sd-'Sd+}");
   1507         } else {
   1508           Format(instr, "vstm'cond'pu 'rn'w, {'Sd-'Sd+}");
   1509         }
   1510         break;
   1511       }
   1512       default:
   1513         Unknown(instr);  // Not used by V8.
   1514     }
   1515   } else if (instr->CoprocessorValue() == 0xB) {
   1516     switch (instr->OpcodeValue()) {
   1517       case 0x2:
   1518         // Load and store double to two GP registers
   1519         if (instr->Bits(7, 6) != 0 || instr->Bit(4) != 1) {
   1520           Unknown(instr);  // Not used by V8.
   1521         } else if (instr->HasL()) {
   1522           Format(instr, "vmov'cond 'rt, 'rn, 'Dm");
   1523         } else {
   1524           Format(instr, "vmov'cond 'Dm, 'rt, 'rn");
   1525         }
   1526         break;
   1527       case 0x8:
   1528       case 0xA:
   1529         if (instr->HasL()) {
   1530           Format(instr, "vldr'cond 'Dd, ['rn - 4*'imm08@00]");
   1531         } else {
   1532           Format(instr, "vstr'cond 'Dd, ['rn - 4*'imm08@00]");
   1533         }
   1534         break;
   1535       case 0xC:
   1536       case 0xE:
   1537         if (instr->HasL()) {
   1538           Format(instr, "vldr'cond 'Dd, ['rn + 4*'imm08@00]");
   1539         } else {
   1540           Format(instr, "vstr'cond 'Dd, ['rn + 4*'imm08@00]");
   1541         }
   1542         break;
   1543       case 0x4:
   1544       case 0x5:
   1545       case 0x6:
   1546       case 0x7:
   1547       case 0x9:
   1548       case 0xB: {
   1549         bool to_vfp_register = (instr->VLValue() == 0x1);
   1550         if (to_vfp_register) {
   1551           Format(instr, "vldm'cond'pu 'rn'w, {'Dd-'Dd+}");
   1552         } else {
   1553           Format(instr, "vstm'cond'pu 'rn'w, {'Dd-'Dd+}");
   1554         }
   1555         break;
   1556       }
   1557       default:
   1558         Unknown(instr);  // Not used by V8.
   1559     }
   1560   } else {
   1561     Unknown(instr);  // Not used by V8.
   1562   }
   1563 }
   1564 
   1565 
   1566 void Decoder::DecodeSpecialCondition(Instruction* instr) {
   1567   switch (instr->SpecialValue()) {
   1568     case 5:
   1569       if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
   1570           (instr->Bit(4) == 1)) {
   1571         // vmovl signed
   1572         int Vd = (instr->Bit(22) << 4) | instr->VdValue();
   1573         int Vm = (instr->Bit(5) << 4) | instr->VmValue();
   1574         int imm3 = instr->Bits(21, 19);
   1575         out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
   1576                                         "vmovl.s%d q%d, d%d", imm3*8, Vd, Vm);
   1577       } else {
   1578         Unknown(instr);
   1579       }
   1580       break;
   1581     case 7:
   1582       if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
   1583           (instr->Bit(4) == 1)) {
   1584         // vmovl unsigned
   1585         int Vd = (instr->Bit(22) << 4) | instr->VdValue();
   1586         int Vm = (instr->Bit(5) << 4) | instr->VmValue();
   1587         int imm3 = instr->Bits(21, 19);
   1588         out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
   1589                                         "vmovl.u%d q%d, d%d", imm3*8, Vd, Vm);
   1590       } else {
   1591         Unknown(instr);
   1592       }
   1593       break;
   1594     case 8:
   1595       if (instr->Bits(21, 20) == 0) {
   1596         // vst1
   1597         int Vd = (instr->Bit(22) << 4) | instr->VdValue();
   1598         int Rn = instr->VnValue();
   1599         int type = instr->Bits(11, 8);
   1600         int size = instr->Bits(7, 6);
   1601         int align = instr->Bits(5, 4);
   1602         int Rm = instr->VmValue();
   1603         out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
   1604                                         "vst1.%d ", (1 << size) << 3);
   1605         FormatNeonList(Vd, type);
   1606         Print(", ");
   1607         FormatNeonMemory(Rn, align, Rm);
   1608       } else if (instr->Bits(21, 20) == 2) {
   1609         // vld1
   1610         int Vd = (instr->Bit(22) << 4) | instr->VdValue();
   1611         int Rn = instr->VnValue();
   1612         int type = instr->Bits(11, 8);
   1613         int size = instr->Bits(7, 6);
   1614         int align = instr->Bits(5, 4);
   1615         int Rm = instr->VmValue();
   1616         out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
   1617                                         "vld1.%d ", (1 << size) << 3);
   1618         FormatNeonList(Vd, type);
   1619         Print(", ");
   1620         FormatNeonMemory(Rn, align, Rm);
   1621       } else {
   1622         Unknown(instr);
   1623       }
   1624       break;
   1625     case 0xA:
   1626     case 0xB:
   1627       if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) {
   1628         int Rn = instr->Bits(19, 16);
   1629         int offset = instr->Bits(11, 0);
   1630         if (offset == 0) {
   1631           out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
   1632                                           "pld [r%d]", Rn);
   1633         } else if (instr->Bit(23) == 0) {
   1634           out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
   1635                                           "pld [r%d, #-%d]", Rn, offset);
   1636         } else {
   1637           out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
   1638                                           "pld [r%d, #+%d]", Rn, offset);
   1639         }
   1640       } else {
   1641         Unknown(instr);
   1642       }
   1643       break;
   1644     default:
   1645       Unknown(instr);
   1646       break;
   1647   }
   1648 }
   1649 
   1650 #undef VERIFIY
   1651 
   1652 bool Decoder::IsConstantPoolAt(byte* instr_ptr) {
   1653   int instruction_bits = *(reinterpret_cast<int*>(instr_ptr));
   1654   return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker;
   1655 }
   1656 
   1657 
   1658 int Decoder::ConstantPoolSizeAt(byte* instr_ptr) {
   1659   if (IsConstantPoolAt(instr_ptr)) {
   1660     int instruction_bits = *(reinterpret_cast<int*>(instr_ptr));
   1661     return DecodeConstantPoolLength(instruction_bits);
   1662   } else {
   1663     return -1;
   1664   }
   1665 }
   1666 
   1667 
   1668 // Disassemble the instruction at *instr_ptr into the output buffer.
   1669 int Decoder::InstructionDecode(byte* instr_ptr) {
   1670   Instruction* instr = Instruction::At(instr_ptr);
   1671   // Print raw instruction bytes.
   1672   out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
   1673                                   "%08x       ",
   1674                                   instr->InstructionBits());
   1675   if (instr->ConditionField() == kSpecialCondition) {
   1676     DecodeSpecialCondition(instr);
   1677     return Instruction::kInstrSize;
   1678   }
   1679   int instruction_bits = *(reinterpret_cast<int*>(instr_ptr));
   1680   if ((instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker) {
   1681     out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
   1682                                     "constant pool begin (length %d)",
   1683                                     DecodeConstantPoolLength(instruction_bits));
   1684     return Instruction::kInstrSize;
   1685   }
   1686   switch (instr->TypeValue()) {
   1687     case 0:
   1688     case 1: {
   1689       DecodeType01(instr);
   1690       break;
   1691     }
   1692     case 2: {
   1693       DecodeType2(instr);
   1694       break;
   1695     }
   1696     case 3: {
   1697       DecodeType3(instr);
   1698       break;
   1699     }
   1700     case 4: {
   1701       DecodeType4(instr);
   1702       break;
   1703     }
   1704     case 5: {
   1705       DecodeType5(instr);
   1706       break;
   1707     }
   1708     case 6: {
   1709       DecodeType6(instr);
   1710       break;
   1711     }
   1712     case 7: {
   1713       return DecodeType7(instr);
   1714     }
   1715     default: {
   1716       // The type field is 3-bits in the ARM encoding.
   1717       UNREACHABLE();
   1718       break;
   1719     }
   1720   }
   1721   return Instruction::kInstrSize;
   1722 }
   1723 
   1724 
   1725 } }  // namespace v8::internal
   1726 
   1727 
   1728 
   1729 //------------------------------------------------------------------------------
   1730 
   1731 namespace disasm {
   1732 
   1733 
   1734 const char* NameConverter::NameOfAddress(byte* addr) const {
   1735   v8::internal::OS::SNPrintF(tmp_buffer_, "%p", addr);
   1736   return tmp_buffer_.start();
   1737 }
   1738 
   1739 
   1740 const char* NameConverter::NameOfConstant(byte* addr) const {
   1741   return NameOfAddress(addr);
   1742 }
   1743 
   1744 
   1745 const char* NameConverter::NameOfCPURegister(int reg) const {
   1746   return v8::internal::Registers::Name(reg);
   1747 }
   1748 
   1749 
   1750 const char* NameConverter::NameOfByteCPURegister(int reg) const {
   1751   UNREACHABLE();  // ARM does not have the concept of a byte register
   1752   return "nobytereg";
   1753 }
   1754 
   1755 
   1756 const char* NameConverter::NameOfXMMRegister(int reg) const {
   1757   UNREACHABLE();  // ARM does not have any XMM registers
   1758   return "noxmmreg";
   1759 }
   1760 
   1761 
   1762 const char* NameConverter::NameInCode(byte* addr) const {
   1763   // The default name converter is called for unknown code. So we will not try
   1764   // to access any memory.
   1765   return "";
   1766 }
   1767 
   1768 
   1769 //------------------------------------------------------------------------------
   1770 
   1771 Disassembler::Disassembler(const NameConverter& converter)
   1772     : converter_(converter) {}
   1773 
   1774 
   1775 Disassembler::~Disassembler() {}
   1776 
   1777 
   1778 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
   1779                                     byte* instruction) {
   1780   v8::internal::Decoder d(converter_, buffer);
   1781   return d.InstructionDecode(instruction);
   1782 }
   1783 
   1784 
   1785 int Disassembler::ConstantPoolSizeAt(byte* instruction) {
   1786   return v8::internal::Decoder::ConstantPoolSizeAt(instruction);
   1787 }
   1788 
   1789 
   1790 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
   1791   NameConverter converter;
   1792   Disassembler d(converter);
   1793   for (byte* pc = begin; pc < end;) {
   1794     v8::internal::EmbeddedVector<char, 128> buffer;
   1795     buffer[0] = '\0';
   1796     byte* prev_pc = pc;
   1797     pc += d.InstructionDecode(buffer, pc);
   1798     v8::internal::PrintF(
   1799         f, "%p    %08x      %s\n",
   1800         prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
   1801   }
   1802 }
   1803 
   1804 
   1805 }  // namespace disasm
   1806 
   1807 #endif  // V8_TARGET_ARCH_ARM
   1808