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