提交 2c2f8cac 编写于 作者: L Lluís Vilanova 提交者: Richard Henderson

target/i386: [tcg] Port to translate_insn

Incrementally paves the way towards using the generic instruction translation
loop.
Signed-off-by: NLluís Vilanova <vilanova@ac.upc.edu>
Reviewed-by: NRichard Henderson <rth@twiddle.net>
Reviewed-by: NEmilio G. Cota <cota@braap.org>
Message-Id: <150002195074.22386.16195894320027075398.stgit@frigg.lan>
Signed-off-by: NRichard Henderson <rth@twiddle.net>
上级 e6b41ec3
......@@ -4417,15 +4417,16 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
/* convert one instruction. s->base.is_jmp is set if the translation must
be stopped. Return the next pc value */
static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
target_ulong pc_start)
static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
{
CPUX86State *env = cpu->env_ptr;
int b, prefixes;
int shift;
TCGMemOp ot, aflag, dflag;
int modrm, reg, rm, mod, op, opreg, val;
target_ulong next_eip, tval;
int rex_w, rex_r;
target_ulong pc_start = s->base.pc_next;
s->pc_start = s->pc = pc_start;
prefixes = 0;
......@@ -8476,10 +8477,46 @@ static bool i386_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
}
}
static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
target_ulong pc_next = disas_insn(dc, cpu);
if (dc->tf || (dc->base.tb->flags & HF_INHIBIT_IRQ_MASK)) {
/* if single step mode, we generate only one instruction and
generate an exception */
/* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
the flag and abort the translation to give the irqs a
chance to happen */
gen_jmp_im(pc_next - dc->cs_base);
gen_eob(dc);
dc->base.is_jmp = DISAS_TOO_MANY;
} else if ((dc->base.tb->cflags & CF_USE_ICOUNT)
&& ((dc->base.pc_next & TARGET_PAGE_MASK)
!= ((dc->base.pc_next + TARGET_MAX_INSN_SIZE - 1)
& TARGET_PAGE_MASK)
|| (dc->base.pc_next & ~TARGET_PAGE_MASK) == 0)) {
/* Do not cross the boundary of the pages in icount mode,
it can cause an exception. Do it only when boundary is
crossed by the first instruction in the block.
If current instruction already crossed the bound - it's ok,
because an exception hasn't stopped this code.
*/
gen_jmp_im(pc_next - dc->cs_base);
gen_eob(dc);
dc->base.is_jmp = DISAS_TOO_MANY;
} else if ((pc_next - dc->base.pc_first) >= (TARGET_PAGE_SIZE - 32)) {
gen_jmp_im(pc_next - dc->cs_base);
gen_eob(dc);
dc->base.is_jmp = DISAS_TOO_MANY;
}
dc->base.pc_next = pc_next;
}
/* generate intermediate code for basic block 'tb'. */
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
{
CPUX86State *env = cs->env_ptr;
DisasContext dc1, *dc = &dc1;
int num_insns;
int max_insns;
......@@ -8525,39 +8562,20 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
gen_io_start();
}
dc->base.pc_next = disas_insn(env, dc, dc->base.pc_next);
i386_tr_translate_insn(&dc->base, cs);
/* stop translation if indicated */
if (dc->base.is_jmp) {
break;
}
/* if single step mode, we generate only one instruction and
generate an exception */
/* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
the flag and abort the translation to give the irqs a
change to be happen */
if (dc->tf || dc->base.singlestep_enabled ||
(dc->base.tb->flags & HF_INHIBIT_IRQ_MASK)) {
gen_jmp_im(dc->base.pc_next - dc->cs_base);
gen_eob(dc);
break;
}
/* Do not cross the boundary of the pages in icount mode,
it can cause an exception. Do it only when boundary is
crossed by the first instruction in the block.
If current instruction already crossed the bound - it's ok,
because an exception hasn't stopped this code.
*/
if ((tb->cflags & CF_USE_ICOUNT)
&& ((dc->base.pc_next & TARGET_PAGE_MASK)
!= ((dc->base.pc_next + TARGET_MAX_INSN_SIZE - 1) & TARGET_PAGE_MASK)
|| (dc->base.pc_next & ~TARGET_PAGE_MASK) == 0)) {
if (dc->base.singlestep_enabled) {
gen_jmp_im(dc->base.pc_next - dc->cs_base);
gen_eob(dc);
break;
}
/* if too long translation, stop generation too */
if (tcg_op_buf_full() ||
(dc->base.pc_next - dc->base.pc_first) >= (TARGET_PAGE_SIZE - 32) ||
num_insns >= max_insns) {
gen_jmp_im(dc->base.pc_next - dc->cs_base);
gen_eob(dc);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册