aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Macke <sebastian@macke.de>2013-10-22 02:12:37 +0200
committerJia Liu <proljc@gmail.com>2013-11-20 21:40:07 +0800
commit352367e8bb53bd4e16abaecbcb9fc0bcadf5881b (patch)
tree72023dae654c9d8d74fca9022c35edeb91ce4a22
parent394cfa39ba24dd838ace1308ae24961243947fb8 (diff)
target-openrisc: Speed up move instruction
The OpenRISC architecture does not have its own move register instruction. Instead it uses either "l.addi rd, r0, x" or "l.ori rd, rs, 0" or "l.or rd, rx, r0" The l.ori instruction is automatically optimized but not the l.addi instruction. This patch optimizes for this special case. Signed-off-by: Sebastian Macke <sebastian@macke.de> Reviewed-by: Jia Liu <proljc@gmail.com> Signed-off-by: Jia Liu <proljc@gmail.com>
-rw-r--r--target-openrisc/translate.c50
1 files changed, 27 insertions, 23 deletions
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 8908a2e32b..8276ce73a2 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -904,29 +904,33 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
case 0x27: /* l.addi */
LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16);
{
- int lab = gen_new_label();
- TCGv_i64 ta = tcg_temp_new_i64();
- TCGv_i64 td = tcg_temp_local_new_i64();
- TCGv_i32 res = tcg_temp_local_new_i32();
- TCGv_i32 sr_ove = tcg_temp_local_new_i32();
- tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
- tcg_gen_addi_i64(td, ta, sign_extend(I16, 16));
- tcg_gen_trunc_i64_i32(res, td);
- tcg_gen_shri_i64(td, td, 32);
- tcg_gen_andi_i64(td, td, 0x3);
- /* Jump to lab when no overflow. */
- tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
- tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
- tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
- tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
- tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
- gen_exception(dc, EXCP_RANGE);
- gen_set_label(lab);
- tcg_gen_mov_i32(cpu_R[rd], res);
- tcg_temp_free_i64(ta);
- tcg_temp_free_i64(td);
- tcg_temp_free_i32(res);
- tcg_temp_free_i32(sr_ove);
+ if (I16 == 0) {
+ tcg_gen_mov_tl(cpu_R[rd], cpu_R[ra]);
+ } else {
+ int lab = gen_new_label();
+ TCGv_i64 ta = tcg_temp_new_i64();
+ TCGv_i64 td = tcg_temp_local_new_i64();
+ TCGv_i32 res = tcg_temp_local_new_i32();
+ TCGv_i32 sr_ove = tcg_temp_local_new_i32();
+ tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
+ tcg_gen_addi_i64(td, ta, sign_extend(I16, 16));
+ tcg_gen_trunc_i64_i32(res, td);
+ tcg_gen_shri_i64(td, td, 32);
+ tcg_gen_andi_i64(td, td, 0x3);
+ /* Jump to lab when no overflow. */
+ tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
+ tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
+ tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
+ tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
+ tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
+ gen_exception(dc, EXCP_RANGE);
+ gen_set_label(lab);
+ tcg_gen_mov_i32(cpu_R[rd], res);
+ tcg_temp_free_i64(ta);
+ tcg_temp_free_i64(td);
+ tcg_temp_free_i32(res);
+ tcg_temp_free_i32(sr_ove);
+ }
}
break;