diff options
Diffstat (limited to 'target-cris/translate.c')
-rw-r--r-- | target-cris/translate.c | 48 |
1 files changed, 23 insertions, 25 deletions
diff --git a/target-cris/translate.c b/target-cris/translate.c index 4e4606cb25..5184155302 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -577,20 +577,15 @@ static inline void t_gen_swapr(TCGv d, TCGv s) static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false) { - TCGv btaken; int l1; l1 = gen_new_label(); - btaken = tcg_temp_new(); /* Conditional jmp. */ - tcg_gen_mov_tl(btaken, env_btaken); tcg_gen_mov_tl(env_pc, pc_false); - tcg_gen_brcondi_tl(TCG_COND_EQ, btaken, 0, l1); + tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1); tcg_gen_mov_tl(env_pc, pc_true); gen_set_label(l1); - - tcg_temp_free(btaken); } static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) @@ -1134,7 +1129,7 @@ static void cris_store_direct_jmp(DisasContext *dc) /* Store the direct jmp state into the cpu-state. */ if (dc->jmp == JMP_DIRECT) { tcg_gen_movi_tl(env_btarget, dc->jmp_pc); - tcg_gen_movi_tl(env_btaken, 1); + dc->jmp = JMP_INDIRECT; } } @@ -1144,17 +1139,11 @@ static void cris_prepare_cc_branch (DisasContext *dc, /* This helps us re-schedule the micro-code to insns in delay-slots before the actual jump. */ dc->delayed_branch = 2; + dc->jmp = JMP_DIRECT; dc->jmp_pc = dc->pc + offset; - if (cond != CC_A) - { - dc->jmp = JMP_INDIRECT; - gen_tst_cc (dc, env_btaken, cond); - tcg_gen_movi_tl(env_btarget, dc->jmp_pc); - } else { - /* Allow chaining. */ - dc->jmp = JMP_DIRECT; - } + gen_tst_cc (dc, env_btaken, cond); + tcg_gen_movi_tl(env_btarget, dc->jmp_pc); } @@ -1166,8 +1155,7 @@ static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type) before the actual jump. */ dc->delayed_branch = 2; dc->jmp = type; - if (type == JMP_INDIRECT) - tcg_gen_movi_tl(env_btaken, 1); + tcg_gen_movi_tl(env_btaken, 1); } static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr) @@ -3320,8 +3308,24 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, if (tb->flags & 7) t_gen_mov_env_TN(dslot, tcg_const_tl(0)); + if (dc->cpustate_changed || !dc->flagx_known + || (dc->flags_x != (tb->flags & X_FLAG))) { + cris_store_direct_jmp(dc); + } if (dc->jmp == JMP_DIRECT) { - dc->is_jmp = DISAS_NEXT; + int l1; + + l1 = gen_new_label(); + cris_evaluate_flags(dc); + + /* Conditional jmp. */ + tcg_gen_brcondi_tl(TCG_COND_EQ, + env_btaken, 0, l1); + gen_goto_tb(dc, 1, dc->jmp_pc); + gen_set_label(l1); + gen_goto_tb(dc, 0, dc->pc); + dc->is_jmp = DISAS_TB_JUMP; + dc->jmp = JMP_NOJMP; } else { t_gen_cc_jmp(env_btarget, tcg_const_tl(dc->pc)); @@ -3341,16 +3345,10 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, && (dc->pc < next_page_start) && num_insns < max_insns); - if (dc->tb_flags != orig_flags) { - dc->cpustate_changed = 1; - } - if (dc->clear_locked_irq) t_gen_mov_env_TN(locked_irq, tcg_const_tl(0)); npc = dc->pc; - if (dc->jmp == JMP_DIRECT && !dc->delayed_branch) - npc = dc->jmp_pc; if (tb->cflags & CF_LAST_IO) gen_io_end(); |