Revision e80cfcfc target-sparc/translate.c
b/target-sparc/translate.c | ||
---|---|---|
646 | 646 |
switch (xop) { |
647 | 647 |
case 0x0: |
648 | 648 |
case 0x1: /* UNIMPL */ |
649 |
case 0x5: /*CBN+x */ |
|
649 | 650 |
default: |
650 | 651 |
goto illegal_insn; |
651 | 652 |
case 0x2: /* BN+x */ |
... | ... | |
657 | 658 |
} |
658 | 659 |
case 0x6: /* FBN+x */ |
659 | 660 |
{ |
661 |
#if !defined(CONFIG_USER_ONLY) |
|
662 |
gen_op_trap_ifnofpu(); |
|
663 |
#endif |
|
660 | 664 |
target <<= 2; |
661 | 665 |
target = sign_extend(target, 22); |
662 | 666 |
do_fbranch(dc, target, insn); |
663 | 667 |
goto jmp_insn; |
664 | 668 |
} |
665 | 669 |
case 0x4: /* SETHI */ |
666 |
gen_movl_imm_T0(target << 10); |
|
667 |
gen_movl_T0_reg(rd); |
|
668 |
break; |
|
669 |
case 0x5: /*CBN+x */ |
|
670 |
#define OPTIM |
|
671 |
#if defined(OPTIM) |
|
672 |
if (rd) { // nop |
|
673 |
#endif |
|
674 |
gen_movl_imm_T0(target << 10); |
|
675 |
gen_movl_T0_reg(rd); |
|
676 |
#if defined(OPTIM) |
|
677 |
} |
|
678 |
#endif |
|
670 | 679 |
break; |
671 | 680 |
} |
672 | 681 |
break; |
... | ... | |
691 | 700 |
gen_movl_reg_T0(rs1); |
692 | 701 |
if (IS_IMM) { |
693 | 702 |
rs2 = GET_FIELD(insn, 25, 31); |
703 |
#if defined(OPTIM) |
|
694 | 704 |
if (rs2 != 0) { |
695 |
gen_movl_imm_T1(rs2); |
|
696 |
gen_op_add_T1_T0(); |
|
705 |
#endif |
|
706 |
gen_movl_imm_T1(rs2); |
|
707 |
gen_op_add_T1_T0(); |
|
708 |
#if defined(OPTIM) |
|
697 | 709 |
} |
710 |
#endif |
|
698 | 711 |
} else { |
699 | 712 |
rs2 = GET_FIELD(insn, 27, 31); |
700 |
gen_movl_reg_T1(rs2); |
|
701 |
gen_op_add_T1_T0(); |
|
713 |
#if defined(OPTIM) |
|
714 |
if (rs2 != 0) { |
|
715 |
#endif |
|
716 |
gen_movl_reg_T1(rs2); |
|
717 |
gen_op_add_T1_T0(); |
|
718 |
#if defined(OPTIM) |
|
719 |
} |
|
720 |
#endif |
|
702 | 721 |
} |
703 | 722 |
save_state(dc); |
704 | 723 |
cond = GET_FIELD(insn, 3, 6); |
... | ... | |
707 | 726 |
dc->is_br = 1; |
708 | 727 |
goto jmp_insn; |
709 | 728 |
} else { |
729 |
gen_cond(cond); |
|
710 | 730 |
gen_op_trapcc_T0(); |
711 | 731 |
} |
712 | 732 |
} else if (xop == 0x28) { |
... | ... | |
741 | 761 |
gen_movl_T0_reg(rd); |
742 | 762 |
break; |
743 | 763 |
#endif |
744 |
} else if (xop == 0x34 || xop == 0x35) { /* FPU Operations */ |
|
764 |
} else if (xop == 0x34) { /* FPU Operations */ |
|
765 |
#if !defined(CONFIG_USER_ONLY) |
|
766 |
gen_op_trap_ifnofpu(); |
|
767 |
#endif |
|
745 | 768 |
rs1 = GET_FIELD(insn, 13, 17); |
746 | 769 |
rs2 = GET_FIELD(insn, 27, 31); |
747 | 770 |
xop = GET_FIELD(insn, 18, 26); |
... | ... | |
770 | 793 |
gen_op_fsqrtd(); |
771 | 794 |
gen_op_store_DT0_fpr(rd); |
772 | 795 |
break; |
796 |
case 0x2b: /* fsqrtq */ |
|
797 |
goto nfpu_insn; |
|
773 | 798 |
case 0x41: |
774 | 799 |
gen_op_load_fpr_FT0(rs1); |
775 | 800 |
gen_op_load_fpr_FT1(rs2); |
... | ... | |
782 | 807 |
gen_op_faddd(); |
783 | 808 |
gen_op_store_DT0_fpr(rd); |
784 | 809 |
break; |
810 |
case 0x43: /* faddq */ |
|
811 |
goto nfpu_insn; |
|
785 | 812 |
case 0x45: |
786 | 813 |
gen_op_load_fpr_FT0(rs1); |
787 | 814 |
gen_op_load_fpr_FT1(rs2); |
... | ... | |
794 | 821 |
gen_op_fsubd(); |
795 | 822 |
gen_op_store_DT0_fpr(rd); |
796 | 823 |
break; |
824 |
case 0x47: /* fsubq */ |
|
825 |
goto nfpu_insn; |
|
797 | 826 |
case 0x49: |
798 | 827 |
gen_op_load_fpr_FT0(rs1); |
799 | 828 |
gen_op_load_fpr_FT1(rs2); |
... | ... | |
806 | 835 |
gen_op_fmuld(); |
807 | 836 |
gen_op_store_DT0_fpr(rd); |
808 | 837 |
break; |
838 |
case 0x4b: /* fmulq */ |
|
839 |
goto nfpu_insn; |
|
809 | 840 |
case 0x4d: |
810 | 841 |
gen_op_load_fpr_FT0(rs1); |
811 | 842 |
gen_op_load_fpr_FT1(rs2); |
... | ... | |
818 | 849 |
gen_op_fdivd(); |
819 | 850 |
gen_op_store_DT0_fpr(rd); |
820 | 851 |
break; |
821 |
case 0x51: |
|
822 |
gen_op_load_fpr_FT0(rs1); |
|
823 |
gen_op_load_fpr_FT1(rs2); |
|
824 |
gen_op_fcmps(); |
|
825 |
break; |
|
826 |
case 0x52: |
|
827 |
gen_op_load_fpr_DT0(rs1); |
|
828 |
gen_op_load_fpr_DT1(rs2); |
|
829 |
gen_op_fcmpd(); |
|
830 |
break; |
|
831 |
case 0x55: /* fcmpes */ |
|
832 |
gen_op_load_fpr_FT0(rs1); |
|
833 |
gen_op_load_fpr_FT1(rs2); |
|
834 |
gen_op_fcmps(); /* XXX */ |
|
835 |
break; |
|
836 |
case 0x56: /* fcmped */ |
|
837 |
gen_op_load_fpr_DT0(rs1); |
|
838 |
gen_op_load_fpr_DT1(rs2); |
|
839 |
gen_op_fcmpd(); /* XXX */ |
|
840 |
break; |
|
852 |
case 0x4f: /* fdivq */ |
|
853 |
goto nfpu_insn; |
|
841 | 854 |
case 0x69: |
842 | 855 |
gen_op_load_fpr_FT0(rs1); |
843 | 856 |
gen_op_load_fpr_FT1(rs2); |
844 | 857 |
gen_op_fsmuld(); |
845 | 858 |
gen_op_store_DT0_fpr(rd); |
846 | 859 |
break; |
860 |
case 0x6e: /* fdmulq */ |
|
861 |
goto nfpu_insn; |
|
847 | 862 |
case 0xc4: |
848 | 863 |
gen_op_load_fpr_FT1(rs2); |
849 | 864 |
gen_op_fitos(); |
... | ... | |
854 | 869 |
gen_op_fdtos(); |
855 | 870 |
gen_op_store_FT0_fpr(rd); |
856 | 871 |
break; |
872 |
case 0xc7: /* fqtos */ |
|
873 |
goto nfpu_insn; |
|
857 | 874 |
case 0xc8: |
858 | 875 |
gen_op_load_fpr_FT1(rs2); |
859 | 876 |
gen_op_fitod(); |
... | ... | |
864 | 881 |
gen_op_fstod(); |
865 | 882 |
gen_op_store_DT0_fpr(rd); |
866 | 883 |
break; |
884 |
case 0xcb: /* fqtod */ |
|
885 |
goto nfpu_insn; |
|
886 |
case 0xcc: /* fitoq */ |
|
887 |
goto nfpu_insn; |
|
888 |
case 0xcd: /* fstoq */ |
|
889 |
goto nfpu_insn; |
|
890 |
case 0xce: /* fdtoq */ |
|
891 |
goto nfpu_insn; |
|
867 | 892 |
case 0xd1: |
868 | 893 |
gen_op_load_fpr_FT1(rs2); |
869 | 894 |
gen_op_fstoi(); |
... | ... | |
874 | 899 |
gen_op_fdtoi(); |
875 | 900 |
gen_op_store_FT0_fpr(rd); |
876 | 901 |
break; |
902 |
case 0xd3: /* fqtoi */ |
|
903 |
goto nfpu_insn; |
|
877 | 904 |
default: |
878 | 905 |
goto illegal_insn; |
879 | 906 |
} |
880 |
} else { |
|
907 |
} else if (xop == 0x35) { /* FPU Operations */ |
|
908 |
#if !defined(CONFIG_USER_ONLY) |
|
909 |
gen_op_trap_ifnofpu(); |
|
910 |
#endif |
|
881 | 911 |
rs1 = GET_FIELD(insn, 13, 17); |
882 |
gen_movl_reg_T0(rs1); |
|
883 |
if (IS_IMM) { /* immediate */ |
|
912 |
rs2 = GET_FIELD(insn, 27, 31); |
|
913 |
xop = GET_FIELD(insn, 18, 26); |
|
914 |
switch (xop) { |
|
915 |
case 0x51: |
|
916 |
gen_op_load_fpr_FT0(rs1); |
|
917 |
gen_op_load_fpr_FT1(rs2); |
|
918 |
gen_op_fcmps(); |
|
919 |
break; |
|
920 |
case 0x52: |
|
921 |
gen_op_load_fpr_DT0(rs1); |
|
922 |
gen_op_load_fpr_DT1(rs2); |
|
923 |
gen_op_fcmpd(); |
|
924 |
break; |
|
925 |
case 0x53: /* fcmpq */ |
|
926 |
goto nfpu_insn; |
|
927 |
case 0x55: /* fcmpes */ |
|
928 |
gen_op_load_fpr_FT0(rs1); |
|
929 |
gen_op_load_fpr_FT1(rs2); |
|
930 |
gen_op_fcmps(); /* XXX should trap if qNaN or sNaN */ |
|
931 |
break; |
|
932 |
case 0x56: /* fcmped */ |
|
933 |
gen_op_load_fpr_DT0(rs1); |
|
934 |
gen_op_load_fpr_DT1(rs2); |
|
935 |
gen_op_fcmpd(); /* XXX should trap if qNaN or sNaN */ |
|
936 |
break; |
|
937 |
case 0x57: /* fcmpeq */ |
|
938 |
goto nfpu_insn; |
|
939 |
default: |
|
940 |
goto illegal_insn; |
|
941 |
} |
|
942 |
#if defined(OPTIM) |
|
943 |
} else if (xop == 0x2) { |
|
944 |
// clr/mov shortcut |
|
945 |
|
|
946 |
rs1 = GET_FIELD(insn, 13, 17); |
|
947 |
if (rs1 == 0) { |
|
948 |
// or %g0, x, y -> mov T1, x; mov y, T1 |
|
949 |
if (IS_IMM) { /* immediate */ |
|
950 |
rs2 = GET_FIELDs(insn, 19, 31); |
|
951 |
gen_movl_imm_T1(rs2); |
|
952 |
} else { /* register */ |
|
953 |
rs2 = GET_FIELD(insn, 27, 31); |
|
954 |
gen_movl_reg_T1(rs2); |
|
955 |
} |
|
956 |
gen_movl_T1_reg(rd); |
|
957 |
} else { |
|
958 |
gen_movl_reg_T0(rs1); |
|
959 |
if (IS_IMM) { /* immediate */ |
|
960 |
// or x, #0, y -> mov T1, x; mov y, T1 |
|
961 |
rs2 = GET_FIELDs(insn, 19, 31); |
|
962 |
if (rs2 != 0) { |
|
963 |
gen_movl_imm_T1(rs2); |
|
964 |
gen_op_or_T1_T0(); |
|
965 |
} |
|
966 |
} else { /* register */ |
|
967 |
// or x, %g0, y -> mov T1, x; mov y, T1 |
|
968 |
rs2 = GET_FIELD(insn, 27, 31); |
|
969 |
if (rs2 != 0) { |
|
970 |
gen_movl_reg_T1(rs2); |
|
971 |
gen_op_or_T1_T0(); |
|
972 |
} |
|
973 |
} |
|
974 |
gen_movl_T0_reg(rd); |
|
975 |
} |
|
976 |
#endif |
|
977 |
} else if (xop < 0x38) { |
|
978 |
rs1 = GET_FIELD(insn, 13, 17); |
|
979 |
gen_movl_reg_T0(rs1); |
|
980 |
if (IS_IMM) { /* immediate */ |
|
884 | 981 |
rs2 = GET_FIELDs(insn, 19, 31); |
885 | 982 |
gen_movl_imm_T1(rs2); |
886 | 983 |
} else { /* register */ |
... | ... | |
901 | 998 |
gen_op_logic_T0_cc(); |
902 | 999 |
break; |
903 | 1000 |
case 0x2: |
904 |
gen_op_or_T1_T0();
|
|
905 |
if (xop & 0x10)
|
|
906 |
gen_op_logic_T0_cc();
|
|
907 |
break;
|
|
1001 |
gen_op_or_T1_T0();
|
|
1002 |
if (xop & 0x10)
|
|
1003 |
gen_op_logic_T0_cc();
|
|
1004 |
break;
|
|
908 | 1005 |
case 0x3: |
909 | 1006 |
gen_op_xor_T1_T0(); |
910 | 1007 |
if (xop & 0x10) |
... | ... | |
964 | 1061 |
default: |
965 | 1062 |
goto illegal_insn; |
966 | 1063 |
} |
967 |
gen_movl_T0_reg(rd);
|
|
1064 |
gen_movl_T0_reg(rd);
|
|
968 | 1065 |
} else { |
969 | 1066 |
switch (xop) { |
1067 |
case 0x20: /* taddcc */ |
|
1068 |
case 0x21: /* tsubcc */ |
|
1069 |
case 0x22: /* taddcctv */ |
|
1070 |
case 0x23: /* tsubcctv */ |
|
1071 |
goto illegal_insn; |
|
970 | 1072 |
case 0x24: /* mulscc */ |
971 | 1073 |
gen_op_mulscc_T1_T0(); |
972 | 1074 |
gen_movl_T0_reg(rd); |
... | ... | |
1021 | 1123 |
} |
1022 | 1124 |
break; |
1023 | 1125 |
#endif |
1024 |
case 0x38: /* jmpl */ |
|
1025 |
{ |
|
1026 |
gen_op_add_T1_T0(); |
|
1027 |
gen_op_movl_npc_T0(); |
|
1028 |
if (rd != 0) { |
|
1029 |
gen_op_movl_T0_im((long) (dc->pc)); |
|
1030 |
gen_movl_T0_reg(rd); |
|
1031 |
} |
|
1032 |
dc->pc = dc->npc; |
|
1033 |
dc->npc = DYNAMIC_PC; |
|
1034 |
} |
|
1035 |
goto jmp_insn; |
|
1036 |
#if !defined(CONFIG_USER_ONLY) |
|
1037 |
case 0x39: /* rett */ |
|
1038 |
{ |
|
1039 |
if (!supervisor(dc)) |
|
1040 |
goto priv_insn; |
|
1041 |
gen_op_add_T1_T0(); |
|
1042 |
gen_op_movl_npc_T0(); |
|
1043 |
gen_op_rett(); |
|
1044 |
#if 0 |
|
1045 |
dc->pc = dc->npc; |
|
1046 |
dc->npc = DYNAMIC_PC; |
|
1126 |
default: |
|
1127 |
goto illegal_insn; |
|
1128 |
} |
|
1129 |
} |
|
1130 |
} else { |
|
1131 |
rs1 = GET_FIELD(insn, 13, 17); |
|
1132 |
gen_movl_reg_T0(rs1); |
|
1133 |
if (IS_IMM) { /* immediate */ |
|
1134 |
rs2 = GET_FIELDs(insn, 19, 31); |
|
1135 |
#if defined(OPTIM) |
|
1136 |
if (rs2) { |
|
1047 | 1137 |
#endif |
1048 |
} |
|
1049 |
#if 0 |
|
1050 |
goto jmp_insn; |
|
1138 |
gen_movl_imm_T1(rs2); |
|
1139 |
gen_op_add_T1_T0(); |
|
1140 |
#if defined(OPTIM) |
|
1141 |
} |
|
1051 | 1142 |
#endif |
1052 |
break; |
|
1143 |
} else { /* register */ |
|
1144 |
rs2 = GET_FIELD(insn, 27, 31); |
|
1145 |
#if defined(OPTIM) |
|
1146 |
if (rs2) { |
|
1147 |
#endif |
|
1148 |
gen_movl_reg_T1(rs2); |
|
1149 |
gen_op_add_T1_T0(); |
|
1150 |
#if defined(OPTIM) |
|
1151 |
} |
|
1053 | 1152 |
#endif |
1054 |
case 0x3b: /* flush */ |
|
1055 |
gen_op_add_T1_T0(); |
|
1056 |
gen_op_flush_T0(); |
|
1057 |
break; |
|
1058 |
case 0x3c: /* save */ |
|
1059 |
save_state(dc); |
|
1060 |
gen_op_add_T1_T0(); |
|
1061 |
gen_op_save(); |
|
1062 |
gen_movl_T0_reg(rd); |
|
1063 |
break; |
|
1064 |
case 0x3d: /* restore */ |
|
1065 |
save_state(dc); |
|
1066 |
gen_op_add_T1_T0(); |
|
1067 |
gen_op_restore(); |
|
1068 |
gen_movl_T0_reg(rd); |
|
1069 |
break; |
|
1070 |
default: |
|
1071 |
goto illegal_insn; |
|
1072 |
} |
|
1073 | 1153 |
} |
1154 |
switch (xop) { |
|
1155 |
case 0x38: /* jmpl */ |
|
1156 |
{ |
|
1157 |
gen_op_movl_npc_T0(); |
|
1158 |
if (rd != 0) { |
|
1159 |
gen_op_movl_T0_im((long) (dc->pc)); |
|
1160 |
gen_movl_T0_reg(rd); |
|
1161 |
} |
|
1162 |
dc->pc = dc->npc; |
|
1163 |
dc->npc = DYNAMIC_PC; |
|
1164 |
} |
|
1165 |
goto jmp_insn; |
|
1166 |
#if !defined(CONFIG_USER_ONLY) |
|
1167 |
case 0x39: /* rett */ |
|
1168 |
{ |
|
1169 |
if (!supervisor(dc)) |
|
1170 |
goto priv_insn; |
|
1171 |
gen_op_movl_npc_T0(); |
|
1172 |
gen_op_rett(); |
|
1173 |
} |
|
1174 |
break; |
|
1175 |
#endif |
|
1176 |
case 0x3b: /* flush */ |
|
1177 |
gen_op_flush_T0(); |
|
1178 |
break; |
|
1179 |
case 0x3c: /* save */ |
|
1180 |
save_state(dc); |
|
1181 |
gen_op_save(); |
|
1182 |
gen_movl_T0_reg(rd); |
|
1183 |
break; |
|
1184 |
case 0x3d: /* restore */ |
|
1185 |
save_state(dc); |
|
1186 |
gen_op_restore(); |
|
1187 |
gen_movl_T0_reg(rd); |
|
1188 |
break; |
|
1189 |
default: |
|
1190 |
goto illegal_insn; |
|
1191 |
} |
|
1074 | 1192 |
} |
1075 | 1193 |
break; |
1076 | 1194 |
} |
... | ... | |
1081 | 1199 |
gen_movl_reg_T0(rs1); |
1082 | 1200 |
if (IS_IMM) { /* immediate */ |
1083 | 1201 |
rs2 = GET_FIELDs(insn, 19, 31); |
1202 |
#if defined(OPTIM) |
|
1084 | 1203 |
if (rs2 != 0) { |
1204 |
#endif |
|
1085 | 1205 |
gen_movl_imm_T1(rs2); |
1086 | 1206 |
gen_op_add_T1_T0(); |
1207 |
#if defined(OPTIM) |
|
1087 | 1208 |
} |
1209 |
#endif |
|
1088 | 1210 |
} else { /* register */ |
1089 | 1211 |
rs2 = GET_FIELD(insn, 27, 31); |
1090 |
gen_movl_reg_T1(rs2); |
|
1091 |
gen_op_add_T1_T0(); |
|
1212 |
#if defined(OPTIM) |
|
1213 |
if (rs2 != 0) { |
|
1214 |
#endif |
|
1215 |
gen_movl_reg_T1(rs2); |
|
1216 |
gen_op_add_T1_T0(); |
|
1217 |
#if defined(OPTIM) |
|
1218 |
} |
|
1219 |
#endif |
|
1092 | 1220 |
} |
1093 | 1221 |
if (xop < 4 || (xop > 7 && xop < 0x14) || \ |
1094 | 1222 |
(xop > 0x17 && xop < 0x20)) { |
... | ... | |
1116 | 1244 |
gen_op_ldst(ldstub); |
1117 | 1245 |
break; |
1118 | 1246 |
case 0x0f: /* swap register with memory. Also atomically */ |
1247 |
gen_movl_reg_T1(rd); |
|
1119 | 1248 |
gen_op_ldst(swap); |
1120 | 1249 |
break; |
1250 |
#if !defined(CONFIG_USER_ONLY) |
|
1121 | 1251 |
case 0x10: /* load word alternate */ |
1122 | 1252 |
if (!supervisor(dc)) |
1123 | 1253 |
goto priv_insn; |
... | ... | |
1157 | 1287 |
case 0x1f: /* swap reg with alt. memory. Also atomically */ |
1158 | 1288 |
if (!supervisor(dc)) |
1159 | 1289 |
goto priv_insn; |
1290 |
gen_movl_reg_T1(rd); |
|
1160 | 1291 |
gen_op_swapa(insn, 1, 4, 0); |
1161 | 1292 |
break; |
1293 |
#endif |
|
1294 |
default: |
|
1295 |
goto illegal_insn; |
|
1162 | 1296 |
} |
1163 | 1297 |
gen_movl_T1_reg(rd); |
1164 | 1298 |
} else if (xop >= 0x20 && xop < 0x24) { |
1299 |
#if !defined(CONFIG_USER_ONLY) |
|
1300 |
gen_op_trap_ifnofpu(); |
|
1301 |
#endif |
|
1165 | 1302 |
switch (xop) { |
1166 | 1303 |
case 0x20: /* load fpreg */ |
1167 | 1304 |
gen_op_ldst(ldf); |
... | ... | |
1169 | 1306 |
break; |
1170 | 1307 |
case 0x21: /* load fsr */ |
1171 | 1308 |
gen_op_ldfsr(); |
1309 |
gen_op_store_FT0_fpr(rd); |
|
1172 | 1310 |
break; |
1173 | 1311 |
case 0x23: /* load double fpreg */ |
1174 | 1312 |
gen_op_ldst(lddf); |
1175 | 1313 |
gen_op_store_DT0_fpr(rd); |
1176 | 1314 |
break; |
1315 |
default: |
|
1316 |
goto illegal_insn; |
|
1177 | 1317 |
} |
1178 | 1318 |
} else if (xop < 8 || (xop >= 0x14 && xop < 0x18)) { |
1179 | 1319 |
gen_movl_reg_T1(rd); |
... | ... | |
1192 | 1332 |
gen_movl_reg_T2(rd + 1); |
1193 | 1333 |
gen_op_ldst(std); |
1194 | 1334 |
break; |
1335 |
#if !defined(CONFIG_USER_ONLY) |
|
1195 | 1336 |
case 0x14: |
1196 | 1337 |
if (!supervisor(dc)) |
1197 | 1338 |
goto priv_insn; |
... | ... | |
1214 | 1355 |
gen_movl_reg_T2(rd + 1); |
1215 | 1356 |
gen_op_stda(insn, 0, 8, 0); |
1216 | 1357 |
break; |
1358 |
#endif |
|
1359 |
default: |
|
1360 |
goto illegal_insn; |
|
1217 | 1361 |
} |
1218 | 1362 |
} else if (xop > 0x23 && xop < 0x28) { |
1363 |
#if !defined(CONFIG_USER_ONLY) |
|
1364 |
gen_op_trap_ifnofpu(); |
|
1365 |
#endif |
|
1219 | 1366 |
switch (xop) { |
1220 | 1367 |
case 0x24: |
1221 | 1368 |
gen_op_load_fpr_FT0(rd); |
1222 | 1369 |
gen_op_ldst(stf); |
1223 | 1370 |
break; |
1224 | 1371 |
case 0x25: |
1372 |
gen_op_load_fpr_FT0(rd); |
|
1225 | 1373 |
gen_op_stfsr(); |
1226 | 1374 |
break; |
1227 | 1375 |
case 0x27: |
1228 | 1376 |
gen_op_load_fpr_DT0(rd); |
1229 | 1377 |
gen_op_ldst(stdf); |
1230 | 1378 |
break; |
1379 |
case 0x26: /* stdfq */ |
|
1380 |
default: |
|
1381 |
goto illegal_insn; |
|
1231 | 1382 |
} |
1232 | 1383 |
} else if (xop > 0x33 && xop < 0x38) { |
1233 | 1384 |
/* Co-processor */ |
1385 |
goto illegal_insn; |
|
1234 | 1386 |
} |
1387 |
else |
|
1388 |
goto illegal_insn; |
|
1235 | 1389 |
} |
1236 | 1390 |
} |
1237 | 1391 |
/* default case for non jump instructions */ |
... | ... | |
1246 | 1400 |
dc->pc = dc->npc; |
1247 | 1401 |
dc->npc = dc->npc + 4; |
1248 | 1402 |
} |
1249 |
jmp_insn:;
|
|
1403 |
jmp_insn:
|
|
1250 | 1404 |
return; |
1251 | 1405 |
illegal_insn: |
1252 | 1406 |
save_state(dc); |
1253 | 1407 |
gen_op_exception(TT_ILL_INSN); |
1254 | 1408 |
dc->is_br = 1; |
1255 | 1409 |
return; |
1410 |
#if !defined(CONFIG_USER_ONLY) |
|
1256 | 1411 |
priv_insn: |
1257 | 1412 |
save_state(dc); |
1258 | 1413 |
gen_op_exception(TT_PRIV_INSN); |
1259 | 1414 |
dc->is_br = 1; |
1415 |
return; |
|
1416 |
#endif |
|
1417 |
nfpu_insn: |
|
1418 |
save_state(dc); |
|
1419 |
gen_op_fpexception_im(FSR_FTT_UNIMPFPOP); |
|
1420 |
dc->is_br = 1; |
|
1260 | 1421 |
} |
1261 | 1422 |
|
1262 | 1423 |
static inline int gen_intermediate_code_internal(TranslationBlock * tb, |
... | ... | |
1271 | 1432 |
dc->tb = tb; |
1272 | 1433 |
pc_start = tb->pc; |
1273 | 1434 |
dc->pc = pc_start; |
1435 |
last_pc = dc->pc; |
|
1274 | 1436 |
dc->npc = (target_ulong) tb->cs_base; |
1275 | 1437 |
#if defined(CONFIG_USER_ONLY) |
1276 | 1438 |
dc->mem_idx = 0; |
... | ... | |
1285 | 1447 |
if (env->nb_breakpoints > 0) { |
1286 | 1448 |
for(j = 0; j < env->nb_breakpoints; j++) { |
1287 | 1449 |
if (env->breakpoints[j] == dc->pc) { |
1288 |
gen_debug(dc, dc->pc); |
|
1289 |
break; |
|
1450 |
if (dc->pc != pc_start) |
|
1451 |
save_state(dc); |
|
1452 |
gen_op_debug(); |
|
1453 |
gen_op_movl_T0_0(); |
|
1454 |
gen_op_exit_tb(); |
|
1455 |
dc->is_br = 1; |
|
1456 |
goto exit_gen_loop; |
|
1290 | 1457 |
} |
1291 | 1458 |
} |
1292 | 1459 |
} |
... | ... | |
1310 | 1477 |
/* if the next PC is different, we abort now */ |
1311 | 1478 |
if (dc->pc != (last_pc + 4)) |
1312 | 1479 |
break; |
1480 |
/* if single step mode, we generate only one instruction and |
|
1481 |
generate an exception */ |
|
1482 |
if (env->singlestep_enabled) { |
|
1483 |
gen_op_jmp_im(dc->pc); |
|
1484 |
gen_op_movl_T0_0(); |
|
1485 |
gen_op_exit_tb(); |
|
1486 |
break; |
|
1487 |
} |
|
1313 | 1488 |
} while ((gen_opc_ptr < gen_opc_end) && |
1314 | 1489 |
(dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32)); |
1490 |
|
|
1491 |
exit_gen_loop: |
|
1315 | 1492 |
if (!dc->is_br) { |
1316 | 1493 |
if (dc->pc != DYNAMIC_PC && |
1317 | 1494 |
(dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) { |
... | ... | |
1338 | 1515 |
} |
1339 | 1516 |
#endif |
1340 | 1517 |
} else { |
1341 |
tb->size = dc->npc - pc_start;
|
|
1518 |
tb->size = last_pc + 4 - pc_start;
|
|
1342 | 1519 |
} |
1343 | 1520 |
#ifdef DEBUG_DISAS |
1344 | 1521 |
if (loglevel & CPU_LOG_TB_IN_ASM) { |
... | ... | |
1366 | 1543 |
return gen_intermediate_code_internal(tb, 1, env); |
1367 | 1544 |
} |
1368 | 1545 |
|
1369 |
CPUSPARCState *cpu_sparc_init(void) |
|
1370 |
{ |
|
1371 |
CPUSPARCState *env; |
|
1372 |
|
|
1373 |
cpu_exec_init(); |
|
1546 |
extern int ram_size; |
|
1374 | 1547 |
|
1375 |
if (!(env = malloc(sizeof(CPUSPARCState))))
|
|
1376 |
return (NULL);
|
|
1548 |
void cpu_reset(CPUSPARCState *env)
|
|
1549 |
{
|
|
1377 | 1550 |
memset(env, 0, sizeof(*env)); |
1378 | 1551 |
env->cwp = 0; |
1379 | 1552 |
env->wim = 1; |
... | ... | |
1381 | 1554 |
#if defined(CONFIG_USER_ONLY) |
1382 | 1555 |
env->user_mode_only = 1; |
1383 | 1556 |
#else |
1384 |
/* Emulate Prom */ |
|
1385 | 1557 |
env->psrs = 1; |
1386 |
env->pc = 0x4000; |
|
1558 |
env->pc = 0xffd00000; |
|
1559 |
env->gregs[1] = ram_size; |
|
1560 |
env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */ |
|
1387 | 1561 |
env->npc = env->pc + 4; |
1388 |
env->mmuregs[0] = (0x10<<24) | MMU_E; /* Impl 1, ver 0, MMU Enabled */ |
|
1389 |
env->mmuregs[1] = 0x3000 >> 4; /* MMU Context table */ |
|
1390 | 1562 |
#endif |
1563 |
} |
|
1564 |
|
|
1565 |
CPUSPARCState *cpu_sparc_init(void) |
|
1566 |
{ |
|
1567 |
CPUSPARCState *env; |
|
1568 |
|
|
1569 |
cpu_exec_init(); |
|
1570 |
|
|
1571 |
if (!(env = malloc(sizeof(CPUSPARCState)))) |
|
1572 |
return (NULL); |
|
1391 | 1573 |
cpu_single_env = env; |
1574 |
cpu_reset(env); |
|
1392 | 1575 |
return (env); |
1393 | 1576 |
} |
1394 | 1577 |
|
... | ... | |
1436 | 1619 |
cpu_fprintf(f, "fsr: 0x%08x\n", env->fsr); |
1437 | 1620 |
} |
1438 | 1621 |
|
1622 |
#if defined(CONFIG_USER_ONLY) |
|
1439 | 1623 |
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) |
1440 | 1624 |
{ |
1441 | 1625 |
return addr; |
1442 | 1626 |
} |
1443 | 1627 |
|
1628 |
#else |
|
1629 |
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) |
|
1630 |
{ |
|
1631 |
uint32_t phys_addr; |
|
1632 |
int prot, access_index; |
|
1633 |
|
|
1634 |
if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0) |
|
1635 |
return -1; |
|
1636 |
return phys_addr; |
|
1637 |
} |
|
1638 |
#endif |
|
1639 |
|
|
1444 | 1640 |
void helper_flush(target_ulong addr) |
1445 | 1641 |
{ |
1446 | 1642 |
addr &= ~7; |
Also available in: Unified diff