mirror of https://github.com/xemu-project/xemu.git
target/i386: cpu_load_eflags already sets cc_op
No need to set it again at the end of the translation block, cc_op_dirty can be set to false. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
f6ac77eab6
commit
a0625efd4d
|
@ -1883,7 +1883,7 @@ static void gen_IRET(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||||
gen_helper_iret_protected(tcg_env, tcg_constant_i32(s->dflag - 1),
|
gen_helper_iret_protected(tcg_env, tcg_constant_i32(s->dflag - 1),
|
||||||
eip_next_i32(s));
|
eip_next_i32(s));
|
||||||
}
|
}
|
||||||
set_cc_op(s, CC_OP_EFLAGS);
|
assume_cc_op(s, CC_OP_EFLAGS);
|
||||||
s->base.is_jmp = DISAS_EOB_ONLY;
|
s->base.is_jmp = DISAS_EOB_ONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -309,7 +309,7 @@ static const uint8_t cc_op_live[CC_OP_NB] = {
|
||||||
[CC_OP_POPCNT] = USES_CC_SRC,
|
[CC_OP_POPCNT] = USES_CC_SRC,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void set_cc_op(DisasContext *s, CCOp op)
|
static void set_cc_op_1(DisasContext *s, CCOp op, bool dirty)
|
||||||
{
|
{
|
||||||
int dead;
|
int dead;
|
||||||
|
|
||||||
|
@ -332,20 +332,27 @@ static void set_cc_op(DisasContext *s, CCOp op)
|
||||||
tcg_gen_discard_tl(s->cc_srcT);
|
tcg_gen_discard_tl(s->cc_srcT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op == CC_OP_DYNAMIC) {
|
if (dirty && s->cc_op == CC_OP_DYNAMIC) {
|
||||||
/* The DYNAMIC setting is translator only, and should never be
|
tcg_gen_discard_i32(cpu_cc_op);
|
||||||
stored. Thus we always consider it clean. */
|
|
||||||
s->cc_op_dirty = false;
|
|
||||||
} else {
|
|
||||||
/* Discard any computed CC_OP value (see shifts). */
|
|
||||||
if (s->cc_op == CC_OP_DYNAMIC) {
|
|
||||||
tcg_gen_discard_i32(cpu_cc_op);
|
|
||||||
}
|
|
||||||
s->cc_op_dirty = true;
|
|
||||||
}
|
}
|
||||||
|
s->cc_op_dirty = dirty;
|
||||||
s->cc_op = op;
|
s->cc_op = op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_cc_op(DisasContext *s, CCOp op)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The DYNAMIC setting is translator only, everything else
|
||||||
|
* will be spilled later.
|
||||||
|
*/
|
||||||
|
set_cc_op_1(s, op, op != CC_OP_DYNAMIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void assume_cc_op(DisasContext *s, CCOp op)
|
||||||
|
{
|
||||||
|
set_cc_op_1(s, op, false);
|
||||||
|
}
|
||||||
|
|
||||||
static void gen_update_cc_op(DisasContext *s)
|
static void gen_update_cc_op(DisasContext *s)
|
||||||
{
|
{
|
||||||
if (s->cc_op_dirty) {
|
if (s->cc_op_dirty) {
|
||||||
|
@ -3554,6 +3561,10 @@ static void disas_insn_old(DisasContext *s, CPUState *cpu, int b)
|
||||||
gen_update_cc_op(s);
|
gen_update_cc_op(s);
|
||||||
gen_update_eip_cur(s);
|
gen_update_eip_cur(s);
|
||||||
gen_helper_syscall(tcg_env, cur_insn_len_i32(s));
|
gen_helper_syscall(tcg_env, cur_insn_len_i32(s));
|
||||||
|
/* condition codes are modified only in long mode */
|
||||||
|
if (LMA(s)) {
|
||||||
|
assume_cc_op(s, CC_OP_EFLAGS);
|
||||||
|
}
|
||||||
/* TF handling for the syscall insn is different. The TF bit is checked
|
/* TF handling for the syscall insn is different. The TF bit is checked
|
||||||
after the syscall insn completes. This allows #DB to not be
|
after the syscall insn completes. This allows #DB to not be
|
||||||
generated after one has entered CPL0 if TF is set in FMASK. */
|
generated after one has entered CPL0 if TF is set in FMASK. */
|
||||||
|
@ -3570,7 +3581,7 @@ static void disas_insn_old(DisasContext *s, CPUState *cpu, int b)
|
||||||
gen_helper_sysret(tcg_env, tcg_constant_i32(dflag - 1));
|
gen_helper_sysret(tcg_env, tcg_constant_i32(dflag - 1));
|
||||||
/* condition codes are modified only in long mode */
|
/* condition codes are modified only in long mode */
|
||||||
if (LMA(s)) {
|
if (LMA(s)) {
|
||||||
set_cc_op(s, CC_OP_EFLAGS);
|
assume_cc_op(s, CC_OP_EFLAGS);
|
||||||
}
|
}
|
||||||
/* TF handling for the sysret insn is different. The TF bit is
|
/* TF handling for the sysret insn is different. The TF bit is
|
||||||
checked after the sysret insn completes. This allows #DB to be
|
checked after the sysret insn completes. This allows #DB to be
|
||||||
|
@ -4489,7 +4500,7 @@ static void disas_insn_old(DisasContext *s, CPUState *cpu, int b)
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
#else
|
#else
|
||||||
gen_helper_rsm(tcg_env);
|
gen_helper_rsm(tcg_env);
|
||||||
set_cc_op(s, CC_OP_EFLAGS);
|
assume_cc_op(s, CC_OP_EFLAGS);
|
||||||
#endif /* CONFIG_USER_ONLY */
|
#endif /* CONFIG_USER_ONLY */
|
||||||
s->base.is_jmp = DISAS_EOB_ONLY;
|
s->base.is_jmp = DISAS_EOB_ONLY;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue