Patchwork [09/57] target-i386: compute eflags outside rcl/rcr helper

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

Comments

Richard Henderson - Feb. 19, 2013, 5:39 p.m.
From: Paolo Bonzini <pbonzini@redhat.com>

Always compute EFLAGS first since it is needed whenever
the shift is non-zero, i.e. most of the time.  This makes it possible
to remove some writes of CC_OP_EFLAGS to cpu_cc_op and more importantly
removes cases where s->cc_op becomes CC_OP_DYNAMIC.  Also, we can
remove cc_tmp and just modify cc_src from within the helper.

Finally, always follow gen_compute_eflags(cpu_cc_src) by setting s->cc_op
and discarding cpu_cc_dst.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-i386/cpu.h                   |  1 -
 target-i386/shift_helper_template.h | 12 ++++--------
 target-i386/translate.c             | 20 ++++----------------
 3 files changed, 8 insertions(+), 25 deletions(-)

Patch

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 7577e4f..cd35cd5 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -764,7 +764,6 @@  typedef struct CPUX86State {
     XMMReg xmm_regs[CPU_NB_REGS];
     XMMReg xmm_t0;
     MMXReg mmx_t0;
-    target_ulong cc_tmp; /* temporary for rcr/rcl */
 
     /* sysenter registers */
     uint32_t sysenter_cs;
diff --git a/target-i386/shift_helper_template.h b/target-i386/shift_helper_template.h
index dda0da3..cf91a2d 100644
--- a/target-i386/shift_helper_template.h
+++ b/target-i386/shift_helper_template.h
@@ -55,7 +55,7 @@  target_ulong glue(helper_rcl, SUFFIX)(CPUX86State *env, target_ulong t0,
     count = rclb_table[count];
 #endif
     if (count) {
-        eflags = helper_cc_compute_all(env, CC_OP);
+        eflags = env->cc_src;
         t0 &= DATA_MASK;
         src = t0;
         res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
@@ -63,11 +63,9 @@  target_ulong glue(helper_rcl, SUFFIX)(CPUX86State *env, target_ulong t0,
             res |= t0 >> (DATA_BITS + 1 - count);
         }
         t0 = res;
-        env->cc_tmp = (eflags & ~(CC_C | CC_O)) |
+        env->cc_src = (eflags & ~(CC_C | CC_O)) |
             (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
             ((src >> (DATA_BITS - count)) & CC_C);
-    } else {
-        env->cc_tmp = -1;
     }
     return t0;
 }
@@ -86,7 +84,7 @@  target_ulong glue(helper_rcr, SUFFIX)(CPUX86State *env, target_ulong t0,
     count = rclb_table[count];
 #endif
     if (count) {
-        eflags = helper_cc_compute_all(env, CC_OP);
+        eflags = env->cc_src;
         t0 &= DATA_MASK;
         src = t0;
         res = (t0 >> count) |
@@ -95,11 +93,9 @@  target_ulong glue(helper_rcr, SUFFIX)(CPUX86State *env, target_ulong t0,
             res |= t0 << (DATA_BITS + 1 - count);
         }
         t0 = res;
-        env->cc_tmp = (eflags & ~(CC_C | CC_O)) |
+        env->cc_src = (eflags & ~(CC_C | CC_O)) |
             (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
             ((src >> (count - 1)) & CC_C);
-    } else {
-        env->cc_tmp = -1;
     }
     return t0;
 }
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 0970954..80483c0 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -51,7 +51,7 @@ 
 
 /* global register indexes */
 static TCGv_ptr cpu_env;
-static TCGv cpu_A0, cpu_cc_src, cpu_cc_dst, cpu_cc_tmp;
+static TCGv cpu_A0, cpu_cc_src, cpu_cc_dst;
 static TCGv_i32 cpu_cc_op;
 static TCGv cpu_regs[CPU_NB_REGS];
 /* local temps */
@@ -1706,10 +1706,11 @@  static void gen_rot_rm_im(DisasContext *s, int ot, int op1, int op2,
 static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 
                            int is_right)
 {
-    int label1;
-
     if (s->cc_op != CC_OP_DYNAMIC)
         gen_op_set_cc_op(s->cc_op);
+    gen_compute_eflags(cpu_cc_src);
+    tcg_gen_discard_tl(cpu_cc_dst);
+    s->cc_op = CC_OP_EFLAGS;
 
     /* load */
     if (op1 == OR_TMP0)
@@ -1757,17 +1758,6 @@  static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1,
         gen_op_st_T0_A0(ot + s->mem_index);
     else
         gen_op_mov_reg_T0(ot, op1);
-
-    /* update eflags */
-    label1 = gen_new_label();
-    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_tmp, -1, label1);
-
-    tcg_gen_mov_tl(cpu_cc_src, cpu_cc_tmp);
-    tcg_gen_discard_tl(cpu_cc_dst);
-    tcg_gen_movi_i32(cpu_cc_op, CC_OP_EFLAGS);
-        
-    gen_set_label(label1);
-    s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
 }
 
 /* XXX: add faster immediate case */
@@ -7763,8 +7753,6 @@  void optimize_flags_init(void)
                                     "cc_src");
     cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst),
                                     "cc_dst");
-    cpu_cc_tmp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_tmp),
-                                    "cc_tmp");
 
 #ifdef TARGET_X86_64
     cpu_regs[R_EAX] = tcg_global_mem_new_i64(TCG_AREG0,