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::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.
     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(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.
    175 int 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.
    203 int 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.
    335 void 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.
    360 void 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.
    366 void 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 
    373 void 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 
    542 void 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 
    914 void 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 
    931 void 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 
   1067 void 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 
   1095 void 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.
   1120 int 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 
   1447 namespace disasm {
   1448 
   1449 
   1450 const 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 
   1456 const char* NameConverter::NameOfConstant(byte* addr) const {
   1457   return NameOfAddress(addr);
   1458 }
   1459 
   1460 
   1461 const char* NameConverter::NameOfCPURegister(int reg) const {
   1462   return v8::internal::GetRegConfig()->GetGeneralRegisterName(reg);
   1463 }
   1464 
   1465 const char* NameConverter::NameOfByteCPURegister(int reg) const {
   1466   UNREACHABLE();  // PPC does not have the concept of a byte register
   1467   return "nobytereg";
   1468 }
   1469 
   1470 
   1471 const char* NameConverter::NameOfXMMRegister(int reg) const {
   1472   UNREACHABLE();  // PPC does not have any XMM registers
   1473   return "noxmmreg";
   1474 }
   1475 
   1476 const 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 
   1485 Disassembler::Disassembler(const NameConverter& converter)
   1486     : converter_(converter) {}
   1487 
   1488 
   1489 Disassembler::~Disassembler() {}
   1490 
   1491 
   1492 int 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.
   1500 int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; }
   1501 
   1502 
   1503 void 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