Patchwork [41/57] target-i386: Make helper_cc_compute_{all, c} const

login
register
mail settings
Submitter Richard Henderson
Date Feb. 19, 2013, 5:40 p.m.
Message ID <1361295631-21316-42-git-send-email-rth@twiddle.net>
Download mbox | patch
Permalink /patch/221750/
State New
Headers show

Comments

Richard Henderson - Feb. 19, 2013, 5:40 p.m.
Pass the data in explicitly, rather than indirectly via env.
This avoids all sorts of unnecessary register spillage.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-i386/cc_helper.c | 12 ++++--------
 target-i386/helper.h    |  4 ++--
 target-i386/translate.c | 31 +++++++++++++++++++++++++++----
 3 files changed, 33 insertions(+), 14 deletions(-)

Patch

diff --git a/target-i386/cc_helper.c b/target-i386/cc_helper.c
index 61427dd..a5d8181 100644
--- a/target-i386/cc_helper.c
+++ b/target-i386/cc_helper.c
@@ -75,10 +75,8 @@  const uint8_t parity_table[256] = {
 
 #endif
 
-uint32_t helper_cc_compute_all(CPUX86State *env, int op)
+target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1, int op)
 {
-    target_ulong dst = CC_DST, src1 = CC_SRC;
-
     switch (op) {
     default: /* should never happen */
         return 0;
@@ -183,13 +181,11 @@  uint32_t helper_cc_compute_all(CPUX86State *env, int op)
 
 uint32_t cpu_cc_compute_all(CPUX86State *env, int op)
 {
-    return helper_cc_compute_all(env, op);
+    return helper_cc_compute_all(CC_DST, CC_SRC, op);
 }
 
-uint32_t helper_cc_compute_c(CPUX86State *env, int op)
+target_ulong helper_cc_compute_c(target_ulong dst, target_ulong src1, int op)
 {
-    target_ulong dst = CC_DST, src1 = CC_SRC;
-
     switch (op) {
     default: /* should never happen */
     case CC_OP_LOGICB:
@@ -281,7 +277,7 @@  target_ulong helper_read_eflags(CPUX86State *env)
 {
     uint32_t eflags;
 
-    eflags = helper_cc_compute_all(env, CC_OP);
+    eflags = cpu_cc_compute_all(env, CC_OP);
     eflags |= (DF & DF_MASK);
     eflags |= env->eflags & ~(VM_MASK | RF_MASK);
     return eflags;
diff --git a/target-i386/helper.h b/target-i386/helper.h
index 9ed720d..901ff73 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -1,7 +1,7 @@ 
 #include "exec/def-helper.h"
 
-DEF_HELPER_FLAGS_2(cc_compute_all, TCG_CALL_NO_SE, i32, env, int)
-DEF_HELPER_FLAGS_2(cc_compute_c, TCG_CALL_NO_SE, i32, env, int)
+DEF_HELPER_FLAGS_3(cc_compute_all, TCG_CALL_NO_RWG_SE, tl, tl, tl, int)
+DEF_HELPER_FLAGS_3(cc_compute_c, TCG_CALL_NO_RWG_SE, tl, tl, tl, int)
 
 DEF_HELPER_0(lock, void)
 DEF_HELPER_0(unlock, void)
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 31e3442..5235aff 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -882,13 +882,37 @@  static void gen_op_update_neg_cc(void)
 /* compute all eflags to cc_src */
 static void gen_compute_eflags(DisasContext *s)
 {
+    TCGv zero, dst, src1;
+    int live, dead;
+
     if (s->cc_op == CC_OP_EFLAGS) {
         return;
     }
+
+    TCGV_UNUSED(zero);
+    dst = cpu_cc_dst;
+    src1 = cpu_cc_src;
+
+    /* Take care to not read values that are not live.  */
+    live = cc_op_live[s->cc_op] & ~USES_CC_SRCT;
+    dead = live ^ (USES_CC_DST | USES_CC_SRC);
+    if (dead) {
+        zero = tcg_const_tl(0);
+        if (dead & USES_CC_DST) {
+            dst = zero;
+        }
+        if (dead & USES_CC_SRC) {
+            src1 = zero;
+        }
+    }
+
     gen_update_cc_op(s);
-    gen_helper_cc_compute_all(cpu_tmp2_i32, cpu_env, cpu_cc_op);
+    gen_helper_cc_compute_all(cpu_cc_src, dst, src1, cpu_cc_op);
     set_cc_op(s, CC_OP_EFLAGS);
-    tcg_gen_extu_i32_tl(cpu_cc_src, cpu_tmp2_i32);
+
+    if (dead) {
+        tcg_temp_free(zero);
+    }
 }
 
 typedef struct CCPrepare {
@@ -980,8 +1004,7 @@  static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)
        /* The need to compute only C from CC_OP_DYNAMIC is important
           in efficiently implementing e.g. INC at the start of a TB.  */
        gen_update_cc_op(s);
-       gen_helper_cc_compute_c(cpu_tmp2_i32, cpu_env, cpu_cc_op);
-       tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);
+       gen_helper_cc_compute_c(reg, cpu_cc_dst, cpu_cc_src, cpu_cc_op);
        return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,
                             .mask = -1, .no_setcond = true };
     }