1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 // A Disassembler object is used to disassemble a block of code instruction by 29 // instruction. The default implementation of the NameConverter object can be 30 // overriden to modify register names or to do symbol lookup on addresses. 31 // 32 // The example below will disassemble a block of code and print it to stdout. 33 // 34 // NameConverter converter; 35 // Disassembler d(converter); 36 // for (byte* pc = begin; pc < end;) { 37 // v8::internal::EmbeddedVector<char, 256> buffer; 38 // byte* prev_pc = pc; 39 // pc += d.InstructionDecode(buffer, pc); 40 // printf("%p %08x %s\n", 41 // prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer); 42 // } 43 // 44 // The Disassembler class also has a convenience method to disassemble a block 45 // of code into a FILE*, meaning that the above functionality could also be 46 // achieved by just calling Disassembler::Disassemble(stdout, begin, end); 47 48 49 #include <assert.h> 50 #include <stdio.h> 51 #include <stdarg.h> 52 #include <string.h> 53 #ifndef WIN32 54 #include <stdint.h> 55 #endif 56 57 #include "v8.h" 58 59 #if defined(V8_TARGET_ARCH_MIPS) 60 61 #include "mips/constants-mips.h" 62 #include "disasm.h" 63 #include "macro-assembler.h" 64 #include "platform.h" 65 66 namespace v8 { 67 namespace internal { 68 69 //------------------------------------------------------------------------------ 70 71 // Decoder decodes and disassembles instructions into an output buffer. 72 // It uses the converter to convert register names and call destinations into 73 // more informative description. 74 class Decoder { 75 public: 76 Decoder(const disasm::NameConverter& converter, 77 v8::internal::Vector<char> out_buffer) 78 : converter_(converter), 79 out_buffer_(out_buffer), 80 out_buffer_pos_(0) { 81 out_buffer_[out_buffer_pos_] = '\0'; 82 } 83 84 ~Decoder() {} 85 86 // Writes one disassembled instruction into 'buffer' (0-terminated). 87 // Returns the length of the disassembled machine instruction in bytes. 88 int InstructionDecode(byte* instruction); 89 90 private: 91 // Bottleneck functions to print into the out_buffer. 92 void PrintChar(const char ch); 93 void Print(const char* str); 94 95 // Printing of common values. 96 void PrintRegister(int reg); 97 void PrintFPURegister(int freg); 98 void PrintRs(Instruction* instr); 99 void PrintRt(Instruction* instr); 100 void PrintRd(Instruction* instr); 101 void PrintFs(Instruction* instr); 102 void PrintFt(Instruction* instr); 103 void PrintFd(Instruction* instr); 104 void PrintSa(Instruction* instr); 105 void PrintSd(Instruction* instr); 106 void PrintSs1(Instruction* instr); 107 void PrintSs2(Instruction* instr); 108 void PrintBc(Instruction* instr); 109 void PrintCc(Instruction* instr); 110 void PrintFunction(Instruction* instr); 111 void PrintSecondaryField(Instruction* instr); 112 void PrintUImm16(Instruction* instr); 113 void PrintSImm16(Instruction* instr); 114 void PrintXImm16(Instruction* instr); 115 void PrintXImm26(Instruction* instr); 116 void PrintCode(Instruction* instr); // For break and trap instructions. 117 // Printing of instruction name. 118 void PrintInstructionName(Instruction* instr); 119 120 // Handle formatting of instructions and their options. 121 int FormatRegister(Instruction* instr, const char* option); 122 int FormatFPURegister(Instruction* instr, const char* option); 123 int FormatOption(Instruction* instr, const char* option); 124 void Format(Instruction* instr, const char* format); 125 void Unknown(Instruction* instr); 126 127 // Each of these functions decodes one particular instruction type. 128 void DecodeTypeRegister(Instruction* instr); 129 void DecodeTypeImmediate(Instruction* instr); 130 void DecodeTypeJump(Instruction* instr); 131 132 const disasm::NameConverter& converter_; 133 v8::internal::Vector<char> out_buffer_; 134 int out_buffer_pos_; 135 136 DISALLOW_COPY_AND_ASSIGN(Decoder); 137 }; 138 139 140 // Support for assertions in the Decoder formatting functions. 141 #define STRING_STARTS_WITH(string, compare_string) \ 142 (strncmp(string, compare_string, strlen(compare_string)) == 0) 143 144 145 // Append the ch to the output buffer. 146 void Decoder::PrintChar(const char ch) { 147 out_buffer_[out_buffer_pos_++] = ch; 148 } 149 150 151 // Append the str to the output buffer. 152 void Decoder::Print(const char* str) { 153 char cur = *str++; 154 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 155 PrintChar(cur); 156 cur = *str++; 157 } 158 out_buffer_[out_buffer_pos_] = 0; 159 } 160 161 162 // Print the register name according to the active name converter. 163 void Decoder::PrintRegister(int reg) { 164 Print(converter_.NameOfCPURegister(reg)); 165 } 166 167 168 void Decoder::PrintRs(Instruction* instr) { 169 int reg = instr->RsValue(); 170 PrintRegister(reg); 171 } 172 173 174 void Decoder::PrintRt(Instruction* instr) { 175 int reg = instr->RtValue(); 176 PrintRegister(reg); 177 } 178 179 180 void Decoder::PrintRd(Instruction* instr) { 181 int reg = instr->RdValue(); 182 PrintRegister(reg); 183 } 184 185 186 // Print the FPUregister name according to the active name converter. 187 void Decoder::PrintFPURegister(int freg) { 188 Print(converter_.NameOfXMMRegister(freg)); 189 } 190 191 192 void Decoder::PrintFs(Instruction* instr) { 193 int freg = instr->RsValue(); 194 PrintFPURegister(freg); 195 } 196 197 198 void Decoder::PrintFt(Instruction* instr) { 199 int freg = instr->RtValue(); 200 PrintFPURegister(freg); 201 } 202 203 204 void Decoder::PrintFd(Instruction* instr) { 205 int freg = instr->RdValue(); 206 PrintFPURegister(freg); 207 } 208 209 210 // Print the integer value of the sa field. 211 void Decoder::PrintSa(Instruction* instr) { 212 int sa = instr->SaValue(); 213 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa); 214 } 215 216 217 // Print the integer value of the rd field, when it is not used as reg. 218 void Decoder::PrintSd(Instruction* instr) { 219 int sd = instr->RdValue(); 220 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sd); 221 } 222 223 224 // Print the integer value of the rd field, when used as 'ext' size. 225 void Decoder::PrintSs1(Instruction* instr) { 226 int ss = instr->RdValue(); 227 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss + 1); 228 } 229 230 231 // Print the integer value of the rd field, when used as 'ins' size. 232 void Decoder::PrintSs2(Instruction* instr) { 233 int ss = instr->RdValue(); 234 int pos = instr->SaValue(); 235 out_buffer_pos_ += 236 OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss - pos + 1); 237 } 238 239 240 // Print the integer value of the cc field for the bc1t/f instructions. 241 void Decoder::PrintBc(Instruction* instr) { 242 int cc = instr->FBccValue(); 243 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", cc); 244 } 245 246 247 // Print the integer value of the cc field for the FP compare instructions. 248 void Decoder::PrintCc(Instruction* instr) { 249 int cc = instr->FCccValue(); 250 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "cc(%d)", cc); 251 } 252 253 254 // Print 16-bit unsigned immediate value. 255 void Decoder::PrintUImm16(Instruction* instr) { 256 int32_t imm = instr->Imm16Value(); 257 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); 258 } 259 260 261 // Print 16-bit signed immediate value. 262 void Decoder::PrintSImm16(Instruction* instr) { 263 int32_t imm = ((instr->Imm16Value()) << 16) >> 16; 264 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 265 } 266 267 268 // Print 16-bit hexa immediate value. 269 void Decoder::PrintXImm16(Instruction* instr) { 270 int32_t imm = instr->Imm16Value(); 271 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 272 } 273 274 275 // Print 26-bit immediate value. 276 void Decoder::PrintXImm26(Instruction* instr) { 277 uint32_t imm = instr->Imm26Value() << kImmFieldShift; 278 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 279 } 280 281 282 // Print 26-bit immediate value. 283 void Decoder::PrintCode(Instruction* instr) { 284 if (instr->OpcodeFieldRaw() != SPECIAL) 285 return; // Not a break or trap instruction. 286 switch (instr->FunctionFieldRaw()) { 287 case BREAK: { 288 int32_t code = instr->Bits(25, 6); 289 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, 290 "0x%05x (%d)", code, code); 291 break; 292 } 293 case TGE: 294 case TGEU: 295 case TLT: 296 case TLTU: 297 case TEQ: 298 case TNE: { 299 int32_t code = instr->Bits(15, 6); 300 out_buffer_pos_ += 301 OS::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code); 302 break; 303 } 304 default: // Not a break or trap instruction. 305 break; 306 }; 307 } 308 309 310 // Printing of instruction name. 311 void Decoder::PrintInstructionName(Instruction* instr) { 312 } 313 314 315 // Handle all register based formatting in this function to reduce the 316 // complexity of FormatOption. 317 int Decoder::FormatRegister(Instruction* instr, const char* format) { 318 ASSERT(format[0] == 'r'); 319 if (format[1] == 's') { // 'rs: Rs register. 320 int reg = instr->RsValue(); 321 PrintRegister(reg); 322 return 2; 323 } else if (format[1] == 't') { // 'rt: rt register. 324 int reg = instr->RtValue(); 325 PrintRegister(reg); 326 return 2; 327 } else if (format[1] == 'd') { // 'rd: rd register. 328 int reg = instr->RdValue(); 329 PrintRegister(reg); 330 return 2; 331 } 332 UNREACHABLE(); 333 return -1; 334 } 335 336 337 // Handle all FPUregister based formatting in this function to reduce the 338 // complexity of FormatOption. 339 int Decoder::FormatFPURegister(Instruction* instr, const char* format) { 340 ASSERT(format[0] == 'f'); 341 if (format[1] == 's') { // 'fs: fs register. 342 int reg = instr->FsValue(); 343 PrintFPURegister(reg); 344 return 2; 345 } else if (format[1] == 't') { // 'ft: ft register. 346 int reg = instr->FtValue(); 347 PrintFPURegister(reg); 348 return 2; 349 } else if (format[1] == 'd') { // 'fd: fd register. 350 int reg = instr->FdValue(); 351 PrintFPURegister(reg); 352 return 2; 353 } 354 UNREACHABLE(); 355 return -1; 356 } 357 358 359 // FormatOption takes a formatting string and interprets it based on 360 // the current instructions. The format string points to the first 361 // character of the option string (the option escape has already been 362 // consumed by the caller.) FormatOption returns the number of 363 // characters that were consumed from the formatting string. 364 int Decoder::FormatOption(Instruction* instr, const char* format) { 365 switch (format[0]) { 366 case 'c': { // 'code for break or trap instructions. 367 ASSERT(STRING_STARTS_WITH(format, "code")); 368 PrintCode(instr); 369 return 4; 370 } 371 case 'i': { // 'imm16u or 'imm26. 372 if (format[3] == '1') { 373 ASSERT(STRING_STARTS_WITH(format, "imm16")); 374 if (format[5] == 's') { 375 ASSERT(STRING_STARTS_WITH(format, "imm16s")); 376 PrintSImm16(instr); 377 } else if (format[5] == 'u') { 378 ASSERT(STRING_STARTS_WITH(format, "imm16u")); 379 PrintSImm16(instr); 380 } else { 381 ASSERT(STRING_STARTS_WITH(format, "imm16x")); 382 PrintXImm16(instr); 383 } 384 return 6; 385 } else { 386 ASSERT(STRING_STARTS_WITH(format, "imm26x")); 387 PrintXImm26(instr); 388 return 6; 389 } 390 } 391 case 'r': { // 'r: registers. 392 return FormatRegister(instr, format); 393 } 394 case 'f': { // 'f: FPUregisters. 395 return FormatFPURegister(instr, format); 396 } 397 case 's': { // 'sa. 398 switch (format[1]) { 399 case 'a': { 400 ASSERT(STRING_STARTS_WITH(format, "sa")); 401 PrintSa(instr); 402 return 2; 403 } 404 case 'd': { 405 ASSERT(STRING_STARTS_WITH(format, "sd")); 406 PrintSd(instr); 407 return 2; 408 } 409 case 's': { 410 if (format[2] == '1') { 411 ASSERT(STRING_STARTS_WITH(format, "ss1")); /* ext size */ 412 PrintSs1(instr); 413 return 3; 414 } else { 415 ASSERT(STRING_STARTS_WITH(format, "ss2")); /* ins size */ 416 PrintSs2(instr); 417 return 3; 418 } 419 } 420 } 421 } 422 case 'b': { // 'bc - Special for bc1 cc field. 423 ASSERT(STRING_STARTS_WITH(format, "bc")); 424 PrintBc(instr); 425 return 2; 426 } 427 case 'C': { // 'Cc - Special for c.xx.d cc field. 428 ASSERT(STRING_STARTS_WITH(format, "Cc")); 429 PrintCc(instr); 430 return 2; 431 } 432 }; 433 UNREACHABLE(); 434 return -1; 435 } 436 437 438 // Format takes a formatting string for a whole instruction and prints it into 439 // the output buffer. All escaped options are handed to FormatOption to be 440 // parsed further. 441 void Decoder::Format(Instruction* instr, const char* format) { 442 char cur = *format++; 443 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 444 if (cur == '\'') { // Single quote is used as the formatting escape. 445 format += FormatOption(instr, format); 446 } else { 447 out_buffer_[out_buffer_pos_++] = cur; 448 } 449 cur = *format++; 450 } 451 out_buffer_[out_buffer_pos_] = '\0'; 452 } 453 454 455 // For currently unimplemented decodings the disassembler calls Unknown(instr) 456 // which will just print "unknown" of the instruction bits. 457 void Decoder::Unknown(Instruction* instr) { 458 Format(instr, "unknown"); 459 } 460 461 462 void Decoder::DecodeTypeRegister(Instruction* instr) { 463 switch (instr->OpcodeFieldRaw()) { 464 case COP1: // Coprocessor instructions. 465 switch (instr->RsFieldRaw()) { 466 case BC1: // bc1 handled in DecodeTypeImmediate. 467 UNREACHABLE(); 468 break; 469 case MFC1: 470 Format(instr, "mfc1 'rt, 'fs"); 471 break; 472 case MFHC1: 473 Format(instr, "mfhc1 'rt, 'fs"); 474 break; 475 case MTC1: 476 Format(instr, "mtc1 'rt, 'fs"); 477 break; 478 // These are called "fs" too, although they are not FPU registers. 479 case CTC1: 480 Format(instr, "ctc1 'rt, 'fs"); 481 break; 482 case CFC1: 483 Format(instr, "cfc1 'rt, 'fs"); 484 break; 485 case MTHC1: 486 Format(instr, "mthc1 'rt, 'fs"); 487 break; 488 case D: 489 switch (instr->FunctionFieldRaw()) { 490 case ADD_D: 491 Format(instr, "add.d 'fd, 'fs, 'ft"); 492 break; 493 case SUB_D: 494 Format(instr, "sub.d 'fd, 'fs, 'ft"); 495 break; 496 case MUL_D: 497 Format(instr, "mul.d 'fd, 'fs, 'ft"); 498 break; 499 case DIV_D: 500 Format(instr, "div.d 'fd, 'fs, 'ft"); 501 break; 502 case ABS_D: 503 Format(instr, "abs.d 'fd, 'fs"); 504 break; 505 case MOV_D: 506 Format(instr, "mov.d 'fd, 'fs"); 507 break; 508 case NEG_D: 509 Format(instr, "neg.d 'fd, 'fs"); 510 break; 511 case SQRT_D: 512 Format(instr, "sqrt.d 'fd, 'fs"); 513 break; 514 case CVT_W_D: 515 Format(instr, "cvt.w.d 'fd, 'fs"); 516 break; 517 case CVT_L_D: { 518 if (kArchVariant == kMips32r2) { 519 Format(instr, "cvt.l.d 'fd, 'fs"); 520 } else { 521 Unknown(instr); 522 } 523 break; 524 } 525 case TRUNC_W_D: 526 Format(instr, "trunc.w.d 'fd, 'fs"); 527 break; 528 case TRUNC_L_D: { 529 if (kArchVariant == kMips32r2) { 530 Format(instr, "trunc.l.d 'fd, 'fs"); 531 } else { 532 Unknown(instr); 533 } 534 break; 535 } 536 case ROUND_W_D: 537 Format(instr, "round.w.d 'fd, 'fs"); 538 break; 539 case FLOOR_W_D: 540 Format(instr, "floor.w.d 'fd, 'fs"); 541 break; 542 case CEIL_W_D: 543 Format(instr, "ceil.w.d 'fd, 'fs"); 544 break; 545 case CVT_S_D: 546 Format(instr, "cvt.s.d 'fd, 'fs"); 547 break; 548 case C_F_D: 549 Format(instr, "c.f.d 'fs, 'ft, 'Cc"); 550 break; 551 case C_UN_D: 552 Format(instr, "c.un.d 'fs, 'ft, 'Cc"); 553 break; 554 case C_EQ_D: 555 Format(instr, "c.eq.d 'fs, 'ft, 'Cc"); 556 break; 557 case C_UEQ_D: 558 Format(instr, "c.ueq.d 'fs, 'ft, 'Cc"); 559 break; 560 case C_OLT_D: 561 Format(instr, "c.olt.d 'fs, 'ft, 'Cc"); 562 break; 563 case C_ULT_D: 564 Format(instr, "c.ult.d 'fs, 'ft, 'Cc"); 565 break; 566 case C_OLE_D: 567 Format(instr, "c.ole.d 'fs, 'ft, 'Cc"); 568 break; 569 case C_ULE_D: 570 Format(instr, "c.ule.d 'fs, 'ft, 'Cc"); 571 break; 572 default: 573 Format(instr, "unknown.cop1.d"); 574 break; 575 } 576 break; 577 case S: 578 UNIMPLEMENTED_MIPS(); 579 break; 580 case W: 581 switch (instr->FunctionFieldRaw()) { 582 case CVT_S_W: // Convert word to float (single). 583 Format(instr, "cvt.s.w 'fd, 'fs"); 584 break; 585 case CVT_D_W: // Convert word to double. 586 Format(instr, "cvt.d.w 'fd, 'fs"); 587 break; 588 default: 589 UNREACHABLE(); 590 } 591 break; 592 case L: 593 switch (instr->FunctionFieldRaw()) { 594 case CVT_D_L: { 595 if (kArchVariant == kMips32r2) { 596 Format(instr, "cvt.d.l 'fd, 'fs"); 597 } else { 598 Unknown(instr); 599 } 600 break; 601 } 602 case CVT_S_L: { 603 if (kArchVariant == kMips32r2) { 604 Format(instr, "cvt.s.l 'fd, 'fs"); 605 } else { 606 Unknown(instr); 607 } 608 break; 609 } 610 default: 611 UNREACHABLE(); 612 } 613 break; 614 case PS: 615 UNIMPLEMENTED_MIPS(); 616 break; 617 default: 618 UNREACHABLE(); 619 } 620 break; 621 case SPECIAL: 622 switch (instr->FunctionFieldRaw()) { 623 case JR: 624 Format(instr, "jr 'rs"); 625 break; 626 case JALR: 627 Format(instr, "jalr 'rs"); 628 break; 629 case SLL: 630 if ( 0x0 == static_cast<int>(instr->InstructionBits())) 631 Format(instr, "nop"); 632 else 633 Format(instr, "sll 'rd, 'rt, 'sa"); 634 break; 635 case SRL: 636 if (instr->RsValue() == 0) { 637 Format(instr, "srl 'rd, 'rt, 'sa"); 638 } else { 639 if (kArchVariant == kMips32r2) { 640 Format(instr, "rotr 'rd, 'rt, 'sa"); 641 } else { 642 Unknown(instr); 643 } 644 } 645 break; 646 case SRA: 647 Format(instr, "sra 'rd, 'rt, 'sa"); 648 break; 649 case SLLV: 650 Format(instr, "sllv 'rd, 'rt, 'rs"); 651 break; 652 case SRLV: 653 if (instr->SaValue() == 0) { 654 Format(instr, "srlv 'rd, 'rt, 'rs"); 655 } else { 656 if (kArchVariant == kMips32r2) { 657 Format(instr, "rotrv 'rd, 'rt, 'rs"); 658 } else { 659 Unknown(instr); 660 } 661 } 662 break; 663 case SRAV: 664 Format(instr, "srav 'rd, 'rt, 'rs"); 665 break; 666 case MFHI: 667 Format(instr, "mfhi 'rd"); 668 break; 669 case MFLO: 670 Format(instr, "mflo 'rd"); 671 break; 672 case MULT: 673 Format(instr, "mult 'rs, 'rt"); 674 break; 675 case MULTU: 676 Format(instr, "multu 'rs, 'rt"); 677 break; 678 case DIV: 679 Format(instr, "div 'rs, 'rt"); 680 break; 681 case DIVU: 682 Format(instr, "divu 'rs, 'rt"); 683 break; 684 case ADD: 685 Format(instr, "add 'rd, 'rs, 'rt"); 686 break; 687 case ADDU: 688 Format(instr, "addu 'rd, 'rs, 'rt"); 689 break; 690 case SUB: 691 Format(instr, "sub 'rd, 'rs, 'rt"); 692 break; 693 case SUBU: 694 Format(instr, "subu 'rd, 'rs, 'rt"); 695 break; 696 case AND: 697 Format(instr, "and 'rd, 'rs, 'rt"); 698 break; 699 case OR: 700 if (0 == instr->RsValue()) { 701 Format(instr, "mov 'rd, 'rt"); 702 } else if (0 == instr->RtValue()) { 703 Format(instr, "mov 'rd, 'rs"); 704 } else { 705 Format(instr, "or 'rd, 'rs, 'rt"); 706 } 707 break; 708 case XOR: 709 Format(instr, "xor 'rd, 'rs, 'rt"); 710 break; 711 case NOR: 712 Format(instr, "nor 'rd, 'rs, 'rt"); 713 break; 714 case SLT: 715 Format(instr, "slt 'rd, 'rs, 'rt"); 716 break; 717 case SLTU: 718 Format(instr, "sltu 'rd, 'rs, 'rt"); 719 break; 720 case BREAK: 721 Format(instr, "break, code: 'code"); 722 break; 723 case TGE: 724 Format(instr, "tge 'rs, 'rt, code: 'code"); 725 break; 726 case TGEU: 727 Format(instr, "tgeu 'rs, 'rt, code: 'code"); 728 break; 729 case TLT: 730 Format(instr, "tlt 'rs, 'rt, code: 'code"); 731 break; 732 case TLTU: 733 Format(instr, "tltu 'rs, 'rt, code: 'code"); 734 break; 735 case TEQ: 736 Format(instr, "teq 'rs, 'rt, code: 'code"); 737 break; 738 case TNE: 739 Format(instr, "tne 'rs, 'rt, code: 'code"); 740 break; 741 case MOVZ: 742 Format(instr, "movz 'rd, 'rs, 'rt"); 743 break; 744 case MOVN: 745 Format(instr, "movn 'rd, 'rs, 'rt"); 746 break; 747 case MOVCI: 748 if (instr->Bit(16)) { 749 Format(instr, "movt 'rd, 'rs, 'bc"); 750 } else { 751 Format(instr, "movf 'rd, 'rs, 'bc"); 752 } 753 break; 754 default: 755 UNREACHABLE(); 756 } 757 break; 758 case SPECIAL2: 759 switch (instr->FunctionFieldRaw()) { 760 case MUL: 761 Format(instr, "mul 'rd, 'rs, 'rt"); 762 break; 763 case CLZ: 764 Format(instr, "clz 'rd, 'rs"); 765 break; 766 default: 767 UNREACHABLE(); 768 } 769 break; 770 case SPECIAL3: 771 switch (instr->FunctionFieldRaw()) { 772 case INS: { 773 if (kArchVariant == kMips32r2) { 774 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); 775 } else { 776 Unknown(instr); 777 } 778 break; 779 } 780 case EXT: { 781 if (kArchVariant == kMips32r2) { 782 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); 783 } else { 784 Unknown(instr); 785 } 786 break; 787 } 788 default: 789 UNREACHABLE(); 790 } 791 break; 792 default: 793 UNREACHABLE(); 794 } 795 } 796 797 798 void Decoder::DecodeTypeImmediate(Instruction* instr) { 799 switch (instr->OpcodeFieldRaw()) { 800 // ------------- REGIMM class. 801 case COP1: 802 switch (instr->RsFieldRaw()) { 803 case BC1: 804 if (instr->FBtrueValue()) { 805 Format(instr, "bc1t 'bc, 'imm16u"); 806 } else { 807 Format(instr, "bc1f 'bc, 'imm16u"); 808 } 809 break; 810 default: 811 UNREACHABLE(); 812 }; 813 break; // Case COP1. 814 case REGIMM: 815 switch (instr->RtFieldRaw()) { 816 case BLTZ: 817 Format(instr, "bltz 'rs, 'imm16u"); 818 break; 819 case BLTZAL: 820 Format(instr, "bltzal 'rs, 'imm16u"); 821 break; 822 case BGEZ: 823 Format(instr, "bgez 'rs, 'imm16u"); 824 break; 825 case BGEZAL: 826 Format(instr, "bgezal 'rs, 'imm16u"); 827 break; 828 default: 829 UNREACHABLE(); 830 } 831 break; // Case REGIMM. 832 // ------------- Branch instructions. 833 case BEQ: 834 Format(instr, "beq 'rs, 'rt, 'imm16u"); 835 break; 836 case BNE: 837 Format(instr, "bne 'rs, 'rt, 'imm16u"); 838 break; 839 case BLEZ: 840 Format(instr, "blez 'rs, 'imm16u"); 841 break; 842 case BGTZ: 843 Format(instr, "bgtz 'rs, 'imm16u"); 844 break; 845 // ------------- Arithmetic instructions. 846 case ADDI: 847 Format(instr, "addi 'rt, 'rs, 'imm16s"); 848 break; 849 case ADDIU: 850 Format(instr, "addiu 'rt, 'rs, 'imm16s"); 851 break; 852 case SLTI: 853 Format(instr, "slti 'rt, 'rs, 'imm16s"); 854 break; 855 case SLTIU: 856 Format(instr, "sltiu 'rt, 'rs, 'imm16u"); 857 break; 858 case ANDI: 859 Format(instr, "andi 'rt, 'rs, 'imm16x"); 860 break; 861 case ORI: 862 Format(instr, "ori 'rt, 'rs, 'imm16x"); 863 break; 864 case XORI: 865 Format(instr, "xori 'rt, 'rs, 'imm16x"); 866 break; 867 case LUI: 868 Format(instr, "lui 'rt, 'imm16x"); 869 break; 870 // ------------- Memory instructions. 871 case LB: 872 Format(instr, "lb 'rt, 'imm16s('rs)"); 873 break; 874 case LH: 875 Format(instr, "lh 'rt, 'imm16s('rs)"); 876 break; 877 case LWL: 878 Format(instr, "lwl 'rt, 'imm16s('rs)"); 879 break; 880 case LW: 881 Format(instr, "lw 'rt, 'imm16s('rs)"); 882 break; 883 case LBU: 884 Format(instr, "lbu 'rt, 'imm16s('rs)"); 885 break; 886 case LHU: 887 Format(instr, "lhu 'rt, 'imm16s('rs)"); 888 break; 889 case LWR: 890 Format(instr, "lwr 'rt, 'imm16s('rs)"); 891 break; 892 case SB: 893 Format(instr, "sb 'rt, 'imm16s('rs)"); 894 break; 895 case SH: 896 Format(instr, "sh 'rt, 'imm16s('rs)"); 897 break; 898 case SWL: 899 Format(instr, "swl 'rt, 'imm16s('rs)"); 900 break; 901 case SW: 902 Format(instr, "sw 'rt, 'imm16s('rs)"); 903 break; 904 case SWR: 905 Format(instr, "swr 'rt, 'imm16s('rs)"); 906 break; 907 case LWC1: 908 Format(instr, "lwc1 'ft, 'imm16s('rs)"); 909 break; 910 case LDC1: 911 Format(instr, "ldc1 'ft, 'imm16s('rs)"); 912 break; 913 case SWC1: 914 Format(instr, "swc1 'ft, 'imm16s('rs)"); 915 break; 916 case SDC1: 917 Format(instr, "sdc1 'ft, 'imm16s('rs)"); 918 break; 919 default: 920 UNREACHABLE(); 921 break; 922 }; 923 } 924 925 926 void Decoder::DecodeTypeJump(Instruction* instr) { 927 switch (instr->OpcodeFieldRaw()) { 928 case J: 929 Format(instr, "j 'imm26x"); 930 break; 931 case JAL: 932 Format(instr, "jal 'imm26x"); 933 break; 934 default: 935 UNREACHABLE(); 936 } 937 } 938 939 940 // Disassemble the instruction at *instr_ptr into the output buffer. 941 int Decoder::InstructionDecode(byte* instr_ptr) { 942 Instruction* instr = Instruction::At(instr_ptr); 943 // Print raw instruction bytes. 944 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, 945 "%08x ", 946 instr->InstructionBits()); 947 switch (instr->InstructionType()) { 948 case Instruction::kRegisterType: { 949 DecodeTypeRegister(instr); 950 break; 951 } 952 case Instruction::kImmediateType: { 953 DecodeTypeImmediate(instr); 954 break; 955 } 956 case Instruction::kJumpType: { 957 DecodeTypeJump(instr); 958 break; 959 } 960 default: { 961 Format(instr, "UNSUPPORTED"); 962 UNSUPPORTED_MIPS(); 963 } 964 } 965 return Instruction::kInstrSize; 966 } 967 968 969 } } // namespace v8::internal 970 971 972 973 //------------------------------------------------------------------------------ 974 975 namespace disasm { 976 977 const char* NameConverter::NameOfAddress(byte* addr) const { 978 v8::internal::OS::SNPrintF(tmp_buffer_, "%p", addr); 979 return tmp_buffer_.start(); 980 } 981 982 983 const char* NameConverter::NameOfConstant(byte* addr) const { 984 return NameOfAddress(addr); 985 } 986 987 988 const char* NameConverter::NameOfCPURegister(int reg) const { 989 return v8::internal::Registers::Name(reg); 990 } 991 992 993 const char* NameConverter::NameOfXMMRegister(int reg) const { 994 return v8::internal::FPURegisters::Name(reg); 995 } 996 997 998 const char* NameConverter::NameOfByteCPURegister(int reg) const { 999 UNREACHABLE(); // MIPS does not have the concept of a byte register. 1000 return "nobytereg"; 1001 } 1002 1003 1004 const char* NameConverter::NameInCode(byte* addr) const { 1005 // The default name converter is called for unknown code. So we will not try 1006 // to access any memory. 1007 return ""; 1008 } 1009 1010 1011 //------------------------------------------------------------------------------ 1012 1013 Disassembler::Disassembler(const NameConverter& converter) 1014 : converter_(converter) {} 1015 1016 1017 Disassembler::~Disassembler() {} 1018 1019 1020 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, 1021 byte* instruction) { 1022 v8::internal::Decoder d(converter_, buffer); 1023 return d.InstructionDecode(instruction); 1024 } 1025 1026 1027 // The MIPS assembler does not currently use constant pools. 1028 int Disassembler::ConstantPoolSizeAt(byte* instruction) { 1029 return -1; 1030 } 1031 1032 1033 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { 1034 NameConverter converter; 1035 Disassembler d(converter); 1036 for (byte* pc = begin; pc < end;) { 1037 v8::internal::EmbeddedVector<char, 128> buffer; 1038 buffer[0] = '\0'; 1039 byte* prev_pc = pc; 1040 pc += d.InstructionDecode(buffer, pc); 1041 fprintf(f, "%p %08x %s\n", 1042 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); 1043 } 1044 } 1045 1046 1047 #undef UNSUPPORTED 1048 1049 } // namespace disasm 1050 1051 #endif // V8_TARGET_ARCH_MIPS 1052