Commit d66c7132d23d41796f374aec2f5aff1fb01479ee

Authored by aurel32
1 parent 324d9e32

target-mips: optimize gen_ldst()

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7093 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 64 additions and 22 deletions
target-mips/translate.c
@@ -932,7 +932,7 @@ OP_LD_ATOMIC(lld,ld64); @@ -932,7 +932,7 @@ OP_LD_ATOMIC(lld,ld64);
932 #define OP_ST_ATOMIC(insn,fname,almask) \ 932 #define OP_ST_ATOMIC(insn,fname,almask) \
933 static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \ 933 static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
934 { \ 934 { \
935 - TCGv r_tmp = tcg_temp_local_new(); \ 935 + TCGv r_tmp = tcg_temp_new(); \
936 int l1 = gen_new_label(); \ 936 int l1 = gen_new_label(); \
937 int l2 = gen_new_label(); \ 937 int l2 = gen_new_label(); \
938 int l3 = gen_new_label(); \ 938 int l3 = gen_new_label(); \
@@ -944,13 +944,13 @@ static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \ @@ -944,13 +944,13 @@ static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
944 gen_set_label(l1); \ 944 gen_set_label(l1); \
945 tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr)); \ 945 tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr)); \
946 tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2); \ 946 tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2); \
  947 + tcg_temp_free(r_tmp); \
