• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
Decoder(const disasm::NameConverter & converter,Vector<char> out_buffer)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 
~Decoder()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.
PrintChar(const char ch)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.
Print(const char * str)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.
PrintCondition(Instruction * instr)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.
PrintRegister(int reg)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.
PrintSRegister(int reg)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.
PrintDRegister(int reg)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.
PrintShiftRm(Instruction * instr)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.
PrintShiftImm(Instruction * instr)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.
PrintShiftSat(Instruction * instr)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.
PrintPU(Instruction * instr)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.
PrintSoftwareInterrupt(SoftwareInterruptCodes svc)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.
FormatRegister(Instruction * instr,const char * format)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.
FormatVFPRegister(Instruction * instr,const char * format)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 
FormatVFPinstruction(Instruction * instr,const char * format)392 int Decoder::FormatVFPinstruction(Instruction* instr, const char* format) {
393     Print(format);
394     return 0;
395 }
396 
397 
FormatNeonList(int Vd,int type)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 
FormatNeonMemory(int Rn,int align,int Rm)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.
PrintMovwMovt(Instruction * instr)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.
FormatOption(Instruction * instr,const char * format)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.
Format(Instruction * instr,const char * format)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.
Unknown(Instruction * instr)695 void Decoder::Unknown(Instruction* instr) {
696   Format(instr, "unknown");
697 }
698 
699 
DecodeType01(Instruction * instr)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 
DecodeType2(Instruction * instr)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 
DecodeType3(Instruction * instr)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 
DecodeType4(Instruction * instr)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 
DecodeType5(Instruction * instr)1282 void Decoder::DecodeType5(Instruction* instr) {
1283   Format(instr, "b'l'cond 'target");
1284 }
1285 
1286 
DecodeType6(Instruction * instr)1287 void Decoder::DecodeType6(Instruction* instr) {
1288   DecodeType6CoprocessorIns(instr);
1289 }
1290 
1291 
DecodeType7(Instruction * instr)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
DecodeTypeVFP(Instruction * instr)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 
DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction * instr)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 
DecodeVCMP(Instruction * instr)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 
DecodeVCVTBetweenDoubleAndSingle(Instruction * instr)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 
DecodeVCVTBetweenFloatingPointAndInteger(Instruction * instr)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.
DecodeType6CoprocessorIns(Instruction * instr)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 
DecodeSpecialCondition(Instruction * instr)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 
IsConstantPoolAt(byte * instr_ptr)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 
ConstantPoolSizeAt(byte * instr_ptr)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.
InstructionDecode(byte * instr_ptr)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 
NameOfAddress(byte * addr) const1914 const char* NameConverter::NameOfAddress(byte* addr) const {
1915   v8::internal::SNPrintF(tmp_buffer_, "%p", addr);
1916   return tmp_buffer_.start();
1917 }
1918 
1919 
NameOfConstant(byte * addr) const1920 const char* NameConverter::NameOfConstant(byte* addr) const {
1921   return NameOfAddress(addr);
1922 }
1923 
1924 
NameOfCPURegister(int reg) const1925 const char* NameConverter::NameOfCPURegister(int reg) const {
1926   return v8::internal::Register::from_code(reg).ToString();
1927 }
1928 
1929 
NameOfByteCPURegister(int reg) const1930 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 
NameOfXMMRegister(int reg) const1936 const char* NameConverter::NameOfXMMRegister(int reg) const {
1937   UNREACHABLE();  // ARM does not have any XMM registers
1938   return "noxmmreg";
1939 }
1940 
1941 
NameInCode(byte * addr) const1942 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 
Disassembler(const NameConverter & converter)1951 Disassembler::Disassembler(const NameConverter& converter)
1952     : converter_(converter) {}
1953 
1954 
~Disassembler()1955 Disassembler::~Disassembler() {}
1956 
1957 
InstructionDecode(v8::internal::Vector<char> buffer,byte * instruction)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 
ConstantPoolSizeAt(byte * instruction)1965 int Disassembler::ConstantPoolSizeAt(byte* instruction) {
1966   return v8::internal::Decoder::ConstantPoolSizeAt(instruction);
1967 }
1968 
1969 
Disassemble(FILE * f,byte * begin,byte * end)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