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