Commit d66c7132d23d41796f374aec2f5aff1fb01479ee
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 | 932 | #define OP_ST_ATOMIC(insn,fname,almask) \ |
| 933 | 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 | 936 | int l1 = gen_new_label(); \ |
| 937 | 937 | int l2 = gen_new_label(); \ |
| 938 | 938 | int l3 = gen_new_label(); \ |
| ... | ... | @@ -944,13 +944,13 @@ static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \ |
| 944 | 944 | gen_set_label(l1); \ |
| 945 | 945 | tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr)); \ |
| 946 | 946 | tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2); \ |
| 947 | + tcg_temp_free(r_tmp); \ | |
| 947 | 948 | tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx); \ |
| 948 | 949 | tcg_gen_movi_tl(t0, 1); \ |
| 949 | 950 | tcg_gen_br(l3); \ |
| 950 | 951 | gen_set_label(l2); \ |
| 951 | 952 | tcg_gen_movi_tl(t0, 0); \ |
| 952 | 953 | gen_set_label(l3); \ |
| 953 | - tcg_temp_free(r_tmp); \ | |
| 954 | 954 | } |
| 955 | 955 | OP_ST_ATOMIC(sc,st32,0x3); |
| 956 | 956 | #if defined(TARGET_MIPS64) |
| ... | ... | @@ -963,8 +963,8 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
| 963 | 963 | int base, int16_t offset) |
| 964 | 964 | { |
| 965 | 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 | 969 | if (base == 0) { |
| 970 | 970 | tcg_gen_movi_tl(t0, offset); |
| ... | ... | @@ -979,32 +979,29 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
| 979 | 979 | switch (opc) { |
| 980 | 980 | #if defined(TARGET_MIPS64) |
| 981 | 981 | case OPC_LWU: |
| 982 | + save_cpu_state(ctx, 0); | |
| 982 | 983 | op_ldst_lwu(t0, ctx); |
| 983 | 984 | gen_store_gpr(t0, rt); |
| 984 | 985 | opn = "lwu"; |
| 985 | 986 | break; |
| 986 | 987 | case OPC_LD: |
| 988 | + save_cpu_state(ctx, 0); | |
| 987 | 989 | op_ldst_ld(t0, ctx); |
| 988 | 990 | gen_store_gpr(t0, rt); |
| 989 | 991 | opn = "ld"; |
| 990 | 992 | break; |
| 991 | 993 | case OPC_LLD: |
| 994 | + save_cpu_state(ctx, 0); | |
| 992 | 995 | op_ldst_lld(t0, t1, ctx); |
| 993 | 996 | gen_store_gpr(t0, rt); |
| 994 | 997 | opn = "lld"; |
| 995 | 998 | break; |
| 996 | 999 | case OPC_SD: |
| 1000 | + save_cpu_state(ctx, 0); | |
| 997 | 1001 | gen_load_gpr(t1, rt); |
| 998 | 1002 | op_ldst_sd(t0, t1, ctx); |
| 999 | 1003 | opn = "sd"; |
| 1000 | 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 | 1005 | case OPC_LDL: |
| 1009 | 1006 | save_cpu_state(ctx, 1); |
| 1010 | 1007 | gen_load_gpr(t1, rt); |
| ... | ... | @@ -1033,41 +1030,49 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
| 1033 | 1030 | break; |
| 1034 | 1031 | #endif |
| 1035 | 1032 | case OPC_LW: |
| 1033 | + save_cpu_state(ctx, 0); | |
| 1036 | 1034 | op_ldst_lw(t0, ctx); |
| 1037 | 1035 | gen_store_gpr(t0, rt); |
| 1038 | 1036 | opn = "lw"; |
| 1039 | 1037 | break; |
| 1040 | 1038 | case OPC_SW: |
| 1039 | + save_cpu_state(ctx, 0); | |
| 1041 | 1040 | gen_load_gpr(t1, rt); |
| 1042 | 1041 | op_ldst_sw(t0, t1, ctx); |
| 1043 | 1042 | opn = "sw"; |
| 1044 | 1043 | break; |
| 1045 | 1044 | case OPC_LH: |
| 1045 | + save_cpu_state(ctx, 0); | |
| 1046 | 1046 | op_ldst_lh(t0, ctx); |
| 1047 | 1047 | gen_store_gpr(t0, rt); |
| 1048 | 1048 | opn = "lh"; |
| 1049 | 1049 | break; |
| 1050 | 1050 | case OPC_SH: |
| 1051 | + save_cpu_state(ctx, 0); | |
| 1051 | 1052 | gen_load_gpr(t1, rt); |
| 1052 | 1053 | op_ldst_sh(t0, t1, ctx); |
| 1053 | 1054 | opn = "sh"; |
| 1054 | 1055 | break; |
| 1055 | 1056 | case OPC_LHU: |
| 1057 | + save_cpu_state(ctx, 0); | |
| 1056 | 1058 | op_ldst_lhu(t0, ctx); |
| 1057 | 1059 | gen_store_gpr(t0, rt); |
| 1058 | 1060 | opn = "lhu"; |
| 1059 | 1061 | break; |
| 1060 | 1062 | case OPC_LB: |
| 1063 | + save_cpu_state(ctx, 0); | |
| 1061 | 1064 | op_ldst_lb(t0, ctx); |
| 1062 | 1065 | gen_store_gpr(t0, rt); |
| 1063 | 1066 | opn = "lb"; |
| 1064 | 1067 | break; |
| 1065 | 1068 | case OPC_SB: |
| 1069 | + save_cpu_state(ctx, 0); | |
| 1066 | 1070 | gen_load_gpr(t1, rt); |
| 1067 | 1071 | op_ldst_sb(t0, t1, ctx); |
| 1068 | 1072 | opn = "sb"; |
| 1069 | 1073 | break; |
| 1070 | 1074 | case OPC_LBU: |
| 1075 | + save_cpu_state(ctx, 0); | |
| 1071 | 1076 | op_ldst_lbu(t0, ctx); |
| 1072 | 1077 | gen_store_gpr(t0, rt); |
| 1073 | 1078 | opn = "lbu"; |
| ... | ... | @@ -1099,26 +1104,57 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
| 1099 | 1104 | opn = "swr"; |
| 1100 | 1105 | break; |
| 1101 | 1106 | case OPC_LL: |
| 1107 | + save_cpu_state(ctx, 0); | |
| 1102 | 1108 | op_ldst_ll(t0, t1, ctx); |
| 1103 | 1109 | gen_store_gpr(t0, rt); |
| 1104 | 1110 | opn = "ll"; |
| 1105 | 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 | 1148 | case OPC_SC: |
| 1107 | - save_cpu_state(ctx, 1); | |
| 1108 | - gen_load_gpr(t1, rt); | |
| 1149 | + save_cpu_state(ctx, 0); | |
| 1109 | 1150 | op_ldst_sc(t0, t1, ctx); |
| 1110 | - gen_store_gpr(t0, rt); | |
| 1111 | 1151 | opn = "sc"; |
| 1112 | 1152 | break; |
| 1113 | - default: | |
| 1114 | - MIPS_INVAL(opn); | |
| 1115 | - generate_exception(ctx, EXCP_RI); | |
| 1116 | - goto out; | |
| 1117 | 1153 | } |
| 1118 | 1154 | MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); |
| 1119 | - out: | |
| 1120 | - tcg_temp_free(t0); | |
| 1121 | 1155 | tcg_temp_free(t1); |
| 1156 | + gen_store_gpr(t0, rt); | |
| 1157 | + tcg_temp_free(t0); | |
| 1122 | 1158 | } |
| 1123 | 1159 | |
| 1124 | 1160 | /* Load and store */ |
| ... | ... | @@ -7997,9 +8033,11 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
| 7997 | 8033 | case OPC_SB ... OPC_SW: |
| 7998 | 8034 | case OPC_SWR: |
| 7999 | 8035 | case OPC_LL: |
| 8000 | - case OPC_SC: | |
| 8001 | 8036 | gen_ldst(ctx, op, rt, rs, imm); |
| 8002 | 8037 | break; |
| 8038 | + case OPC_SC: | |
| 8039 | + gen_st_cond(ctx, op, rt, rs, imm); | |
| 8040 | + break; | |
| 8003 | 8041 | case OPC_CACHE: |
| 8004 | 8042 | check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32); |
| 8005 | 8043 | /* Treat as NOP. */ |
| ... | ... | @@ -8128,12 +8166,16 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
| 8128 | 8166 | case OPC_SDL ... OPC_SDR: |
| 8129 | 8167 | case OPC_LLD: |
| 8130 | 8168 | case OPC_LD: |
| 8131 | - case OPC_SCD: | |
| 8132 | 8169 | case OPC_SD: |
| 8133 | 8170 | check_insn(env, ctx, ISA_MIPS3); |
| 8134 | 8171 | check_mips_64(ctx); |
| 8135 | 8172 | gen_ldst(ctx, op, rt, rs, imm); |
| 8136 | 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 | 8179 | case OPC_DADDI: |
| 8138 | 8180 | case OPC_DADDIU: |
| 8139 | 8181 | check_insn(env, ctx, ISA_MIPS3); | ... | ... |