1 // Copyright 2012 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_MIPS64 32 33 #include "src/base/platform/platform.h" 34 #include "src/disasm.h" 35 #include "src/macro-assembler.h" 36 #include "src/mips64/constants-mips64.h" 37 38 namespace v8 { 39 namespace internal { 40 41 //------------------------------------------------------------------------------ 42 43 // Decoder decodes and disassembles instructions into an output buffer. 44 // It uses the converter to convert register names and call destinations into 45 // more informative description. 46 class Decoder { 47 public: 48 Decoder(const disasm::NameConverter& converter, 49 v8::internal::Vector<char> out_buffer) 50 : converter_(converter), 51 out_buffer_(out_buffer), 52 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 PrintFPURegister(int freg); 70 void PrintFPUStatusRegister(int freg); 71 void PrintRs(Instruction* instr); 72 void PrintRt(Instruction* instr); 73 void PrintRd(Instruction* instr); 74 void PrintFs(Instruction* instr); 75 void PrintFt(Instruction* instr); 76 void PrintFd(Instruction* instr); 77 void PrintSa(Instruction* instr); 78 void PrintLsaSa(Instruction* instr); 79 void PrintSd(Instruction* instr); 80 void PrintSs1(Instruction* instr); 81 void PrintSs2(Instruction* instr); 82 void PrintBc(Instruction* instr); 83 void PrintCc(Instruction* instr); 84 void PrintFunction(Instruction* instr); 85 void PrintSecondaryField(Instruction* instr); 86 void PrintUImm16(Instruction* instr); 87 void PrintSImm16(Instruction* instr); 88 void PrintXImm16(Instruction* instr); 89 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits); 90 void PrintXImm18(Instruction* instr); 91 void PrintSImm18(Instruction* instr); 92 void PrintXImm19(Instruction* instr); 93 void PrintSImm19(Instruction* instr); 94 void PrintXImm21(Instruction* instr); 95 void PrintSImm21(Instruction* instr); 96 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits); 97 void PrintXImm26(Instruction* instr); 98 void PrintSImm26(Instruction* instr); 99 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits); 100 void PrintPCImm26(Instruction* instr); 101 void PrintCode(Instruction* instr); // For break and trap instructions. 102 void PrintFormat(Instruction* instr); // For floating format postfix. 103 void PrintBp2(Instruction* instr); 104 void PrintBp3(Instruction* instr); 105 // Printing of instruction name. 106 void PrintInstructionName(Instruction* instr); 107 108 // Handle formatting of instructions and their options. 109 int FormatRegister(Instruction* instr, const char* option); 110 int FormatFPURegister(Instruction* instr, const char* option); 111 int FormatOption(Instruction* instr, const char* option); 112 void Format(Instruction* instr, const char* format); 113 void Unknown(Instruction* instr); 114 int DecodeBreakInstr(Instruction* instr); 115 116 // Each of these functions decodes one particular instruction type. 117 bool DecodeTypeRegisterRsType(Instruction* instr); 118 void DecodeTypeRegisterSRsType(Instruction* instr); 119 void DecodeTypeRegisterDRsType(Instruction* instr); 120 void DecodeTypeRegisterLRsType(Instruction* instr); 121 void DecodeTypeRegisterWRsType(Instruction* instr); 122 void DecodeTypeRegisterSPECIAL(Instruction* instr); 123 void DecodeTypeRegisterSPECIAL2(Instruction* instr); 124 void DecodeTypeRegisterSPECIAL3(Instruction* instr); 125 void DecodeTypeRegisterCOP1(Instruction* instr); 126 void DecodeTypeRegisterCOP1X(Instruction* instr); 127 int DecodeTypeRegister(Instruction* instr); 128 129 void DecodeTypeImmediateCOP1(Instruction* instr); 130 void DecodeTypeImmediateREGIMM(Instruction* instr); 131 void DecodeTypeImmediate(Instruction* instr); 132 133 void DecodeTypeJump(Instruction* instr); 134 135 const disasm::NameConverter& converter_; 136 v8::internal::Vector<char> out_buffer_; 137 int out_buffer_pos_; 138 139 DISALLOW_COPY_AND_ASSIGN(Decoder); 140 }; 141 142 143 // Support for assertions in the Decoder formatting functions. 144 #define STRING_STARTS_WITH(string, compare_string) \ 145 (strncmp(string, compare_string, strlen(compare_string)) == 0) 146 147 148 // Append the ch to the output buffer. 149 void Decoder::PrintChar(const char ch) { 150 out_buffer_[out_buffer_pos_++] = ch; 151 } 152 153 154 // Append the str to the output buffer. 155 void Decoder::Print(const char* str) { 156 char cur = *str++; 157 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 158 PrintChar(cur); 159 cur = *str++; 160 } 161 out_buffer_[out_buffer_pos_] = 0; 162 } 163 164 165 // Print the register name according to the active name converter. 166 void Decoder::PrintRegister(int reg) { 167 Print(converter_.NameOfCPURegister(reg)); 168 } 169 170 171 void Decoder::PrintRs(Instruction* instr) { 172 int reg = instr->RsValue(); 173 PrintRegister(reg); 174 } 175 176 177 void Decoder::PrintRt(Instruction* instr) { 178 int reg = instr->RtValue(); 179 PrintRegister(reg); 180 } 181 182 183 void Decoder::PrintRd(Instruction* instr) { 184 int reg = instr->RdValue(); 185 PrintRegister(reg); 186 } 187 188 189 // Print the FPUregister name according to the active name converter. 190 void Decoder::PrintFPURegister(int freg) { 191 Print(converter_.NameOfXMMRegister(freg)); 192 } 193 194 195 void Decoder::PrintFPUStatusRegister(int freg) { 196 switch (freg) { 197 case kFCSRRegister: 198 Print("FCSR"); 199 break; 200 default: 201 Print(converter_.NameOfXMMRegister(freg)); 202 } 203 } 204 205 206 void Decoder::PrintFs(Instruction* instr) { 207 int freg = instr->RsValue(); 208 PrintFPURegister(freg); 209 } 210 211 212 void Decoder::PrintFt(Instruction* instr) { 213 int freg = instr->RtValue(); 214 PrintFPURegister(freg); 215 } 216 217 218 void Decoder::PrintFd(Instruction* instr) { 219 int freg = instr->RdValue(); 220 PrintFPURegister(freg); 221 } 222 223 224 // Print the integer value of the sa field. 225 void Decoder::PrintSa(Instruction* instr) { 226 int sa = instr->SaValue(); 227 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa); 228 } 229 230 231 // Print the integer value of the sa field of a lsa instruction. 232 void Decoder::PrintLsaSa(Instruction* instr) { 233 int sa = instr->LsaSaValue() + 1; 234 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa); 235 } 236 237 238 // Print the integer value of the rd field, when it is not used as reg. 239 void Decoder::PrintSd(Instruction* instr) { 240 int sd = instr->RdValue(); 241 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sd); 242 } 243 244 245 // Print the integer value of the rd field, when used as 'ext' size. 246 void Decoder::PrintSs1(Instruction* instr) { 247 int ss = instr->RdValue(); 248 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss + 1); 249 } 250 251 252 // Print the integer value of the rd field, when used as 'ins' size. 253 void Decoder::PrintSs2(Instruction* instr) { 254 int ss = instr->RdValue(); 255 int pos = instr->SaValue(); 256 out_buffer_pos_ += 257 SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss - pos + 1); 258 } 259 260 261 // Print the integer value of the cc field for the bc1t/f instructions. 262 void Decoder::PrintBc(Instruction* instr) { 263 int cc = instr->FBccValue(); 264 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", cc); 265 } 266 267 268 // Print the integer value of the cc field for the FP compare instructions. 269 void Decoder::PrintCc(Instruction* instr) { 270 int cc = instr->FCccValue(); 271 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "cc(%d)", cc); 272 } 273 274 275 // Print 16-bit unsigned immediate value. 276 void Decoder::PrintUImm16(Instruction* instr) { 277 int32_t imm = instr->Imm16Value(); 278 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); 279 } 280 281 282 // Print 16-bit signed immediate value. 283 void Decoder::PrintSImm16(Instruction* instr) { 284 int32_t imm = 285 ((instr->Imm16Value()) << (32 - kImm16Bits)) >> (32 - kImm16Bits); 286 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 287 } 288 289 290 // Print 16-bit hexa immediate value. 291 void Decoder::PrintXImm16(Instruction* instr) { 292 int32_t imm = instr->Imm16Value(); 293 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 294 } 295 296 297 // Print absoulte address for 16-bit offset or immediate value. 298 // The absolute address is calculated according following expression: 299 // PC + delta_pc + (offset << n_bits) 300 void Decoder::PrintPCImm16(Instruction* instr, int delta_pc, int n_bits) { 301 int16_t offset = instr->Imm16Value(); 302 out_buffer_pos_ += 303 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", 304 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + 305 delta_pc + (offset << n_bits))); 306 } 307 308 309 // Print 18-bit signed immediate value. 310 void Decoder::PrintSImm18(Instruction* instr) { 311 int32_t imm = 312 ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits); 313 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 314 } 315 316 317 // Print 18-bit hexa immediate value. 318 void Decoder::PrintXImm18(Instruction* instr) { 319 int32_t imm = instr->Imm18Value(); 320 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 321 } 322 323 324 // Print 19-bit hexa immediate value. 325 void Decoder::PrintXImm19(Instruction* instr) { 326 int32_t imm = instr->Imm19Value(); 327 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 328 } 329 330 331 // Print 19-bit signed immediate value. 332 void Decoder::PrintSImm19(Instruction* instr) { 333 int32_t imm19 = instr->Imm19Value(); 334 // set sign 335 imm19 <<= (32 - kImm19Bits); 336 imm19 >>= (32 - kImm19Bits); 337 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm19); 338 } 339 340 341 // Print 21-bit immediate value. 342 void Decoder::PrintXImm21(Instruction* instr) { 343 uint32_t imm = instr->Imm21Value(); 344 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 345 } 346 347 348 // Print 21-bit signed immediate value. 349 void Decoder::PrintSImm21(Instruction* instr) { 350 int32_t imm21 = instr->Imm21Value(); 351 // set sign 352 imm21 <<= (32 - kImm21Bits); 353 imm21 >>= (32 - kImm21Bits); 354 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm21); 355 } 356 357 358 // Print absoulte address for 21-bit offset or immediate value. 359 // The absolute address is calculated according following expression: 360 // PC + delta_pc + (offset << n_bits) 361 void Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) { 362 int32_t imm21 = instr->Imm21Value(); 363 // set sign 364 imm21 <<= (32 - kImm21Bits); 365 imm21 >>= (32 - kImm21Bits); 366 out_buffer_pos_ += 367 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", 368 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + 369 delta_pc + (imm21 << n_bits))); 370 } 371 372 373 // Print 26-bit hex immediate value. 374 void Decoder::PrintXImm26(Instruction* instr) { 375 uint64_t target = static_cast<uint64_t>(instr->Imm26Value()) 376 << kImmFieldShift; 377 target = (reinterpret_cast<uint64_t>(instr) & ~0xfffffff) | target; 378 out_buffer_pos_ += 379 SNPrintF(out_buffer_ + out_buffer_pos_, "0x%" PRIx64, target); 380 } 381 382 383 // Print 26-bit signed immediate value. 384 void Decoder::PrintSImm26(Instruction* instr) { 385 int32_t imm26 = instr->Imm26Value(); 386 // set sign 387 imm26 <<= (32 - kImm26Bits); 388 imm26 >>= (32 - kImm26Bits); 389 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26); 390 } 391 392 393 // Print absoulte address for 26-bit offset or immediate value. 394 // The absolute address is calculated according following expression: 395 // PC + delta_pc + (offset << n_bits) 396 void Decoder::PrintPCImm26(Instruction* instr, int delta_pc, int n_bits) { 397 int32_t imm26 = instr->Imm26Value(); 398 // set sign 399 imm26 <<= (32 - kImm26Bits); 400 imm26 >>= (32 - kImm26Bits); 401 out_buffer_pos_ += 402 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", 403 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + 404 delta_pc + (imm26 << n_bits))); 405 } 406 407 408 // Print absoulte address for 26-bit offset or immediate value. 409 // The absolute address is calculated according following expression: 410 // PC[GPRLEN-1 .. 28] || instr_index26 || 00 411 void Decoder::PrintPCImm26(Instruction* instr) { 412 int32_t imm26 = instr->Imm26Value(); 413 uint64_t pc_mask = ~0xfffffff; 414 uint64_t pc = ((uint64_t)(instr + 1) & pc_mask) | (imm26 << 2); 415 out_buffer_pos_ += 416 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", 417 converter_.NameOfAddress((reinterpret_cast<byte*>(pc)))); 418 } 419 420 421 void Decoder::PrintBp2(Instruction* instr) { 422 int bp2 = instr->Bp2Value(); 423 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp2); 424 } 425 426 427 void Decoder::PrintBp3(Instruction* instr) { 428 int bp3 = instr->Bp3Value(); 429 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp3); 430 } 431 432 433 // Print 26-bit immediate value. 434 void Decoder::PrintCode(Instruction* instr) { 435 if (instr->OpcodeFieldRaw() != SPECIAL) 436 return; // Not a break or trap instruction. 437 switch (instr->FunctionFieldRaw()) { 438 case BREAK: { 439 int32_t code = instr->Bits(25, 6); 440 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 441 "0x%05x (%d)", code, code); 442 break; 443 } 444 case TGE: 445 case TGEU: 446 case TLT: 447 case TLTU: 448 case TEQ: 449 case TNE: { 450 int32_t code = instr->Bits(15, 6); 451 out_buffer_pos_ += 452 SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code); 453 break; 454 } 455 default: // Not a break or trap instruction. 456 break; 457 } 458 } 459 460 461 void Decoder::PrintFormat(Instruction* instr) { 462 char formatLetter = ' '; 463 switch (instr->RsFieldRaw()) { 464 case S: 465 formatLetter = 's'; 466 break; 467 case D: 468 formatLetter = 'd'; 469 break; 470 case W: 471 formatLetter = 'w'; 472 break; 473 case L: 474 formatLetter = 'l'; 475 break; 476 default: 477 UNREACHABLE(); 478 break; 479 } 480 PrintChar(formatLetter); 481 } 482 483 484 // Printing of instruction name. 485 void Decoder::PrintInstructionName(Instruction* instr) { 486 } 487 488 489 // Handle all register based formatting in this function to reduce the 490 // complexity of FormatOption. 491 int Decoder::FormatRegister(Instruction* instr, const char* format) { 492 DCHECK(format[0] == 'r'); 493 if (format[1] == 's') { // 'rs: Rs register. 494 int reg = instr->RsValue(); 495 PrintRegister(reg); 496 return 2; 497 } else if (format[1] == 't') { // 'rt: rt register. 498 int reg = instr->RtValue(); 499 PrintRegister(reg); 500 return 2; 501 } else if (format[1] == 'd') { // 'rd: rd register. 502 int reg = instr->RdValue(); 503 PrintRegister(reg); 504 return 2; 505 } 506 UNREACHABLE(); 507 return -1; 508 } 509 510 511 // Handle all FPUregister based formatting in this function to reduce the 512 // complexity of FormatOption. 513 int Decoder::FormatFPURegister(Instruction* instr, const char* format) { 514 DCHECK(format[0] == 'f'); 515 if ((CTC1 == instr->RsFieldRaw()) || (CFC1 == instr->RsFieldRaw())) { 516 if (format[1] == 's') { // 'fs: fs register. 517 int reg = instr->FsValue(); 518 PrintFPUStatusRegister(reg); 519 return 2; 520 } else if (format[1] == 't') { // 'ft: ft register. 521 int reg = instr->FtValue(); 522 PrintFPUStatusRegister(reg); 523 return 2; 524 } else if (format[1] == 'd') { // 'fd: fd register. 525 int reg = instr->FdValue(); 526 PrintFPUStatusRegister(reg); 527 return 2; 528 } else if (format[1] == 'r') { // 'fr: fr register. 529 int reg = instr->FrValue(); 530 PrintFPUStatusRegister(reg); 531 return 2; 532 } 533 } else { 534 if (format[1] == 's') { // 'fs: fs register. 535 int reg = instr->FsValue(); 536 PrintFPURegister(reg); 537 return 2; 538 } else if (format[1] == 't') { // 'ft: ft register. 539 int reg = instr->FtValue(); 540 PrintFPURegister(reg); 541 return 2; 542 } else if (format[1] == 'd') { // 'fd: fd register. 543 int reg = instr->FdValue(); 544 PrintFPURegister(reg); 545 return 2; 546 } else if (format[1] == 'r') { // 'fr: fr register. 547 int reg = instr->FrValue(); 548 PrintFPURegister(reg); 549 return 2; 550 } 551 } 552 UNREACHABLE(); 553 return -1; 554 } 555 556 557 // FormatOption takes a formatting string and interprets it based on 558 // the current instructions. The format string points to the first 559 // character of the option string (the option escape has already been 560 // consumed by the caller.) FormatOption returns the number of 561 // characters that were consumed from the formatting string. 562 int Decoder::FormatOption(Instruction* instr, const char* format) { 563 switch (format[0]) { 564 case 'c': { // 'code for break or trap instructions. 565 DCHECK(STRING_STARTS_WITH(format, "code")); 566 PrintCode(instr); 567 return 4; 568 } 569 case 'i': { // 'imm16u or 'imm26. 570 if (format[3] == '1') { 571 if (format[4] == '6') { 572 DCHECK(STRING_STARTS_WITH(format, "imm16")); 573 switch (format[5]) { 574 case 's': 575 DCHECK(STRING_STARTS_WITH(format, "imm16s")); 576 PrintSImm16(instr); 577 break; 578 case 'u': 579 DCHECK(STRING_STARTS_WITH(format, "imm16u")); 580 PrintSImm16(instr); 581 break; 582 case 'x': 583 DCHECK(STRING_STARTS_WITH(format, "imm16x")); 584 PrintXImm16(instr); 585 break; 586 case 'p': { // The PC relative address. 587 DCHECK(STRING_STARTS_WITH(format, "imm16p")); 588 int delta_pc = 0; 589 int n_bits = 0; 590 switch (format[6]) { 591 case '4': { 592 DCHECK(STRING_STARTS_WITH(format, "imm16p4")); 593 delta_pc = 4; 594 switch (format[8]) { 595 case '2': 596 DCHECK(STRING_STARTS_WITH(format, "imm16p4s2")); 597 n_bits = 2; 598 PrintPCImm16(instr, delta_pc, n_bits); 599 return 9; 600 } 601 } 602 } 603 } 604 } 605 return 6; 606 } else if (format[4] == '8') { 607 DCHECK(STRING_STARTS_WITH(format, "imm18")); 608 switch (format[5]) { 609 case 's': 610 DCHECK(STRING_STARTS_WITH(format, "imm18s")); 611 PrintSImm18(instr); 612 break; 613 case 'x': 614 DCHECK(STRING_STARTS_WITH(format, "imm18x")); 615 PrintXImm18(instr); 616 break; 617 } 618 return 6; 619 } else if (format[4] == '9') { 620 DCHECK(STRING_STARTS_WITH(format, "imm19")); 621 switch (format[5]) { 622 case 's': 623 DCHECK(STRING_STARTS_WITH(format, "imm19s")); 624 PrintSImm19(instr); 625 break; 626 case 'x': 627 DCHECK(STRING_STARTS_WITH(format, "imm19x")); 628 PrintXImm19(instr); 629 break; 630 } 631 return 6; 632 } 633 } else if (format[3] == '2' && format[4] == '1') { 634 DCHECK(STRING_STARTS_WITH(format, "imm21")); 635 switch (format[5]) { 636 case 's': 637 DCHECK(STRING_STARTS_WITH(format, "imm21s")); 638 PrintSImm21(instr); 639 break; 640 case 'x': 641 DCHECK(STRING_STARTS_WITH(format, "imm21x")); 642 PrintXImm21(instr); 643 break; 644 case 'p': { // The PC relative address. 645 DCHECK(STRING_STARTS_WITH(format, "imm21p")); 646 int delta_pc = 0; 647 int n_bits = 0; 648 switch (format[6]) { 649 case '4': { 650 DCHECK(STRING_STARTS_WITH(format, "imm21p4")); 651 delta_pc = 4; 652 switch (format[8]) { 653 case '2': 654 DCHECK(STRING_STARTS_WITH(format, "imm21p4s2")); 655 n_bits = 2; 656 PrintPCImm21(instr, delta_pc, n_bits); 657 return 9; 658 } 659 } 660 } 661 } 662 } 663 return 6; 664 } else if (format[3] == '2' && format[4] == '6') { 665 DCHECK(STRING_STARTS_WITH(format, "imm26")); 666 switch (format[5]) { 667 case 's': 668 DCHECK(STRING_STARTS_WITH(format, "imm26s")); 669 PrintSImm26(instr); 670 break; 671 case 'x': 672 DCHECK(STRING_STARTS_WITH(format, "imm26x")); 673 PrintXImm26(instr); 674 break; 675 case 'p': { // The PC relative address. 676 DCHECK(STRING_STARTS_WITH(format, "imm26p")); 677 int delta_pc = 0; 678 int n_bits = 0; 679 switch (format[6]) { 680 case '4': { 681 DCHECK(STRING_STARTS_WITH(format, "imm26p4")); 682 delta_pc = 4; 683 switch (format[8]) { 684 case '2': 685 DCHECK(STRING_STARTS_WITH(format, "imm26p4s2")); 686 n_bits = 2; 687 PrintPCImm26(instr, delta_pc, n_bits); 688 return 9; 689 } 690 } 691 } 692 } 693 case 'j': { // Absolute address for jump instructions. 694 DCHECK(STRING_STARTS_WITH(format, "imm26j")); 695 PrintPCImm26(instr); 696 break; 697 } 698 } 699 return 6; 700 } 701 } 702 case 'r': { // 'r: registers. 703 return FormatRegister(instr, format); 704 } 705 case 'f': { // 'f: FPUregisters. 706 return FormatFPURegister(instr, format); 707 } 708 case 's': { // 'sa. 709 switch (format[1]) { 710 case 'a': 711 if (format[2] == '2') { 712 DCHECK(STRING_STARTS_WITH(format, "sa2")); // 'sa2 713 PrintLsaSa(instr); 714 return 3; 715 } else { 716 DCHECK(STRING_STARTS_WITH(format, "sa")); 717 PrintSa(instr); 718 return 2; 719 } 720 break; 721 case 'd': { 722 DCHECK(STRING_STARTS_WITH(format, "sd")); 723 PrintSd(instr); 724 return 2; 725 } 726 case 's': { 727 if (format[2] == '1') { 728 DCHECK(STRING_STARTS_WITH(format, "ss1")); /* ext size */ 729 PrintSs1(instr); 730 return 3; 731 } else { 732 DCHECK(STRING_STARTS_WITH(format, "ss2")); /* ins size */ 733 PrintSs2(instr); 734 return 3; 735 } 736 } 737 } 738 } 739 case 'b': { 740 switch (format[1]) { 741 case 'c': { // 'bc - Special for bc1 cc field. 742 DCHECK(STRING_STARTS_WITH(format, "bc")); 743 PrintBc(instr); 744 return 2; 745 } 746 case 'p': { 747 switch (format[2]) { 748 case '2': { // 'bp2 749 DCHECK(STRING_STARTS_WITH(format, "bp2")); 750 PrintBp2(instr); 751 return 3; 752 } 753 case '3': { // 'bp3 754 DCHECK(STRING_STARTS_WITH(format, "bp3")); 755 PrintBp3(instr); 756 return 3; 757 } 758 } 759 } 760 } 761 } 762 case 'C': { // 'Cc - Special for c.xx.d cc field. 763 DCHECK(STRING_STARTS_WITH(format, "Cc")); 764 PrintCc(instr); 765 return 2; 766 } 767 case 't': 768 PrintFormat(instr); 769 return 1; 770 } 771 UNREACHABLE(); 772 return -1; 773 } 774 775 776 // Format takes a formatting string for a whole instruction and prints it into 777 // the output buffer. All escaped options are handed to FormatOption to be 778 // parsed further. 779 void Decoder::Format(Instruction* instr, const char* format) { 780 char cur = *format++; 781 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 782 if (cur == '\'') { // Single quote is used as the formatting escape. 783 format += FormatOption(instr, format); 784 } else { 785 out_buffer_[out_buffer_pos_++] = cur; 786 } 787 cur = *format++; 788 } 789 out_buffer_[out_buffer_pos_] = '\0'; 790 } 791 792 793 // For currently unimplemented decodings the disassembler calls Unknown(instr) 794 // which will just print "unknown" of the instruction bits. 795 void Decoder::Unknown(Instruction* instr) { 796 Format(instr, "unknown"); 797 } 798 799 800 int Decoder::DecodeBreakInstr(Instruction* instr) { 801 // This is already known to be BREAK instr, just extract the code. 802 if (instr->Bits(25, 6) == static_cast<int>(kMaxStopCode)) { 803 // This is stop(msg). 804 Format(instr, "break, code: 'code"); 805 out_buffer_pos_ += SNPrintF( 806 out_buffer_ + out_buffer_pos_, 807 "\n%p %08" PRIx64 " stop msg: %s", 808 static_cast<void*>( 809 reinterpret_cast<int32_t*>(instr + Instruction::kInstrSize)), 810 reinterpret_cast<uint64_t>( 811 *reinterpret_cast<char**>(instr + Instruction::kInstrSize)), 812 *reinterpret_cast<char**>(instr + Instruction::kInstrSize)); 813 // Size 3: the break_ instr, plus embedded 64-bit char pointer. 814 return 3 * Instruction::kInstrSize; 815 } else { 816 Format(instr, "break, code: 'code"); 817 return Instruction::kInstrSize; 818 } 819 } 820 821 822 bool Decoder::DecodeTypeRegisterRsType(Instruction* instr) { 823 switch (instr->FunctionFieldRaw()) { 824 case RINT: 825 Format(instr, "rint.'t 'fd, 'fs"); 826 break; 827 case SEL: 828 Format(instr, "sel.'t 'fd, 'fs, 'ft"); 829 break; 830 case SELEQZ_C: 831 Format(instr, "seleqz.'t 'fd, 'fs, 'ft"); 832 break; 833 case SELNEZ_C: 834 Format(instr, "selnez.'t 'fd, 'fs, 'ft"); 835 break; 836 case MOVZ_C: 837 Format(instr, "movz.'t 'fd, 'fs, 'rt"); 838 break; 839 case MOVN_C: 840 Format(instr, "movn.'t 'fd, 'fs, 'rt"); 841 break; 842 case MOVF: 843 if (instr->Bit(16)) { 844 Format(instr, "movt.'t 'fd, 'fs, 'Cc"); 845 } else { 846 Format(instr, "movf.'t 'fd, 'fs, 'Cc"); 847 } 848 break; 849 case MIN: 850 Format(instr, "min.'t 'fd, 'fs, 'ft"); 851 break; 852 case MAX: 853 Format(instr, "max.'t 'fd, 'fs, 'ft"); 854 break; 855 case MINA: 856 Format(instr, "mina.'t 'fd, 'fs, 'ft"); 857 break; 858 case MAXA: 859 Format(instr, "maxa.'t 'fd, 'fs, 'ft"); 860 break; 861 case ADD_D: 862 Format(instr, "add.'t 'fd, 'fs, 'ft"); 863 break; 864 case SUB_D: 865 Format(instr, "sub.'t 'fd, 'fs, 'ft"); 866 break; 867 case MUL_D: 868 Format(instr, "mul.'t 'fd, 'fs, 'ft"); 869 break; 870 case DIV_D: 871 Format(instr, "div.'t 'fd, 'fs, 'ft"); 872 break; 873 case ABS_D: 874 Format(instr, "abs.'t 'fd, 'fs"); 875 break; 876 case MOV_D: 877 Format(instr, "mov.'t 'fd, 'fs"); 878 break; 879 case NEG_D: 880 Format(instr, "neg.'t 'fd, 'fs"); 881 break; 882 case SQRT_D: 883 Format(instr, "sqrt.'t 'fd, 'fs"); 884 break; 885 case RECIP_D: 886 Format(instr, "recip.'t 'fd, 'fs"); 887 break; 888 case RSQRT_D: 889 Format(instr, "rsqrt.'t 'fd, 'fs"); 890 break; 891 case CVT_W_D: 892 Format(instr, "cvt.w.'t 'fd, 'fs"); 893 break; 894 case CVT_L_D: 895 Format(instr, "cvt.l.'t 'fd, 'fs"); 896 break; 897 case TRUNC_W_D: 898 Format(instr, "trunc.w.'t 'fd, 'fs"); 899 break; 900 case TRUNC_L_D: 901 Format(instr, "trunc.l.'t 'fd, 'fs"); 902 break; 903 case ROUND_W_D: 904 Format(instr, "round.w.'t 'fd, 'fs"); 905 break; 906 case ROUND_L_D: 907 Format(instr, "round.l.'t 'fd, 'fs"); 908 break; 909 case FLOOR_W_D: 910 Format(instr, "floor.w.'t 'fd, 'fs"); 911 break; 912 case FLOOR_L_D: 913 Format(instr, "floor.l.'t 'fd, 'fs"); 914 break; 915 case CEIL_W_D: 916 Format(instr, "ceil.w.'t 'fd, 'fs"); 917 break; 918 case CEIL_L_D: 919 Format(instr, "ceil.l.'t 'fd, 'fs"); 920 break; 921 case CLASS_D: 922 Format(instr, "class.'t 'fd, 'fs"); 923 break; 924 case CVT_S_D: 925 Format(instr, "cvt.s.'t 'fd, 'fs"); 926 break; 927 case C_F_D: 928 Format(instr, "c.f.'t 'fs, 'ft, 'Cc"); 929 break; 930 case C_UN_D: 931 Format(instr, "c.un.'t 'fs, 'ft, 'Cc"); 932 break; 933 case C_EQ_D: 934 Format(instr, "c.eq.'t 'fs, 'ft, 'Cc"); 935 break; 936 case C_UEQ_D: 937 Format(instr, "c.ueq.'t 'fs, 'ft, 'Cc"); 938 break; 939 case C_OLT_D: 940 Format(instr, "c.olt.'t 'fs, 'ft, 'Cc"); 941 break; 942 case C_ULT_D: 943 Format(instr, "c.ult.'t 'fs, 'ft, 'Cc"); 944 break; 945 case C_OLE_D: 946 Format(instr, "c.ole.'t 'fs, 'ft, 'Cc"); 947 break; 948 case C_ULE_D: 949 Format(instr, "c.ule.'t 'fs, 'ft, 'Cc"); 950 break; 951 default: 952 return false; 953 } 954 return true; 955 } 956 957 958 void Decoder::DecodeTypeRegisterSRsType(Instruction* instr) { 959 if (!DecodeTypeRegisterRsType(instr)) { 960 switch (instr->FunctionFieldRaw()) { 961 case CVT_D_S: 962 Format(instr, "cvt.d.'t 'fd, 'fs"); 963 break; 964 default: 965 Format(instr, "unknown.cop1.'t"); 966 break; 967 } 968 } 969 } 970 971 972 void Decoder::DecodeTypeRegisterDRsType(Instruction* instr) { 973 if (!DecodeTypeRegisterRsType(instr)) { 974 Format(instr, "unknown.cop1.'t"); 975 } 976 } 977 978 979 void Decoder::DecodeTypeRegisterLRsType(Instruction* instr) { 980 switch (instr->FunctionFieldRaw()) { 981 case CVT_D_L: 982 Format(instr, "cvt.d.l 'fd, 'fs"); 983 break; 984 case CVT_S_L: 985 Format(instr, "cvt.s.l 'fd, 'fs"); 986 break; 987 case CMP_AF: 988 Format(instr, "cmp.af.d 'fd, 'fs, 'ft"); 989 break; 990 case CMP_UN: 991 Format(instr, "cmp.un.d 'fd, 'fs, 'ft"); 992 break; 993 case CMP_EQ: 994 Format(instr, "cmp.eq.d 'fd, 'fs, 'ft"); 995 break; 996 case CMP_UEQ: 997 Format(instr, "cmp.ueq.d 'fd, 'fs, 'ft"); 998 break; 999 case CMP_LT: 1000 Format(instr, "cmp.lt.d 'fd, 'fs, 'ft"); 1001 break; 1002 case CMP_ULT: 1003 Format(instr, "cmp.ult.d 'fd, 'fs, 'ft"); 1004 break; 1005 case CMP_LE: 1006 Format(instr, "cmp.le.d 'fd, 'fs, 'ft"); 1007 break; 1008 case CMP_ULE: 1009 Format(instr, "cmp.ule.d 'fd, 'fs, 'ft"); 1010 break; 1011 case CMP_OR: 1012 Format(instr, "cmp.or.d 'fd, 'fs, 'ft"); 1013 break; 1014 case CMP_UNE: 1015 Format(instr, "cmp.une.d 'fd, 'fs, 'ft"); 1016 break; 1017 case CMP_NE: 1018 Format(instr, "cmp.ne.d 'fd, 'fs, 'ft"); 1019 break; 1020 default: 1021 UNREACHABLE(); 1022 } 1023 } 1024 1025 1026 void Decoder::DecodeTypeRegisterWRsType(Instruction* instr) { 1027 switch (instr->FunctionValue()) { 1028 case CVT_S_W: // Convert word to float (single). 1029 Format(instr, "cvt.s.w 'fd, 'fs"); 1030 break; 1031 case CVT_D_W: // Convert word to double. 1032 Format(instr, "cvt.d.w 'fd, 'fs"); 1033 break; 1034 case CMP_AF: 1035 Format(instr, "cmp.af.s 'fd, 'fs, 'ft"); 1036 break; 1037 case CMP_UN: 1038 Format(instr, "cmp.un.s 'fd, 'fs, 'ft"); 1039 break; 1040 case CMP_EQ: 1041 Format(instr, "cmp.eq.s 'fd, 'fs, 'ft"); 1042 break; 1043 case CMP_UEQ: 1044 Format(instr, "cmp.ueq.s 'fd, 'fs, 'ft"); 1045 break; 1046 case CMP_LT: 1047 Format(instr, "cmp.lt.s 'fd, 'fs, 'ft"); 1048 break; 1049 case CMP_ULT: 1050 Format(instr, "cmp.ult.s 'fd, 'fs, 'ft"); 1051 break; 1052 case CMP_LE: 1053 Format(instr, "cmp.le.s 'fd, 'fs, 'ft"); 1054 break; 1055 case CMP_ULE: 1056 Format(instr, "cmp.ule.s 'fd, 'fs, 'ft"); 1057 break; 1058 case CMP_OR: 1059 Format(instr, "cmp.or.s 'fd, 'fs, 'ft"); 1060 break; 1061 case CMP_UNE: 1062 Format(instr, "cmp.une.s 'fd, 'fs, 'ft"); 1063 break; 1064 case CMP_NE: 1065 Format(instr, "cmp.ne.s 'fd, 'fs, 'ft"); 1066 break; 1067 default: 1068 UNREACHABLE(); 1069 } 1070 } 1071 1072 1073 void Decoder::DecodeTypeRegisterCOP1(Instruction* instr) { 1074 switch (instr->RsFieldRaw()) { 1075 case MFC1: 1076 Format(instr, "mfc1 'rt, 'fs"); 1077 break; 1078 case DMFC1: 1079 Format(instr, "dmfc1 'rt, 'fs"); 1080 break; 1081 case MFHC1: 1082 Format(instr, "mfhc1 'rt, 'fs"); 1083 break; 1084 case MTC1: 1085 Format(instr, "mtc1 'rt, 'fs"); 1086 break; 1087 case DMTC1: 1088 Format(instr, "dmtc1 'rt, 'fs"); 1089 break; 1090 // These are called "fs" too, although they are not FPU registers. 1091 case CTC1: 1092 Format(instr, "ctc1 'rt, 'fs"); 1093 break; 1094 case CFC1: 1095 Format(instr, "cfc1 'rt, 'fs"); 1096 break; 1097 case MTHC1: 1098 Format(instr, "mthc1 'rt, 'fs"); 1099 break; 1100 case S: 1101 DecodeTypeRegisterSRsType(instr); 1102 break; 1103 case D: 1104 DecodeTypeRegisterDRsType(instr); 1105 break; 1106 case W: 1107 DecodeTypeRegisterWRsType(instr); 1108 break; 1109 case L: 1110 DecodeTypeRegisterLRsType(instr); 1111 break; 1112 default: 1113 UNREACHABLE(); 1114 } 1115 } 1116 1117 1118 void Decoder::DecodeTypeRegisterCOP1X(Instruction* instr) { 1119 switch (instr->FunctionFieldRaw()) { 1120 case MADD_D: 1121 Format(instr, "madd.d 'fd, 'fr, 'fs, 'ft"); 1122 break; 1123 default: 1124 UNREACHABLE(); 1125 } 1126 } 1127 1128 1129 void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) { 1130 switch (instr->FunctionFieldRaw()) { 1131 case JR: 1132 Format(instr, "jr 'rs"); 1133 break; 1134 case JALR: 1135 Format(instr, "jalr 'rs, 'rd"); 1136 break; 1137 case SLL: 1138 if (0x0 == static_cast<int>(instr->InstructionBits())) 1139 Format(instr, "nop"); 1140 else 1141 Format(instr, "sll 'rd, 'rt, 'sa"); 1142 break; 1143 case DSLL: 1144 Format(instr, "dsll 'rd, 'rt, 'sa"); 1145 break; 1146 case D_MUL_MUH: // Equals to DMUL. 1147 if (kArchVariant != kMips64r6) { 1148 Format(instr, "dmult 'rs, 'rt"); 1149 } else { 1150 if (instr->SaValue() == MUL_OP) { 1151 Format(instr, "dmul 'rd, 'rs, 'rt"); 1152 } else { 1153 Format(instr, "dmuh 'rd, 'rs, 'rt"); 1154 } 1155 } 1156 break; 1157 case DSLL32: 1158 Format(instr, "dsll32 'rd, 'rt, 'sa"); 1159 break; 1160 case SRL: 1161 if (instr->RsValue() == 0) { 1162 Format(instr, "srl 'rd, 'rt, 'sa"); 1163 } else { 1164 Format(instr, "rotr 'rd, 'rt, 'sa"); 1165 } 1166 break; 1167 case DSRL: 1168 if (instr->RsValue() == 0) { 1169 Format(instr, "dsrl 'rd, 'rt, 'sa"); 1170 } else { 1171 Format(instr, "drotr 'rd, 'rt, 'sa"); 1172 } 1173 break; 1174 case DSRL32: 1175 if (instr->RsValue() == 0) { 1176 Format(instr, "dsrl32 'rd, 'rt, 'sa"); 1177 } else { 1178 Format(instr, "drotr32 'rd, 'rt, 'sa"); 1179 } 1180 break; 1181 case SRA: 1182 Format(instr, "sra 'rd, 'rt, 'sa"); 1183 break; 1184 case DSRA: 1185 Format(instr, "dsra 'rd, 'rt, 'sa"); 1186 break; 1187 case DSRA32: 1188 Format(instr, "dsra32 'rd, 'rt, 'sa"); 1189 break; 1190 case SLLV: 1191 Format(instr, "sllv 'rd, 'rt, 'rs"); 1192 break; 1193 case DSLLV: 1194 Format(instr, "dsllv 'rd, 'rt, 'rs"); 1195 break; 1196 case SRLV: 1197 if (instr->SaValue() == 0) { 1198 Format(instr, "srlv 'rd, 'rt, 'rs"); 1199 } else { 1200 Format(instr, "rotrv 'rd, 'rt, 'rs"); 1201 } 1202 break; 1203 case DSRLV: 1204 if (instr->SaValue() == 0) { 1205 Format(instr, "dsrlv 'rd, 'rt, 'rs"); 1206 } else { 1207 Format(instr, "drotrv 'rd, 'rt, 'rs"); 1208 } 1209 break; 1210 case SRAV: 1211 Format(instr, "srav 'rd, 'rt, 'rs"); 1212 break; 1213 case DSRAV: 1214 Format(instr, "dsrav 'rd, 'rt, 'rs"); 1215 break; 1216 case LSA: 1217 Format(instr, "lsa 'rd, 'rt, 'rs, 'sa2"); 1218 break; 1219 case DLSA: 1220 Format(instr, "dlsa 'rd, 'rt, 'rs, 'sa2"); 1221 break; 1222 case MFHI: 1223 if (instr->Bits(25, 16) == 0) { 1224 Format(instr, "mfhi 'rd"); 1225 } else { 1226 if ((instr->FunctionFieldRaw() == CLZ_R6) && (instr->FdValue() == 1)) { 1227 Format(instr, "clz 'rd, 'rs"); 1228 } else if ((instr->FunctionFieldRaw() == CLO_R6) && 1229 (instr->FdValue() == 1)) { 1230 Format(instr, "clo 'rd, 'rs"); 1231 } 1232 } 1233 break; 1234 case MFLO: 1235 if (instr->Bits(25, 16) == 0) { 1236 Format(instr, "mflo 'rd"); 1237 } else { 1238 if ((instr->FunctionFieldRaw() == DCLZ_R6) && (instr->FdValue() == 1)) { 1239 Format(instr, "dclz 'rd, 'rs"); 1240 } else if ((instr->FunctionFieldRaw() == DCLO_R6) && 1241 (instr->FdValue() == 1)) { 1242 Format(instr, "dclo 'rd, 'rs"); 1243 } 1244 } 1245 break; 1246 case D_MUL_MUH_U: // Equals to DMULTU. 1247 if (kArchVariant != kMips64r6) { 1248 Format(instr, "dmultu 'rs, 'rt"); 1249 } else { 1250 if (instr->SaValue() == MUL_OP) { 1251 Format(instr, "dmulu 'rd, 'rs, 'rt"); 1252 } else { 1253 Format(instr, "dmuhu 'rd, 'rs, 'rt"); 1254 } 1255 } 1256 break; 1257 case MULT: // @Mips64r6 == MUL_MUH. 1258 if (kArchVariant != kMips64r6) { 1259 Format(instr, "mult 'rs, 'rt"); 1260 } else { 1261 if (instr->SaValue() == MUL_OP) { 1262 Format(instr, "mul 'rd, 'rs, 'rt"); 1263 } else { 1264 Format(instr, "muh 'rd, 'rs, 'rt"); 1265 } 1266 } 1267 break; 1268 case MULTU: // @Mips64r6 == MUL_MUH_U. 1269 if (kArchVariant != kMips64r6) { 1270 Format(instr, "multu 'rs, 'rt"); 1271 } else { 1272 if (instr->SaValue() == MUL_OP) { 1273 Format(instr, "mulu 'rd, 'rs, 'rt"); 1274 } else { 1275 Format(instr, "muhu 'rd, 'rs, 'rt"); 1276 } 1277 } 1278 1279 break; 1280 case DIV: // @Mips64r6 == DIV_MOD. 1281 if (kArchVariant != kMips64r6) { 1282 Format(instr, "div 'rs, 'rt"); 1283 } else { 1284 if (instr->SaValue() == DIV_OP) { 1285 Format(instr, "div 'rd, 'rs, 'rt"); 1286 } else { 1287 Format(instr, "mod 'rd, 'rs, 'rt"); 1288 } 1289 } 1290 break; 1291 case DDIV: // @Mips64r6 == D_DIV_MOD. 1292 if (kArchVariant != kMips64r6) { 1293 Format(instr, "ddiv 'rs, 'rt"); 1294 } else { 1295 if (instr->SaValue() == DIV_OP) { 1296 Format(instr, "ddiv 'rd, 'rs, 'rt"); 1297 } else { 1298 Format(instr, "dmod 'rd, 'rs, 'rt"); 1299 } 1300 } 1301 break; 1302 case DIVU: // @Mips64r6 == DIV_MOD_U. 1303 if (kArchVariant != kMips64r6) { 1304 Format(instr, "divu 'rs, 'rt"); 1305 } else { 1306 if (instr->SaValue() == DIV_OP) { 1307 Format(instr, "divu 'rd, 'rs, 'rt"); 1308 } else { 1309 Format(instr, "modu 'rd, 'rs, 'rt"); 1310 } 1311 } 1312 break; 1313 case DDIVU: // @Mips64r6 == D_DIV_MOD_U. 1314 if (kArchVariant != kMips64r6) { 1315 Format(instr, "ddivu 'rs, 'rt"); 1316 } else { 1317 if (instr->SaValue() == DIV_OP) { 1318 Format(instr, "ddivu 'rd, 'rs, 'rt"); 1319 } else { 1320 Format(instr, "dmodu 'rd, 'rs, 'rt"); 1321 } 1322 } 1323 break; 1324 case ADD: 1325 Format(instr, "add 'rd, 'rs, 'rt"); 1326 break; 1327 case DADD: 1328 Format(instr, "dadd 'rd, 'rs, 'rt"); 1329 break; 1330 case ADDU: 1331 Format(instr, "addu 'rd, 'rs, 'rt"); 1332 break; 1333 case DADDU: 1334 Format(instr, "daddu 'rd, 'rs, 'rt"); 1335 break; 1336 case SUB: 1337 Format(instr, "sub 'rd, 'rs, 'rt"); 1338 break; 1339 case DSUB: 1340 Format(instr, "dsub 'rd, 'rs, 'rt"); 1341 break; 1342 case SUBU: 1343 Format(instr, "subu 'rd, 'rs, 'rt"); 1344 break; 1345 case DSUBU: 1346 Format(instr, "dsubu 'rd, 'rs, 'rt"); 1347 break; 1348 case AND: 1349 Format(instr, "and 'rd, 'rs, 'rt"); 1350 break; 1351 case OR: 1352 if (0 == instr->RsValue()) { 1353 Format(instr, "mov 'rd, 'rt"); 1354 } else if (0 == instr->RtValue()) { 1355 Format(instr, "mov 'rd, 'rs"); 1356 } else { 1357 Format(instr, "or 'rd, 'rs, 'rt"); 1358 } 1359 break; 1360 case XOR: 1361 Format(instr, "xor 'rd, 'rs, 'rt"); 1362 break; 1363 case NOR: 1364 Format(instr, "nor 'rd, 'rs, 'rt"); 1365 break; 1366 case SLT: 1367 Format(instr, "slt 'rd, 'rs, 'rt"); 1368 break; 1369 case SLTU: 1370 Format(instr, "sltu 'rd, 'rs, 'rt"); 1371 break; 1372 case TGE: 1373 Format(instr, "tge 'rs, 'rt, code: 'code"); 1374 break; 1375 case TGEU: 1376 Format(instr, "tgeu 'rs, 'rt, code: 'code"); 1377 break; 1378 case TLT: 1379 Format(instr, "tlt 'rs, 'rt, code: 'code"); 1380 break; 1381 case TLTU: 1382 Format(instr, "tltu 'rs, 'rt, code: 'code"); 1383 break; 1384 case TEQ: 1385 Format(instr, "teq 'rs, 'rt, code: 'code"); 1386 break; 1387 case TNE: 1388 Format(instr, "tne 'rs, 'rt, code: 'code"); 1389 break; 1390 case SYNC: 1391 Format(instr, "sync"); 1392 break; 1393 case MOVZ: 1394 Format(instr, "movz 'rd, 'rs, 'rt"); 1395 break; 1396 case MOVN: 1397 Format(instr, "movn 'rd, 'rs, 'rt"); 1398 break; 1399 case MOVCI: 1400 if (instr->Bit(16)) { 1401 Format(instr, "movt 'rd, 'rs, 'bc"); 1402 } else { 1403 Format(instr, "movf 'rd, 'rs, 'bc"); 1404 } 1405 break; 1406 case SELEQZ_S: 1407 Format(instr, "seleqz 'rd, 'rs, 'rt"); 1408 break; 1409 case SELNEZ_S: 1410 Format(instr, "selnez 'rd, 'rs, 'rt"); 1411 break; 1412 default: 1413 UNREACHABLE(); 1414 } 1415 } 1416 1417 1418 void Decoder::DecodeTypeRegisterSPECIAL2(Instruction* instr) { 1419 switch (instr->FunctionFieldRaw()) { 1420 case MUL: 1421 Format(instr, "mul 'rd, 'rs, 'rt"); 1422 break; 1423 case CLZ: 1424 if (kArchVariant != kMips64r6) { 1425 Format(instr, "clz 'rd, 'rs"); 1426 } 1427 break; 1428 case DCLZ: 1429 if (kArchVariant != kMips64r6) { 1430 Format(instr, "dclz 'rd, 'rs"); 1431 } 1432 break; 1433 default: 1434 UNREACHABLE(); 1435 } 1436 } 1437 1438 1439 void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) { 1440 switch (instr->FunctionFieldRaw()) { 1441 case INS: { 1442 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); 1443 break; 1444 } 1445 case EXT: { 1446 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); 1447 break; 1448 } 1449 case DEXT: { 1450 Format(instr, "dext 'rt, 'rs, 'sa, 'ss1"); 1451 break; 1452 } 1453 case BSHFL: { 1454 int sa = instr->SaFieldRaw() >> kSaShift; 1455 switch (sa) { 1456 case BITSWAP: { 1457 Format(instr, "bitswap 'rd, 'rt"); 1458 break; 1459 } 1460 case SEB: { 1461 Format(instr, "seb 'rd, 'rt"); 1462 break; 1463 } 1464 case SEH: { 1465 Format(instr, "seh 'rd, 'rt"); 1466 break; 1467 } 1468 case WSBH: { 1469 Format(instr, "wsbh 'rd, 'rt"); 1470 break; 1471 } 1472 default: { 1473 sa >>= kBp2Bits; 1474 switch (sa) { 1475 case ALIGN: { 1476 Format(instr, "align 'rd, 'rs, 'rt, 'bp2"); 1477 break; 1478 } 1479 default: 1480 UNREACHABLE(); 1481 break; 1482 } 1483 break; 1484 } 1485 } 1486 break; 1487 } 1488 case DBSHFL: { 1489 int sa = instr->SaFieldRaw() >> kSaShift; 1490 switch (sa) { 1491 case DBITSWAP: { 1492 switch (instr->SaFieldRaw() >> kSaShift) { 1493 case DBITSWAP_SA: 1494 Format(instr, "dbitswap 'rd, 'rt"); 1495 break; 1496 default: 1497 UNREACHABLE(); 1498 break; 1499 } 1500 break; 1501 } 1502 case DSBH: { 1503 Format(instr, "dsbh 'rd, 'rt"); 1504 break; 1505 } 1506 case DSHD: { 1507 Format(instr, "dshd 'rd, 'rt"); 1508 break; 1509 } 1510 default: { 1511 sa >>= kBp3Bits; 1512 switch (sa) { 1513 case DALIGN: { 1514 Format(instr, "dalign 'rd, 'rs, 'rt, 'bp3"); 1515 break; 1516 } 1517 default: 1518 UNREACHABLE(); 1519 break; 1520 } 1521 break; 1522 } 1523 } 1524 break; 1525 } 1526 default: 1527 UNREACHABLE(); 1528 } 1529 } 1530 1531 1532 int Decoder::DecodeTypeRegister(Instruction* instr) { 1533 switch (instr->OpcodeFieldRaw()) { 1534 case COP1: // Coprocessor instructions. 1535 DecodeTypeRegisterCOP1(instr); 1536 break; 1537 case COP1X: 1538 DecodeTypeRegisterCOP1X(instr); 1539 break; 1540 case SPECIAL: 1541 switch (instr->FunctionFieldRaw()) { 1542 case BREAK: 1543 return DecodeBreakInstr(instr); 1544 default: 1545 DecodeTypeRegisterSPECIAL(instr); 1546 break; 1547 } 1548 break; 1549 case SPECIAL2: 1550 DecodeTypeRegisterSPECIAL2(instr); 1551 break; 1552 case SPECIAL3: 1553 DecodeTypeRegisterSPECIAL3(instr); 1554 break; 1555 default: 1556 UNREACHABLE(); 1557 } 1558 return Instruction::kInstrSize; 1559 } 1560 1561 1562 void Decoder::DecodeTypeImmediateCOP1(Instruction* instr) { 1563 switch (instr->RsFieldRaw()) { 1564 case BC1: 1565 if (instr->FBtrueValue()) { 1566 Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2"); 1567 } else { 1568 Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2"); 1569 } 1570 break; 1571 case BC1EQZ: 1572 Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2"); 1573 break; 1574 case BC1NEZ: 1575 Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2"); 1576 break; 1577 default: 1578 UNREACHABLE(); 1579 } 1580 } 1581 1582 1583 void Decoder::DecodeTypeImmediateREGIMM(Instruction* instr) { 1584 switch (instr->RtFieldRaw()) { 1585 case BLTZ: 1586 Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2"); 1587 break; 1588 case BLTZAL: 1589 Format(instr, "bltzal 'rs, 'imm16u -> 'imm16p4s2"); 1590 break; 1591 case BGEZ: 1592 Format(instr, "bgez 'rs, 'imm16u -> 'imm16p4s2"); 1593 break; 1594 case BGEZAL: { 1595 if (instr->RsValue() == 0) 1596 Format(instr, "bal 'imm16s -> 'imm16p4s2"); 1597 else 1598 Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2"); 1599 break; 1600 } 1601 case BGEZALL: 1602 Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2"); 1603 break; 1604 case DAHI: 1605 Format(instr, "dahi 'rs, 'imm16x"); 1606 break; 1607 case DATI: 1608 Format(instr, "dati 'rs, 'imm16x"); 1609 break; 1610 default: 1611 UNREACHABLE(); 1612 } 1613 } 1614 1615 1616 void Decoder::DecodeTypeImmediate(Instruction* instr) { 1617 switch (instr->OpcodeFieldRaw()) { 1618 case COP1: 1619 DecodeTypeImmediateCOP1(instr); 1620 break; // Case COP1. 1621 // ------------- REGIMM class. 1622 case REGIMM: 1623 DecodeTypeImmediateREGIMM(instr); 1624 break; // Case REGIMM. 1625 // ------------- Branch instructions. 1626 case BEQ: 1627 Format(instr, "beq 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1628 break; 1629 case BC: 1630 Format(instr, "bc 'imm26s -> 'imm26p4s2"); 1631 break; 1632 case BALC: 1633 Format(instr, "balc 'imm26s -> 'imm26p4s2"); 1634 break; 1635 case BNE: 1636 Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1637 break; 1638 case BLEZ: 1639 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { 1640 Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2"); 1641 } else if ((instr->RtValue() != instr->RsValue()) && 1642 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 1643 Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1644 } else if ((instr->RtValue() == instr->RsValue()) && 1645 (instr->RtValue() != 0)) { 1646 Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2"); 1647 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 1648 Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2"); 1649 } else { 1650 UNREACHABLE(); 1651 } 1652 break; 1653 case BGTZ: 1654 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { 1655 Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2"); 1656 } else if ((instr->RtValue() != instr->RsValue()) && 1657 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 1658 Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1659 } else if ((instr->RtValue() == instr->RsValue()) && 1660 (instr->RtValue() != 0)) { 1661 Format(instr, "bltzalc 'rt, 'imm16u -> 'imm16p4s2"); 1662 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 1663 Format(instr, "bgtzalc 'rt, 'imm16u -> 'imm16p4s2"); 1664 } else { 1665 UNREACHABLE(); 1666 } 1667 break; 1668 case BLEZL: 1669 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { 1670 Format(instr, "bgezc 'rt, 'imm16u -> 'imm16p4s2"); 1671 } else if ((instr->RtValue() != instr->RsValue()) && 1672 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 1673 Format(instr, "bgec 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1674 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 1675 Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2"); 1676 } else { 1677 UNREACHABLE(); 1678 } 1679 break; 1680 case BGTZL: 1681 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { 1682 Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2"); 1683 } else if ((instr->RtValue() != instr->RsValue()) && 1684 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 1685 Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1686 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 1687 Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2"); 1688 } else { 1689 UNREACHABLE(); 1690 } 1691 break; 1692 case POP66: 1693 if (instr->RsValue() == JIC) { 1694 Format(instr, "jic 'rt, 'imm16s"); 1695 } else { 1696 Format(instr, "beqzc 'rs, 'imm21s -> 'imm21p4s2"); 1697 } 1698 break; 1699 case POP76: 1700 if (instr->RsValue() == JIALC) { 1701 Format(instr, "jialc 'rt, 'imm16s"); 1702 } else { 1703 Format(instr, "bnezc 'rs, 'imm21s -> 'imm21p4s2"); 1704 } 1705 break; 1706 // ------------- Arithmetic instructions. 1707 case ADDI: 1708 if (kArchVariant != kMips64r6) { 1709 Format(instr, "addi 'rt, 'rs, 'imm16s"); 1710 } else { 1711 int rs_reg = instr->RsValue(); 1712 int rt_reg = instr->RtValue(); 1713 // Check if BOVC, BEQZALC or BEQC instruction. 1714 if (rs_reg >= rt_reg) { 1715 Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 1716 } else { 1717 DCHECK(rt_reg > 0); 1718 if (rs_reg == 0) { 1719 Format(instr, "beqzalc 'rt, 'imm16s -> 'imm16p4s2"); 1720 } else { 1721 Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 1722 } 1723 } 1724 } 1725 break; 1726 case DADDI: 1727 if (kArchVariant != kMips64r6) { 1728 Format(instr, "daddi 'rt, 'rs, 'imm16s"); 1729 } else { 1730 int rs_reg = instr->RsValue(); 1731 int rt_reg = instr->RtValue(); 1732 // Check if BNVC, BNEZALC or BNEC instruction. 1733 if (rs_reg >= rt_reg) { 1734 Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 1735 } else { 1736 DCHECK(rt_reg > 0); 1737 if (rs_reg == 0) { 1738 Format(instr, "bnezalc 'rt, 'imm16s -> 'imm16p4s2"); 1739 } else { 1740 Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 1741 } 1742 } 1743 } 1744 break; 1745 case ADDIU: 1746 Format(instr, "addiu 'rt, 'rs, 'imm16s"); 1747 break; 1748 case DADDIU: 1749 Format(instr, "daddiu 'rt, 'rs, 'imm16s"); 1750 break; 1751 case SLTI: 1752 Format(instr, "slti 'rt, 'rs, 'imm16s"); 1753 break; 1754 case SLTIU: 1755 Format(instr, "sltiu 'rt, 'rs, 'imm16u"); 1756 break; 1757 case ANDI: 1758 Format(instr, "andi 'rt, 'rs, 'imm16x"); 1759 break; 1760 case ORI: 1761 Format(instr, "ori 'rt, 'rs, 'imm16x"); 1762 break; 1763 case XORI: 1764 Format(instr, "xori 'rt, 'rs, 'imm16x"); 1765 break; 1766 case LUI: 1767 if (kArchVariant != kMips64r6) { 1768 Format(instr, "lui 'rt, 'imm16x"); 1769 } else { 1770 if (instr->RsValue() != 0) { 1771 Format(instr, "aui 'rt, 'rs, 'imm16x"); 1772 } else { 1773 Format(instr, "lui 'rt, 'imm16x"); 1774 } 1775 } 1776 break; 1777 case DAUI: 1778 Format(instr, "daui 'rt, 'rs, 'imm16x"); 1779 break; 1780 // ------------- Memory instructions. 1781 case LB: 1782 Format(instr, "lb 'rt, 'imm16s('rs)"); 1783 break; 1784 case LH: 1785 Format(instr, "lh 'rt, 'imm16s('rs)"); 1786 break; 1787 case LWL: 1788 Format(instr, "lwl 'rt, 'imm16s('rs)"); 1789 break; 1790 case LDL: 1791 Format(instr, "ldl 'rt, 'imm16s('rs)"); 1792 break; 1793 case LW: 1794 Format(instr, "lw 'rt, 'imm16s('rs)"); 1795 break; 1796 case LWU: 1797 Format(instr, "lwu 'rt, 'imm16s('rs)"); 1798 break; 1799 case LD: 1800 Format(instr, "ld 'rt, 'imm16s('rs)"); 1801 break; 1802 case LBU: 1803 Format(instr, "lbu 'rt, 'imm16s('rs)"); 1804 break; 1805 case LHU: 1806 Format(instr, "lhu 'rt, 'imm16s('rs)"); 1807 break; 1808 case LWR: 1809 Format(instr, "lwr 'rt, 'imm16s('rs)"); 1810 break; 1811 case LDR: 1812 Format(instr, "ldr 'rt, 'imm16s('rs)"); 1813 break; 1814 case PREF: 1815 Format(instr, "pref 'rt, 'imm16s('rs)"); 1816 break; 1817 case SB: 1818 Format(instr, "sb 'rt, 'imm16s('rs)"); 1819 break; 1820 case SH: 1821 Format(instr, "sh 'rt, 'imm16s('rs)"); 1822 break; 1823 case SWL: 1824 Format(instr, "swl 'rt, 'imm16s('rs)"); 1825 break; 1826 case SW: 1827 Format(instr, "sw 'rt, 'imm16s('rs)"); 1828 break; 1829 case SD: 1830 Format(instr, "sd 'rt, 'imm16s('rs)"); 1831 break; 1832 case SWR: 1833 Format(instr, "swr 'rt, 'imm16s('rs)"); 1834 break; 1835 case LWC1: 1836 Format(instr, "lwc1 'ft, 'imm16s('rs)"); 1837 break; 1838 case LDC1: 1839 Format(instr, "ldc1 'ft, 'imm16s('rs)"); 1840 break; 1841 case SWC1: 1842 Format(instr, "swc1 'ft, 'imm16s('rs)"); 1843 break; 1844 case SDC1: 1845 Format(instr, "sdc1 'ft, 'imm16s('rs)"); 1846 break; 1847 case PCREL: { 1848 int32_t imm21 = instr->Imm21Value(); 1849 // rt field: 5-bits checking 1850 uint8_t rt = (imm21 >> kImm16Bits); 1851 switch (rt) { 1852 case ALUIPC: 1853 Format(instr, "aluipc 'rs, 'imm16s"); 1854 break; 1855 case AUIPC: 1856 Format(instr, "auipc 'rs, 'imm16s"); 1857 break; 1858 default: { 1859 // rt field: checking of the most significant 3-bits 1860 rt = (imm21 >> kImm18Bits); 1861 switch (rt) { 1862 case LDPC: 1863 Format(instr, "ldpc 'rs, 'imm18s"); 1864 break; 1865 default: { 1866 // rt field: checking of the most significant 2-bits 1867 rt = (imm21 >> kImm19Bits); 1868 switch (rt) { 1869 case LWUPC: 1870 Format(instr, "lwupc 'rs, 'imm19s"); 1871 break; 1872 case LWPC: 1873 Format(instr, "lwpc 'rs, 'imm19s"); 1874 break; 1875 case ADDIUPC: 1876 Format(instr, "addiupc 'rs, 'imm19s"); 1877 break; 1878 default: 1879 UNREACHABLE(); 1880 break; 1881 } 1882 break; 1883 } 1884 } 1885 break; 1886 } 1887 } 1888 break; 1889 } 1890 default: 1891 printf("a 0x%x \n", instr->OpcodeFieldRaw()); 1892 UNREACHABLE(); 1893 break; 1894 } 1895 } 1896 1897 1898 void Decoder::DecodeTypeJump(Instruction* instr) { 1899 switch (instr->OpcodeFieldRaw()) { 1900 case J: 1901 Format(instr, "j 'imm26x -> 'imm26j"); 1902 break; 1903 case JAL: 1904 Format(instr, "jal 'imm26x -> 'imm26j"); 1905 break; 1906 default: 1907 UNREACHABLE(); 1908 } 1909 } 1910 1911 1912 // Disassemble the instruction at *instr_ptr into the output buffer. 1913 // All instructions are one word long, except for the simulator 1914 // psuedo-instruction stop(msg). For that one special case, we return 1915 // size larger than one kInstrSize. 1916 int Decoder::InstructionDecode(byte* instr_ptr) { 1917 Instruction* instr = Instruction::At(instr_ptr); 1918 // Print raw instruction bytes. 1919 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1920 "%08x ", 1921 instr->InstructionBits()); 1922 switch (instr->InstructionType(Instruction::TypeChecks::EXTRA)) { 1923 case Instruction::kRegisterType: { 1924 return DecodeTypeRegister(instr); 1925 } 1926 case Instruction::kImmediateType: { 1927 DecodeTypeImmediate(instr); 1928 break; 1929 } 1930 case Instruction::kJumpType: { 1931 DecodeTypeJump(instr); 1932 break; 1933 } 1934 default: { 1935 Format(instr, "UNSUPPORTED"); 1936 UNSUPPORTED_MIPS(); 1937 } 1938 } 1939 return Instruction::kInstrSize; 1940 } 1941 1942 1943 } // namespace internal 1944 } // namespace v8 1945 1946 1947 //------------------------------------------------------------------------------ 1948 1949 namespace disasm { 1950 1951 const char* NameConverter::NameOfAddress(byte* addr) const { 1952 v8::internal::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr)); 1953 return tmp_buffer_.start(); 1954 } 1955 1956 1957 const char* NameConverter::NameOfConstant(byte* addr) const { 1958 return NameOfAddress(addr); 1959 } 1960 1961 1962 const char* NameConverter::NameOfCPURegister(int reg) const { 1963 return v8::internal::Registers::Name(reg); 1964 } 1965 1966 1967 const char* NameConverter::NameOfXMMRegister(int reg) const { 1968 return v8::internal::FPURegisters::Name(reg); 1969 } 1970 1971 1972 const char* NameConverter::NameOfByteCPURegister(int reg) const { 1973 UNREACHABLE(); // MIPS does not have the concept of a byte register. 1974 return "nobytereg"; 1975 } 1976 1977 1978 const char* NameConverter::NameInCode(byte* addr) const { 1979 // The default name converter is called for unknown code. So we will not try 1980 // to access any memory. 1981 return ""; 1982 } 1983 1984 1985 //------------------------------------------------------------------------------ 1986 1987 Disassembler::Disassembler(const NameConverter& converter) 1988 : converter_(converter) {} 1989 1990 1991 Disassembler::~Disassembler() {} 1992 1993 1994 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, 1995 byte* instruction) { 1996 v8::internal::Decoder d(converter_, buffer); 1997 return d.InstructionDecode(instruction); 1998 } 1999 2000 2001 // The MIPS assembler does not currently use constant pools. 2002 int Disassembler::ConstantPoolSizeAt(byte* instruction) { 2003 return -1; 2004 } 2005 2006 2007 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { 2008 NameConverter converter; 2009 Disassembler d(converter); 2010 for (byte* pc = begin; pc < end;) { 2011 v8::internal::EmbeddedVector<char, 128> buffer; 2012 buffer[0] = '\0'; 2013 byte* prev_pc = pc; 2014 pc += d.InstructionDecode(buffer, pc); 2015 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), 2016 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); 2017 } 2018 } 2019 2020 2021 #undef UNSUPPORTED 2022 2023 } // namespace disasm 2024 2025 #endif // V8_TARGET_ARCH_MIPS64 2026