1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// A Disassembler object is used to disassemble a block of code instruction by
6// instruction. The default implementation of the NameConverter object can be
7// overriden to modify register names or to do symbol lookup on addresses.
8//
9// The example below will disassemble a block of code and print it to stdout.
10//
11//   NameConverter converter;
12//   Disassembler d(converter);
13//   for (byte* pc = begin; pc < end;) {
14//     v8::internal::EmbeddedVector<char, 256> buffer;
15//     byte* prev_pc = pc;
16//     pc += d.InstructionDecode(buffer, pc);
17//     printf("%p    %08x      %s\n",
18//            prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
19//   }
20//
21// The Disassembler class also has a convenience method to disassemble a block
22// of code into a FILE*, meaning that the above functionality could also be
23// achieved by just calling Disassembler::Disassemble(stdout, begin, end);
24
25
26#include <assert.h>
27#include <stdarg.h>
28#include <stdio.h>
29#include <string.h>
30
31#if V8_TARGET_ARCH_PPC
32
33#include "src/base/platform/platform.h"
34#include "src/disasm.h"
35#include "src/macro-assembler.h"
36#include "src/ppc/constants-ppc.h"
37
38
39namespace v8 {
40namespace internal {
41
42const auto GetRegConfig = RegisterConfiguration::Crankshaft;
43
44//------------------------------------------------------------------------------
45
46// Decoder decodes and disassembles instructions into an output buffer.
47// It uses the converter to convert register names and call destinations into
48// more informative description.
49class Decoder {
50 public:
51  Decoder(const disasm::NameConverter& converter, Vector<char> out_buffer)
52      : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) {
53    out_buffer_[out_buffer_pos_] = '\0';
54  }
55
56  ~Decoder() {}
57
58  // Writes one disassembled instruction into 'buffer' (0-terminated).
59  // Returns the length of the disassembled machine instruction in bytes.
60  int InstructionDecode(byte* instruction);
61
62 private:
63  // Bottleneck functions to print into the out_buffer.
64  void PrintChar(const char ch);
65  void Print(const char* str);
66
67  // Printing of common values.
68  void PrintRegister(int reg);
69  void PrintDRegister(int reg);
70  int FormatFPRegister(Instruction* instr, const char* format);
71  void PrintSoftwareInterrupt(SoftwareInterruptCodes svc);
72
73  // Handle formatting of instructions and their options.
74  int FormatRegister(Instruction* instr, const char* option);
75  int FormatOption(Instruction* instr, const char* option);
76  void Format(Instruction* instr, const char* format);
77  void Unknown(Instruction* instr);
78  void UnknownFormat(Instruction* instr, const char* opcname);
79
80  void DecodeExt1(Instruction* instr);
81  void DecodeExt2(Instruction* instr);
82  void DecodeExt3(Instruction* instr);
83  void DecodeExt4(Instruction* instr);
84  void DecodeExt5(Instruction* instr);
85  void DecodeExt6(Instruction* instr);
86
87  const disasm::NameConverter& converter_;
88  Vector<char> out_buffer_;
89  int out_buffer_pos_;
90
91  DISALLOW_COPY_AND_ASSIGN(Decoder);
92};
93
94
95// Support for assertions in the Decoder formatting functions.
96#define STRING_STARTS_WITH(string, compare_string) \
97  (strncmp(string, compare_string, strlen(compare_string)) == 0)
98
99
100// Append the ch to the output buffer.
101void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
102
103
104// Append the str to the output buffer.
105void Decoder::Print(const char* str) {
106  char cur = *str++;
107  while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
108    PrintChar(cur);
109    cur = *str++;
110  }
111  out_buffer_[out_buffer_pos_] = 0;
112}
113
114
115// Print the register name according to the active name converter.
116void Decoder::PrintRegister(int reg) {
117  Print(converter_.NameOfCPURegister(reg));
118}
119
120
121// Print the double FP register name according to the active name converter.
122void Decoder::PrintDRegister(int reg) {
123  Print(GetRegConfig()->GetDoubleRegisterName(reg));
124}
125
126
127// Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
128// the FormatOption method.
129void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) {
130  switch (svc) {
131    case kCallRtRedirected:
132      Print("call rt redirected");
133      return;
134    case kBreakpoint:
135      Print("breakpoint");
136      return;
137    default:
138      if (svc >= kStopCode) {
139        out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d - 0x%x",
140                                    svc & kStopCodeMask, svc & kStopCodeMask);
141      } else {
142        out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", svc);
143      }
144      return;
145  }
146}
147
148
149// Handle all register based formatting in this function to reduce the
150// complexity of FormatOption.
151int Decoder::FormatRegister(Instruction* instr, const char* format) {
152  DCHECK(format[0] == 'r');
153
154  if ((format[1] == 't') || (format[1] == 's')) {  // 'rt & 'rs register
155    int reg = instr->RTValue();
156    PrintRegister(reg);
157    return 2;
158  } else if (format[1] == 'a') {  // 'ra: RA register
159    int reg = instr->RAValue();
160    PrintRegister(reg);
161    return 2;
162  } else if (format[1] == 'b') {  // 'rb: RB register
163    int reg = instr->RBValue();
164    PrintRegister(reg);
165    return 2;
166  }
167
168  UNREACHABLE();
169  return -1;
170}
171
172
173// Handle all FP register based formatting in this function to reduce the
174// complexity of FormatOption.
175int Decoder::FormatFPRegister(Instruction* instr, const char* format) {
176  DCHECK(format[0] == 'D');
177
178  int retval = 2;
179  int reg = -1;
180  if (format[1] == 't') {
181    reg = instr->RTValue();
182  } else if (format[1] == 'a') {
183    reg = instr->RAValue();
184  } else if (format[1] == 'b') {
185    reg = instr->RBValue();
186  } else if (format[1] == 'c') {
187    reg = instr->RCValue();
188  } else {
189    UNREACHABLE();
190  }
191
192  PrintDRegister(reg);
193
194  return retval;
195}
196
197
198// FormatOption takes a formatting string and interprets it based on
199// the current instructions. The format string points to the first
200// character of the option string (the option escape has already been
201// consumed by the caller.)  FormatOption returns the number of
202// characters that were consumed from the formatting string.
203int Decoder::FormatOption(Instruction* instr, const char* format) {
204  switch (format[0]) {
205    case 'o': {
206      if (instr->Bit(10) == 1) {
207        Print("o");
208      }
209      return 1;
210    }
211    case '.': {
212      if (instr->Bit(0) == 1) {
213        Print(".");
214      } else {
215        Print(" ");  // ensure consistent spacing
216      }
217      return 1;
218    }
219    case 'r': {
220      return FormatRegister(instr, format);
221    }
222    case 'D': {
223      return FormatFPRegister(instr, format);
224    }
225    case 'i': {  // int16
226      int32_t value = (instr->Bits(15, 0) << 16) >> 16;
227      out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
228      return 5;
229    }
230    case 'u': {  // uint16
231      int32_t value = instr->Bits(15, 0);
232      out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
233      return 6;
234    }
235    case 'l': {
236      // Link (LK) Bit 0
237      if (instr->Bit(0) == 1) {
238        Print("l");
239      }
240      return 1;
241    }
242    case 'a': {
243      // Absolute Address Bit 1
244      if (instr->Bit(1) == 1) {
245        Print("a");
246      }
247      return 1;
248    }
249    case 'c': {  // 'cr: condition register of branch instruction
250      int code = instr->Bits(20, 18);
251      if (code != 7) {
252        out_buffer_pos_ +=
253            SNPrintF(out_buffer_ + out_buffer_pos_, " cr%d", code);
254      }
255      return 2;
256    }
257    case 't': {  // 'target: target of branch instructions
258      // target26 or target16
259      DCHECK(STRING_STARTS_WITH(format, "target"));
260      if ((format[6] == '2') && (format[7] == '6')) {
261        int off = ((instr->Bits(25, 2)) << 8) >> 6;
262        out_buffer_pos_ += SNPrintF(
263            out_buffer_ + out_buffer_pos_, "%+d -> %s", off,
264            converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off));
265        return 8;
266      } else if ((format[6] == '1') && (format[7] == '6')) {
267        int off = ((instr->Bits(15, 2)) << 18) >> 16;
268        out_buffer_pos_ += SNPrintF(
269            out_buffer_ + out_buffer_pos_, "%+d -> %s", off,
270            converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off));
271        return 8;
272      }
273      case 's': {
274        DCHECK(format[1] == 'h');
275        int32_t value = 0;
276        int32_t opcode = instr->OpcodeValue() << 26;
277        int32_t sh = instr->Bits(15, 11);
278        if (opcode == EXT5 ||
279            (opcode == EXT2 && instr->Bits(10, 2) << 2 == SRADIX)) {
280          // SH Bits 1 and 15-11 (split field)
281          value = (sh | (instr->Bit(1) << 5));
282        } else {
283          // SH Bits 15-11
284          value = (sh << 26) >> 26;
285        }
286        out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
287        return 2;
288      }
289      case 'm': {
290        int32_t value = 0;
291        if (format[1] == 'e') {
292          if (instr->OpcodeValue() << 26 != EXT5) {
293            // ME Bits 10-6
294            value = (instr->Bits(10, 6) << 26) >> 26;
295          } else {
296            // ME Bits 5 and 10-6 (split field)
297            value = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
298          }
299        } else if (format[1] == 'b') {
300          if (instr->OpcodeValue() << 26 != EXT5) {
301            // MB Bits 5-1
302            value = (instr->Bits(5, 1) << 26) >> 26;
303          } else {
304            // MB Bits 5 and 10-6 (split field)
305            value = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
306          }
307        } else {
308          UNREACHABLE();  // bad format
309        }
310        out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
311        return 2;
312      }
313    }
314#if V8_TARGET_ARCH_PPC64
315    case 'd': {  // ds value for offset
316      int32_t value = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3);
317      out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
318      return 1;
319    }
320#endif
321    default: {
322      UNREACHABLE();
323      break;
324    }
325  }
326
327  UNREACHABLE();
328  return -1;
329}
330
331
332// Format takes a formatting string for a whole instruction and prints it into
333// the output buffer. All escaped options are handed to FormatOption to be
334// parsed further.
335void Decoder::Format(Instruction* instr, const char* format) {
336  char cur = *format++;
337  while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
338    if (cur == '\'') {  // Single quote is used as the formatting escape.
339      format += FormatOption(instr, format);
340    } else {
341      out_buffer_[out_buffer_pos_++] = cur;
342    }
343    cur = *format++;
344  }
345  out_buffer_[out_buffer_pos_] = '\0';
346}
347
348
349// The disassembler may end up decoding data inlined in the code. We do not want
350// it to crash if the data does not ressemble any known instruction.
351#define VERIFY(condition) \
352  if (!(condition)) {     \
353    Unknown(instr);       \
354    return;               \
355  }
356
357
358// For currently unimplemented decodings the disassembler calls Unknown(instr)
359// which will just print "unknown" of the instruction bits.
360void Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); }
361
362
363// For currently unimplemented decodings the disassembler calls
364// UnknownFormat(instr) which will just print opcode name of the
365// instruction bits.
366void Decoder::UnknownFormat(Instruction* instr, const char* name) {
367  char buffer[100];
368  snprintf(buffer, sizeof(buffer), "%s (unknown-format)", name);
369  Format(instr, buffer);
370}
371
372
373void Decoder::DecodeExt1(Instruction* instr) {
374  switch (EXT1 | (instr->BitField(10, 1))) {
375    case MCRF: {
376      UnknownFormat(instr, "mcrf");  // not used by V8
377      break;
378    }
379    case BCLRX: {
380      int bo = instr->BitField(25, 21);
381      int bi = instr->Bits(20, 16);
382      CRBit cond = static_cast<CRBit>(bi & (CRWIDTH - 1));
383      switch (bo) {
384        case DCBNZF: {
385          UnknownFormat(instr, "bclrx-dcbnzf");
386          break;
387        }
388        case DCBEZF: {
389          UnknownFormat(instr, "bclrx-dcbezf");
390          break;
391        }
392        case BF: {
393          switch (cond) {
394            case CR_EQ:
395              Format(instr, "bnelr'l'cr");
396              break;
397            case CR_GT:
398              Format(instr, "blelr'l'cr");
399              break;
400            case CR_LT:
401              Format(instr, "bgelr'l'cr");
402              break;
403            case CR_SO:
404              Format(instr, "bnsolr'l'cr");
405              break;
406          }
407          break;
408        }
409        case DCBNZT: {
410          UnknownFormat(instr, "bclrx-dcbbzt");
411          break;
412        }
413        case DCBEZT: {
414          UnknownFormat(instr, "bclrx-dcbnezt");
415          break;
416        }
417        case BT: {
418          switch (cond) {
419            case CR_EQ:
420              Format(instr, "beqlr'l'cr");
421              break;
422            case CR_GT:
423              Format(instr, "bgtlr'l'cr");
424              break;
425            case CR_LT:
426              Format(instr, "bltlr'l'cr");
427              break;
428            case CR_SO:
429              Format(instr, "bsolr'l'cr");
430              break;
431          }
432          break;
433        }
434        case DCBNZ: {
435          UnknownFormat(instr, "bclrx-dcbnz");
436          break;
437        }
438        case DCBEZ: {
439          UnknownFormat(instr, "bclrx-dcbez");  // not used by V8
440          break;
441        }
442        case BA: {
443          Format(instr, "blr'l");
444          break;
445        }
446      }
447      break;
448    }
449    case BCCTRX: {
450      switch (instr->BitField(25, 21)) {
451        case DCBNZF: {
452          UnknownFormat(instr, "bcctrx-dcbnzf");
453          break;
454        }
455        case DCBEZF: {
456          UnknownFormat(instr, "bcctrx-dcbezf");
457          break;
458        }
459        case BF: {
460          UnknownFormat(instr, "bcctrx-bf");
461          break;
462        }
463        case DCBNZT: {
464          UnknownFormat(instr, "bcctrx-dcbnzt");
465          break;
466        }
467        case DCBEZT: {
468          UnknownFormat(instr, "bcctrx-dcbezf");
469          break;
470        }
471        case BT: {
472          UnknownFormat(instr, "bcctrx-bt");
473          break;
474        }
475        case DCBNZ: {
476          UnknownFormat(instr, "bcctrx-dcbnz");
477          break;
478        }
479        case DCBEZ: {
480          UnknownFormat(instr, "bcctrx-dcbez");
481          break;
482        }
483        case BA: {
484          if (instr->Bit(0) == 1) {
485            Format(instr, "bctrl");
486          } else {
487            Format(instr, "bctr");
488          }
489          break;
490        }
491        default: { UNREACHABLE(); }
492      }
493      break;
494    }
495    case CRNOR: {
496      Format(instr, "crnor (stuff)");
497      break;
498    }
499    case RFI: {
500      Format(instr, "rfi (stuff)");
501      break;
502    }
503    case CRANDC: {
504      Format(instr, "crandc (stuff)");
505      break;
506    }
507    case ISYNC: {
508      Format(instr, "isync (stuff)");
509      break;
510    }
511    case CRXOR: {
512      Format(instr, "crxor (stuff)");
513      break;
514    }
515    case CRNAND: {
516      UnknownFormat(instr, "crnand");
517      break;
518    }
519    case CRAND: {
520      UnknownFormat(instr, "crand");
521      break;
522    }
523    case CREQV: {
524      UnknownFormat(instr, "creqv");
525      break;
526    }
527    case CRORC: {
528      UnknownFormat(instr, "crorc");
529      break;
530    }
531    case CROR: {
532      UnknownFormat(instr, "cror");
533      break;
534    }
535    default: {
536      Unknown(instr);  // not used by V8
537    }
538  }
539}
540
541
542void Decoder::DecodeExt2(Instruction* instr) {
543  // Some encodings are 10-1 bits, handle those first
544  switch (EXT2 | (instr->BitField(10, 1))) {
545    case SRWX: {
546      Format(instr, "srw'.    'ra, 'rs, 'rb");
547      return;
548    }
549#if V8_TARGET_ARCH_PPC64
550    case SRDX: {
551      Format(instr, "srd'.    'ra, 'rs, 'rb");
552      return;
553    }
554#endif
555    case SRAW: {
556      Format(instr, "sraw'.   'ra, 'rs, 'rb");
557      return;
558    }
559#if V8_TARGET_ARCH_PPC64
560    case SRAD: {
561      Format(instr, "srad'.   'ra, 'rs, 'rb");
562      return;
563    }
564#endif
565    case MODSW: {
566      Format(instr, "modsw  'rt, 'ra, 'rb");
567      return;
568    }
569    case MODUW: {
570      Format(instr, "moduw  'rt, 'ra, 'rb");
571      return;
572    }
573#if V8_TARGET_ARCH_PPC64
574    case MODSD: {
575      Format(instr, "modsd  'rt, 'ra, 'rb");
576      return;
577    }
578    case MODUD: {
579      Format(instr, "modud  'rt, 'ra, 'rb");
580      return;
581    }
582#endif
583    case SRAWIX: {
584      Format(instr, "srawi'.  'ra,'rs,'sh");
585      return;
586    }
587    case EXTSH: {
588      Format(instr, "extsh'.  'ra, 'rs");
589      return;
590    }
591#if V8_TARGET_ARCH_PPC64
592    case EXTSW: {
593      Format(instr, "extsw'.  'ra, 'rs");
594      return;
595    }
596#endif
597    case EXTSB: {
598      Format(instr, "extsb'.  'ra, 'rs");
599      return;
600    }
601    case LFSX: {
602      Format(instr, "lfsx    'rt, 'ra, 'rb");
603      return;
604    }
605    case LFSUX: {
606      Format(instr, "lfsux   'rt, 'ra, 'rb");
607      return;
608    }
609    case LFDX: {
610      Format(instr, "lfdx    'rt, 'ra, 'rb");
611      return;
612    }
613    case LFDUX: {
614      Format(instr, "lfdux   'rt, 'ra, 'rb");
615      return;
616    }
617    case STFSX: {
618      Format(instr, "stfsx    'rs, 'ra, 'rb");
619      return;
620    }
621    case STFSUX: {
622      Format(instr, "stfsux   'rs, 'ra, 'rb");
623      return;
624    }
625    case STFDX: {
626      Format(instr, "stfdx    'rs, 'ra, 'rb");
627      return;
628    }
629    case STFDUX: {
630      Format(instr, "stfdux   'rs, 'ra, 'rb");
631      return;
632    }
633    case POPCNTW: {
634      Format(instr, "popcntw  'ra, 'rs");
635      return;
636    }
637#if V8_TARGET_ARCH_PPC64
638    case POPCNTD: {
639      Format(instr, "popcntd  'ra, 'rs");
640      return;
641    }
642#endif
643  }
644
645  switch (EXT2 | (instr->BitField(10, 2))) {
646    case SRADIX: {
647      Format(instr, "sradi'.  'ra,'rs,'sh");
648      return;
649    }
650  }
651
652  // ?? are all of these xo_form?
653  switch (EXT2 | (instr->BitField(9, 1))) {
654    case CMP: {
655#if V8_TARGET_ARCH_PPC64
656      if (instr->Bit(21)) {
657#endif
658        Format(instr, "cmp     'ra, 'rb");
659#if V8_TARGET_ARCH_PPC64
660      } else {
661        Format(instr, "cmpw    'ra, 'rb");
662      }
663#endif
664      return;
665    }
666    case SLWX: {
667      Format(instr, "slw'.   'ra, 'rs, 'rb");
668      return;
669    }
670#if V8_TARGET_ARCH_PPC64
671    case SLDX: {
672      Format(instr, "sld'.   'ra, 'rs, 'rb");
673      return;
674    }
675#endif
676    case SUBFCX: {
677      Format(instr, "subfc'. 'rt, 'ra, 'rb");
678      return;
679    }
680    case SUBFEX: {
681      Format(instr, "subfe'. 'rt, 'ra, 'rb");
682      return;
683    }
684    case ADDCX: {
685      Format(instr, "addc'.   'rt, 'ra, 'rb");
686      return;
687    }
688    case ADDEX: {
689      Format(instr, "adde'.   'rt, 'ra, 'rb");
690      return;
691    }
692    case CNTLZWX: {
693      Format(instr, "cntlzw'. 'ra, 'rs");
694      return;
695    }
696#if V8_TARGET_ARCH_PPC64
697    case CNTLZDX: {
698      Format(instr, "cntlzd'. 'ra, 'rs");
699      return;
700    }
701#endif
702    case ANDX: {
703      Format(instr, "and'.    'ra, 'rs, 'rb");
704      return;
705    }
706    case ANDCX: {
707      Format(instr, "andc'.   'ra, 'rs, 'rb");
708      return;
709    }
710    case CMPL: {
711#if V8_TARGET_ARCH_PPC64
712      if (instr->Bit(21)) {
713#endif
714        Format(instr, "cmpl    'ra, 'rb");
715#if V8_TARGET_ARCH_PPC64
716      } else {
717        Format(instr, "cmplw   'ra, 'rb");
718      }
719#endif
720      return;
721    }
722    case NEGX: {
723      Format(instr, "neg'.    'rt, 'ra");
724      return;
725    }
726    case NORX: {
727      Format(instr, "nor'.    'rt, 'ra, 'rb");
728      return;
729    }
730    case SUBFX: {
731      Format(instr, "subf'.   'rt, 'ra, 'rb");
732      return;
733    }
734    case MULHWX: {
735      Format(instr, "mulhw'o'.  'rt, 'ra, 'rb");
736      return;
737    }
738    case ADDZEX: {
739      Format(instr, "addze'.   'rt, 'ra");
740      return;
741    }
742    case MULLW: {
743      Format(instr, "mullw'o'.  'rt, 'ra, 'rb");
744      return;
745    }
746#if V8_TARGET_ARCH_PPC64
747    case MULLD: {
748      Format(instr, "mulld'o'.  'rt, 'ra, 'rb");
749      return;
750    }
751#endif
752    case DIVW: {
753      Format(instr, "divw'o'.   'rt, 'ra, 'rb");
754      return;
755    }
756    case DIVWU: {
757      Format(instr, "divwu'o'.  'rt, 'ra, 'rb");
758      return;
759    }
760#if V8_TARGET_ARCH_PPC64
761    case DIVD: {
762      Format(instr, "divd'o'.   'rt, 'ra, 'rb");
763      return;
764    }
765#endif
766    case ADDX: {
767      Format(instr, "add'o     'rt, 'ra, 'rb");
768      return;
769    }
770    case XORX: {
771      Format(instr, "xor'.    'ra, 'rs, 'rb");
772      return;
773    }
774    case ORX: {
775      if (instr->RTValue() == instr->RBValue()) {
776        Format(instr, "mr      'ra, 'rb");
777      } else {
778        Format(instr, "or      'ra, 'rs, 'rb");
779      }
780      return;
781    }
782    case MFSPR: {
783      int spr = instr->Bits(20, 11);
784      if (256 == spr) {
785        Format(instr, "mflr    'rt");
786      } else {
787        Format(instr, "mfspr   'rt ??");
788      }
789      return;
790    }
791    case MTSPR: {
792      int spr = instr->Bits(20, 11);
793      if (256 == spr) {
794        Format(instr, "mtlr    'rt");
795      } else if (288 == spr) {
796        Format(instr, "mtctr   'rt");
797      } else {
798        Format(instr, "mtspr   'rt ??");
799      }
800      return;
801    }
802    case MFCR: {
803      Format(instr, "mfcr    'rt");
804      return;
805    }
806    case STWX: {
807      Format(instr, "stwx    'rs, 'ra, 'rb");
808      return;
809    }
810    case STWUX: {
811      Format(instr, "stwux   'rs, 'ra, 'rb");
812      return;
813    }
814    case STBX: {
815      Format(instr, "stbx    'rs, 'ra, 'rb");
816      return;
817    }
818    case STBUX: {
819      Format(instr, "stbux   'rs, 'ra, 'rb");
820      return;
821    }
822    case STHX: {
823      Format(instr, "sthx    'rs, 'ra, 'rb");
824      return;
825    }
826    case STHUX: {
827      Format(instr, "sthux   'rs, 'ra, 'rb");
828      return;
829    }
830    case LWZX: {
831      Format(instr, "lwzx    'rt, 'ra, 'rb");
832      return;
833    }
834    case LWZUX: {
835      Format(instr, "lwzux   'rt, 'ra, 'rb");
836      return;
837    }
838    case LWAX: {
839      Format(instr, "lwax    'rt, 'ra, 'rb");
840      return;
841    }
842    case LBZX: {
843      Format(instr, "lbzx    'rt, 'ra, 'rb");
844      return;
845    }
846    case LBZUX: {
847      Format(instr, "lbzux   'rt, 'ra, 'rb");
848      return;
849    }
850    case LHZX: {
851      Format(instr, "lhzx    'rt, 'ra, 'rb");
852      return;
853    }
854    case LHZUX: {
855      Format(instr, "lhzux   'rt, 'ra, 'rb");
856      return;
857    }
858    case LHAX: {
859      Format(instr, "lhax    'rt, 'ra, 'rb");
860      return;
861    }
862#if V8_TARGET_ARCH_PPC64
863    case LDX: {
864      Format(instr, "ldx     'rt, 'ra, 'rb");
865      return;
866    }
867    case LDUX: {
868      Format(instr, "ldux    'rt, 'ra, 'rb");
869      return;
870    }
871    case STDX: {
872      Format(instr, "stdx    'rt, 'ra, 'rb");
873      return;
874    }
875    case STDUX: {
876      Format(instr, "stdux   'rt, 'ra, 'rb");
877      return;
878    }
879    case MFVSRD: {
880      Format(instr, "mffprd  'ra, 'Dt");
881      return;
882    }
883    case MFVSRWZ: {
884      Format(instr, "mffprwz 'ra, 'Dt");
885      return;
886    }
887    case MTVSRD: {
888      Format(instr, "mtfprd  'Dt, 'ra");
889      return;
890    }
891    case MTVSRWA: {
892      Format(instr, "mtfprwa 'Dt, 'ra");
893      return;
894    }
895    case MTVSRWZ: {
896      Format(instr, "mtfprwz 'Dt, 'ra");
897      return;
898    }
899#endif
900  }
901
902  switch (EXT2 | (instr->BitField(5, 1))) {
903    case ISEL: {
904      Format(instr, "isel    'rt, 'ra, 'rb");
905      return;
906    }
907    default: {
908      Unknown(instr);  // not used by V8
909    }
910  }
911}
912
913
914void Decoder::DecodeExt3(Instruction* instr) {
915  switch (EXT3 | (instr->BitField(10, 1))) {
916    case FCFID: {
917      Format(instr, "fcfids'. 'Dt, 'Db");
918      break;
919    }
920    case FCFIDU: {
921      Format(instr, "fcfidus'.'Dt, 'Db");
922      break;
923    }
924    default: {
925      Unknown(instr);  // not used by V8
926    }
927  }
928}
929
930
931void Decoder::DecodeExt4(Instruction* instr) {
932  switch (EXT4 | (instr->BitField(5, 1))) {
933    case FDIV: {
934      Format(instr, "fdiv'.   'Dt, 'Da, 'Db");
935      return;
936    }
937    case FSUB: {
938      Format(instr, "fsub'.   'Dt, 'Da, 'Db");
939      return;
940    }
941    case FADD: {
942      Format(instr, "fadd'.   'Dt, 'Da, 'Db");
943      return;
944    }
945    case FSQRT: {
946      Format(instr, "fsqrt'.  'Dt, 'Db");
947      return;
948    }
949    case FSEL: {
950      Format(instr, "fsel'.   'Dt, 'Da, 'Dc, 'Db");
951      return;
952    }
953    case FMUL: {
954      Format(instr, "fmul'.   'Dt, 'Da, 'Dc");
955      return;
956    }
957    case FMSUB: {
958      Format(instr, "fmsub'.  'Dt, 'Da, 'Dc, 'Db");
959      return;
960    }
961    case FMADD: {
962      Format(instr, "fmadd'.  'Dt, 'Da, 'Dc, 'Db");
963      return;
964    }
965  }
966
967  switch (EXT4 | (instr->BitField(10, 1))) {
968    case FCMPU: {
969      Format(instr, "fcmpu   'Da, 'Db");
970      break;
971    }
972    case FRSP: {
973      Format(instr, "frsp'.   'Dt, 'Db");
974      break;
975    }
976    case FCFID: {
977      Format(instr, "fcfid'.  'Dt, 'Db");
978      break;
979    }
980    case FCFIDU: {
981      Format(instr, "fcfidu'. 'Dt, 'Db");
982      break;
983    }
984    case FCTID: {
985      Format(instr, "fctid   'Dt, 'Db");
986      break;
987    }
988    case FCTIDZ: {
989      Format(instr, "fctidz  'Dt, 'Db");
990      break;
991    }
992    case FCTIDU: {
993      Format(instr, "fctidu  'Dt, 'Db");
994      break;
995    }
996    case FCTIDUZ: {
997      Format(instr, "fctiduz 'Dt, 'Db");
998      break;
999    }
1000    case FCTIW: {
1001      Format(instr, "fctiw'. 'Dt, 'Db");
1002      break;
1003    }
1004    case FCTIWZ: {
1005      Format(instr, "fctiwz'. 'Dt, 'Db");
1006      break;
1007    }
1008    case FMR: {
1009      Format(instr, "fmr'.    'Dt, 'Db");
1010      break;
1011    }
1012    case MTFSFI: {
1013      Format(instr, "mtfsfi'.  ?,?");
1014      break;
1015    }
1016    case MFFS: {
1017      Format(instr, "mffs'.   'Dt");
1018      break;
1019    }
1020    case MTFSF: {
1021      Format(instr, "mtfsf'.  'Db ?,?,?");
1022      break;
1023    }
1024    case FABS: {
1025      Format(instr, "fabs'.   'Dt, 'Db");
1026      break;
1027    }
1028    case FRIN: {
1029      Format(instr, "frin.   'Dt, 'Db");
1030      break;
1031    }
1032    case FRIZ: {
1033      Format(instr, "friz.   'Dt, 'Db");
1034      break;
1035    }
1036    case FRIP: {
1037      Format(instr, "frip.   'Dt, 'Db");
1038      break;
1039    }
1040    case FRIM: {
1041      Format(instr, "frim.   'Dt, 'Db");
1042      break;
1043    }
1044    case FNEG: {
1045      Format(instr, "fneg'.   'Dt, 'Db");
1046      break;
1047    }
1048    case MCRFS: {
1049      Format(instr, "mcrfs   ?,?");
1050      break;
1051    }
1052    case MTFSB0: {
1053      Format(instr, "mtfsb0'. ?");
1054      break;
1055    }
1056    case MTFSB1: {
1057      Format(instr, "mtfsb1'. ?");
1058      break;
1059    }
1060    default: {
1061      Unknown(instr);  // not used by V8
1062    }
1063  }
1064}
1065
1066
1067void Decoder::DecodeExt5(Instruction* instr) {
1068  switch (EXT5 | (instr->BitField(4, 2))) {
1069    case RLDICL: {
1070      Format(instr, "rldicl'. 'ra, 'rs, 'sh, 'mb");
1071      return;
1072    }
1073    case RLDICR: {
1074      Format(instr, "rldicr'. 'ra, 'rs, 'sh, 'me");
1075      return;
1076    }
1077    case RLDIC: {
1078      Format(instr, "rldic'.  'ra, 'rs, 'sh, 'mb");
1079      return;
1080    }
1081    case RLDIMI: {
1082      Format(instr, "rldimi'. 'ra, 'rs, 'sh, 'mb");
1083      return;
1084    }
1085  }
1086  switch (EXT5 | (instr->BitField(4, 1))) {
1087    case RLDCL: {
1088      Format(instr, "rldcl'.  'ra, 'rs, 'sb, 'mb");
1089      return;
1090    }
1091  }
1092  Unknown(instr);  // not used by V8
1093}
1094
1095void Decoder::DecodeExt6(Instruction* instr) {
1096  switch (EXT6 | (instr->BitField(10, 3))) {
1097#define DECODE_XX3_INSTRUCTIONS(name, opcode_name, opcode_value) \
1098  case opcode_name: {                                            \
1099    Format(instr, #name" 'Dt, 'Da, 'Db");                        \
1100    return;                                                      \
1101  }
1102    PPC_XX3_OPCODE_LIST(DECODE_XX3_INSTRUCTIONS)
1103#undef DECODE_XX3_INSTRUCTIONS
1104  }
1105  switch (EXT6 | (instr->BitField(10, 2))) {
1106#define DECODE_XX2_INSTRUCTIONS(name, opcode_name, opcode_value) \
1107  case opcode_name: {                                            \
1108    Format(instr, #name" 'Dt, 'Db");                             \
1109    return;                                                      \
1110  }
1111    PPC_XX2_OPCODE_LIST(DECODE_XX2_INSTRUCTIONS)
1112  }
1113#undef DECODE_XX3_INSTRUCTIONS
1114  Unknown(instr);  // not used by V8
1115}
1116
1117#undef VERIFIY
1118
1119// Disassemble the instruction at *instr_ptr into the output buffer.
1120int Decoder::InstructionDecode(byte* instr_ptr) {
1121  Instruction* instr = Instruction::At(instr_ptr);
1122  // Print raw instruction bytes.
1123  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%08x       ",
1124                              instr->InstructionBits());
1125
1126  if (ABI_USES_FUNCTION_DESCRIPTORS && instr->InstructionBits() == 0) {
1127    // The first field will be identified as a jump table entry.  We
1128    // emit the rest of the structure as zero, so just skip past them.
1129    Format(instr, "constant");
1130    return Instruction::kInstrSize;
1131  }
1132
1133  uint32_t opcode = instr->OpcodeValue() << 26;
1134  switch (opcode) {
1135    case TWI: {
1136      PrintSoftwareInterrupt(instr->SvcValue());
1137      break;
1138    }
1139    case MULLI: {
1140      UnknownFormat(instr, "mulli");
1141      break;
1142    }
1143    case SUBFIC: {
1144      Format(instr, "subfic  'rt, 'ra, 'int16");
1145      break;
1146    }
1147    case CMPLI: {
1148#if V8_TARGET_ARCH_PPC64
1149      if (instr->Bit(21)) {
1150#endif
1151        Format(instr, "cmpli   'ra, 'uint16");
1152#if V8_TARGET_ARCH_PPC64
1153      } else {
1154        Format(instr, "cmplwi  'ra, 'uint16");
1155      }
1156#endif
1157      break;
1158    }
1159    case CMPI: {
1160#if V8_TARGET_ARCH_PPC64
1161      if (instr->Bit(21)) {
1162#endif
1163        Format(instr, "cmpi    'ra, 'int16");
1164#if V8_TARGET_ARCH_PPC64
1165      } else {
1166        Format(instr, "cmpwi   'ra, 'int16");
1167      }
1168#endif
1169      break;
1170    }
1171    case ADDIC: {
1172      Format(instr, "addic   'rt, 'ra, 'int16");
1173      break;
1174    }
1175    case ADDICx: {
1176      UnknownFormat(instr, "addicx");
1177      break;
1178    }
1179    case ADDI: {
1180      if (instr->RAValue() == 0) {
1181        // this is load immediate
1182        Format(instr, "li      'rt, 'int16");
1183      } else {
1184        Format(instr, "addi    'rt, 'ra, 'int16");
1185      }
1186      break;
1187    }
1188    case ADDIS: {
1189      if (instr->RAValue() == 0) {
1190        Format(instr, "lis     'rt, 'int16");
1191      } else {
1192        Format(instr, "addis   'rt, 'ra, 'int16");
1193      }
1194      break;
1195    }
1196    case BCX: {
1197      int bo = instr->Bits(25, 21) << 21;
1198      int bi = instr->Bits(20, 16);
1199      CRBit cond = static_cast<CRBit>(bi & (CRWIDTH - 1));
1200      switch (bo) {
1201        case BT: {  // Branch if condition true
1202          switch (cond) {
1203            case CR_EQ:
1204              Format(instr, "beq'l'a'cr 'target16");
1205              break;
1206            case CR_GT:
1207              Format(instr, "bgt'l'a'cr 'target16");
1208              break;
1209            case CR_LT:
1210              Format(instr, "blt'l'a'cr 'target16");
1211              break;
1212            case CR_SO:
1213              Format(instr, "bso'l'a'cr 'target16");
1214              break;
1215          }
1216          break;
1217        }
1218        case BF: {  // Branch if condition false
1219          switch (cond) {
1220            case CR_EQ:
1221              Format(instr, "bne'l'a'cr 'target16");
1222              break;
1223            case CR_GT:
1224              Format(instr, "ble'l'a'cr 'target16");
1225              break;
1226            case CR_LT:
1227              Format(instr, "bge'l'a'cr 'target16");
1228              break;
1229            case CR_SO:
1230              Format(instr, "bnso'l'a'cr 'target16");
1231              break;
1232          }
1233          break;
1234        }
1235        case DCBNZ: {  // Decrement CTR; branch if CTR != 0
1236          Format(instr, "bdnz'l'a 'target16");
1237          break;
1238        }
1239        default:
1240          Format(instr, "bc'l'a'cr 'target16");
1241          break;
1242      }
1243      break;
1244    }
1245    case SC: {
1246      UnknownFormat(instr, "sc");
1247      break;
1248    }
1249    case BX: {
1250      Format(instr, "b'l'a 'target26");
1251      break;
1252    }
1253    case EXT1: {
1254      DecodeExt1(instr);
1255      break;
1256    }
1257    case RLWIMIX: {
1258      Format(instr, "rlwimi'. 'ra, 'rs, 'sh, 'me, 'mb");
1259      break;
1260    }
1261    case RLWINMX: {
1262      Format(instr, "rlwinm'. 'ra, 'rs, 'sh, 'me, 'mb");
1263      break;
1264    }
1265    case RLWNMX: {
1266      Format(instr, "rlwnm'.  'ra, 'rs, 'rb, 'me, 'mb");
1267      break;
1268    }
1269    case ORI: {
1270      Format(instr, "ori     'ra, 'rs, 'uint16");
1271      break;
1272    }
1273    case ORIS: {
1274      Format(instr, "oris    'ra, 'rs, 'uint16");
1275      break;
1276    }
1277    case XORI: {
1278      Format(instr, "xori    'ra, 'rs, 'uint16");
1279      break;
1280    }
1281    case XORIS: {
1282      Format(instr, "xoris   'ra, 'rs, 'uint16");
1283      break;
1284    }
1285    case ANDIx: {
1286      Format(instr, "andi.   'ra, 'rs, 'uint16");
1287      break;
1288    }
1289    case ANDISx: {
1290      Format(instr, "andis.  'ra, 'rs, 'uint16");
1291      break;
1292    }
1293    case EXT2: {
1294      DecodeExt2(instr);
1295      break;
1296    }
1297    case LWZ: {
1298      Format(instr, "lwz     'rt, 'int16('ra)");
1299      break;
1300    }
1301    case LWZU: {
1302      Format(instr, "lwzu    'rt, 'int16('ra)");
1303      break;
1304    }
1305    case LBZ: {
1306      Format(instr, "lbz     'rt, 'int16('ra)");
1307      break;
1308    }
1309    case LBZU: {
1310      Format(instr, "lbzu    'rt, 'int16('ra)");
1311      break;
1312    }
1313    case STW: {
1314      Format(instr, "stw     'rs, 'int16('ra)");
1315      break;
1316    }
1317    case STWU: {
1318      Format(instr, "stwu    'rs, 'int16('ra)");
1319      break;
1320    }
1321    case STB: {
1322      Format(instr, "stb     'rs, 'int16('ra)");
1323      break;
1324    }
1325    case STBU: {
1326      Format(instr, "stbu    'rs, 'int16('ra)");
1327      break;
1328    }
1329    case LHZ: {
1330      Format(instr, "lhz     'rt, 'int16('ra)");
1331      break;
1332    }
1333    case LHZU: {
1334      Format(instr, "lhzu    'rt, 'int16('ra)");
1335      break;
1336    }
1337    case LHA: {
1338      Format(instr, "lha     'rt, 'int16('ra)");
1339      break;
1340    }
1341    case LHAU: {
1342      Format(instr, "lhau    'rt, 'int16('ra)");
1343      break;
1344    }
1345    case STH: {
1346      Format(instr, "sth 'rs, 'int16('ra)");
1347      break;
1348    }
1349    case STHU: {
1350      Format(instr, "sthu 'rs, 'int16('ra)");
1351      break;
1352    }
1353    case LMW: {
1354      UnknownFormat(instr, "lmw");
1355      break;
1356    }
1357    case STMW: {
1358      UnknownFormat(instr, "stmw");
1359      break;
1360    }
1361    case LFS: {
1362      Format(instr, "lfs     'Dt, 'int16('ra)");
1363      break;
1364    }
1365    case LFSU: {
1366      Format(instr, "lfsu    'Dt, 'int16('ra)");
1367      break;
1368    }
1369    case LFD: {
1370      Format(instr, "lfd     'Dt, 'int16('ra)");
1371      break;
1372    }
1373    case LFDU: {
1374      Format(instr, "lfdu    'Dt, 'int16('ra)");
1375      break;
1376    }
1377    case STFS: {
1378      Format(instr, "stfs    'Dt, 'int16('ra)");
1379      break;
1380    }
1381    case STFSU: {
1382      Format(instr, "stfsu   'Dt, 'int16('ra)");
1383      break;
1384    }
1385    case STFD: {
1386      Format(instr, "stfd    'Dt, 'int16('ra)");
1387      break;
1388    }
1389    case STFDU: {
1390      Format(instr, "stfdu   'Dt, 'int16('ra)");
1391      break;
1392    }
1393    case EXT3: {
1394      DecodeExt3(instr);
1395      break;
1396    }
1397    case EXT4: {
1398      DecodeExt4(instr);
1399      break;
1400    }
1401    case EXT5: {
1402      DecodeExt5(instr);
1403      break;
1404    }
1405    case EXT6: {
1406      DecodeExt6(instr);
1407      break;
1408    }
1409#if V8_TARGET_ARCH_PPC64
1410    case LD: {
1411      switch (instr->Bits(1, 0)) {
1412        case 0:
1413          Format(instr, "ld      'rt, 'd('ra)");
1414          break;
1415        case 1:
1416          Format(instr, "ldu     'rt, 'd('ra)");
1417          break;
1418        case 2:
1419          Format(instr, "lwa     'rt, 'd('ra)");
1420          break;
1421      }
1422      break;
1423    }
1424    case STD: {  // could be STD or STDU
1425      if (instr->Bit(0) == 0) {
1426        Format(instr, "std     'rs, 'd('ra)");
1427      } else {
1428        Format(instr, "stdu    'rs, 'd('ra)");
1429      }
1430      break;
1431    }
1432#endif
1433    default: {
1434      Unknown(instr);
1435      break;
1436    }
1437  }
1438
1439  return Instruction::kInstrSize;
1440}
1441}  // namespace internal
1442}  // namespace v8
1443
1444
1445//------------------------------------------------------------------------------
1446
1447namespace disasm {
1448
1449
1450const char* NameConverter::NameOfAddress(byte* addr) const {
1451  v8::internal::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
1452  return tmp_buffer_.start();
1453}
1454
1455
1456const char* NameConverter::NameOfConstant(byte* addr) const {
1457  return NameOfAddress(addr);
1458}
1459
1460
1461const char* NameConverter::NameOfCPURegister(int reg) const {
1462  return v8::internal::GetRegConfig()->GetGeneralRegisterName(reg);
1463}
1464
1465const char* NameConverter::NameOfByteCPURegister(int reg) const {
1466  UNREACHABLE();  // PPC does not have the concept of a byte register
1467  return "nobytereg";
1468}
1469
1470
1471const char* NameConverter::NameOfXMMRegister(int reg) const {
1472  UNREACHABLE();  // PPC does not have any XMM registers
1473  return "noxmmreg";
1474}
1475
1476const char* NameConverter::NameInCode(byte* addr) const {
1477  // The default name converter is called for unknown code. So we will not try
1478  // to access any memory.
1479  return "";
1480}
1481
1482
1483//------------------------------------------------------------------------------
1484
1485Disassembler::Disassembler(const NameConverter& converter)
1486    : converter_(converter) {}
1487
1488
1489Disassembler::~Disassembler() {}
1490
1491
1492int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
1493                                    byte* instruction) {
1494  v8::internal::Decoder d(converter_, buffer);
1495  return d.InstructionDecode(instruction);
1496}
1497
1498
1499// The PPC assembler does not currently use constant pools.
1500int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; }
1501
1502
1503void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
1504  NameConverter converter;
1505  Disassembler d(converter);
1506  for (byte* pc = begin; pc < end;) {
1507    v8::internal::EmbeddedVector<char, 128> buffer;
1508    buffer[0] = '\0';
1509    byte* prev_pc = pc;
1510    pc += d.InstructionDecode(buffer, pc);
1511    v8::internal::PrintF(f, "%p    %08x      %s\n", static_cast<void*>(prev_pc),
1512                         *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
1513  }
1514}
1515
1516
1517}  // namespace disasm
1518
1519#endif  // V8_TARGET_ARCH_PPC
1520