947 tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx); \ 948 tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx); \
948 tcg_gen_movi_tl(t0, 1); \ 949 tcg_gen_movi_tl(t0, 1); \
949 tcg_gen_br(l3); \ 950 tcg_gen_br(l3); \
950 gen_set_label(l2); \ 951 gen_set_label(l2); \
951 tcg_gen_movi_tl(t0, 0); \ 952 tcg_gen_movi_tl(t0, 0); \
952 gen_set_label(l3); \ 953 gen_set_label(l3); \
953 - tcg_temp_free(r_tmp); \  
954 } 954 }
955 OP_ST_ATOMIC(sc,st32,0x3); 955 OP_ST_ATOMIC(sc,st32,0x3);
956 #if defined(TARGET_MIPS64) 956 #if defined(TARGET_MIPS64)
@@ -963,8 +963,8 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, @@ -963,8 +963,8 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
963 int base, int16_t offset) 963 int base, int16_t offset)
964 { 964 {
965 const char *opn = "ldst"; 965 const char *opn = "ldst";
966 - TCGv t0 = tcg_temp_local_new();  
967 - TCGv t1 = tcg_temp_local_new(); 966 + TCGv t0 = tcg_temp_new();
  967 + TCGv t1 = tcg_temp_new();
968 968
969 if (base == 0) { 969 if (base == 0) {
970 tcg_gen_movi_tl(t0, offset); 970 tcg_gen_movi_tl(t0, offset);
@@ -979,32 +979,29 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, @@ -979,32 +979,29 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
979 switch (opc) { 979 switch (opc) {
980 #if defined(TARGET_MIPS64) 980 #if defined(TARGET_MIPS64)
981 case OPC_LWU: 981 case OPC_LWU:
  982 + save_cpu_state(ctx, 0);
982 op_ldst_lwu(t0, ctx); 983 op_ldst_lwu(t0, ctx);
983 gen_store_gpr(t0, rt); 984 gen_store_gpr(t0, rt);
984 opn = "lwu"; 985 opn = "lwu";
985 break; 986 break;
986 case OPC_LD: 987 case OPC_LD:
  988 + save_cpu_state(ctx, 0);
987 op_ldst_ld(t0, ctx); 989 op_ldst_ld(t0, ctx);
988 gen_store_gpr(t0, rt); 990 gen_store_gpr(t0, rt);
989 opn = "ld"; 991 opn = "ld";
990 break; 992 break;
991 case OPC_LLD: 993 case OPC_LLD:
  994 + save_cpu_state(ctx, 0);
992 op_ldst_lld(t0, t1, ctx); 995 op_ldst_lld(t0, t1, ctx);
993 gen_store_gpr(t0, rt); 996 gen_store_gpr(t0, rt);
994 opn = "lld"; 997 opn = "lld";
995 break; 998 break;
996 case OPC_SD: 999 case OPC_SD:
  1000 + save_cpu_state(ctx, 0);
997 gen_load_gpr(t1, rt); 1001 gen_load_gpr(t1, rt);
998 op_ldst_sd(t0, t1, ctx); 1002 op_ldst_sd(t0, t1, ctx);
999 opn = "sd"; 1003 opn = "sd";
1000 break; 1004 break;
1001 - case OPC_SCD:  
1002 - save_cpu_state(ctx, 1);  
1003 - gen_load_gpr(t1, rt);  
1004 - op_ldst_scd(t0, t1, ctx);  
1005 - gen_store_gpr(t0, rt);  
1006 - opn = "scd";  
1007 - break;  
1008 case OPC_LDL: 1005 case OPC_LDL:
1009 save_cpu_state(ctx, 1); 1006 save_cpu_state(ctx, 1);
1010 gen_load_gpr(t1, rt); 1007 gen_load_gpr(t1, rt);
@@ -1033,41 +1030,49 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, @@ -1033,41 +1030,49 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1033 break; 1030 break;
1034 #endif 1031 #endif
1035 case OPC_LW: 1032 case OPC_LW:
  1033 + save_cpu_state(ctx, 0);
1036 op_ldst_lw(t0, ctx); 1034 op_ldst_lw(t0, ctx);
1037 gen_store_gpr(t0, rt); 1035 gen_store_gpr(t0, rt);
1038 opn = "lw"; 1036 opn = "lw";
1039 break; 1037 break;
1040 case OPC_SW: 1038 case OPC_SW:
  1039 + save_cpu_state(ctx, 0);
1041 gen_load_gpr(t1, rt); 1040 gen_load_gpr(t1, rt);
1042 op_ldst_sw(t0, t1, ctx); 1041 op_ldst_sw(t0, t1, ctx);
1043 opn = "sw"; 1042 opn = "sw";
1044 break; 1043 break;
1045 case OPC_LH: 1044 case OPC_LH:
  1045 + save_cpu_state(ctx, 0);
1046 op_ldst_lh(t0, ctx); 1046 op_ldst_lh(t0, ctx);
1047 gen_store_gpr(t0, rt); 1047 gen_store_gpr(t0, rt);
1048 opn = "lh"; 1048 opn = "lh";
1049 break; 1049 break;
1050 case OPC_SH: 1050 case OPC_SH:
  1051 + save_cpu_state(ctx, 0);
1051 gen_load_gpr(t1, rt); 1052 gen_load_gpr(t1, rt);
1052 op_ldst_sh(t0, t1, ctx); 1053 op_ldst_sh(t0, t1, ctx);
1053 opn = "sh"; 1054 opn = "sh";
1054 break; 1055 break;
1055 case OPC_LHU: 1056 case OPC_LHU:
  1057 + save_cpu_state(ctx, 0);
1056 op_ldst_lhu(t0, ctx); 1058 op_ldst_lhu(t0, ctx);
1057 gen_store_gpr(t0, rt); 1059 gen_store_gpr(t0, rt);
1058 opn = "lhu"; 1060 opn = "lhu";
1059 break; 1061 break;
1060 case OPC_LB: 1062 case OPC_LB:
  1063 + save_cpu_state(ctx, 0);
1061 op_ldst_lb(t0, ctx); 1064 op_ldst_lb(t0, ctx);
1062 gen_store_gpr(t0, rt); 1065 gen_store_gpr(t0, rt);
1063 opn = "lb"; 1066 opn = "lb";
1064 break; 1067 break;
1065 case OPC_SB: 1068 case OPC_SB:
  1069 + save_cpu_state(ctx, 0);
1066 gen_load_gpr(t1, rt); 1070 gen_load_gpr(t1, rt);
1067 op_ldst_sb(t0, t1, ctx); 1071 op_ldst_sb(t0, t1, ctx);
1068 opn = "sb"; 1072 opn = "sb";
1069 break; 1073 break;
1070 case OPC_LBU: 1074 case OPC_LBU:
  1075 + save_cpu_state(ctx, 0);
1071 op_ldst_lbu(t0, ctx); 1076 op_ldst_lbu(t0, ctx);
1072 gen_store_gpr(t0, rt); 1077 gen_store_gpr(t0, rt);
1073 opn = "lbu"; 1078 opn = "lbu";
@@ -1099,26 +1104,57 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, @@ -1099,26 +1104,57 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1099 opn = "swr"; 1104 opn = "swr";
1100 break; 1105 break;
1101 case OPC_LL: 1106 case OPC_LL:
  1107 + save_cpu_state(ctx, 0);
1102 op_ldst_ll(t0, t1, ctx); 1108 op_ldst_ll(t0, t1, ctx);
1103 gen_store_gpr(t0, rt); 1109 gen_store_gpr(t0, rt);
1104 opn = "ll"; 1110 opn = "ll";
1105 break; 1111 break;
  1112 + }
  1113 + MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
  1114 + tcg_temp_free(t0);
  1115 + tcg_temp_free(t1);
  1116 +}
  1117 +
  1118 +/* Store conditional */
  1119 +static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
  1120 + int base, int16_t offset)
  1121 +{
  1122 + const char *opn = "st_cond";
  1123 + TCGv t0, t1;
  1124 +
  1125 + t0 = tcg_temp_local_new();
  1126 +
  1127 + if (base == 0) {
  1128 + tcg_gen_movi_tl(t0, offset);
  1129 + } else if (offset == 0) {
  1130 + gen_load_gpr(t0, base);
  1131 + } else {
  1132 + tcg_gen_movi_tl(t0, offset);
  1133 + gen_op_addr_add(ctx, t0, cpu_gpr[base]);
  1134 + }
  1135 + /* Don't do NOP if destination is zero: we must perform the actual
  1136 + memory access. */
  1137 +
  1138 + t1 = tcg_temp_local_new();
  1139 + gen_load_gpr(t1, rt);
  1140 + switch (opc) {
  1141 +#if defined(TARGET_MIPS64)
  1142 + case OPC_SCD:
  1143 + save_cpu_state(ctx, 0);
  1144 + op_ldst_scd(t0, t1, ctx);
  1145 + opn = "scd";
  1146 + break;
  1147 +#endif
1106 case OPC_SC: 1148 case OPC_SC:
1107 - save_cpu_state(ctx, 1);  
1108 - gen_load_gpr(t1, rt); 1149 + save_cpu_state(ctx, 0);
1109 op_ldst_sc(t0, t1, ctx); 1150 op_ldst_sc(t0, t1, ctx);
1110 - gen_store_gpr(t0, rt);  
1111 opn = "sc"; 1151 opn = "sc";
1112 break; 1152 break;
1113 - default:  
1114 - MIPS_INVAL(opn);  
1115 - generate_exception(ctx, EXCP_RI);  
1116 - goto out;  
1117 } 1153 }
1118 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); 1154 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1119 - out:  
1120 - tcg_temp_free(t0);  
1121 tcg_temp_free(t1); 1155 tcg_temp_free(t1);
  1156 + gen_store_gpr(t0, rt);
  1157 + tcg_temp_free(t0);
1122 } 1158 }
1123 1159
1124 /* Load and store */ 1160 /* Load and store */
@@ -7997,9 +8033,11 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -7997,9 +8033,11 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
7997 case OPC_SB ... OPC_SW: 8033 case OPC_SB ... OPC_SW:
7998 case OPC_SWR: 8034 case OPC_SWR:
7999 case OPC_LL: 8035 case OPC_LL:
8000 - case OPC_SC:  
8001 gen_ldst(ctx, op, rt, rs, imm); 8036 gen_ldst(ctx, op, rt, rs, imm);
8002 break; 8037 break;
  8038 + case OPC_SC:
  8039 + gen_st_cond(ctx, op, rt, rs, imm);
  8040 + break;
