Patchwork [v3] target-arm: optimize arm load/store multiple ops

login
register
mail settings
Submitter Juha.Riihimaki@nokia.com
Date Oct. 27, 2009, 8:46 a.m.
Message ID <1256633172-10636-1-git-send-email-juha.riihimaki@nokia.com>
Download mbox | patch
Permalink /patch/36968/
State New
Headers show

Comments

Juha.Riihimaki@nokia.com - Oct. 27, 2009, 8:46 a.m.
From: Juha Riihimäki <juha.riihimaki@nokia.com>

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 if there are more than one register
accessed, otherwise the number of generated TCG ops is the same. This
patch has been revised to apply against the latest git where tmp2 is
already used inside the optimized loop so we use tmp3 for the new
temporary constant value.

Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com>
---
 target-arm/translate.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

Patch

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 1988cc6..24fb9d2 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6824,6 +6824,7 @@  static void disas_arm_insn(CPUState * env, DisasContext *s)
                 }
                 rn = (insn >> 16) & 0xf;
                 addr = load_reg(s, rn);
+                tmp3 = tcg_const_i32(4);
 
                 /* compute total size */
                 loaded_base = 0;
@@ -6837,7 +6838,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, tmp3);
                     } else {
                         /* post increment */
                     }
@@ -6890,7 +6891,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, tmp3);
                     }
                 }
                 if (insn & (1 << 21)) {
@@ -6900,7 +6901,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, tmp3);
                         }
                     } else {
                         if (insn & (1 << 24)) {
@@ -6916,6 +6917,7 @@  static void disas_arm_insn(CPUState * env, DisasContext *s)
                 } else {
                     dead_tmp(addr);
                 }
+                tcg_temp_free_i32(tmp3);
                 if (loaded_base) {
                     store_reg(s, rn, loaded_var);
                 }