aboutsummaryrefslogtreecommitdiff
path: root/target-microblaze
diff options
context:
space:
mode:
authorEdgar E. Iglesias <edgar.iglesias@petalogix.com>2011-01-14 12:30:26 +0100
committerEdgar E. Iglesias <edgar.iglesias@petalogix.com>2011-01-14 12:30:26 +0100
commit844bab604b4369f6ee84065756da0b1d7f915715 (patch)
tree1121d4cb911c285f17ee2a3de48c03843618f198 /target-microblaze
parentd03d11260ee2d55579e8b76116e35ccdf5031833 (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.c21
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);