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