Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1001)

Side by Side Diff: src/mips64/disasm-mips64.cc

Issue 1046873004: MIPS: Refactor simulator and add selection instructions for r6. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 94
95 // Handle formatting of instructions and their options. 95 // Handle formatting of instructions and their options.
96 int FormatRegister(Instruction* instr, const char* option); 96 int FormatRegister(Instruction* instr, const char* option);
97 int FormatFPURegister(Instruction* instr, const char* option); 97 int FormatFPURegister(Instruction* instr, const char* option);
98 int FormatOption(Instruction* instr, const char* option); 98 int FormatOption(Instruction* instr, const char* option);
99 void Format(Instruction* instr, const char* format); 99 void Format(Instruction* instr, const char* format);
100 void Unknown(Instruction* instr); 100 void Unknown(Instruction* instr);
101 int DecodeBreakInstr(Instruction* instr); 101 int DecodeBreakInstr(Instruction* instr);
102 102
103 // Each of these functions decodes one particular instruction type. 103 // Each of these functions decodes one particular instruction type.
104 void DecodeTypeRegisterDRsType(Instruction* instr);
105 void DecodeTypeRegisterLRsType(Instruction* instr);
106 void DecodeTypeRegisterSPECIAL(Instruction* instr);
107 void DecodeTypeRegisterSPECIAL2(Instruction* instr);
108 void DecodeTypeRegisterSPECIAL3(Instruction* instr);
109 void DecodeTypeRegisterCOP1(Instruction* instr);
110 void DecodeTypeRegisterCOP1X(Instruction* instr);
104 int DecodeTypeRegister(Instruction* instr); 111 int DecodeTypeRegister(Instruction* instr);
112
113 void DecodeTypeImmediateCOP1W(Instruction* instr);
114 void DecodeTypeImmediateCOP1L(Instruction* instr);
115 void DecodeTypeImmediateCOP1S(Instruction* instr);
116 void DecodeTypeImmediateCOP1D(Instruction* instr);
117 void DecodeTypeImmediateCOP1(Instruction* instr);
118 void DecodeTypeImmediateREGIMM(Instruction* instr);
105 void DecodeTypeImmediate(Instruction* instr); 119 void DecodeTypeImmediate(Instruction* instr);
120
106 void DecodeTypeJump(Instruction* instr); 121 void DecodeTypeJump(Instruction* instr);
107 122
108 const disasm::NameConverter& converter_; 123 const disasm::NameConverter& converter_;
109 v8::internal::Vector<char> out_buffer_; 124 v8::internal::Vector<char> out_buffer_;
110 int out_buffer_pos_; 125 int out_buffer_pos_;
111 126
112 DISALLOW_COPY_AND_ASSIGN(Decoder); 127 DISALLOW_COPY_AND_ASSIGN(Decoder);
113 }; 128 };
114 129
115 130
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 + Instruction::kInstrSize)); 482 + Instruction::kInstrSize));
468 // Size 3: the break_ instr, plus embedded 64-bit char pointer. 483 // Size 3: the break_ instr, plus embedded 64-bit char pointer.
469 return 3 * Instruction::kInstrSize; 484 return 3 * Instruction::kInstrSize;
470 } else { 485 } else {
471 Format(instr, "break, code: 'code"); 486 Format(instr, "break, code: 'code");
472 return Instruction::kInstrSize; 487 return Instruction::kInstrSize;
473 } 488 }
474 } 489 }
475 490
476 491
477 int Decoder::DecodeTypeRegister(Instruction* instr) { 492 void Decoder::DecodeTypeRegisterDRsType(Instruction* instr) {
478 switch (instr->OpcodeFieldRaw()) { 493 switch (instr->FunctionFieldRaw()) {
479 case COP1: // Coprocessor instructions. 494 case SELEQZ_C:
480 switch (instr->RsFieldRaw()) { 495 Format(instr, "seleqz.D 'ft, 'fs, 'fd");
481 case MFC1: 496 break;
482 Format(instr, "mfc1 'rt, 'fs"); 497 case SELNEZ_C:
483 break; 498 Format(instr, "selnez.D 'ft, 'fs, 'fd");
484 case DMFC1: 499 break;
485 Format(instr, "dmfc1 'rt, 'fs"); 500 case ADD_D:
486 break; 501 Format(instr, "add.d 'fd, 'fs, 'ft");
487 case MFHC1: 502 break;
488 Format(instr, "mfhc1 'rt, 'fs"); 503 case SUB_D:
489 break; 504 Format(instr, "sub.d 'fd, 'fs, 'ft");
490 case MTC1: 505 break;
491 Format(instr, "mtc1 'rt, 'fs"); 506 case MUL_D:
492 break; 507 Format(instr, "mul.d 'fd, 'fs, 'ft");
493 case DMTC1: 508 break;
494 Format(instr, "dmtc1 'rt, 'fs"); 509 case DIV_D:
495 break; 510 Format(instr, "div.d 'fd, 'fs, 'ft");
496 // These are called "fs" too, although they are not FPU registers. 511 break;
497 case CTC1: 512 case ABS_D:
498 Format(instr, "ctc1 'rt, 'fs"); 513 Format(instr, "abs.d 'fd, 'fs");
499 break; 514 break;
500 case CFC1: 515 case MOV_D:
501 Format(instr, "cfc1 'rt, 'fs"); 516 Format(instr, "mov.d 'fd, 'fs");
502 break; 517 break;
503 case MTHC1: 518 case NEG_D:
504 Format(instr, "mthc1 'rt, 'fs"); 519 Format(instr, "neg.d 'fd, 'fs");
505 break; 520 break;
506 case D: 521 case SQRT_D:
507 switch (instr->FunctionFieldRaw()) { 522 Format(instr, "sqrt.d 'fd, 'fs");
508 case ADD_D: 523 break;
509 Format(instr, "add.d 'fd, 'fs, 'ft"); 524 case CVT_W_D:
510 break; 525 Format(instr, "cvt.w.d 'fd, 'fs");
511 case SUB_D: 526 break;
512 Format(instr, "sub.d 'fd, 'fs, 'ft"); 527 case CVT_L_D:
513 break; 528 Format(instr, "cvt.l.d 'fd, 'fs");
514 case MUL_D: 529 break;
515 Format(instr, "mul.d 'fd, 'fs, 'ft"); 530 case TRUNC_W_D:
516 break; 531 Format(instr, "trunc.w.d 'fd, 'fs");
517 case DIV_D: 532 break;
518 Format(instr, "div.d 'fd, 'fs, 'ft"); 533 case TRUNC_L_D:
519 break; 534 Format(instr, "trunc.l.d 'fd, 'fs");
520 case ABS_D: 535 break;
521 Format(instr, "abs.d 'fd, 'fs"); 536 case ROUND_W_D:
522 break; 537 Format(instr, "round.w.d 'fd, 'fs");
523 case MOV_D: 538 break;
524 Format(instr, "mov.d 'fd, 'fs"); 539 case ROUND_L_D:
525 break; 540 Format(instr, "round.l.d 'fd, 'fs");
526 case NEG_D: 541 break;
527 Format(instr, "neg.d 'fd, 'fs"); 542 case FLOOR_W_D:
528 break; 543 Format(instr, "floor.w.d 'fd, 'fs");
529 case SQRT_D: 544 break;
530 Format(instr, "sqrt.d 'fd, 'fs"); 545 case FLOOR_L_D:
531 break; 546 Format(instr, "floor.l.d 'fd, 'fs");
532 case CVT_W_D: 547 break;
533 Format(instr, "cvt.w.d 'fd, 'fs"); 548 case CEIL_W_D:
534 break; 549 Format(instr, "ceil.w.d 'fd, 'fs");
535 case CVT_L_D: 550 break;
536 Format(instr, "cvt.l.d 'fd, 'fs"); 551 case CEIL_L_D:
537 break; 552 Format(instr, "ceil.l.d 'fd, 'fs");
538 case TRUNC_W_D: 553 break;
539 Format(instr, "trunc.w.d 'fd, 'fs"); 554 case CVT_S_D:
540 break; 555 Format(instr, "cvt.s.d 'fd, 'fs");
541 case TRUNC_L_D: 556 break;
542 Format(instr, "trunc.l.d 'fd, 'fs"); 557 case C_F_D:
543 break; 558 Format(instr, "c.f.d 'fs, 'ft, 'Cc");
544 case ROUND_W_D: 559 break;
545 Format(instr, "round.w.d 'fd, 'fs"); 560 case C_UN_D:
546 break; 561 Format(instr, "c.un.d 'fs, 'ft, 'Cc");
547 case ROUND_L_D: 562 break;
548 Format(instr, "round.l.d 'fd, 'fs"); 563 case C_EQ_D:
549 break; 564 Format(instr, "c.eq.d 'fs, 'ft, 'Cc");
550 case FLOOR_W_D: 565 break;
551 Format(instr, "floor.w.d 'fd, 'fs"); 566 case C_UEQ_D:
552 break; 567 Format(instr, "c.ueq.d 'fs, 'ft, 'Cc");
553 case FLOOR_L_D: 568 break;
554 Format(instr, "floor.l.d 'fd, 'fs"); 569 case C_OLT_D:
555 break; 570 Format(instr, "c.olt.d 'fs, 'ft, 'Cc");
556 case CEIL_W_D: 571 break;
557 Format(instr, "ceil.w.d 'fd, 'fs"); 572 case C_ULT_D:
558 break; 573 Format(instr, "c.ult.d 'fs, 'ft, 'Cc");
559 case CEIL_L_D: 574 break;
560 Format(instr, "ceil.l.d 'fd, 'fs"); 575 case C_OLE_D:
561 break; 576 Format(instr, "c.ole.d 'fs, 'ft, 'Cc");
562 case CVT_S_D: 577 break;
563 Format(instr, "cvt.s.d 'fd, 'fs"); 578 case C_ULE_D:
564 break; 579 Format(instr, "c.ule.d 'fs, 'ft, 'Cc");
565 case C_F_D: 580 break;
566 Format(instr, "c.f.d 'fs, 'ft, 'Cc"); 581 default:
567 break; 582 Format(instr, "unknown.cop1.d");
568 case C_UN_D: 583 break;
569 Format(instr, "c.un.d 'fs, 'ft, 'Cc"); 584 }
570 break; 585 }
571 case C_EQ_D: 586
572 Format(instr, "c.eq.d 'fs, 'ft, 'Cc"); 587
573 break; 588 void Decoder::DecodeTypeRegisterLRsType(Instruction* instr) {
574 case C_UEQ_D: 589 switch (instr->FunctionFieldRaw()) {
575 Format(instr, "c.ueq.d 'fs, 'ft, 'Cc"); 590 case CVT_D_L:
576 break; 591 Format(instr, "cvt.d.l 'fd, 'fs");
577 case C_OLT_D: 592 break;
578 Format(instr, "c.olt.d 'fs, 'ft, 'Cc"); 593 case CVT_S_L:
579 break; 594 Format(instr, "cvt.s.l 'fd, 'fs");
580 case C_ULT_D: 595 break;
581 Format(instr, "c.ult.d 'fs, 'ft, 'Cc"); 596 case CMP_UN:
582 break; 597 Format(instr, "cmp.un.d 'fd, 'fs, 'ft");
583 case C_OLE_D: 598 break;
584 Format(instr, "c.ole.d 'fs, 'ft, 'Cc"); 599 case CMP_EQ:
585 break; 600 Format(instr, "cmp.eq.d 'fd, 'fs, 'ft");
586 case C_ULE_D: 601 break;
587 Format(instr, "c.ule.d 'fs, 'ft, 'Cc"); 602 case CMP_UEQ:
588 break; 603 Format(instr, "cmp.ueq.d 'fd, 'fs, 'ft");
589 default: 604 break;
590 Format(instr, "unknown.cop1.d"); 605 case CMP_LT:
591 break; 606 Format(instr, "cmp.lt.d 'fd, 'fs, 'ft");
592 } 607 break;
593 break; 608 case CMP_ULT:
594 case W: 609 Format(instr, "cmp.ult.d 'fd, 'fs, 'ft");
595 switch (instr->FunctionFieldRaw()) { 610 break;
596 case CVT_D_W: // Convert word to double. 611 case CMP_LE:
597 Format(instr, "cvt.d.w 'fd, 'fs"); 612 Format(instr, "cmp.le.d 'fd, 'fs, 'ft");
598 break; 613 break;
599 default: 614 case CMP_ULE:
600 UNREACHABLE(); 615 Format(instr, "cmp.ule.d 'fd, 'fs, 'ft");
601 } 616 break;
602 break; 617 case CMP_OR:
603 case L: 618 Format(instr, "cmp.or.d 'fd, 'fs, 'ft");
604 switch (instr->FunctionFieldRaw()) { 619 break;
605 case CVT_D_L: 620 case CMP_UNE:
606 Format(instr, "cvt.d.l 'fd, 'fs"); 621 Format(instr, "cmp.une.d 'fd, 'fs, 'ft");
607 break; 622 break;
608 case CVT_S_L: 623 case CMP_NE:
609 Format(instr, "cvt.s.l 'fd, 'fs"); 624 Format(instr, "cmp.ne.d 'fd, 'fs, 'ft");
610 break; 625 break;
611 case CMP_UN: 626 default:
612 Format(instr, "cmp.un.d 'fd, 'fs, 'ft"); 627 UNREACHABLE();
613 break; 628 }
614 case CMP_EQ: 629 }
615 Format(instr, "cmp.eq.d 'fd, 'fs, 'ft"); 630
616 break; 631
617 case CMP_UEQ: 632 void Decoder::DecodeTypeRegisterCOP1(Instruction* instr) {
618 Format(instr, "cmp.ueq.d 'fd, 'fs, 'ft"); 633 switch (instr->RsFieldRaw()) {
619 break; 634 case MFC1:
620 case CMP_LT: 635 Format(instr, "mfc1 'rt, 'fs");
621 Format(instr, "cmp.lt.d 'fd, 'fs, 'ft"); 636 break;
622 break; 637 case DMFC1:
623 case CMP_ULT: 638 Format(instr, "dmfc1 'rt, 'fs");
624 Format(instr, "cmp.ult.d 'fd, 'fs, 'ft"); 639 break;
625 break; 640 case MFHC1:
626 case CMP_LE: 641 Format(instr, "mfhc1 'rt, 'fs");
627 Format(instr, "cmp.le.d 'fd, 'fs, 'ft"); 642 break;
628 break; 643 case MTC1:
629 case CMP_ULE: 644 Format(instr, "mtc1 'rt, 'fs");
630 Format(instr, "cmp.ule.d 'fd, 'fs, 'ft"); 645 break;
631 break; 646 case DMTC1:
632 case CMP_OR: 647 Format(instr, "dmtc1 'rt, 'fs");
633 Format(instr, "cmp.or.d 'fd, 'fs, 'ft"); 648 break;
634 break; 649 // These are called "fs" too, although they are not FPU registers.
635 case CMP_UNE: 650 case CTC1:
636 Format(instr, "cmp.une.d 'fd, 'fs, 'ft"); 651 Format(instr, "ctc1 'rt, 'fs");
637 break; 652 break;
638 case CMP_NE: 653 case CFC1:
639 Format(instr, "cmp.ne.d 'fd, 'fs, 'ft"); 654 Format(instr, "cfc1 'rt, 'fs");
640 break; 655 break;
641 default: 656 case MTHC1:
642 UNREACHABLE(); 657 Format(instr, "mthc1 'rt, 'fs");
643 } 658 break;
659 case D:
660 DecodeTypeRegisterDRsType(instr);
661 break;
662 case W:
663 switch (instr->FunctionFieldRaw()) {
664 case CVT_D_W: // Convert word to double.
665 Format(instr, "cvt.d.w 'fd, 'fs");
644 break; 666 break;
645 default: 667 default:
646 UNREACHABLE(); 668 UNREACHABLE();
647 } 669 }
648 break; 670 break;
671 case L:
672 DecodeTypeRegisterLRsType(instr);
673 break;
674 default:
675 UNREACHABLE();
676 }
677 }
678
679
680 void Decoder::DecodeTypeRegisterCOP1X(Instruction* instr) {
681 switch (instr->FunctionFieldRaw()) {
682 case MADD_D:
683 Format(instr, "madd.d 'fd, 'fr, 'fs, 'ft");
684 break;
685 default:
686 UNREACHABLE();
687 }
688 }
689
690
691 void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) {
692 switch (instr->FunctionFieldRaw()) {
693 case JR:
694 Format(instr, "jr 'rs");
695 break;
696 case JALR:
697 Format(instr, "jalr 'rs");
698 break;
699 case SLL:
700 if (0x0 == static_cast<int>(instr->InstructionBits()))
701 Format(instr, "nop");
702 else
703 Format(instr, "sll 'rd, 'rt, 'sa");
704 break;
705 case DSLL:
706 Format(instr, "dsll 'rd, 'rt, 'sa");
707 break;
708 case D_MUL_MUH: // Equals to DMUL.
709 if (kArchVariant != kMips64r6) {
710 Format(instr, "dmult 'rs, 'rt");
711 } else {
712 if (instr->SaValue() == MUL_OP) {
713 Format(instr, "dmul 'rd, 'rs, 'rt");
714 } else {
715 Format(instr, "dmuh 'rd, 'rs, 'rt");
716 }
717 }
718 break;
719 case DSLL32:
720 Format(instr, "dsll32 'rd, 'rt, 'sa");
721 break;
722 case SRL:
723 if (instr->RsValue() == 0) {
724 Format(instr, "srl 'rd, 'rt, 'sa");
725 } else {
726 if (kArchVariant == kMips64r2) {
727 Format(instr, "rotr 'rd, 'rt, 'sa");
728 } else {
729 Unknown(instr);
730 }
731 }
732 break;
733 case DSRL:
734 if (instr->RsValue() == 0) {
735 Format(instr, "dsrl 'rd, 'rt, 'sa");
736 } else {
737 if (kArchVariant == kMips64r2) {
738 Format(instr, "drotr 'rd, 'rt, 'sa");
739 } else {
740 Unknown(instr);
741 }
742 }
743 break;
744 case DSRL32:
745 Format(instr, "dsrl32 'rd, 'rt, 'sa");
746 break;
747 case SRA:
748 Format(instr, "sra 'rd, 'rt, 'sa");
749 break;
750 case DSRA:
751 Format(instr, "dsra 'rd, 'rt, 'sa");
752 break;
753 case DSRA32:
754 Format(instr, "dsra32 'rd, 'rt, 'sa");
755 break;
756 case SLLV:
757 Format(instr, "sllv 'rd, 'rt, 'rs");
758 break;
759 case DSLLV:
760 Format(instr, "dsllv 'rd, 'rt, 'rs");
761 break;
762 case SRLV:
763 if (instr->SaValue() == 0) {
764 Format(instr, "srlv 'rd, 'rt, 'rs");
765 } else {
766 if (kArchVariant == kMips64r2) {
767 Format(instr, "rotrv 'rd, 'rt, 'rs");
768 } else {
769 Unknown(instr);
770 }
771 }
772 break;
773 case DSRLV:
774 if (instr->SaValue() == 0) {
775 Format(instr, "dsrlv 'rd, 'rt, 'rs");
776 } else {
777 if (kArchVariant == kMips64r2) {
778 Format(instr, "drotrv 'rd, 'rt, 'rs");
779 } else {
780 Unknown(instr);
781 }
782 }
783 break;
784 case SRAV:
785 Format(instr, "srav 'rd, 'rt, 'rs");
786 break;
787 case DSRAV:
788 Format(instr, "dsrav 'rd, 'rt, 'rs");
789 break;
790 case MFHI:
791 if (instr->Bits(25, 16) == 0) {
792 Format(instr, "mfhi 'rd");
793 } else {
794 if ((instr->FunctionFieldRaw() == CLZ_R6) && (instr->FdValue() == 1)) {
795 Format(instr, "clz 'rd, 'rs");
796 } else if ((instr->FunctionFieldRaw() == CLO_R6) &&
797 (instr->FdValue() == 1)) {
798 Format(instr, "clo 'rd, 'rs");
799 }
800 }
801 break;
802 case MFLO:
803 Format(instr, "mflo 'rd");
804 break;
805 case D_MUL_MUH_U: // Equals to DMULTU.
806 if (kArchVariant != kMips64r6) {
807 Format(instr, "dmultu 'rs, 'rt");
808 } else {
809 if (instr->SaValue() == MUL_OP) {
810 Format(instr, "dmulu 'rd, 'rs, 'rt");
811 } else {
812 Format(instr, "dmuhu 'rd, 'rs, 'rt");
813 }
814 }
815 break;
816 case MULT: // @Mips64r6 == MUL_MUH.
817 if (kArchVariant != kMips64r6) {
818 Format(instr, "mult 'rs, 'rt");
819 } else {
820 if (instr->SaValue() == MUL_OP) {
821 Format(instr, "mul 'rd, 'rs, 'rt");
822 } else {
823 Format(instr, "muh 'rd, 'rs, 'rt");
824 }
825 }
826 break;
827 case MULTU: // @Mips64r6 == MUL_MUH_U.
828 if (kArchVariant != kMips64r6) {
829 Format(instr, "multu 'rs, 'rt");
830 } else {
831 if (instr->SaValue() == MUL_OP) {
832 Format(instr, "mulu 'rd, 'rs, 'rt");
833 } else {
834 Format(instr, "muhu 'rd, 'rs, 'rt");
835 }
836 }
837
838 break;
839 case DIV: // @Mips64r6 == DIV_MOD.
840 if (kArchVariant != kMips64r6) {
841 Format(instr, "div 'rs, 'rt");
842 } else {
843 if (instr->SaValue() == DIV_OP) {
844 Format(instr, "div 'rd, 'rs, 'rt");
845 } else {
846 Format(instr, "mod 'rd, 'rs, 'rt");
847 }
848 }
849 break;
850 case DDIV: // @Mips64r6 == D_DIV_MOD.
851 if (kArchVariant != kMips64r6) {
852 Format(instr, "ddiv 'rs, 'rt");
853 } else {
854 if (instr->SaValue() == DIV_OP) {
855 Format(instr, "ddiv 'rd, 'rs, 'rt");
856 } else {
857 Format(instr, "dmod 'rd, 'rs, 'rt");
858 }
859 }
860 break;
861 case DIVU: // @Mips64r6 == DIV_MOD_U.
862 if (kArchVariant != kMips64r6) {
863 Format(instr, "divu 'rs, 'rt");
864 } else {
865 if (instr->SaValue() == DIV_OP) {
866 Format(instr, "divu 'rd, 'rs, 'rt");
867 } else {
868 Format(instr, "modu 'rd, 'rs, 'rt");
869 }
870 }
871 break;
872 case DDIVU: // @Mips64r6 == D_DIV_MOD_U.
873 if (kArchVariant != kMips64r6) {
874 Format(instr, "ddivu 'rs, 'rt");
875 } else {
876 if (instr->SaValue() == DIV_OP) {
877 Format(instr, "ddivu 'rd, 'rs, 'rt");
878 } else {
879 Format(instr, "dmodu 'rd, 'rs, 'rt");
880 }
881 }
882 break;
883 case ADD:
884 Format(instr, "add 'rd, 'rs, 'rt");
885 break;
886 case DADD:
887 Format(instr, "dadd 'rd, 'rs, 'rt");
888 break;
889 case ADDU:
890 Format(instr, "addu 'rd, 'rs, 'rt");
891 break;
892 case DADDU:
893 Format(instr, "daddu 'rd, 'rs, 'rt");
894 break;
895 case SUB:
896 Format(instr, "sub 'rd, 'rs, 'rt");
897 break;
898 case DSUB:
899 Format(instr, "dsub 'rd, 'rs, 'rt");
900 break;
901 case SUBU:
902 Format(instr, "subu 'rd, 'rs, 'rt");
903 break;
904 case DSUBU:
905 Format(instr, "dsubu 'rd, 'rs, 'rt");
906 break;
907 case AND:
908 Format(instr, "and 'rd, 'rs, 'rt");
909 break;
910 case OR:
911 if (0 == instr->RsValue()) {
912 Format(instr, "mov 'rd, 'rt");
913 } else if (0 == instr->RtValue()) {
914 Format(instr, "mov 'rd, 'rs");
915 } else {
916 Format(instr, "or 'rd, 'rs, 'rt");
917 }
918 break;
919 case XOR:
920 Format(instr, "xor 'rd, 'rs, 'rt");
921 break;
922 case NOR:
923 Format(instr, "nor 'rd, 'rs, 'rt");
924 break;
925 case SLT:
926 Format(instr, "slt 'rd, 'rs, 'rt");
927 break;
928 case SLTU:
929 Format(instr, "sltu 'rd, 'rs, 'rt");
930 break;
931 case TGE:
932 Format(instr, "tge 'rs, 'rt, code: 'code");
933 break;
934 case TGEU:
935 Format(instr, "tgeu 'rs, 'rt, code: 'code");
936 break;
937 case TLT:
938 Format(instr, "tlt 'rs, 'rt, code: 'code");
939 break;
940 case TLTU:
941 Format(instr, "tltu 'rs, 'rt, code: 'code");
942 break;
943 case TEQ:
944 Format(instr, "teq 'rs, 'rt, code: 'code");
945 break;
946 case TNE:
947 Format(instr, "tne 'rs, 'rt, code: 'code");
948 break;
949 case MOVZ:
950 Format(instr, "movz 'rd, 'rs, 'rt");
951 break;
952 case MOVN:
953 Format(instr, "movn 'rd, 'rs, 'rt");
954 break;
955 case MOVCI:
956 if (instr->Bit(16)) {
957 Format(instr, "movt 'rd, 'rs, 'bc");
958 } else {
959 Format(instr, "movf 'rd, 'rs, 'bc");
960 }
961 break;
962 case SELEQZ_S:
963 Format(instr, "seleqz 'rs, 'rt, 'rd");
964 break;
965 case SELNEZ_S:
966 Format(instr, "selnez 'rs, 'rt, 'rd");
967 break;
968 default:
969 UNREACHABLE();
970 }
971 }
972
973
974 void Decoder::DecodeTypeRegisterSPECIAL2(Instruction* instr) {
975 switch (instr->FunctionFieldRaw()) {
976 case MUL:
977 Format(instr, "mul 'rd, 'rs, 'rt");
978 break;
979 case CLZ:
980 if (kArchVariant != kMips64r6) {
981 Format(instr, "clz 'rd, 'rs");
982 }
983 break;
984 default:
985 UNREACHABLE();
986 }
987 }
988
989
990 void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) {
991 switch (instr->FunctionFieldRaw()) {
992 case INS: {
993 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2");
994 break;
995 }
996 case EXT: {
997 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1");
998 break;
999 }
1000 case DEXT: {
1001 Format(instr, "dext 'rt, 'rs, 'sa, 'ss1");
1002 break;
1003 }
1004 default:
1005 UNREACHABLE();
1006 }
1007 }
1008
1009
1010 int Decoder::DecodeTypeRegister(Instruction* instr) {
1011 switch (instr->OpcodeFieldRaw()) {
1012 case COP1: // Coprocessor instructions.
1013 DecodeTypeRegisterCOP1(instr);
1014 break;
649 case COP1X: 1015 case COP1X:
650 switch (instr->FunctionFieldRaw()) { 1016 DecodeTypeRegisterCOP1X(instr);
651 case MADD_D:
652 Format(instr, "madd.d 'fd, 'fr, 'fs, 'ft");
653 break;
654 default:
655 UNREACHABLE();
656 }
657 break; 1017 break;
658 case SPECIAL: 1018 case SPECIAL:
659 switch (instr->FunctionFieldRaw()) { 1019 switch (instr->FunctionFieldRaw()) {
660 case JR:
661 Format(instr, "jr 'rs");
662 break;
663 case JALR:
664 Format(instr, "jalr 'rs");
665 break;
666 case SLL:
667 if (0x0 == static_cast<int>(instr->InstructionBits()))
668 Format(instr, "nop");
669 else
670 Format(instr, "sll 'rd, 'rt, 'sa");
671 break;
672 case DSLL:
673 Format(instr, "dsll 'rd, 'rt, 'sa");
674 break;
675 case D_MUL_MUH: // Equals to DMUL.
676 if (kArchVariant != kMips64r6) {
677 Format(instr, "dmult 'rs, 'rt");
678 } else {
679 if (instr->SaValue() == MUL_OP) {
680 Format(instr, "dmul 'rd, 'rs, 'rt");
681 } else {
682 Format(instr, "dmuh 'rd, 'rs, 'rt");
683 }
684 }
685 break;
686 case DSLL32:
687 Format(instr, "dsll32 'rd, 'rt, 'sa");
688 break;
689 case SRL:
690 if (instr->RsValue() == 0) {
691 Format(instr, "srl 'rd, 'rt, 'sa");
692 } else {
693 if (kArchVariant == kMips64r2) {
694 Format(instr, "rotr 'rd, 'rt, 'sa");
695 } else {
696 Unknown(instr);
697 }
698 }
699 break;
700 case DSRL:
701 if (instr->RsValue() == 0) {
702 Format(instr, "dsrl 'rd, 'rt, 'sa");
703 } else {
704 if (kArchVariant == kMips64r2) {
705 Format(instr, "drotr 'rd, 'rt, 'sa");
706 } else {
707 Unknown(instr);
708 }
709 }
710 break;
711 case DSRL32:
712 Format(instr, "dsrl32 'rd, 'rt, 'sa");
713 break;
714 case SRA:
715 Format(instr, "sra 'rd, 'rt, 'sa");
716 break;
717 case DSRA:
718 Format(instr, "dsra 'rd, 'rt, 'sa");
719 break;
720 case DSRA32:
721 Format(instr, "dsra32 'rd, 'rt, 'sa");
722 break;
723 case SLLV:
724 Format(instr, "sllv 'rd, 'rt, 'rs");
725 break;
726 case DSLLV:
727 Format(instr, "dsllv 'rd, 'rt, 'rs");
728 break;
729 case SRLV:
730 if (instr->SaValue() == 0) {
731 Format(instr, "srlv 'rd, 'rt, 'rs");
732 } else {
733 if (kArchVariant == kMips64r2) {
734 Format(instr, "rotrv 'rd, 'rt, 'rs");
735 } else {
736 Unknown(instr);
737 }
738 }
739 break;
740 case DSRLV:
741 if (instr->SaValue() == 0) {
742 Format(instr, "dsrlv 'rd, 'rt, 'rs");
743 } else {
744 if (kArchVariant == kMips64r2) {
745 Format(instr, "drotrv 'rd, 'rt, 'rs");
746 } else {
747 Unknown(instr);
748 }
749 }
750 break;
751 case SRAV:
752 Format(instr, "srav 'rd, 'rt, 'rs");
753 break;
754 case DSRAV:
755 Format(instr, "dsrav 'rd, 'rt, 'rs");
756 break;
757 case MFHI:
758 if (instr->Bits(25, 16) == 0) {
759 Format(instr, "mfhi 'rd");
760 } else {
761 if ((instr->FunctionFieldRaw() == CLZ_R6)
762 && (instr->FdValue() == 1)) {
763 Format(instr, "clz 'rd, 'rs");
764 } else if ((instr->FunctionFieldRaw() == CLO_R6)
765 && (instr->FdValue() == 1)) {
766 Format(instr, "clo 'rd, 'rs");
767 }
768 }
769 break;
770 case MFLO:
771 Format(instr, "mflo 'rd");
772 break;
773 case D_MUL_MUH_U: // Equals to DMULTU.
774 if (kArchVariant != kMips64r6) {
775 Format(instr, "dmultu 'rs, 'rt");
776 } else {
777 if (instr->SaValue() == MUL_OP) {
778 Format(instr, "dmulu 'rd, 'rs, 'rt");
779 } else {
780 Format(instr, "dmuhu 'rd, 'rs, 'rt");
781 }
782 }
783 break;
784 case MULT: // @Mips64r6 == MUL_MUH.
785 if (kArchVariant != kMips64r6) {
786 Format(instr, "mult 'rs, 'rt");
787 } else {
788 if (instr->SaValue() == MUL_OP) {
789 Format(instr, "mul 'rd, 'rs, 'rt");
790 } else {
791 Format(instr, "muh 'rd, 'rs, 'rt");
792 }
793 }
794 break;
795 case MULTU: // @Mips64r6 == MUL_MUH_U.
796 if (kArchVariant != kMips64r6) {
797 Format(instr, "multu 'rs, 'rt");
798 } else {
799 if (instr->SaValue() == MUL_OP) {
800 Format(instr, "mulu 'rd, 'rs, 'rt");
801 } else {
802 Format(instr, "muhu 'rd, 'rs, 'rt");
803 }
804 }
805
806 break;
807 case DIV: // @Mips64r6 == DIV_MOD.
808 if (kArchVariant != kMips64r6) {
809 Format(instr, "div 'rs, 'rt");
810 } else {
811 if (instr->SaValue() == DIV_OP) {
812 Format(instr, "div 'rd, 'rs, 'rt");
813 } else {
814 Format(instr, "mod 'rd, 'rs, 'rt");
815 }
816 }
817 break;
818 case DDIV: // @Mips64r6 == D_DIV_MOD.
819 if (kArchVariant != kMips64r6) {
820 Format(instr, "ddiv 'rs, 'rt");
821 } else {
822 if (instr->SaValue() == DIV_OP) {
823 Format(instr, "ddiv 'rd, 'rs, 'rt");
824 } else {
825 Format(instr, "dmod 'rd, 'rs, 'rt");
826 }
827 }
828 break;
829 case DIVU: // @Mips64r6 == DIV_MOD_U.
830 if (kArchVariant != kMips64r6) {
831 Format(instr, "divu 'rs, 'rt");
832 } else {
833 if (instr->SaValue() == DIV_OP) {
834 Format(instr, "divu 'rd, 'rs, 'rt");
835 } else {
836 Format(instr, "modu 'rd, 'rs, 'rt");
837 }
838 }
839 break;
840 case DDIVU: // @Mips64r6 == D_DIV_MOD_U.
841 if (kArchVariant != kMips64r6) {
842 Format(instr, "ddivu 'rs, 'rt");
843 } else {
844 if (instr->SaValue() == DIV_OP) {
845 Format(instr, "ddivu 'rd, 'rs, 'rt");
846 } else {
847 Format(instr, "dmodu 'rd, 'rs, 'rt");
848 }
849 }
850 break;
851 case ADD:
852 Format(instr, "add 'rd, 'rs, 'rt");
853 break;
854 case DADD:
855 Format(instr, "dadd 'rd, 'rs, 'rt");
856 break;
857 case ADDU:
858 Format(instr, "addu 'rd, 'rs, 'rt");
859 break;
860 case DADDU:
861 Format(instr, "daddu 'rd, 'rs, 'rt");
862 break;
863 case SUB:
864 Format(instr, "sub 'rd, 'rs, 'rt");
865 break;
866 case DSUB:
867 Format(instr, "dsub 'rd, 'rs, 'rt");
868 break;
869 case SUBU:
870 Format(instr, "subu 'rd, 'rs, 'rt");
871 break;
872 case DSUBU:
873 Format(instr, "dsubu 'rd, 'rs, 'rt");
874 break;
875 case AND:
876 Format(instr, "and 'rd, 'rs, 'rt");
877 break;
878 case OR:
879 if (0 == instr->RsValue()) {
880 Format(instr, "mov 'rd, 'rt");
881 } else if (0 == instr->RtValue()) {
882 Format(instr, "mov 'rd, 'rs");
883 } else {
884 Format(instr, "or 'rd, 'rs, 'rt");
885 }
886 break;
887 case XOR:
888 Format(instr, "xor 'rd, 'rs, 'rt");
889 break;
890 case NOR:
891 Format(instr, "nor 'rd, 'rs, 'rt");
892 break;
893 case SLT:
894 Format(instr, "slt 'rd, 'rs, 'rt");
895 break;
896 case SLTU:
897 Format(instr, "sltu 'rd, 'rs, 'rt");
898 break;
899 case BREAK: 1020 case BREAK:
900 return DecodeBreakInstr(instr); 1021 return DecodeBreakInstr(instr);
901 case TGE: 1022 default:
902 Format(instr, "tge 'rs, 'rt, code: 'code"); 1023 DecodeTypeRegisterSPECIAL(instr);
903 break; 1024 break;
904 case TGEU:
905 Format(instr, "tgeu 'rs, 'rt, code: 'code");
906 break;
907 case TLT:
908 Format(instr, "tlt 'rs, 'rt, code: 'code");
909 break;
910 case TLTU:
911 Format(instr, "tltu 'rs, 'rt, code: 'code");
912 break;
913 case TEQ:
914 Format(instr, "teq 'rs, 'rt, code: 'code");
915 break;
916 case TNE:
917 Format(instr, "tne 'rs, 'rt, code: 'code");
918 break;
919 case MOVZ:
920 Format(instr, "movz 'rd, 'rs, 'rt");
921 break;
922 case MOVN:
923 Format(instr, "movn 'rd, 'rs, 'rt");
924 break;
925 case MOVCI:
926 if (instr->Bit(16)) {
927 Format(instr, "movt 'rd, 'rs, 'bc");
928 } else {
929 Format(instr, "movf 'rd, 'rs, 'bc");
930 }
931 break;
932 case SELEQZ_S:
933 Format(instr, "seleqz 'rd, 'rs, 'rt");
934 break;
935 case SELNEZ_S:
936 Format(instr, "selnez 'rd, 'rs, 'rt");
937 break;
938 default:
939 UNREACHABLE();
940 } 1025 }
941 break; 1026 break;
942 case SPECIAL2: 1027 case SPECIAL2:
943 switch (instr->FunctionFieldRaw()) { 1028 DecodeTypeRegisterSPECIAL2(instr);
944 case MUL:
945 Format(instr, "mul 'rd, 'rs, 'rt");
946 break;
947 case CLZ:
948 if (kArchVariant != kMips64r6) {
949 Format(instr, "clz 'rd, 'rs");
950 }
951 break;
952 default:
953 UNREACHABLE();
954 }
955 break; 1029 break;
956 case SPECIAL3: 1030 case SPECIAL3:
957 switch (instr->FunctionFieldRaw()) { 1031 DecodeTypeRegisterSPECIAL3(instr);
958 case INS: { 1032 break;
959 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); 1033 default:
960 break; 1034 UNREACHABLE();
961 } 1035 }
962 case EXT: {
963 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1");
964 break;
965 }
966 case DEXT: {
967 Format(instr, "dext 'rt, 'rs, 'sa, 'ss1");
968 break;
969 }
970 default:
971 UNREACHABLE();
972 }
973 break;
974 default:
975 UNREACHABLE();
976 }
977 return Instruction::kInstrSize; 1036 return Instruction::kInstrSize;
978 } 1037 }
979 1038
980 1039
1040 void Decoder::DecodeTypeImmediateCOP1D(Instruction* instr) {
1041 switch (instr->FunctionValue()) {
1042 case SEL:
1043 Format(instr, "sel.D 'ft, 'fs, 'fd");
1044 break;
1045 case SELEQZ_C:
1046 Format(instr, "seleqz.D 'ft, 'fs, 'fd");
1047 break;
1048 case SELNEZ_C:
1049 Format(instr, "selnez.D 'ft, 'fs, 'fd");
1050 break;
1051 case MIN:
1052 Format(instr, "min.D 'ft, 'fs, 'fd");
1053 break;
1054 case MINA:
1055 Format(instr, "mina.D 'ft, 'fs, 'fd");
1056 break;
1057 case MAX:
1058 Format(instr, "max.D 'ft, 'fs, 'fd");
1059 break;
1060 case MAXA:
1061 Format(instr, "maxa.D 'ft, 'fs, 'fd");
1062 break;
1063 default:
1064 UNREACHABLE();
1065 }
1066 }
1067
1068
1069 void Decoder::DecodeTypeImmediateCOP1L(Instruction* instr) {
1070 switch (instr->FunctionValue()) {
1071 case CMP_AF:
1072 Format(instr, "cmp.af.D 'ft, 'fs, 'fd");
1073 break;
1074 case CMP_UN:
1075 Format(instr, "cmp.un.D 'ft, 'fs, 'fd");
1076 break;
1077 case CMP_EQ:
1078 Format(instr, "cmp.eq.D 'ft, 'fs, 'fd");
1079 break;
1080 case CMP_UEQ:
1081 Format(instr, "cmp.ueq.D 'ft, 'fs, 'fd");
1082 break;
1083 case CMP_LT:
1084 Format(instr, "cmp.lt.D 'ft, 'fs, 'fd");
1085 break;
1086 case CMP_ULT:
1087 Format(instr, "cmp.ult.D 'ft, 'fs, 'fd");
1088 break;
1089 case CMP_LE:
1090 Format(instr, "cmp.le.D 'ft, 'fs, 'fd");
1091 break;
1092 case CMP_ULE:
1093 Format(instr, "cmp.ule.D 'ft, 'fs, 'fd");
1094 break;
1095 case CMP_OR:
1096 Format(instr, "cmp.or.D 'ft, 'fs, 'fd");
1097 break;
1098 case CMP_UNE:
1099 Format(instr, "cmp.une.D 'ft, 'fs, 'fd");
1100 break;
1101 case CMP_NE:
1102 Format(instr, "cmp.ne.D 'ft, 'fs, 'fd");
1103 break;
1104 default:
1105 UNREACHABLE();
1106 }
1107 }
1108
1109
1110 void Decoder::DecodeTypeImmediateCOP1S(Instruction* instr) {
1111 switch (instr->FunctionValue()) {
1112 case SEL:
1113 Format(instr, "sel.S 'ft, 'fs, 'fd");
1114 break;
1115 case SELEQZ_C:
1116 Format(instr, "seleqz.S 'ft, 'fs, 'fd");
1117 break;
1118 case SELNEZ_C:
1119 Format(instr, "selnez.S 'ft, 'fs, 'fd");
1120 break;
1121 case MIN:
1122 Format(instr, "min.S 'ft, 'fs, 'fd");
1123 break;
1124 case MINA:
1125 Format(instr, "mina.S 'ft, 'fs, 'fd");
1126 break;
1127 case MAX:
1128 Format(instr, "max.S 'ft, 'fs, 'fd");
1129 break;
1130 case MAXA:
1131 Format(instr, "maxa.S 'ft, 'fs, 'fd");
1132 break;
1133 default:
1134 UNREACHABLE();
1135 }
1136 }
1137
1138
1139 void Decoder::DecodeTypeImmediateCOP1W(Instruction* instr) {
1140 switch (instr->FunctionValue()) {
1141 case CMP_AF:
1142 Format(instr, "cmp.af.S 'ft, 'fs, 'fd");
1143 break;
1144 case CMP_UN:
1145 Format(instr, "cmp.un.S 'ft, 'fs, 'fd");
1146 break;
1147 case CMP_EQ:
1148 Format(instr, "cmp.eq.S 'ft, 'fs, 'fd");
1149 break;
1150 case CMP_UEQ:
1151 Format(instr, "cmp.ueq.S 'ft, 'fs, 'fd");
1152 break;
1153 case CMP_LT:
1154 Format(instr, "cmp.lt.S 'ft, 'fs, 'fd");
1155 break;
1156 case CMP_ULT:
1157 Format(instr, "cmp.ult.S 'ft, 'fs, 'fd");
1158 break;
1159 case CMP_LE:
1160 Format(instr, "cmp.le.S 'ft, 'fs, 'fd");
1161 break;
1162 case CMP_ULE:
1163 Format(instr, "cmp.ule.S 'ft, 'fs, 'fd");
1164 break;
1165 case CMP_OR:
1166 Format(instr, "cmp.or.S 'ft, 'fs, 'fd");
1167 break;
1168 case CMP_UNE:
1169 Format(instr, "cmp.une.S 'ft, 'fs, 'fd");
1170 break;
1171 case CMP_NE:
1172 Format(instr, "cmp.ne.S 'ft, 'fs, 'fd");
1173 break;
1174 default:
1175 UNREACHABLE();
1176 }
1177 }
1178
1179
1180 void Decoder::DecodeTypeImmediateCOP1(Instruction* instr) {
1181 switch (instr->RsFieldRaw()) {
1182 case BC1:
1183 if (instr->FBtrueValue()) {
1184 Format(instr, "bc1t 'bc, 'imm16u");
1185 } else {
1186 Format(instr, "bc1f 'bc, 'imm16u");
1187 }
1188 break;
1189 case BC1EQZ:
1190 Format(instr, "bc1eqz 'ft, 'imm16u");
1191 break;
1192 case BC1NEZ:
1193 Format(instr, "bc1nez 'ft, 'imm16u");
1194 break;
1195 case W: // CMP.S instruction.
1196 DecodeTypeImmediateCOP1W(instr);
1197 break;
1198 case L: // CMP.D instruction.
1199 DecodeTypeImmediateCOP1L(instr);
1200 break;
1201 case S:
1202 DecodeTypeImmediateCOP1S(instr);
1203 break;
1204 case D:
1205 DecodeTypeImmediateCOP1D(instr);
1206 break;
1207 default:
1208 UNREACHABLE();
1209 }
1210 }
1211
1212
1213 void Decoder::DecodeTypeImmediateREGIMM(Instruction* instr) {
1214 switch (instr->RtFieldRaw()) {
1215 case BLTZ:
1216 Format(instr, "bltz 'rs, 'imm16u");
1217 break;
1218 case BLTZAL:
1219 Format(instr, "bltzal 'rs, 'imm16u");
1220 break;
1221 case BGEZ:
1222 Format(instr, "bgez 'rs, 'imm16u");
1223 break;
1224 case BGEZAL:
1225 Format(instr, "bgezal 'rs, 'imm16u");
1226 break;
1227 case BGEZALL:
1228 Format(instr, "bgezall 'rs, 'imm16u");
1229 break;
1230 case DAHI:
1231 Format(instr, "dahi 'rs, 'imm16u");
1232 break;
1233 case DATI:
1234 Format(instr, "dati 'rs, 'imm16u");
1235 break;
1236 default:
1237 UNREACHABLE();
1238 }
1239 }
1240
1241
981 void Decoder::DecodeTypeImmediate(Instruction* instr) { 1242 void Decoder::DecodeTypeImmediate(Instruction* instr) {
982 switch (instr->OpcodeFieldRaw()) { 1243 switch (instr->OpcodeFieldRaw()) {
983 case COP1: 1244 case COP1:
984 switch (instr->RsFieldRaw()) { 1245 DecodeTypeImmediateCOP1(instr);
985 case BC1:
986 if (instr->FBtrueValue()) {
987 Format(instr, "bc1t 'bc, 'imm16u");
988 } else {
989 Format(instr, "bc1f 'bc, 'imm16u");
990 }
991 break;
992 case BC1EQZ:
993 Format(instr, "bc1eqz 'ft, 'imm16u");
994 break;
995 case BC1NEZ:
996 Format(instr, "bc1nez 'ft, 'imm16u");
997 break;
998 case W: // CMP.S instruction.
999 switch (instr->FunctionValue()) {
1000 case CMP_AF:
1001 Format(instr, "cmp.af.S 'ft, 'fs, 'fd");
1002 break;
1003 case CMP_UN:
1004 Format(instr, "cmp.un.S 'ft, 'fs, 'fd");
1005 break;
1006 case CMP_EQ:
1007 Format(instr, "cmp.eq.S 'ft, 'fs, 'fd");
1008 break;
1009 case CMP_UEQ:
1010 Format(instr, "cmp.ueq.S 'ft, 'fs, 'fd");
1011 break;
1012 case CMP_LT:
1013 Format(instr, "cmp.lt.S 'ft, 'fs, 'fd");
1014 break;
1015 case CMP_ULT:
1016 Format(instr, "cmp.ult.S 'ft, 'fs, 'fd");
1017 break;
1018 case CMP_LE:
1019 Format(instr, "cmp.le.S 'ft, 'fs, 'fd");
1020 break;
1021 case CMP_ULE:
1022 Format(instr, "cmp.ule.S 'ft, 'fs, 'fd");
1023 break;
1024 case CMP_OR:
1025 Format(instr, "cmp.or.S 'ft, 'fs, 'fd");
1026 break;
1027 case CMP_UNE:
1028 Format(instr, "cmp.une.S 'ft, 'fs, 'fd");
1029 break;
1030 case CMP_NE:
1031 Format(instr, "cmp.ne.S 'ft, 'fs, 'fd");
1032 break;
1033 default:
1034 UNREACHABLE();
1035 }
1036 break;
1037 case L: // CMP.D instruction.
1038 switch (instr->FunctionValue()) {
1039 case CMP_AF:
1040 Format(instr, "cmp.af.D 'ft, 'fs, 'fd");
1041 break;
1042 case CMP_UN:
1043 Format(instr, "cmp.un.D 'ft, 'fs, 'fd");
1044 break;
1045 case CMP_EQ:
1046 Format(instr, "cmp.eq.D 'ft, 'fs, 'fd");
1047 break;
1048 case CMP_UEQ:
1049 Format(instr, "cmp.ueq.D 'ft, 'fs, 'fd");
1050 break;
1051 case CMP_LT:
1052 Format(instr, "cmp.lt.D 'ft, 'fs, 'fd");
1053 break;
1054 case CMP_ULT:
1055 Format(instr, "cmp.ult.D 'ft, 'fs, 'fd");
1056 break;
1057 case CMP_LE:
1058 Format(instr, "cmp.le.D 'ft, 'fs, 'fd");
1059 break;
1060 case CMP_ULE:
1061 Format(instr, "cmp.ule.D 'ft, 'fs, 'fd");
1062 break;
1063 case CMP_OR:
1064 Format(instr, "cmp.or.D 'ft, 'fs, 'fd");
1065 break;
1066 case CMP_UNE:
1067 Format(instr, "cmp.une.D 'ft, 'fs, 'fd");
1068 break;
1069 case CMP_NE:
1070 Format(instr, "cmp.ne.D 'ft, 'fs, 'fd");
1071 break;
1072 default:
1073 UNREACHABLE();
1074 }
1075 break;
1076 case S:
1077 switch (instr->FunctionValue()) {
1078 case SEL:
1079 Format(instr, "sel.S 'ft, 'fs, 'fd");
1080 break;
1081 case SELEQZ_C:
1082 Format(instr, "seleqz.S 'ft, 'fs, 'fd");
1083 break;
1084 case SELNEZ_C:
1085 Format(instr, "selnez.S 'ft, 'fs, 'fd");
1086 break;
1087 case MIN:
1088 Format(instr, "min.S 'ft, 'fs, 'fd");
1089 break;
1090 case MINA:
1091 Format(instr, "mina.S 'ft, 'fs, 'fd");
1092 break;
1093 case MAX:
1094 Format(instr, "max.S 'ft, 'fs, 'fd");
1095 break;
1096 case MAXA:
1097 Format(instr, "maxa.S 'ft, 'fs, 'fd");
1098 break;
1099 default:
1100 UNREACHABLE();
1101 }
1102 break;
1103 case D:
1104 switch (instr->FunctionValue()) {
1105 case SEL:
1106 Format(instr, "sel.D 'ft, 'fs, 'fd");
1107 break;
1108 case SELEQZ_C:
1109 Format(instr, "seleqz.D 'ft, 'fs, 'fd");
1110 break;
1111 case SELNEZ_C:
1112 Format(instr, "selnez.D 'ft, 'fs, 'fd");
1113 break;
1114 case MIN:
1115 Format(instr, "min.D 'ft, 'fs, 'fd");
1116 break;
1117 case MINA:
1118 Format(instr, "mina.D 'ft, 'fs, 'fd");
1119 break;
1120 case MAX:
1121 Format(instr, "max.D 'ft, 'fs, 'fd");
1122 break;
1123 case MAXA:
1124 Format(instr, "maxa.D 'ft, 'fs, 'fd");
1125 break;
1126 default:
1127 UNREACHABLE();
1128 }
1129 break;
1130 default:
1131 UNREACHABLE();
1132 }
1133
1134 break; // Case COP1. 1246 break; // Case COP1.
1135 // ------------- REGIMM class. 1247 // ------------- REGIMM class.
1136 case REGIMM: 1248 case REGIMM:
1137 switch (instr->RtFieldRaw()) { 1249
1138 case BLTZ:
1139 Format(instr, "bltz 'rs, 'imm16u");
1140 break;
1141 case BLTZAL:
1142 Format(instr, "bltzal 'rs, 'imm16u");
1143 break;
1144 case BGEZ:
1145 Format(instr, "bgez 'rs, 'imm16u");
1146 break;
1147 case BGEZAL:
1148 Format(instr, "bgezal 'rs, 'imm16u");
1149 break;
1150 case BGEZALL:
1151 Format(instr, "bgezall 'rs, 'imm16u");
1152 break;
1153 case DAHI:
1154 Format(instr, "dahi 'rs, 'imm16u");
1155 break;
1156 case DATI:
1157 Format(instr, "dati 'rs, 'imm16u");
1158 break;
1159 default:
1160 UNREACHABLE();
1161 }
1162 break; // Case REGIMM. 1250 break; // Case REGIMM.
1163 // ------------- Branch instructions. 1251 // ------------- Branch instructions.
1164 case BEQ: 1252 case BEQ:
1165 Format(instr, "beq 'rs, 'rt, 'imm16u"); 1253 Format(instr, "beq 'rs, 'rt, 'imm16u");
1166 break; 1254 break;
1167 case BNE: 1255 case BNE:
1168 Format(instr, "bne 'rs, 'rt, 'imm16u"); 1256 Format(instr, "bne 'rs, 'rt, 'imm16u");
1169 break; 1257 break;
1170 case BLEZ: 1258 case BLEZ:
1171 if ((instr->RtFieldRaw() == 0) 1259 if ((instr->RtFieldRaw() == 0)
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
1499 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); 1587 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
1500 } 1588 }
1501 } 1589 }
1502 1590
1503 1591
1504 #undef UNSUPPORTED 1592 #undef UNSUPPORTED
1505 1593
1506 } // namespace disasm 1594 } // namespace disasm
1507 1595
1508 #endif // V8_TARGET_ARCH_MIPS64 1596 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698