target/sparc: Discard cpu_cond at the end of each insn
If the insn raises no exceptions, there will be no path in which cpu_cond is used, and so the computation may be optimized away. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
533f042f14
commit
89527e3a75
@ -171,6 +171,7 @@ typedef struct DisasContext {
|
||||
target_ulong jump_pc[2];
|
||||
|
||||
int mem_idx;
|
||||
bool cpu_cond_live;
|
||||
bool fpu_enabled;
|
||||
bool address_mask_32bit;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
@ -912,6 +913,19 @@ static void gen_op_eval_fbo(TCGv dst, TCGv src, unsigned int fcc_offset)
|
||||
tcg_gen_xori_tl(dst, dst, 0x1);
|
||||
}
|
||||
|
||||
static void finishing_insn(DisasContext *dc)
|
||||
{
|
||||
/*
|
||||
* From here, there is no future path through an unwinding exception.
|
||||
* If the current insn cannot raise an exception, the computation of
|
||||
* cpu_cond may be able to be elided.
|
||||
*/
|
||||
if (dc->cpu_cond_live) {
|
||||
tcg_gen_discard_tl(cpu_cond);
|
||||
dc->cpu_cond_live = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_generic_branch(DisasContext *dc)
|
||||
{
|
||||
TCGv npc0 = tcg_constant_tl(dc->jump_pc[0]);
|
||||
@ -958,6 +972,7 @@ static void save_state(DisasContext *dc)
|
||||
|
||||
static void gen_exception(DisasContext *dc, int which)
|
||||
{
|
||||
finishing_insn(dc);
|
||||
save_state(dc);
|
||||
gen_helper_raise_exception(tcg_env, tcg_constant_i32(which));
|
||||
dc->base.is_jmp = DISAS_NORETURN;
|
||||
@ -999,6 +1014,8 @@ static void gen_check_align(DisasContext *dc, TCGv addr, int mask)
|
||||
|
||||
static void gen_mov_pc_npc(DisasContext *dc)
|
||||
{
|
||||
finishing_insn(dc);
|
||||
|
||||
if (dc->npc & 3) {
|
||||
switch (dc->npc) {
|
||||
case JUMP_PC:
|
||||
@ -2339,6 +2356,8 @@ static bool advance_pc(DisasContext *dc)
|
||||
{
|
||||
TCGLabel *l1;
|
||||
|
||||
finishing_insn(dc);
|
||||
|
||||
if (dc->npc & 3) {
|
||||
switch (dc->npc) {
|
||||
case DYNAMIC_PC:
|
||||
@ -2383,6 +2402,8 @@ static bool advance_jump_cond(DisasContext *dc, DisasCompare *cmp,
|
||||
target_ulong dest = address_mask_i(dc, dc->pc + disp * 4);
|
||||
target_ulong npc;
|
||||
|
||||
finishing_insn(dc);
|
||||
|
||||
if (cmp->cond == TCG_COND_ALWAYS) {
|
||||
if (annul) {
|
||||
dc->pc = dest;
|
||||
@ -2449,6 +2470,7 @@ static bool advance_jump_cond(DisasContext *dc, DisasCompare *cmp,
|
||||
} else {
|
||||
tcg_gen_setcondi_tl(cmp->cond, cpu_cond, cmp->c1, cmp->c2);
|
||||
}
|
||||
dc->cpu_cond_live = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -2585,6 +2607,8 @@ static bool do_tcc(DisasContext *dc, int cond, int cc,
|
||||
tcg_gen_addi_i32(trap, trap, TT_TRAP);
|
||||
}
|
||||
|
||||
finishing_insn(dc);
|
||||
|
||||
/* Trap always. */
|
||||
if (cond == 8) {
|
||||
save_state(dc);
|
||||
@ -3201,6 +3225,7 @@ TRANS(WRSTICK_CMPR, 64, do_wr_special, a, supervisor(dc), do_wrstick_cmpr)
|
||||
|
||||
static void do_wrpowerdown(DisasContext *dc, TCGv src)
|
||||
{
|
||||
finishing_insn(dc);
|
||||
save_state(dc);
|
||||
gen_helper_power_down(tcg_env);
|
||||
}
|
||||
@ -5080,6 +5105,8 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||
DisasDelayException *e, *e_next;
|
||||
bool may_lookup;
|
||||
|
||||
finishing_insn(dc);
|
||||
|
||||
switch (dc->base.is_jmp) {
|
||||
case DISAS_NEXT:
|
||||
case DISAS_TOO_MANY:
|
||||
|
Loading…
Reference in New Issue
Block a user