summaryrefslogtreecommitdiff
path: root/target-mips/translate.c
diff options
context:
space:
mode:
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-04 08:16:10 +0000
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-04 08:16:10 +0000
commitecedda1c644ff6d440aaad75e107481a058857b9 (patch)
treead88300b5a090520568839df676d1ff0e39cdebd /target-mips/translate.c
parentf76b746d38057b4623368e021b32efb5e9eb4c0f (diff)
downloadqemu-ecedda1c644ff6d440aaad75e107481a058857b9.tar.gz
qemu-ecedda1c644ff6d440aaad75e107481a058857b9.tar.bz2
qemu-ecedda1c644ff6d440aaad75e107481a058857b9.zip
Simplify mips branch handling. Retire T2 from use. Use TCG for branches.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4320 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r--target-mips/translate.c77
1 files changed, 48 insertions, 29 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index a5def256c4..eb8e09e09e 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -421,6 +421,8 @@ enum {
OPC_NMSUB_PS= 0x3E | OPC_CP3,
};
+/* global register indices */
+static TCGv cpu_env, current_tc_regs, cpu_T[2];
const unsigned char *regnames[] =
{ "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
@@ -448,7 +450,6 @@ static always_inline void func(int n) \
/* General purpose registers moves */
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
-GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
@@ -599,15 +600,6 @@ do { \
} \
} while (0)
-#define GEN_LOAD_REG_T2(Rn) \
-do { \
- if (Rn == 0) { \
- gen_op_reset_T2(); \
- } else { \
- gen_op_load_gpr_T2(Rn); \
- } \
-} while (0)
-
#define GEN_LOAD_SRSREG_TN(Tn, Rn) \
do { \
if (Rn == 0) { \
@@ -714,14 +706,9 @@ static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
ctx->saved_hflags = ctx->hflags;
switch (ctx->hflags & MIPS_HFLAG_BMASK) {
case MIPS_HFLAG_BR:
- gen_op_save_breg_target();
break;
case MIPS_HFLAG_BC:
- gen_op_save_bcond();
- /* fall through */
case MIPS_HFLAG_BL:
- /* bcond was already saved by the BL insn */
- /* fall through */
case MIPS_HFLAG_B:
gen_save_btarget(ctx->btarget);
break;
@@ -734,15 +721,11 @@ static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
ctx->saved_hflags = ctx->hflags;
switch (ctx->hflags & MIPS_HFLAG_BMASK) {
case MIPS_HFLAG_BR:
- gen_op_restore_breg_target();
- break;
- case MIPS_HFLAG_B:
- ctx->btarget = env->btarget;
break;
case MIPS_HFLAG_BC:
case MIPS_HFLAG_BL:
+ case MIPS_HFLAG_B:
ctx->btarget = env->btarget;
- gen_op_restore_bcond();
break;
}
}
@@ -1770,6 +1753,19 @@ static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong des
}
}
+static inline void tcg_gen_set_bcond(void)
+{
+ tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
+}
+
+static inline void tcg_gen_jnz_bcond(int label)
+{
+ int r_tmp = tcg_temp_new(TCG_TYPE_TL);
+
+ tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
+ tcg_gen_brcond_tl(TCG_COND_NE, r_tmp, tcg_const_i32(0), label);
+}
+
/* Branches (before delay slot) */
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
int rs, int rt, int32_t offset)
@@ -1838,7 +1834,8 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
generate_exception(ctx, EXCP_RI);
return;
}
- GEN_LOAD_REG_T2(rs);
+ GEN_LOAD_REG_T1(rs);
+ gen_op_save_breg_target();
break;
default:
MIPS_INVAL("branch/jump");
@@ -1983,7 +1980,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
not_likely:
ctx->hflags |= MIPS_HFLAG_BC;
- gen_op_set_bcond();
+ tcg_gen_set_bcond();
break;
case OPC_BLTZALL:
gen_op_ltz();
@@ -1991,8 +1988,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
likely:
ctx->hflags |= MIPS_HFLAG_BL;
- gen_op_set_bcond();
- gen_op_save_bcond();
+ tcg_gen_set_bcond();
break;
default:
MIPS_INVAL("conditional branch/jump");
@@ -4863,8 +4859,7 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
opn = "bc1tl";
likely:
ctx->hflags |= MIPS_HFLAG_BL;
- gen_op_set_bcond();
- gen_op_save_bcond();
+ tcg_gen_set_bcond();
break;
case OPC_BC1FANY2:
gen_op_bc1any2f(cc);
@@ -4883,7 +4878,7 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
opn = "bc1any4t";
not_likely:
ctx->hflags |= MIPS_HFLAG_BC;
- gen_op_set_bcond();
+ tcg_gen_set_bcond();
break;
default:
MIPS_INVAL(opn);
@@ -6056,7 +6051,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
/* Handle blikely not taken case */
MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
l1 = gen_new_label();
- gen_op_jnz_T2(l1);
+ tcg_gen_jnz_bcond(l1);
gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
gen_goto_tb(ctx, 1, ctx->pc + 4);
gen_set_label(l1);
@@ -6612,7 +6607,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
{
int l1;
l1 = gen_new_label();
- gen_op_jnz_T2(l1);
+ tcg_gen_jnz_bcond(l1);
gen_goto_tb(ctx, 1, ctx->pc + 4);
gen_set_label(l1);
gen_goto_tb(ctx, 0, ctx->btarget);
@@ -6877,6 +6872,29 @@ void cpu_dump_state (CPUState *env, FILE *f,
#endif
}
+static void mips_tcg_init(void)
+{
+ static int inited;
+
+ /* Initialize various static tables. */
+ if (inited)
+ return;
+
+ cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
+ current_tc_regs = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG1, "current_tc_regs");
+#if TARGET_LONG_BITS > HOST_LONG_BITS
+ cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
+ TCG_AREG0, offsetof(CPUState, t0), "T0");
+ cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
+ TCG_AREG0, offsetof(CPUState, t1), "T1");
+#else
+ cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T0");
+ cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T1");
+#endif
+
+ inited = 1;
+}
+
#include "translate_init.c"
CPUMIPSState *cpu_mips_init (const char *cpu_model)
@@ -6894,6 +6912,7 @@ CPUMIPSState *cpu_mips_init (const char *cpu_model)
cpu_exec_init(env);
env->cpu_model_str = cpu_model;
+ mips_tcg_init();
cpu_reset(env);
return env;
}