disasm-mips.cc revision f2e3994fa5148cc3d9946666f0b0596290192b0e
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 37namespace v8 { 38namespace 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. 45class 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. 141void Decoder::PrintChar(const char ch) { 142 out_buffer_[out_buffer_pos_++] = ch; 143} 144 145 146// Append the str to the output buffer. 147void 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. 158void Decoder::PrintRegister(int reg) { 159 Print(converter_.NameOfCPURegister(reg)); 160} 161 162 163void Decoder::PrintRs(Instruction* instr) { 164 int reg = instr->RsValue(); 165 PrintRegister(reg); 166} 167 168 169void Decoder::PrintRt(Instruction* instr) { 170 int reg = instr->RtValue(); 171 PrintRegister(reg); 172} 173 174 175void 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. 182void Decoder::PrintFPURegister(int freg) { 183 Print(converter_.NameOfXMMRegister(freg)); 184} 185 186 187void 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 198void Decoder::PrintFs(Instruction* instr) { 199 int freg = instr->RsValue(); 200 PrintFPURegister(freg); 201} 202 203 204void Decoder::PrintFt(Instruction* instr) { 205 int freg = instr->RtValue(); 206 PrintFPURegister(freg); 207} 208 209 210void Decoder::PrintFd(Instruction* instr) { 211 int freg = instr->RdValue(); 212 PrintFPURegister(freg); 213} 214 215 216// Print the integer value of the sa field. 217void 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. 224void 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. 231void 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. 238void 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. 245void 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. 254void 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. 261void 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 267void 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. 274void 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. 281void 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. 288void 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) 297void 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. 307void 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. 315void 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. 322void 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. 329void 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. 339void 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. 346void 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) 358void 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. 371void 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. 380void 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) 392void 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 407void 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. 418void 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 445void 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. 469void Decoder::PrintInstructionName(Instruction* instr) { 470} 471 472 473// Handle all register based formatting in this function to reduce the 474// complexity of FormatOption. 475int 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. 497int 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. 546int 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. 758void 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. 774void Decoder::Unknown(Instruction* instr) { 775 Format(instr, "unknown"); 776} 777 778 779bool 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 915void 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 929void Decoder::DecodeTypeRegisterDRsType(Instruction* instr) { 930 if (!DecodeTypeRegisterRsType(instr)) { 931 Format(instr, "unknown.cop1.'t"); 932 } 933} 934 935 936void 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 983void 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 1030void 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 MOVZ: 1195 Format(instr, "movz 'rd, 'rs, 'rt"); 1196 break; 1197 case MOVN: 1198 Format(instr, "movn 'rd, 'rs, 'rt"); 1199 break; 1200 case MOVCI: 1201 if (instr->Bit(16)) { 1202 Format(instr, "movt 'rd, 'rs, 'bc"); 1203 } else { 1204 Format(instr, "movf 'rd, 'rs, 'bc"); 1205 } 1206 break; 1207 case SELEQZ_S: 1208 Format(instr, "seleqz 'rd, 'rs, 'rt"); 1209 break; 1210 case SELNEZ_S: 1211 Format(instr, "selnez 'rd, 'rs, 'rt"); 1212 break; 1213 default: 1214 UNREACHABLE(); 1215 } 1216} 1217 1218 1219void Decoder::DecodeTypeRegisterSPECIAL2(Instruction* instr) { 1220 switch (instr->FunctionFieldRaw()) { 1221 case MUL: 1222 Format(instr, "mul 'rd, 'rs, 'rt"); 1223 break; 1224 case CLZ: 1225 if (!IsMipsArchVariant(kMips32r6)) { 1226 Format(instr, "clz 'rd, 'rs"); 1227 } 1228 break; 1229 default: 1230 UNREACHABLE(); 1231 } 1232} 1233 1234 1235void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) { 1236 switch (instr->FunctionFieldRaw()) { 1237 case INS: { 1238 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { 1239 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); 1240 } else { 1241 Unknown(instr); 1242 } 1243 break; 1244 } 1245 case EXT: { 1246 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { 1247 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); 1248 } else { 1249 Unknown(instr); 1250 } 1251 break; 1252 } 1253 case BSHFL: { 1254 int sa = instr->SaFieldRaw() >> kSaShift; 1255 switch (sa) { 1256 case BITSWAP: { 1257 if (IsMipsArchVariant(kMips32r6)) { 1258 Format(instr, "bitswap 'rd, 'rt"); 1259 } else { 1260 Unknown(instr); 1261 } 1262 break; 1263 } 1264 case SEB: 1265 case SEH: 1266 case WSBH: 1267 UNREACHABLE(); 1268 break; 1269 default: { 1270 sa >>= kBp2Bits; 1271 switch (sa) { 1272 case ALIGN: { 1273 if (IsMipsArchVariant(kMips32r6)) { 1274 Format(instr, "align 'rd, 'rs, 'rt, 'bp2"); 1275 } else { 1276 Unknown(instr); 1277 } 1278 break; 1279 } 1280 default: 1281 UNREACHABLE(); 1282 break; 1283 } 1284 } 1285 } 1286 break; 1287 } 1288 default: 1289 UNREACHABLE(); 1290 } 1291} 1292 1293 1294void Decoder::DecodeTypeRegister(Instruction* instr) { 1295 switch (instr->OpcodeFieldRaw()) { 1296 case COP1: // Coprocessor instructions. 1297 switch (instr->RsFieldRaw()) { 1298 case BC1: // bc1 handled in DecodeTypeImmediate. 1299 UNREACHABLE(); 1300 break; 1301 case MFC1: 1302 Format(instr, "mfc1 'rt, 'fs"); 1303 break; 1304 case MFHC1: 1305 Format(instr, "mfhc1 'rt, 'fs"); 1306 break; 1307 case MTC1: 1308 Format(instr, "mtc1 'rt, 'fs"); 1309 break; 1310 // These are called "fs" too, although they are not FPU registers. 1311 case CTC1: 1312 Format(instr, "ctc1 'rt, 'fs"); 1313 break; 1314 case CFC1: 1315 Format(instr, "cfc1 'rt, 'fs"); 1316 break; 1317 case MTHC1: 1318 Format(instr, "mthc1 'rt, 'fs"); 1319 break; 1320 case S: 1321 DecodeTypeRegisterSRsType(instr); 1322 break; 1323 case D: 1324 DecodeTypeRegisterDRsType(instr); 1325 break; 1326 case L: 1327 DecodeTypeRegisterLRsType(instr); 1328 break; 1329 case W: 1330 DecodeTypeRegisterWRsType(instr); 1331 break; 1332 case PS: 1333 UNIMPLEMENTED_MIPS(); 1334 break; 1335 default: 1336 UNREACHABLE(); 1337 } 1338 break; 1339 case COP1X: 1340 switch (instr->FunctionFieldRaw()) { 1341 case MADD_D: 1342 Format(instr, "madd.d 'fd, 'fr, 'fs, 'ft"); 1343 break; 1344 default: 1345 UNREACHABLE(); 1346 } 1347 break; 1348 case SPECIAL: 1349 DecodeTypeRegisterSPECIAL(instr); 1350 break; 1351 case SPECIAL2: 1352 DecodeTypeRegisterSPECIAL2(instr); 1353 break; 1354 case SPECIAL3: 1355 DecodeTypeRegisterSPECIAL3(instr); 1356 break; 1357 default: 1358 UNREACHABLE(); 1359 } 1360} 1361 1362 1363void Decoder::DecodeTypeImmediate(Instruction* instr) { 1364 switch (instr->OpcodeFieldRaw()) { 1365 case COP1: 1366 switch (instr->RsFieldRaw()) { 1367 case BC1: 1368 if (instr->FBtrueValue()) { 1369 Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2"); 1370 } else { 1371 Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2"); 1372 } 1373 break; 1374 case BC1EQZ: 1375 Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2"); 1376 break; 1377 case BC1NEZ: 1378 Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2"); 1379 break; 1380 default: 1381 UNREACHABLE(); 1382 } 1383 1384 break; // Case COP1. 1385 // ------------- REGIMM class. 1386 case REGIMM: 1387 switch (instr->RtFieldRaw()) { 1388 case BLTZ: 1389 Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2"); 1390 break; 1391 case BLTZAL: 1392 Format(instr, "bltzal 'rs, 'imm16u -> 'imm16p4s2"); 1393 break; 1394 case BGEZ: 1395 Format(instr, "bgez 'rs, 'imm16u -> 'imm16p4s2"); 1396 break; 1397 case BGEZAL: { 1398 if (instr->RsValue() == 0) 1399 Format(instr, "bal 'imm16s -> 'imm16p4s2"); 1400 else 1401 Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2"); 1402 break; 1403 } 1404 case BGEZALL: 1405 Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2"); 1406 break; 1407 default: 1408 UNREACHABLE(); 1409 } 1410 break; // Case REGIMM. 1411 // ------------- Branch instructions. 1412 case BEQ: 1413 Format(instr, "beq 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1414 break; 1415 case BC: 1416 Format(instr, "bc 'imm26s -> 'imm26p4s2"); 1417 break; 1418 case BALC: 1419 Format(instr, "balc 'imm26s -> 'imm26p4s2"); 1420 break; 1421 case BNE: 1422 Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1423 break; 1424 case BLEZ: 1425 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { 1426 Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2"); 1427 } else if ((instr->RtValue() != instr->RsValue()) && 1428 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 1429 Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1430 } else if ((instr->RtValue() == instr->RsValue()) && 1431 (instr->RtValue() != 0)) { 1432 Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2"); 1433 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 1434 Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2"); 1435 } else { 1436 UNREACHABLE(); 1437 } 1438 break; 1439 case BGTZ: 1440 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { 1441 Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2"); 1442 } else if ((instr->RtValue() != instr->RsValue()) && 1443 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 1444 Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1445 } else if ((instr->RtValue() == instr->RsValue()) && 1446 (instr->RtValue() != 0)) { 1447 Format(instr, "bltzalc 'rt, 'imm16u -> 'imm16p4s2"); 1448 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 1449 Format(instr, "bgtzalc 'rt, 'imm16u -> 'imm16p4s2"); 1450 } else { 1451 UNREACHABLE(); 1452 } 1453 break; 1454 case BLEZL: 1455 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { 1456 Format(instr, "bgezc 'rt, 'imm16u -> 'imm16p4s2"); 1457 } else if ((instr->RtValue() != instr->RsValue()) && 1458 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 1459 Format(instr, "bgec 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1460 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 1461 Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2"); 1462 } else { 1463 UNREACHABLE(); 1464 } 1465 break; 1466 case BGTZL: 1467 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { 1468 Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2"); 1469 } else if ((instr->RtValue() != instr->RsValue()) && 1470 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 1471 Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1472 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 1473 Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2"); 1474 } else { 1475 UNREACHABLE(); 1476 } 1477 break; 1478 case POP66: 1479 if (instr->RsValue() == JIC) { 1480 Format(instr, "jic 'rt, 'imm16s"); 1481 } else { 1482 Format(instr, "beqzc 'rs, 'imm21s -> 'imm21p4s2"); 1483 } 1484 break; 1485 case POP76: 1486 if (instr->RsValue() == JIALC) { 1487 Format(instr, "jialc 'rt, 'imm16s"); 1488 } else { 1489 Format(instr, "bnezc 'rs, 'imm21s -> 'imm21p4s2"); 1490 } 1491 break; 1492 // ------------- Arithmetic instructions. 1493 case ADDI: 1494 if (!IsMipsArchVariant(kMips32r6)) { 1495 Format(instr, "addi 'rt, 'rs, 'imm16s"); 1496 } else { 1497 int rs_reg = instr->RsValue(); 1498 int rt_reg = instr->RtValue(); 1499 // Check if BOVC, BEQZALC or BEQC instruction. 1500 if (rs_reg >= rt_reg) { 1501 Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 1502 } else { 1503 if (rs_reg == 0) { 1504 Format(instr, "beqzalc 'rt, 'imm16s -> 'imm16p4s2"); 1505 } else { 1506 Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 1507 } 1508 } 1509 } 1510 break; 1511 case DADDI: 1512 if (IsMipsArchVariant(kMips32r6)) { 1513 int rs_reg = instr->RsValue(); 1514 int rt_reg = instr->RtValue(); 1515 // Check if BNVC, BNEZALC or BNEC instruction. 1516 if (rs_reg >= rt_reg) { 1517 Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 1518 } else { 1519 if (rs_reg == 0) { 1520 Format(instr, "bnezalc 'rt, 'imm16s -> 'imm16p4s2"); 1521 } else { 1522 Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 1523 } 1524 } 1525 } 1526 break; 1527 case ADDIU: 1528 Format(instr, "addiu 'rt, 'rs, 'imm16s"); 1529 break; 1530 case SLTI: 1531 Format(instr, "slti 'rt, 'rs, 'imm16s"); 1532 break; 1533 case SLTIU: 1534 Format(instr, "sltiu 'rt, 'rs, 'imm16u"); 1535 break; 1536 case ANDI: 1537 Format(instr, "andi 'rt, 'rs, 'imm16x"); 1538 break; 1539 case ORI: 1540 Format(instr, "ori 'rt, 'rs, 'imm16x"); 1541 break; 1542 case XORI: 1543 Format(instr, "xori 'rt, 'rs, 'imm16x"); 1544 break; 1545 case LUI: 1546 if (!IsMipsArchVariant(kMips32r6)) { 1547 Format(instr, "lui 'rt, 'imm16x"); 1548 } else { 1549 if (instr->RsValue() != 0) { 1550 Format(instr, "aui 'rt, 'rs, 'imm16x"); 1551 } else { 1552 Format(instr, "lui 'rt, 'imm16x"); 1553 } 1554 } 1555 break; 1556 // ------------- Memory instructions. 1557 case LB: 1558 Format(instr, "lb 'rt, 'imm16s('rs)"); 1559 break; 1560 case LH: 1561 Format(instr, "lh 'rt, 'imm16s('rs)"); 1562 break; 1563 case LWL: 1564 Format(instr, "lwl 'rt, 'imm16s('rs)"); 1565 break; 1566 case LW: 1567 Format(instr, "lw 'rt, 'imm16s('rs)"); 1568 break; 1569 case LBU: 1570 Format(instr, "lbu 'rt, 'imm16s('rs)"); 1571 break; 1572 case LHU: 1573 Format(instr, "lhu 'rt, 'imm16s('rs)"); 1574 break; 1575 case LWR: 1576 Format(instr, "lwr 'rt, 'imm16s('rs)"); 1577 break; 1578 case PREF: 1579 Format(instr, "pref 'rt, 'imm16s('rs)"); 1580 break; 1581 case SB: 1582 Format(instr, "sb 'rt, 'imm16s('rs)"); 1583 break; 1584 case SH: 1585 Format(instr, "sh 'rt, 'imm16s('rs)"); 1586 break; 1587 case SWL: 1588 Format(instr, "swl 'rt, 'imm16s('rs)"); 1589 break; 1590 case SW: 1591 Format(instr, "sw 'rt, 'imm16s('rs)"); 1592 break; 1593 case SWR: 1594 Format(instr, "swr 'rt, 'imm16s('rs)"); 1595 break; 1596 case LWC1: 1597 Format(instr, "lwc1 'ft, 'imm16s('rs)"); 1598 break; 1599 case LDC1: 1600 Format(instr, "ldc1 'ft, 'imm16s('rs)"); 1601 break; 1602 case SWC1: 1603 Format(instr, "swc1 'ft, 'imm16s('rs)"); 1604 break; 1605 case SDC1: 1606 Format(instr, "sdc1 'ft, 'imm16s('rs)"); 1607 break; 1608 case PCREL: { 1609 int32_t imm21 = instr->Imm21Value(); 1610 // rt field: 5-bits checking 1611 uint8_t rt = (imm21 >> kImm16Bits); 1612 switch (rt) { 1613 case ALUIPC: 1614 Format(instr, "aluipc 'rs, 'imm16s"); 1615 break; 1616 case AUIPC: 1617 Format(instr, "auipc 'rs, 'imm16s"); 1618 break; 1619 default: { 1620 // rt field: checking of the most significant 2-bits 1621 rt = (imm21 >> kImm19Bits); 1622 switch (rt) { 1623 case LWPC: 1624 Format(instr, "lwpc 'rs, 'imm19s"); 1625 break; 1626 case ADDIUPC: 1627 Format(instr, "addiupc 'rs, 'imm19s"); 1628 break; 1629 default: 1630 UNREACHABLE(); 1631 break; 1632 } 1633 } 1634 } 1635 break; 1636 } 1637 default: 1638 printf("a 0x%x \n", instr->OpcodeFieldRaw()); 1639 UNREACHABLE(); 1640 break; 1641 } 1642} 1643 1644 1645void Decoder::DecodeTypeJump(Instruction* instr) { 1646 switch (instr->OpcodeFieldRaw()) { 1647 case J: 1648 Format(instr, "j 'imm26x -> 'imm26j"); 1649 break; 1650 case JAL: 1651 Format(instr, "jal 'imm26x -> 'imm26j"); 1652 break; 1653 default: 1654 UNREACHABLE(); 1655 } 1656} 1657 1658 1659// Disassemble the instruction at *instr_ptr into the output buffer. 1660int Decoder::InstructionDecode(byte* instr_ptr) { 1661 Instruction* instr = Instruction::At(instr_ptr); 1662 // Print raw instruction bytes. 1663 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1664 "%08x ", 1665 instr->InstructionBits()); 1666 switch (instr->InstructionType(Instruction::EXTRA)) { 1667 case Instruction::kRegisterType: { 1668 DecodeTypeRegister(instr); 1669 break; 1670 } 1671 case Instruction::kImmediateType: { 1672 DecodeTypeImmediate(instr); 1673 break; 1674 } 1675 case Instruction::kJumpType: { 1676 DecodeTypeJump(instr); 1677 break; 1678 } 1679 default: { 1680 Format(instr, "UNSUPPORTED"); 1681 UNSUPPORTED_MIPS(); 1682 } 1683 } 1684 return Instruction::kInstrSize; 1685} 1686 1687 1688} // namespace internal 1689} // namespace v8 1690 1691 1692//------------------------------------------------------------------------------ 1693 1694namespace disasm { 1695 1696const char* NameConverter::NameOfAddress(byte* addr) const { 1697 v8::internal::SNPrintF(tmp_buffer_, "%p", addr); 1698 return tmp_buffer_.start(); 1699} 1700 1701 1702const char* NameConverter::NameOfConstant(byte* addr) const { 1703 return NameOfAddress(addr); 1704} 1705 1706 1707const char* NameConverter::NameOfCPURegister(int reg) const { 1708 return v8::internal::Registers::Name(reg); 1709} 1710 1711 1712const char* NameConverter::NameOfXMMRegister(int reg) const { 1713 return v8::internal::FPURegisters::Name(reg); 1714} 1715 1716 1717const char* NameConverter::NameOfByteCPURegister(int reg) const { 1718 UNREACHABLE(); // MIPS does not have the concept of a byte register. 1719 return "nobytereg"; 1720} 1721 1722 1723const char* NameConverter::NameInCode(byte* addr) const { 1724 // The default name converter is called for unknown code. So we will not try 1725 // to access any memory. 1726 return ""; 1727} 1728 1729 1730//------------------------------------------------------------------------------ 1731 1732Disassembler::Disassembler(const NameConverter& converter) 1733 : converter_(converter) {} 1734 1735 1736Disassembler::~Disassembler() {} 1737 1738 1739int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, 1740 byte* instruction) { 1741 v8::internal::Decoder d(converter_, buffer); 1742 return d.InstructionDecode(instruction); 1743} 1744 1745 1746// The MIPS assembler does not currently use constant pools. 1747int Disassembler::ConstantPoolSizeAt(byte* instruction) { 1748 return -1; 1749} 1750 1751 1752void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { 1753 NameConverter converter; 1754 Disassembler d(converter); 1755 for (byte* pc = begin; pc < end;) { 1756 v8::internal::EmbeddedVector<char, 128> buffer; 1757 buffer[0] = '\0'; 1758 byte* prev_pc = pc; 1759 pc += d.InstructionDecode(buffer, pc); 1760 v8::internal::PrintF(f, "%p %08x %s\n", 1761 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); 1762 } 1763} 1764 1765 1766#undef UNSUPPORTED 1767 1768} // namespace disasm 1769 1770#endif // V8_TARGET_ARCH_MIPS 1771