8003 case OPC_CACHE: 8041 case OPC_CACHE:
8004 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32); 8042 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8005 /* Treat as NOP. */ 8043 /* Treat as NOP. */
@@ -8128,12 +8166,16 @@ static void decode_opc (CPUState *env, DisasContext *ctx) @@ -8128,12 +8166,16 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
8128 case OPC_SDL ... OPC_SDR: 8166 case OPC_SDL ... OPC_SDR:
8129 case OPC_LLD: 8167 case OPC_LLD:
8130 case OPC_LD: 8168 case OPC_LD:
8131 - case OPC_SCD:  
8132 case OPC_SD: 8169 case OPC_SD:
8133 check_insn(env, ctx, ISA_MIPS3); 8170 check_insn(env, ctx, ISA_MIPS3);
8134 check_mips_64(ctx); 8171 check_mips_64(ctx);
8135 gen_ldst(ctx, op, rt, rs, imm); 8172 gen_ldst(ctx, op, rt, rs, imm);
8136 break; 8173 break;
  8174 + case OPC_SCD:
  8175 + check_insn(env, ctx, ISA_MIPS3);
  8176 + check_mips_64(ctx);
  8177 + gen_st_cond(ctx, op, rt, rs, imm);
  8178 + break;
8137 case OPC_DADDI: 8179 case OPC_DADDI:
8138 case OPC_DADDIU: 8180 case OPC_DADDIU:
8139 check_insn(env, ctx, ISA_MIPS3); 8181 check_insn(env, ctx, ISA_MIPS3);