提交 c4d4525c 编写于 作者: P Pavel Dovgalyuk 提交者: Richard Henderson

target-i386: fix icount processing for repz instructions

TCG generates optimized code for i386 repz instructions in single step mode.
It means that when ecx becomes 0, execution of the string instruction breaks
immediately without an additional iteration for ecx==0 (which will only check
ecx and set the flags). Omitting this iteration leads to different
instructions counting in singlestep mode and in normal execution.
This patch disables optimization of this last iteration for icount mode
which should be deterministic.

v2: inverted the condition and formatted the comment
Signed-off-by: NPavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
Signed-off-by: NRichard Henderson <rth@twiddle.net>
上级 18b41f95
......@@ -115,6 +115,7 @@ typedef struct DisasContext {
int tf; /* TF cpu flag */
int singlestep_enabled; /* "hardware" single step enabled */
int jmp_opt; /* use direct block chaining for direct jumps */
int repz_opt; /* optimize jumps within repz instructions */
int mem_index; /* select memory access functions */
uint64_t flags; /* all execution flags */
struct TranslationBlock *tb;
......@@ -1215,7 +1216,7 @@ static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
gen_op_add_reg_im(s->aflag, R_ECX, -1); \
/* a loop would cause two single step exceptions if ECX = 1 \
before rep string_insn */ \
if (!s->jmp_opt) \
if (s->repz_opt) \
gen_op_jz_ecx(s->aflag, l2); \
gen_jmp(s, cur_eip); \
}
......@@ -1233,7 +1234,7 @@ static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
gen_op_add_reg_im(s->aflag, R_ECX, -1); \
gen_update_cc_op(s); \
gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
if (!s->jmp_opt) \
if (s->repz_opt) \
gen_op_jz_ecx(s->aflag, l2); \
gen_jmp(s, cur_eip); \
}
......@@ -7951,6 +7952,17 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
|| (flags & HF_SOFTMMU_MASK)
#endif
);
/* Do not optimize repz jumps at all in icount mode, because
rep movsS instructions are execured with different paths
in !repz_opt and repz_opt modes. The first one was used
always except single step mode. And this setting
disables jumps optimization and control paths become
equivalent in run and single step modes.
Now there will be no jump optimization for repz in
record/replay modes and there will always be an
additional step for ecx=0 when icount is enabled.
*/
dc->repz_opt = !dc->jmp_opt && !use_icount;
#if 0
/* check addseg logic */
if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册