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>
This commit is contained in:
Sebastian Macke 2013-10-22 02:12:37 +02:00 committed by Jia Liu
parent 394cfa39ba
commit 352367e8bb

View file

@ -904,29 +904,33 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
case 0x27: /* l.addi */ case 0x27: /* l.addi */
LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16); LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16);
{ {
int lab = gen_new_label(); if (I16 == 0) {
TCGv_i64 ta = tcg_temp_new_i64(); tcg_gen_mov_tl(cpu_R[rd], cpu_R[ra]);
TCGv_i64 td = tcg_temp_local_new_i64(); } else {
TCGv_i32 res = tcg_temp_local_new_i32(); int lab = gen_new_label();
TCGv_i32 sr_ove = tcg_temp_local_new_i32(); TCGv_i64 ta = tcg_temp_new_i64();
tcg_gen_extu_i32_i64(ta, cpu_R[ra]); TCGv_i64 td = tcg_temp_local_new_i64();
tcg_gen_addi_i64(td, ta, sign_extend(I16, 16)); TCGv_i32 res = tcg_temp_local_new_i32();
tcg_gen_trunc_i64_i32(res, td); TCGv_i32 sr_ove = tcg_temp_local_new_i32();
tcg_gen_shri_i64(td, td, 32); tcg_gen_extu_i32_i64(ta, cpu_R[ra]);
tcg_gen_andi_i64(td, td, 0x3); tcg_gen_addi_i64(td, ta, sign_extend(I16, 16));
/* Jump to lab when no overflow. */ tcg_gen_trunc_i64_i32(res, td);
tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); tcg_gen_shri_i64(td, td, 32);
tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); tcg_gen_andi_i64(td, td, 0x3);
tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); /* Jump to lab when no overflow. */
tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);
tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);
gen_exception(dc, EXCP_RANGE); tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));
gen_set_label(lab); tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);
tcg_gen_mov_i32(cpu_R[rd], res); tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);
tcg_temp_free_i64(ta); gen_exception(dc, EXCP_RANGE);
tcg_temp_free_i64(td); gen_set_label(lab);
tcg_temp_free_i32(res); tcg_gen_mov_i32(cpu_R[rd], res);
tcg_temp_free_i32(sr_ove); tcg_temp_free_i64(ta);
tcg_temp_free_i64(td);
tcg_temp_free_i32(res);
tcg_temp_free_i32(sr_ove);
}
} }
break; break;