diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2012-10-06 00:18:55 +0200 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2013-02-18 15:03:56 -0800 |
commit | f5847c912d62d60a9917ed1e88cd6d4548fd40f3 (patch) | |
tree | dbe0eaca71459a4b66143b1de77e27341f732a45 /target-i386 | |
parent | 0ff6addd92979b9759efa1c0945526e6ac78ce5b (diff) | |
download | qemu-f5847c912d62d60a9917ed1e88cd6d4548fd40f3.tar.gz qemu-f5847c912d62d60a9917ed1e88cd6d4548fd40f3.tar.bz2 qemu-f5847c912d62d60a9917ed1e88cd6d4548fd40f3.zip |
target-i386: compute eflags outside rcl/rcr helper
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>
Diffstat (limited to 'target-i386')
-rw-r--r-- | target-i386/cpu.h | 1 | ||||
-rw-r--r-- | target-i386/shift_helper_template.h | 12 | ||||
-rw-r--r-- | target-i386/translate.c | 20 |
3 files changed, 8 insertions, 25 deletions
diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 7577e4f8bb..cd35cd52c0 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 dda0da30cf..cf91a2d284 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 0970954217..80483c0ffd 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, |