aboutsummaryrefslogtreecommitdiff
path: root/target-microblaze
diff options
context:
space:
mode:
authorEdgar E. Iglesias <edgar.iglesias@petalogix.com>2010-07-24 21:24:59 +0200
committerEdgar E. Iglesias <edgar.iglesias@gmail.com>2010-07-24 21:24:59 +0200
commit61204ce8ec39bd59d4107466ef608787e117119f (patch)
tree5f6088c5c19ff28343a55d39b469ea6d72574e2d /target-microblaze
parent04906034f59b1a842da98636c0f7d4d7c151717c (diff)
microblaze: Improve branch with small immediates
Slight improvements of conditional branches with small immediate offsets. Signed-off-by: Edgar E. Iglesias <edgar.iglesias@petalogix.com>
Diffstat (limited to 'target-microblaze')
-rw-r--r--target-microblaze/translate.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index ca54e2c30e..5d2a0e6dee 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -153,6 +153,14 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
}
}
+/* True if ALU operand b is a small immediate that may deserve
+ faster treatment. */
+static inline int dec_alu_op_b_is_small_imm(DisasContext *dc)
+{
+ /* Immediate insn without the imm prefix ? */
+ return dc->type_b && !(dc->tb_flags & IMM_FLAG);
+}
+
static inline TCGv *dec_alu_op_b(DisasContext *dc)
{
if (dc->type_b) {
@@ -984,10 +992,16 @@ static void dec_bcc(DisasContext *dc)
cpu_env, offsetof(CPUState, bimm));
}
- tcg_gen_movi_tl(env_btarget, dc->pc);
- tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
- eval_cc(dc, cc, env_btaken, cpu_R[dc->ra], tcg_const_tl(0));
+ if (dec_alu_op_b_is_small_imm(dc)) {
+ int32_t offset = (int32_t)((int16_t)dc->imm); /* sign-extend. */
+
+ tcg_gen_movi_tl(env_btarget, dc->pc + offset);
+ } else {
+ tcg_gen_movi_tl(env_btarget, dc->pc);
+ tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
+ }
dc->jmp = JMP_INDIRECT;
+ eval_cc(dc, cc, env_btaken, cpu_R[dc->ra], tcg_const_tl(0));
}
static void dec_br(DisasContext *dc)
@@ -1031,13 +1045,13 @@ static void dec_br(DisasContext *dc)
}
}
} else {
- if (!dc->type_b || (dc->tb_flags & IMM_FLAG)) {
+ if (dec_alu_op_b_is_small_imm(dc)) {
+ dc->jmp = JMP_DIRECT;
+ dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm);
+ } else {
tcg_gen_movi_tl(env_btaken, 1);
tcg_gen_movi_tl(env_btarget, dc->pc);
tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
- } else {
- dc->jmp = JMP_DIRECT;
- dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm);
}
}
}