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