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