Commit aaa9128a024df25dcd80c62b01fa72a4c0988b07
1 parent
36271893
Convert some MIPS load/store instructions to TCG.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4369 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
175 additions
and
109 deletions
target-mips/op.c
... | ... | @@ -247,30 +247,6 @@ |
247 | 247 | #include "fop_template.c" |
248 | 248 | #undef FTN |
249 | 249 | |
250 | -void op_load_HI (void) | |
251 | -{ | |
252 | - T0 = env->HI[env->current_tc][PARAM1]; | |
253 | - FORCE_RET(); | |
254 | -} | |
255 | - | |
256 | -void op_store_HI (void) | |
257 | -{ | |
258 | - env->HI[env->current_tc][PARAM1] = T0; | |
259 | - FORCE_RET(); | |
260 | -} | |
261 | - | |
262 | -void op_load_LO (void) | |
263 | -{ | |
264 | - T0 = env->LO[env->current_tc][PARAM1]; | |
265 | - FORCE_RET(); | |
266 | -} | |
267 | - | |
268 | -void op_store_LO (void) | |
269 | -{ | |
270 | - env->LO[env->current_tc][PARAM1] = T0; | |
271 | - FORCE_RET(); | |
272 | -} | |
273 | - | |
274 | 250 | /* Load and store */ |
275 | 251 | #define MEMSUFFIX _raw |
276 | 252 | #include "op_mem.c" | ... | ... |
target-mips/op_template.c
... | ... | @@ -56,37 +56,3 @@ void glue(op_store_T0_srsgpr_gpr, REG) (void) |
56 | 56 | FORCE_RET(); |
57 | 57 | } |
58 | 58 | #endif |
59 | - | |
60 | -#if defined (TN) | |
61 | -#define SET_RESET(treg, tregname) \ | |
62 | - void glue(op_set, tregname)(void) \ | |
63 | - { \ | |
64 | - treg = (int32_t)PARAM1; \ | |
65 | - FORCE_RET(); \ | |
66 | - } \ | |
67 | - void glue(op_reset, tregname)(void) \ | |
68 | - { \ | |
69 | - treg = 0; \ | |
70 | - FORCE_RET(); \ | |
71 | - } \ | |
72 | - | |
73 | -SET_RESET(T0, _T0) | |
74 | -SET_RESET(T1, _T1) | |
75 | - | |
76 | -#undef SET_RESET | |
77 | - | |
78 | -#if defined(TARGET_MIPS64) | |
79 | -#define SET64(treg, tregname) \ | |
80 | - void glue(op_set64, tregname)(void) \ | |
81 | - { \ | |
82 | - treg = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2; \ | |
83 | - FORCE_RET(); \ | |
84 | - } | |
85 | - | |
86 | -SET64(T0, _T0) | |
87 | -SET64(T1, _T1) | |
88 | - | |
89 | -#undef SET64 | |
90 | - | |
91 | -#endif | |
92 | -#endif | ... | ... |
target-mips/translate.c
... | ... | @@ -488,6 +488,50 @@ static inline void gen_op_store_srsgpr_T0(int reg) |
488 | 488 | tcg_gen_st_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg); |
489 | 489 | } |
490 | 490 | |
491 | +/* Load immediates, zero being a special case. */ | |
492 | +static inline void gen_op_set_T0(target_ulong arg) | |
493 | +{ | |
494 | + tcg_gen_movi_tl(cpu_T[0], arg); | |
495 | +} | |
496 | + | |
497 | +static inline void gen_op_set_T1(target_ulong arg) | |
498 | +{ | |
499 | + tcg_gen_movi_tl(cpu_T[1], arg); | |
500 | +} | |
501 | + | |
502 | +static inline void gen_op_reset_T0(void) | |
503 | +{ | |
504 | + tcg_gen_movi_tl(cpu_T[0], 0); | |
505 | +} | |
506 | + | |
507 | +static inline void gen_op_reset_T1(void) | |
508 | +{ | |
509 | + tcg_gen_movi_tl(cpu_T[1], 0); | |
510 | +} | |
511 | + | |
512 | +/* Moves to/from HI/LO registers. */ | |
513 | +static inline void gen_op_load_HI(int reg) | |
514 | +{ | |
515 | + tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[reg])); | |
516 | +} | |
517 | + | |
518 | +static inline void gen_op_store_HI(int reg) | |
519 | +{ | |
520 | + tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[reg])); | |
521 | +} | |
522 | + | |
523 | +static inline void gen_op_load_LO(int reg) | |
524 | +{ | |
525 | + tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[reg])); | |
526 | +} | |
527 | + | |
528 | +static inline void gen_op_store_LO(int reg) | |
529 | +{ | |
530 | + tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[reg])); | |
531 | +} | |
532 | + | |
533 | + | |
534 | +/* Floating point register moves. */ | |
491 | 535 | static const char *fregnames[] = |
492 | 536 | { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", |
493 | 537 | "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", |
... | ... | @@ -639,18 +683,6 @@ do { \ |
639 | 683 | } \ |
640 | 684 | } while (0) |
641 | 685 | |
642 | -#if defined(TARGET_MIPS64) | |
643 | -#define GEN_LOAD_IMM_TN(Tn, Imm) \ | |
644 | -do { \ | |
645 | - if (Imm == 0) { \ | |
646 | - glue(gen_op_reset_, Tn)(); \ | |
647 | - } else if ((int32_t)Imm == Imm) { \ | |
648 | - glue(gen_op_set_, Tn)(Imm); \ | |
649 | - } else { \ | |
650 | - glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm); \ | |
651 | - } \ | |
652 | -} while (0) | |
653 | -#else | |
654 | 686 | #define GEN_LOAD_IMM_TN(Tn, Imm) \ |
655 | 687 | do { \ |
656 | 688 | if (Imm == 0) { \ |
... | ... | @@ -659,7 +691,6 @@ do { \ |
659 | 691 | glue(gen_op_set_, Tn)(Imm); \ |
660 | 692 | } \ |
661 | 693 | } while (0) |
662 | -#endif | |
663 | 694 | |
664 | 695 | #define GEN_STORE_T0_REG(Rn) \ |
665 | 696 | do { \ |
... | ... | @@ -759,6 +790,24 @@ static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx) |
759 | 790 | } |
760 | 791 | } |
761 | 792 | |
793 | +static always_inline void | |
794 | +generate_tcg_exception_err (DisasContext *ctx, int excp, int err) | |
795 | +{ | |
796 | + save_cpu_state(ctx, 1); | |
797 | + if (err == 0) | |
798 | + gen_op_raise_exception(excp); | |
799 | + else | |
800 | + gen_op_raise_exception_err(excp, err); | |
801 | + gen_op_interrupt_restart(); | |
802 | + tcg_gen_exit_tb(0); | |
803 | +} | |
804 | + | |
805 | +static always_inline void | |
806 | +generate_tcg_exception (DisasContext *ctx, int excp) | |
807 | +{ | |
808 | + generate_tcg_exception_err (ctx, excp, 0); | |
809 | +} | |
810 | + | |
762 | 811 | static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err) |
763 | 812 | { |
764 | 813 | #if defined MIPS_DEBUG_DISAS |
... | ... | @@ -864,30 +913,15 @@ static GenOpFunc *gen_op_s##width[] = { \ |
864 | 913 | #endif |
865 | 914 | |
866 | 915 | #if defined(TARGET_MIPS64) |
867 | -OP_LD_TABLE(d); | |
868 | 916 | OP_LD_TABLE(dl); |
869 | 917 | OP_LD_TABLE(dr); |
870 | -OP_ST_TABLE(d); | |
871 | 918 | OP_ST_TABLE(dl); |
872 | 919 | OP_ST_TABLE(dr); |
873 | -OP_LD_TABLE(ld); | |
874 | -OP_ST_TABLE(cd); | |
875 | -OP_LD_TABLE(wu); | |
876 | 920 | #endif |
877 | -OP_LD_TABLE(w); | |
878 | 921 | OP_LD_TABLE(wl); |
879 | 922 | OP_LD_TABLE(wr); |
880 | -OP_ST_TABLE(w); | |
881 | 923 | OP_ST_TABLE(wl); |
882 | 924 | OP_ST_TABLE(wr); |
883 | -OP_LD_TABLE(h); | |
884 | -OP_LD_TABLE(hu); | |
885 | -OP_ST_TABLE(h); | |
886 | -OP_LD_TABLE(b); | |
887 | -OP_LD_TABLE(bu); | |
888 | -OP_ST_TABLE(b); | |
889 | -OP_LD_TABLE(l); | |
890 | -OP_ST_TABLE(c); | |
891 | 925 | OP_LD_TABLE(wc1); |
892 | 926 | OP_ST_TABLE(wc1); |
893 | 927 | OP_LD_TABLE(dc1); |
... | ... | @@ -895,6 +929,96 @@ OP_ST_TABLE(dc1); |
895 | 929 | OP_LD_TABLE(uxc1); |
896 | 930 | OP_ST_TABLE(uxc1); |
897 | 931 | |
932 | +#define OP_LD(insn,fname) \ | |
933 | +void inline op_ldst_##insn(DisasContext *ctx) \ | |
934 | +{ \ | |
935 | + tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx); \ | |
936 | +} | |
937 | +OP_LD(lb,ld8s); | |
938 | +OP_LD(lbu,ld8u); | |
939 | +OP_LD(lh,ld16s); | |
940 | +OP_LD(lhu,ld16u); | |
941 | +OP_LD(lw,ld32s); | |
942 | +#if defined(TARGET_MIPS64) | |
943 | +OP_LD(lwu,ld32u); | |
944 | +OP_LD(ld,ld64); | |
945 | +#endif | |
946 | +#undef OP_LD | |
947 | + | |
948 | +#define OP_ST(insn,fname) \ | |
949 | +void inline op_ldst_##insn(DisasContext *ctx) \ | |
950 | +{ \ | |
951 | + tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx); \ | |
952 | +} | |
953 | +OP_ST(sb,st8); | |
954 | +OP_ST(sh,st16); | |
955 | +OP_ST(sw,st32); | |
956 | +#if defined(TARGET_MIPS64) | |
957 | +OP_ST(sd,st64); | |
958 | +#endif | |
959 | +#undef OP_ST | |
960 | + | |
961 | +#define OP_LD_ATOMIC(insn,fname) \ | |
962 | +void inline op_ldst_##insn(DisasContext *ctx) \ | |
963 | +{ \ | |
964 | + tcg_gen_mov_tl(cpu_T[1], cpu_T[0]); \ | |
965 | + tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx); \ | |
966 | + tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr)); \ | |
967 | +} | |
968 | +OP_LD_ATOMIC(ll,ld32s); | |
969 | +#if defined(TARGET_MIPS64) | |
970 | +OP_LD_ATOMIC(lld,ld64); | |
971 | +#endif | |
972 | +#undef OP_LD_ATOMIC | |
973 | + | |
974 | +#define OP_ST_ATOMIC(insn,fname,almask) \ | |
975 | +void inline op_ldst_##insn(DisasContext *ctx) \ | |
976 | +{ \ | |
977 | + int r_tmp = tcg_temp_new(TCG_TYPE_TL); \ | |
978 | + int l1 = gen_new_label(); \ | |
979 | + int l2 = gen_new_label(); \ | |
980 | + int l3 = gen_new_label(); \ | |
981 | + \ | |
982 | + tcg_gen_andi_tl(r_tmp, cpu_T[0], almask); \ | |
983 | + tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp, tcg_const_tl(0), l1); \ | |
984 | + tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \ | |
985 | + generate_tcg_exception(ctx, EXCP_AdES); \ | |
986 | + gen_set_label(l1); \ | |
987 | + tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr)); \ | |
988 | + tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2); \ | |
989 | + tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx); \ | |
990 | + tcg_gen_movi_tl(cpu_T[0], 1); \ | |
991 | + tcg_gen_br(l3); \ | |
992 | + gen_set_label(l2); \ | |
993 | + tcg_gen_movi_tl(cpu_T[0], 0); \ | |
994 | + gen_set_label(l3); \ | |
995 | +} | |
996 | +OP_ST_ATOMIC(sc,st32,0x3); | |
997 | +#if defined(TARGET_MIPS64) | |
998 | +OP_ST_ATOMIC(scd,st64,0x7); | |
999 | +#endif | |
1000 | +#undef OP_ST_ATOMIC | |
1001 | + | |
1002 | +void inline op_ldst_lwc1(DisasContext *ctx) | |
1003 | +{ | |
1004 | + op_ldst(lwc1); | |
1005 | +} | |
1006 | + | |
1007 | +void inline op_ldst_ldc1(DisasContext *ctx) | |
1008 | +{ | |
1009 | + op_ldst(ldc1); | |
1010 | +} | |
1011 | + | |
1012 | +void inline op_ldst_swc1(DisasContext *ctx) | |
1013 | +{ | |
1014 | + op_ldst(swc1); | |
1015 | +} | |
1016 | + | |
1017 | +void inline op_ldst_sdc1(DisasContext *ctx) | |
1018 | +{ | |
1019 | + op_ldst(sdc1); | |
1020 | +} | |
1021 | + | |
898 | 1022 | /* Load and store */ |
899 | 1023 | static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
900 | 1024 | int base, int16_t offset) |
... | ... | @@ -915,29 +1039,29 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
915 | 1039 | switch (opc) { |
916 | 1040 | #if defined(TARGET_MIPS64) |
917 | 1041 | case OPC_LWU: |
918 | - op_ldst(lwu); | |
1042 | + op_ldst_lwu(ctx); | |
919 | 1043 | GEN_STORE_T0_REG(rt); |
920 | 1044 | opn = "lwu"; |
921 | 1045 | break; |
922 | 1046 | case OPC_LD: |
923 | - op_ldst(ld); | |
1047 | + op_ldst_ld(ctx); | |
924 | 1048 | GEN_STORE_T0_REG(rt); |
925 | 1049 | opn = "ld"; |
926 | 1050 | break; |
927 | 1051 | case OPC_LLD: |
928 | - op_ldst(lld); | |
1052 | + op_ldst_lld(ctx); | |
929 | 1053 | GEN_STORE_T0_REG(rt); |
930 | 1054 | opn = "lld"; |
931 | 1055 | break; |
932 | 1056 | case OPC_SD: |
933 | 1057 | GEN_LOAD_REG_T1(rt); |
934 | - op_ldst(sd); | |
1058 | + op_ldst_sd(ctx); | |
935 | 1059 | opn = "sd"; |
936 | 1060 | break; |
937 | 1061 | case OPC_SCD: |
938 | 1062 | save_cpu_state(ctx, 1); |
939 | 1063 | GEN_LOAD_REG_T1(rt); |
940 | - op_ldst(scd); | |
1064 | + op_ldst_scd(ctx); | |
941 | 1065 | GEN_STORE_T0_REG(rt); |
942 | 1066 | opn = "scd"; |
943 | 1067 | break; |
... | ... | @@ -965,42 +1089,42 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
965 | 1089 | break; |
966 | 1090 | #endif |
967 | 1091 | case OPC_LW: |
968 | - op_ldst(lw); | |
1092 | + op_ldst_lw(ctx); | |
969 | 1093 | GEN_STORE_T0_REG(rt); |
970 | 1094 | opn = "lw"; |
971 | 1095 | break; |
972 | 1096 | case OPC_SW: |
973 | 1097 | GEN_LOAD_REG_T1(rt); |
974 | - op_ldst(sw); | |
1098 | + op_ldst_sw(ctx); | |
975 | 1099 | opn = "sw"; |
976 | 1100 | break; |
977 | 1101 | case OPC_LH: |
978 | - op_ldst(lh); | |
1102 | + op_ldst_lh(ctx); | |
979 | 1103 | GEN_STORE_T0_REG(rt); |
980 | 1104 | opn = "lh"; |
981 | 1105 | break; |
982 | 1106 | case OPC_SH: |
983 | 1107 | GEN_LOAD_REG_T1(rt); |
984 | - op_ldst(sh); | |
1108 | + op_ldst_sh(ctx); | |
985 | 1109 | opn = "sh"; |
986 | 1110 | break; |
987 | 1111 | case OPC_LHU: |
988 | - op_ldst(lhu); | |
1112 | + op_ldst_lhu(ctx); | |
989 | 1113 | GEN_STORE_T0_REG(rt); |
990 | 1114 | opn = "lhu"; |
991 | 1115 | break; |
992 | 1116 | case OPC_LB: |
993 | - op_ldst(lb); | |
1117 | + op_ldst_lb(ctx); | |
994 | 1118 | GEN_STORE_T0_REG(rt); |
995 | 1119 | opn = "lb"; |
996 | 1120 | break; |
997 | 1121 | case OPC_SB: |
998 | 1122 | GEN_LOAD_REG_T1(rt); |
999 | - op_ldst(sb); | |
1123 | + op_ldst_sb(ctx); | |
1000 | 1124 | opn = "sb"; |
1001 | 1125 | break; |
1002 | 1126 | case OPC_LBU: |
1003 | - op_ldst(lbu); | |
1127 | + op_ldst_lbu(ctx); | |
1004 | 1128 | GEN_STORE_T0_REG(rt); |
1005 | 1129 | opn = "lbu"; |
1006 | 1130 | break; |
... | ... | @@ -1027,14 +1151,14 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
1027 | 1151 | opn = "swr"; |
1028 | 1152 | break; |
1029 | 1153 | case OPC_LL: |
1030 | - op_ldst(ll); | |
1154 | + op_ldst_ll(ctx); | |
1031 | 1155 | GEN_STORE_T0_REG(rt); |
1032 | 1156 | opn = "ll"; |
1033 | 1157 | break; |
1034 | 1158 | case OPC_SC: |
1035 | 1159 | save_cpu_state(ctx, 1); |
1036 | 1160 | GEN_LOAD_REG_T1(rt); |
1037 | - op_ldst(sc); | |
1161 | + op_ldst_sc(ctx); | |
1038 | 1162 | GEN_STORE_T0_REG(rt); |
1039 | 1163 | opn = "sc"; |
1040 | 1164 | break; |
... | ... | @@ -1065,23 +1189,23 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, |
1065 | 1189 | memory access. */ |
1066 | 1190 | switch (opc) { |
1067 | 1191 | case OPC_LWC1: |
1068 | - op_ldst(lwc1); | |
1192 | + op_ldst_lwc1(ctx); | |
1069 | 1193 | GEN_STORE_FTN_FREG(ft, WT0); |
1070 | 1194 | opn = "lwc1"; |
1071 | 1195 | break; |
1072 | 1196 | case OPC_SWC1: |
1073 | 1197 | GEN_LOAD_FREG_FTN(WT0, ft); |
1074 | - op_ldst(swc1); | |
1198 | + op_ldst_swc1(ctx); | |
1075 | 1199 | opn = "swc1"; |
1076 | 1200 | break; |
1077 | 1201 | case OPC_LDC1: |
1078 | - op_ldst(ldc1); | |
1202 | + op_ldst_ldc1(ctx); | |
1079 | 1203 | GEN_STORE_FTN_FREG(ft, DT0); |
1080 | 1204 | opn = "ldc1"; |
1081 | 1205 | break; |
1082 | 1206 | case OPC_SDC1: |
1083 | 1207 | GEN_LOAD_FREG_FTN(DT0, ft); |
1084 | - op_ldst(sdc1); | |
1208 | + op_ldst_sdc1(ctx); | |
1085 | 1209 | opn = "sdc1"; |
1086 | 1210 | break; |
1087 | 1211 | default: |
... | ... | @@ -5852,14 +5976,14 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, |
5852 | 5976 | switch (opc) { |
5853 | 5977 | case OPC_LWXC1: |
5854 | 5978 | check_cop1x(ctx); |
5855 | - op_ldst(lwc1); | |
5979 | + op_ldst_lwc1(ctx); | |
5856 | 5980 | GEN_STORE_FTN_FREG(fd, WT0); |
5857 | 5981 | opn = "lwxc1"; |
5858 | 5982 | break; |
5859 | 5983 | case OPC_LDXC1: |
5860 | 5984 | check_cop1x(ctx); |
5861 | 5985 | check_cp1_registers(ctx, fd); |
5862 | - op_ldst(ldc1); | |
5986 | + op_ldst_ldc1(ctx); | |
5863 | 5987 | GEN_STORE_FTN_FREG(fd, DT0); |
5864 | 5988 | opn = "ldxc1"; |
5865 | 5989 | break; |
... | ... | @@ -5872,7 +5996,7 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, |
5872 | 5996 | case OPC_SWXC1: |
5873 | 5997 | check_cop1x(ctx); |
5874 | 5998 | GEN_LOAD_FREG_FTN(WT0, fs); |
5875 | - op_ldst(swc1); | |
5999 | + op_ldst_swc1(ctx); | |
5876 | 6000 | opn = "swxc1"; |
5877 | 6001 | store = 1; |
5878 | 6002 | break; |
... | ... | @@ -5880,7 +6004,7 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, |
5880 | 6004 | check_cop1x(ctx); |
5881 | 6005 | check_cp1_registers(ctx, fs); |
5882 | 6006 | GEN_LOAD_FREG_FTN(DT0, fs); |
5883 | - op_ldst(sdc1); | |
6007 | + op_ldst_sdc1(ctx); | |
5884 | 6008 | opn = "sdxc1"; |
5885 | 6009 | store = 1; |
5886 | 6010 | break; | ... | ... |