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

Side by Side Diff: src/mips/disasm-mips.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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 // Printing of instruction name. 92 // Printing of instruction name.
93 void PrintInstructionName(Instruction* instr); 93 void PrintInstructionName(Instruction* instr);
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 101
102
102 // 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);
paul.l... 2015/03/31 04:02:01 nit: consider naming here, maybe: DecodeTypeRegist
107 void DecodeTypeRegisterSPECIAL2(Instruction* instr);
108 void DecodeTypeRegisterSPECIAL3(Instruction* instr);
103 void DecodeTypeRegister(Instruction* instr); 109 void DecodeTypeRegister(Instruction* instr);
104 void DecodeTypeImmediate(Instruction* instr); 110 void DecodeTypeImmediate(Instruction* instr);
105 void DecodeTypeJump(Instruction* instr); 111 void DecodeTypeJump(Instruction* instr);
106 112
107 const disasm::NameConverter& converter_; 113 const disasm::NameConverter& converter_;
108 v8::internal::Vector<char> out_buffer_; 114 v8::internal::Vector<char> out_buffer_;
109 int out_buffer_pos_; 115 int out_buffer_pos_;
110 116
111 DISALLOW_COPY_AND_ASSIGN(Decoder); 117 DISALLOW_COPY_AND_ASSIGN(Decoder);
112 }; 118 };
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 } 448 }
443 449
444 450
445 // For currently unimplemented decodings the disassembler calls Unknown(instr) 451 // For currently unimplemented decodings the disassembler calls Unknown(instr)
446 // which will just print "unknown" of the instruction bits. 452 // which will just print "unknown" of the instruction bits.
447 void Decoder::Unknown(Instruction* instr) { 453 void Decoder::Unknown(Instruction* instr) {
448 Format(instr, "unknown"); 454 Format(instr, "unknown");
449 } 455 }
450 456
451 457
458 void Decoder::DecodeTypeRegisterDRsType(Instruction* instr) {
459 switch (instr->FunctionFieldRaw()) {
460 case ADD_D:
461 Format(instr, "add.d 'fd, 'fs, 'ft");
462 break;
463 case SUB_D:
464 Format(instr, "sub.d 'fd, 'fs, 'ft");
465 break;
466 case MUL_D:
467 Format(instr, "mul.d 'fd, 'fs, 'ft");
468 break;
469 case DIV_D:
470 Format(instr, "div.d 'fd, 'fs, 'ft");
471 break;
472 case ABS_D:
473 Format(instr, "abs.d 'fd, 'fs");
474 break;
475 case MOV_D:
476 Format(instr, "mov.d 'fd, 'fs");
477 break;
478 case NEG_D:
479 Format(instr, "neg.d 'fd, 'fs");
480 break;
481 case SQRT_D:
482 Format(instr, "sqrt.d 'fd, 'fs");
483 break;
484 case CVT_W_D:
485 Format(instr, "cvt.w.d 'fd, 'fs");
486 break;
487 case CVT_L_D:
488 Format(instr, "cvt.l.d 'fd, 'fs");
489 break;
490 case TRUNC_W_D:
491 Format(instr, "trunc.w.d 'fd, 'fs");
492 break;
493 case TRUNC_L_D:
494 Format(instr, "trunc.l.d 'fd, 'fs");
495 break;
496 case ROUND_W_D:
497 Format(instr, "round.w.d 'fd, 'fs");
498 break;
499 case FLOOR_W_D:
500 Format(instr, "floor.w.d 'fd, 'fs");
501 break;
502 case CEIL_W_D:
503 Format(instr, "ceil.w.d 'fd, 'fs");
504 break;
505 case CVT_S_D:
506 Format(instr, "cvt.s.d 'fd, 'fs");
507 break;
508 case C_F_D:
509 Format(instr, "c.f.d 'fs, 'ft, 'Cc");
510 break;
511 case C_UN_D:
512 Format(instr, "c.un.d 'fs, 'ft, 'Cc");
513 break;
514 case C_EQ_D:
515 Format(instr, "c.eq.d 'fs, 'ft, 'Cc");
516 break;
517 case C_UEQ_D:
518 Format(instr, "c.ueq.d 'fs, 'ft, 'Cc");
519 break;
520 case C_OLT_D:
521 Format(instr, "c.olt.d 'fs, 'ft, 'Cc");
522 break;
523 case C_ULT_D:
524 Format(instr, "c.ult.d 'fs, 'ft, 'Cc");
525 break;
526 case C_OLE_D:
527 Format(instr, "c.ole.d 'fs, 'ft, 'Cc");
528 break;
529 case C_ULE_D:
530 Format(instr, "c.ule.d 'fs, 'ft, 'Cc");
531 break;
532 default:
533 Format(instr, "unknown.cop1.d");
534 break;
535 }
536 }
537
538
539 void Decoder::DecodeTypeRegisterLRsType(Instruction* instr) {
540 switch (instr->FunctionFieldRaw()) {
541 case CVT_D_L:
542 Format(instr, "cvt.d.l 'fd, 'fs");
543 break;
544 case CVT_S_L:
545 Format(instr, "cvt.s.l 'fd, 'fs");
546 break;
547 case CMP_UN:
548 Format(instr, "cmp.un.d 'fd, 'fs, 'ft");
549 break;
550 case CMP_EQ:
551 Format(instr, "cmp.eq.d 'fd, 'fs, 'ft");
552 break;
553 case CMP_UEQ:
554 Format(instr, "cmp.ueq.d 'fd, 'fs, 'ft");
555 break;
556 case CMP_LT:
557 Format(instr, "cmp.lt.d 'fd, 'fs, 'ft");
558 break;
559 case CMP_ULT:
560 Format(instr, "cmp.ult.d 'fd, 'fs, 'ft");
561 break;
562 case CMP_LE:
563 Format(instr, "cmp.le.d 'fd, 'fs, 'ft");
564 break;
565 case CMP_ULE:
566 Format(instr, "cmp.ule.d 'fd, 'fs, 'ft");
567 break;
568 case CMP_OR:
569 Format(instr, "cmp.or.d 'fd, 'fs, 'ft");
570 break;
571 case CMP_UNE:
572 Format(instr, "cmp.une.d 'fd, 'fs, 'ft");
573 break;
574 case CMP_NE:
575 Format(instr, "cmp.ne.d 'fd, 'fs, 'ft");
576 break;
577 default:
578 UNREACHABLE();
579 }
580 }
581
582
583 void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) {
584 switch (instr->FunctionFieldRaw()) {
585 case JR:
586 Format(instr, "jr 'rs");
587 break;
588 case JALR:
589 Format(instr, "jalr 'rs");
590 break;
591 case SLL:
592 if (0x0 == static_cast<int>(instr->InstructionBits()))
593 Format(instr, "nop");
594 else
595 Format(instr, "sll 'rd, 'rt, 'sa");
596 break;
597 case SRL:
598 if (instr->RsValue() == 0) {
599 Format(instr, "srl 'rd, 'rt, 'sa");
600 } else {
601 if (IsMipsArchVariant(kMips32r2)) {
602 Format(instr, "rotr 'rd, 'rt, 'sa");
603 } else {
604 Unknown(instr);
605 }
606 }
607 break;
608 case SRA:
609 Format(instr, "sra 'rd, 'rt, 'sa");
610 break;
611 case SLLV:
612 Format(instr, "sllv 'rd, 'rt, 'rs");
613 break;
614 case SRLV:
615 if (instr->SaValue() == 0) {
616 Format(instr, "srlv 'rd, 'rt, 'rs");
617 } else {
618 if (IsMipsArchVariant(kMips32r2)) {
619 Format(instr, "rotrv 'rd, 'rt, 'rs");
620 } else {
621 Unknown(instr);
622 }
623 }
624 break;
625 case SRAV:
626 Format(instr, "srav 'rd, 'rt, 'rs");
627 break;
628 case MFHI:
629 if (instr->Bits(25, 16) == 0) {
630 Format(instr, "mfhi 'rd");
631 } else {
632 if ((instr->FunctionFieldRaw() == CLZ_R6) && (instr->FdValue() == 1)) {
633 Format(instr, "clz 'rd, 'rs");
634 } else if ((instr->FunctionFieldRaw() == CLO_R6) &&
635 (instr->FdValue() == 1)) {
636 Format(instr, "clo 'rd, 'rs");
637 }
638 }
639 break;
640 case MFLO:
641 Format(instr, "mflo 'rd");
642 break;
643 case MULT: // @Mips32r6 == MUL_MUH.
644 if (!IsMipsArchVariant(kMips32r6)) {
645 Format(instr, "mult 'rs, 'rt");
646 } else {
647 if (instr->SaValue() == MUL_OP) {
648 Format(instr, "mul 'rd, 'rs, 'rt");
649 } else {
650 Format(instr, "muh 'rd, 'rs, 'rt");
651 }
652 }
653 break;
654 case MULTU: // @Mips32r6 == MUL_MUH_U.
655 if (!IsMipsArchVariant(kMips32r6)) {
656 Format(instr, "multu 'rs, 'rt");
657 } else {
658 if (instr->SaValue() == MUL_OP) {
659 Format(instr, "mulu 'rd, 'rs, 'rt");
660 } else {
661 Format(instr, "muhu 'rd, 'rs, 'rt");
662 }
663 }
664 break;
665 case DIV: // @Mips32r6 == DIV_MOD.
666 if (!IsMipsArchVariant(kMips32r6)) {
667 Format(instr, "div 'rs, 'rt");
668 } else {
669 if (instr->SaValue() == DIV_OP) {
670 Format(instr, "div 'rd, 'rs, 'rt");
671 } else {
672 Format(instr, "mod 'rd, 'rs, 'rt");
673 }
674 }
675 break;
676 case DIVU: // @Mips32r6 == DIV_MOD_U.
677 if (!IsMipsArchVariant(kMips32r6)) {
678 Format(instr, "divu 'rs, 'rt");
679 } else {
680 if (instr->SaValue() == DIV_OP) {
681 Format(instr, "divu 'rd, 'rs, 'rt");
682 } else {
683 Format(instr, "modu 'rd, 'rs, 'rt");
684 }
685 }
686 break;
687 case ADD:
688 Format(instr, "add 'rd, 'rs, 'rt");
689 break;
690 case ADDU:
691 Format(instr, "addu 'rd, 'rs, 'rt");
692 break;
693 case SUB:
694 Format(instr, "sub 'rd, 'rs, 'rt");
695 break;
696 case SUBU:
697 Format(instr, "subu 'rd, 'rs, 'rt");
698 break;
699 case AND:
700 Format(instr, "and 'rd, 'rs, 'rt");
701 break;
702 case OR:
703 if (0 == instr->RsValue()) {
704 Format(instr, "mov 'rd, 'rt");
705 } else if (0 == instr->RtValue()) {
706 Format(instr, "mov 'rd, 'rs");
707 } else {
708 Format(instr, "or 'rd, 'rs, 'rt");
709 }
710 break;
711 case XOR:
712 Format(instr, "xor 'rd, 'rs, 'rt");
713 break;
714 case NOR:
715 Format(instr, "nor 'rd, 'rs, 'rt");
716 break;
717 case SLT:
718 Format(instr, "slt 'rd, 'rs, 'rt");
719 break;
720 case SLTU:
721 Format(instr, "sltu 'rd, 'rs, 'rt");
722 break;
723 case BREAK:
724 Format(instr, "break, code: 'code");
725 break;
726 case TGE:
727 Format(instr, "tge 'rs, 'rt, code: 'code");
728 break;
729 case TGEU:
730 Format(instr, "tgeu 'rs, 'rt, code: 'code");
731 break;
732 case TLT:
733 Format(instr, "tlt 'rs, 'rt, code: 'code");
734 break;
735 case TLTU:
736 Format(instr, "tltu 'rs, 'rt, code: 'code");
737 break;
738 case TEQ:
739 Format(instr, "teq 'rs, 'rt, code: 'code");
740 break;
741 case TNE:
742 Format(instr, "tne 'rs, 'rt, code: 'code");
743 break;
744 case MOVZ:
745 Format(instr, "movz 'rd, 'rs, 'rt");
746 break;
747 case MOVN:
748 Format(instr, "movn 'rd, 'rs, 'rt");
749 break;
750 case MOVCI:
751 if (instr->Bit(16)) {
752 Format(instr, "movt 'rd, 'rs, 'bc");
753 } else {
754 Format(instr, "movf 'rd, 'rs, 'bc");
755 }
756 break;
757 case SELEQZ_S:
758 Format(instr, "seleqz 'rs, 'rt, 'rd");
759 break;
760 case SELNEZ_S:
761 Format(instr, "selnez 'rs, 'rt, 'rd");
762 break;
763 default:
764 UNREACHABLE();
765 }
766 }
767
768
769 void Decoder::DecodeTypeRegisterSPECIAL2(Instruction* instr) {
770 switch (instr->FunctionFieldRaw()) {
771 case MUL:
772 Format(instr, "mul 'rd, 'rs, 'rt");
773 break;
774 case CLZ:
775 if (!IsMipsArchVariant(kMips32r6)) {
776 Format(instr, "clz 'rd, 'rs");
777 }
778 break;
779 default:
780 UNREACHABLE();
781 }
782 }
783
784
785 void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) {
786 switch (instr->FunctionFieldRaw()) {
787 case INS: {
788 if (IsMipsArchVariant(kMips32r2)) {
789 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2");
790 } else {
791 Unknown(instr);
792 }
793 break;
794 }
795 case EXT: {
796 if (IsMipsArchVariant(kMips32r2)) {
797 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1");
798 } else {
799 Unknown(instr);
800 }
801 break;
802 }
803 default:
804 UNREACHABLE();
805 }
806 }
807
808
452 void Decoder::DecodeTypeRegister(Instruction* instr) { 809 void Decoder::DecodeTypeRegister(Instruction* instr) {
453 switch (instr->OpcodeFieldRaw()) { 810 switch (instr->OpcodeFieldRaw()) {
454 case COP1: // Coprocessor instructions. 811 case COP1: // Coprocessor instructions.
455 switch (instr->RsFieldRaw()) { 812 switch (instr->RsFieldRaw()) {
456 case BC1: // bc1 handled in DecodeTypeImmediate. 813 case BC1: // bc1 handled in DecodeTypeImmediate.
457 UNREACHABLE(); 814 UNREACHABLE();
458 break; 815 break;
459 case MFC1: 816 case MFC1:
460 Format(instr, "mfc1 'rt, 'fs"); 817 Format(instr, "mfc1 'rt, 'fs");
461 break; 818 break;
462 case MFHC1: 819 case MFHC1:
463 Format(instr, "mfhc1 'rt, 'fs"); 820 Format(instr, "mfhc1 'rt, 'fs");
464 break; 821 break;
465 case MTC1: 822 case MTC1:
466 Format(instr, "mtc1 'rt, 'fs"); 823 Format(instr, "mtc1 'rt, 'fs");
467 break; 824 break;
468 // These are called "fs" too, although they are not FPU registers. 825 // These are called "fs" too, although they are not FPU registers.
469 case CTC1: 826 case CTC1:
470 Format(instr, "ctc1 'rt, 'fs"); 827 Format(instr, "ctc1 'rt, 'fs");
471 break; 828 break;
472 case CFC1: 829 case CFC1:
473 Format(instr, "cfc1 'rt, 'fs"); 830 Format(instr, "cfc1 'rt, 'fs");
474 break; 831 break;
475 case MTHC1: 832 case MTHC1:
476 Format(instr, "mthc1 'rt, 'fs"); 833 Format(instr, "mthc1 'rt, 'fs");
477 break; 834 break;
478 case D: 835 case D:
479 switch (instr->FunctionFieldRaw()) { 836 DecodeTypeRegisterDRsType(instr);
480 case ADD_D:
481 Format(instr, "add.d 'fd, 'fs, 'ft");
482 break;
483 case SUB_D:
484 Format(instr, "sub.d 'fd, 'fs, 'ft");
485 break;
486 case MUL_D:
487 Format(instr, "mul.d 'fd, 'fs, 'ft");
488 break;
489 case DIV_D:
490 Format(instr, "div.d 'fd, 'fs, 'ft");
491 break;
492 case ABS_D:
493 Format(instr, "abs.d 'fd, 'fs");
494 break;
495 case MOV_D:
496 Format(instr, "mov.d 'fd, 'fs");
497 break;
498 case NEG_D:
499 Format(instr, "neg.d 'fd, 'fs");
500 break;
501 case SQRT_D:
502 Format(instr, "sqrt.d 'fd, 'fs");
503 break;
504 case CVT_W_D:
505 Format(instr, "cvt.w.d 'fd, 'fs");
506 break;
507 case CVT_L_D:
508 Format(instr, "cvt.l.d 'fd, 'fs");
509 break;
510 case TRUNC_W_D:
511 Format(instr, "trunc.w.d 'fd, 'fs");
512 break;
513 case TRUNC_L_D:
514 Format(instr, "trunc.l.d 'fd, 'fs");
515 break;
516 case ROUND_W_D:
517 Format(instr, "round.w.d 'fd, 'fs");
518 break;
519 case FLOOR_W_D:
520 Format(instr, "floor.w.d 'fd, 'fs");
521 break;
522 case CEIL_W_D:
523 Format(instr, "ceil.w.d 'fd, 'fs");
524 break;
525 case CVT_S_D:
526 Format(instr, "cvt.s.d 'fd, 'fs");
527 break;
528 case C_F_D:
529 Format(instr, "c.f.d 'fs, 'ft, 'Cc");
530 break;
531 case C_UN_D:
532 Format(instr, "c.un.d 'fs, 'ft, 'Cc");
533 break;
534 case C_EQ_D:
535 Format(instr, "c.eq.d 'fs, 'ft, 'Cc");
536 break;
537 case C_UEQ_D:
538 Format(instr, "c.ueq.d 'fs, 'ft, 'Cc");
539 break;
540 case C_OLT_D:
541 Format(instr, "c.olt.d 'fs, 'ft, 'Cc");
542 break;
543 case C_ULT_D:
544 Format(instr, "c.ult.d 'fs, 'ft, 'Cc");
545 break;
546 case C_OLE_D:
547 Format(instr, "c.ole.d 'fs, 'ft, 'Cc");
548 break;
549 case C_ULE_D:
550 Format(instr, "c.ule.d 'fs, 'ft, 'Cc");
551 break;
552 default:
553 Format(instr, "unknown.cop1.d");
554 break;
555 }
556 break; 837 break;
557 case S: 838 case S:
558 switch (instr->FunctionFieldRaw()) { 839 switch (instr->FunctionFieldRaw()) {
559 case CVT_D_S: 840 case CVT_D_S:
560 Format(instr, "cvt.d.s 'fd, 'fs"); 841 Format(instr, "cvt.d.s 'fd, 'fs");
561 break; 842 break;
562 default: 843 default:
563 UNIMPLEMENTED_MIPS(); 844 UNIMPLEMENTED_MIPS();
564 } 845 }
565 break; 846 break;
566 case W: 847 case W:
567 switch (instr->FunctionFieldRaw()) { 848 switch (instr->FunctionFieldRaw()) {
568 case CVT_S_W: // Convert word to float (single). 849 case CVT_S_W: // Convert word to float (single).
569 Format(instr, "cvt.s.w 'fd, 'fs"); 850 Format(instr, "cvt.s.w 'fd, 'fs");
570 break; 851 break;
571 case CVT_D_W: // Convert word to double. 852 case CVT_D_W: // Convert word to double.
572 Format(instr, "cvt.d.w 'fd, 'fs"); 853 Format(instr, "cvt.d.w 'fd, 'fs");
573 break; 854 break;
574 default: 855 default:
575 UNREACHABLE(); 856 UNREACHABLE();
576 } 857 }
577 break; 858 break;
578 case L: 859 case L:
579 switch (instr->FunctionFieldRaw()) { 860 DecodeTypeRegisterLRsType(instr);
580 case CVT_D_L:
581 Format(instr, "cvt.d.l 'fd, 'fs");
582 break;
583 case CVT_S_L:
584 Format(instr, "cvt.s.l 'fd, 'fs");
585 break;
586 case CMP_UN:
587 Format(instr, "cmp.un.d 'fd, 'fs, 'ft");
588 break;
589 case CMP_EQ:
590 Format(instr, "cmp.eq.d 'fd, 'fs, 'ft");
591 break;
592 case CMP_UEQ:
593 Format(instr, "cmp.ueq.d 'fd, 'fs, 'ft");
594 break;
595 case CMP_LT:
596 Format(instr, "cmp.lt.d 'fd, 'fs, 'ft");
597 break;
598 case CMP_ULT:
599 Format(instr, "cmp.ult.d 'fd, 'fs, 'ft");
600 break;
601 case CMP_LE:
602 Format(instr, "cmp.le.d 'fd, 'fs, 'ft");
603 break;
604 case CMP_ULE:
605 Format(instr, "cmp.ule.d 'fd, 'fs, 'ft");
606 break;
607 case CMP_OR:
608 Format(instr, "cmp.or.d 'fd, 'fs, 'ft");
609 break;
610 case CMP_UNE:
611 Format(instr, "cmp.une.d 'fd, 'fs, 'ft");
612 break;
613 case CMP_NE:
614 Format(instr, "cmp.ne.d 'fd, 'fs, 'ft");
615 break;
616 default:
617 UNREACHABLE();
618 }
619 break; 861 break;
620 case PS: 862 case PS:
621 UNIMPLEMENTED_MIPS(); 863 UNIMPLEMENTED_MIPS();
622 break; 864 break;
623 default: 865 default:
624 UNREACHABLE(); 866 UNREACHABLE();
625 } 867 }
626 break; 868 break;
627 case COP1X: 869 case COP1X:
628 switch (instr->FunctionFieldRaw()) { 870 switch (instr->FunctionFieldRaw()) {
629 case MADD_D: 871 case MADD_D:
630 Format(instr, "madd.d 'fd, 'fr, 'fs, 'ft"); 872 Format(instr, "madd.d 'fd, 'fr, 'fs, 'ft");
631 break; 873 break;
632 default: 874 default:
633 UNREACHABLE(); 875 UNREACHABLE();
634 } 876 }
635 break; 877 break;
636 case SPECIAL: 878 case SPECIAL:
637 switch (instr->FunctionFieldRaw()) { 879 DecodeTypeRegisterSPECIAL(instr);
638 case JR:
639 Format(instr, "jr 'rs");
640 break;
641 case JALR:
642 Format(instr, "jalr 'rs");
643 break;
644 case SLL:
645 if ( 0x0 == static_cast<int>(instr->InstructionBits()))
646 Format(instr, "nop");
647 else
648 Format(instr, "sll 'rd, 'rt, 'sa");
649 break;
650 case SRL:
651 if (instr->RsValue() == 0) {
652 Format(instr, "srl 'rd, 'rt, 'sa");
653 } else {
654 if (IsMipsArchVariant(kMips32r2)) {
655 Format(instr, "rotr 'rd, 'rt, 'sa");
656 } else {
657 Unknown(instr);
658 }
659 }
660 break;
661 case SRA:
662 Format(instr, "sra 'rd, 'rt, 'sa");
663 break;
664 case SLLV:
665 Format(instr, "sllv 'rd, 'rt, 'rs");
666 break;
667 case SRLV:
668 if (instr->SaValue() == 0) {
669 Format(instr, "srlv 'rd, 'rt, 'rs");
670 } else {
671 if (IsMipsArchVariant(kMips32r2)) {
672 Format(instr, "rotrv 'rd, 'rt, 'rs");
673 } else {
674 Unknown(instr);
675 }
676 }
677 break;
678 case SRAV:
679 Format(instr, "srav 'rd, 'rt, 'rs");
680 break;
681 case MFHI:
682 if (instr->Bits(25, 16) == 0) {
683 Format(instr, "mfhi 'rd");
684 } else {
685 if ((instr->FunctionFieldRaw() == CLZ_R6)
686 && (instr->FdValue() == 1)) {
687 Format(instr, "clz 'rd, 'rs");
688 } else if ((instr->FunctionFieldRaw() == CLO_R6)
689 && (instr->FdValue() == 1)) {
690 Format(instr, "clo 'rd, 'rs");
691 }
692 }
693 break;
694 case MFLO:
695 Format(instr, "mflo 'rd");
696 break;
697 case MULT: // @Mips32r6 == MUL_MUH.
698 if (!IsMipsArchVariant(kMips32r6)) {
699 Format(instr, "mult 'rs, 'rt");
700 } else {
701 if (instr->SaValue() == MUL_OP) {
702 Format(instr, "mul 'rd, 'rs, 'rt");
703 } else {
704 Format(instr, "muh 'rd, 'rs, 'rt");
705 }
706 }
707 break;
708 case MULTU: // @Mips32r6 == MUL_MUH_U.
709 if (!IsMipsArchVariant(kMips32r6)) {
710 Format(instr, "multu 'rs, 'rt");
711 } else {
712 if (instr->SaValue() == MUL_OP) {
713 Format(instr, "mulu 'rd, 'rs, 'rt");
714 } else {
715 Format(instr, "muhu 'rd, 'rs, 'rt");
716 }
717 }
718 break;
719 case DIV: // @Mips32r6 == DIV_MOD.
720 if (!IsMipsArchVariant(kMips32r6)) {
721 Format(instr, "div 'rs, 'rt");
722 } else {
723 if (instr->SaValue() == DIV_OP) {
724 Format(instr, "div 'rd, 'rs, 'rt");
725 } else {
726 Format(instr, "mod 'rd, 'rs, 'rt");
727 }
728 }
729 break;
730 case DIVU: // @Mips32r6 == DIV_MOD_U.
731 if (!IsMipsArchVariant(kMips32r6)) {
732 Format(instr, "divu 'rs, 'rt");
733 } else {
734 if (instr->SaValue() == DIV_OP) {
735 Format(instr, "divu 'rd, 'rs, 'rt");
736 } else {
737 Format(instr, "modu 'rd, 'rs, 'rt");
738 }
739 }
740 break;
741 case ADD:
742 Format(instr, "add 'rd, 'rs, 'rt");
743 break;
744 case ADDU:
745 Format(instr, "addu 'rd, 'rs, 'rt");
746 break;
747 case SUB:
748 Format(instr, "sub 'rd, 'rs, 'rt");
749 break;
750 case SUBU:
751 Format(instr, "subu 'rd, 'rs, 'rt");
752 break;
753 case AND:
754 Format(instr, "and 'rd, 'rs, 'rt");
755 break;
756 case OR:
757 if (0 == instr->RsValue()) {
758 Format(instr, "mov 'rd, 'rt");
759 } else if (0 == instr->RtValue()) {
760 Format(instr, "mov 'rd, 'rs");
761 } else {
762 Format(instr, "or 'rd, 'rs, 'rt");
763 }
764 break;
765 case XOR:
766 Format(instr, "xor 'rd, 'rs, 'rt");
767 break;
768 case NOR:
769 Format(instr, "nor 'rd, 'rs, 'rt");
770 break;
771 case SLT:
772 Format(instr, "slt 'rd, 'rs, 'rt");
773 break;
774 case SLTU:
775 Format(instr, "sltu 'rd, 'rs, 'rt");
776 break;
777 case BREAK:
778 Format(instr, "break, code: 'code");
779 break;
780 case TGE:
781 Format(instr, "tge 'rs, 'rt, code: 'code");
782 break;
783 case TGEU:
784 Format(instr, "tgeu 'rs, 'rt, code: 'code");
785 break;
786 case TLT:
787 Format(instr, "tlt 'rs, 'rt, code: 'code");
788 break;
789 case TLTU:
790 Format(instr, "tltu 'rs, 'rt, code: 'code");
791 break;
792 case TEQ:
793 Format(instr, "teq 'rs, 'rt, code: 'code");
794 break;
795 case TNE:
796 Format(instr, "tne 'rs, 'rt, code: 'code");
797 break;
798 case MOVZ:
799 Format(instr, "movz 'rd, 'rs, 'rt");
800 break;
801 case MOVN:
802 Format(instr, "movn 'rd, 'rs, 'rt");
803 break;
804 case MOVCI:
805 if (instr->Bit(16)) {
806 Format(instr, "movt 'rd, 'rs, 'bc");
807 } else {
808 Format(instr, "movf 'rd, 'rs, 'bc");
809 }
810 break;
811 case SELEQZ_S:
812 Format(instr, "seleqz 'rd, 'rs, 'rt");
813 break;
814 case SELNEZ_S:
815 Format(instr, "selnez 'rd, 'rs, 'rt");
816 break;
817 default:
818 UNREACHABLE();
819 }
820 break; 880 break;
821 case SPECIAL2: 881 case SPECIAL2:
822 switch (instr->FunctionFieldRaw()) { 882 DecodeTypeRegisterSPECIAL2(instr);
823 case MUL:
824 Format(instr, "mul 'rd, 'rs, 'rt");
825 break;
826 case CLZ:
827 if (!IsMipsArchVariant(kMips32r6)) {
828 Format(instr, "clz 'rd, 'rs");
829 }
830 break;
831 default:
832 UNREACHABLE();
833 }
834 break; 883 break;
835 case SPECIAL3: 884 case SPECIAL3:
836 switch (instr->FunctionFieldRaw()) { 885 DecodeTypeRegisterSPECIAL3(instr);
837 case INS: {
838 if (IsMipsArchVariant(kMips32r2)) {
839 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2");
840 } else {
841 Unknown(instr);
842 }
843 break;
844 }
845 case EXT: {
846 if (IsMipsArchVariant(kMips32r2)) {
847 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1");
848 } else {
849 Unknown(instr);
850 }
851 break;
852 }
853 default:
854 UNREACHABLE();
855 }
856 break; 886 break;
857 default: 887 default:
858 UNREACHABLE(); 888 UNREACHABLE();
859 } 889 }
860 } 890 }
861 891
862 892
863 void Decoder::DecodeTypeImmediate(Instruction* instr) { 893 void Decoder::DecodeTypeImmediate(Instruction* instr) {
864 switch (instr->OpcodeFieldRaw()) { 894 switch (instr->OpcodeFieldRaw()) {
865 case COP1: 895 case COP1:
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); 1380 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
1351 } 1381 }
1352 } 1382 }
1353 1383
1354 1384
1355 #undef UNSUPPORTED 1385 #undef UNSUPPORTED
1356 1386
1357 } // namespace disasm 1387 } // namespace disasm
1358 1388
1359 #endif // V8_TARGET_ARCH_MIPS 1389 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698