diff options
author | Edgar E. Iglesias <edgar.iglesias@petalogix.com> | 2011-01-14 12:30:26 +0100 |
---|---|---|
committer | Edgar E. Iglesias <edgar.iglesias@petalogix.com> | 2011-01-14 12:30:26 +0100 |
commit | 844bab604b4369f6ee84065756da0b1d7f915715 (patch) | |
tree | 1121d4cb911c285f17ee2a3de48c03843618f198 /target-microblaze | |
parent | d03d11260ee2d55579e8b76116e35ccdf5031833 (diff) |
microblaze: Improve unconditional direct branching
Avoid emitting conditional tcg operations for uncoditional
direct branches.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@petalogix.com>
Diffstat (limited to 'target-microblaze')
-rw-r--r-- | target-microblaze/translate.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index c018c99826..2e236fb844 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -78,9 +78,10 @@ typedef struct DisasContext { unsigned int clear_imm; int is_jmp; -#define JMP_NOJMP 0 -#define JMP_DIRECT 1 -#define JMP_INDIRECT 2 +#define JMP_NOJMP 0 +#define JMP_DIRECT 1 +#define JMP_DIRECT_CC 2 +#define JMP_INDIRECT 3 unsigned int jmp; uint32_t jmp_pc; @@ -751,7 +752,10 @@ static void dec_bit(DisasContext *dc) static inline void sync_jmpstate(DisasContext *dc) { - if (dc->jmp == JMP_DIRECT) { + if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) { + if (dc->jmp == JMP_DIRECT) { + tcg_gen_movi_tl(env_btaken, 1); + } dc->jmp = JMP_INDIRECT; tcg_gen_movi_tl(env_btarget, dc->jmp_pc); } @@ -975,7 +979,7 @@ static void dec_bcc(DisasContext *dc) int32_t offset = (int32_t)((int16_t)dc->imm); /* sign-extend. */ tcg_gen_movi_tl(env_btarget, dc->pc + offset); - dc->jmp = JMP_DIRECT; + dc->jmp = JMP_DIRECT_CC; dc->jmp_pc = dc->pc + offset; } else { dc->jmp = JMP_INDIRECT; @@ -1029,7 +1033,6 @@ static void dec_br(DisasContext *dc) if (dec_alu_op_b_is_small_imm(dc)) { dc->jmp = JMP_DIRECT; dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm); - tcg_gen_movi_tl(env_btaken, 1); } else { tcg_gen_movi_tl(env_btaken, 1); tcg_gen_movi_tl(env_btarget, dc->pc); @@ -1451,6 +1454,10 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, eval_cond_jmp(dc, env_btarget, tcg_const_tl(dc->pc)); dc->is_jmp = DISAS_JUMP; } else if (dc->jmp == JMP_DIRECT) { + t_sync_flags(dc); + gen_goto_tb(dc, 0, dc->jmp_pc); + dc->is_jmp = DISAS_TB_JUMP; + } else if (dc->jmp == JMP_DIRECT_CC) { int l1; t_sync_flags(dc); @@ -1475,7 +1482,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, && num_insns < max_insns); npc = dc->pc; - if (dc->jmp == JMP_DIRECT) { + if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) { if (dc->tb_flags & D_FLAG) { dc->is_jmp = DISAS_UPDATE; tcg_gen_movi_tl(cpu_SR[SR_PC], npc); |