Make bcond and btarget TCG registers.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4805 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
ths 2008-06-30 11:30:34 +00:00
parent d297f464d3
commit d077b6f759
1 changed files with 43 additions and 73 deletions

View File

@ -423,7 +423,7 @@ enum {
};
/* global register indices */
static TCGv cpu_env, current_fpu;
static TCGv cpu_env, bcond, btarget, current_fpu;
/* FPU TNs, global for now. */
static TCGv fpu32_T[3], fpu64_T[3], fpu32h_T[3];
@ -532,8 +532,7 @@ typedef struct DisasContext {
enum {
BS_NONE = 0, /* We go out of the TB without reaching a branch or an
* exception condition
*/
* exception condition */
BS_STOP = 1, /* We want to stop translation for any reason */
BS_BRANCH = 2, /* We reached a branch condition */
BS_EXCP = 3, /* We reached an exception condition */
@ -823,33 +822,6 @@ static inline void gen_save_pc(target_ulong pc)
tcg_temp_free(r_tmp);
}
static inline void gen_breg_pc(void)
{
TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, active_tc.PC));
tcg_temp_free(r_tmp);
}
static inline void gen_save_btarget(target_ulong btarget)
{
TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
tcg_gen_movi_tl(r_tmp, btarget);
tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
tcg_temp_free(r_tmp);
}
static always_inline void gen_save_breg_target(int reg)
{
TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
gen_load_gpr(r_tmp, reg);
tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
tcg_temp_free(r_tmp);
}
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
{
#if defined MIPS_DEBUG_DISAS
@ -875,7 +847,7 @@ static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
case MIPS_HFLAG_BC:
case MIPS_HFLAG_BL:
case MIPS_HFLAG_B:
gen_save_btarget(ctx->btarget);
tcg_gen_movi_tl(btarget, ctx->btarget);
break;
}
}
@ -2505,7 +2477,7 @@ static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong des
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
int rs, int rt, int32_t offset)
{
target_ulong btarget = -1;
target_ulong btgt = -1;
int blink = 0;
int bcond = 0;
TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
@ -2535,7 +2507,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
gen_load_gpr(t1, rt);
bcond = 1;
}
btarget = ctx->pc + 4 + offset;
btgt = ctx->pc + 4 + offset;
break;
case OPC_BGEZ:
case OPC_BGEZAL:
@ -2554,12 +2526,12 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
gen_load_gpr(t0, rs);
bcond = 1;
}
btarget = ctx->pc + 4 + offset;
btgt = ctx->pc + 4 + offset;
break;
case OPC_J:
case OPC_JAL:
/* Jump to immediate */
btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
break;
case OPC_JR:
case OPC_JALR:
@ -2571,7 +2543,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
generate_exception(ctx, EXCP_RI);
goto out;
}
gen_save_breg_target(rs);
gen_load_gpr(btarget, rs);
break;
default:
MIPS_INVAL("branch/jump");
@ -2625,12 +2597,12 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
goto out;
case OPC_J:
ctx->hflags |= MIPS_HFLAG_B;
MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
break;
case OPC_JAL:
blink = 31;
ctx->hflags |= MIPS_HFLAG_B;
MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
break;
case OPC_JR:
ctx->hflags |= MIPS_HFLAG_BR;
@ -2651,80 +2623,80 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
case OPC_BEQ:
gen_op_eq(t0, t1);
MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
regnames[rs], regnames[rt], btarget);
regnames[rs], regnames[rt], btgt);
goto not_likely;
case OPC_BEQL:
gen_op_eq(t0, t1);
MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
regnames[rs], regnames[rt], btarget);
regnames[rs], regnames[rt], btgt);
goto likely;
case OPC_BNE:
gen_op_ne(t0, t1);
MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
regnames[rs], regnames[rt], btarget);
regnames[rs], regnames[rt], btgt);
goto not_likely;
case OPC_BNEL:
gen_op_ne(t0, t1);
MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
regnames[rs], regnames[rt], btarget);
regnames[rs], regnames[rt], btgt);
goto likely;
case OPC_BGEZ:
gen_op_gez(t0);
MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto not_likely;
case OPC_BGEZL:
gen_op_gez(t0);
MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto likely;
case OPC_BGEZAL:
gen_op_gez(t0);
MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
blink = 31;
goto not_likely;
case OPC_BGEZALL:
gen_op_gez(t0);
blink = 31;
MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto likely;
case OPC_BGTZ:
gen_op_gtz(t0);
MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto not_likely;
case OPC_BGTZL:
gen_op_gtz(t0);
MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto likely;
case OPC_BLEZ:
gen_op_lez(t0);
MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto not_likely;
case OPC_BLEZL:
gen_op_lez(t0);
MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto likely;
case OPC_BLTZ:
gen_op_ltz(t0);
MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto not_likely;
case OPC_BLTZL:
gen_op_ltz(t0);
MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto likely;
case OPC_BLTZAL:
gen_op_ltz(t0);
blink = 31;
MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
not_likely:
ctx->hflags |= MIPS_HFLAG_BC;
tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond));
tcg_gen_trunc_tl_i32(bcond, t0);
break;
case OPC_BLTZALL:
gen_op_ltz(t0);
blink = 31;
MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
likely:
ctx->hflags |= MIPS_HFLAG_BL;
tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond));
tcg_gen_trunc_tl_i32(bcond, t0);
break;
default:
MIPS_INVAL("conditional branch/jump");
@ -2733,9 +2705,9 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
}
}
MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
blink, ctx->hflags, btarget);
blink, ctx->hflags, btgt);
ctx->btarget = btarget;
ctx->btarget = btgt;
if (blink > 0) {
tcg_gen_movi_tl(t0, ctx->pc + 8);
gen_store_gpr(t0, blink);
@ -5789,7 +5761,7 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
opn = "bc1tl";
likely:
ctx->hflags |= MIPS_HFLAG_BL;
tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond));
tcg_gen_trunc_tl_i32(bcond, t0);
break;
case OPC_BC1FANY2:
{
@ -5874,7 +5846,7 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
opn = "bc1any4t";
not_likely:
ctx->hflags |= MIPS_HFLAG_BC;
tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond));
tcg_gen_trunc_tl_i32(bcond, t0);
break;
default:
MIPS_INVAL(opn);
@ -7209,19 +7181,16 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
/* Handle blikely not taken case */
if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);
int l1 = gen_new_label();
MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
tcg_temp_free(r_tmp);
tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
{
TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
tcg_gen_movi_i32(r_tmp2, ctx->hflags & ~MIPS_HFLAG_BMASK);
tcg_gen_st_i32(r_tmp2, cpu_env, offsetof(CPUState, hflags));
tcg_temp_free(r_tmp2);
tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
tcg_temp_free(r_tmp);
}
gen_goto_tb(ctx, 1, ctx->pc + 4);
gen_set_label(l1);
@ -7818,12 +7787,9 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
/* Conditional branch */
MIPS_DEBUG("conditional branch");
{
TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);
int l1 = gen_new_label();
tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
tcg_temp_free(r_tmp);
tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
gen_goto_tb(ctx, 1, ctx->pc + 4);
gen_set_label(l1);
gen_goto_tb(ctx, 0, ctx->btarget);
@ -7832,7 +7798,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
case MIPS_HFLAG_BR:
/* unconditional branch to register */
MIPS_DEBUG("branch to register");
gen_breg_pc();
tcg_gen_st_tl(btarget, cpu_env, offsetof(CPUState, active_tc.PC));
tcg_gen_exit_tb(0);
break;
default:
@ -8125,6 +8091,10 @@ static void mips_tcg_init(void)
return;
cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
bcond = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
offsetof(CPUState, bcond), "bcond");
btarget = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
offsetof(CPUState, btarget), "btarget");
current_fpu = tcg_global_mem_new(TCG_TYPE_PTR,
TCG_AREG0,
offsetof(CPUState, fpu),