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