ARM load/store multiple instructions can be slightly optimized by loading the register offset constant into a variable outside the register loop and using the preloaded variable inside the loop instead of reloading the offset value to a temporary variable on each loop iteration. This causes less TCG ops to be generated for a ARM load/ store multiple instruction.
Signed-off-by: Juha Riihimäki <juha.riihim...@nokia.com> --- diff --git a/target-arm/translate.c b/target-arm/translate.c index e5a2881..bae1122 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -6852,6 +6852,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) } rn = (insn >> 16) & 0xf; addr = load_reg(s, rn); + tmp2 = tcg_const_i32(4); /* compute total size */ loaded_base = 0; @@ -6865,7 +6866,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) if (insn & (1 << 23)) { if (insn & (1 << 24)) { /* pre increment */ - tcg_gen_addi_i32(addr, addr, 4); + tcg_gen_add_i32(addr, addr, tmp2); } else { /* post increment */ } @@ -6918,7 +6919,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) j++; /* no need to add after the last transfer */ if (j != n) - tcg_gen_addi_i32(addr, addr, 4); + tcg_gen_add_i32(addr, addr, tmp2); } } if (insn & (1 << 21)) { @@ -6928,7 +6929,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) /* pre increment */ } else { /* post increment */ - tcg_gen_addi_i32(addr, addr, 4); + tcg_gen_add_i32(addr, addr, tmp2); } } else { if (insn & (1 << 24)) { @@ -6944,6 +6945,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) } else { dead_tmp(addr); } + tcg_temp_free_i32(tmp2); if (loaded_base) { store_reg(s, rn, loaded_var); }
translate.c.ldmstm.diff
Description: translate.c.ldmstm.diff