mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-15 22:21:57 -06:00
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
1 changed files with 27 additions and 0 deletions
|
@ -171,6 +171,7 @@ typedef struct DisasContext {
|
||||||
target_ulong jump_pc[2];
|
target_ulong jump_pc[2];
|
||||||
|
|
||||||
int mem_idx;
|
int mem_idx;
|
||||||
|
bool cpu_cond_live;
|
||||||
bool fpu_enabled;
|
bool fpu_enabled;
|
||||||
bool address_mask_32bit;
|
bool address_mask_32bit;
|
||||||
#ifndef CONFIG_USER_ONLY
|
#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);
|
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)
|
static void gen_generic_branch(DisasContext *dc)
|
||||||
{
|
{
|
||||||
TCGv npc0 = tcg_constant_tl(dc->jump_pc[0]);
|
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)
|
static void gen_exception(DisasContext *dc, int which)
|
||||||
{
|
{
|
||||||
|
finishing_insn(dc);
|
||||||
save_state(dc);
|
save_state(dc);
|
||||||
gen_helper_raise_exception(tcg_env, tcg_constant_i32(which));
|
gen_helper_raise_exception(tcg_env, tcg_constant_i32(which));
|
||||||
dc->base.is_jmp = DISAS_NORETURN;
|
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)
|
static void gen_mov_pc_npc(DisasContext *dc)
|
||||||
{
|
{
|
||||||
|
finishing_insn(dc);
|
||||||
|
|
||||||
if (dc->npc & 3) {
|
if (dc->npc & 3) {
|
||||||
switch (dc->npc) {
|
switch (dc->npc) {
|
||||||
case JUMP_PC:
|
case JUMP_PC:
|
||||||
|
@ -2339,6 +2356,8 @@ static bool advance_pc(DisasContext *dc)
|
||||||
{
|
{
|
||||||
TCGLabel *l1;
|
TCGLabel *l1;
|
||||||
|
|
||||||
|
finishing_insn(dc);
|
||||||
|
|
||||||
if (dc->npc & 3) {
|
if (dc->npc & 3) {
|
||||||
switch (dc->npc) {
|
switch (dc->npc) {
|
||||||
case DYNAMIC_PC:
|
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 dest = address_mask_i(dc, dc->pc + disp * 4);
|
||||||
target_ulong npc;
|
target_ulong npc;
|
||||||
|
|
||||||
|
finishing_insn(dc);
|
||||||
|
|
||||||
if (cmp->cond == TCG_COND_ALWAYS) {
|
if (cmp->cond == TCG_COND_ALWAYS) {
|
||||||
if (annul) {
|
if (annul) {
|
||||||
dc->pc = dest;
|
dc->pc = dest;
|
||||||
|
@ -2449,6 +2470,7 @@ static bool advance_jump_cond(DisasContext *dc, DisasCompare *cmp,
|
||||||
} else {
|
} else {
|
||||||
tcg_gen_setcondi_tl(cmp->cond, cpu_cond, cmp->c1, cmp->c2);
|
tcg_gen_setcondi_tl(cmp->cond, cpu_cond, cmp->c1, cmp->c2);
|
||||||
}
|
}
|
||||||
|
dc->cpu_cond_live = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 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);
|
tcg_gen_addi_i32(trap, trap, TT_TRAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finishing_insn(dc);
|
||||||
|
|
||||||
/* Trap always. */
|
/* Trap always. */
|
||||||
if (cond == 8) {
|
if (cond == 8) {
|
||||||
save_state(dc);
|
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)
|
static void do_wrpowerdown(DisasContext *dc, TCGv src)
|
||||||
{
|
{
|
||||||
|
finishing_insn(dc);
|
||||||
save_state(dc);
|
save_state(dc);
|
||||||
gen_helper_power_down(tcg_env);
|
gen_helper_power_down(tcg_env);
|
||||||
}
|
}
|
||||||
|
@ -5080,6 +5105,8 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
|
||||||
DisasDelayException *e, *e_next;
|
DisasDelayException *e, *e_next;
|
||||||
bool may_lookup;
|
bool may_lookup;
|
||||||
|
|
||||||
|
finishing_insn(dc);
|
||||||
|
|
||||||
switch (dc->base.is_jmp) {
|
switch (dc->base.is_jmp) {
|
||||||
case DISAS_NEXT:
|
case DISAS_NEXT:
|
||||||
case DISAS_TOO_MANY:
|
case DISAS_TOO_MANY:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue