Skip to content

Commit

Permalink
target/i386: [tcg] Port to translate_insn
Browse files Browse the repository at this point in the history
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Emilio G. Cota <cota@braap.org>
Message-Id: <150002195074.22386.16195894320027075398.stgit@frigg.lan>
Signed-off-by: Richard Henderson <rth@twiddle.net>
  • Loading branch information
Lluís Vilanova authored and rth7680 committed Sep 6, 2017
1 parent e6b41ec commit 2c2f8ca
Showing 1 changed file with 42 additions and 24 deletions.
66 changes: 42 additions & 24 deletions target/i386/translate.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 2c2f8ca

Please sign in to comment.