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