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>
This commit is contained in:
		
							parent
							
								
									0ff6addd92
								
							
						
					
					
						commit
						f5847c912d
					
				@ -764,7 +764,6 @@ typedef struct CPUX86State {
 | 
				
			|||||||
    XMMReg xmm_regs[CPU_NB_REGS];
 | 
					    XMMReg xmm_regs[CPU_NB_REGS];
 | 
				
			||||||
    XMMReg xmm_t0;
 | 
					    XMMReg xmm_t0;
 | 
				
			||||||
    MMXReg mmx_t0;
 | 
					    MMXReg mmx_t0;
 | 
				
			||||||
    target_ulong cc_tmp; /* temporary for rcr/rcl */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* sysenter registers */
 | 
					    /* sysenter registers */
 | 
				
			||||||
    uint32_t sysenter_cs;
 | 
					    uint32_t sysenter_cs;
 | 
				
			||||||
 | 
				
			|||||||
@ -55,7 +55,7 @@ target_ulong glue(helper_rcl, SUFFIX)(CPUX86State *env, target_ulong t0,
 | 
				
			|||||||
    count = rclb_table[count];
 | 
					    count = rclb_table[count];
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    if (count) {
 | 
					    if (count) {
 | 
				
			||||||
        eflags = helper_cc_compute_all(env, CC_OP);
 | 
					        eflags = env->cc_src;
 | 
				
			||||||
        t0 &= DATA_MASK;
 | 
					        t0 &= DATA_MASK;
 | 
				
			||||||
        src = t0;
 | 
					        src = t0;
 | 
				
			||||||
        res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
 | 
					        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);
 | 
					            res |= t0 >> (DATA_BITS + 1 - count);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        t0 = res;
 | 
					        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) |
 | 
					            (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
 | 
				
			||||||
            ((src >> (DATA_BITS - count)) & CC_C);
 | 
					            ((src >> (DATA_BITS - count)) & CC_C);
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        env->cc_tmp = -1;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return t0;
 | 
					    return t0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -86,7 +84,7 @@ target_ulong glue(helper_rcr, SUFFIX)(CPUX86State *env, target_ulong t0,
 | 
				
			|||||||
    count = rclb_table[count];
 | 
					    count = rclb_table[count];
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    if (count) {
 | 
					    if (count) {
 | 
				
			||||||
        eflags = helper_cc_compute_all(env, CC_OP);
 | 
					        eflags = env->cc_src;
 | 
				
			||||||
        t0 &= DATA_MASK;
 | 
					        t0 &= DATA_MASK;
 | 
				
			||||||
        src = t0;
 | 
					        src = t0;
 | 
				
			||||||
        res = (t0 >> count) |
 | 
					        res = (t0 >> count) |
 | 
				
			||||||
@ -95,11 +93,9 @@ target_ulong glue(helper_rcr, SUFFIX)(CPUX86State *env, target_ulong t0,
 | 
				
			|||||||
            res |= t0 << (DATA_BITS + 1 - count);
 | 
					            res |= t0 << (DATA_BITS + 1 - count);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        t0 = res;
 | 
					        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) |
 | 
					            (lshift(src ^ t0, 11 - (DATA_BITS - 1)) & CC_O) |
 | 
				
			||||||
            ((src >> (count - 1)) & CC_C);
 | 
					            ((src >> (count - 1)) & CC_C);
 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        env->cc_tmp = -1;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return t0;
 | 
					    return t0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -51,7 +51,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* global register indexes */
 | 
					/* global register indexes */
 | 
				
			||||||
static TCGv_ptr cpu_env;
 | 
					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_i32 cpu_cc_op;
 | 
				
			||||||
static TCGv cpu_regs[CPU_NB_REGS];
 | 
					static TCGv cpu_regs[CPU_NB_REGS];
 | 
				
			||||||
/* local temps */
 | 
					/* 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, 
 | 
					static void gen_rotc_rm_T1(DisasContext *s, int ot, int op1, 
 | 
				
			||||||
                           int is_right)
 | 
					                           int is_right)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int label1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (s->cc_op != CC_OP_DYNAMIC)
 | 
					    if (s->cc_op != CC_OP_DYNAMIC)
 | 
				
			||||||
        gen_op_set_cc_op(s->cc_op);
 | 
					        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 */
 | 
					    /* load */
 | 
				
			||||||
    if (op1 == OR_TMP0)
 | 
					    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);
 | 
					        gen_op_st_T0_A0(ot + s->mem_index);
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        gen_op_mov_reg_T0(ot, op1);
 | 
					        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 */
 | 
					/* XXX: add faster immediate case */
 | 
				
			||||||
@ -7763,8 +7753,6 @@ void optimize_flags_init(void)
 | 
				
			|||||||
                                    "cc_src");
 | 
					                                    "cc_src");
 | 
				
			||||||
    cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst),
 | 
					    cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst),
 | 
				
			||||||
                                    "cc_dst");
 | 
					                                    "cc_dst");
 | 
				
			||||||
    cpu_cc_tmp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_tmp),
 | 
					 | 
				
			||||||
                                    "cc_tmp");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef TARGET_X86_64
 | 
					#ifdef TARGET_X86_64
 | 
				
			||||||
    cpu_regs[R_EAX] = tcg_global_mem_new_i64(TCG_AREG0,
 | 
					    cpu_regs[R_EAX] = tcg_global_mem_new_i64(TCG_AREG0,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user