From b709d15b13a2e26ed46b19e2cf30e597f5eba54e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 16 Feb 2018 00:46:58 -0500 Subject: [PATCH] target-sparc: Split out gen_branch_n Unify three copies of this code from different branch types. Fix the case when npc == DYNAMIC_PC, i.e. a branch within a delay slot. Backports commit 2bf2e019ed0a6349220620240c0ba807846793b9 from qemu --- qemu/target-sparc/translate.c | 57 ++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/qemu/target-sparc/translate.c b/qemu/target-sparc/translate.c index 9692cc19..3bab22ac 100644 --- a/qemu/target-sparc/translate.c +++ b/qemu/target-sparc/translate.c @@ -1038,6 +1038,33 @@ static void gen_branch_a(DisasContext *dc, target_ulong pc1) dc->is_br = 1; } +static void gen_branch_n(DisasContext *dc, target_ulong pc1) +{ + TCGContext *tcg_ctx = dc->uc->tcg_ctx; + target_ulong npc = dc->npc; + + if (likely(npc != DYNAMIC_PC)) { + dc->pc = npc; + dc->jump_pc[0] = pc1; + dc->jump_pc[1] = npc + 4; + dc->npc = JUMP_PC; + } else { + TCGv t, z; + + tcg_gen_mov_tl(tcg_ctx, *(TCGv *)tcg_ctx->sparc_cpu_pc, *(TCGv *)tcg_ctx->cpu_npc); + + tcg_gen_addi_tl(tcg_ctx, *(TCGv *)tcg_ctx->cpu_npc, *(TCGv *)tcg_ctx->cpu_npc, 4); + t = tcg_const_tl(tcg_ctx, pc1); + z = tcg_const_tl(tcg_ctx, 0); + tcg_gen_movcond_tl(tcg_ctx, TCG_COND_NE, *(TCGv *)tcg_ctx->cpu_npc, *(TCGv *)tcg_ctx->cpu_cond, z, t, *(TCGv *)tcg_ctx->cpu_npc); + tcg_temp_free(tcg_ctx, t); + tcg_temp_free(tcg_ctx, z); + + dc->pc = DYNAMIC_PC; + } +} + + static inline void gen_generic_branch(DisasContext *dc) { TCGContext *tcg_ctx = dc->uc->tcg_ctx; @@ -1481,15 +1508,7 @@ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc) if (a) { gen_branch_a(dc, target); } else { - dc->pc = dc->npc; - dc->jump_pc[0] = target; - if (unlikely(dc->npc == DYNAMIC_PC)) { - dc->jump_pc[1] = DYNAMIC_PC; - tcg_gen_addi_tl(tcg_ctx, *(TCGv *)tcg_ctx->sparc_cpu_pc, *(TCGv *)tcg_ctx->cpu_npc, 4); - } else { - dc->jump_pc[1] = dc->npc + 4; - dc->npc = JUMP_PC; - } + gen_branch_n(dc, target); } } } @@ -1530,15 +1549,7 @@ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc) if (a) { gen_branch_a(dc, target); } else { - dc->pc = dc->npc; - dc->jump_pc[0] = target; - if (unlikely(dc->npc == DYNAMIC_PC)) { - dc->jump_pc[1] = DYNAMIC_PC; - tcg_gen_addi_tl(tcg_ctx, *(TCGv *)tcg_ctx->sparc_cpu_pc, *(TCGv *)tcg_ctx->cpu_npc, 4); - } else { - dc->jump_pc[1] = dc->npc + 4; - dc->npc = JUMP_PC; - } + gen_branch_n(dc, target); } } } @@ -1559,15 +1570,7 @@ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn, if (a) { gen_branch_a(dc, target); } else { - dc->pc = dc->npc; - dc->jump_pc[0] = target; - if (unlikely(dc->npc == DYNAMIC_PC)) { - dc->jump_pc[1] = DYNAMIC_PC; - tcg_gen_addi_tl(tcg_ctx, *(TCGv *)tcg_ctx->sparc_cpu_pc, *(TCGv *)tcg_ctx->cpu_npc, 4); - } else { - dc->jump_pc[1] = dc->npc + 4; - dc->npc = JUMP_PC; - } + gen_branch_n(dc, target); } }