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

View File

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