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