11#include "srxfixup_internal.h"
17static void getrs(
unsigned int data,
Operand *opr);
18static void getrt(
unsigned int data,
Operand *opr);
19static void getrd(
unsigned int data,
Operand *opr);
20static void getc0rd_iop(
unsigned int data,
Operand *opr);
21static void getc0rd_ee(
unsigned int data,
Operand *opr);
22static void getczrd(
unsigned int data,
Operand *opr);
23static void getshamt(
unsigned int data,
Operand *opr);
24static void getfs(
unsigned int data,
Operand *opr);
25static void getft(
unsigned int data,
Operand *opr);
26static void getfd(
unsigned int data,
Operand *opr);
27static void getczfs(
unsigned int data,
Operand *opr);
28static void getbroff(
unsigned int addr,
unsigned int data,
Operand *opr);
60static int regnmsw[5] = { 1, 1, 0, 1, 0 };
61static const char *
const REGNAME[2][32] =
132static const char *
const REGC0_iop[2][32] =
203static const char *
const REGC0_ee[2][32] =
274static const char *
const REGC1[2][32] =
350 const char *mnemonic;
357 unsigned int bit_mask;
361static void getrs(
unsigned int data,
Operand *opr)
363 opr->tag = OprTag_reg;
364 opr->reg = (data >> 21) & 0x1F;
367static void getrt(
unsigned int data,
Operand *opr)
369 opr->tag = OprTag_reg;
370 opr->reg = (data >> 16) & 0x1F;
373static void getrd(
unsigned int data,
Operand *opr)
375 opr->tag = OprTag_reg;
376 opr->reg = (data >> 11) & 0x1F;
379static void getc0rd_iop(
unsigned int data,
Operand *opr)
381 opr->tag = OprTag_c0reg_iop;
382 opr->reg = (data >> 11) & 0x1F;
385static void getc0rd_ee(
unsigned int data,
Operand *opr)
387 opr->tag = OprTag_c0reg_ee;
388 opr->reg = (data >> 11) & 0x1F;
391static void getczrd(
unsigned int data,
Operand *opr)
393 opr->tag = OprTag_czreg;
394 opr->reg = (data >> 11) & 0x1F;
397static void getshamt(
unsigned int data,
Operand *opr)
399 opr->tag = OprTag_shamt;
400 opr->data = (data >> 6) & 0x1F;
403static void getfs(
unsigned int data,
Operand *opr)
405 opr->tag = OprTag_c1reg;
406 opr->reg = (data >> 11) & 0x1F;
409static void getft(
unsigned int data,
Operand *opr)
411 opr->tag = OprTag_c1reg;
412 opr->reg = (data >> 16) & 0x1F;
415static void getfd(
unsigned int data,
Operand *opr)
417 opr->tag = OprTag_c1reg;
418 opr->reg = (data >> 6) & 0x1F;
421static void getczfs(
unsigned int data,
Operand *opr)
423 opr->tag = OprTag_c1reg;
424 opr->reg = (data >> 11) & 0x1F;
427static void getbroff(
unsigned int addr,
unsigned int data,
Operand *opr)
429 opr->tag = OprTag_jtarget;
430 if ( (data & 0x8000) != 0 )
432 opr->data = 4 * (uint16_t)data - 0x40000;
436 opr->data = 4 * (uint16_t)data;
438 opr->data += 4 + addr;
443 getrs(result->data, result->operands);
448 getrd(result->data, result->operands);
453 getrd(result->data, result->operands);
454 getrs(result->data, &result->operands[1]);
459 getrs(result->data, result->operands);
460 getrt(result->data, &result->operands[1]);
465 getrt(result->data, result->operands);
466 getc0rd_iop(result->data, &result->operands[1]);
471 getrt(result->data, result->operands);
472 getc0rd_ee(result->data, &result->operands[1]);
477 getrt(result->data, result->operands);
478 getczrd(result->data, &result->operands[1]);
483 getrd(result->data, result->operands);
484 getrs(result->data, &result->operands[1]);
485 getrt(result->data, &result->operands[2]);
490 getrd(result->data, result->operands);
491 getrt(result->data, &result->operands[1]);
492 getrs(result->data, &result->operands[2]);
497 getrd(result->data, result->operands);
498 getrt(result->data, &result->operands[1]);
499 getshamt(result->data, &result->operands[2]);
506 getrs(result->data, result->operands);
507 if ( (int16_t)(result->data & 0xFFFF) < 0 )
509 imm = (result->data & 0xFFFF) - 0x10000;
513 imm = (result->data & 0xFFFF);
515 result->operands[1].tag = OprTag_imm;
516 result->operands[1].data = imm;
523 getrt(result->data, result->operands);
524 getrs(result->data, &result->operands[1]);
525 if ( (int16_t)(result->data & 0xFFFF) < 0 )
527 imm = (result->data & 0xFFFF) - 0x10000;
531 imm = (result->data & 0xFFFF);
533 result->operands[2].tag = OprTag_imm;
534 result->operands[2].data = imm;
539 getrt(result->data, result->operands);
540 getrs(result->data, &result->operands[1]);
541 result->operands[2].tag = OprTag_imm;
542 result->operands[2].data = (result->data & 0xFFFF);
548 getrd(result->data, result->operands);
549 result->operands[1].tag = OprTag_imm;
550 result->operands[1].data = (result->data & 0xFFFF);
555 getrs(result->data, result->operands);
556 result->operands[1].tag = OprTag_imm;
557 result->operands[1].data = (result->data & 0xFFFF);
563 getrt(result->data, result->operands);
564 result->operands[1].tag = OprTag_imm;
565 result->operands[1].data = (result->data & 0xFFFF);
570 getrs(result->data, result->operands);
571 getrt(result->data, &result->operands[1]);
572 getbroff(result->addr, result->data, &result->operands[2]);
577 getrs(result->data, result->operands);
578 getbroff(result->addr, result->data, &result->operands[1]);
585 if ( (int16_t)(result->data & 0xFFFF) < 0 )
587 off = (result->data & 0xFFFF) - 0x10000;
591 off = (result->data & 0xFFFF);
593 getrt(result->data, result->operands);
594 result->operands[1].tag = OprTag_regoffset;
595 result->operands[1].data = off;
596 result->operands[1].reg = (result->data >> 21) & 0x1F;
601 getfd(result->data, result->operands);
602 getfs(result->data, &result->operands[1]);
607 getfs(result->data, result->operands);
608 getft(result->data, &result->operands[1]);
613 getfd(result->data, result->operands);
614 getfs(result->data, &result->operands[1]);
615 getft(result->data, &result->operands[2]);
620 getrt(result->data, result->operands);
621 getczfs(result->data, &result->operands[1]);
626 result->operands[0].tag = OprTag_code20;
627 result->operands[0].data = (result->data >> 6) & 0xFFFFF;
632 result->operands[0].tag = OprTag_jtarget;
633 result->operands[0].data = (4 * (result->data & 0x3FFFFFF)) | (result->addr & 0xF0000000);
638 result->operands[0].tag = OprTag_code25;
639 result->operands[0].data = result->data & 0x1FFFFFF;
644 result->mnemonic[0] =
'b';
645 result->mnemonic[1] =
'c';
646 result->mnemonic[2] = result->mnemonic[3];
647 if ( (result->data & 0x10000) != 0 )
649 result->mnemonic[3] =
't';
653 result->mnemonic[3] =
'f';
655 if ( (result->data & 0x20000) != 0 )
657 result->mnemonic[4] =
'l';
661 result->mnemonic[4] =
'\x00';
663 result->mnemonic[5] =
'\x00';
664 getbroff(result->addr, result->data, result->operands);
670 {
"sll", NULL, &Rdrtshamt },
671 { NULL, NULL, NULL },
672 {
"srl", NULL, &Rdrtshamt },
673 {
"sra", NULL, &Rdrtshamt },
674 {
"sllv", NULL, &Rdrtrs },
675 { NULL, NULL, NULL },
676 {
"srlv", NULL, &Rdrtrs },
677 {
"srav", NULL, &Rdrtrs },
679 {
"jalr", NULL, &Rdrs },
680 { NULL, NULL, NULL },
681 { NULL, NULL, NULL },
682 {
"syscall", NULL, &Code20 },
683 {
"break", NULL, &Code20 },
684 { NULL, NULL, NULL },
685 { NULL, NULL, NULL },
686 {
"mfhi", NULL, &Rd },
687 {
"mthi", NULL, &Rs },
688 {
"mflo", NULL, &Rd },
689 {
"mtlo", NULL, &Rs },
690 { NULL, NULL, NULL },
691 { NULL, NULL, NULL },
692 { NULL, NULL, NULL },
693 { NULL, NULL, NULL },
694 {
"mult", NULL, &Rsrt },
695 {
"multu", NULL, &Rsrt },
696 {
"div", NULL, &Rsrt },
697 {
"divu", NULL, &Rsrt },
698 { NULL, NULL, NULL },
699 { NULL, NULL, NULL },
700 { NULL, NULL, NULL },
701 { NULL, NULL, NULL },
702 {
"add", NULL, &Rdrsrt },
703 {
"addu", NULL, &Rdrsrt },
704 {
"sub", NULL, &Rdrsrt },
705 {
"subu", NULL, &Rdrsrt },
706 {
"and", NULL, &Rdrsrt },
707 {
"or", NULL, &Rdrsrt },
708 {
"xor", NULL, &Rdrsrt },
709 {
"nor", NULL, &Rdrsrt },
710 { NULL, NULL, NULL },
711 { NULL, NULL, NULL },
712 {
"slt", NULL, &Rdrsrt },
713 {
"sltu", NULL, &Rdrsrt },
714 { NULL, NULL, NULL },
715 { NULL, NULL, NULL },
716 { NULL, NULL, NULL },
717 { NULL, NULL, NULL },
718 { NULL, NULL, NULL },
719 { NULL, NULL, NULL },
720 { NULL, NULL, NULL },
721 { NULL, NULL, NULL },
722 { NULL, NULL, NULL },
723 { NULL, NULL, NULL },
724 { NULL, NULL, NULL },
725 { NULL, NULL, NULL },
726 { NULL, NULL, NULL },
727 { NULL, NULL, NULL },
728 { NULL, NULL, NULL },
729 { NULL, NULL, NULL },
730 { NULL, NULL, NULL },
731 { NULL, NULL, NULL },
732 { NULL, NULL, NULL },
735static const Opcode_table iop_SPECIAL = { 0, 63, iop_SPECIAL_entries };
738 {
"sll", NULL, &Rdrtshamt },
739 { NULL, NULL, NULL },
740 {
"srl", NULL, &Rdrtshamt },
741 {
"sra", NULL, &Rdrtshamt },
742 {
"sllv", NULL, &Rdrtrs },
743 { NULL, NULL, NULL },
744 {
"srlv", NULL, &Rdrtrs },
745 {
"srav", NULL, &Rdrtrs },
747 {
"jalr", NULL, &Rdrs },
748 {
"movz", NULL, &Rdrtrs },
749 {
"movn", NULL, &Rdrtrs },
750 {
"syscall", NULL, &Code20 },
751 {
"break", NULL, &Code20 },
752 { NULL, NULL, NULL },
753 {
"sync", NULL, NULL },
754 {
"mfhi", NULL, &Rd },
755 {
"mthi", NULL, &Rs },
756 {
"mflo", NULL, &Rd },
757 {
"mtlo", NULL, &Rs },
758 {
"dsllv", NULL, &Rdrtrs },
759 { NULL, NULL, NULL },
760 {
"dsrlv", NULL, &Rdrtrs },
761 {
"dsrav", NULL, &Rdrtrs },
762 {
"mult", NULL, &Rsrt },
763 {
"multu", NULL, &Rsrt },
764 {
"div", NULL, &Rsrt },
765 {
"divu", NULL, &Rsrt },
766 { NULL, NULL, NULL },
767 { NULL, NULL, NULL },
768 { NULL, NULL, NULL },
769 { NULL, NULL, NULL },
770 {
"add", NULL, &Rdrsrt },
771 {
"addu", NULL, &Rdrsrt },
772 {
"sub", NULL, &Rdrsrt },
773 {
"subu", NULL, &Rdrsrt },
774 {
"and", NULL, &Rdrsrt },
775 {
"or", NULL, &Rdrsrt },
776 {
"xor", NULL, &Rdrsrt },
777 {
"nor", NULL, &Rdrsrt },
778 {
"mfsa", NULL, &Rd },
779 {
"mtsa", NULL, &Rs },
780 {
"slt", NULL, &Rdrsrt },
781 {
"sltu", NULL, &Rdrsrt },
782 {
"dadd", NULL, &Rdrsrt },
783 {
"daddu", NULL, &Rdrsrt },
784 {
"dsub", NULL, &Rdrsrt },
785 {
"dsubu", NULL, &Rdrsrt },
786 {
"tge", NULL, &Rsrt },
787 {
"tgeu", NULL, &Rsrt },
788 {
"tlt", NULL, &Rsrt },
789 {
"tltu", NULL, &Rsrt },
790 {
"teq", NULL, &Rsrt },
791 { NULL, NULL, NULL },
792 {
"tne", NULL, &Rsrt },
793 { NULL, NULL, NULL },
794 {
"dsll", NULL, &Rdrtshamt },
795 { NULL, NULL, NULL },
796 {
"dsrl", NULL, &Rdrtshamt },
797 {
"dsra", NULL, &Rdrtshamt },
798 {
"dsll32", NULL, &Rdrtshamt },
799 { NULL, NULL, NULL },
800 {
"dsrl32", NULL, &Rdrtshamt },
801 {
"dsra32", NULL, &Rdrtshamt }
803static const Opcode_table ee_SPECIAL = { 0, 63, ee_SPECIAL_entries };
806 {
"bltz", NULL, &Rsbroff },
807 {
"bgez", NULL, &Rsbroff },
808 { NULL, NULL, NULL },
809 { NULL, NULL, NULL },
810 { NULL, NULL, NULL },
811 { NULL, NULL, NULL },
812 { NULL, NULL, NULL },
813 { NULL, NULL, NULL },
814 { NULL, NULL, NULL },
815 { NULL, NULL, NULL },
816 { NULL, NULL, NULL },
817 { NULL, NULL, NULL },
818 { NULL, NULL, NULL },
819 { NULL, NULL, NULL },
820 { NULL, NULL, NULL },
821 { NULL, NULL, NULL },
822 {
"bltzal", NULL, &Rsbroff },
823 {
"bgezal", NULL, &Rsbroff },
824 { NULL, NULL, NULL },
825 { NULL, NULL, NULL },
826 { NULL, NULL, NULL },
827 { NULL, NULL, NULL },
828 { NULL, NULL, NULL },
829 { NULL, NULL, NULL },
830 { NULL, NULL, NULL },
831 { NULL, NULL, NULL },
832 { NULL, NULL, NULL },
833 { NULL, NULL, NULL },
834 { NULL, NULL, NULL },
835 { NULL, NULL, NULL },
836 { NULL, NULL, NULL },
839static const Opcode_table BCOND = { 16, 31, BCOND_entries };
842 {
"bltz", NULL, &Rsbroff },
843 {
"bgez", NULL, &Rsbroff },
844 {
"bltzl", NULL, &Rsbroff },
845 {
"bgezl", NULL, &Rsbroff },
846 { NULL, NULL, NULL },
847 { NULL, NULL, NULL },
848 { NULL, NULL, NULL },
849 { NULL, NULL, NULL },
850 {
"tgei", NULL, &Rsseimm },
851 {
"tgeiu", NULL, &Rsseimm },
852 {
"tlti", NULL, &Rsseimm },
853 {
"tltiu", NULL, &Rsseimm },
854 {
"teqi", NULL, &Rsseimm },
855 { NULL, NULL, NULL },
856 {
"tnei", NULL, &Rsseimm },
857 { NULL, NULL, NULL },
858 {
"bltzal", NULL, &Rsbroff },
859 {
"bgezal", NULL, &Rsbroff },
860 {
"bltzall", NULL, &Rsbroff },
861 {
"bgezall", NULL, &Rsbroff },
862 { NULL, NULL, NULL },
863 { NULL, NULL, NULL },
864 { NULL, NULL, NULL },
865 { NULL, NULL, NULL },
866 {
"mtsab", NULL, &Rsseimm },
867 {
"mtsah", NULL, &Rsseimm },
868 { NULL, NULL, NULL },
869 { NULL, NULL, NULL },
870 { NULL, NULL, NULL },
871 { NULL, NULL, NULL },
872 { NULL, NULL, NULL },
875static const Opcode_table ee_REGIMM = { 16, 31, ee_REGIMM_entries };
878 { NULL, NULL, NULL },
879 {
"tlbr", NULL, NULL },
880 {
"tlbwi", NULL, NULL },
881 { NULL, NULL, NULL },
882 { NULL, NULL, NULL },
883 { NULL, NULL, NULL },
884 {
"tlbwr", NULL, NULL },
885 { NULL, NULL, NULL },
886 {
"tlbp", NULL, NULL },
887 { NULL, NULL, NULL },
888 { NULL, NULL, NULL },
889 { NULL, NULL, NULL },
890 { NULL, NULL, NULL },
891 { NULL, NULL, NULL },
892 { NULL, NULL, NULL },
893 { NULL, NULL, NULL },
894 {
"rfe", NULL, NULL },
895 { NULL, NULL, NULL },
896 { NULL, NULL, NULL },
897 { NULL, NULL, NULL },
898 { NULL, NULL, NULL },
899 { NULL, NULL, NULL },
900 { NULL, NULL, NULL },
901 { NULL, NULL, NULL },
902 { NULL, NULL, NULL },
903 { NULL, NULL, NULL },
904 { NULL, NULL, NULL },
905 { NULL, NULL, NULL },
906 { NULL, NULL, NULL },
907 { NULL, NULL, NULL },
908 { NULL, NULL, NULL },
909 { NULL, NULL, NULL },
910 { NULL, NULL, NULL },
911 { NULL, NULL, NULL },
912 { NULL, NULL, NULL },
913 { NULL, NULL, NULL },
914 { NULL, NULL, NULL },
915 { NULL, NULL, NULL },
916 { NULL, NULL, NULL },
917 { NULL, NULL, NULL },
918 { NULL, NULL, NULL },
919 { NULL, NULL, NULL },
920 { NULL, NULL, NULL },
921 { NULL, NULL, NULL },
922 { NULL, NULL, NULL },
923 { NULL, NULL, NULL },
924 { NULL, NULL, NULL },
925 { NULL, NULL, NULL },
926 { NULL, NULL, NULL },
927 { NULL, NULL, NULL },
928 { NULL, NULL, NULL },
929 { NULL, NULL, NULL },
930 { NULL, NULL, NULL },
931 { NULL, NULL, NULL },
932 { NULL, NULL, NULL },
933 { NULL, NULL, NULL },
934 { NULL, NULL, NULL },
935 { NULL, NULL, NULL },
936 { NULL, NULL, NULL },
937 { NULL, NULL, NULL },
938 { NULL, NULL, NULL },
939 { NULL, NULL, NULL },
940 { NULL, NULL, NULL },
943static const Opcode_table iop_COP0CO = { 0, 63, iop_COP0CO_entries };
946 { NULL, NULL, NULL },
947 {
"tlbr", NULL, NULL },
948 {
"tlbwi", NULL, NULL },
949 { NULL, NULL, NULL },
950 { NULL, NULL, NULL },
951 { NULL, NULL, NULL },
952 {
"tlbwr", NULL, NULL },
953 { NULL, NULL, NULL },
954 {
"tlbp", NULL, NULL },
955 { NULL, NULL, NULL },
956 { NULL, NULL, NULL },
957 { NULL, NULL, NULL },
958 { NULL, NULL, NULL },
959 { NULL, NULL, NULL },
960 { NULL, NULL, NULL },
961 { NULL, NULL, NULL },
962 { NULL, NULL, NULL },
963 { NULL, NULL, NULL },
964 { NULL, NULL, NULL },
965 { NULL, NULL, NULL },
966 { NULL, NULL, NULL },
967 { NULL, NULL, NULL },
968 { NULL, NULL, NULL },
969 { NULL, NULL, NULL },
970 {
"eret", NULL, NULL },
971 { NULL, NULL, NULL },
972 { NULL, NULL, NULL },
973 { NULL, NULL, NULL },
974 { NULL, NULL, NULL },
975 { NULL, NULL, NULL },
976 { NULL, NULL, NULL },
977 { NULL, NULL, NULL },
978 { NULL, NULL, NULL },
979 { NULL, NULL, NULL },
980 { NULL, NULL, NULL },
981 { NULL, NULL, NULL },
982 { NULL, NULL, NULL },
983 { NULL, NULL, NULL },
984 { NULL, NULL, NULL },
985 { NULL, NULL, NULL },
986 { NULL, NULL, NULL },
987 { NULL, NULL, NULL },
988 { NULL, NULL, NULL },
989 { NULL, NULL, NULL },
990 { NULL, NULL, NULL },
991 { NULL, NULL, NULL },
992 { NULL, NULL, NULL },
993 { NULL, NULL, NULL },
994 { NULL, NULL, NULL },
995 { NULL, NULL, NULL },
996 { NULL, NULL, NULL },
997 { NULL, NULL, NULL },
998 { NULL, NULL, NULL },
999 { NULL, NULL, NULL },
1000 { NULL, NULL, NULL },
1001 { NULL, NULL, NULL },
1002 {
"ei", NULL, NULL },
1003 {
"di", NULL, NULL },
1004 { NULL, NULL, NULL },
1005 { NULL, NULL, NULL },
1006 { NULL, NULL, NULL },
1007 { NULL, NULL, NULL },
1008 { NULL, NULL, NULL },
1009 { NULL, NULL, NULL }
1011static const Opcode_table ee_COP0CO = { 0, 63, ee_COP0CO_entries };
1014 {
"mfc0", NULL, &Rtc0rd_iop },
1015 { NULL, NULL, NULL },
1016 {
"cfc0", NULL, &Rtc0rd_iop },
1017 { NULL, NULL, NULL },
1018 {
"mtc0", NULL, &Rtc0rd_iop },
1019 { NULL, NULL, NULL },
1020 {
"ctc0", NULL, &Rtc0rd_iop },
1021 { NULL, NULL, NULL },
1022 {
"cop0", NULL, &Bcft },
1023 { NULL, NULL, NULL },
1024 { NULL, NULL, NULL },
1025 { NULL, NULL, NULL },
1026 {
"cop0", NULL, &Bcft },
1027 { NULL, NULL, NULL },
1028 { NULL, NULL, NULL },
1029 { NULL, NULL, NULL },
1030 { NULL, &iop_COP0CO, NULL },
1031 { NULL, &iop_COP0CO, NULL },
1032 { NULL, &iop_COP0CO, NULL },
1033 { NULL, &iop_COP0CO, NULL },
1034 { NULL, &iop_COP0CO, NULL },
1035 { NULL, &iop_COP0CO, NULL },
1036 { NULL, &iop_COP0CO, NULL },
1037 { NULL, &iop_COP0CO, NULL },
1038 { NULL, &iop_COP0CO, NULL },
1039 { NULL, &iop_COP0CO, NULL },
1040 { NULL, &iop_COP0CO, NULL },
1041 { NULL, &iop_COP0CO, NULL },
1042 { NULL, &iop_COP0CO, NULL },
1043 { NULL, &iop_COP0CO, NULL },
1044 { NULL, &iop_COP0CO, NULL },
1045 { NULL, &iop_COP0CO, NULL }
1047static const Opcode_table iop_COP0 = { 21, 31, iop_COP0_entries };
1050 {
"mfc0", NULL, &Rtc0rd_ee },
1051 { NULL, NULL, NULL },
1052 {
"cfc0", NULL, &Rtc0rd_ee },
1053 { NULL, NULL, NULL },
1054 {
"mtc0", NULL, &Rtc0rd_ee },
1055 { NULL, NULL, NULL },
1056 {
"ctc0", NULL, &Rtc0rd_ee },
1057 { NULL, NULL, NULL },
1058 {
"cop0", NULL, &Bcft },
1059 { NULL, NULL, NULL },
1060 { NULL, NULL, NULL },
1061 { NULL, NULL, NULL },
1062 {
"cop0", NULL, &Bcft },
1063 { NULL, NULL, NULL },
1064 { NULL, NULL, NULL },
1065 { NULL, NULL, NULL },
1066 { NULL, &ee_COP0CO, NULL },
1067 { NULL, &ee_COP0CO, NULL },
1068 { NULL, &ee_COP0CO, NULL },
1069 { NULL, &ee_COP0CO, NULL },
1070 { NULL, &ee_COP0CO, NULL },
1071 { NULL, &ee_COP0CO, NULL },
1072 { NULL, &ee_COP0CO, NULL },
1073 { NULL, &ee_COP0CO, NULL },
1074 { NULL, &ee_COP0CO, NULL },
1075 { NULL, &ee_COP0CO, NULL },
1076 { NULL, &ee_COP0CO, NULL },
1077 { NULL, &ee_COP0CO, NULL },
1078 { NULL, &ee_COP0CO, NULL },
1079 { NULL, &ee_COP0CO, NULL },
1080 { NULL, &ee_COP0CO, NULL },
1081 { NULL, &ee_COP0CO, NULL }
1083static const Opcode_table ee_COP0 = { 21, 31, ee_COP0_entries };
1086 {
"add.s", NULL, &Fdfsft },
1087 {
"sub.s", NULL, &Fdfsft },
1088 {
"mul.s", NULL, &Fdfsft },
1089 {
"div.s", NULL, &Fdfsft },
1090 {
"sqrt.s", NULL, &Fdfs },
1091 {
"abs.s", NULL, &Fdfs },
1092 {
"mov.s", NULL, &Fdfs },
1093 {
"neg.s", NULL, &Fdfs },
1094 { NULL, NULL, NULL },
1095 { NULL, NULL, NULL },
1096 { NULL, NULL, NULL },
1097 { NULL, NULL, NULL },
1098 { NULL, NULL, NULL },
1099 { NULL, NULL, NULL },
1100 { NULL, NULL, NULL },
1101 { NULL, NULL, NULL },
1102 { NULL, NULL, NULL },
1103 { NULL, NULL, NULL },
1104 { NULL, NULL, NULL },
1105 { NULL, NULL, NULL },
1106 { NULL, NULL, NULL },
1107 { NULL, NULL, NULL },
1108 {
"rsqrt.s", NULL, &Fdfs },
1109 { NULL, NULL, NULL },
1110 {
"adda.s", NULL, &Fsft },
1111 {
"suba.s", NULL, &Fsft },
1112 {
"mula.s", NULL, &Fsft },
1113 { NULL, NULL, NULL },
1114 {
"madd.s", NULL, &Fdfsft },
1115 {
"msub.s", NULL, &Fdfsft },
1116 {
"madda.s", NULL, &Fsft },
1117 {
"msuba.s", NULL, &Fsft },
1118 {
"cvt", NULL, &Fdfs },
1119 { NULL, NULL, NULL },
1120 { NULL, NULL, NULL },
1121 { NULL, NULL, NULL },
1122 {
"cvt", NULL, &Fdfs },
1123 { NULL, NULL, NULL },
1124 { NULL, NULL, NULL },
1125 { NULL, NULL, NULL },
1126 {
"max.s", NULL, &Fdfs },
1127 {
"min.s", NULL, &Fdfs },
1128 { NULL, NULL, NULL },
1129 { NULL, NULL, NULL },
1130 { NULL, NULL, NULL },
1131 { NULL, NULL, NULL },
1132 { NULL, NULL, NULL },
1133 { NULL, NULL, NULL },
1134 {
"c.f.s", NULL, &Fsft },
1135 { NULL, NULL, NULL },
1136 {
"c.eq.s", NULL, &Fsft },
1137 { NULL, NULL, NULL },
1138 {
"c.lt.s", NULL, &Fsft },
1139 { NULL, NULL, NULL },
1140 {
"c.le.s", NULL, &Fsft },
1141 { NULL, NULL, NULL },
1142 { NULL, NULL, NULL },
1143 { NULL, NULL, NULL },
1144 { NULL, NULL, NULL },
1145 { NULL, NULL, NULL },
1146 { NULL, NULL, NULL },
1147 { NULL, NULL, NULL },
1148 { NULL, NULL, NULL },
1149 { NULL, NULL, NULL }
1151static const Opcode_table ee_COP1CO = { 0, 63, ee_COP1CO_entries };
1154 {
"mfc1", NULL, &Rtczrd },
1155 { NULL, NULL, NULL },
1156 {
"cfc1", NULL, &Rtczrd },
1157 { NULL, NULL, NULL },
1158 {
"mtc1", NULL, &Rtczrd },
1159 { NULL, NULL, NULL },
1160 {
"ctc1", NULL, &Rtczrd },
1161 { NULL, NULL, NULL },
1162 {
"cop1", NULL, &Bcft },
1163 { NULL, NULL, NULL },
1164 { NULL, NULL, NULL },
1165 { NULL, NULL, NULL },
1166 {
"cop1", NULL, &Bcft },
1167 { NULL, NULL, NULL },
1168 { NULL, NULL, NULL },
1169 { NULL, NULL, NULL },
1170 {
"cop1", NULL, &Cofun },
1171 {
"cop1", NULL, &Cofun },
1172 {
"cop1", NULL, &Cofun },
1173 {
"cop1", NULL, &Cofun },
1174 {
"cop1", NULL, &Cofun },
1175 {
"cop1", NULL, &Cofun },
1176 {
"cop1", NULL, &Cofun },
1177 {
"cop1", NULL, &Cofun },
1178 {
"cop1", NULL, &Cofun },
1179 {
"cop1", NULL, &Cofun },
1180 {
"cop1", NULL, &Cofun },
1181 {
"cop1", NULL, &Cofun },
1182 {
"cop1", NULL, &Cofun },
1183 {
"cop1", NULL, &Cofun },
1184 {
"cop1", NULL, &Cofun },
1185 {
"cop1", NULL, &Cofun }
1187static const Opcode_table iop_COP1 = { 21, 31, iop_COP1_entries };
1190 {
"mfc1", NULL, &Rtczfs },
1191 { NULL, NULL, NULL },
1192 {
"cfc1", NULL, &Rtczfs },
1193 { NULL, NULL, NULL },
1194 {
"mtc1", NULL, &Rtczfs },
1195 { NULL, NULL, NULL },
1196 {
"ctc1", NULL, &Rtczfs },
1197 { NULL, NULL, NULL },
1198 {
"cop1", NULL, &Bcft },
1199 { NULL, NULL, NULL },
1200 { NULL, NULL, NULL },
1201 { NULL, NULL, NULL },
1202 {
"cop1", NULL, &Bcft },
1203 { NULL, NULL, NULL },
1204 { NULL, NULL, NULL },
1205 { NULL, NULL, NULL },
1206 { NULL, &ee_COP1CO, NULL },
1207 { NULL, &ee_COP1CO, NULL },
1208 { NULL, &ee_COP1CO, NULL },
1209 { NULL, &ee_COP1CO, NULL },
1210 { NULL, &ee_COP1CO, NULL },
1211 { NULL, &ee_COP1CO, NULL },
1212 { NULL, &ee_COP1CO, NULL },
1213 { NULL, &ee_COP1CO, NULL },
1214 { NULL, &ee_COP1CO, NULL },
1215 { NULL, &ee_COP1CO, NULL },
1216 { NULL, &ee_COP1CO, NULL },
1217 { NULL, &ee_COP1CO, NULL },
1218 { NULL, &ee_COP1CO, NULL },
1219 { NULL, &ee_COP1CO, NULL },
1220 { NULL, &ee_COP1CO, NULL },
1221 { NULL, &ee_COP1CO, NULL }
1223static const Opcode_table ee_COP1 = { 21, 31, ee_COP1_entries };
1226 {
"mfc2", NULL, &Rtczrd },
1227 { NULL, NULL, NULL },
1228 {
"cfc2", NULL, &Rtczrd },
1229 { NULL, NULL, NULL },
1230 {
"mtc2", NULL, &Rtczrd },
1231 { NULL, NULL, NULL },
1232 {
"ctc2", NULL, &Rtczrd },
1233 { NULL, NULL, NULL },
1234 {
"cop2", NULL, &Bcft },
1235 { NULL, NULL, NULL },
1236 { NULL, NULL, NULL },
1237 { NULL, NULL, NULL },
1238 {
"cop2", NULL, &Bcft },
1239 { NULL, NULL, NULL },
1240 { NULL, NULL, NULL },
1241 { NULL, NULL, NULL },
1242 {
"cop2", NULL, &Cofun },
1243 {
"cop2", NULL, &Cofun },
1244 {
"cop2", NULL, &Cofun },
1245 {
"cop2", NULL, &Cofun },
1246 {
"cop2", NULL, &Cofun },
1247 {
"cop2", NULL, &Cofun },
1248 {
"cop2", NULL, &Cofun },
1249 {
"cop2", NULL, &Cofun },
1250 {
"cop2", NULL, &Cofun },
1251 {
"cop2", NULL, &Cofun },
1252 {
"cop2", NULL, &Cofun },
1253 {
"cop2", NULL, &Cofun },
1254 {
"cop2", NULL, &Cofun },
1255 {
"cop2", NULL, &Cofun },
1256 {
"cop2", NULL, &Cofun },
1257 {
"cop2", NULL, &Cofun }
1259static const Opcode_table iop_COP2 = { 21, 31, iop_COP2_entries };
1262 {
"mfc2", NULL, &Rtczrd },
1263 {
"qmfc2", NULL, &Rtczrd },
1264 {
"cfc2", NULL, &Rtczrd },
1265 { NULL, NULL, NULL },
1266 {
"mtc2", NULL, &Rtczrd },
1267 {
"qmtc2", NULL, &Rtczrd },
1268 {
"ctc2", NULL, &Rtczrd },
1269 { NULL, NULL, NULL },
1270 {
"cop2", NULL, &Bcft },
1271 { NULL, NULL, NULL },
1272 { NULL, NULL, NULL },
1273 { NULL, NULL, NULL },
1274 {
"cop2", NULL, &Bcft },
1275 { NULL, NULL, NULL },
1276 { NULL, NULL, NULL },
1277 { NULL, NULL, NULL },
1278 {
"cop2", NULL, &Cofun },
1279 {
"cop2", NULL, &Cofun },
1280 {
"cop2", NULL, &Cofun },
1281 {
"cop2", NULL, &Cofun },
1282 {
"cop2", NULL, &Cofun },
1283 {
"cop2", NULL, &Cofun },
1284 {
"cop2", NULL, &Cofun },
1285 {
"cop2", NULL, &Cofun },
1286 {
"cop2", NULL, &Cofun },
1287 {
"cop2", NULL, &Cofun },
1288 {
"cop2", NULL, &Cofun },
1289 {
"cop2", NULL, &Cofun },
1290 {
"cop2", NULL, &Cofun },
1291 {
"cop2", NULL, &Cofun },
1292 {
"cop2", NULL, &Cofun },
1293 {
"cop2", NULL, &Cofun }
1295static const Opcode_table ee_COP2 = { 21, 31, ee_COP2_entries };
1298 {
"mfc3", NULL, &Rtczrd },
1299 { NULL, NULL, NULL },
1300 {
"cfc3", NULL, &Rtczrd },
1301 { NULL, NULL, NULL },
1302 {
"mtc3", NULL, &Rtczrd },
1303 { NULL, NULL, NULL },
1304 {
"ctc3", NULL, &Rtczrd },
1305 { NULL, NULL, NULL },
1306 {
"cop3", NULL, &Bcft },
1307 { NULL, NULL, NULL },
1308 { NULL, NULL, NULL },
1309 { NULL, NULL, NULL },
1310 {
"cop3", NULL, &Bcft },
1311 { NULL, NULL, NULL },
1312 { NULL, NULL, NULL },
1313 { NULL, NULL, NULL },
1314 {
"cop3", NULL, &Cofun },
1315 {
"cop3", NULL, &Cofun },
1316 {
"cop3", NULL, &Cofun },
1317 {
"cop3", NULL, &Cofun },
1318 {
"cop3", NULL, &Cofun },
1319 {
"cop3", NULL, &Cofun },
1320 {
"cop3", NULL, &Cofun },
1321 {
"cop3", NULL, &Cofun },
1322 {
"cop3", NULL, &Cofun },
1323 {
"cop3", NULL, &Cofun },
1324 {
"cop3", NULL, &Cofun },
1325 {
"cop3", NULL, &Cofun },
1326 {
"cop3", NULL, &Cofun },
1327 {
"cop3", NULL, &Cofun },
1328 {
"cop3", NULL, &Cofun },
1329 {
"cop3", NULL, &Cofun }
1331static const Opcode_table COP3 = { 21, 31, COP3_entries };
1334 { NULL, &iop_SPECIAL, NULL },
1335 { NULL, &BCOND, NULL },
1336 {
"j", NULL, &Jtarget },
1337 {
"jal", NULL, &Jtarget },
1338 {
"beq", NULL, &Rsrtbroff },
1339 {
"bne", NULL, &Rsrtbroff },
1340 {
"blez", NULL, &Rsbroff },
1341 {
"bgtz", NULL, &Rsbroff },
1342 {
"addi", NULL, &Rtrsseimm },
1343 {
"addiu", NULL, &Rtrsseimm },
1344 {
"slti", NULL, &Rtrsseimm },
1345 {
"sltiu", NULL, &Rtrsseimm },
1346 {
"andi", NULL, &Rtrsimm },
1347 {
"ori", NULL, &Rtrsimm },
1348 {
"xori", NULL, &Rtrsimm },
1349 {
"lui", NULL, &Rtimm },
1350 { NULL, &iop_COP0, NULL },
1351 { NULL, &iop_COP1, NULL },
1352 { NULL, &iop_COP2, NULL },
1353 { NULL, &COP3, NULL },
1354 { NULL, NULL, NULL },
1355 { NULL, NULL, NULL },
1356 { NULL, NULL, NULL },
1357 { NULL, NULL, NULL },
1358 { NULL, NULL, NULL },
1359 { NULL, NULL, NULL },
1360 { NULL, NULL, NULL },
1361 { NULL, NULL, NULL },
1362 { NULL, NULL, NULL },
1363 { NULL, NULL, NULL },
1364 { NULL, NULL, NULL },
1365 { NULL, NULL, NULL },
1366 {
"lb", NULL, &Rtoffbase },
1367 {
"lh", NULL, &Rtoffbase },
1368 {
"lwl", NULL, &Rtoffbase },
1369 {
"lw", NULL, &Rtoffbase },
1370 {
"lbu", NULL, &Rtoffbase },
1371 {
"lhu", NULL, &Rtoffbase },
1372 {
"lwr", NULL, &Rtoffbase },
1373 { NULL, NULL, NULL },
1374 {
"sb", NULL, &Rtoffbase },
1375 {
"sh", NULL, &Rtoffbase },
1376 {
"swl", NULL, &Rtoffbase },
1377 {
"sw", NULL, &Rtoffbase },
1378 { NULL, NULL, NULL },
1379 { NULL, NULL, NULL },
1380 {
"swr", NULL, &Rtoffbase },
1381 { NULL, NULL, NULL },
1382 {
"lwc0", NULL, &Rtoffbase },
1383 {
"lwc1", NULL, &Rtoffbase },
1384 {
"lwc2", NULL, &Rtoffbase },
1385 {
"lwc3", NULL, &Rtoffbase },
1386 { NULL, NULL, NULL },
1387 { NULL, NULL, NULL },
1388 { NULL, NULL, NULL },
1389 { NULL, NULL, NULL },
1390 {
"swc0", NULL, &Rtoffbase },
1391 {
"swc1", NULL, &Rtoffbase },
1392 {
"swc2", NULL, &Rtoffbase },
1393 {
"swc3", NULL, &Rtoffbase },
1394 { NULL, NULL, NULL },
1395 { NULL, NULL, NULL },
1396 { NULL, NULL, NULL },
1397 { NULL, NULL, NULL }
1401 { NULL, &ee_SPECIAL, NULL },
1402 { NULL, &ee_REGIMM, NULL },
1403 {
"j", NULL, &Jtarget },
1404 {
"jal", NULL, &Jtarget },
1405 {
"beq", NULL, &Rsrtbroff },
1406 {
"bne", NULL, &Rsrtbroff },
1407 {
"blez", NULL, &Rsbroff },
1408 {
"bgtz", NULL, &Rsbroff },
1409 {
"addi", NULL, &Rtrsseimm },
1410 {
"addiu", NULL, &Rtrsseimm },
1411 {
"slti", NULL, &Rtrsseimm },
1412 {
"sltiu", NULL, &Rtrsseimm },
1413 {
"andi", NULL, &Rtrsimm },
1414 {
"ori", NULL, &Rtrsimm },
1415 {
"xori", NULL, &Rtrsimm },
1416 {
"lui", NULL, &Rtimm },
1417 { NULL, &ee_COP0, NULL },
1418 { NULL, &ee_COP1, NULL },
1419 { NULL, &ee_COP2, NULL },
1420 { NULL, &COP3, NULL },
1421 {
"beql", NULL, &Rsrtbroff },
1422 {
"bnel", NULL, &Rsrtbroff },
1423 {
"blezl", NULL, &Rsbroff },
1424 {
"bgtzl", NULL, &Rsbroff },
1425 {
"daddi", NULL, &Rtrsseimm },
1426 {
"daddiu", NULL, &Rtrsseimm },
1427 {
"ldl", NULL, &Rtoffbase },
1428 {
"ldr", NULL, &Rtoffbase },
1429 {
"mmi", NULL, NULL },
1430 { NULL, NULL, NULL },
1431 {
"lq", NULL, &Rtoffbase },
1432 {
"sq", NULL, &Rtoffbase },
1433 {
"lb", NULL, &Rtoffbase },
1434 {
"lh", NULL, &Rtoffbase },
1435 {
"lwl", NULL, &Rtoffbase },
1436 {
"lw", NULL, &Rtoffbase },
1437 {
"lbu", NULL, &Rtoffbase },
1438 {
"lhu", NULL, &Rtoffbase },
1439 {
"lwr", NULL, &Rtoffbase },
1440 { NULL, NULL, NULL },
1441 {
"sb", NULL, &Rtoffbase },
1442 {
"sh", NULL, &Rtoffbase },
1443 {
"swl", NULL, &Rtoffbase },
1444 {
"sw", NULL, &Rtoffbase },
1445 {
"sdl", NULL, &Rtoffbase },
1446 {
"sdr", NULL, &Rtoffbase },
1447 {
"swr", NULL, &Rtoffbase },
1448 {
"cache", NULL, NULL },
1449 {
"lwc0", NULL, &Rtoffbase },
1450 {
"lwc1", NULL, &Rtoffbase },
1451 {
"lwc2", NULL, &Rtoffbase },
1452 {
"pref", NULL, &Rtoffbase },
1453 { NULL, NULL, NULL },
1454 { NULL, NULL, NULL },
1455 {
"lqc2", NULL, &Rtoffbase },
1456 {
"ld", NULL, &Rtoffbase },
1457 {
"swc0", NULL, &Rtoffbase },
1458 {
"swc1", NULL, &Rtoffbase },
1459 {
"swc2", NULL, &Rtoffbase },
1460 {
"swc3", NULL, &Rtoffbase },
1461 { NULL, NULL, NULL },
1462 { NULL, NULL, NULL },
1463 {
"sqc2", NULL, &Rtoffbase },
1464 {
"sd", NULL, &Rtoffbase }
1466static const Opcode_table iop_opcode_root_table = { 26, 63, iop_opcode_root_table_entries };
1467static const Opcode_table ee_opcode_root_table = { 26, 63, ee_opcode_root_table_entries };
1468static const Opcode_table * opcode_root_table = &iop_opcode_root_table;
1476 !strcmp(
"beq", result->mnemonic) && result->operands[0].tag == OprTag_reg && result->operands[1].tag == OprTag_reg
1477 && result->operands[1].reg == result->operands[0].reg )
1479 strcpy(result->mnemonic,
"b");
1480 result->operands[0] = result->operands[2];
1481 result->operands[1].tag = OprTag_none;
1483 else if ( !strcmp(
"bgezal", result->mnemonic) && result->operands[0].tag == OprTag_reg && !result->operands[0].reg )
1485 strcpy(result->mnemonic,
"bal");
1486 result->operands[0] = result->operands[1];
1487 result->operands[1].tag = OprTag_none;
1489 else if ( !strcmp(
"cvt", result->mnemonic) )
1491 if ( ((result->data >> 21) & 0x1F) == 20 )
1493 strcpy(result->mnemonic,
"cvt.s.w");
1495 else if ( ((result->data >> 21) & 0x1F) == 16 )
1497 strcpy(result->mnemonic,
"cvt.w.s");
1503 strcpy(result->mnemonic,
"nop");
1504 result->operands[0].tag = OprTag_none;
1508void initdisasm(
int arch,
int regform0,
int regform1,
int regform2,
int regform3)
1513 opcode_root_table = &iop_opcode_root_table;
1516 opcode_root_table = &ee_opcode_root_table;
1521 if ( regform0 != -1 )
1523 if ( !regform0 || regform0 == 1 )
1525 regnmsw[0] = regform0;
1527 if ( !regform1 || regform1 == 1 )
1529 regnmsw[1] = regform0;
1531 if ( !regform2 || regform2 == 1 )
1533 regnmsw[2] = regform0;
1535 if ( !regform3 || regform3 == 1 )
1537 regnmsw[3] = regform3;
1542Disasm_result *disassemble(
unsigned int addr,
unsigned int data)
1548 optable = opcode_root_table;
1552 op = &optable->entries[(data >> optable->bit_pos) & optable->bit_mask];
1553 if ( !op->subtable )
1557 optable = op->subtable;
1563 strcpy(v3->mnemonic, op->mnemonic);
1572void shex(
char *buf,
unsigned int data)
1574 if ( (data & 0x80000000) != 0 )
1576 sprintf(buf,
"-0x%x", -data);
1580 sprintf(buf,
"0x%x", data);
1584void format_operand(
const Operand *opr,
char *buf)
1589 strcpy(buf, REGNAME[regnmsw[0]][opr->reg]);
1591 case OprTag_c0reg_iop:
1592 strcpy(buf, REGC0_iop[regnmsw[0]][opr->reg]);
1594 case OprTag_c0reg_ee:
1595 strcpy(buf, REGC0_ee[regnmsw[0]][opr->reg]);
1598 sprintf(buf,
"$%d", opr->reg);
1601 strcpy(buf, REGC1[regnmsw[1]][opr->reg]);
1604 case OprTag_jtarget:
1605 shex(buf, opr->data);
1608 sprintf(buf,
"%d", (
int)(opr->data));
1610 case OprTag_regoffset:
1611 shex(buf, opr->data);
1612 sprintf(&buf[strlen(buf)],
"(%s)", REGNAME[regnmsw[0]][opr->reg]);
1616 sprintf(buf,
"0x%x", opr->data);
1619 sprintf(buf,
"?type?(0x%x)", opr->tag);
1620 fprintf(stderr,
"Panic unknown oprand type 0x%x\n", opr->tag);
1629 sprintf(buf,
"%08x: %08x", dis->addr, dis->data);
1630 s = &buf[strlen(buf)];
1631 if ( dis->mnemonic[0] )
1636 sprintf(s,
" %-8s", dis->mnemonic);
1638 for ( i = 0; dis->operands[i].tag; i += 1 )
1640 format_operand(&dis->operands[i], sa);
1641 if ( dis->operands[i + 1].tag )