OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // A Disassembler object is used to disassemble a block of code instruction by | 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 | 6 // instruction. The default implementation of the NameConverter object can be |
7 // overriden to modify register names or to do symbol lookup on addresses. | 7 // overriden to modify register names or to do symbol lookup on addresses. |
8 // | 8 // |
9 // The example below will disassemble a block of code and print it to stdout. | 9 // The example below will disassemble a block of code and print it to stdout. |
10 // | 10 // |
(...skipping 12 matching lines...) Expand all Loading... |
23 // achieved by just calling Disassembler::Disassemble(stdout, begin, end); | 23 // achieved by just calling Disassembler::Disassemble(stdout, begin, end); |
24 | 24 |
25 | 25 |
26 #include <assert.h> | 26 #include <assert.h> |
27 #include <stdarg.h> | 27 #include <stdarg.h> |
28 #include <stdio.h> | 28 #include <stdio.h> |
29 #include <string.h> | 29 #include <string.h> |
30 | 30 |
31 #include "src/v8.h" | 31 #include "src/v8.h" |
32 | 32 |
33 #if V8_TARGET_ARCH_MIPS | 33 #if V8_TARGET_ARCH_MIPS64 |
34 | 34 |
35 #include "src/base/platform/platform.h" | 35 #include "src/base/platform/platform.h" |
36 #include "src/disasm.h" | 36 #include "src/disasm.h" |
37 #include "src/macro-assembler.h" | 37 #include "src/macro-assembler.h" |
38 #include "src/mips/constants-mips.h" | 38 #include "src/mips64/constants-mips64.h" |
39 | 39 |
40 namespace v8 { | 40 namespace v8 { |
41 namespace internal { | 41 namespace internal { |
42 | 42 |
43 //------------------------------------------------------------------------------ | 43 //------------------------------------------------------------------------------ |
44 | 44 |
45 // Decoder decodes and disassembles instructions into an output buffer. | 45 // Decoder decodes and disassembles instructions into an output buffer. |
46 // It uses the converter to convert register names and call destinations into | 46 // It uses the converter to convert register names and call destinations into |
47 // more informative description. | 47 // more informative description. |
48 class Decoder { | 48 class Decoder { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 void PrintCode(Instruction* instr); // For break and trap instructions. | 90 void PrintCode(Instruction* instr); // For break and trap instructions. |
91 // Printing of instruction name. | 91 // Printing of instruction name. |
92 void PrintInstructionName(Instruction* instr); | 92 void PrintInstructionName(Instruction* instr); |
93 | 93 |
94 // Handle formatting of instructions and their options. | 94 // Handle formatting of instructions and their options. |
95 int FormatRegister(Instruction* instr, const char* option); | 95 int FormatRegister(Instruction* instr, const char* option); |
96 int FormatFPURegister(Instruction* instr, const char* option); | 96 int FormatFPURegister(Instruction* instr, const char* option); |
97 int FormatOption(Instruction* instr, const char* option); | 97 int FormatOption(Instruction* instr, const char* option); |
98 void Format(Instruction* instr, const char* format); | 98 void Format(Instruction* instr, const char* format); |
99 void Unknown(Instruction* instr); | 99 void Unknown(Instruction* instr); |
| 100 int DecodeBreakInstr(Instruction* instr); |
100 | 101 |
101 // Each of these functions decodes one particular instruction type. | 102 // Each of these functions decodes one particular instruction type. |
102 void DecodeTypeRegister(Instruction* instr); | 103 int DecodeTypeRegister(Instruction* instr); |
103 void DecodeTypeImmediate(Instruction* instr); | 104 void DecodeTypeImmediate(Instruction* instr); |
104 void DecodeTypeJump(Instruction* instr); | 105 void DecodeTypeJump(Instruction* instr); |
105 | 106 |
106 const disasm::NameConverter& converter_; | 107 const disasm::NameConverter& converter_; |
107 v8::internal::Vector<char> out_buffer_; | 108 v8::internal::Vector<char> out_buffer_; |
108 int out_buffer_pos_; | 109 int out_buffer_pos_; |
109 | 110 |
110 DISALLOW_COPY_AND_ASSIGN(Decoder); | 111 DISALLOW_COPY_AND_ASSIGN(Decoder); |
111 }; | 112 }; |
112 | 113 |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 } | 431 } |
431 | 432 |
432 | 433 |
433 // For currently unimplemented decodings the disassembler calls Unknown(instr) | 434 // For currently unimplemented decodings the disassembler calls Unknown(instr) |
434 // which will just print "unknown" of the instruction bits. | 435 // which will just print "unknown" of the instruction bits. |
435 void Decoder::Unknown(Instruction* instr) { | 436 void Decoder::Unknown(Instruction* instr) { |
436 Format(instr, "unknown"); | 437 Format(instr, "unknown"); |
437 } | 438 } |
438 | 439 |
439 | 440 |
440 void Decoder::DecodeTypeRegister(Instruction* instr) { | 441 int Decoder::DecodeBreakInstr(Instruction* instr) { |
| 442 // This is already known to be BREAK instr, just extract the code. |
| 443 if (instr->Bits(25, 6) == static_cast<int>(kMaxStopCode)) { |
| 444 // This is stop(msg). |
| 445 Format(instr, "break, code: 'code"); |
| 446 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 447 "\n%p %08lx stop msg: %s", |
| 448 static_cast<void*> |
| 449 (reinterpret_cast<int32_t*>(instr |
| 450 + Instruction::kInstrSize)), |
| 451 reinterpret_cast<uint64_t> |
| 452 (*reinterpret_cast<char**>(instr |
| 453 + Instruction::kInstrSize)), |
| 454 *reinterpret_cast<char**>(instr |
| 455 + Instruction::kInstrSize)); |
| 456 // Size 3: the break_ instr, plus embedded 64-bit char pointer. |
| 457 return 3 * Instruction::kInstrSize; |
| 458 } else { |
| 459 Format(instr, "break, code: 'code"); |
| 460 return Instruction::kInstrSize; |
| 461 } |
| 462 } |
| 463 |
| 464 |
| 465 int Decoder::DecodeTypeRegister(Instruction* instr) { |
441 switch (instr->OpcodeFieldRaw()) { | 466 switch (instr->OpcodeFieldRaw()) { |
442 case COP1: // Coprocessor instructions. | 467 case COP1: // Coprocessor instructions. |
443 switch (instr->RsFieldRaw()) { | 468 switch (instr->RsFieldRaw()) { |
444 case BC1: // bc1 handled in DecodeTypeImmediate. | 469 case BC1: // bc1 handled in DecodeTypeImmediate. |
445 UNREACHABLE(); | 470 UNREACHABLE(); |
446 break; | 471 break; |
447 case MFC1: | 472 case MFC1: |
448 Format(instr, "mfc1 'rt, 'fs"); | 473 Format(instr, "mfc1 'rt, 'fs"); |
449 break; | 474 break; |
| 475 case DMFC1: |
| 476 Format(instr, "dmfc1 'rt, 'fs"); |
| 477 break; |
450 case MFHC1: | 478 case MFHC1: |
451 Format(instr, "mfhc1 'rt, 'fs"); | 479 Format(instr, "mfhc1 'rt, 'fs"); |
452 break; | 480 break; |
453 case MTC1: | 481 case MTC1: |
454 Format(instr, "mtc1 'rt, 'fs"); | 482 Format(instr, "mtc1 'rt, 'fs"); |
455 break; | 483 break; |
| 484 case DMTC1: |
| 485 Format(instr, "dmtc1 'rt, 'fs"); |
| 486 break; |
456 // These are called "fs" too, although they are not FPU registers. | 487 // These are called "fs" too, although they are not FPU registers. |
457 case CTC1: | 488 case CTC1: |
458 Format(instr, "ctc1 'rt, 'fs"); | 489 Format(instr, "ctc1 'rt, 'fs"); |
459 break; | 490 break; |
460 case CFC1: | 491 case CFC1: |
461 Format(instr, "cfc1 'rt, 'fs"); | 492 Format(instr, "cfc1 'rt, 'fs"); |
462 break; | 493 break; |
463 case MTHC1: | 494 case MTHC1: |
464 Format(instr, "mthc1 'rt, 'fs"); | 495 Format(instr, "mthc1 'rt, 'fs"); |
465 break; | 496 break; |
(...skipping 19 matching lines...) Expand all Loading... |
485 break; | 516 break; |
486 case NEG_D: | 517 case NEG_D: |
487 Format(instr, "neg.d 'fd, 'fs"); | 518 Format(instr, "neg.d 'fd, 'fs"); |
488 break; | 519 break; |
489 case SQRT_D: | 520 case SQRT_D: |
490 Format(instr, "sqrt.d 'fd, 'fs"); | 521 Format(instr, "sqrt.d 'fd, 'fs"); |
491 break; | 522 break; |
492 case CVT_W_D: | 523 case CVT_W_D: |
493 Format(instr, "cvt.w.d 'fd, 'fs"); | 524 Format(instr, "cvt.w.d 'fd, 'fs"); |
494 break; | 525 break; |
495 case CVT_L_D: { | 526 case CVT_L_D: |
496 if (kArchVariant == kMips32r2) { | 527 Format(instr, "cvt.l.d 'fd, 'fs"); |
497 Format(instr, "cvt.l.d 'fd, 'fs"); | |
498 } else { | |
499 Unknown(instr); | |
500 } | |
501 break; | 528 break; |
502 } | |
503 case TRUNC_W_D: | 529 case TRUNC_W_D: |
504 Format(instr, "trunc.w.d 'fd, 'fs"); | 530 Format(instr, "trunc.w.d 'fd, 'fs"); |
505 break; | 531 break; |
506 case TRUNC_L_D: { | 532 case TRUNC_L_D: |
507 if (kArchVariant == kMips32r2) { | 533 Format(instr, "trunc.l.d 'fd, 'fs"); |
508 Format(instr, "trunc.l.d 'fd, 'fs"); | |
509 } else { | |
510 Unknown(instr); | |
511 } | |
512 break; | 534 break; |
513 } | |
514 case ROUND_W_D: | 535 case ROUND_W_D: |
515 Format(instr, "round.w.d 'fd, 'fs"); | 536 Format(instr, "round.w.d 'fd, 'fs"); |
516 break; | 537 break; |
| 538 case ROUND_L_D: |
| 539 Format(instr, "round.l.d 'fd, 'fs"); |
| 540 break; |
517 case FLOOR_W_D: | 541 case FLOOR_W_D: |
518 Format(instr, "floor.w.d 'fd, 'fs"); | 542 Format(instr, "floor.w.d 'fd, 'fs"); |
519 break; | 543 break; |
| 544 case FLOOR_L_D: |
| 545 Format(instr, "floor.l.d 'fd, 'fs"); |
| 546 break; |
520 case CEIL_W_D: | 547 case CEIL_W_D: |
521 Format(instr, "ceil.w.d 'fd, 'fs"); | 548 Format(instr, "ceil.w.d 'fd, 'fs"); |
522 break; | 549 break; |
| 550 case CEIL_L_D: |
| 551 Format(instr, "ceil.l.d 'fd, 'fs"); |
| 552 break; |
523 case CVT_S_D: | 553 case CVT_S_D: |
524 Format(instr, "cvt.s.d 'fd, 'fs"); | 554 Format(instr, "cvt.s.d 'fd, 'fs"); |
525 break; | 555 break; |
526 case C_F_D: | 556 case C_F_D: |
527 Format(instr, "c.f.d 'fs, 'ft, 'Cc"); | 557 Format(instr, "c.f.d 'fs, 'ft, 'Cc"); |
528 break; | 558 break; |
529 case C_UN_D: | 559 case C_UN_D: |
530 Format(instr, "c.un.d 'fs, 'ft, 'Cc"); | 560 Format(instr, "c.un.d 'fs, 'ft, 'Cc"); |
531 break; | 561 break; |
532 case C_EQ_D: | 562 case C_EQ_D: |
(...skipping 29 matching lines...) Expand all Loading... |
562 break; | 592 break; |
563 case CVT_D_W: // Convert word to double. | 593 case CVT_D_W: // Convert word to double. |
564 Format(instr, "cvt.d.w 'fd, 'fs"); | 594 Format(instr, "cvt.d.w 'fd, 'fs"); |
565 break; | 595 break; |
566 default: | 596 default: |
567 UNREACHABLE(); | 597 UNREACHABLE(); |
568 } | 598 } |
569 break; | 599 break; |
570 case L: | 600 case L: |
571 switch (instr->FunctionFieldRaw()) { | 601 switch (instr->FunctionFieldRaw()) { |
572 case CVT_D_L: { | 602 case CVT_D_L: |
573 if (kArchVariant == kMips32r2) { | 603 Format(instr, "cvt.d.l 'fd, 'fs"); |
574 Format(instr, "cvt.d.l 'fd, 'fs"); | |
575 } else { | |
576 Unknown(instr); | |
577 } | |
578 break; | 604 break; |
579 } | 605 case CVT_S_L: |
580 case CVT_S_L: { | 606 Format(instr, "cvt.s.l 'fd, 'fs"); |
581 if (kArchVariant == kMips32r2) { | |
582 Format(instr, "cvt.s.l 'fd, 'fs"); | |
583 } else { | |
584 Unknown(instr); | |
585 } | |
586 break; | 607 break; |
587 } | |
588 default: | 608 default: |
589 UNREACHABLE(); | 609 UNREACHABLE(); |
590 } | 610 } |
591 break; | 611 break; |
592 case PS: | 612 case PS: |
593 UNIMPLEMENTED_MIPS(); | 613 UNIMPLEMENTED_MIPS(); |
594 break; | 614 break; |
595 default: | 615 default: |
596 UNREACHABLE(); | 616 UNREACHABLE(); |
597 } | 617 } |
(...skipping 14 matching lines...) Expand all Loading... |
612 break; | 632 break; |
613 case JALR: | 633 case JALR: |
614 Format(instr, "jalr 'rs"); | 634 Format(instr, "jalr 'rs"); |
615 break; | 635 break; |
616 case SLL: | 636 case SLL: |
617 if ( 0x0 == static_cast<int>(instr->InstructionBits())) | 637 if ( 0x0 == static_cast<int>(instr->InstructionBits())) |
618 Format(instr, "nop"); | 638 Format(instr, "nop"); |
619 else | 639 else |
620 Format(instr, "sll 'rd, 'rt, 'sa"); | 640 Format(instr, "sll 'rd, 'rt, 'sa"); |
621 break; | 641 break; |
| 642 case DSLL: |
| 643 Format(instr, "dsll 'rd, 'rt, 'sa"); |
| 644 break; |
| 645 case DSLL32: |
| 646 Format(instr, "dsll32 'rd, 'rt, 'sa"); |
| 647 break; |
622 case SRL: | 648 case SRL: |
623 if (instr->RsValue() == 0) { | 649 if (instr->RsValue() == 0) { |
624 Format(instr, "srl 'rd, 'rt, 'sa"); | 650 Format(instr, "srl 'rd, 'rt, 'sa"); |
625 } else { | 651 } else { |
626 if (kArchVariant == kMips32r2) { | 652 if (kArchVariant == kMips64r2) { |
627 Format(instr, "rotr 'rd, 'rt, 'sa"); | 653 Format(instr, "rotr 'rd, 'rt, 'sa"); |
628 } else { | 654 } else { |
629 Unknown(instr); | 655 Unknown(instr); |
630 } | 656 } |
631 } | 657 } |
632 break; | 658 break; |
| 659 case DSRL: |
| 660 if (instr->RsValue() == 0) { |
| 661 Format(instr, "dsrl 'rd, 'rt, 'sa"); |
| 662 } else { |
| 663 if (kArchVariant == kMips64r2) { |
| 664 Format(instr, "drotr 'rd, 'rt, 'sa"); |
| 665 } else { |
| 666 Unknown(instr); |
| 667 } |
| 668 } |
| 669 break; |
| 670 case DSRL32: |
| 671 Format(instr, "dsrl32 'rd, 'rt, 'sa"); |
| 672 break; |
633 case SRA: | 673 case SRA: |
634 Format(instr, "sra 'rd, 'rt, 'sa"); | 674 Format(instr, "sra 'rd, 'rt, 'sa"); |
635 break; | 675 break; |
| 676 case DSRA: |
| 677 Format(instr, "dsra 'rd, 'rt, 'sa"); |
| 678 break; |
| 679 case DSRA32: |
| 680 Format(instr, "dsra32 'rd, 'rt, 'sa"); |
| 681 break; |
636 case SLLV: | 682 case SLLV: |
637 Format(instr, "sllv 'rd, 'rt, 'rs"); | 683 Format(instr, "sllv 'rd, 'rt, 'rs"); |
638 break; | 684 break; |
| 685 case DSLLV: |
| 686 Format(instr, "dsllv 'rd, 'rt, 'rs"); |
| 687 break; |
639 case SRLV: | 688 case SRLV: |
640 if (instr->SaValue() == 0) { | 689 if (instr->SaValue() == 0) { |
641 Format(instr, "srlv 'rd, 'rt, 'rs"); | 690 Format(instr, "srlv 'rd, 'rt, 'rs"); |
642 } else { | 691 } else { |
643 if (kArchVariant == kMips32r2) { | 692 if (kArchVariant == kMips64r2) { |
644 Format(instr, "rotrv 'rd, 'rt, 'rs"); | 693 Format(instr, "rotrv 'rd, 'rt, 'rs"); |
645 } else { | 694 } else { |
646 Unknown(instr); | 695 Unknown(instr); |
647 } | 696 } |
648 } | 697 } |
649 break; | 698 break; |
| 699 case DSRLV: |
| 700 if (instr->SaValue() == 0) { |
| 701 Format(instr, "dsrlv 'rd, 'rt, 'rs"); |
| 702 } else { |
| 703 if (kArchVariant == kMips64r2) { |
| 704 Format(instr, "drotrv 'rd, 'rt, 'rs"); |
| 705 } else { |
| 706 Unknown(instr); |
| 707 } |
| 708 } |
| 709 break; |
650 case SRAV: | 710 case SRAV: |
651 Format(instr, "srav 'rd, 'rt, 'rs"); | 711 Format(instr, "srav 'rd, 'rt, 'rs"); |
652 break; | 712 break; |
| 713 case DSRAV: |
| 714 Format(instr, "dsrav 'rd, 'rt, 'rs"); |
| 715 break; |
653 case MFHI: | 716 case MFHI: |
654 Format(instr, "mfhi 'rd"); | 717 Format(instr, "mfhi 'rd"); |
655 break; | 718 break; |
656 case MFLO: | 719 case MFLO: |
657 Format(instr, "mflo 'rd"); | 720 Format(instr, "mflo 'rd"); |
658 break; | 721 break; |
659 case MULT: | 722 case MULT: |
660 Format(instr, "mult 'rs, 'rt"); | 723 Format(instr, "mult 'rs, 'rt"); |
661 break; | 724 break; |
| 725 case DMULT: |
| 726 Format(instr, "dmult 'rs, 'rt"); |
| 727 break; |
662 case MULTU: | 728 case MULTU: |
663 Format(instr, "multu 'rs, 'rt"); | 729 Format(instr, "multu 'rs, 'rt"); |
664 break; | 730 break; |
| 731 case DMULTU: |
| 732 Format(instr, "dmultu 'rs, 'rt"); |
| 733 break; |
665 case DIV: | 734 case DIV: |
666 Format(instr, "div 'rs, 'rt"); | 735 Format(instr, "div 'rs, 'rt"); |
667 break; | 736 break; |
| 737 case DDIV: |
| 738 Format(instr, "ddiv 'rs, 'rt"); |
| 739 break; |
668 case DIVU: | 740 case DIVU: |
669 Format(instr, "divu 'rs, 'rt"); | 741 Format(instr, "divu 'rs, 'rt"); |
670 break; | 742 break; |
| 743 case DDIVU: |
| 744 Format(instr, "ddivu 'rs, 'rt"); |
| 745 break; |
671 case ADD: | 746 case ADD: |
672 Format(instr, "add 'rd, 'rs, 'rt"); | 747 Format(instr, "add 'rd, 'rs, 'rt"); |
673 break; | 748 break; |
| 749 case DADD: |
| 750 Format(instr, "dadd 'rd, 'rs, 'rt"); |
| 751 break; |
674 case ADDU: | 752 case ADDU: |
675 Format(instr, "addu 'rd, 'rs, 'rt"); | 753 Format(instr, "addu 'rd, 'rs, 'rt"); |
676 break; | 754 break; |
| 755 case DADDU: |
| 756 Format(instr, "daddu 'rd, 'rs, 'rt"); |
| 757 break; |
677 case SUB: | 758 case SUB: |
678 Format(instr, "sub 'rd, 'rs, 'rt"); | 759 Format(instr, "sub 'rd, 'rs, 'rt"); |
679 break; | 760 break; |
| 761 case DSUB: |
| 762 Format(instr, "dsub 'rd, 'rs, 'rt"); |
| 763 break; |
680 case SUBU: | 764 case SUBU: |
681 Format(instr, "subu 'rd, 'rs, 'rt"); | 765 Format(instr, "subu 'rd, 'rs, 'rt"); |
682 break; | 766 break; |
| 767 case DSUBU: |
| 768 Format(instr, "dsubu 'rd, 'rs, 'rt"); |
| 769 break; |
683 case AND: | 770 case AND: |
684 Format(instr, "and 'rd, 'rs, 'rt"); | 771 Format(instr, "and 'rd, 'rs, 'rt"); |
685 break; | 772 break; |
686 case OR: | 773 case OR: |
687 if (0 == instr->RsValue()) { | 774 if (0 == instr->RsValue()) { |
688 Format(instr, "mov 'rd, 'rt"); | 775 Format(instr, "mov 'rd, 'rt"); |
689 } else if (0 == instr->RtValue()) { | 776 } else if (0 == instr->RtValue()) { |
690 Format(instr, "mov 'rd, 'rs"); | 777 Format(instr, "mov 'rd, 'rs"); |
691 } else { | 778 } else { |
692 Format(instr, "or 'rd, 'rs, 'rt"); | 779 Format(instr, "or 'rd, 'rs, 'rt"); |
693 } | 780 } |
694 break; | 781 break; |
695 case XOR: | 782 case XOR: |
696 Format(instr, "xor 'rd, 'rs, 'rt"); | 783 Format(instr, "xor 'rd, 'rs, 'rt"); |
697 break; | 784 break; |
698 case NOR: | 785 case NOR: |
699 Format(instr, "nor 'rd, 'rs, 'rt"); | 786 Format(instr, "nor 'rd, 'rs, 'rt"); |
700 break; | 787 break; |
701 case SLT: | 788 case SLT: |
702 Format(instr, "slt 'rd, 'rs, 'rt"); | 789 Format(instr, "slt 'rd, 'rs, 'rt"); |
703 break; | 790 break; |
704 case SLTU: | 791 case SLTU: |
705 Format(instr, "sltu 'rd, 'rs, 'rt"); | 792 Format(instr, "sltu 'rd, 'rs, 'rt"); |
706 break; | 793 break; |
707 case BREAK: | 794 case BREAK: |
708 Format(instr, "break, code: 'code"); | 795 return DecodeBreakInstr(instr); |
709 break; | |
710 case TGE: | 796 case TGE: |
711 Format(instr, "tge 'rs, 'rt, code: 'code"); | 797 Format(instr, "tge 'rs, 'rt, code: 'code"); |
712 break; | 798 break; |
713 case TGEU: | 799 case TGEU: |
714 Format(instr, "tgeu 'rs, 'rt, code: 'code"); | 800 Format(instr, "tgeu 'rs, 'rt, code: 'code"); |
715 break; | 801 break; |
716 case TLT: | 802 case TLT: |
717 Format(instr, "tlt 'rs, 'rt, code: 'code"); | 803 Format(instr, "tlt 'rs, 'rt, code: 'code"); |
718 break; | 804 break; |
719 case TLTU: | 805 case TLTU: |
(...skipping 30 matching lines...) Expand all Loading... |
750 case CLZ: | 836 case CLZ: |
751 Format(instr, "clz 'rd, 'rs"); | 837 Format(instr, "clz 'rd, 'rs"); |
752 break; | 838 break; |
753 default: | 839 default: |
754 UNREACHABLE(); | 840 UNREACHABLE(); |
755 } | 841 } |
756 break; | 842 break; |
757 case SPECIAL3: | 843 case SPECIAL3: |
758 switch (instr->FunctionFieldRaw()) { | 844 switch (instr->FunctionFieldRaw()) { |
759 case INS: { | 845 case INS: { |
760 if (kArchVariant == kMips32r2) { | 846 if (kArchVariant == kMips64r2) { |
761 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); | 847 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); |
762 } else { | 848 } else { |
763 Unknown(instr); | 849 Unknown(instr); |
764 } | 850 } |
765 break; | 851 break; |
766 } | 852 } |
767 case EXT: { | 853 case EXT: { |
768 if (kArchVariant == kMips32r2) { | 854 if (kArchVariant == kMips64r2) { |
769 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); | 855 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); |
770 } else { | 856 } else { |
771 Unknown(instr); | 857 Unknown(instr); |
772 } | 858 } |
773 break; | 859 break; |
774 } | 860 } |
775 default: | 861 default: |
776 UNREACHABLE(); | 862 UNREACHABLE(); |
777 } | 863 } |
778 break; | 864 break; |
779 default: | 865 default: |
780 UNREACHABLE(); | 866 UNREACHABLE(); |
781 } | 867 } |
| 868 return Instruction::kInstrSize; |
782 } | 869 } |
783 | 870 |
784 | 871 |
785 void Decoder::DecodeTypeImmediate(Instruction* instr) { | 872 void Decoder::DecodeTypeImmediate(Instruction* instr) { |
786 switch (instr->OpcodeFieldRaw()) { | 873 switch (instr->OpcodeFieldRaw()) { |
787 // ------------- REGIMM class. | 874 // ------------- REGIMM class. |
788 case COP1: | 875 case COP1: |
789 switch (instr->RsFieldRaw()) { | 876 switch (instr->RsFieldRaw()) { |
790 case BC1: | 877 case BC1: |
791 if (instr->FBtrueValue()) { | 878 if (instr->FBtrueValue()) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 case BLEZ: | 913 case BLEZ: |
827 Format(instr, "blez 'rs, 'imm16u"); | 914 Format(instr, "blez 'rs, 'imm16u"); |
828 break; | 915 break; |
829 case BGTZ: | 916 case BGTZ: |
830 Format(instr, "bgtz 'rs, 'imm16u"); | 917 Format(instr, "bgtz 'rs, 'imm16u"); |
831 break; | 918 break; |
832 // ------------- Arithmetic instructions. | 919 // ------------- Arithmetic instructions. |
833 case ADDI: | 920 case ADDI: |
834 Format(instr, "addi 'rt, 'rs, 'imm16s"); | 921 Format(instr, "addi 'rt, 'rs, 'imm16s"); |
835 break; | 922 break; |
| 923 case DADDI: |
| 924 Format(instr, "daddi 'rt, 'rs, 'imm16s"); |
| 925 break; |
836 case ADDIU: | 926 case ADDIU: |
837 Format(instr, "addiu 'rt, 'rs, 'imm16s"); | 927 Format(instr, "addiu 'rt, 'rs, 'imm16s"); |
838 break; | 928 break; |
| 929 case DADDIU: |
| 930 Format(instr, "daddiu 'rt, 'rs, 'imm16s"); |
| 931 break; |
839 case SLTI: | 932 case SLTI: |
840 Format(instr, "slti 'rt, 'rs, 'imm16s"); | 933 Format(instr, "slti 'rt, 'rs, 'imm16s"); |
841 break; | 934 break; |
842 case SLTIU: | 935 case SLTIU: |
843 Format(instr, "sltiu 'rt, 'rs, 'imm16u"); | 936 Format(instr, "sltiu 'rt, 'rs, 'imm16u"); |
844 break; | 937 break; |
845 case ANDI: | 938 case ANDI: |
846 Format(instr, "andi 'rt, 'rs, 'imm16x"); | 939 Format(instr, "andi 'rt, 'rs, 'imm16x"); |
847 break; | 940 break; |
848 case ORI: | 941 case ORI: |
849 Format(instr, "ori 'rt, 'rs, 'imm16x"); | 942 Format(instr, "ori 'rt, 'rs, 'imm16x"); |
850 break; | 943 break; |
851 case XORI: | 944 case XORI: |
852 Format(instr, "xori 'rt, 'rs, 'imm16x"); | 945 Format(instr, "xori 'rt, 'rs, 'imm16x"); |
853 break; | 946 break; |
854 case LUI: | 947 case LUI: |
855 Format(instr, "lui 'rt, 'imm16x"); | 948 Format(instr, "lui 'rt, 'imm16x"); |
856 break; | 949 break; |
857 // ------------- Memory instructions. | 950 // ------------- Memory instructions. |
858 case LB: | 951 case LB: |
859 Format(instr, "lb 'rt, 'imm16s('rs)"); | 952 Format(instr, "lb 'rt, 'imm16s('rs)"); |
860 break; | 953 break; |
861 case LH: | 954 case LH: |
862 Format(instr, "lh 'rt, 'imm16s('rs)"); | 955 Format(instr, "lh 'rt, 'imm16s('rs)"); |
863 break; | 956 break; |
864 case LWL: | 957 case LWL: |
865 Format(instr, "lwl 'rt, 'imm16s('rs)"); | 958 Format(instr, "lwl 'rt, 'imm16s('rs)"); |
866 break; | 959 break; |
| 960 case LDL: |
| 961 Format(instr, "ldl 'rt, 'imm16s('rs)"); |
| 962 break; |
867 case LW: | 963 case LW: |
868 Format(instr, "lw 'rt, 'imm16s('rs)"); | 964 Format(instr, "lw 'rt, 'imm16s('rs)"); |
869 break; | 965 break; |
| 966 case LWU: |
| 967 Format(instr, "lwu 'rt, 'imm16s('rs)"); |
| 968 break; |
| 969 case LD: |
| 970 Format(instr, "ld 'rt, 'imm16s('rs)"); |
| 971 break; |
870 case LBU: | 972 case LBU: |
871 Format(instr, "lbu 'rt, 'imm16s('rs)"); | 973 Format(instr, "lbu 'rt, 'imm16s('rs)"); |
872 break; | 974 break; |
873 case LHU: | 975 case LHU: |
874 Format(instr, "lhu 'rt, 'imm16s('rs)"); | 976 Format(instr, "lhu 'rt, 'imm16s('rs)"); |
875 break; | 977 break; |
876 case LWR: | 978 case LWR: |
877 Format(instr, "lwr 'rt, 'imm16s('rs)"); | 979 Format(instr, "lwr 'rt, 'imm16s('rs)"); |
878 break; | 980 break; |
| 981 case LDR: |
| 982 Format(instr, "ldr 'rt, 'imm16s('rs)"); |
| 983 break; |
879 case PREF: | 984 case PREF: |
880 Format(instr, "pref 'rt, 'imm16s('rs)"); | 985 Format(instr, "pref 'rt, 'imm16s('rs)"); |
881 break; | 986 break; |
882 case SB: | 987 case SB: |
883 Format(instr, "sb 'rt, 'imm16s('rs)"); | 988 Format(instr, "sb 'rt, 'imm16s('rs)"); |
884 break; | 989 break; |
885 case SH: | 990 case SH: |
886 Format(instr, "sh 'rt, 'imm16s('rs)"); | 991 Format(instr, "sh 'rt, 'imm16s('rs)"); |
887 break; | 992 break; |
888 case SWL: | 993 case SWL: |
889 Format(instr, "swl 'rt, 'imm16s('rs)"); | 994 Format(instr, "swl 'rt, 'imm16s('rs)"); |
890 break; | 995 break; |
891 case SW: | 996 case SW: |
892 Format(instr, "sw 'rt, 'imm16s('rs)"); | 997 Format(instr, "sw 'rt, 'imm16s('rs)"); |
893 break; | 998 break; |
| 999 case SD: |
| 1000 Format(instr, "sd 'rt, 'imm16s('rs)"); |
| 1001 break; |
894 case SWR: | 1002 case SWR: |
895 Format(instr, "swr 'rt, 'imm16s('rs)"); | 1003 Format(instr, "swr 'rt, 'imm16s('rs)"); |
896 break; | 1004 break; |
897 case LWC1: | 1005 case LWC1: |
898 Format(instr, "lwc1 'ft, 'imm16s('rs)"); | 1006 Format(instr, "lwc1 'ft, 'imm16s('rs)"); |
899 break; | 1007 break; |
900 case LDC1: | 1008 case LDC1: |
901 Format(instr, "ldc1 'ft, 'imm16s('rs)"); | 1009 Format(instr, "ldc1 'ft, 'imm16s('rs)"); |
902 break; | 1010 break; |
903 case SWC1: | 1011 case SWC1: |
904 Format(instr, "swc1 'ft, 'imm16s('rs)"); | 1012 Format(instr, "swc1 'ft, 'imm16s('rs)"); |
905 break; | 1013 break; |
906 case SDC1: | 1014 case SDC1: |
907 Format(instr, "sdc1 'ft, 'imm16s('rs)"); | 1015 Format(instr, "sdc1 'ft, 'imm16s('rs)"); |
908 break; | 1016 break; |
909 default: | 1017 default: |
910 UNREACHABLE(); | 1018 printf("a 0x%x \n", instr->OpcodeFieldRaw()); |
| 1019 UNREACHABLE(); |
911 break; | 1020 break; |
912 } | 1021 } |
913 } | 1022 } |
914 | 1023 |
915 | 1024 |
916 void Decoder::DecodeTypeJump(Instruction* instr) { | 1025 void Decoder::DecodeTypeJump(Instruction* instr) { |
917 switch (instr->OpcodeFieldRaw()) { | 1026 switch (instr->OpcodeFieldRaw()) { |
918 case J: | 1027 case J: |
919 Format(instr, "j 'imm26x"); | 1028 Format(instr, "j 'imm26x"); |
920 break; | 1029 break; |
921 case JAL: | 1030 case JAL: |
922 Format(instr, "jal 'imm26x"); | 1031 Format(instr, "jal 'imm26x"); |
923 break; | 1032 break; |
924 default: | 1033 default: |
925 UNREACHABLE(); | 1034 UNREACHABLE(); |
926 } | 1035 } |
927 } | 1036 } |
928 | 1037 |
929 | 1038 |
930 // Disassemble the instruction at *instr_ptr into the output buffer. | 1039 // Disassemble the instruction at *instr_ptr into the output buffer. |
| 1040 // All instructions are one word long, except for the simulator |
| 1041 // psuedo-instruction stop(msg). For that one special case, we return |
| 1042 // size larger than one kInstrSize. |
931 int Decoder::InstructionDecode(byte* instr_ptr) { | 1043 int Decoder::InstructionDecode(byte* instr_ptr) { |
932 Instruction* instr = Instruction::At(instr_ptr); | 1044 Instruction* instr = Instruction::At(instr_ptr); |
933 // Print raw instruction bytes. | 1045 // Print raw instruction bytes. |
934 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 1046 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
935 "%08x ", | 1047 "%08x ", |
936 instr->InstructionBits()); | 1048 instr->InstructionBits()); |
937 switch (instr->InstructionType()) { | 1049 switch (instr->InstructionType()) { |
938 case Instruction::kRegisterType: { | 1050 case Instruction::kRegisterType: { |
939 DecodeTypeRegister(instr); | 1051 return DecodeTypeRegister(instr); |
940 break; | |
941 } | 1052 } |
942 case Instruction::kImmediateType: { | 1053 case Instruction::kImmediateType: { |
943 DecodeTypeImmediate(instr); | 1054 DecodeTypeImmediate(instr); |
944 break; | 1055 break; |
945 } | 1056 } |
946 case Instruction::kJumpType: { | 1057 case Instruction::kJumpType: { |
947 DecodeTypeJump(instr); | 1058 DecodeTypeJump(instr); |
948 break; | 1059 break; |
949 } | 1060 } |
950 default: { | 1061 default: { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1031 v8::internal::PrintF(f, "%p %08x %s\n", | 1142 v8::internal::PrintF(f, "%p %08x %s\n", |
1032 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1143 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1033 } | 1144 } |
1034 } | 1145 } |
1035 | 1146 |
1036 | 1147 |
1037 #undef UNSUPPORTED | 1148 #undef UNSUPPORTED |
1038 | 1149 |
1039 } // namespace disasm | 1150 } // namespace disasm |
1040 | 1151 |
1041 #endif // V8_TARGET_ARCH_MIPS | 1152 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |