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