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 
     86   const disasm::NameConverter& converter_;
     87   Vector<char> out_buffer_;
     88   int out_buffer_pos_;
     89 
     90   DISALLOW_COPY_AND_ASSIGN(Decoder);
     91 };
     92 
     93 
     94 // Support for assertions in the Decoder formatting functions.
     95 #define STRING_STARTS_WITH(string, compare_string) \
     96   (strncmp(string, compare_string, strlen(compare_string)) == 0)
     97 
     98 
     99 // Append the ch to the output buffer.
    100 void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
    101 
    102 
    103 // Append the str to the output buffer.
    104 void Decoder::Print(const char* str) {
    105   char cur = *str++;
    106   while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
    107     PrintChar(cur);
    108     cur = *str++;
    109   }
    110   out_buffer_[out_buffer_pos_] = 0;
    111 }
    112 
    113 
    114 // Print the register name according to the active name converter.
    115 void Decoder::PrintRegister(int reg) {
    116   Print(converter_.NameOfCPURegister(reg));
    117 }
    118 
    119 
    120 // Print the double FP register name according to the active name converter.
    121 void Decoder::PrintDRegister(int reg) {
    122   Print(GetRegConfig()->GetDoubleRegisterName(reg));
    123 }
    124 
    125 
    126 // Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
    127 // the FormatOption method.
    128 void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) {
    129   switch (svc) {
    130     case kCallRtRedirected:
    131       Print("call rt redirected");
    132       return;
    133     case kBreakpoint:
    134       Print("breakpoint");
    135       return;
    136     default:
    137       if (svc >= kStopCode) {
    138         out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d - 0x%x",
    139                                     svc & kStopCodeMask, svc & kStopCodeMask);
    140       } else {
    141         out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", svc);
    142       }
    143       return;
    144   }
    145 }
    146 
    147 
    148 // Handle all register based formatting in this function to reduce the
    149 // complexity of FormatOption.
    150 int Decoder::FormatRegister(Instruction* instr, const char* format) {
    151   DCHECK(format[0] == 'r');
    152 
    153   if ((format[1] == 't') || (format[1] == 's')) {  // 'rt & 'rs register
    154     int reg = instr->RTValue();
    155     PrintRegister(reg);
    156     return 2;
    157   } else if (format[1] == 'a') {  // 'ra: RA register
    158     int reg = instr->RAValue();
    159     PrintRegister(reg);
    160     return 2;
    161   } else if (format[1] == 'b') {  // 'rb: RB register
    162     int reg = instr->RBValue();
    163     PrintRegister(reg);
    164     return 2;
    165   }
    166 
    167   UNREACHABLE();
    168   return -1;
    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(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       case 's': {
    273         DCHECK(format[1] == 'h');
    274         int32_t value = 0;
    275         int32_t opcode = instr->OpcodeValue() << 26;
    276         int32_t sh = instr->Bits(15, 11);
    277         if (opcode == EXT5 ||
    278             (opcode == EXT2 && instr->Bits(10, 2) << 2 == SRADIX)) {
    279           // SH Bits 1 and 15-11 (split field)
    280           value = (sh | (instr->Bit(1) << 5));
    281         } else {
    282           // SH Bits 15-11
    283           value = (sh << 26) >> 26;
    284         }
    285         out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
    286         return 2;
    287       }
    288       case 'm': {
    289         int32_t value = 0;
    290         if (format[1] == 'e') {
    291           if (instr->OpcodeValue() << 26 != EXT5) {
    292             // ME Bits 10-6
    293             value = (instr->Bits(10, 6) << 26) >> 26;
    294           } else {
    295             // ME Bits 5 and 10-6 (split field)
    296             value = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
    297           }
    298         } else if (format[1] == 'b') {
    299           if (instr->OpcodeValue() << 26 != EXT5) {
    300             // MB Bits 5-1
    301             value = (instr->Bits(5, 1) << 26) >> 26;
    302           } else {
    303             // MB Bits 5 and 10-6 (split field)
    304             value = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
    305           }
    306         } else {
    307           UNREACHABLE();  // bad format
    308         }
    309         out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
    310         return 2;
    311       }
    312     }
    313 #if V8_TARGET_ARCH_PPC64
    314     case 'd': {  // ds value for offset
    315       int32_t value = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3);
    316       out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
    317       return 1;
    318     }
    319 #endif
    320     default: {
    321       UNREACHABLE();
    322       break;
    323     }
    324   }
    325 
    326   UNREACHABLE();
    327   return -1;
    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 ressemble 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 (instr->Bits(10, 1) << 1) {
    374     case MCRF: {
    375       UnknownFormat(instr, "mcrf");  // not used by V8
    376       break;
    377     }
    378     case BCLRX: {
    379       int bo = instr->Bits(25, 21) << 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->Bits(25, 21) << 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 (instr->Bits(10, 1) << 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 SRAWIX: {
    565       Format(instr, "srawi'.  'ra,'rs,'sh");
    566       return;
    567     }
    568     case EXTSH: {
    569       Format(instr, "extsh'.  'ra, 'rs");
    570       return;
    571     }
    572 #if V8_TARGET_ARCH_PPC64
    573     case EXTSW: {
    574       Format(instr, "extsw'.  'ra, 'rs");
    575       return;
    576     }
    577 #endif
    578     case EXTSB: {
    579       Format(instr, "extsb'.  'ra, 'rs");
    580       return;
    581     }
    582     case LFSX: {
    583       Format(instr, "lfsx    'rt, 'ra, 'rb");
    584       return;
    585     }
    586     case LFSUX: {
    587       Format(instr, "lfsux   'rt, 'ra, 'rb");
    588       return;
    589     }
    590     case LFDX: {
    591       Format(instr, "lfdx    'rt, 'ra, 'rb");
    592       return;
    593     }
    594     case LFDUX: {
    595       Format(instr, "lfdux   'rt, 'ra, 'rb");
    596       return;
    597     }
    598     case STFSX: {
    599       Format(instr, "stfsx    'rs, 'ra, 'rb");
    600       return;
    601     }
    602     case STFSUX: {
    603       Format(instr, "stfsux   'rs, 'ra, 'rb");
    604       return;
    605     }
    606     case STFDX: {
    607       Format(instr, "stfdx    'rs, 'ra, 'rb");
    608       return;
    609     }
    610     case STFDUX: {
    611       Format(instr, "stfdux   'rs, 'ra, 'rb");
    612       return;
    613     }
    614     case POPCNTW: {
    615       Format(instr, "popcntw  'ra, 'rs");
    616       return;
    617     }
    618 #if V8_TARGET_ARCH_PPC64
    619     case POPCNTD: {
    620       Format(instr, "popcntd  'ra, 'rs");
    621       return;
    622     }
    623 #endif
    624   }
    625 
    626   switch (instr->Bits(10, 2) << 2) {
    627     case SRADIX: {
    628       Format(instr, "sradi'.  'ra,'rs,'sh");
    629       return;
    630     }
    631   }
    632 
    633   // ?? are all of these xo_form?
    634   switch (instr->Bits(9, 1) << 1) {
    635     case CMP: {
    636 #if V8_TARGET_ARCH_PPC64
    637       if (instr->Bit(21)) {
    638 #endif
    639         Format(instr, "cmp     'ra, 'rb");
    640 #if V8_TARGET_ARCH_PPC64
    641       } else {
    642         Format(instr, "cmpw    'ra, 'rb");
    643       }
    644 #endif
    645       return;
    646     }
    647     case SLWX: {
    648       Format(instr, "slw'.   'ra, 'rs, 'rb");
    649       return;
    650     }
    651 #if V8_TARGET_ARCH_PPC64
    652     case SLDX: {
    653       Format(instr, "sld'.   'ra, 'rs, 'rb");
    654       return;
    655     }
    656 #endif
    657     case SUBFCX: {
    658       Format(instr, "subfc'. 'rt, 'ra, 'rb");
    659       return;
    660     }
    661     case SUBFEX: {
    662       Format(instr, "subfe'. 'rt, 'ra, 'rb");
    663       return;
    664     }
    665     case ADDCX: {
    666       Format(instr, "addc'.   'rt, 'ra, 'rb");
    667       return;
    668     }
    669     case ADDEX: {
    670       Format(instr, "adde'.   'rt, 'ra, 'rb");
    671       return;
    672     }
    673     case CNTLZWX: {
    674       Format(instr, "cntlzw'. 'ra, 'rs");
    675       return;
    676     }
    677 #if V8_TARGET_ARCH_PPC64
    678     case CNTLZDX: {
    679       Format(instr, "cntlzd'. 'ra, 'rs");
    680       return;
    681     }
    682 #endif
    683     case ANDX: {
    684       Format(instr, "and'.    'ra, 'rs, 'rb");
    685       return;
    686     }
    687     case ANDCX: {
    688       Format(instr, "andc'.   'ra, 'rs, 'rb");
    689       return;
    690     }
    691     case CMPL: {
    692 #if V8_TARGET_ARCH_PPC64
    693       if (instr->Bit(21)) {
    694 #endif
    695         Format(instr, "cmpl    'ra, 'rb");
    696 #if V8_TARGET_ARCH_PPC64
    697       } else {
    698         Format(instr, "cmplw   'ra, 'rb");
    699       }
    700 #endif
    701       return;
    702     }
    703     case NEGX: {
    704       Format(instr, "neg'.    'rt, 'ra");
    705       return;
    706     }
    707     case NORX: {
    708       Format(instr, "nor'.    'rt, 'ra, 'rb");
    709       return;
    710     }
    711     case SUBFX: {
    712       Format(instr, "subf'.   'rt, 'ra, 'rb");
    713       return;
    714     }
    715     case MULHWX: {
    716       Format(instr, "mulhw'o'.  'rt, 'ra, 'rb");
    717       return;
    718     }
    719     case ADDZEX: {
    720       Format(instr, "addze'.   'rt, 'ra");
    721       return;
    722     }
    723     case MULLW: {
    724       Format(instr, "mullw'o'.  'rt, 'ra, 'rb");
    725       return;
    726     }
    727 #if V8_TARGET_ARCH_PPC64
    728     case MULLD: {
    729       Format(instr, "mulld'o'.  'rt, 'ra, 'rb");
    730       return;
    731     }
    732 #endif
    733     case DIVW: {
    734       Format(instr, "divw'o'.   'rt, 'ra, 'rb");
    735       return;
    736     }
    737     case DIVWU: {
    738       Format(instr, "divwu'o'.  'rt, 'ra, 'rb");
    739       return;
    740     }
    741 #if V8_TARGET_ARCH_PPC64
    742     case DIVD: {
    743       Format(instr, "divd'o'.   'rt, 'ra, 'rb");
    744       return;
    745     }
    746 #endif
    747     case ADDX: {
    748       Format(instr, "add'o     'rt, 'ra, 'rb");
    749       return;
    750     }
    751     case XORX: {
    752       Format(instr, "xor'.    'ra, 'rs, 'rb");
    753       return;
    754     }
    755     case ORX: {
    756       if (instr->RTValue() == instr->RBValue()) {
    757         Format(instr, "mr      'ra, 'rb");
    758       } else {
    759         Format(instr, "or      'ra, 'rs, 'rb");
    760       }
    761       return;
    762     }
    763     case MFSPR: {
    764       int spr = instr->Bits(20, 11);
    765       if (256 == spr) {
    766         Format(instr, "mflr    'rt");
    767       } else {
    768         Format(instr, "mfspr   'rt ??");
    769       }
    770       return;
    771     }
    772     case MTSPR: {
    773       int spr = instr->Bits(20, 11);
    774       if (256 == spr) {
    775         Format(instr, "mtlr    'rt");
    776       } else if (288 == spr) {
    777         Format(instr, "mtctr   'rt");
    778       } else {
    779         Format(instr, "mtspr   'rt ??");
    780       }
    781       return;
    782     }
    783     case MFCR: {
    784       Format(instr, "mfcr    'rt");
    785       return;
    786     }
    787     case STWX: {
    788       Format(instr, "stwx    'rs, 'ra, 'rb");
    789       return;
    790     }
    791     case STWUX: {
    792       Format(instr, "stwux   'rs, 'ra, 'rb");
    793       return;
    794     }
    795     case STBX: {
    796       Format(instr, "stbx    'rs, 'ra, 'rb");
    797       return;
    798     }
    799     case STBUX: {
    800       Format(instr, "stbux   'rs, 'ra, 'rb");
    801       return;
    802     }
    803     case STHX: {
    804       Format(instr, "sthx    'rs, 'ra, 'rb");
    805       return;
    806     }
    807     case STHUX: {
    808       Format(instr, "sthux   'rs, 'ra, 'rb");
    809       return;
    810     }
    811     case LWZX: {
    812       Format(instr, "lwzx    'rt, 'ra, 'rb");
    813       return;
    814     }
    815     case LWZUX: {
    816       Format(instr, "lwzux   'rt, 'ra, 'rb");
    817       return;
    818     }
    819     case LWAX: {
    820       Format(instr, "lwax    'rt, 'ra, 'rb");
    821       return;
    822     }
    823     case LBZX: {
    824       Format(instr, "lbzx    'rt, 'ra, 'rb");
    825       return;
    826     }
    827     case LBZUX: {
    828       Format(instr, "lbzux   'rt, 'ra, 'rb");
    829       return;
    830     }
    831     case LHZX: {
    832       Format(instr, "lhzx    'rt, 'ra, 'rb");
    833       return;
    834     }
    835     case LHZUX: {
    836       Format(instr, "lhzux   'rt, 'ra, 'rb");
    837       return;
    838     }
    839     case LHAX: {
    840       Format(instr, "lhax    'rt, 'ra, 'rb");
    841       return;
    842     }
    843 #if V8_TARGET_ARCH_PPC64
    844     case LDX: {
    845       Format(instr, "ldx     'rt, 'ra, 'rb");
    846       return;
    847     }
    848     case LDUX: {
    849       Format(instr, "ldux    'rt, 'ra, 'rb");
    850       return;
    851     }
    852     case STDX: {
    853       Format(instr, "stdx    'rt, 'ra, 'rb");
    854       return;
    855     }
    856     case STDUX: {
    857       Format(instr, "stdux   'rt, 'ra, 'rb");
    858       return;
    859     }
    860     case MFVSRD: {
    861       Format(instr, "mffprd  'ra, 'Dt");
    862       return;
    863     }
    864     case MFVSRWZ: {
    865       Format(instr, "mffprwz 'ra, 'Dt");
    866       return;
    867     }
    868     case MTVSRD: {
    869       Format(instr, "mtfprd  'Dt, 'ra");
    870       return;
    871     }
    872     case MTVSRWA: {
    873       Format(instr, "mtfprwa 'Dt, 'ra");
    874       return;
    875     }
    876     case MTVSRWZ: {
    877       Format(instr, "mtfprwz 'Dt, 'ra");
    878       return;
    879     }
    880 #endif
    881   }
    882 
    883   switch (instr->Bits(5, 1) << 1) {
    884     case ISEL: {
    885       Format(instr, "isel    'rt, 'ra, 'rb");
    886       return;
    887     }
    888     default: {
    889       Unknown(instr);  // not used by V8
    890     }
    891   }
    892 }
    893 
    894 
    895 void Decoder::DecodeExt3(Instruction* instr) {
    896   switch (instr->Bits(10, 1) << 1) {
    897     case FCFID: {
    898       Format(instr, "fcfids'. 'Dt, 'Db");
    899       break;
    900     }
    901     case FCFIDU: {
    902       Format(instr, "fcfidus'.'Dt, 'Db");
    903       break;
    904     }
    905     default: {
    906       Unknown(instr);  // not used by V8
    907     }
    908   }
    909 }
    910 
    911 
    912 void Decoder::DecodeExt4(Instruction* instr) {
    913   switch (instr->Bits(5, 1) << 1) {
    914     case FDIV: {
    915       Format(instr, "fdiv'.   'Dt, 'Da, 'Db");
    916       return;
    917     }
    918     case FSUB: {
    919       Format(instr, "fsub'.   'Dt, 'Da, 'Db");
    920       return;
    921     }
    922     case FADD: {
    923       Format(instr, "fadd'.   'Dt, 'Da, 'Db");
    924       return;
    925     }
    926     case FSQRT: {
    927       Format(instr, "fsqrt'.  'Dt, 'Db");
    928       return;
    929     }
    930     case FSEL: {
    931       Format(instr, "fsel'.   'Dt, 'Da, 'Dc, 'Db");
    932       return;
    933     }
    934     case FMUL: {
    935       Format(instr, "fmul'.   'Dt, 'Da, 'Dc");
    936       return;
    937     }
    938     case FMSUB: {
    939       Format(instr, "fmsub'.  'Dt, 'Da, 'Dc, 'Db");
    940       return;
    941     }
    942     case FMADD: {
    943       Format(instr, "fmadd'.  'Dt, 'Da, 'Dc, 'Db");
    944       return;
    945     }
    946   }
    947 
    948   switch (instr->Bits(10, 1) << 1) {
    949     case FCMPU: {
    950       Format(instr, "fcmpu   'Da, 'Db");
    951       break;
    952     }
    953     case FRSP: {
    954       Format(instr, "frsp'.   'Dt, 'Db");
    955       break;
    956     }
    957     case FCFID: {
    958       Format(instr, "fcfid'.  'Dt, 'Db");
    959       break;
    960     }
    961     case FCFIDU: {
    962       Format(instr, "fcfidu'. 'Dt, 'Db");
    963       break;
    964     }
    965     case FCTID: {
    966       Format(instr, "fctid   'Dt, 'Db");
    967       break;
    968     }
    969     case FCTIDZ: {
    970       Format(instr, "fctidz  'Dt, 'Db");
    971       break;
    972     }
    973     case FCTIDU: {
    974       Format(instr, "fctidu  'Dt, 'Db");
    975       break;
    976     }
    977     case FCTIDUZ: {
    978       Format(instr, "fctiduz 'Dt, 'Db");
    979       break;
    980     }
    981     case FCTIW: {
    982       Format(instr, "fctiw'. 'Dt, 'Db");
    983       break;
    984     }
    985     case FCTIWZ: {
    986       Format(instr, "fctiwz'. 'Dt, 'Db");
    987       break;
    988     }
    989     case FMR: {
    990       Format(instr, "fmr'.    'Dt, 'Db");
    991       break;
    992     }
    993     case MTFSFI: {
    994       Format(instr, "mtfsfi'.  ?,?");
    995       break;
    996     }
    997     case MFFS: {
    998       Format(instr, "mffs'.   'Dt");
    999       break;
   1000     }
   1001     case MTFSF: {
   1002       Format(instr, "mtfsf'.  'Db ?,?,?");
   1003       break;
   1004     }
   1005     case FABS: {
   1006       Format(instr, "fabs'.   'Dt, 'Db");
   1007       break;
   1008     }
   1009     case FRIN: {
   1010       Format(instr, "frin.   'Dt, 'Db");
   1011       break;
   1012     }
   1013     case FRIZ: {
   1014       Format(instr, "friz.   'Dt, 'Db");
   1015       break;
   1016     }
   1017     case FRIP: {
   1018       Format(instr, "frip.   'Dt, 'Db");
   1019       break;
   1020     }
   1021     case FRIM: {
   1022       Format(instr, "frim.   'Dt, 'Db");
   1023       break;
   1024     }
   1025     case FNEG: {
   1026       Format(instr, "fneg'.   'Dt, 'Db");
   1027       break;
   1028     }
   1029     case MCRFS: {
   1030       Format(instr, "mcrfs   ?,?");
   1031       break;
   1032     }
   1033     case MTFSB0: {
   1034       Format(instr, "mtfsb0'. ?");
   1035       break;
   1036     }
   1037     case MTFSB1: {
   1038       Format(instr, "mtfsb1'. ?");
   1039       break;
   1040     }
   1041     default: {
   1042       Unknown(instr);  // not used by V8
   1043     }
   1044   }
   1045 }
   1046 
   1047 
   1048 void Decoder::DecodeExt5(Instruction* instr) {
   1049   switch (instr->Bits(4, 2) << 2) {
   1050     case RLDICL: {
   1051       Format(instr, "rldicl'. 'ra, 'rs, 'sh, 'mb");
   1052       return;
   1053     }
   1054     case RLDICR: {
   1055       Format(instr, "rldicr'. 'ra, 'rs, 'sh, 'me");
   1056       return;
   1057     }
   1058     case RLDIC: {
   1059       Format(instr, "rldic'.  'ra, 'rs, 'sh, 'mb");
   1060       return;
   1061     }
   1062     case RLDIMI: {
   1063       Format(instr, "rldimi'. 'ra, 'rs, 'sh, 'mb");
   1064       return;
   1065     }
   1066   }
   1067   switch (instr->Bits(4, 1) << 1) {
   1068     case RLDCL: {
   1069       Format(instr, "rldcl'.  'ra, 'rs, 'sb, 'mb");
   1070       return;
   1071     }
   1072   }
   1073   Unknown(instr);  // not used by V8
   1074 }
   1075 
   1076 #undef VERIFIY
   1077 
   1078 // Disassemble the instruction at *instr_ptr into the output buffer.
   1079 int Decoder::InstructionDecode(byte* instr_ptr) {
   1080   Instruction* instr = Instruction::At(instr_ptr);
   1081   // Print raw instruction bytes.
   1082   out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%08x       ",
   1083                               instr->InstructionBits());
   1084 
   1085   if (ABI_USES_FUNCTION_DESCRIPTORS && instr->InstructionBits() == 0) {
   1086     // The first field will be identified as a jump table entry.  We
   1087     // emit the rest of the structure as zero, so just skip past them.
   1088     Format(instr, "constant");
   1089     return Instruction::kInstrSize;
   1090   }
   1091 
   1092   switch (instr->OpcodeValue() << 26) {
   1093     case TWI: {
   1094       PrintSoftwareInterrupt(instr->SvcValue());
   1095       break;
   1096     }
   1097     case MULLI: {
   1098       UnknownFormat(instr, "mulli");
   1099       break;
   1100     }
   1101     case SUBFIC: {
   1102       Format(instr, "subfic  'rt, 'ra, 'int16");
   1103       break;
   1104     }
   1105     case CMPLI: {
   1106 #if V8_TARGET_ARCH_PPC64
   1107       if (instr->Bit(21)) {
   1108 #endif
   1109         Format(instr, "cmpli   'ra, 'uint16");
   1110 #if V8_TARGET_ARCH_PPC64
   1111       } else {
   1112         Format(instr, "cmplwi  'ra, 'uint16");
   1113       }
   1114 #endif
   1115       break;
   1116     }
   1117     case CMPI: {
   1118 #if V8_TARGET_ARCH_PPC64
   1119       if (instr->Bit(21)) {
   1120 #endif
   1121         Format(instr, "cmpi    'ra, 'int16");
   1122 #if V8_TARGET_ARCH_PPC64
   1123       } else {
   1124         Format(instr, "cmpwi   'ra, 'int16");
   1125       }
   1126 #endif
   1127       break;
   1128     }
   1129     case ADDIC: {
   1130       Format(instr, "addic   'rt, 'ra, 'int16");
   1131       break;
   1132     }
   1133     case ADDICx: {
   1134       UnknownFormat(instr, "addicx");
   1135       break;
   1136     }
   1137     case ADDI: {
   1138       if (instr->RAValue() == 0) {
   1139         // this is load immediate
   1140         Format(instr, "li      'rt, 'int16");
   1141       } else {
   1142         Format(instr, "addi    'rt, 'ra, 'int16");
   1143       }
   1144       break;
   1145     }
   1146     case ADDIS: {
   1147       if (instr->RAValue() == 0) {
   1148         Format(instr, "lis     'rt, 'int16");
   1149       } else {
   1150         Format(instr, "addis   'rt, 'ra, 'int16");
   1151       }
   1152       break;
   1153     }
   1154     case BCX: {
   1155       int bo = instr->Bits(25, 21) << 21;
   1156       int bi = instr->Bits(20, 16);
   1157       CRBit cond = static_cast<CRBit>(bi & (CRWIDTH - 1));
   1158       switch (bo) {
   1159         case BT: {  // Branch if condition true
   1160           switch (cond) {
   1161             case CR_EQ:
   1162               Format(instr, "beq'l'a'cr 'target16");
   1163               break;
   1164             case CR_GT:
   1165               Format(instr, "bgt'l'a'cr 'target16");
   1166               break;
   1167             case CR_LT:
   1168               Format(instr, "blt'l'a'cr 'target16");
   1169               break;
   1170             case CR_SO:
   1171               Format(instr, "bso'l'a'cr 'target16");
   1172               break;
   1173           }
   1174           break;
   1175         }
   1176         case BF: {  // Branch if condition false
   1177           switch (cond) {
   1178             case CR_EQ:
   1179               Format(instr, "bne'l'a'cr 'target16");
   1180               break;
   1181             case CR_GT:
   1182               Format(instr, "ble'l'a'cr 'target16");
   1183               break;
   1184             case CR_LT:
   1185               Format(instr, "bge'l'a'cr 'target16");
   1186               break;
   1187             case CR_SO:
   1188               Format(instr, "bnso'l'a'cr 'target16");
   1189               break;
   1190           }
   1191           break;
   1192         }
   1193         case DCBNZ: {  // Decrement CTR; branch if CTR != 0
   1194           Format(instr, "bdnz'l'a 'target16");
   1195           break;
   1196         }
   1197         default:
   1198           Format(instr, "bc'l'a'cr 'target16");
   1199           break;
   1200       }
   1201       break;
   1202     }
   1203     case SC: {
   1204       UnknownFormat(instr, "sc");
   1205       break;
   1206     }
   1207     case BX: {
   1208       Format(instr, "b'l'a 'target26");
   1209       break;
   1210     }
   1211     case EXT1: {
   1212       DecodeExt1(instr);
   1213       break;
   1214     }
   1215     case RLWIMIX: {
   1216       Format(instr, "rlwimi'. 'ra, 'rs, 'sh, 'me, 'mb");
   1217       break;
   1218     }
   1219     case RLWINMX: {
   1220       Format(instr, "rlwinm'. 'ra, 'rs, 'sh, 'me, 'mb");
   1221       break;
   1222     }
   1223     case RLWNMX: {
   1224       Format(instr, "rlwnm'.  'ra, 'rs, 'rb, 'me, 'mb");
   1225       break;
   1226     }
   1227     case ORI: {
   1228       Format(instr, "ori     'ra, 'rs, 'uint16");
   1229       break;
   1230     }
   1231     case ORIS: {
   1232       Format(instr, "oris    'ra, 'rs, 'uint16");
   1233       break;
   1234     }
   1235     case XORI: {
   1236       Format(instr, "xori    'ra, 'rs, 'uint16");
   1237       break;
   1238     }
   1239     case XORIS: {
   1240       Format(instr, "xoris   'ra, 'rs, 'uint16");
   1241       break;
   1242     }
   1243     case ANDIx: {
   1244       Format(instr, "andi.   'ra, 'rs, 'uint16");
   1245       break;
   1246     }
   1247     case ANDISx: {
   1248       Format(instr, "andis.  'ra, 'rs, 'uint16");
   1249       break;
   1250     }
   1251     case EXT2: {
   1252       DecodeExt2(instr);
   1253       break;
   1254     }
   1255     case LWZ: {
   1256       Format(instr, "lwz     'rt, 'int16('ra)");
   1257       break;
   1258     }
   1259     case LWZU: {
   1260       Format(instr, "lwzu    'rt, 'int16('ra)");
   1261       break;
   1262     }
   1263     case LBZ: {
   1264       Format(instr, "lbz     'rt, 'int16('ra)");
   1265       break;
   1266     }
   1267     case LBZU: {
   1268       Format(instr, "lbzu    'rt, 'int16('ra)");
   1269       break;
   1270     }
   1271     case STW: {
   1272       Format(instr, "stw     'rs, 'int16('ra)");
   1273       break;
   1274     }
   1275     case STWU: {
   1276       Format(instr, "stwu    'rs, 'int16('ra)");
   1277       break;
   1278     }
   1279     case STB: {
   1280       Format(instr, "stb     'rs, 'int16('ra)");
   1281       break;
   1282     }
   1283     case STBU: {
   1284       Format(instr, "stbu    'rs, 'int16('ra)");
   1285       break;
   1286     }
   1287     case LHZ: {
   1288       Format(instr, "lhz     'rt, 'int16('ra)");
   1289       break;
   1290     }
   1291     case LHZU: {
   1292       Format(instr, "lhzu    'rt, 'int16('ra)");
   1293       break;
   1294     }
   1295     case LHA: {
   1296       Format(instr, "lha     'rt, 'int16('ra)");
   1297       break;
   1298     }
   1299     case LHAU: {
   1300       Format(instr, "lhau    'rt, 'int16('ra)");
   1301       break;
   1302     }
   1303     case STH: {
   1304       Format(instr, "sth 'rs, 'int16('ra)");
   1305       break;
   1306     }
   1307     case STHU: {
   1308       Format(instr, "sthu 'rs, 'int16('ra)");
   1309       break;
   1310     }
   1311     case LMW: {
   1312       UnknownFormat(instr, "lmw");
   1313       break;
   1314     }
   1315     case STMW: {
   1316       UnknownFormat(instr, "stmw");
   1317       break;
   1318     }
   1319     case LFS: {
   1320       Format(instr, "lfs     'Dt, 'int16('ra)");
   1321       break;
   1322     }
   1323     case LFSU: {
   1324       Format(instr, "lfsu    'Dt, 'int16('ra)");
   1325       break;
   1326     }
   1327     case LFD: {
   1328       Format(instr, "lfd     'Dt, 'int16('ra)");
   1329       break;
   1330     }
   1331     case LFDU: {
   1332       Format(instr, "lfdu    'Dt, 'int16('ra)");
   1333       break;
   1334     }
   1335     case STFS: {
   1336       Format(instr, "stfs    'Dt, 'int16('ra)");
   1337       break;
   1338     }
   1339     case STFSU: {
   1340       Format(instr, "stfsu   'Dt, 'int16('ra)");
   1341       break;
   1342     }
   1343     case STFD: {
   1344       Format(instr, "stfd    'Dt, 'int16('ra)");
   1345       break;
   1346     }
   1347     case STFDU: {
   1348       Format(instr, "stfdu   'Dt, 'int16('ra)");
   1349       break;
   1350     }
   1351     case EXT3: {
   1352       DecodeExt3(instr);
   1353       break;
   1354     }
   1355     case EXT4: {
   1356       DecodeExt4(instr);
   1357       break;
   1358     }
   1359     case EXT5: {
   1360       DecodeExt5(instr);
   1361       break;
   1362     }
   1363 #if V8_TARGET_ARCH_PPC64
   1364     case LD: {
   1365       switch (instr->Bits(1, 0)) {
   1366         case 0:
   1367           Format(instr, "ld      'rt, 'd('ra)");
   1368           break;
   1369         case 1:
   1370           Format(instr, "ldu     'rt, 'd('ra)");
   1371           break;
   1372         case 2:
   1373           Format(instr, "lwa     'rt, 'd('ra)");
   1374           break;
   1375       }
   1376       break;
   1377     }
   1378     case STD: {  // could be STD or STDU
   1379       if (instr->Bit(0) == 0) {
   1380         Format(instr, "std     'rs, 'd('ra)");
   1381       } else {
   1382         Format(instr, "stdu    'rs, 'd('ra)");
   1383       }
   1384       break;
   1385     }
   1386 #endif
   1387     default: {
   1388       Unknown(instr);
   1389       break;
   1390     }
   1391   }
   1392 
   1393   return Instruction::kInstrSize;
   1394 }
   1395 }  // namespace internal
   1396 }  // namespace v8
   1397 
   1398 
   1399 //------------------------------------------------------------------------------
   1400 
   1401 namespace disasm {
   1402 
   1403 
   1404 const char* NameConverter::NameOfAddress(byte* addr) const {
   1405   v8::internal::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
   1406   return tmp_buffer_.start();
   1407 }
   1408 
   1409 
   1410 const char* NameConverter::NameOfConstant(byte* addr) const {
   1411   return NameOfAddress(addr);
   1412 }
   1413 
   1414 
   1415 const char* NameConverter::NameOfCPURegister(int reg) const {
   1416   return v8::internal::GetRegConfig()->GetGeneralRegisterName(reg);
   1417 }
   1418 
   1419 const char* NameConverter::NameOfByteCPURegister(int reg) const {
   1420   UNREACHABLE();  // PPC does not have the concept of a byte register
   1421   return "nobytereg";
   1422 }
   1423 
   1424 
   1425 const char* NameConverter::NameOfXMMRegister(int reg) const {
   1426   UNREACHABLE();  // PPC does not have any XMM registers
   1427   return "noxmmreg";
   1428 }
   1429 
   1430 const char* NameConverter::NameInCode(byte* addr) const {
   1431   // The default name converter is called for unknown code. So we will not try
   1432   // to access any memory.
   1433   return "";
   1434 }
   1435 
   1436 
   1437 //------------------------------------------------------------------------------
   1438 
   1439 Disassembler::Disassembler(const NameConverter& converter)
   1440     : converter_(converter) {}
   1441 
   1442 
   1443 Disassembler::~Disassembler() {}
   1444 
   1445 
   1446 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
   1447                                     byte* instruction) {
   1448   v8::internal::Decoder d(converter_, buffer);
   1449   return d.InstructionDecode(instruction);
   1450 }
   1451 
   1452 
   1453 // The PPC assembler does not currently use constant pools.
   1454 int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; }
   1455 
   1456 
   1457 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
   1458   NameConverter converter;
   1459   Disassembler d(converter);
   1460   for (byte* pc = begin; pc < end;) {
   1461     v8::internal::EmbeddedVector<char, 128> buffer;
   1462     buffer[0] = '\0';
   1463     byte* prev_pc = pc;
   1464     pc += d.InstructionDecode(buffer, pc);
   1465     v8::internal::PrintF(f, "%p    %08x      %s\n", static_cast<void*>(prev_pc),
   1466                          *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
   1467   }
   1468 }
   1469 
   1470 
   1471 }  // namespace disasm
   1472 
   1473 #endif  // V8_TARGET_ARCH_PPC
   1474