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