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_t0; | ||||
|     MMXReg mmx_t0; | ||||
|     target_ulong cc_tmp; /* temporary for rcr/rcl */ | ||||
| 
 | ||||
|     /* sysenter registers */ | ||||
|     uint32_t sysenter_cs; | ||||
|  | ||||
| @ -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; | ||||
| } | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Paolo Bonzini
						Paolo Bonzini