aboutsummaryrefslogtreecommitdiff
path: root/target/i386/translate.c
diff options
context:
space:
mode:
authorLluís Vilanova <vilanova@ac.upc.edu>2017-07-14 11:45:50 +0300
committerRichard Henderson <richard.henderson@linaro.org>2017-09-06 08:06:47 -0700
commit2c2f8cacd8cf4f67d6f1384b19d38f9a0a25878b (patch)
tree9a8fcf44d700d63c0a3a94fc07f867b9c98a6ef5 /target/i386/translate.c
parente6b41ec37f0a9742374dfdb90e662745969cd7ea (diff)
target/i386: [tcg] Port to translate_insn
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>
Diffstat (limited to 'target/i386/translate.c')
-rw-r--r--target/i386/translate.c66
1 files changed, 42 insertions, 24 deletions
diff --git a/target/i386/translate.c b/target/i386/translate.c
index 4d4083fe30..0f38896f17 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -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);