* [PATCH v2 01/23] target/i386: Remove pc_start
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 11:49 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 02/23] target/i386: Return bool from disas_insn Richard Henderson
` (22 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
The DisasContext member and the disas_insn local variable of
the same name are identical to DisasContextBase.pc_next.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 114 +++++++++++++++++++-----------------
1 file changed, 60 insertions(+), 54 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index d6420df31d..1e24bb2985 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -76,7 +76,6 @@ typedef struct DisasContext {
DisasContextBase base;
target_ulong pc; /* pc = eip + cs_base */
- target_ulong pc_start; /* pc at TB entry */
target_ulong cs_base; /* base of CS segment */
MemOp aflag;
@@ -1345,13 +1344,13 @@ static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
the instruction is known, but it isn't allowed in the current cpu mode. */
static void gen_illegal_opcode(DisasContext *s)
{
- gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
+ gen_exception(s, EXCP06_ILLOP, s->base.pc_next - s->cs_base);
}
/* Generate #GP for the current instruction. */
static void gen_exception_gpf(DisasContext *s)
{
- gen_exception(s, EXCP0D_GPF, s->pc_start - s->cs_base);
+ gen_exception(s, EXCP0D_GPF, s->base.pc_next - s->cs_base);
}
/* Check for cpl == 0; if not, raise #GP and return false. */
@@ -2016,7 +2015,7 @@ static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
}
s->pc += num_bytes;
- if (unlikely(s->pc - s->pc_start > X86_MAX_INSN_LENGTH)) {
+ if (unlikely(s->pc - s->base.pc_next > X86_MAX_INSN_LENGTH)) {
/* If the instruction's 16th byte is on a different page than the 1st, a
* page fault on the second page wins over the general protection fault
* caused by the instruction being too long.
@@ -2589,7 +2588,7 @@ static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
if (qemu_loglevel_mask(LOG_UNIMP)) {
FILE *logfile = qemu_log_trylock();
if (logfile) {
- target_ulong pc = s->pc_start, end = s->pc;
+ target_ulong pc = s->base.pc_next, end = s->pc;
fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc);
for (; pc < end; ++pc) {
@@ -3199,8 +3198,7 @@ static const struct SSEOpHelper_table7 sse_op_table7[256] = {
goto illegal_op; \
} while (0)
-static void gen_sse(CPUX86State *env, DisasContext *s, int b,
- target_ulong pc_start)
+static void gen_sse(CPUX86State *env, DisasContext *s, int b)
{
int b1, op1_offset, op2_offset, is_xmm, val;
int modrm, mod, rm, reg;
@@ -3242,7 +3240,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
}
/* simple MMX/SSE operation */
if (s->flags & HF_TS_MASK) {
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+ gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
return;
}
if (s->flags & HF_EM_MASK) {
@@ -4675,11 +4673,10 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
MemOp ot, aflag, dflag;
int modrm, reg, rm, mod, op, opreg, val;
target_ulong next_eip, tval;
- target_ulong pc_start = s->base.pc_next;
bool orig_cc_op_dirty = s->cc_op_dirty;
CCOp orig_cc_op = s->cc_op;
- s->pc_start = s->pc = pc_start;
+ s->pc = s->base.pc_next;
s->override = -1;
#ifdef TARGET_X86_64
s->rex_w = false;
@@ -4703,7 +4700,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
s->base.num_insns--;
tcg_remove_ops_after(s->prev_insn_end);
s->base.is_jmp = DISAS_TOO_MANY;
- return pc_start;
+ return s->base.pc_next;
default:
g_assert_not_reached();
}
@@ -6044,7 +6041,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
/* if CR0.EM or CR0.TS are set, generate an FPU exception */
/* XXX: what to do if illegal op ? */
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+ gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
break;
}
modrm = x86_ldub_code(env, s);
@@ -6585,7 +6582,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
offsetof(CPUX86State, segs[R_CS].selector));
tcg_gen_st16_i32(s->tmp2_i32, cpu_env,
offsetof(CPUX86State, fpcs));
- tcg_gen_st_tl(tcg_constant_tl(pc_start - s->cs_base),
+ tcg_gen_st_tl(tcg_constant_tl(s->base.pc_next - s->cs_base),
cpu_env, offsetof(CPUX86State, fpip));
}
}
@@ -6597,7 +6594,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xa5:
ot = mo_b_d(b, dflag);
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
+ gen_repz_movs(s, ot, s->base.pc_next - s->cs_base,
+ s->pc - s->cs_base);
} else {
gen_movs(s, ot);
}
@@ -6607,7 +6605,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xab:
ot = mo_b_d(b, dflag);
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
+ gen_repz_stos(s, ot, s->base.pc_next - s->cs_base,
+ s->pc - s->cs_base);
} else {
gen_stos(s, ot);
}
@@ -6616,7 +6615,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xad:
ot = mo_b_d(b, dflag);
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
+ gen_repz_lods(s, ot, s->base.pc_next - s->cs_base,
+ s->pc - s->cs_base);
} else {
gen_lods(s, ot);
}
@@ -6625,9 +6625,11 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xaf:
ot = mo_b_d(b, dflag);
if (prefixes & PREFIX_REPNZ) {
- gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
+ gen_repz_scas(s, ot, s->base.pc_next - s->cs_base,
+ s->pc - s->cs_base, 1);
} else if (prefixes & PREFIX_REPZ) {
- gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
+ gen_repz_scas(s, ot, s->base.pc_next - s->cs_base,
+ s->pc - s->cs_base, 0);
} else {
gen_scas(s, ot);
}
@@ -6637,9 +6639,11 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xa7:
ot = mo_b_d(b, dflag);
if (prefixes & PREFIX_REPNZ) {
- gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
+ gen_repz_cmps(s, ot, s->base.pc_next - s->cs_base,
+ s->pc - s->cs_base, 1);
} else if (prefixes & PREFIX_REPZ) {
- gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
+ gen_repz_cmps(s, ot, s->base.pc_next - s->cs_base,
+ s->pc - s->cs_base, 0);
} else {
gen_cmps(s, ot);
}
@@ -6657,7 +6661,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_io_start();
}
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
+ gen_repz_ins(s, ot, s->base.pc_next - s->cs_base,
+ s->pc - s->cs_base);
/* jump generated by gen_repz_ins */
} else {
gen_ins(s, ot);
@@ -6678,7 +6683,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_io_start();
}
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
+ gen_repz_outs(s, ot, s->base.pc_next - s->cs_base,
+ s->pc - s->cs_base);
/* jump generated by gen_repz_outs */
} else {
gen_outs(s, ot);
@@ -6790,7 +6796,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
do_lret:
if (PE(s) && !VM86(s)) {
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
tcg_const_i32(val));
} else {
@@ -7260,7 +7266,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
val = x86_ldub_code(env, s);
if (val == 0) {
- gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
+ gen_exception(s, EXCP00_DIVZ, s->base.pc_next - s->cs_base);
} else {
gen_helper_aam(cpu_env, tcg_const_i32(val));
set_cc_op(s, CC_OP_LOGICB);
@@ -7286,34 +7292,34 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
}
if (prefixes & PREFIX_REPZ) {
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
- gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_helper_pause(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
s->base.is_jmp = DISAS_NORETURN;
}
break;
case 0x9b: /* fwait */
if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
(HF_MP_MASK | HF_TS_MASK)) {
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+ gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
} else {
gen_helper_fwait(cpu_env);
}
break;
case 0xcc: /* int3 */
- gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
+ gen_interrupt(s, EXCP03_INT3, s->base.pc_next - s->cs_base, s->pc - s->cs_base);
break;
case 0xcd: /* int N */
val = x86_ldub_code(env, s);
if (check_vm86_iopl(s)) {
- gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
+ gen_interrupt(s, val, s->base.pc_next - s->cs_base, s->pc - s->cs_base);
}
break;
case 0xce: /* into */
if (CODE64(s))
goto illegal_op;
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
- gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_helper_into(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
break;
#ifdef WANT_ICEBP
case 0xf1: /* icebp (undocumented, exits to external debugger) */
@@ -7419,7 +7425,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0x132: /* rdmsr */
if (check_cpl0(s)) {
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
if (b & 2) {
gen_helper_rdmsr(cpu_env);
} else {
@@ -7431,7 +7437,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break;
case 0x131: /* rdtsc */
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
}
@@ -7442,7 +7448,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break;
case 0x133: /* rdpmc */
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
gen_helper_rdpmc(cpu_env);
s->base.is_jmp = DISAS_NORETURN;
break;
@@ -7472,8 +7478,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0x105: /* syscall */
/* XXX: is it usable in real mode ? */
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
- gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
/* TF handling for the syscall insn is different. The TF bit is checked
after the syscall insn completes. This allows #DB to not be
generated after one has entered CPL0 if TF is set in FMASK. */
@@ -7498,14 +7504,14 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
#endif
case 0x1a2: /* cpuid */
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
gen_helper_cpuid(cpu_env);
break;
case 0xf4: /* hlt */
if (check_cpl0(s)) {
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
- gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
s->base.is_jmp = DISAS_NORETURN;
}
break;
@@ -7601,7 +7607,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
gen_extu(s->aflag, s->A0);
gen_add_A0_ds_seg(s);
@@ -7613,8 +7619,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
- gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
s->base.is_jmp = DISAS_NORETURN;
break;
@@ -7691,9 +7697,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break;
}
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
- tcg_const_i32(s->pc - pc_start));
+ tcg_const_i32(s->pc - s->base.pc_next));
tcg_gen_exit_tb(NULL, 0);
s->base.is_jmp = DISAS_NORETURN;
break;
@@ -7703,7 +7709,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
gen_helper_vmmcall(cpu_env);
break;
@@ -7715,7 +7721,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break;
}
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
break;
@@ -7727,7 +7733,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break;
}
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
break;
@@ -7753,7 +7759,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break;
}
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
gen_helper_clgi(cpu_env);
break;
@@ -7899,7 +7905,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
gen_update_cc_op(s);
- gen_jmp_im(s, pc_start - s->cs_base);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
}
@@ -8351,7 +8357,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+ gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
break;
}
gen_lea_modrm(env, s, modrm);
@@ -8364,7 +8370,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+ gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
break;
}
gen_lea_modrm(env, s, modrm);
@@ -8376,7 +8382,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
if (s->flags & HF_TS_MASK) {
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+ gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
break;
}
gen_lea_modrm(env, s, modrm);
@@ -8389,7 +8395,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
if (s->flags & HF_TS_MASK) {
- gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+ gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
break;
}
gen_helper_update_mxcsr(cpu_env);
@@ -8598,7 +8604,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0x1c2:
case 0x1c4 ... 0x1c6:
case 0x1d0 ... 0x1fe:
- gen_sse(env, s, b, pc_start);
+ gen_sse(env, s, b);
break;
default:
goto unknown_op;
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 01/23] target/i386: Remove pc_start
2022-09-06 10:09 ` [PATCH v2 01/23] target/i386: Remove pc_start Richard Henderson
@ 2022-09-21 11:49 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 11:49 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The DisasContext member and the disas_insn local variable of
> the same name are identical to DisasContextBase.pc_next.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> target/i386/tcg/translate.c | 114 +++++++++++++++++++-----------------
> 1 file changed, 60 insertions(+), 54 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index d6420df31d..1e24bb2985 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -76,7 +76,6 @@ typedef struct DisasContext {
> DisasContextBase base;
>
> target_ulong pc; /* pc = eip + cs_base */
> - target_ulong pc_start; /* pc at TB entry */
> target_ulong cs_base; /* base of CS segment */
>
> MemOp aflag;
> @@ -1345,13 +1344,13 @@ static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
> the instruction is known, but it isn't allowed in the current cpu mode. */
> static void gen_illegal_opcode(DisasContext *s)
> {
> - gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
> + gen_exception(s, EXCP06_ILLOP, s->base.pc_next - s->cs_base);
> }
>
> /* Generate #GP for the current instruction. */
> static void gen_exception_gpf(DisasContext *s)
> {
> - gen_exception(s, EXCP0D_GPF, s->pc_start - s->cs_base);
> + gen_exception(s, EXCP0D_GPF, s->base.pc_next - s->cs_base);
> }
>
> /* Check for cpl == 0; if not, raise #GP and return false. */
> @@ -2016,7 +2015,7 @@ static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
> }
>
> s->pc += num_bytes;
> - if (unlikely(s->pc - s->pc_start > X86_MAX_INSN_LENGTH)) {
> + if (unlikely(s->pc - s->base.pc_next > X86_MAX_INSN_LENGTH)) {
> /* If the instruction's 16th byte is on a different page than the 1st, a
> * page fault on the second page wins over the general protection fault
> * caused by the instruction being too long.
> @@ -2589,7 +2588,7 @@ static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
> if (qemu_loglevel_mask(LOG_UNIMP)) {
> FILE *logfile = qemu_log_trylock();
> if (logfile) {
> - target_ulong pc = s->pc_start, end = s->pc;
> + target_ulong pc = s->base.pc_next, end = s->pc;
>
> fprintf(logfile, "ILLOPC: " TARGET_FMT_lx ":", pc);
> for (; pc < end; ++pc) {
> @@ -3199,8 +3198,7 @@ static const struct SSEOpHelper_table7 sse_op_table7[256] = {
> goto illegal_op; \
> } while (0)
>
> -static void gen_sse(CPUX86State *env, DisasContext *s, int b,
> - target_ulong pc_start)
> +static void gen_sse(CPUX86State *env, DisasContext *s, int b)
> {
> int b1, op1_offset, op2_offset, is_xmm, val;
> int modrm, mod, rm, reg;
> @@ -3242,7 +3240,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
> }
> /* simple MMX/SSE operation */
> if (s->flags & HF_TS_MASK) {
> - gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
> + gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
> return;
> }
> if (s->flags & HF_EM_MASK) {
> @@ -4675,11 +4673,10 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> MemOp ot, aflag, dflag;
> int modrm, reg, rm, mod, op, opreg, val;
> target_ulong next_eip, tval;
> - target_ulong pc_start = s->base.pc_next;
> bool orig_cc_op_dirty = s->cc_op_dirty;
> CCOp orig_cc_op = s->cc_op;
>
> - s->pc_start = s->pc = pc_start;
> + s->pc = s->base.pc_next;
> s->override = -1;
> #ifdef TARGET_X86_64
> s->rex_w = false;
> @@ -4703,7 +4700,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> s->base.num_insns--;
> tcg_remove_ops_after(s->prev_insn_end);
> s->base.is_jmp = DISAS_TOO_MANY;
> - return pc_start;
> + return s->base.pc_next;
> default:
> g_assert_not_reached();
> }
> @@ -6044,7 +6041,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
> /* if CR0.EM or CR0.TS are set, generate an FPU exception */
> /* XXX: what to do if illegal op ? */
> - gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
> + gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
> break;
> }
> modrm = x86_ldub_code(env, s);
> @@ -6585,7 +6582,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> offsetof(CPUX86State, segs[R_CS].selector));
> tcg_gen_st16_i32(s->tmp2_i32, cpu_env,
> offsetof(CPUX86State, fpcs));
> - tcg_gen_st_tl(tcg_constant_tl(pc_start - s->cs_base),
> + tcg_gen_st_tl(tcg_constant_tl(s->base.pc_next - s->cs_base),
> cpu_env, offsetof(CPUX86State, fpip));
> }
> }
> @@ -6597,7 +6594,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> case 0xa5:
> ot = mo_b_d(b, dflag);
> if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
> - gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
> + gen_repz_movs(s, ot, s->base.pc_next - s->cs_base,
> + s->pc - s->cs_base);
> } else {
> gen_movs(s, ot);
> }
> @@ -6607,7 +6605,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> case 0xab:
> ot = mo_b_d(b, dflag);
> if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
> - gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
> + gen_repz_stos(s, ot, s->base.pc_next - s->cs_base,
> + s->pc - s->cs_base);
> } else {
> gen_stos(s, ot);
> }
> @@ -6616,7 +6615,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> case 0xad:
> ot = mo_b_d(b, dflag);
> if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
> - gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
> + gen_repz_lods(s, ot, s->base.pc_next - s->cs_base,
> + s->pc - s->cs_base);
> } else {
> gen_lods(s, ot);
> }
> @@ -6625,9 +6625,11 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> case 0xaf:
> ot = mo_b_d(b, dflag);
> if (prefixes & PREFIX_REPNZ) {
> - gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
> + gen_repz_scas(s, ot, s->base.pc_next - s->cs_base,
> + s->pc - s->cs_base, 1);
> } else if (prefixes & PREFIX_REPZ) {
> - gen_repz_scas(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
> + gen_repz_scas(s, ot, s->base.pc_next - s->cs_base,
> + s->pc - s->cs_base, 0);
> } else {
> gen_scas(s, ot);
> }
> @@ -6637,9 +6639,11 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> case 0xa7:
> ot = mo_b_d(b, dflag);
> if (prefixes & PREFIX_REPNZ) {
> - gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 1);
> + gen_repz_cmps(s, ot, s->base.pc_next - s->cs_base,
> + s->pc - s->cs_base, 1);
> } else if (prefixes & PREFIX_REPZ) {
> - gen_repz_cmps(s, ot, pc_start - s->cs_base, s->pc - s->cs_base, 0);
> + gen_repz_cmps(s, ot, s->base.pc_next - s->cs_base,
> + s->pc - s->cs_base, 0);
> } else {
> gen_cmps(s, ot);
> }
> @@ -6657,7 +6661,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> gen_io_start();
> }
> if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
> - gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
> + gen_repz_ins(s, ot, s->base.pc_next - s->cs_base,
> + s->pc - s->cs_base);
> /* jump generated by gen_repz_ins */
> } else {
> gen_ins(s, ot);
> @@ -6678,7 +6683,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> gen_io_start();
> }
> if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
> - gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
> + gen_repz_outs(s, ot, s->base.pc_next - s->cs_base,
> + s->pc - s->cs_base);
> /* jump generated by gen_repz_outs */
> } else {
> gen_outs(s, ot);
> @@ -6790,7 +6796,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> do_lret:
> if (PE(s) && !VM86(s)) {
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
> tcg_const_i32(val));
> } else {
> @@ -7260,7 +7266,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> val = x86_ldub_code(env, s);
> if (val == 0) {
> - gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
> + gen_exception(s, EXCP00_DIVZ, s->base.pc_next - s->cs_base);
> } else {
> gen_helper_aam(cpu_env, tcg_const_i32(val));
> set_cc_op(s, CC_OP_LOGICB);
> @@ -7286,34 +7292,34 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> }
> if (prefixes & PREFIX_REPZ) {
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> - gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_helper_pause(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
> s->base.is_jmp = DISAS_NORETURN;
> }
> break;
> case 0x9b: /* fwait */
> if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
> (HF_MP_MASK | HF_TS_MASK)) {
> - gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
> + gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
> } else {
> gen_helper_fwait(cpu_env);
> }
> break;
> case 0xcc: /* int3 */
> - gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
> + gen_interrupt(s, EXCP03_INT3, s->base.pc_next - s->cs_base, s->pc - s->cs_base);
> break;
> case 0xcd: /* int N */
> val = x86_ldub_code(env, s);
> if (check_vm86_iopl(s)) {
> - gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
> + gen_interrupt(s, val, s->base.pc_next - s->cs_base, s->pc - s->cs_base);
> }
> break;
> case 0xce: /* into */
> if (CODE64(s))
> goto illegal_op;
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> - gen_helper_into(cpu_env, tcg_const_i32(s->pc - pc_start));
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_helper_into(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
> break;
> #ifdef WANT_ICEBP
> case 0xf1: /* icebp (undocumented, exits to external debugger) */
> @@ -7419,7 +7425,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> case 0x132: /* rdmsr */
> if (check_cpl0(s)) {
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> if (b & 2) {
> gen_helper_rdmsr(cpu_env);
> } else {
> @@ -7431,7 +7437,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> break;
> case 0x131: /* rdtsc */
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> }
> @@ -7442,7 +7448,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> break;
> case 0x133: /* rdpmc */
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> gen_helper_rdpmc(cpu_env);
> s->base.is_jmp = DISAS_NORETURN;
> break;
> @@ -7472,8 +7478,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> case 0x105: /* syscall */
> /* XXX: is it usable in real mode ? */
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> - gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - pc_start));
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
> /* TF handling for the syscall insn is different. The TF bit is checked
> after the syscall insn completes. This allows #DB to not be
> generated after one has entered CPL0 if TF is set in FMASK. */
> @@ -7498,14 +7504,14 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> #endif
> case 0x1a2: /* cpuid */
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> gen_helper_cpuid(cpu_env);
> break;
> case 0xf4: /* hlt */
> if (check_cpl0(s)) {
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> - gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
> s->base.is_jmp = DISAS_NORETURN;
> }
> break;
> @@ -7601,7 +7607,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
> gen_extu(s->aflag, s->A0);
> gen_add_A0_ds_seg(s);
> @@ -7613,8 +7619,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> - gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
> s->base.is_jmp = DISAS_NORETURN;
> break;
>
> @@ -7691,9 +7697,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> break;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
> - tcg_const_i32(s->pc - pc_start));
> + tcg_const_i32(s->pc - s->base.pc_next));
> tcg_gen_exit_tb(NULL, 0);
> s->base.is_jmp = DISAS_NORETURN;
> break;
> @@ -7703,7 +7709,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> gen_helper_vmmcall(cpu_env);
> break;
>
> @@ -7715,7 +7721,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> break;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
> break;
>
> @@ -7727,7 +7733,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> break;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
> break;
>
> @@ -7753,7 +7759,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> break;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> gen_helper_clgi(cpu_env);
> break;
>
> @@ -7899,7 +7905,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, pc_start - s->cs_base);
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> }
> @@ -8351,7 +8357,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
> - gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
> + gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
> break;
> }
> gen_lea_modrm(env, s, modrm);
> @@ -8364,7 +8370,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
> - gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
> + gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
> break;
> }
> gen_lea_modrm(env, s, modrm);
> @@ -8376,7 +8382,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> if (s->flags & HF_TS_MASK) {
> - gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
> + gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
> break;
> }
> gen_lea_modrm(env, s, modrm);
> @@ -8389,7 +8395,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> if (s->flags & HF_TS_MASK) {
> - gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
> + gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
> break;
> }
> gen_helper_update_mxcsr(cpu_env);
> @@ -8598,7 +8604,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> case 0x1c2:
> case 0x1c4 ... 0x1c6:
> case 0x1d0 ... 0x1fe:
> - gen_sse(env, s, b, pc_start);
> + gen_sse(env, s, b);
> break;
> default:
> goto unknown_op;
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 02/23] target/i386: Return bool from disas_insn
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
2022-09-06 10:09 ` [PATCH v2 01/23] target/i386: Remove pc_start Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-06 14:42 ` Philippe Mathieu-Daudé via
2022-09-06 10:09 ` [PATCH v2 03/23] target/i386: Remove cur_eip argument to gen_exception Richard Henderson
` (21 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Instead of returning the new pc, which is present in
DisasContext, return true if an insn was translated.
This is false when we detect a page crossing and must
undo the insn under translation.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 42 +++++++++++++++++++------------------
1 file changed, 22 insertions(+), 20 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 1e24bb2985..46300ffd91 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -4665,7 +4665,7 @@ 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(DisasContext *s, CPUState *cpu)
+static bool disas_insn(DisasContext *s, CPUState *cpu)
{
CPUX86State *env = cpu->env_ptr;
int b, prefixes;
@@ -4695,12 +4695,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
return s->pc;
case 2:
/* Restore state that may affect the next instruction. */
+ s->pc = s->base.pc_next;
s->cc_op_dirty = orig_cc_op_dirty;
s->cc_op = orig_cc_op;
s->base.num_insns--;
tcg_remove_ops_after(s->prev_insn_end);
s->base.is_jmp = DISAS_TOO_MANY;
- return s->base.pc_next;
+ return false;
default:
g_assert_not_reached();
}
@@ -8609,13 +8610,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
default:
goto unknown_op;
}
- return s->pc;
+ return true;
illegal_op:
gen_illegal_opcode(s);
- return s->pc;
+ return true;
unknown_op:
gen_unknown_opcode(env, s);
- return s->pc;
+ return true;
}
void tcg_x86_init(void)
@@ -8780,7 +8781,6 @@ static void i386_tr_insn_start(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;
#ifdef TARGET_VSYSCALL_PAGE
/*
@@ -8793,21 +8793,23 @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
}
#endif
- pc_next = disas_insn(dc, cpu);
- dc->base.pc_next = pc_next;
+ if (disas_insn(dc, cpu)) {
+ target_ulong pc_next = dc->pc;
+ dc->base.pc_next = pc_next;
- if (dc->base.is_jmp == DISAS_NEXT) {
- if (dc->flags & (HF_TF_MASK | 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.
- */
- dc->base.is_jmp = DISAS_TOO_MANY;
- } else if (!is_same_page(&dc->base, pc_next)) {
- dc->base.is_jmp = DISAS_TOO_MANY;
+ if (dc->base.is_jmp == DISAS_NEXT) {
+ if (dc->flags & (HF_TF_MASK | 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.
+ */
+ dc->base.is_jmp = DISAS_TOO_MANY;
+ } else if (!is_same_page(&dc->base, pc_next)) {
+ dc->base.is_jmp = DISAS_TOO_MANY;
+ }
}
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 02/23] target/i386: Return bool from disas_insn
2022-09-06 10:09 ` [PATCH v2 02/23] target/i386: Return bool from disas_insn Richard Henderson
@ 2022-09-06 14:42 ` Philippe Mathieu-Daudé via
2022-09-08 12:14 ` Richard Henderson
0 siblings, 1 reply; 61+ messages in thread
From: Philippe Mathieu-Daudé via @ 2022-09-06 14:42 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: pbonzini
On 6/9/22 12:09, Richard Henderson wrote:
> Instead of returning the new pc, which is present in
> DisasContext, return true if an insn was translated.
> This is false when we detect a page crossing and must
> undo the insn under translation.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/i386/tcg/translate.c | 42 +++++++++++++++++++------------------
> 1 file changed, 22 insertions(+), 20 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 1e24bb2985..46300ffd91 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -4665,7 +4665,7 @@ 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(DisasContext *s, CPUState *cpu)
> +static bool disas_insn(DisasContext *s, CPUState *cpu)
> {
> CPUX86State *env = cpu->env_ptr;
> int b, prefixes;
> @@ -4695,12 +4695,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> return s->pc;
Shouldn't we return 'true' here?
> case 2:
> /* Restore state that may affect the next instruction. */
> + s->pc = s->base.pc_next;
> s->cc_op_dirty = orig_cc_op_dirty;
> s->cc_op = orig_cc_op;
> s->base.num_insns--;
> tcg_remove_ops_after(s->prev_insn_end);
> s->base.is_jmp = DISAS_TOO_MANY;
> - return s->base.pc_next;
> + return false;
> default:
> g_assert_not_reached();
> }
> @@ -8609,13 +8610,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
> default:
> goto unknown_op;
> }
> - return s->pc;
> + return true;
> illegal_op:
> gen_illegal_opcode(s);
> - return s->pc;
> + return true;
> unknown_op:
> gen_unknown_opcode(env, s);
> - return s->pc;
> + return true;
> }
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 02/23] target/i386: Return bool from disas_insn
2022-09-06 14:42 ` Philippe Mathieu-Daudé via
@ 2022-09-08 12:14 ` Richard Henderson
2022-09-21 17:51 ` Philippe Mathieu-Daudé via
0 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-08 12:14 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel; +Cc: pbonzini
On 9/6/22 15:42, Philippe Mathieu-Daudé wrote:
> On 6/9/22 12:09, Richard Henderson wrote:
>> Instead of returning the new pc, which is present in
>> DisasContext, return true if an insn was translated.
>> This is false when we detect a page crossing and must
>> undo the insn under translation.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>> target/i386/tcg/translate.c | 42 +++++++++++++++++++------------------
>> 1 file changed, 22 insertions(+), 20 deletions(-)
>>
>> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
>> index 1e24bb2985..46300ffd91 100644
>> --- a/target/i386/tcg/translate.c
>> +++ b/target/i386/tcg/translate.c
>> @@ -4665,7 +4665,7 @@ 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(DisasContext *s, CPUState *cpu)
>> +static bool disas_insn(DisasContext *s, CPUState *cpu)
>> {
>> CPUX86State *env = cpu->env_ptr;
>> int b, prefixes;
>> @@ -4695,12 +4695,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>> return s->pc;
>
> Shouldn't we return 'true' here?
Whoops, yes.
r~
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 02/23] target/i386: Return bool from disas_insn
2022-09-08 12:14 ` Richard Henderson
@ 2022-09-21 17:51 ` Philippe Mathieu-Daudé via
0 siblings, 0 replies; 61+ messages in thread
From: Philippe Mathieu-Daudé via @ 2022-09-21 17:51 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: pbonzini
On 8/9/22 14:14, Richard Henderson wrote:
> On 9/6/22 15:42, Philippe Mathieu-Daudé wrote:
>> On 6/9/22 12:09, Richard Henderson wrote:
>>> Instead of returning the new pc, which is present in
>>> DisasContext, return true if an insn was translated.
>>> This is false when we detect a page crossing and must
>>> undo the insn under translation.
>>>
>>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>>> ---
>>> target/i386/tcg/translate.c | 42 +++++++++++++++++++------------------
>>> 1 file changed, 22 insertions(+), 20 deletions(-)
>>>
>>> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
>>> index 1e24bb2985..46300ffd91 100644
>>> --- a/target/i386/tcg/translate.c
>>> +++ b/target/i386/tcg/translate.c
>>> @@ -4665,7 +4665,7 @@ 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(DisasContext *s, CPUState *cpu)
>>> +static bool disas_insn(DisasContext *s, CPUState *cpu)
>>> {
>>> CPUX86State *env = cpu->env_ptr;
>>> int b, prefixes;
>>> @@ -4695,12 +4695,13 @@ static target_ulong disas_insn(DisasContext
>>> *s, CPUState *cpu)
>>> return s->pc;
>>
>> Shouldn't we return 'true' here?
>
> Whoops, yes.
Returning 'true':
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 03/23] target/i386: Remove cur_eip argument to gen_exception
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
2022-09-06 10:09 ` [PATCH v2 01/23] target/i386: Remove pc_start Richard Henderson
2022-09-06 10:09 ` [PATCH v2 02/23] target/i386: Return bool from disas_insn Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-06 14:44 ` Philippe Mathieu-Daudé via
2022-09-06 10:09 ` [PATCH v2 04/23] target/i386: Remove cur_eip, next_eip arguments to gen_interrupt Richard Henderson
` (20 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
All callers pass s->base.pc_next - s->cs_base, which we can just
as well compute within the function. Note the special case of
EXCP_VSYSCALL in which s->cs_base didn't have the subtraction,
but cs_base is always zero in 64-bit mode, when vsyscall is used.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 46300ffd91..58e74c3162 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -1332,10 +1332,10 @@ static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
}
}
-static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
+static void gen_exception(DisasContext *s, int trapno)
{
gen_update_cc_op(s);
- gen_jmp_im(s, cur_eip);
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
s->base.is_jmp = DISAS_NORETURN;
}
@@ -1344,13 +1344,13 @@ static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
the instruction is known, but it isn't allowed in the current cpu mode. */
static void gen_illegal_opcode(DisasContext *s)
{
- gen_exception(s, EXCP06_ILLOP, s->base.pc_next - s->cs_base);
+ gen_exception(s, EXCP06_ILLOP);
}
/* Generate #GP for the current instruction. */
static void gen_exception_gpf(DisasContext *s)
{
- gen_exception(s, EXCP0D_GPF, s->base.pc_next - s->cs_base);
+ gen_exception(s, EXCP0D_GPF);
}
/* Check for cpl == 0; if not, raise #GP and return false. */
@@ -3240,7 +3240,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b)
}
/* simple MMX/SSE operation */
if (s->flags & HF_TS_MASK) {
- gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
+ gen_exception(s, EXCP07_PREX);
return;
}
if (s->flags & HF_EM_MASK) {
@@ -6042,7 +6042,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
/* if CR0.EM or CR0.TS are set, generate an FPU exception */
/* XXX: what to do if illegal op ? */
- gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
+ gen_exception(s, EXCP07_PREX);
break;
}
modrm = x86_ldub_code(env, s);
@@ -7267,7 +7267,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
val = x86_ldub_code(env, s);
if (val == 0) {
- gen_exception(s, EXCP00_DIVZ, s->base.pc_next - s->cs_base);
+ gen_exception(s, EXCP00_DIVZ);
} else {
gen_helper_aam(cpu_env, tcg_const_i32(val));
set_cc_op(s, CC_OP_LOGICB);
@@ -7301,7 +7301,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
case 0x9b: /* fwait */
if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
(HF_MP_MASK | HF_TS_MASK)) {
- gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
+ gen_exception(s, EXCP07_PREX);
} else {
gen_helper_fwait(cpu_env);
}
@@ -8358,7 +8358,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
- gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
+ gen_exception(s, EXCP07_PREX);
break;
}
gen_lea_modrm(env, s, modrm);
@@ -8371,7 +8371,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
- gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
+ gen_exception(s, EXCP07_PREX);
break;
}
gen_lea_modrm(env, s, modrm);
@@ -8383,7 +8383,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
if (s->flags & HF_TS_MASK) {
- gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
+ gen_exception(s, EXCP07_PREX);
break;
}
gen_lea_modrm(env, s, modrm);
@@ -8396,7 +8396,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
if (s->flags & HF_TS_MASK) {
- gen_exception(s, EXCP07_PREX, s->base.pc_next - s->cs_base);
+ gen_exception(s, EXCP07_PREX);
break;
}
gen_helper_update_mxcsr(cpu_env);
@@ -8787,7 +8787,7 @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
* Detect entry into the vsyscall page and invoke the syscall.
*/
if ((dc->base.pc_next & TARGET_PAGE_MASK) == TARGET_VSYSCALL_PAGE) {
- gen_exception(dc, EXCP_VSYSCALL, dc->base.pc_next);
+ gen_exception(dc, EXCP_VSYSCALL);
dc->base.pc_next = dc->pc + 1;
return;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 03/23] target/i386: Remove cur_eip argument to gen_exception
2022-09-06 10:09 ` [PATCH v2 03/23] target/i386: Remove cur_eip argument to gen_exception Richard Henderson
@ 2022-09-06 14:44 ` Philippe Mathieu-Daudé via
2022-09-21 11:51 ` Paolo Bonzini
0 siblings, 1 reply; 61+ messages in thread
From: Philippe Mathieu-Daudé via @ 2022-09-06 14:44 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: pbonzini
On 6/9/22 12:09, Richard Henderson wrote:
> All callers pass s->base.pc_next - s->cs_base, which we can just
> as well compute within the function. Note the special case of
> EXCP_VSYSCALL in which s->cs_base didn't have the subtraction,
> but cs_base is always zero in 64-bit mode, when vsyscall is used.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/i386/tcg/translate.c | 26 +++++++++++++-------------
> 1 file changed, 13 insertions(+), 13 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 03/23] target/i386: Remove cur_eip argument to gen_exception
2022-09-06 14:44 ` Philippe Mathieu-Daudé via
@ 2022-09-21 11:51 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 11:51 UTC (permalink / raw)
To: Philippe Mathieu-Daudé; +Cc: Richard Henderson, qemu-devel
On Tue, Sep 6, 2022 at 4:45 PM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
> On 6/9/22 12:09, Richard Henderson wrote:
> > All callers pass s->base.pc_next - s->cs_base, which we can just
> > as well compute within the function. Note the special case of
> > EXCP_VSYSCALL in which s->cs_base didn't have the subtraction,
> > but cs_base is always zero in 64-bit mode, when vsyscall is used.
> >
> > Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> > ---
> > target/i386/tcg/translate.c | 26 +++++++++++++-------------
> > 1 file changed, 13 insertions(+), 13 deletions(-)
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 04/23] target/i386: Remove cur_eip, next_eip arguments to gen_interrupt
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (2 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 03/23] target/i386: Remove cur_eip argument to gen_exception Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-06 14:46 ` Philippe Mathieu-Daudé via
2022-09-06 10:09 ` [PATCH v2 05/23] target/i386: Create gen_update_eip_cur Richard Henderson
` (19 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
All callers pass s->base.pc_next and s->pc, which we can just
as well compute within the function.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 58e74c3162..0210382f77 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2602,13 +2602,12 @@ static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
/* an interrupt is different from an exception because of the
privilege checks */
-static void gen_interrupt(DisasContext *s, int intno,
- target_ulong cur_eip, target_ulong next_eip)
+static void gen_interrupt(DisasContext *s, int intno)
{
gen_update_cc_op(s);
- gen_jmp_im(s, cur_eip);
- gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
- tcg_const_i32(next_eip - cur_eip));
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_helper_raise_interrupt(cpu_env, tcg_constant_i32(intno),
+ tcg_constant_i32(s->pc - s->base.pc_next));
s->base.is_jmp = DISAS_NORETURN;
}
@@ -7307,12 +7306,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
break;
case 0xcc: /* int3 */
- gen_interrupt(s, EXCP03_INT3, s->base.pc_next - s->cs_base, s->pc - s->cs_base);
+ gen_interrupt(s, EXCP03_INT3);
break;
case 0xcd: /* int N */
val = x86_ldub_code(env, s);
if (check_vm86_iopl(s)) {
- gen_interrupt(s, val, s->base.pc_next - s->cs_base, s->pc - s->cs_base);
+ gen_interrupt(s, val);
}
break;
case 0xce: /* into */
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 04/23] target/i386: Remove cur_eip, next_eip arguments to gen_interrupt
2022-09-06 10:09 ` [PATCH v2 04/23] target/i386: Remove cur_eip, next_eip arguments to gen_interrupt Richard Henderson
@ 2022-09-06 14:46 ` Philippe Mathieu-Daudé via
2022-09-21 11:51 ` Paolo Bonzini
0 siblings, 1 reply; 61+ messages in thread
From: Philippe Mathieu-Daudé via @ 2022-09-06 14:46 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: pbonzini
On 6/9/22 12:09, Richard Henderson wrote:
> All callers pass s->base.pc_next and s->pc, which we can just
> as well compute within the function.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/i386/tcg/translate.c | 13 ++++++-------
> 1 file changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 58e74c3162..0210382f77 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -2602,13 +2602,12 @@ static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
>
> /* an interrupt is different from an exception because of the
> privilege checks */
> -static void gen_interrupt(DisasContext *s, int intno,
> - target_ulong cur_eip, target_ulong next_eip)
> +static void gen_interrupt(DisasContext *s, int intno)
> {
> gen_update_cc_op(s);
> - gen_jmp_im(s, cur_eip);
> - gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
> - tcg_const_i32(next_eip - cur_eip));
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_helper_raise_interrupt(cpu_env, tcg_constant_i32(intno),
> + tcg_constant_i32(s->pc - s->base.pc_next));
Maybe note the switch to tcg_constant() in the description?
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 04/23] target/i386: Remove cur_eip, next_eip arguments to gen_interrupt
2022-09-06 14:46 ` Philippe Mathieu-Daudé via
@ 2022-09-21 11:51 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 11:51 UTC (permalink / raw)
To: Philippe Mathieu-Daudé; +Cc: Richard Henderson, qemu-devel
On Tue, Sep 6, 2022 at 4:46 PM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
> On 6/9/22 12:09, Richard Henderson wrote:
> > All callers pass s->base.pc_next and s->pc, which we can just
> > as well compute within the function.
> >
> > Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> > ---
> > target/i386/tcg/translate.c | 13 ++++++-------
> > 1 file changed, 6 insertions(+), 7 deletions(-)
> >
> > diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> > index 58e74c3162..0210382f77 100644
> > --- a/target/i386/tcg/translate.c
> > +++ b/target/i386/tcg/translate.c
> > @@ -2602,13 +2602,12 @@ static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
> >
> > /* an interrupt is different from an exception because of the
> > privilege checks */
> > -static void gen_interrupt(DisasContext *s, int intno,
> > - target_ulong cur_eip, target_ulong next_eip)
> > +static void gen_interrupt(DisasContext *s, int intno)
> > {
> > gen_update_cc_op(s);
> > - gen_jmp_im(s, cur_eip);
> > - gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
> > - tcg_const_i32(next_eip - cur_eip));
> > + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> > + gen_helper_raise_interrupt(cpu_env, tcg_constant_i32(intno),
> > + tcg_constant_i32(s->pc - s->base.pc_next));
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 05/23] target/i386: Create gen_update_eip_cur
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (3 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 04/23] target/i386: Remove cur_eip, next_eip arguments to gen_interrupt Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 11:58 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 06/23] target/i386: Create gen_update_eip_next Richard Henderson
` (18 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Like gen_update_cc_op, sync EIP before doing something
that could raise an exception. Replace all gen_jmp_im
that use s->base.pc_next.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 52 ++++++++++++++++++++-----------------
1 file changed, 28 insertions(+), 24 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 0210382f77..83cb925571 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -511,10 +511,14 @@ static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
}
}
-static inline void gen_jmp_im(DisasContext *s, target_ulong pc)
+static void gen_jmp_im(DisasContext *s, target_ulong pc)
{
- tcg_gen_movi_tl(s->tmp0, pc);
- gen_op_jmp_v(s->tmp0);
+ gen_op_jmp_v(tcg_constant_tl(pc));
+}
+
+static void gen_update_eip_cur(DisasContext *s)
+{
+ gen_jmp_im(s, s->base.pc_next - s->cs_base);
}
/* Compute SEG:REG into A0. SEG is selected from the override segment
@@ -703,7 +707,7 @@ static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
target_ulong next_eip = s->pc - s->cs_base;
gen_update_cc_op(s);
- gen_jmp_im(s, cur_eip);
+ gen_update_eip_cur(s);
if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
svm_flags |= SVM_IOIO_REP_MASK;
}
@@ -1335,7 +1339,7 @@ static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
static void gen_exception(DisasContext *s, int trapno)
{
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
s->base.is_jmp = DISAS_NORETURN;
}
@@ -2605,7 +2609,7 @@ static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
static void gen_interrupt(DisasContext *s, int intno)
{
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_raise_interrupt(cpu_env, tcg_constant_i32(intno),
tcg_constant_i32(s->pc - s->base.pc_next));
s->base.is_jmp = DISAS_NORETURN;
@@ -6796,7 +6800,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
do_lret:
if (PE(s) && !VM86(s)) {
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
tcg_const_i32(val));
} else {
@@ -7292,7 +7296,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
if (prefixes & PREFIX_REPZ) {
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_pause(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
s->base.is_jmp = DISAS_NORETURN;
}
@@ -7318,7 +7322,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
if (CODE64(s))
goto illegal_op;
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_into(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
break;
#ifdef WANT_ICEBP
@@ -7425,7 +7429,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
case 0x132: /* rdmsr */
if (check_cpl0(s)) {
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
if (b & 2) {
gen_helper_rdmsr(cpu_env);
} else {
@@ -7437,7 +7441,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
break;
case 0x131: /* rdtsc */
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
}
@@ -7448,7 +7452,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
break;
case 0x133: /* rdpmc */
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_rdpmc(cpu_env);
s->base.is_jmp = DISAS_NORETURN;
break;
@@ -7478,7 +7482,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
case 0x105: /* syscall */
/* XXX: is it usable in real mode ? */
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
/* TF handling for the syscall insn is different. The TF bit is checked
after the syscall insn completes. This allows #DB to not be
@@ -7504,13 +7508,13 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
#endif
case 0x1a2: /* cpuid */
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_cpuid(cpu_env);
break;
case 0xf4: /* hlt */
if (check_cpl0(s)) {
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
s->base.is_jmp = DISAS_NORETURN;
}
@@ -7607,7 +7611,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
gen_extu(s->aflag, s->A0);
gen_add_A0_ds_seg(s);
@@ -7619,7 +7623,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
s->base.is_jmp = DISAS_NORETURN;
break;
@@ -7697,7 +7701,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
break;
}
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
tcg_const_i32(s->pc - s->base.pc_next));
tcg_gen_exit_tb(NULL, 0);
@@ -7709,7 +7713,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_vmmcall(cpu_env);
break;
@@ -7721,7 +7725,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
break;
}
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
break;
@@ -7733,7 +7737,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
break;
}
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
break;
@@ -7759,7 +7763,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
break;
}
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
gen_helper_clgi(cpu_env);
break;
@@ -7905,7 +7909,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
gen_update_cc_op(s);
- gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ gen_update_eip_cur(s);
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
}
@@ -8818,7 +8822,7 @@ static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
DisasContext *dc = container_of(dcbase, DisasContext, base);
if (dc->base.is_jmp == DISAS_TOO_MANY) {
- gen_jmp_im(dc, dc->base.pc_next - dc->cs_base);
+ gen_update_eip_cur(dc);
gen_eob(dc);
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 05/23] target/i386: Create gen_update_eip_cur
2022-09-06 10:09 ` [PATCH v2 05/23] target/i386: Create gen_update_eip_cur Richard Henderson
@ 2022-09-21 11:58 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 11:58 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Like gen_update_cc_op, sync EIP before doing something
> that could raise an exception. Replace all gen_jmp_im
> that use s->base.pc_next.
The commit message seems a bit off (it sounds like adding
stuff rather than refactoring), but anyway:
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Paolo
> ---
> target/i386/tcg/translate.c | 52 ++++++++++++++++++++-----------------
> 1 file changed, 28 insertions(+), 24 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 0210382f77..83cb925571 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -511,10 +511,14 @@ static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
> }
> }
>
> -static inline void gen_jmp_im(DisasContext *s, target_ulong pc)
> +static void gen_jmp_im(DisasContext *s, target_ulong pc)
> {
> - tcg_gen_movi_tl(s->tmp0, pc);
> - gen_op_jmp_v(s->tmp0);
> + gen_op_jmp_v(tcg_constant_tl(pc));
> +}
> +
> +static void gen_update_eip_cur(DisasContext *s)
> +{
> + gen_jmp_im(s, s->base.pc_next - s->cs_base);
> }
>
> /* Compute SEG:REG into A0. SEG is selected from the override segment
> @@ -703,7 +707,7 @@ static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
> target_ulong next_eip = s->pc - s->cs_base;
>
> gen_update_cc_op(s);
> - gen_jmp_im(s, cur_eip);
> + gen_update_eip_cur(s);
> if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
> svm_flags |= SVM_IOIO_REP_MASK;
> }
> @@ -1335,7 +1339,7 @@ static void gen_helper_fp_arith_STN_ST0(int op, int opreg)
> static void gen_exception(DisasContext *s, int trapno)
> {
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
> s->base.is_jmp = DISAS_NORETURN;
> }
> @@ -2605,7 +2609,7 @@ static void gen_unknown_opcode(CPUX86State *env, DisasContext *s)
> static void gen_interrupt(DisasContext *s, int intno)
> {
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_raise_interrupt(cpu_env, tcg_constant_i32(intno),
> tcg_constant_i32(s->pc - s->base.pc_next));
> s->base.is_jmp = DISAS_NORETURN;
> @@ -6796,7 +6800,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> do_lret:
> if (PE(s) && !VM86(s)) {
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
> tcg_const_i32(val));
> } else {
> @@ -7292,7 +7296,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> if (prefixes & PREFIX_REPZ) {
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_pause(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
> s->base.is_jmp = DISAS_NORETURN;
> }
> @@ -7318,7 +7322,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> if (CODE64(s))
> goto illegal_op;
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_into(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
> break;
> #ifdef WANT_ICEBP
> @@ -7425,7 +7429,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> case 0x132: /* rdmsr */
> if (check_cpl0(s)) {
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> if (b & 2) {
> gen_helper_rdmsr(cpu_env);
> } else {
> @@ -7437,7 +7441,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> break;
> case 0x131: /* rdtsc */
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> }
> @@ -7448,7 +7452,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> break;
> case 0x133: /* rdpmc */
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_rdpmc(cpu_env);
> s->base.is_jmp = DISAS_NORETURN;
> break;
> @@ -7478,7 +7482,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> case 0x105: /* syscall */
> /* XXX: is it usable in real mode ? */
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
> /* TF handling for the syscall insn is different. The TF bit is checked
> after the syscall insn completes. This allows #DB to not be
> @@ -7504,13 +7508,13 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> #endif
> case 0x1a2: /* cpuid */
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_cpuid(cpu_env);
> break;
> case 0xf4: /* hlt */
> if (check_cpl0(s)) {
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
> s->base.is_jmp = DISAS_NORETURN;
> }
> @@ -7607,7 +7611,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
> gen_extu(s->aflag, s->A0);
> gen_add_A0_ds_seg(s);
> @@ -7619,7 +7623,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
> s->base.is_jmp = DISAS_NORETURN;
> break;
> @@ -7697,7 +7701,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> break;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
> tcg_const_i32(s->pc - s->base.pc_next));
> tcg_gen_exit_tb(NULL, 0);
> @@ -7709,7 +7713,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_vmmcall(cpu_env);
> break;
>
> @@ -7721,7 +7725,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> break;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_vmload(cpu_env, tcg_const_i32(s->aflag - 1));
> break;
>
> @@ -7733,7 +7737,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> break;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_vmsave(cpu_env, tcg_const_i32(s->aflag - 1));
> break;
>
> @@ -7759,7 +7763,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> break;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> gen_helper_clgi(cpu_env);
> break;
>
> @@ -7905,7 +7909,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + gen_update_eip_cur(s);
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> }
> @@ -8818,7 +8822,7 @@ static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
> DisasContext *dc = container_of(dcbase, DisasContext, base);
>
> if (dc->base.is_jmp == DISAS_TOO_MANY) {
> - gen_jmp_im(dc, dc->base.pc_next - dc->cs_base);
> + gen_update_eip_cur(dc);
> gen_eob(dc);
> }
> }
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 06/23] target/i386: Create gen_update_eip_next
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (4 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 05/23] target/i386: Create gen_update_eip_cur Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 12:04 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 07/23] target/i386: Introduce DISAS_EOB* Richard Henderson
` (17 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Sync EIP before exiting a translation block.
Replace all gen_jmp_im that use s->pc.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 45 ++++++++++++++++++++-----------------
1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 83cb925571..6084c85609 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -521,6 +521,11 @@ static void gen_update_eip_cur(DisasContext *s)
gen_jmp_im(s, s->base.pc_next - s->cs_base);
}
+static void gen_update_eip_next(DisasContext *s)
+{
+ gen_jmp_im(s, s->pc - s->cs_base);
+}
+
/* Compute SEG:REG into A0. SEG is selected from the override segment
(OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
indicate no override. */
@@ -5675,7 +5680,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_pop_update(s, ot);
/* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
if (s->base.is_jmp) {
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
if (reg == R_SS) {
s->flags &= ~HF_TF_MASK;
gen_eob_inhibit_irq(s, true);
@@ -5690,7 +5695,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_movl_seg_T0(s, (b >> 3) & 7);
gen_pop_update(s, ot);
if (s->base.is_jmp) {
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
}
break;
@@ -5741,7 +5746,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_movl_seg_T0(s, reg);
/* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
if (s->base.is_jmp) {
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
if (reg == R_SS) {
s->flags &= ~HF_TF_MASK;
gen_eob_inhibit_irq(s, true);
@@ -5948,7 +5953,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
/* then put the data */
gen_op_mov_reg_v(s, ot, reg, s->T1);
if (s->base.is_jmp) {
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
}
break;
@@ -7004,7 +7009,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_pop_update(s, ot);
set_cc_op(s, CC_OP_EFLAGS);
/* abort translation because TF/AC flag may change */
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
}
break;
@@ -7340,7 +7345,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
if (check_iopl(s)) {
gen_helper_sti(cpu_env);
/* interruptions are enabled only the first insn after sti */
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob_inhibit_irq(s, true);
}
break;
@@ -7416,7 +7421,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
gen_set_label(l3);
- gen_jmp_im(s, next_eip);
+ gen_update_eip_next(s);
tcg_gen_br(l2);
gen_set_label(l1);
@@ -7434,7 +7439,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_helper_rdmsr(cpu_env);
} else {
gen_helper_wrmsr(cpu_env);
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
}
}
@@ -7634,7 +7639,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
gen_helper_clac(cpu_env);
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
break;
@@ -7644,7 +7649,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
gen_helper_stac(cpu_env);
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
break;
@@ -7689,7 +7694,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64);
/* End TB because translation flags may change. */
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
break;
@@ -7751,7 +7756,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
gen_update_cc_op(s);
gen_helper_stgi(cpu_env);
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
break;
@@ -7790,7 +7795,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]);
}
gen_helper_flush_page(cpu_env, s->A0);
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
break;
@@ -7874,7 +7879,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
tcg_gen_andi_tl(s->T1, s->T1, ~0xe);
tcg_gen_or_tl(s->T0, s->T0, s->T1);
gen_helper_write_crN(cpu_env, tcg_constant_i32(0), s->T0);
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
break;
@@ -7885,7 +7890,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_svm_check_intercept(s, SVM_EXIT_INVLPG);
gen_lea_modrm(env, s, modrm);
gen_helper_flush_page(cpu_env, s->A0);
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
break;
@@ -8285,7 +8290,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
gen_op_mov_v_reg(s, ot, s->T0, rm);
gen_helper_write_crN(cpu_env, tcg_constant_i32(reg), s->T0);
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
} else {
gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
@@ -8320,7 +8325,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_op_mov_v_reg(s, ot, s->T0, rm);
tcg_gen_movi_i32(s->tmp2_i32, reg);
gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0);
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
} else {
gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg);
@@ -8335,7 +8340,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
gen_helper_clts(cpu_env);
/* abort block because static cpu state changed */
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
}
break;
@@ -8433,7 +8438,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
/* XRSTOR is how MPX is enabled, which changes how
we translate. Thus we need to end the TB. */
gen_update_cc_op(s);
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_eob(s);
break;
@@ -8567,7 +8572,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
g_assert_not_reached();
#else
gen_update_cc_op(s);
- gen_jmp_im(s, s->pc - s->cs_base);
+ gen_update_eip_next(s);
gen_helper_rsm(cpu_env);
#endif /* CONFIG_USER_ONLY */
gen_eob(s);
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 06/23] target/i386: Create gen_update_eip_next
2022-09-06 10:09 ` [PATCH v2 06/23] target/i386: Create gen_update_eip_next Richard Henderson
@ 2022-09-21 12:04 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 12:04 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Sync EIP before exiting a translation block.
> Replace all gen_jmp_im that use s->pc.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/i386/tcg/translate.c | 45 ++++++++++++++++++++-----------------
> 1 file changed, 25 insertions(+), 20 deletions(-)
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 83cb925571..6084c85609 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -521,6 +521,11 @@ static void gen_update_eip_cur(DisasContext *s)
> gen_jmp_im(s, s->base.pc_next - s->cs_base);
> }
>
> +static void gen_update_eip_next(DisasContext *s)
> +{
> + gen_jmp_im(s, s->pc - s->cs_base);
> +}
> +
> /* Compute SEG:REG into A0. SEG is selected from the override segment
> (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
> indicate no override. */
> @@ -5675,7 +5680,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_pop_update(s, ot);
> /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
> if (s->base.is_jmp) {
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> if (reg == R_SS) {
> s->flags &= ~HF_TF_MASK;
> gen_eob_inhibit_irq(s, true);
> @@ -5690,7 +5695,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_movl_seg_T0(s, (b >> 3) & 7);
> gen_pop_update(s, ot);
> if (s->base.is_jmp) {
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> }
> break;
> @@ -5741,7 +5746,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_movl_seg_T0(s, reg);
> /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
> if (s->base.is_jmp) {
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> if (reg == R_SS) {
> s->flags &= ~HF_TF_MASK;
> gen_eob_inhibit_irq(s, true);
> @@ -5948,7 +5953,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> /* then put the data */
> gen_op_mov_reg_v(s, ot, reg, s->T1);
> if (s->base.is_jmp) {
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> }
> break;
> @@ -7004,7 +7009,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_pop_update(s, ot);
> set_cc_op(s, CC_OP_EFLAGS);
> /* abort translation because TF/AC flag may change */
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> }
> break;
> @@ -7340,7 +7345,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> if (check_iopl(s)) {
> gen_helper_sti(cpu_env);
> /* interruptions are enabled only the first insn after sti */
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob_inhibit_irq(s, true);
> }
> break;
> @@ -7416,7 +7421,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
>
> gen_set_label(l3);
> - gen_jmp_im(s, next_eip);
> + gen_update_eip_next(s);
> tcg_gen_br(l2);
>
> gen_set_label(l1);
> @@ -7434,7 +7439,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_helper_rdmsr(cpu_env);
> } else {
> gen_helper_wrmsr(cpu_env);
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> }
> }
> @@ -7634,7 +7639,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> gen_helper_clac(cpu_env);
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> break;
>
> @@ -7644,7 +7649,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> gen_helper_stac(cpu_env);
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> break;
>
> @@ -7689,7 +7694,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
> gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64);
> /* End TB because translation flags may change. */
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> break;
>
> @@ -7751,7 +7756,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> gen_update_cc_op(s);
> gen_helper_stgi(cpu_env);
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> break;
>
> @@ -7790,7 +7795,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]);
> }
> gen_helper_flush_page(cpu_env, s->A0);
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> break;
>
> @@ -7874,7 +7879,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> tcg_gen_andi_tl(s->T1, s->T1, ~0xe);
> tcg_gen_or_tl(s->T0, s->T0, s->T1);
> gen_helper_write_crN(cpu_env, tcg_constant_i32(0), s->T0);
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> break;
>
> @@ -7885,7 +7890,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_svm_check_intercept(s, SVM_EXIT_INVLPG);
> gen_lea_modrm(env, s, modrm);
> gen_helper_flush_page(cpu_env, s->A0);
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> break;
>
> @@ -8285,7 +8290,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
> gen_op_mov_v_reg(s, ot, s->T0, rm);
> gen_helper_write_crN(cpu_env, tcg_constant_i32(reg), s->T0);
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> } else {
> gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
> @@ -8320,7 +8325,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_op_mov_v_reg(s, ot, s->T0, rm);
> tcg_gen_movi_i32(s->tmp2_i32, reg);
> gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0);
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> } else {
> gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg);
> @@ -8335,7 +8340,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
> gen_helper_clts(cpu_env);
> /* abort block because static cpu state changed */
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> }
> break;
> @@ -8433,7 +8438,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> /* XRSTOR is how MPX is enabled, which changes how
> we translate. Thus we need to end the TB. */
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_eob(s);
> break;
>
> @@ -8567,7 +8572,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> g_assert_not_reached();
> #else
> gen_update_cc_op(s);
> - gen_jmp_im(s, s->pc - s->cs_base);
> + gen_update_eip_next(s);
> gen_helper_rsm(cpu_env);
> #endif /* CONFIG_USER_ONLY */
> gen_eob(s);
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 07/23] target/i386: Introduce DISAS_EOB*
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (5 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 06/23] target/i386: Create gen_update_eip_next Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 12:05 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 08/23] target/i386: Use DISAS_EOB* in gen_movl_seg_T0 Richard Henderson
` (16 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Add a few DISAS_TARGET_* aliases to reduce the number of
calls to gen_eob() and gen_eob_inhibit_irq(). So far,
only update i386_tr_translate_insn for exiting the block
because of single-step or previous inhibit irq.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 6084c85609..778ee4ed4c 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -132,6 +132,10 @@ typedef struct DisasContext {
TCGOp *prev_insn_end;
} DisasContext;
+#define DISAS_EOB_ONLY DISAS_TARGET_0
+#define DISAS_EOB_NEXT DISAS_TARGET_1
+#define DISAS_EOB_INHIBIT_IRQ DISAS_TARGET_2
+
/* The environment in which user-only runs is constrained. */
#ifdef CONFIG_USER_ONLY
#define PE(S) true
@@ -8814,7 +8818,7 @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
* the flag and abort the translation to give the irqs a
* chance to happen.
*/
- dc->base.is_jmp = DISAS_TOO_MANY;
+ dc->base.is_jmp = DISAS_EOB_NEXT;
} else if (!is_same_page(&dc->base, pc_next)) {
dc->base.is_jmp = DISAS_TOO_MANY;
}
@@ -8826,9 +8830,24 @@ static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
- if (dc->base.is_jmp == DISAS_TOO_MANY) {
+ switch (dc->base.is_jmp) {
+ case DISAS_NORETURN:
+ break;
+ case DISAS_TOO_MANY:
+ case DISAS_EOB_NEXT:
+ gen_update_cc_op(dc);
gen_update_eip_cur(dc);
+ /* fall through */
+ case DISAS_EOB_ONLY:
gen_eob(dc);
+ break;
+ case DISAS_EOB_INHIBIT_IRQ:
+ gen_update_cc_op(dc);
+ gen_update_eip_cur(dc);
+ gen_eob_inhibit_irq(dc, true);
+ break;
+ default:
+ g_assert_not_reached();
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 07/23] target/i386: Introduce DISAS_EOB*
2022-09-06 10:09 ` [PATCH v2 07/23] target/i386: Introduce DISAS_EOB* Richard Henderson
@ 2022-09-21 12:05 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 12:05 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Add a few DISAS_TARGET_* aliases to reduce the number of
> calls to gen_eob() and gen_eob_inhibit_irq(). So far,
> only update i386_tr_translate_insn for exiting the block
> because of single-step or previous inhibit irq.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> target/i386/tcg/translate.c | 23 +++++++++++++++++++++--
> 1 file changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 6084c85609..778ee4ed4c 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -132,6 +132,10 @@ typedef struct DisasContext {
> TCGOp *prev_insn_end;
> } DisasContext;
>
> +#define DISAS_EOB_ONLY DISAS_TARGET_0
> +#define DISAS_EOB_NEXT DISAS_TARGET_1
> +#define DISAS_EOB_INHIBIT_IRQ DISAS_TARGET_2
> +
> /* The environment in which user-only runs is constrained. */
> #ifdef CONFIG_USER_ONLY
> #define PE(S) true
> @@ -8814,7 +8818,7 @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
> * the flag and abort the translation to give the irqs a
> * chance to happen.
> */
> - dc->base.is_jmp = DISAS_TOO_MANY;
> + dc->base.is_jmp = DISAS_EOB_NEXT;
> } else if (!is_same_page(&dc->base, pc_next)) {
> dc->base.is_jmp = DISAS_TOO_MANY;
> }
> @@ -8826,9 +8830,24 @@ static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
> {
> DisasContext *dc = container_of(dcbase, DisasContext, base);
>
> - if (dc->base.is_jmp == DISAS_TOO_MANY) {
> + switch (dc->base.is_jmp) {
> + case DISAS_NORETURN:
> + break;
> + case DISAS_TOO_MANY:
> + case DISAS_EOB_NEXT:
> + gen_update_cc_op(dc);
> gen_update_eip_cur(dc);
> + /* fall through */
> + case DISAS_EOB_ONLY:
> gen_eob(dc);
> + break;
> + case DISAS_EOB_INHIBIT_IRQ:
> + gen_update_cc_op(dc);
> + gen_update_eip_cur(dc);
> + gen_eob_inhibit_irq(dc, true);
> + break;
> + default:
> + g_assert_not_reached();
> }
> }
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 08/23] target/i386: Use DISAS_EOB* in gen_movl_seg_T0
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (6 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 07/23] target/i386: Introduce DISAS_EOB* Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 12:09 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 09/23] target/i386: Use DISAS_EOB_NEXT Richard Henderson
` (15 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Set is_jmp properly in gen_movl_seg_T0, so that the callers
need to nothing special.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 36 +++++-------------------------------
1 file changed, 5 insertions(+), 31 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 778ee4ed4c..ea35d3e9b4 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2432,13 +2432,15 @@ static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg)
because ss32 may change. For R_SS, translation must always
stop as a special handling must be done to disable hardware
interrupts for the next instruction */
- if (seg_reg == R_SS || (CODE32(s) && seg_reg < R_FS)) {
- s->base.is_jmp = DISAS_TOO_MANY;
+ if (seg_reg == R_SS) {
+ s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
+ } else if (CODE32(s) && seg_reg < R_FS) {
+ s->base.is_jmp = DISAS_EOB_NEXT;
}
} else {
gen_op_movl_seg_T0_vm(s, seg_reg);
if (seg_reg == R_SS) {
- s->base.is_jmp = DISAS_TOO_MANY;
+ s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
}
}
}
@@ -5682,26 +5684,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
ot = gen_pop_T0(s);
gen_movl_seg_T0(s, reg);
gen_pop_update(s, ot);
- /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
- if (s->base.is_jmp) {
- gen_update_eip_next(s);
- if (reg == R_SS) {
- s->flags &= ~HF_TF_MASK;
- gen_eob_inhibit_irq(s, true);
- } else {
- gen_eob(s);
- }
- }
break;
case 0x1a1: /* pop fs */
case 0x1a9: /* pop gs */
ot = gen_pop_T0(s);
gen_movl_seg_T0(s, (b >> 3) & 7);
gen_pop_update(s, ot);
- if (s->base.is_jmp) {
- gen_update_eip_next(s);
- gen_eob(s);
- }
break;
/**************************/
@@ -5748,16 +5736,6 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
gen_movl_seg_T0(s, reg);
- /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
- if (s->base.is_jmp) {
- gen_update_eip_next(s);
- if (reg == R_SS) {
- s->flags &= ~HF_TF_MASK;
- gen_eob_inhibit_irq(s, true);
- } else {
- gen_eob(s);
- }
- }
break;
case 0x8c: /* mov Gv, seg */
modrm = x86_ldub_code(env, s);
@@ -5956,10 +5934,6 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_movl_seg_T0(s, op);
/* then put the data */
gen_op_mov_reg_v(s, ot, reg, s->T1);
- if (s->base.is_jmp) {
- gen_update_eip_next(s);
- gen_eob(s);
- }
break;
/************************/
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 08/23] target/i386: Use DISAS_EOB* in gen_movl_seg_T0
2022-09-06 10:09 ` [PATCH v2 08/23] target/i386: Use DISAS_EOB* in gen_movl_seg_T0 Richard Henderson
@ 2022-09-21 12:09 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 12:09 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Set is_jmp properly in gen_movl_seg_T0, so that the callers
> need to nothing special.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> target/i386/tcg/translate.c | 36 +++++-------------------------------
> 1 file changed, 5 insertions(+), 31 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 778ee4ed4c..ea35d3e9b4 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -2432,13 +2432,15 @@ static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg)
> because ss32 may change. For R_SS, translation must always
> stop as a special handling must be done to disable hardware
> interrupts for the next instruction */
> - if (seg_reg == R_SS || (CODE32(s) && seg_reg < R_FS)) {
> - s->base.is_jmp = DISAS_TOO_MANY;
> + if (seg_reg == R_SS) {
> + s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
> + } else if (CODE32(s) && seg_reg < R_FS) {
> + s->base.is_jmp = DISAS_EOB_NEXT;
> }
> } else {
> gen_op_movl_seg_T0_vm(s, seg_reg);
> if (seg_reg == R_SS) {
> - s->base.is_jmp = DISAS_TOO_MANY;
> + s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
> }
> }
> }
> @@ -5682,26 +5684,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> ot = gen_pop_T0(s);
> gen_movl_seg_T0(s, reg);
> gen_pop_update(s, ot);
> - /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
> - if (s->base.is_jmp) {
> - gen_update_eip_next(s);
> - if (reg == R_SS) {
> - s->flags &= ~HF_TF_MASK;
> - gen_eob_inhibit_irq(s, true);
> - } else {
> - gen_eob(s);
> - }
> - }
> break;
> case 0x1a1: /* pop fs */
> case 0x1a9: /* pop gs */
> ot = gen_pop_T0(s);
> gen_movl_seg_T0(s, (b >> 3) & 7);
> gen_pop_update(s, ot);
> - if (s->base.is_jmp) {
> - gen_update_eip_next(s);
> - gen_eob(s);
> - }
> break;
>
> /**************************/
> @@ -5748,16 +5736,6 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
> gen_movl_seg_T0(s, reg);
> - /* Note that reg == R_SS in gen_movl_seg_T0 always sets is_jmp. */
> - if (s->base.is_jmp) {
> - gen_update_eip_next(s);
> - if (reg == R_SS) {
> - s->flags &= ~HF_TF_MASK;
> - gen_eob_inhibit_irq(s, true);
> - } else {
> - gen_eob(s);
> - }
> - }
> break;
> case 0x8c: /* mov Gv, seg */
> modrm = x86_ldub_code(env, s);
> @@ -5956,10 +5934,6 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_movl_seg_T0(s, op);
> /* then put the data */
> gen_op_mov_reg_v(s, ot, reg, s->T1);
> - if (s->base.is_jmp) {
> - gen_update_eip_next(s);
> - gen_eob(s);
> - }
> break;
>
> /************************/
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 09/23] target/i386: Use DISAS_EOB_NEXT
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (7 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 08/23] target/i386: Use DISAS_EOB* in gen_movl_seg_T0 Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 12:25 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 10/23] target/i386: USe DISAS_EOB_ONLY Richard Henderson
` (14 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Replace sequences of gen_update_cc_op, gen_update_eip_next,
and gen_eob with the new is_jmp enumerator.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 40 ++++++++++++-------------------------
1 file changed, 13 insertions(+), 27 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index ea35d3e9b4..a7e5bcdec7 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -6987,8 +6987,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_pop_update(s, ot);
set_cc_op(s, CC_OP_EFLAGS);
/* abort translation because TF/AC flag may change */
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
}
break;
case 0x9e: /* sahf */
@@ -7417,8 +7416,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_helper_rdmsr(cpu_env);
} else {
gen_helper_wrmsr(cpu_env);
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
}
}
break;
@@ -7617,8 +7615,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
gen_helper_clac(cpu_env);
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
break;
case 0xcb: /* stac */
@@ -7627,8 +7624,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
}
gen_helper_stac(cpu_env);
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
break;
CASE_MODRM_MEM_OP(1): /* sidt */
@@ -7672,8 +7668,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64);
/* End TB because translation flags may change. */
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
break;
case 0xd8: /* VMRUN */
@@ -7734,8 +7729,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
gen_update_cc_op(s);
gen_helper_stgi(cpu_env);
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
break;
case 0xdd: /* CLGI */
@@ -7773,8 +7767,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]);
}
gen_helper_flush_page(cpu_env, s->A0);
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
break;
CASE_MODRM_MEM_OP(2): /* lgdt */
@@ -7857,8 +7850,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
tcg_gen_andi_tl(s->T1, s->T1, ~0xe);
tcg_gen_or_tl(s->T0, s->T0, s->T1);
gen_helper_write_crN(cpu_env, tcg_constant_i32(0), s->T0);
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
break;
CASE_MODRM_MEM_OP(7): /* invlpg */
@@ -7868,8 +7860,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_svm_check_intercept(s, SVM_EXIT_INVLPG);
gen_lea_modrm(env, s, modrm);
gen_helper_flush_page(cpu_env, s->A0);
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
break;
case 0xf8: /* swapgs */
@@ -8268,8 +8259,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
gen_op_mov_v_reg(s, ot, s->T0, rm);
gen_helper_write_crN(cpu_env, tcg_constant_i32(reg), s->T0);
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
} else {
gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
gen_helper_read_crN(s->T0, cpu_env, tcg_constant_i32(reg));
@@ -8303,8 +8293,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_op_mov_v_reg(s, ot, s->T0, rm);
tcg_gen_movi_i32(s->tmp2_i32, reg);
gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0);
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
} else {
gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg);
tcg_gen_movi_i32(s->tmp2_i32, reg);
@@ -8318,8 +8307,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
gen_helper_clts(cpu_env);
/* abort block because static cpu state changed */
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
}
break;
/* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
@@ -8415,9 +8403,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_helper_xrstor(cpu_env, s->A0, s->tmp1_i64);
/* XRSTOR is how MPX is enabled, which changes how
we translate. Thus we need to end the TB. */
- gen_update_cc_op(s);
- gen_update_eip_next(s);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_NEXT;
break;
CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 09/23] target/i386: Use DISAS_EOB_NEXT
2022-09-06 10:09 ` [PATCH v2 09/23] target/i386: Use DISAS_EOB_NEXT Richard Henderson
@ 2022-09-21 12:25 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 12:25 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Replace sequences of gen_update_cc_op, gen_update_eip_next,
> and gen_eob with the new is_jmp enumerator.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> target/i386/tcg/translate.c | 40 ++++++++++++-------------------------
> 1 file changed, 13 insertions(+), 27 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index ea35d3e9b4..a7e5bcdec7 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -6987,8 +6987,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_pop_update(s, ot);
> set_cc_op(s, CC_OP_EFLAGS);
> /* abort translation because TF/AC flag may change */
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> }
> break;
> case 0x9e: /* sahf */
> @@ -7417,8 +7416,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_helper_rdmsr(cpu_env);
> } else {
> gen_helper_wrmsr(cpu_env);
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> }
> }
> break;
> @@ -7617,8 +7615,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> gen_helper_clac(cpu_env);
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> break;
>
> case 0xcb: /* stac */
> @@ -7627,8 +7624,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> goto illegal_op;
> }
> gen_helper_stac(cpu_env);
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> break;
>
> CASE_MODRM_MEM_OP(1): /* sidt */
> @@ -7672,8 +7668,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
> gen_helper_xsetbv(cpu_env, s->tmp2_i32, s->tmp1_i64);
> /* End TB because translation flags may change. */
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> break;
>
> case 0xd8: /* VMRUN */
> @@ -7734,8 +7729,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> gen_update_cc_op(s);
> gen_helper_stgi(cpu_env);
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> break;
>
> case 0xdd: /* CLGI */
> @@ -7773,8 +7767,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]);
> }
> gen_helper_flush_page(cpu_env, s->A0);
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> break;
>
> CASE_MODRM_MEM_OP(2): /* lgdt */
> @@ -7857,8 +7850,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> tcg_gen_andi_tl(s->T1, s->T1, ~0xe);
> tcg_gen_or_tl(s->T0, s->T0, s->T1);
> gen_helper_write_crN(cpu_env, tcg_constant_i32(0), s->T0);
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> break;
>
> CASE_MODRM_MEM_OP(7): /* invlpg */
> @@ -7868,8 +7860,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_svm_check_intercept(s, SVM_EXIT_INVLPG);
> gen_lea_modrm(env, s, modrm);
> gen_helper_flush_page(cpu_env, s->A0);
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> break;
>
> case 0xf8: /* swapgs */
> @@ -8268,8 +8259,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
> gen_op_mov_v_reg(s, ot, s->T0, rm);
> gen_helper_write_crN(cpu_env, tcg_constant_i32(reg), s->T0);
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> } else {
> gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
> gen_helper_read_crN(s->T0, cpu_env, tcg_constant_i32(reg));
> @@ -8303,8 +8293,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_op_mov_v_reg(s, ot, s->T0, rm);
> tcg_gen_movi_i32(s->tmp2_i32, reg);
> gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0);
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> } else {
> gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg);
> tcg_gen_movi_i32(s->tmp2_i32, reg);
> @@ -8318,8 +8307,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
> gen_helper_clts(cpu_env);
> /* abort block because static cpu state changed */
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> }
> break;
> /* MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4 support */
> @@ -8415,9 +8403,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_helper_xrstor(cpu_env, s->A0, s->tmp1_i64);
> /* XRSTOR is how MPX is enabled, which changes how
> we translate. Thus we need to end the TB. */
> - gen_update_cc_op(s);
> - gen_update_eip_next(s);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_NEXT;
> break;
>
> CASE_MODRM_MEM_OP(6): /* xsaveopt / clwb */
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 10/23] target/i386: USe DISAS_EOB_ONLY
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (8 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 09/23] target/i386: Use DISAS_EOB_NEXT Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 12:10 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 11/23] target/i386: Create cur_insn_len, cur_insn_len_i32 Richard Henderson
` (13 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Replace lone calls to gen_eob() with the new enumerator.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index a7e5bcdec7..5b77414a0a 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -6800,7 +6800,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
/* add stack offset */
gen_stack_update(s, val + (2 << dflag));
}
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_ONLY;
break;
case 0xcb: /* lret */
val = 0;
@@ -6818,7 +6818,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
tcg_const_i32(s->pc - s->cs_base));
}
set_cc_op(s, CC_OP_EFLAGS);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_ONLY;
break;
case 0xe8: /* call im */
{
@@ -7404,7 +7404,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_set_label(l1);
gen_jmp_im(s, tval);
gen_set_label(l2);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_ONLY;
}
break;
case 0x130: /* wrmsr */
@@ -7445,7 +7445,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_exception_gpf(s);
} else {
gen_helper_sysenter(cpu_env);
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_ONLY;
}
break;
case 0x135: /* sysexit */
@@ -7456,7 +7456,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_exception_gpf(s);
} else {
gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_ONLY;
}
break;
#ifdef TARGET_X86_64
@@ -8539,7 +8539,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_update_eip_next(s);
gen_helper_rsm(cpu_env);
#endif /* CONFIG_USER_ONLY */
- gen_eob(s);
+ s->base.is_jmp = DISAS_EOB_ONLY;
break;
case 0x1b8: /* SSE4.2 popcnt */
if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 10/23] target/i386: USe DISAS_EOB_ONLY
2022-09-06 10:09 ` [PATCH v2 10/23] target/i386: USe DISAS_EOB_ONLY Richard Henderson
@ 2022-09-21 12:10 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 12:10 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Replace lone calls to gen_eob() with the new enumerator.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> target/i386/tcg/translate.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index a7e5bcdec7..5b77414a0a 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -6800,7 +6800,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> /* add stack offset */
> gen_stack_update(s, val + (2 << dflag));
> }
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_ONLY;
> break;
> case 0xcb: /* lret */
> val = 0;
> @@ -6818,7 +6818,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> tcg_const_i32(s->pc - s->cs_base));
> }
> set_cc_op(s, CC_OP_EFLAGS);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_ONLY;
> break;
> case 0xe8: /* call im */
> {
> @@ -7404,7 +7404,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_set_label(l1);
> gen_jmp_im(s, tval);
> gen_set_label(l2);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_ONLY;
> }
> break;
> case 0x130: /* wrmsr */
> @@ -7445,7 +7445,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_exception_gpf(s);
> } else {
> gen_helper_sysenter(cpu_env);
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_ONLY;
> }
> break;
> case 0x135: /* sysexit */
> @@ -7456,7 +7456,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_exception_gpf(s);
> } else {
> gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_ONLY;
> }
> break;
> #ifdef TARGET_X86_64
> @@ -8539,7 +8539,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_update_eip_next(s);
> gen_helper_rsm(cpu_env);
> #endif /* CONFIG_USER_ONLY */
> - gen_eob(s);
> + s->base.is_jmp = DISAS_EOB_ONLY;
> break;
> case 0x1b8: /* SSE4.2 popcnt */
> if ((prefixes & (PREFIX_REPZ | PREFIX_LOCK | PREFIX_REPNZ)) !=
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 11/23] target/i386: Create cur_insn_len, cur_insn_len_i32
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (9 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 10/23] target/i386: USe DISAS_EOB_ONLY Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-06 14:49 ` Philippe Mathieu-Daudé via
2022-09-06 10:09 ` [PATCH v2 12/23] target/i386: Remove cur_eip, next_eip arguments to gen_repz* Richard Henderson
` (12 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Create common routines for computing the length of the insn.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 5b77414a0a..393a1c1075 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -530,6 +530,16 @@ static void gen_update_eip_next(DisasContext *s)
gen_jmp_im(s, s->pc - s->cs_base);
}
+static int cur_insn_len(DisasContext *s)
+{
+ return s->pc - s->base.pc_next;
+}
+
+static TCGv_i32 cur_insn_len_i32(DisasContext *s)
+{
+ return tcg_constant_i32(cur_insn_len(s));
+}
+
/* Compute SEG:REG into A0. SEG is selected from the override segment
(OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
indicate no override. */
@@ -712,9 +722,6 @@ static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
gen_helper_check_io(cpu_env, port, tcg_constant_i32(1 << ot));
}
if (GUEST(s)) {
- target_ulong cur_eip = s->base.pc_next - s->cs_base;
- target_ulong next_eip = s->pc - s->cs_base;
-
gen_update_cc_op(s);
gen_update_eip_cur(s);
if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
@@ -723,7 +730,7 @@ static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot);
gen_helper_svm_check_io(cpu_env, port,
tcg_constant_i32(svm_flags),
- tcg_constant_i32(next_eip - cur_eip));
+ cur_insn_len_i32(s));
}
return true;
#endif
@@ -2028,7 +2035,7 @@ static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
}
s->pc += num_bytes;
- if (unlikely(s->pc - s->base.pc_next > X86_MAX_INSN_LENGTH)) {
+ if (unlikely(cur_insn_len(s) > X86_MAX_INSN_LENGTH)) {
/* If the instruction's 16th byte is on a different page than the 1st, a
* page fault on the second page wins over the general protection fault
* caused by the instruction being too long.
@@ -2622,7 +2629,7 @@ static void gen_interrupt(DisasContext *s, int intno)
gen_update_cc_op(s);
gen_update_eip_cur(s);
gen_helper_raise_interrupt(cpu_env, tcg_constant_i32(intno),
- tcg_constant_i32(s->pc - s->base.pc_next));
+ cur_insn_len_i32(s));
s->base.is_jmp = DISAS_NORETURN;
}
@@ -7279,7 +7286,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
if (prefixes & PREFIX_REPZ) {
gen_update_cc_op(s);
gen_update_eip_cur(s);
- gen_helper_pause(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
+ gen_helper_pause(cpu_env, cur_insn_len_i32(s));
s->base.is_jmp = DISAS_NORETURN;
}
break;
@@ -7305,7 +7312,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
gen_update_cc_op(s);
gen_update_eip_cur(s);
- gen_helper_into(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
+ gen_helper_into(cpu_env, cur_insn_len_i32(s));
break;
#ifdef WANT_ICEBP
case 0xf1: /* icebp (undocumented, exits to external debugger) */
@@ -7464,7 +7471,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
/* XXX: is it usable in real mode ? */
gen_update_cc_op(s);
gen_update_eip_cur(s);
- gen_helper_syscall(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
+ gen_helper_syscall(cpu_env, cur_insn_len_i32(s));
/* TF handling for the syscall insn is different. The TF bit is checked
after the syscall insn completes. This allows #DB to not be
generated after one has entered CPL0 if TF is set in FMASK. */
@@ -7496,7 +7503,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
if (check_cpl0(s)) {
gen_update_cc_op(s);
gen_update_eip_cur(s);
- gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
+ gen_helper_hlt(cpu_env, cur_insn_len_i32(s));
s->base.is_jmp = DISAS_NORETURN;
}
break;
@@ -7605,7 +7612,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
gen_update_cc_op(s);
gen_update_eip_cur(s);
- gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - s->base.pc_next));
+ gen_helper_mwait(cpu_env, cur_insn_len_i32(s));
s->base.is_jmp = DISAS_NORETURN;
break;
@@ -7681,7 +7688,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_update_cc_op(s);
gen_update_eip_cur(s);
gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
- tcg_const_i32(s->pc - s->base.pc_next));
+ cur_insn_len_i32(s));
tcg_gen_exit_tb(NULL, 0);
s->base.is_jmp = DISAS_NORETURN;
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 11/23] target/i386: Create cur_insn_len, cur_insn_len_i32
2022-09-06 10:09 ` [PATCH v2 11/23] target/i386: Create cur_insn_len, cur_insn_len_i32 Richard Henderson
@ 2022-09-06 14:49 ` Philippe Mathieu-Daudé via
2022-09-21 12:25 ` Paolo Bonzini
0 siblings, 1 reply; 61+ messages in thread
From: Philippe Mathieu-Daudé via @ 2022-09-06 14:49 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: pbonzini
On 6/9/22 12:09, Richard Henderson wrote:
> Create common routines for computing the length of the insn.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/i386/tcg/translate.c | 31 +++++++++++++++++++------------
> 1 file changed, 19 insertions(+), 12 deletions(-)
And tcg_const -> tcg_constant.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 11/23] target/i386: Create cur_insn_len, cur_insn_len_i32
2022-09-06 14:49 ` Philippe Mathieu-Daudé via
@ 2022-09-21 12:25 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 12:25 UTC (permalink / raw)
To: Philippe Mathieu-Daudé; +Cc: Richard Henderson, qemu-devel
On Tue, Sep 6, 2022 at 4:50 PM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
> On 6/9/22 12:09, Richard Henderson wrote:
> > Create common routines for computing the length of the insn.
> >
> > Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> > ---
> > target/i386/tcg/translate.c | 31 +++++++++++++++++++------------
> > 1 file changed, 19 insertions(+), 12 deletions(-)
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Paolo
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 12/23] target/i386: Remove cur_eip, next_eip arguments to gen_repz*
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (10 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 11/23] target/i386: Create cur_insn_len, cur_insn_len_i32 Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 12:26 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 13/23] target/i386: Introduce DISAS_JUMP Richard Henderson
` (11 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
All callers pass s->base.pc_next and s->pc, which we can just
as well compute within the functions. Pull out common helpers
and reduce the amount of code under macros.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 116 ++++++++++++++++++------------------
1 file changed, 57 insertions(+), 59 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 393a1c1075..f3c26a9956 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -736,7 +736,7 @@ static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
#endif
}
-static inline void gen_movs(DisasContext *s, MemOp ot)
+static void gen_movs(DisasContext *s, MemOp ot)
{
gen_string_movl_A0_ESI(s);
gen_op_ld_v(s, ot, s->T0, s->A0);
@@ -1156,18 +1156,18 @@ static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
/* XXX: does not work with gdbstub "ice" single step - not a
serious problem */
-static TCGLabel *gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
+static TCGLabel *gen_jz_ecx_string(DisasContext *s)
{
TCGLabel *l1 = gen_new_label();
TCGLabel *l2 = gen_new_label();
gen_op_jnz_ecx(s, s->aflag, l1);
gen_set_label(l2);
- gen_jmp_tb(s, next_eip, 1);
+ gen_jmp_tb(s, s->pc - s->cs_base, 1);
gen_set_label(l1);
return l2;
}
-static inline void gen_stos(DisasContext *s, MemOp ot)
+static void gen_stos(DisasContext *s, MemOp ot)
{
gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
gen_string_movl_A0_EDI(s);
@@ -1176,7 +1176,7 @@ static inline void gen_stos(DisasContext *s, MemOp ot)
gen_op_add_reg_T0(s, s->aflag, R_EDI);
}
-static inline void gen_lods(DisasContext *s, MemOp ot)
+static void gen_lods(DisasContext *s, MemOp ot)
{
gen_string_movl_A0_ESI(s);
gen_op_ld_v(s, ot, s->T0, s->A0);
@@ -1185,7 +1185,7 @@ static inline void gen_lods(DisasContext *s, MemOp ot)
gen_op_add_reg_T0(s, s->aflag, R_ESI);
}
-static inline void gen_scas(DisasContext *s, MemOp ot)
+static void gen_scas(DisasContext *s, MemOp ot)
{
gen_string_movl_A0_EDI(s);
gen_op_ld_v(s, ot, s->T1, s->A0);
@@ -1194,7 +1194,7 @@ static inline void gen_scas(DisasContext *s, MemOp ot)
gen_op_add_reg_T0(s, s->aflag, R_EDI);
}
-static inline void gen_cmps(DisasContext *s, MemOp ot)
+static void gen_cmps(DisasContext *s, MemOp ot)
{
gen_string_movl_A0_EDI(s);
gen_op_ld_v(s, ot, s->T1, s->A0);
@@ -1222,7 +1222,7 @@ static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
}
}
-static inline void gen_ins(DisasContext *s, MemOp ot)
+static void gen_ins(DisasContext *s, MemOp ot)
{
gen_string_movl_A0_EDI(s);
/* Note: we must do this dummy write first to be restartable in
@@ -1238,7 +1238,7 @@ static inline void gen_ins(DisasContext *s, MemOp ot)
gen_bpt_io(s, s->tmp2_i32, ot);
}
-static inline void gen_outs(DisasContext *s, MemOp ot)
+static void gen_outs(DisasContext *s, MemOp ot)
{
gen_string_movl_A0_ESI(s);
gen_op_ld_v(s, ot, s->T0, s->A0);
@@ -1252,42 +1252,49 @@ static inline void gen_outs(DisasContext *s, MemOp ot)
gen_bpt_io(s, s->tmp2_i32, ot);
}
-/* same method as Valgrind : we generate jumps to current or next
- instruction */
-#define GEN_REPZ(op) \
-static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, \
- target_ulong cur_eip, target_ulong next_eip) \
-{ \
- TCGLabel *l2; \
- gen_update_cc_op(s); \
- l2 = gen_jz_ecx_string(s, next_eip); \
- gen_ ## op(s, ot); \
- gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
- /* a loop would cause two single step exceptions if ECX = 1 \
- before rep string_insn */ \
- if (s->repz_opt) \
- gen_op_jz_ecx(s, s->aflag, l2); \
- gen_jmp(s, cur_eip); \
+/* Generate jumps to current or next instruction */
+static void gen_repz(DisasContext *s, MemOp ot,
+ void (*fn)(DisasContext *s, MemOp ot))
+{
+ TCGLabel *l2;
+ gen_update_cc_op(s);
+ l2 = gen_jz_ecx_string(s);
+ fn(s, ot);
+ gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
+ /*
+ * A loop would cause two single step exceptions if ECX = 1
+ * before rep string_insn
+ */
+ if (s->repz_opt) {
+ gen_op_jz_ecx(s, s->aflag, l2);
+ }
+ gen_jmp(s, s->base.pc_next - s->cs_base);
}
-#define GEN_REPZ2(op) \
-static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, \
- target_ulong cur_eip, \
- target_ulong next_eip, \
- int nz) \
-{ \
- TCGLabel *l2; \
- gen_update_cc_op(s); \
- l2 = gen_jz_ecx_string(s, next_eip); \
- gen_ ## op(s, ot); \
- gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
- gen_update_cc_op(s); \
- gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
- if (s->repz_opt) \
- gen_op_jz_ecx(s, s->aflag, l2); \
- gen_jmp(s, cur_eip); \
+#define GEN_REPZ(op) \
+ static inline void gen_repz_ ## op(DisasContext *s, MemOp ot) \
+ { gen_repz(s, ot, gen_##op); }
+
+static void gen_repz2(DisasContext *s, MemOp ot, int nz,
+ void (*fn)(DisasContext *s, MemOp ot))
+{
+ TCGLabel *l2;
+ gen_update_cc_op(s);
+ l2 = gen_jz_ecx_string(s);
+ fn(s, ot);
+ gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
+ gen_update_cc_op(s);
+ gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2);
+ if (s->repz_opt) {
+ gen_op_jz_ecx(s, s->aflag, l2);
+ }
+ gen_jmp(s, s->base.pc_next - s->cs_base);
}
+#define GEN_REPZ2(op) \
+ static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, int nz) \
+ { gen_repz2(s, ot, nz, gen_##op); }
+
GEN_REPZ(movs)
GEN_REPZ(stos)
GEN_REPZ(lods)
@@ -6588,8 +6595,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
case 0xa5:
ot = mo_b_d(b, dflag);
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_movs(s, ot, s->base.pc_next - s->cs_base,
- s->pc - s->cs_base);
+ gen_repz_movs(s, ot);
} else {
gen_movs(s, ot);
}
@@ -6599,8 +6605,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
case 0xab:
ot = mo_b_d(b, dflag);
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_stos(s, ot, s->base.pc_next - s->cs_base,
- s->pc - s->cs_base);
+ gen_repz_stos(s, ot);
} else {
gen_stos(s, ot);
}
@@ -6609,8 +6614,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
case 0xad:
ot = mo_b_d(b, dflag);
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_lods(s, ot, s->base.pc_next - s->cs_base,
- s->pc - s->cs_base);
+ gen_repz_lods(s, ot);
} else {
gen_lods(s, ot);
}
@@ -6619,11 +6623,9 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
case 0xaf:
ot = mo_b_d(b, dflag);
if (prefixes & PREFIX_REPNZ) {
- gen_repz_scas(s, ot, s->base.pc_next - s->cs_base,
- s->pc - s->cs_base, 1);
+ gen_repz_scas(s, ot, 1);
} else if (prefixes & PREFIX_REPZ) {
- gen_repz_scas(s, ot, s->base.pc_next - s->cs_base,
- s->pc - s->cs_base, 0);
+ gen_repz_scas(s, ot, 0);
} else {
gen_scas(s, ot);
}
@@ -6633,11 +6635,9 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
case 0xa7:
ot = mo_b_d(b, dflag);
if (prefixes & PREFIX_REPNZ) {
- gen_repz_cmps(s, ot, s->base.pc_next - s->cs_base,
- s->pc - s->cs_base, 1);
+ gen_repz_cmps(s, ot, 1);
} else if (prefixes & PREFIX_REPZ) {
- gen_repz_cmps(s, ot, s->base.pc_next - s->cs_base,
- s->pc - s->cs_base, 0);
+ gen_repz_cmps(s, ot, 0);
} else {
gen_cmps(s, ot);
}
@@ -6655,8 +6655,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_io_start();
}
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_ins(s, ot, s->base.pc_next - s->cs_base,
- s->pc - s->cs_base);
+ gen_repz_ins(s, ot);
/* jump generated by gen_repz_ins */
} else {
gen_ins(s, ot);
@@ -6677,8 +6676,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_io_start();
}
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
- gen_repz_outs(s, ot, s->base.pc_next - s->cs_base,
- s->pc - s->cs_base);
+ gen_repz_outs(s, ot);
/* jump generated by gen_repz_outs */
} else {
gen_outs(s, ot);
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 12/23] target/i386: Remove cur_eip, next_eip arguments to gen_repz*
2022-09-06 10:09 ` [PATCH v2 12/23] target/i386: Remove cur_eip, next_eip arguments to gen_repz* Richard Henderson
@ 2022-09-21 12:26 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 12:26 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> All callers pass s->base.pc_next and s->pc, which we can just
> as well compute within the functions. Pull out common helpers
> and reduce the amount of code under macros.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> target/i386/tcg/translate.c | 116 ++++++++++++++++++------------------
> 1 file changed, 57 insertions(+), 59 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 393a1c1075..f3c26a9956 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -736,7 +736,7 @@ static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
> #endif
> }
>
> -static inline void gen_movs(DisasContext *s, MemOp ot)
> +static void gen_movs(DisasContext *s, MemOp ot)
> {
> gen_string_movl_A0_ESI(s);
> gen_op_ld_v(s, ot, s->T0, s->A0);
> @@ -1156,18 +1156,18 @@ static inline void gen_jcc1(DisasContext *s, int b, TCGLabel *l1)
>
> /* XXX: does not work with gdbstub "ice" single step - not a
> serious problem */
> -static TCGLabel *gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
> +static TCGLabel *gen_jz_ecx_string(DisasContext *s)
> {
> TCGLabel *l1 = gen_new_label();
> TCGLabel *l2 = gen_new_label();
> gen_op_jnz_ecx(s, s->aflag, l1);
> gen_set_label(l2);
> - gen_jmp_tb(s, next_eip, 1);
> + gen_jmp_tb(s, s->pc - s->cs_base, 1);
> gen_set_label(l1);
> return l2;
> }
>
> -static inline void gen_stos(DisasContext *s, MemOp ot)
> +static void gen_stos(DisasContext *s, MemOp ot)
> {
> gen_op_mov_v_reg(s, MO_32, s->T0, R_EAX);
> gen_string_movl_A0_EDI(s);
> @@ -1176,7 +1176,7 @@ static inline void gen_stos(DisasContext *s, MemOp ot)
> gen_op_add_reg_T0(s, s->aflag, R_EDI);
> }
>
> -static inline void gen_lods(DisasContext *s, MemOp ot)
> +static void gen_lods(DisasContext *s, MemOp ot)
> {
> gen_string_movl_A0_ESI(s);
> gen_op_ld_v(s, ot, s->T0, s->A0);
> @@ -1185,7 +1185,7 @@ static inline void gen_lods(DisasContext *s, MemOp ot)
> gen_op_add_reg_T0(s, s->aflag, R_ESI);
> }
>
> -static inline void gen_scas(DisasContext *s, MemOp ot)
> +static void gen_scas(DisasContext *s, MemOp ot)
> {
> gen_string_movl_A0_EDI(s);
> gen_op_ld_v(s, ot, s->T1, s->A0);
> @@ -1194,7 +1194,7 @@ static inline void gen_scas(DisasContext *s, MemOp ot)
> gen_op_add_reg_T0(s, s->aflag, R_EDI);
> }
>
> -static inline void gen_cmps(DisasContext *s, MemOp ot)
> +static void gen_cmps(DisasContext *s, MemOp ot)
> {
> gen_string_movl_A0_EDI(s);
> gen_op_ld_v(s, ot, s->T1, s->A0);
> @@ -1222,7 +1222,7 @@ static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
> }
> }
>
> -static inline void gen_ins(DisasContext *s, MemOp ot)
> +static void gen_ins(DisasContext *s, MemOp ot)
> {
> gen_string_movl_A0_EDI(s);
> /* Note: we must do this dummy write first to be restartable in
> @@ -1238,7 +1238,7 @@ static inline void gen_ins(DisasContext *s, MemOp ot)
> gen_bpt_io(s, s->tmp2_i32, ot);
> }
>
> -static inline void gen_outs(DisasContext *s, MemOp ot)
> +static void gen_outs(DisasContext *s, MemOp ot)
> {
> gen_string_movl_A0_ESI(s);
> gen_op_ld_v(s, ot, s->T0, s->A0);
> @@ -1252,42 +1252,49 @@ static inline void gen_outs(DisasContext *s, MemOp ot)
> gen_bpt_io(s, s->tmp2_i32, ot);
> }
>
> -/* same method as Valgrind : we generate jumps to current or next
> - instruction */
> -#define GEN_REPZ(op) \
> -static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, \
> - target_ulong cur_eip, target_ulong next_eip) \
> -{ \
> - TCGLabel *l2; \
> - gen_update_cc_op(s); \
> - l2 = gen_jz_ecx_string(s, next_eip); \
> - gen_ ## op(s, ot); \
> - gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
> - /* a loop would cause two single step exceptions if ECX = 1 \
> - before rep string_insn */ \
> - if (s->repz_opt) \
> - gen_op_jz_ecx(s, s->aflag, l2); \
> - gen_jmp(s, cur_eip); \
> +/* Generate jumps to current or next instruction */
> +static void gen_repz(DisasContext *s, MemOp ot,
> + void (*fn)(DisasContext *s, MemOp ot))
> +{
> + TCGLabel *l2;
> + gen_update_cc_op(s);
> + l2 = gen_jz_ecx_string(s);
> + fn(s, ot);
> + gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
> + /*
> + * A loop would cause two single step exceptions if ECX = 1
> + * before rep string_insn
> + */
> + if (s->repz_opt) {
> + gen_op_jz_ecx(s, s->aflag, l2);
> + }
> + gen_jmp(s, s->base.pc_next - s->cs_base);
> }
>
> -#define GEN_REPZ2(op) \
> -static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, \
> - target_ulong cur_eip, \
> - target_ulong next_eip, \
> - int nz) \
> -{ \
> - TCGLabel *l2; \
> - gen_update_cc_op(s); \
> - l2 = gen_jz_ecx_string(s, next_eip); \
> - gen_ ## op(s, ot); \
> - gen_op_add_reg_im(s, s->aflag, R_ECX, -1); \
> - gen_update_cc_op(s); \
> - gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
> - if (s->repz_opt) \
> - gen_op_jz_ecx(s, s->aflag, l2); \
> - gen_jmp(s, cur_eip); \
> +#define GEN_REPZ(op) \
> + static inline void gen_repz_ ## op(DisasContext *s, MemOp ot) \
> + { gen_repz(s, ot, gen_##op); }
> +
> +static void gen_repz2(DisasContext *s, MemOp ot, int nz,
> + void (*fn)(DisasContext *s, MemOp ot))
> +{
> + TCGLabel *l2;
> + gen_update_cc_op(s);
> + l2 = gen_jz_ecx_string(s);
> + fn(s, ot);
> + gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
> + gen_update_cc_op(s);
> + gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2);
> + if (s->repz_opt) {
> + gen_op_jz_ecx(s, s->aflag, l2);
> + }
> + gen_jmp(s, s->base.pc_next - s->cs_base);
> }
>
> +#define GEN_REPZ2(op) \
> + static inline void gen_repz_ ## op(DisasContext *s, MemOp ot, int nz) \
> + { gen_repz2(s, ot, nz, gen_##op); }
> +
> GEN_REPZ(movs)
> GEN_REPZ(stos)
> GEN_REPZ(lods)
> @@ -6588,8 +6595,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> case 0xa5:
> ot = mo_b_d(b, dflag);
> if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
> - gen_repz_movs(s, ot, s->base.pc_next - s->cs_base,
> - s->pc - s->cs_base);
> + gen_repz_movs(s, ot);
> } else {
> gen_movs(s, ot);
> }
> @@ -6599,8 +6605,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> case 0xab:
> ot = mo_b_d(b, dflag);
> if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
> - gen_repz_stos(s, ot, s->base.pc_next - s->cs_base,
> - s->pc - s->cs_base);
> + gen_repz_stos(s, ot);
> } else {
> gen_stos(s, ot);
> }
> @@ -6609,8 +6614,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> case 0xad:
> ot = mo_b_d(b, dflag);
> if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
> - gen_repz_lods(s, ot, s->base.pc_next - s->cs_base,
> - s->pc - s->cs_base);
> + gen_repz_lods(s, ot);
> } else {
> gen_lods(s, ot);
> }
> @@ -6619,11 +6623,9 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> case 0xaf:
> ot = mo_b_d(b, dflag);
> if (prefixes & PREFIX_REPNZ) {
> - gen_repz_scas(s, ot, s->base.pc_next - s->cs_base,
> - s->pc - s->cs_base, 1);
> + gen_repz_scas(s, ot, 1);
> } else if (prefixes & PREFIX_REPZ) {
> - gen_repz_scas(s, ot, s->base.pc_next - s->cs_base,
> - s->pc - s->cs_base, 0);
> + gen_repz_scas(s, ot, 0);
> } else {
> gen_scas(s, ot);
> }
> @@ -6633,11 +6635,9 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> case 0xa7:
> ot = mo_b_d(b, dflag);
> if (prefixes & PREFIX_REPNZ) {
> - gen_repz_cmps(s, ot, s->base.pc_next - s->cs_base,
> - s->pc - s->cs_base, 1);
> + gen_repz_cmps(s, ot, 1);
> } else if (prefixes & PREFIX_REPZ) {
> - gen_repz_cmps(s, ot, s->base.pc_next - s->cs_base,
> - s->pc - s->cs_base, 0);
> + gen_repz_cmps(s, ot, 0);
> } else {
> gen_cmps(s, ot);
> }
> @@ -6655,8 +6655,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_io_start();
> }
> if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
> - gen_repz_ins(s, ot, s->base.pc_next - s->cs_base,
> - s->pc - s->cs_base);
> + gen_repz_ins(s, ot);
> /* jump generated by gen_repz_ins */
> } else {
> gen_ins(s, ot);
> @@ -6677,8 +6676,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_io_start();
> }
> if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
> - gen_repz_outs(s, ot, s->base.pc_next - s->cs_base,
> - s->pc - s->cs_base);
> + gen_repz_outs(s, ot);
> /* jump generated by gen_repz_outs */
> } else {
> gen_outs(s, ot);
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 13/23] target/i386: Introduce DISAS_JUMP
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (11 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 12/23] target/i386: Remove cur_eip, next_eip arguments to gen_repz* Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 12:28 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 14/23] target/i386: Truncate values for lcall_real to i32 Richard Henderson
` (10 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Drop the unused dest argument to gen_jr().
Remove most of the calls to gen_jr, and use DISAS_JUMP.
Remove some unused loads of eip for lcall and ljmp.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index f3c26a9956..1997f8d291 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -135,6 +135,7 @@ typedef struct DisasContext {
#define DISAS_EOB_ONLY DISAS_TARGET_0
#define DISAS_EOB_NEXT DISAS_TARGET_1
#define DISAS_EOB_INHIBIT_IRQ DISAS_TARGET_2
+#define DISAS_JUMP DISAS_TARGET_3
/* The environment in which user-only runs is constrained. */
#ifdef CONFIG_USER_ONLY
@@ -222,7 +223,7 @@ STUB_HELPER(wrmsr, TCGv_env env)
#endif
static void gen_eob(DisasContext *s);
-static void gen_jr(DisasContext *s, TCGv dest);
+static void gen_jr(DisasContext *s);
static void gen_jmp(DisasContext *s, target_ulong eip);
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
static void gen_op(DisasContext *s1, int op, MemOp ot, int d);
@@ -2360,7 +2361,7 @@ static void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
} else {
/* jump to another page */
gen_jmp_im(s, eip);
- gen_jr(s, s->tmp0);
+ gen_jr(s);
}
}
@@ -2729,7 +2730,7 @@ static void gen_eob(DisasContext *s)
}
/* Jump to register */
-static void gen_jr(DisasContext *s, TCGv dest)
+static void gen_jr(DisasContext *s)
{
do_gen_eob_worker(s, false, false, true);
}
@@ -5284,7 +5285,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_push_v(s, s->T1);
gen_op_jmp_v(s->T0);
gen_bnd_jmp(s);
- gen_jr(s, s->T0);
+ s->base.is_jmp = DISAS_JUMP;
break;
case 3: /* lcall Ev */
if (mod == 3) {
@@ -5305,8 +5306,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
tcg_const_i32(dflag - 1),
tcg_const_i32(s->pc - s->cs_base));
}
- tcg_gen_ld_tl(s->tmp4, cpu_env, offsetof(CPUX86State, eip));
- gen_jr(s, s->tmp4);
+ s->base.is_jmp = DISAS_JUMP;
break;
case 4: /* jmp Ev */
if (dflag == MO_16) {
@@ -5314,7 +5314,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
gen_op_jmp_v(s->T0);
gen_bnd_jmp(s);
- gen_jr(s, s->T0);
+ s->base.is_jmp = DISAS_JUMP;
break;
case 5: /* ljmp Ev */
if (mod == 3) {
@@ -5332,8 +5332,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_op_movl_seg_T0_vm(s, R_CS);
gen_op_jmp_v(s->T1);
}
- tcg_gen_ld_tl(s->tmp4, cpu_env, offsetof(CPUX86State, eip));
- gen_jr(s, s->tmp4);
+ s->base.is_jmp = DISAS_JUMP;
break;
case 6: /* push Ev */
gen_push_v(s, s->T0);
@@ -6773,7 +6772,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
/* Note that gen_pop_T0 uses a zero-extending load. */
gen_op_jmp_v(s->T0);
gen_bnd_jmp(s);
- gen_jr(s, s->T0);
+ s->base.is_jmp = DISAS_JUMP;
break;
case 0xc3: /* ret */
ot = gen_pop_T0(s);
@@ -6781,7 +6780,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
/* Note that gen_pop_T0 uses a zero-extending load. */
gen_op_jmp_v(s->T0);
gen_bnd_jmp(s);
- gen_jr(s, s->T0);
+ s->base.is_jmp = DISAS_JUMP;
break;
case 0xca: /* lret im */
val = x86_ldsw_code(env, s);
@@ -8811,6 +8810,9 @@ static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
gen_update_eip_cur(dc);
gen_eob_inhibit_irq(dc, true);
break;
+ case DISAS_JUMP:
+ gen_jr(dc);
+ break;
default:
g_assert_not_reached();
}
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 13/23] target/i386: Introduce DISAS_JUMP
2022-09-06 10:09 ` [PATCH v2 13/23] target/i386: Introduce DISAS_JUMP Richard Henderson
@ 2022-09-21 12:28 ` Paolo Bonzini
2022-09-21 23:27 ` Richard Henderson
0 siblings, 1 reply; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 12:28 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Drop the unused dest argument to gen_jr().
> Remove most of the calls to gen_jr, and use DISAS_JUMP.
> Remove some unused loads of eip for lcall and ljmp.
The only use outside i386_tr_tb_stop is here:
static void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
{
target_ulong pc = s->cs_base + eip;
if (translator_use_goto_tb(&s->base, pc)) {
/* jump to same page: we can use a direct jump */
tcg_gen_goto_tb(tb_num);
gen_jmp_im(s, eip);
tcg_gen_exit_tb(s->base.tb, tb_num);
s->base.is_jmp = DISAS_NORETURN;
} else {
/* jump to another page */
gen_jmp_im(s, eip);
gen_jr(s);
}
}
Should it set s->base.is_jmp = DISAS_JUMP instead, so that gen_jr() can be
inlined into i386_tr_tb_stop() and removed completely? If not,
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Paolo
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 13/23] target/i386: Introduce DISAS_JUMP
2022-09-21 12:28 ` Paolo Bonzini
@ 2022-09-21 23:27 ` Richard Henderson
0 siblings, 0 replies; 61+ messages in thread
From: Richard Henderson @ 2022-09-21 23:27 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 9/21/22 12:28, Paolo Bonzini wrote:
> On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> Drop the unused dest argument to gen_jr().
>> Remove most of the calls to gen_jr, and use DISAS_JUMP.
>> Remove some unused loads of eip for lcall and ljmp.
>
> The only use outside i386_tr_tb_stop is here:
>
> static void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
> {
> target_ulong pc = s->cs_base + eip;
>
> if (translator_use_goto_tb(&s->base, pc)) {
> /* jump to same page: we can use a direct jump */
> tcg_gen_goto_tb(tb_num);
> gen_jmp_im(s, eip);
> tcg_gen_exit_tb(s->base.tb, tb_num);
> s->base.is_jmp = DISAS_NORETURN;
> } else {
> /* jump to another page */
> gen_jmp_im(s, eip);
> gen_jr(s);
> }
> }
>
> Should it set s->base.is_jmp = DISAS_JUMP instead, so that gen_jr() can be
> inlined into i386_tr_tb_stop() and removed completely? If not,
It can't, because of conditional branches which do
brcond something, L1
gen_goto_tb
L1
gen_goto_tb
The first gen_goto_tb can't just fall through, it needs to exit.
r~
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 14/23] target/i386: Truncate values for lcall_real to i32
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (12 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 13/23] target/i386: Introduce DISAS_JUMP Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 12:29 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 15/23] target/i386: Create eip_next_* Richard Henderson
` (9 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Use i32 not int or tl for eip and cs arguments.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/helper.h | 2 +-
target/i386/tcg/seg_helper.c | 6 ++----
target/i386/tcg/translate.c | 3 ++-
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/target/i386/helper.h b/target/i386/helper.h
index ac3b4d1ee3..39a3c24182 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -37,7 +37,7 @@ DEF_HELPER_2(lldt, void, env, int)
DEF_HELPER_2(ltr, void, env, int)
DEF_HELPER_3(load_seg, void, env, int, int)
DEF_HELPER_4(ljmp_protected, void, env, int, tl, tl)
-DEF_HELPER_5(lcall_real, void, env, int, tl, int, int)
+DEF_HELPER_5(lcall_real, void, env, i32, i32, int, i32)
DEF_HELPER_5(lcall_protected, void, env, int, tl, int, tl)
DEF_HELPER_2(iret_real, void, env, int)
DEF_HELPER_3(iret_protected, void, env, int, int)
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index bffd82923f..539189b4d1 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -1504,14 +1504,12 @@ void helper_ljmp_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
}
/* real mode call */
-void helper_lcall_real(CPUX86State *env, int new_cs, target_ulong new_eip1,
- int shift, int next_eip)
+void helper_lcall_real(CPUX86State *env, uint32_t new_cs, uint32_t new_eip,
+ int shift, uint32_t next_eip)
{
- int new_eip;
uint32_t esp, esp_mask;
target_ulong ssp;
- new_eip = new_eip1;
esp = env->regs[R_ESP];
esp_mask = get_sp_mask(env->segs[R_SS].flags);
ssp = env->segs[R_SS].base;
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 1997f8d291..427ee72442 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -5302,7 +5302,8 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
tcg_const_tl(s->pc - s->cs_base));
} else {
tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
- gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->T1,
+ tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
+ gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32,
tcg_const_i32(dflag - 1),
tcg_const_i32(s->pc - s->cs_base));
}
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 14/23] target/i386: Truncate values for lcall_real to i32
2022-09-06 10:09 ` [PATCH v2 14/23] target/i386: Truncate values for lcall_real to i32 Richard Henderson
@ 2022-09-21 12:29 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 12:29 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Use i32 not int or tl for eip and cs arguments.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> target/i386/helper.h | 2 +-
> target/i386/tcg/seg_helper.c | 6 ++----
> target/i386/tcg/translate.c | 3 ++-
> 3 files changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/target/i386/helper.h b/target/i386/helper.h
> index ac3b4d1ee3..39a3c24182 100644
> --- a/target/i386/helper.h
> +++ b/target/i386/helper.h
> @@ -37,7 +37,7 @@ DEF_HELPER_2(lldt, void, env, int)
> DEF_HELPER_2(ltr, void, env, int)
> DEF_HELPER_3(load_seg, void, env, int, int)
> DEF_HELPER_4(ljmp_protected, void, env, int, tl, tl)
> -DEF_HELPER_5(lcall_real, void, env, int, tl, int, int)
> +DEF_HELPER_5(lcall_real, void, env, i32, i32, int, i32)
> DEF_HELPER_5(lcall_protected, void, env, int, tl, int, tl)
> DEF_HELPER_2(iret_real, void, env, int)
> DEF_HELPER_3(iret_protected, void, env, int, int)
> diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
> index bffd82923f..539189b4d1 100644
> --- a/target/i386/tcg/seg_helper.c
> +++ b/target/i386/tcg/seg_helper.c
> @@ -1504,14 +1504,12 @@ void helper_ljmp_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
> }
>
> /* real mode call */
> -void helper_lcall_real(CPUX86State *env, int new_cs, target_ulong new_eip1,
> - int shift, int next_eip)
> +void helper_lcall_real(CPUX86State *env, uint32_t new_cs, uint32_t new_eip,
> + int shift, uint32_t next_eip)
> {
> - int new_eip;
> uint32_t esp, esp_mask;
> target_ulong ssp;
>
> - new_eip = new_eip1;
> esp = env->regs[R_ESP];
> esp_mask = get_sp_mask(env->segs[R_SS].flags);
> ssp = env->segs[R_SS].base;
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 1997f8d291..427ee72442 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -5302,7 +5302,8 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> tcg_const_tl(s->pc - s->cs_base));
> } else {
> tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
> - gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->T1,
> + tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
> + gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32,
> tcg_const_i32(dflag - 1),
> tcg_const_i32(s->pc - s->cs_base));
> }
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 15/23] target/i386: Create eip_next_*
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (13 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 14/23] target/i386: Truncate values for lcall_real to i32 Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 12:34 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 16/23] target/i386: Use DISAS_TOO_MANY to exit after gen_io_start Richard Henderson
` (8 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Create helpers for loading the address of the next insn.
Use tcg_constant_* in adjacent code where convenient.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 44 +++++++++++++++++++------------------
1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 427ee72442..527fb79895 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -541,6 +541,16 @@ static TCGv_i32 cur_insn_len_i32(DisasContext *s)
return tcg_constant_i32(cur_insn_len(s));
}
+static TCGv_i32 eip_next_i32(DisasContext *s)
+{
+ return tcg_constant_i32(s->pc - s->cs_base);
+}
+
+static TCGv eip_next_tl(DisasContext *s)
+{
+ return tcg_constant_tl(s->pc - s->cs_base);
+}
+
/* Compute SEG:REG into A0. SEG is selected from the override segment
(OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
indicate no override. */
@@ -1213,12 +1223,9 @@ static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
/* user-mode cpu should not be in IOBPT mode */
g_assert_not_reached();
#else
- TCGv_i32 t_size = tcg_const_i32(1 << ot);
- TCGv t_next = tcg_const_tl(s->pc - s->cs_base);
-
+ TCGv_i32 t_size = tcg_constant_i32(1 << ot);
+ TCGv t_next = eip_next_tl(s);
gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
- tcg_temp_free_i32(t_size);
- tcg_temp_free(t_next);
#endif /* CONFIG_USER_ONLY */
}
}
@@ -5280,9 +5287,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
if (dflag == MO_16) {
tcg_gen_ext16u_tl(s->T0, s->T0);
}
- next_eip = s->pc - s->cs_base;
- tcg_gen_movi_tl(s->T1, next_eip);
- gen_push_v(s, s->T1);
+ gen_push_v(s, eip_next_tl(s));
gen_op_jmp_v(s->T0);
gen_bnd_jmp(s);
s->base.is_jmp = DISAS_JUMP;
@@ -5298,14 +5303,14 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
if (PE(s) && !VM86(s)) {
tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1,
- tcg_const_i32(dflag - 1),
- tcg_const_tl(s->pc - s->cs_base));
+ tcg_constant_i32(dflag - 1),
+ eip_next_tl(s));
} else {
tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32,
- tcg_const_i32(dflag - 1),
- tcg_const_i32(s->pc - s->cs_base));
+ tcg_constant_i32(dflag - 1),
+ eip_next_i32(s));
}
s->base.is_jmp = DISAS_JUMP;
break;
@@ -5328,7 +5333,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
if (PE(s) && !VM86(s)) {
tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1,
- tcg_const_tl(s->pc - s->cs_base));
+ eip_next_tl(s));
} else {
gen_op_movl_seg_T0_vm(s, R_CS);
gen_op_jmp_v(s->T1);
@@ -6819,8 +6824,8 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
} else {
- gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
- tcg_const_i32(s->pc - s->cs_base));
+ gen_helper_iret_protected(cpu_env, tcg_constant_i32(dflag - 1),
+ eip_next_i32(s));
}
set_cc_op(s, CC_OP_EFLAGS);
s->base.is_jmp = DISAS_EOB_ONLY;
@@ -6832,15 +6837,13 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
} else {
tval = (int16_t)insn_get(env, s, MO_16);
}
- next_eip = s->pc - s->cs_base;
- tval += next_eip;
+ tval += s->pc - s->cs_base;
if (dflag == MO_16) {
tval &= 0xffff;
} else if (!CODE64(s)) {
tval &= 0xffffffff;
}
- tcg_gen_movi_tl(s->T0, next_eip);
- gen_push_v(s, s->T0);
+ gen_push_v(s, eip_next_tl(s));
gen_bnd_jmp(s);
gen_jmp(s, tval);
}
@@ -7374,8 +7377,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
TCGLabel *l1, *l2, *l3;
tval = (int8_t)insn_get(env, s, MO_8);
- next_eip = s->pc - s->cs_base;
- tval += next_eip;
+ tval += s->pc - s->cs_base;
if (dflag == MO_16) {
tval &= 0xffff;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 15/23] target/i386: Create eip_next_*
2022-09-06 10:09 ` [PATCH v2 15/23] target/i386: Create eip_next_* Richard Henderson
@ 2022-09-21 12:34 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 12:34 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Create helpers for loading the address of the next insn.
> Use tcg_constant_* in adjacent code where convenient.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> target/i386/tcg/translate.c | 44 +++++++++++++++++++------------------
> 1 file changed, 23 insertions(+), 21 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 427ee72442..527fb79895 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -541,6 +541,16 @@ static TCGv_i32 cur_insn_len_i32(DisasContext *s)
> return tcg_constant_i32(cur_insn_len(s));
> }
>
> +static TCGv_i32 eip_next_i32(DisasContext *s)
> +{
> + return tcg_constant_i32(s->pc - s->cs_base);
Perhaps this should return 0xdeadbeef or 0xffffffff in 64-bit mode, so
that code goes in the weeds very quickly if it tries to use it?
Alternatively, just make iret_protected take a target_ulong for
next_eip, without too much worries about 64-on-32 emulation.
Paolo
> +}
> +
> +static TCGv eip_next_tl(DisasContext *s)
> +{
> + return tcg_constant_tl(s->pc - s->cs_base);
> +}
> +
> /* Compute SEG:REG into A0. SEG is selected from the override segment
> (OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
> indicate no override. */
> @@ -1213,12 +1223,9 @@ static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
> /* user-mode cpu should not be in IOBPT mode */
> g_assert_not_reached();
> #else
> - TCGv_i32 t_size = tcg_const_i32(1 << ot);
> - TCGv t_next = tcg_const_tl(s->pc - s->cs_base);
> -
> + TCGv_i32 t_size = tcg_constant_i32(1 << ot);
> + TCGv t_next = eip_next_tl(s);
> gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
> - tcg_temp_free_i32(t_size);
> - tcg_temp_free(t_next);
> #endif /* CONFIG_USER_ONLY */
> }
> }
> @@ -5280,9 +5287,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> if (dflag == MO_16) {
> tcg_gen_ext16u_tl(s->T0, s->T0);
> }
> - next_eip = s->pc - s->cs_base;
> - tcg_gen_movi_tl(s->T1, next_eip);
> - gen_push_v(s, s->T1);
> + gen_push_v(s, eip_next_tl(s));
> gen_op_jmp_v(s->T0);
> gen_bnd_jmp(s);
> s->base.is_jmp = DISAS_JUMP;
> @@ -5298,14 +5303,14 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> if (PE(s) && !VM86(s)) {
> tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
> gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1,
> - tcg_const_i32(dflag - 1),
> - tcg_const_tl(s->pc - s->cs_base));
> + tcg_constant_i32(dflag - 1),
> + eip_next_tl(s));
> } else {
> tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
> tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
> gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32,
> - tcg_const_i32(dflag - 1),
> - tcg_const_i32(s->pc - s->cs_base));
> + tcg_constant_i32(dflag - 1),
> + eip_next_i32(s));
> }
> s->base.is_jmp = DISAS_JUMP;
> break;
> @@ -5328,7 +5333,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> if (PE(s) && !VM86(s)) {
> tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
> gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1,
> - tcg_const_tl(s->pc - s->cs_base));
> + eip_next_tl(s));
> } else {
> gen_op_movl_seg_T0_vm(s, R_CS);
> gen_op_jmp_v(s->T1);
> @@ -6819,8 +6824,8 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
> } else {
> - gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
> - tcg_const_i32(s->pc - s->cs_base));
> + gen_helper_iret_protected(cpu_env, tcg_constant_i32(dflag - 1),
> + eip_next_i32(s));
> }
> set_cc_op(s, CC_OP_EFLAGS);
> s->base.is_jmp = DISAS_EOB_ONLY;
> @@ -6832,15 +6837,13 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> } else {
> tval = (int16_t)insn_get(env, s, MO_16);
> }
> - next_eip = s->pc - s->cs_base;
> - tval += next_eip;
> + tval += s->pc - s->cs_base;
> if (dflag == MO_16) {
> tval &= 0xffff;
> } else if (!CODE64(s)) {
> tval &= 0xffffffff;
> }
> - tcg_gen_movi_tl(s->T0, next_eip);
> - gen_push_v(s, s->T0);
> + gen_push_v(s, eip_next_tl(s));
> gen_bnd_jmp(s);
> gen_jmp(s, tval);
> }
> @@ -7374,8 +7377,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> TCGLabel *l1, *l2, *l3;
>
> tval = (int8_t)insn_get(env, s, MO_8);
> - next_eip = s->pc - s->cs_base;
> - tval += next_eip;
> + tval += s->pc - s->cs_base;
> if (dflag == MO_16) {
> tval &= 0xffff;
> }
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 16/23] target/i386: Use DISAS_TOO_MANY to exit after gen_io_start
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (14 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 15/23] target/i386: Create eip_next_* Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 12:38 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 17/23] target/i386: Create gen_jmp_rel Richard Henderson
` (7 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
We can set is_jmp early, using only one if, and let that
be overwritten by gen_repz_* etc.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 42 +++++++++----------------------------
1 file changed, 10 insertions(+), 32 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 527fb79895..cedc195837 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -5605,14 +5605,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
+ s->base.is_jmp = DISAS_TOO_MANY;
}
gen_helper_rdrand(s->T0, cpu_env);
rm = (modrm & 7) | REX_B(s);
gen_op_mov_reg_v(s, dflag, rm, s->T0);
set_cc_op(s, CC_OP_EFLAGS);
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
- gen_jmp(s, s->pc - s->cs_base);
- }
break;
default:
@@ -6658,15 +6656,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
+ s->base.is_jmp = DISAS_TOO_MANY;
}
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
gen_repz_ins(s, ot);
- /* jump generated by gen_repz_ins */
} else {
gen_ins(s, ot);
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
- gen_jmp(s, s->pc - s->cs_base);
- }
}
break;
case 0x6e: /* outsS */
@@ -6679,15 +6674,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
+ s->base.is_jmp = DISAS_TOO_MANY;
}
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
gen_repz_outs(s, ot);
- /* jump generated by gen_repz_outs */
} else {
gen_outs(s, ot);
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
- gen_jmp(s, s->pc - s->cs_base);
- }
}
break;
@@ -6704,13 +6696,11 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
+ s->base.is_jmp = DISAS_TOO_MANY;
}
gen_helper_in_func(ot, s->T1, s->tmp2_i32);
gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
gen_bpt_io(s, s->tmp2_i32, ot);
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
- gen_jmp(s, s->pc - s->cs_base);
- }
break;
case 0xe6:
case 0xe7:
@@ -6722,14 +6712,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
+ s->base.is_jmp = DISAS_TOO_MANY;
}
gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
gen_bpt_io(s, s->tmp2_i32, ot);
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
- gen_jmp(s, s->pc - s->cs_base);
- }
break;
case 0xec:
case 0xed:
@@ -6741,13 +6729,11 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
+ s->base.is_jmp = DISAS_TOO_MANY;
}
gen_helper_in_func(ot, s->T1, s->tmp2_i32);
gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
gen_bpt_io(s, s->tmp2_i32, ot);
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
- gen_jmp(s, s->pc - s->cs_base);
- }
break;
case 0xee:
case 0xef:
@@ -6759,14 +6745,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
+ s->base.is_jmp = DISAS_TOO_MANY;
}
gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
gen_bpt_io(s, s->tmp2_i32, ot);
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
- gen_jmp(s, s->pc - s->cs_base);
- }
break;
/************************/
@@ -7432,11 +7416,9 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_update_eip_cur(s);
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
+ s->base.is_jmp = DISAS_TOO_MANY;
}
gen_helper_rdtsc(cpu_env);
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
- gen_jmp(s, s->pc - s->cs_base);
- }
break;
case 0x133: /* rdpmc */
gen_update_cc_op(s);
@@ -7893,11 +7875,9 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_update_eip_cur(s);
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
+ s->base.is_jmp = DISAS_TOO_MANY;
}
gen_helper_rdtscp(cpu_env);
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
- gen_jmp(s, s->pc - s->cs_base);
- }
break;
default:
@@ -8261,6 +8241,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
gen_io_start();
+ s->base.is_jmp = DISAS_TOO_MANY;
}
if (b & 2) {
gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
@@ -8271,9 +8252,6 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
gen_helper_read_crN(s->T0, cpu_env, tcg_constant_i32(reg));
gen_op_mov_reg_v(s, ot, rm, s->T0);
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
- gen_jmp(s, s->pc - s->cs_base);
- }
}
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 16/23] target/i386: Use DISAS_TOO_MANY to exit after gen_io_start
2022-09-06 10:09 ` [PATCH v2 16/23] target/i386: Use DISAS_TOO_MANY to exit after gen_io_start Richard Henderson
@ 2022-09-21 12:38 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 12:38 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> We can set is_jmp early, using only one if, and let that
> be overwritten by gen_repz_* etc.
Perhaps "be overwritten by gen_rep*'s calls to gen_jmp_rel". Code-wise,
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Paolo
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/i386/tcg/translate.c | 42 +++++++++----------------------------
> 1 file changed, 10 insertions(+), 32 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 527fb79895..cedc195837 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -5605,14 +5605,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> + s->base.is_jmp = DISAS_TOO_MANY;
> }
> gen_helper_rdrand(s->T0, cpu_env);
> rm = (modrm & 7) | REX_B(s);
> gen_op_mov_reg_v(s, dflag, rm, s->T0);
> set_cc_op(s, CC_OP_EFLAGS);
> - if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> - gen_jmp(s, s->pc - s->cs_base);
> - }
> break;
>
> default:
> @@ -6658,15 +6656,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> + s->base.is_jmp = DISAS_TOO_MANY;
> }
> if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
> gen_repz_ins(s, ot);
> - /* jump generated by gen_repz_ins */
> } else {
> gen_ins(s, ot);
> - if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> - gen_jmp(s, s->pc - s->cs_base);
> - }
> }
> break;
> case 0x6e: /* outsS */
> @@ -6679,15 +6674,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> + s->base.is_jmp = DISAS_TOO_MANY;
> }
> if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
> gen_repz_outs(s, ot);
> - /* jump generated by gen_repz_outs */
> } else {
> gen_outs(s, ot);
> - if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> - gen_jmp(s, s->pc - s->cs_base);
> - }
> }
> break;
>
> @@ -6704,13 +6696,11 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> + s->base.is_jmp = DISAS_TOO_MANY;
> }
> gen_helper_in_func(ot, s->T1, s->tmp2_i32);
> gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
> gen_bpt_io(s, s->tmp2_i32, ot);
> - if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> - gen_jmp(s, s->pc - s->cs_base);
> - }
> break;
> case 0xe6:
> case 0xe7:
> @@ -6722,14 +6712,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> + s->base.is_jmp = DISAS_TOO_MANY;
> }
> gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
> tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
> gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
> gen_bpt_io(s, s->tmp2_i32, ot);
> - if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> - gen_jmp(s, s->pc - s->cs_base);
> - }
> break;
> case 0xec:
> case 0xed:
> @@ -6741,13 +6729,11 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> + s->base.is_jmp = DISAS_TOO_MANY;
> }
> gen_helper_in_func(ot, s->T1, s->tmp2_i32);
> gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
> gen_bpt_io(s, s->tmp2_i32, ot);
> - if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> - gen_jmp(s, s->pc - s->cs_base);
> - }
> break;
> case 0xee:
> case 0xef:
> @@ -6759,14 +6745,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> + s->base.is_jmp = DISAS_TOO_MANY;
> }
> gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
> tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
> gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
> gen_bpt_io(s, s->tmp2_i32, ot);
> - if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> - gen_jmp(s, s->pc - s->cs_base);
> - }
> break;
>
> /************************/
> @@ -7432,11 +7416,9 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_update_eip_cur(s);
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> + s->base.is_jmp = DISAS_TOO_MANY;
> }
> gen_helper_rdtsc(cpu_env);
> - if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> - gen_jmp(s, s->pc - s->cs_base);
> - }
> break;
> case 0x133: /* rdpmc */
> gen_update_cc_op(s);
> @@ -7893,11 +7875,9 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_update_eip_cur(s);
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> + s->base.is_jmp = DISAS_TOO_MANY;
> }
> gen_helper_rdtscp(cpu_env);
> - if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> - gen_jmp(s, s->pc - s->cs_base);
> - }
> break;
>
> default:
> @@ -8261,6 +8241,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
>
> if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> gen_io_start();
> + s->base.is_jmp = DISAS_TOO_MANY;
> }
> if (b & 2) {
> gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
> @@ -8271,9 +8252,6 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
> gen_helper_read_crN(s->T0, cpu_env, tcg_constant_i32(reg));
> gen_op_mov_reg_v(s, ot, rm, s->T0);
> - if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
> - gen_jmp(s, s->pc - s->cs_base);
> - }
> }
> break;
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 17/23] target/i386: Create gen_jmp_rel
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (15 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 16/23] target/i386: Use DISAS_TOO_MANY to exit after gen_io_start Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 13:06 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 18/23] target/i386: Use gen_jmp_rel for loop and jecxz insns Richard Henderson
` (6 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Create a common helper for pc-relative branches.
The jmp jb insn was missing a mask for CODE32.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 57 ++++++++++++++++++-------------------
1 file changed, 27 insertions(+), 30 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index cedc195837..07c7764649 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -226,6 +226,7 @@ static void gen_eob(DisasContext *s);
static void gen_jr(DisasContext *s);
static void gen_jmp(DisasContext *s, target_ulong eip);
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
+static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num);
static void gen_op(DisasContext *s1, int op, MemOp ot, int d);
static void gen_exception_gpf(DisasContext *s);
@@ -1173,7 +1174,7 @@ static TCGLabel *gen_jz_ecx_string(DisasContext *s)
TCGLabel *l2 = gen_new_label();
gen_op_jnz_ecx(s, s->aflag, l1);
gen_set_label(l2);
- gen_jmp_tb(s, s->pc - s->cs_base, 1);
+ gen_jmp_rel(s, MO_32, 0, 1);
gen_set_label(l1);
return l2;
}
@@ -2756,6 +2757,18 @@ static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
}
}
+static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
+{
+ target_ulong dest = s->pc - s->cs_base + diff;
+
+ if (ot == MO_16) {
+ dest &= 0xffff;
+ } else if (!CODE64(s)) {
+ dest &= 0xffffffff;
+ }
+ gen_jmp_tb(s, dest, tb_num);
+}
+
static void gen_jmp(DisasContext *s, target_ulong eip)
{
gen_jmp_tb(s, eip, 0);
@@ -6816,20 +6829,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
break;
case 0xe8: /* call im */
{
- if (dflag != MO_16) {
- tval = (int32_t)insn_get(env, s, MO_32);
- } else {
- tval = (int16_t)insn_get(env, s, MO_16);
- }
- tval += s->pc - s->cs_base;
- if (dflag == MO_16) {
- tval &= 0xffff;
- } else if (!CODE64(s)) {
- tval &= 0xffffffff;
- }
+ int diff = (dflag != MO_16
+ ? (int32_t)insn_get(env, s, MO_32)
+ : (int16_t)insn_get(env, s, MO_16));
gen_push_v(s, eip_next_tl(s));
gen_bnd_jmp(s);
- gen_jmp(s, tval);
+ gen_jmp_rel(s, dflag, diff, 0);
}
break;
case 0x9a: /* lcall im */
@@ -6847,19 +6852,13 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
goto do_lcall;
case 0xe9: /* jmp im */
- if (dflag != MO_16) {
- tval = (int32_t)insn_get(env, s, MO_32);
- } else {
- tval = (int16_t)insn_get(env, s, MO_16);
+ {
+ int diff = (dflag != MO_16
+ ? (int32_t)insn_get(env, s, MO_32)
+ : (int16_t)insn_get(env, s, MO_16));
+ gen_bnd_jmp(s);
+ gen_jmp_rel(s, dflag, diff, 0);
}
- tval += s->pc - s->cs_base;
- if (dflag == MO_16) {
- tval &= 0xffff;
- } else if (!CODE64(s)) {
- tval &= 0xffffffff;
- }
- gen_bnd_jmp(s);
- gen_jmp(s, tval);
break;
case 0xea: /* ljmp im */
{
@@ -6876,12 +6875,10 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
goto do_ljmp;
case 0xeb: /* jmp Jb */
- tval = (int8_t)insn_get(env, s, MO_8);
- tval += s->pc - s->cs_base;
- if (dflag == MO_16) {
- tval &= 0xffff;
+ {
+ int diff = (int8_t)insn_get(env, s, MO_8);
+ gen_jmp_rel(s, dflag, diff, 0);
}
- gen_jmp(s, tval);
break;
case 0x70 ... 0x7f: /* jcc Jb */
tval = (int8_t)insn_get(env, s, MO_8);
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 17/23] target/i386: Create gen_jmp_rel
2022-09-06 10:09 ` [PATCH v2 17/23] target/i386: Create gen_jmp_rel Richard Henderson
@ 2022-09-21 13:06 ` Paolo Bonzini
2022-10-01 0:53 ` Richard Henderson
0 siblings, 1 reply; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 13:06 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Create a common helper for pc-relative branches.
> The jmp jb insn was missing a mask for CODE32.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(Oops, my remark the previous patch should still have pointed to gen_jmp_tb).
In gen_jz_ecx_string, in the translation for LOOPNZ/LOOPZ/LOOP/JECXZ
and in i386_tr_tb_stop there is:
> - gen_jmp_tb(s, s->pc - s->cs_base, 1);
> + gen_jmp_rel(s, MO_32, 0, 1);
What happens if the instruction's last byte is at 0xffff? Wraparound
in the middle of an instruction is generally undefined, but I think it
should work if the instruction does not cross the 64K/4G limit (and on
real hardware, which obeys segment limits unlike TCG, said limit must
be 64K/4G of course).
In other words, why MO_32 and not "CODE32(s) ? MO_32 : MO_16"?
Likewise, if you change that you need to change gen_repz/gen_repz2
too.
Paolo
> gen_set_label(l1);
> return l2;
> }
> @@ -2756,6 +2757,18 @@ static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
> }
> }
>
> +static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
> +{
> + target_ulong dest = s->pc - s->cs_base + diff;
> +
> + if (ot == MO_16) {
> + dest &= 0xffff;
> + } else if (!CODE64(s)) {
> + dest &= 0xffffffff;
> + }
> + gen_jmp_tb(s, dest, tb_num);
> +}
> +
> static void gen_jmp(DisasContext *s, target_ulong eip)
> {
> gen_jmp_tb(s, eip, 0);
> @@ -6816,20 +6829,12 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> break;
> case 0xe8: /* call im */
> {
> - if (dflag != MO_16) {
> - tval = (int32_t)insn_get(env, s, MO_32);
> - } else {
> - tval = (int16_t)insn_get(env, s, MO_16);
> - }
> - tval += s->pc - s->cs_base;
> - if (dflag == MO_16) {
> - tval &= 0xffff;
> - } else if (!CODE64(s)) {
> - tval &= 0xffffffff;
> - }
> + int diff = (dflag != MO_16
> + ? (int32_t)insn_get(env, s, MO_32)
> + : (int16_t)insn_get(env, s, MO_16));
> gen_push_v(s, eip_next_tl(s));
> gen_bnd_jmp(s);
> - gen_jmp(s, tval);
> + gen_jmp_rel(s, dflag, diff, 0);
> }
> break;
> case 0x9a: /* lcall im */
> @@ -6847,19 +6852,13 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> goto do_lcall;
> case 0xe9: /* jmp im */
> - if (dflag != MO_16) {
> - tval = (int32_t)insn_get(env, s, MO_32);
> - } else {
> - tval = (int16_t)insn_get(env, s, MO_16);
> + {
> + int diff = (dflag != MO_16
> + ? (int32_t)insn_get(env, s, MO_32)
> + : (int16_t)insn_get(env, s, MO_16));
> + gen_bnd_jmp(s);
> + gen_jmp_rel(s, dflag, diff, 0);
> }
> - tval += s->pc - s->cs_base;
> - if (dflag == MO_16) {
> - tval &= 0xffff;
> - } else if (!CODE64(s)) {
> - tval &= 0xffffffff;
> - }
> - gen_bnd_jmp(s);
> - gen_jmp(s, tval);
> break;
> case 0xea: /* ljmp im */
> {
> @@ -6876,12 +6875,10 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> goto do_ljmp;
> case 0xeb: /* jmp Jb */
> - tval = (int8_t)insn_get(env, s, MO_8);
> - tval += s->pc - s->cs_base;
> - if (dflag == MO_16) {
> - tval &= 0xffff;
> + {
> + int diff = (int8_t)insn_get(env, s, MO_8);
> + gen_jmp_rel(s, dflag, diff, 0);
> }
> - gen_jmp(s, tval);
> break;
> case 0x70 ... 0x7f: /* jcc Jb */
> tval = (int8_t)insn_get(env, s, MO_8);
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 17/23] target/i386: Create gen_jmp_rel
2022-09-21 13:06 ` Paolo Bonzini
@ 2022-10-01 0:53 ` Richard Henderson
2022-10-01 6:54 ` Paolo Bonzini
0 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-10-01 0:53 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 9/21/22 06:06, Paolo Bonzini wrote:
> On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> Create a common helper for pc-relative branches.
>> The jmp jb insn was missing a mask for CODE32.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>
> (Oops, my remark the previous patch should still have pointed to gen_jmp_tb).
>
> In gen_jz_ecx_string, in the translation for LOOPNZ/LOOPZ/LOOP/JECXZ
> and in i386_tr_tb_stop there is:
>
>> - gen_jmp_tb(s, s->pc - s->cs_base, 1);
>> + gen_jmp_rel(s, MO_32, 0, 1);
>
> What happens if the instruction's last byte is at 0xffff? Wraparound
> in the middle of an instruction is generally undefined, but I think it
> should work if the instruction does not cross the 64K/4G limit (and on
> real hardware, which obeys segment limits unlike TCG, said limit must
> be 64K/4G of course).
>
> In other words, why MO_32 and not "CODE32(s) ? MO_32 : MO_16"?
I believe it really should be s->dflag, which makes all users of the function pass dflag
(the manual consistently talks about "operand size"). At which point this parameter goes
away and gen_jmp_rel grabs the operand size from DisasContext.
Also, pre-existing bug vs CODE64 here -- operand size is always 64-bits for near jumps.
r~
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 17/23] target/i386: Create gen_jmp_rel
2022-10-01 0:53 ` Richard Henderson
@ 2022-10-01 6:54 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-10-01 6:54 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Sat, Oct 1, 2022 at 2:53 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
> I believe it really should be s->dflag, which makes all users of the function pass dflag
> (the manual consistently talks about "operand size"). At which point this parameter goes
> away and gen_jmp_rel grabs the operand size from DisasContext.
>
> Also, pre-existing bug vs CODE64 here -- operand size is always 64-bits for near jumps.
Yes, sounds good.
Paolo
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 18/23] target/i386: Use gen_jmp_rel for loop and jecxz insns
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (16 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 17/23] target/i386: Create gen_jmp_rel Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 13:06 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 19/23] target/i386: Use gen_jmp_rel for gen_jcc Richard Henderson
` (5 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
With gen_jmp_rel, we may chain to the next tb
instead of merely writing to eip and exiting.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 07c7764649..fdd17c3cf3 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -7355,24 +7355,18 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
case 0xe2: /* loop */
case 0xe3: /* jecxz */
{
- TCGLabel *l1, *l2, *l3;
-
- tval = (int8_t)insn_get(env, s, MO_8);
- tval += s->pc - s->cs_base;
- if (dflag == MO_16) {
- tval &= 0xffff;
- }
+ TCGLabel *l1, *l2;
+ int diff = (int8_t)insn_get(env, s, MO_8);
l1 = gen_new_label();
l2 = gen_new_label();
- l3 = gen_new_label();
gen_update_cc_op(s);
b &= 3;
switch(b) {
case 0: /* loopnz */
case 1: /* loopz */
gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
- gen_op_jz_ecx(s, s->aflag, l3);
+ gen_op_jz_ecx(s, s->aflag, l2);
gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
break;
case 2: /* loop */
@@ -7385,14 +7379,11 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
break;
}
- gen_set_label(l3);
- gen_update_eip_next(s);
- tcg_gen_br(l2);
+ gen_set_label(l2);
+ gen_jmp_rel(s, MO_32, 0, 1);
gen_set_label(l1);
- gen_jmp_im(s, tval);
- gen_set_label(l2);
- s->base.is_jmp = DISAS_EOB_ONLY;
+ gen_jmp_rel(s, dflag, diff, 0);
}
break;
case 0x130: /* wrmsr */
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 18/23] target/i386: Use gen_jmp_rel for loop and jecxz insns
2022-09-06 10:09 ` [PATCH v2 18/23] target/i386: Use gen_jmp_rel for loop and jecxz insns Richard Henderson
@ 2022-09-21 13:06 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 13:06 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> With gen_jmp_rel, we may chain to the next tb
> instead of merely writing to eip and exiting.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
See comment on the previous patch.
Paolo
> ---
> target/i386/tcg/translate.c | 21 ++++++---------------
> 1 file changed, 6 insertions(+), 15 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 07c7764649..fdd17c3cf3 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -7355,24 +7355,18 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> case 0xe2: /* loop */
> case 0xe3: /* jecxz */
> {
> - TCGLabel *l1, *l2, *l3;
> -
> - tval = (int8_t)insn_get(env, s, MO_8);
> - tval += s->pc - s->cs_base;
> - if (dflag == MO_16) {
> - tval &= 0xffff;
> - }
> + TCGLabel *l1, *l2;
> + int diff = (int8_t)insn_get(env, s, MO_8);
>
> l1 = gen_new_label();
> l2 = gen_new_label();
> - l3 = gen_new_label();
> gen_update_cc_op(s);
> b &= 3;
> switch(b) {
> case 0: /* loopnz */
> case 1: /* loopz */
> gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
> - gen_op_jz_ecx(s, s->aflag, l3);
> + gen_op_jz_ecx(s, s->aflag, l2);
> gen_jcc1(s, (JCC_Z << 1) | (b ^ 1), l1);
> break;
> case 2: /* loop */
> @@ -7385,14 +7379,11 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> break;
> }
>
> - gen_set_label(l3);
> - gen_update_eip_next(s);
> - tcg_gen_br(l2);
> + gen_set_label(l2);
> + gen_jmp_rel(s, MO_32, 0, 1);
>
> gen_set_label(l1);
> - gen_jmp_im(s, tval);
> - gen_set_label(l2);
> - s->base.is_jmp = DISAS_EOB_ONLY;
> + gen_jmp_rel(s, dflag, diff, 0);
> }
> break;
> case 0x130: /* wrmsr */
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 19/23] target/i386: Use gen_jmp_rel for gen_jcc
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (17 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 18/23] target/i386: Use gen_jmp_rel for loop and jecxz insns Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 13:09 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 20/23] target/i386: Use gen_jmp_rel for gen_repz* Richard Henderson
` (4 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 57 ++++++++++++-------------------------
1 file changed, 18 insertions(+), 39 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index fdd17c3cf3..e27f36e4e9 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2373,32 +2373,14 @@ static void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
}
}
-static inline void gen_jcc(DisasContext *s, int b,
- target_ulong val, target_ulong next_eip)
+static void gen_jcc(DisasContext *s, MemOp ot, int b, int diff)
{
- TCGLabel *l1, *l2;
+ TCGLabel *l1 = gen_new_label();
- if (s->jmp_opt) {
- l1 = gen_new_label();
- gen_jcc1(s, b, l1);
-
- gen_goto_tb(s, 0, next_eip);
-
- gen_set_label(l1);
- gen_goto_tb(s, 1, val);
- } else {
- l1 = gen_new_label();
- l2 = gen_new_label();
- gen_jcc1(s, b, l1);
-
- gen_jmp_im(s, next_eip);
- tcg_gen_br(l2);
-
- gen_set_label(l1);
- gen_jmp_im(s, val);
- gen_set_label(l2);
- gen_eob(s);
- }
+ gen_jcc1(s, b, l1);
+ gen_jmp_rel(s, ot, 0, 1);
+ gen_set_label(l1);
+ gen_jmp_rel(s, ot, diff, 0);
}
static void gen_cmovcc1(CPUX86State *env, DisasContext *s, MemOp ot, int b,
@@ -4721,7 +4703,6 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
int shift;
MemOp ot, aflag, dflag;
int modrm, reg, rm, mod, op, opreg, val;
- target_ulong next_eip, tval;
bool orig_cc_op_dirty = s->cc_op_dirty;
CCOp orig_cc_op = s->cc_op;
@@ -6881,22 +6862,20 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
break;
case 0x70 ... 0x7f: /* jcc Jb */
- tval = (int8_t)insn_get(env, s, MO_8);
- goto do_jcc;
+ {
+ int diff = (int8_t)insn_get(env, s, MO_8);
+ gen_bnd_jmp(s);
+ gen_jcc(s, dflag, b, diff);
+ }
+ break;
case 0x180 ... 0x18f: /* jcc Jv */
- if (dflag != MO_16) {
- tval = (int32_t)insn_get(env, s, MO_32);
- } else {
- tval = (int16_t)insn_get(env, s, MO_16);
+ {
+ int diff = (dflag != MO_16
+ ? (int32_t)insn_get(env, s, MO_32)
+ : (int16_t)insn_get(env, s, MO_16));
+ gen_bnd_jmp(s);
+ gen_jcc(s, dflag, b, diff);
}
- do_jcc:
- next_eip = s->pc - s->cs_base;
- tval += next_eip;
- if (dflag == MO_16) {
- tval &= 0xffff;
- }
- gen_bnd_jmp(s);
- gen_jcc(s, b, tval, next_eip);
break;
case 0x190 ... 0x19f: /* setcc Gv */
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 19/23] target/i386: Use gen_jmp_rel for gen_jcc
2022-09-06 10:09 ` [PATCH v2 19/23] target/i386: Use gen_jmp_rel for gen_jcc Richard Henderson
@ 2022-09-21 13:09 ` Paolo Bonzini
2022-10-01 1:04 ` Richard Henderson
0 siblings, 1 reply; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 13:09 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
> -static inline void gen_jcc(DisasContext *s, int b,
> - target_ulong val, target_ulong next_eip)
> +static void gen_jcc(DisasContext *s, MemOp ot, int b, int diff)
> {
> - TCGLabel *l1, *l2;
> + TCGLabel *l1 = gen_new_label();
>
> - if (s->jmp_opt) {
> - l1 = gen_new_label();
> - gen_jcc1(s, b, l1);
> -
> - gen_goto_tb(s, 0, next_eip);
> -
> - gen_set_label(l1);
> - gen_goto_tb(s, 1, val);
> - } else {
> - l1 = gen_new_label();
> - l2 = gen_new_label();
> - gen_jcc1(s, b, l1);
> -
> - gen_jmp_im(s, next_eip);
> - tcg_gen_br(l2);
> -
> - gen_set_label(l1);
> - gen_jmp_im(s, val);
> - gen_set_label(l2);
> - gen_eob(s);
> - }
> + gen_jcc1(s, b, l1);
> + gen_jmp_rel(s, ot, 0, 1);
> + gen_set_label(l1);
> + gen_jmp_rel(s, ot, diff, 0);
Might be worth a comment that jumps with 16-bit operand size truncate
EIP even if the jump is not taken.
Otherwise,
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Paolo
> }
>
> static void gen_cmovcc1(CPUX86State *env, DisasContext *s, MemOp ot, int b,
> @@ -4721,7 +4703,6 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> int shift;
> MemOp ot, aflag, dflag;
> int modrm, reg, rm, mod, op, opreg, val;
> - target_ulong next_eip, tval;
> bool orig_cc_op_dirty = s->cc_op_dirty;
> CCOp orig_cc_op = s->cc_op;
>
> @@ -6881,22 +6862,20 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
> }
> break;
> case 0x70 ... 0x7f: /* jcc Jb */
> - tval = (int8_t)insn_get(env, s, MO_8);
> - goto do_jcc;
> + {
> + int diff = (int8_t)insn_get(env, s, MO_8);
> + gen_bnd_jmp(s);
> + gen_jcc(s, dflag, b, diff);
> + }
> + break;
> case 0x180 ... 0x18f: /* jcc Jv */
> - if (dflag != MO_16) {
> - tval = (int32_t)insn_get(env, s, MO_32);
> - } else {
> - tval = (int16_t)insn_get(env, s, MO_16);
> + {
> + int diff = (dflag != MO_16
> + ? (int32_t)insn_get(env, s, MO_32)
> + : (int16_t)insn_get(env, s, MO_16));
> + gen_bnd_jmp(s);
> + gen_jcc(s, dflag, b, diff);
> }
> - do_jcc:
> - next_eip = s->pc - s->cs_base;
> - tval += next_eip;
> - if (dflag == MO_16) {
> - tval &= 0xffff;
> - }
> - gen_bnd_jmp(s);
> - gen_jcc(s, b, tval, next_eip);
> break;
>
> case 0x190 ... 0x19f: /* setcc Gv */
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 19/23] target/i386: Use gen_jmp_rel for gen_jcc
2022-09-21 13:09 ` Paolo Bonzini
@ 2022-10-01 1:04 ` Richard Henderson
2022-10-01 7:03 ` Paolo Bonzini
0 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-10-01 1:04 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 9/21/22 06:09, Paolo Bonzini wrote:
> On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
> <richard.henderson@linaro.org> wrote:
>> -static inline void gen_jcc(DisasContext *s, int b,
>> - target_ulong val, target_ulong next_eip)
>> +static void gen_jcc(DisasContext *s, MemOp ot, int b, int diff)
>> {
>> - TCGLabel *l1, *l2;
>> + TCGLabel *l1 = gen_new_label();
>>
>> - if (s->jmp_opt) {
>> - l1 = gen_new_label();
>> - gen_jcc1(s, b, l1);
>> -
>> - gen_goto_tb(s, 0, next_eip);
>> -
>> - gen_set_label(l1);
>> - gen_goto_tb(s, 1, val);
>> - } else {
>> - l1 = gen_new_label();
>> - l2 = gen_new_label();
>> - gen_jcc1(s, b, l1);
>> -
>> - gen_jmp_im(s, next_eip);
>> - tcg_gen_br(l2);
>> -
>> - gen_set_label(l1);
>> - gen_jmp_im(s, val);
>> - gen_set_label(l2);
>> - gen_eob(s);
>> - }
>> + gen_jcc1(s, b, l1);
>> + gen_jmp_rel(s, ot, 0, 1);
>> + gen_set_label(l1);
>> + gen_jmp_rel(s, ot, diff, 0);
>
> Might be worth a comment that jumps with 16-bit operand size truncate
> EIP even if the jump is not taken.
Hmm. But is that correct? That's not reflected by the pseudocode for Jcc.
r~
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 19/23] target/i386: Use gen_jmp_rel for gen_jcc
2022-10-01 1:04 ` Richard Henderson
@ 2022-10-01 7:03 ` Paolo Bonzini
2022-10-01 13:58 ` Richard Henderson
0 siblings, 1 reply; 61+ messages in thread
From: Paolo Bonzini @ 2022-10-01 7:03 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Sat, Oct 1, 2022 at 3:04 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 9/21/22 06:09, Paolo Bonzini wrote:
> > On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
> > <richard.henderson@linaro.org> wrote:
> > > + gen_jcc1(s, b, l1);
> > > + gen_jmp_rel(s, ot, 0, 1);
> > > + gen_set_label(l1);
> > > + gen_jmp_rel(s, ot, diff, 0);
> >
> > Might be worth a comment that jumps with 16-bit operand size truncate
> > EIP even if the jump is not taken.
>
> Hmm. But is that correct? That's not reflected by the pseudocode for Jcc.
No, it's not:
int main() {
asm("clc; data16 jc 1f; 1:");
}
does not crash (it does with stc) on real hardware, but it does with
this series applied. So the various occurrences of gen_jmp_rel(s, ot,
0, 1) or gen_jmp_rel(s, MO_32, 0, 1) should stay as gen_jmp_tb(s,
s->pc - s->cs_base, 1).
Paolo
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 19/23] target/i386: Use gen_jmp_rel for gen_jcc
2022-10-01 7:03 ` Paolo Bonzini
@ 2022-10-01 13:58 ` Richard Henderson
0 siblings, 0 replies; 61+ messages in thread
From: Richard Henderson @ 2022-10-01 13:58 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 10/1/22 00:03, Paolo Bonzini wrote:
> On Sat, Oct 1, 2022 at 3:04 AM Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> On 9/21/22 06:09, Paolo Bonzini wrote:
>>> On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
>>> <richard.henderson@linaro.org> wrote:
>>>> + gen_jcc1(s, b, l1);
>>>> + gen_jmp_rel(s, ot, 0, 1);
>>>> + gen_set_label(l1);
>>>> + gen_jmp_rel(s, ot, diff, 0);
>>>
>>> Might be worth a comment that jumps with 16-bit operand size truncate
>>> EIP even if the jump is not taken.
>>
>> Hmm. But is that correct? That's not reflected by the pseudocode for Jcc.
>
> No, it's not:
>
> int main() {
> asm("clc; data16 jc 1f; 1:");
> }
>
> does not crash (it does with stc) on real hardware, but it does with
> this series applied. So the various occurrences of gen_jmp_rel(s, ot,
> 0, 1) or gen_jmp_rel(s, MO_32, 0, 1) should stay as gen_jmp_tb(s,
> s->pc - s->cs_base, 1).
Nice test. I had an idea this would be the case, so I had already added a helper to
perform the jump with truncation to the "current code size". It turned out that I needed
that in other places too, like rep.
New patch set coming up.
r~
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 20/23] target/i386: Use gen_jmp_rel for gen_repz*
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (18 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 19/23] target/i386: Use gen_jmp_rel for gen_jcc Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 13:10 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 21/23] target/i386: Use gen_jmp_rel for DISAS_TOO_MANY Richard Henderson
` (3 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Subtract cur_insn_len to restart the current insn.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index e27f36e4e9..7a9e533c6e 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -224,7 +224,6 @@ STUB_HELPER(wrmsr, TCGv_env env)
static void gen_eob(DisasContext *s);
static void gen_jr(DisasContext *s);
-static void gen_jmp(DisasContext *s, target_ulong eip);
static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num);
static void gen_op(DisasContext *s1, int op, MemOp ot, int d);
@@ -1277,7 +1276,7 @@ static void gen_repz(DisasContext *s, MemOp ot,
if (s->repz_opt) {
gen_op_jz_ecx(s, s->aflag, l2);
}
- gen_jmp(s, s->base.pc_next - s->cs_base);
+ gen_jmp_rel(s, MO_32, -cur_insn_len(s), 0);
}
#define GEN_REPZ(op) \
@@ -1297,7 +1296,7 @@ static void gen_repz2(DisasContext *s, MemOp ot, int nz,
if (s->repz_opt) {
gen_op_jz_ecx(s, s->aflag, l2);
}
- gen_jmp(s, s->base.pc_next - s->cs_base);
+ gen_jmp_rel(s, MO_32, -cur_insn_len(s), 0);
}
#define GEN_REPZ2(op) \
@@ -2751,11 +2750,6 @@ static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
gen_jmp_tb(s, dest, tb_num);
}
-static void gen_jmp(DisasContext *s, target_ulong eip)
-{
- gen_jmp_tb(s, eip, 0);
-}
-
static inline void gen_ldq_env_A0(DisasContext *s, int offset)
{
tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 20/23] target/i386: Use gen_jmp_rel for gen_repz*
2022-09-06 10:09 ` [PATCH v2 20/23] target/i386: Use gen_jmp_rel for gen_repz* Richard Henderson
@ 2022-09-21 13:10 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 13:10 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Subtract cur_insn_len to restart the current insn.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
I wouldn't mind squashing this with the jecxz/loop patch (and the
review comments there apply here too).
Paolo
> ---
> target/i386/tcg/translate.c | 10 ++--------
> 1 file changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index e27f36e4e9..7a9e533c6e 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -224,7 +224,6 @@ STUB_HELPER(wrmsr, TCGv_env env)
>
> static void gen_eob(DisasContext *s);
> static void gen_jr(DisasContext *s);
> -static void gen_jmp(DisasContext *s, target_ulong eip);
> static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
> static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num);
> static void gen_op(DisasContext *s1, int op, MemOp ot, int d);
> @@ -1277,7 +1276,7 @@ static void gen_repz(DisasContext *s, MemOp ot,
> if (s->repz_opt) {
> gen_op_jz_ecx(s, s->aflag, l2);
> }
> - gen_jmp(s, s->base.pc_next - s->cs_base);
> + gen_jmp_rel(s, MO_32, -cur_insn_len(s), 0);
> }
>
> #define GEN_REPZ(op) \
> @@ -1297,7 +1296,7 @@ static void gen_repz2(DisasContext *s, MemOp ot, int nz,
> if (s->repz_opt) {
> gen_op_jz_ecx(s, s->aflag, l2);
> }
> - gen_jmp(s, s->base.pc_next - s->cs_base);
> + gen_jmp_rel(s, MO_32, -cur_insn_len(s), 0);
> }
>
> #define GEN_REPZ2(op) \
> @@ -2751,11 +2750,6 @@ static void gen_jmp_rel(DisasContext *s, MemOp ot, int diff, int tb_num)
> gen_jmp_tb(s, dest, tb_num);
> }
>
> -static void gen_jmp(DisasContext *s, target_ulong eip)
> -{
> - gen_jmp_tb(s, eip, 0);
> -}
> -
> static inline void gen_ldq_env_A0(DisasContext *s, int offset)
> {
> tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 21/23] target/i386: Use gen_jmp_rel for DISAS_TOO_MANY
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (19 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 20/23] target/i386: Use gen_jmp_rel for gen_repz* Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 13:11 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 22/23] target/i386: Create gen_eip_cur Richard Henderson
` (2 subsequent siblings)
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
With gen_jmp_rel, we may chain between two translation blocks
which may only be separated because of TB size limits.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 7a9e533c6e..97a5f7e432 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -8740,6 +8740,9 @@ static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
case DISAS_NORETURN:
break;
case DISAS_TOO_MANY:
+ gen_update_cc_op(dc);
+ gen_jmp_rel(dc, MO_32, 0, 0);
+ break;
case DISAS_EOB_NEXT:
gen_update_cc_op(dc);
gen_update_eip_cur(dc);
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 21/23] target/i386: Use gen_jmp_rel for DISAS_TOO_MANY
2022-09-06 10:09 ` [PATCH v2 21/23] target/i386: Use gen_jmp_rel for DISAS_TOO_MANY Richard Henderson
@ 2022-09-21 13:11 ` Paolo Bonzini
0 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 13:11 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> With gen_jmp_rel, we may chain between two translation blocks
> which may only be separated because of TB size limits.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/i386/tcg/translate.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 7a9e533c6e..97a5f7e432 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -8740,6 +8740,9 @@ static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
> case DISAS_NORETURN:
> break;
> case DISAS_TOO_MANY:
> + gen_update_cc_op(dc);
> + gen_jmp_rel(dc, MO_32, 0, 0);
> + break;
> case DISAS_EOB_NEXT:
> gen_update_cc_op(dc);
> gen_update_eip_cur(dc);
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 22/23] target/i386: Create gen_eip_cur
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (20 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 21/23] target/i386: Use gen_jmp_rel for DISAS_TOO_MANY Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-06 14:50 ` Philippe Mathieu-Daudé via
2022-09-21 13:12 ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 23/23] target/i386: Enable TARGET_TB_PCREL Richard Henderson
2022-09-21 13:32 ` [PATCH v2 00/23] target/i386: pc-relative translation blocks Paolo Bonzini
23 siblings, 2 replies; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/tcg/translate.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 97a5f7e432..39bcb7263b 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -516,6 +516,11 @@ static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
}
}
+static TCGv gen_eip_cur(DisasContext *s)
+{
+ return tcg_constant_tl(s->base.pc_next - s->cs_base);
+}
+
static void gen_jmp_im(DisasContext *s, target_ulong pc)
{
gen_op_jmp_v(tcg_constant_tl(pc));
@@ -6574,7 +6579,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
offsetof(CPUX86State, segs[R_CS].selector));
tcg_gen_st16_i32(s->tmp2_i32, cpu_env,
offsetof(CPUX86State, fpcs));
- tcg_gen_st_tl(tcg_constant_tl(s->base.pc_next - s->cs_base),
+ tcg_gen_st_tl(gen_eip_cur(s),
cpu_env, offsetof(CPUX86State, fpip));
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 22/23] target/i386: Create gen_eip_cur
2022-09-06 10:09 ` [PATCH v2 22/23] target/i386: Create gen_eip_cur Richard Henderson
@ 2022-09-06 14:50 ` Philippe Mathieu-Daudé via
2022-09-21 13:12 ` Paolo Bonzini
1 sibling, 0 replies; 61+ messages in thread
From: Philippe Mathieu-Daudé via @ 2022-09-06 14:50 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: pbonzini
On 6/9/22 12:09, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/i386/tcg/translate.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 22/23] target/i386: Create gen_eip_cur
2022-09-06 10:09 ` [PATCH v2 22/23] target/i386: Create gen_eip_cur Richard Henderson
2022-09-06 14:50 ` Philippe Mathieu-Daudé via
@ 2022-09-21 13:12 ` Paolo Bonzini
1 sibling, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 13:12 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/i386/tcg/translate.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 97a5f7e432..39bcb7263b 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -516,6 +516,11 @@ static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
> }
> }
>
> +static TCGv gen_eip_cur(DisasContext *s)
> +{
> + return tcg_constant_tl(s->base.pc_next - s->cs_base);
> +}
eip_cur_tl() for consistency with eip_next_tl()?
Paolo
^ permalink raw reply [flat|nested] 61+ messages in thread
* [PATCH v2 23/23] target/i386: Enable TARGET_TB_PCREL
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (21 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 22/23] target/i386: Create gen_eip_cur Richard Henderson
@ 2022-09-06 10:09 ` Richard Henderson
2022-09-21 13:31 ` Paolo Bonzini
2022-09-21 13:32 ` [PATCH v2 00/23] target/i386: pc-relative translation blocks Paolo Bonzini
23 siblings, 1 reply; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
To: qemu-devel; +Cc: pbonzini
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/i386/cpu-param.h | 1 +
target/i386/tcg/tcg-cpu.c | 8 ++--
target/i386/tcg/translate.c | 86 ++++++++++++++++++++++++++++++-------
3 files changed, 77 insertions(+), 18 deletions(-)
diff --git a/target/i386/cpu-param.h b/target/i386/cpu-param.h
index 9740bd7abd..51a3f153bf 100644
--- a/target/i386/cpu-param.h
+++ b/target/i386/cpu-param.h
@@ -24,5 +24,6 @@
#endif
#define TARGET_PAGE_BITS 12
#define NB_MMU_MODES 3
+#define TARGET_TB_PCREL 1
#endif
diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c
index 76989a5a9d..74333247c5 100644
--- a/target/i386/tcg/tcg-cpu.c
+++ b/target/i386/tcg/tcg-cpu.c
@@ -49,9 +49,11 @@ static void x86_cpu_exec_exit(CPUState *cs)
static void x86_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
{
- X86CPU *cpu = X86_CPU(cs);
-
- cpu->env.eip = tb_pc(tb) - tb->cs_base;
+ /* The instruction pointer is always up to date with TARGET_TB_PCREL. */
+ if (!TARGET_TB_PCREL) {
+ CPUX86State *env = cs->env_ptr;
+ env->eip = tb_pc(tb) - tb->cs_base;
+ }
}
#ifndef CONFIG_USER_ONLY
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 39bcb7263b..249309ddbc 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -64,6 +64,7 @@
/* global register indexes */
static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2;
+static TCGv cpu_eip;
static TCGv_i32 cpu_cc_op;
static TCGv cpu_regs[CPU_NB_REGS];
static TCGv cpu_seg_base[6];
@@ -77,6 +78,7 @@ typedef struct DisasContext {
target_ulong pc; /* pc = eip + cs_base */
target_ulong cs_base; /* base of CS segment */
+ target_ulong pc_save;
MemOp aflag;
MemOp dflag;
@@ -481,7 +483,7 @@ static void gen_add_A0_im(DisasContext *s, int val)
static inline void gen_op_jmp_v(TCGv dest)
{
- tcg_gen_st_tl(dest, cpu_env, offsetof(CPUX86State, eip));
+ tcg_gen_mov_tl(cpu_eip, dest);
}
static inline
@@ -516,24 +518,36 @@ static inline void gen_op_st_rm_T0_A0(DisasContext *s, int idx, int d)
}
}
-static TCGv gen_eip_cur(DisasContext *s)
+static void gen_jmp_im(DisasContext *s, target_ulong eip)
{
- return tcg_constant_tl(s->base.pc_next - s->cs_base);
-}
-
-static void gen_jmp_im(DisasContext *s, target_ulong pc)
-{
- gen_op_jmp_v(tcg_constant_tl(pc));
+ if (TARGET_TB_PCREL) {
+ target_ulong eip_save = s->pc_save - s->cs_base;
+ tcg_gen_addi_tl(cpu_eip, cpu_eip, eip - eip_save);
+ } else {
+ tcg_gen_movi_tl(cpu_eip, eip);
+ }
}
static void gen_update_eip_cur(DisasContext *s)
{
gen_jmp_im(s, s->base.pc_next - s->cs_base);
+ s->pc_save = s->base.pc_next;
}
static void gen_update_eip_next(DisasContext *s)
{
gen_jmp_im(s, s->pc - s->cs_base);
+ s->pc_save = s->pc;
+}
+
+static TCGv gen_eip_cur(DisasContext *s)
+{
+ if (TARGET_TB_PCREL) {
+ gen_update_eip_cur(s);
+ return cpu_eip;
+ } else {
+ return tcg_constant_tl(s->base.pc_next - s->cs_base);
+ }
}
static int cur_insn_len(DisasContext *s)
@@ -548,12 +562,25 @@ static TCGv_i32 cur_insn_len_i32(DisasContext *s)
static TCGv_i32 eip_next_i32(DisasContext *s)
{
- return tcg_constant_i32(s->pc - s->cs_base);
+ if (TARGET_TB_PCREL) {
+ TCGv_i32 ret = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(ret, cpu_eip);
+ tcg_gen_addi_i32(ret, ret, s->pc - s->pc_save);
+ return ret;
+ } else {
+ return tcg_constant_i32(s->pc - s->cs_base);
+ }
}
static TCGv eip_next_tl(DisasContext *s)
{
- return tcg_constant_tl(s->pc - s->cs_base);
+ if (TARGET_TB_PCREL) {
+ TCGv ret = tcg_temp_new();
+ tcg_gen_addi_tl(ret, cpu_eip, s->pc - s->pc_save);
+ return ret;
+ } else {
+ return tcg_constant_tl(s->pc - s->cs_base);
+ }
}
/* Compute SEG:REG into A0. SEG is selected from the override segment
@@ -2252,7 +2279,12 @@ static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a)
ea = cpu_regs[a.base];
}
if (!ea) {
- tcg_gen_movi_tl(s->A0, a.disp);
+ if (TARGET_TB_PCREL && a.base == -2) {
+ /* With cpu_eip ~= pc_save, the expression is pc-relative. */
+ tcg_gen_addi_tl(s->A0, cpu_eip, a.disp - s->pc_save);
+ } else {
+ tcg_gen_movi_tl(s->A0, a.disp);
+ }
ea = s->A0;
} else if (a.disp != 0) {
tcg_gen_addi_tl(s->A0, ea, a.disp);
@@ -2366,8 +2398,13 @@ static void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
if (translator_use_goto_tb(&s->base, pc)) {
/* jump to same page: we can use a direct jump */
- tcg_gen_goto_tb(tb_num);
- gen_jmp_im(s, eip);
+ if (TARGET_TB_PCREL) {
+ gen_jmp_im(s, eip);
+ tcg_gen_goto_tb(tb_num);
+ } else {
+ tcg_gen_goto_tb(tb_num);
+ gen_jmp_im(s, eip);
+ }
tcg_gen_exit_tb(s->base.tb, tb_num);
s->base.is_jmp = DISAS_NORETURN;
} else {
@@ -8571,6 +8608,13 @@ void tcg_x86_init(void)
[R_EDI] = "edi",
[R_EBP] = "ebp",
[R_ESP] = "esp",
+#endif
+ };
+ static const char eip_name[] = {
+#ifdef TARGET_X86_64
+ "rip"
+#else
+ "eip"
#endif
};
static const char seg_base_names[6][8] = {
@@ -8597,6 +8641,7 @@ void tcg_x86_init(void)
"cc_src");
cpu_cc_src2 = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, cc_src2),
"cc_src2");
+ cpu_eip = tcg_global_mem_new(cpu_env, offsetof(CPUX86State, eip), eip_name);
for (i = 0; i < CPU_NB_REGS; ++i) {
cpu_regs[i] = tcg_global_mem_new(cpu_env,
@@ -8633,6 +8678,7 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
int iopl = (flags >> IOPL_SHIFT) & 3;
dc->cs_base = dc->base.tb->cs_base;
+ dc->pc_save = dc->base.pc_next;
dc->flags = flags;
#ifndef CONFIG_USER_ONLY
dc->cpl = cpl;
@@ -8696,9 +8742,14 @@ static void i386_tr_tb_start(DisasContextBase *db, CPUState *cpu)
static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
+ target_ulong pc_arg = dc->base.pc_next;
dc->prev_insn_end = tcg_last_op();
- tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
+ if (TARGET_TB_PCREL) {
+ pc_arg -= dc->cs_base;
+ pc_arg &= ~TARGET_PAGE_MASK;
+ }
+ tcg_gen_insn_start(pc_arg, dc->cc_op);
}
static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
@@ -8799,7 +8850,12 @@ void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb,
target_ulong *data)
{
int cc_op = data[1];
- env->eip = data[0] - tb->cs_base;
+
+ if (TARGET_TB_PCREL) {
+ env->eip = (env->eip & TARGET_PAGE_MASK) | data[0];
+ } else {
+ env->eip = data[0] - tb->cs_base;
+ }
if (cc_op != CC_OP_DYNAMIC) {
env->cc_op = cc_op;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 61+ messages in thread
* Re: [PATCH v2 23/23] target/i386: Enable TARGET_TB_PCREL
2022-09-06 10:09 ` [PATCH v2 23/23] target/i386: Enable TARGET_TB_PCREL Richard Henderson
@ 2022-09-21 13:31 ` Paolo Bonzini
2022-10-01 1:51 ` Richard Henderson
0 siblings, 1 reply; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 13:31 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Tue, Sep 6, 2022 at 12:10 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
> static void gen_update_eip_cur(DisasContext *s)
> {
> gen_jmp_im(s, s->base.pc_next - s->cs_base);
> + s->pc_save = s->base.pc_next;
s->pc_save is not valid after all gen_jmp_im() calls. Is it worth
noting after each call to gen_jmp_im() why this is not a problem?
> }
>
> static void gen_update_eip_next(DisasContext *s)
> {
> gen_jmp_im(s, s->pc - s->cs_base);
> + s->pc_save = s->pc;
> +}
> +
> +static TCGv gen_eip_cur(DisasContext *s)
> +{
> + if (TARGET_TB_PCREL) {
> + gen_update_eip_cur(s);
> + return cpu_eip;
> + } else {
> + return tcg_constant_tl(s->base.pc_next - s->cs_base);
> + }
Ok, now I see why you called it gen_eip_cur(), but it's still a bit
disconcerting to see the difference in behavior between the
TARGET_TB_PCREL and !TARGET_TB_PCREL cases, one of them updating
cpu_eip and other not.
Perhaps gen_jmp_im() and gen_update_eip_cur() could be rewritten to
return the destination instead:
static TCGv gen_jmp_im(DisasContext *s, target_ulong eip)
{
if (TARGET_TB_PCREL) {
target_ulong eip_save = s->pc_save - s->cs_base;
tcg_gen_addi_tl(cpu_eip, cpu_eip, eip - eip_save);
return cpu_eip;
} else {
TCGv dest = tcg_constant_tl(eip);
tcg_gen_mov_tl(cpu_eip, dest);
return dest;
}
}
static TCGv gen_update_eip_cur(DisasContext *s)
{
TCGv dest = gen_jmp_im(s, s->base.pc_next - s->cs_base);
s->pc_save = s->base.pc_next;
return dest;
}
and the "if (update_ip)" case would use the return value?
This change would basically replace the previous patch, with just the
"if (TARGET_TB_PCREL)" added here.
Paolo
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 23/23] target/i386: Enable TARGET_TB_PCREL
2022-09-21 13:31 ` Paolo Bonzini
@ 2022-10-01 1:51 ` Richard Henderson
0 siblings, 0 replies; 61+ messages in thread
From: Richard Henderson @ 2022-10-01 1:51 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 9/21/22 06:31, Paolo Bonzini wrote:
> On Tue, Sep 6, 2022 at 12:10 PM Richard Henderson
> <richard.henderson@linaro.org> wrote:
>> static void gen_update_eip_cur(DisasContext *s)
>> {
>> gen_jmp_im(s, s->base.pc_next - s->cs_base);
>> + s->pc_save = s->base.pc_next;
>
> s->pc_save is not valid after all gen_jmp_im() calls. Is it worth
> noting after each call to gen_jmp_im() why this is not a problem?
>
>> }
>>
>> static void gen_update_eip_next(DisasContext *s)
>> {
>> gen_jmp_im(s, s->pc - s->cs_base);
>> + s->pc_save = s->pc;
>> +}
>> +
>> +static TCGv gen_eip_cur(DisasContext *s)
>> +{
>> + if (TARGET_TB_PCREL) {
>> + gen_update_eip_cur(s);
>> + return cpu_eip;
>> + } else {
>> + return tcg_constant_tl(s->base.pc_next - s->cs_base);
>> + }
>
> Ok, now I see why you called it gen_eip_cur(), but it's still a bit
> disconcerting to see the difference in behavior between the
> TARGET_TB_PCREL and !TARGET_TB_PCREL cases, one of them updating
> cpu_eip and other not.
>
> Perhaps gen_jmp_im() and gen_update_eip_cur() could be rewritten to
> return the destination instead:
>
> static TCGv gen_jmp_im(DisasContext *s, target_ulong eip)
> {
> if (TARGET_TB_PCREL) {
> target_ulong eip_save = s->pc_save - s->cs_base;
> tcg_gen_addi_tl(cpu_eip, cpu_eip, eip - eip_save);
> return cpu_eip;
> } else {
> TCGv dest = tcg_constant_tl(eip);
> tcg_gen_mov_tl(cpu_eip, dest);
> return dest;
> }
> }
>
> static TCGv gen_update_eip_cur(DisasContext *s)
> {
> TCGv dest = gen_jmp_im(s, s->base.pc_next - s->cs_base);
> s->pc_save = s->base.pc_next;
> return dest;
> }
I don't see what I'd do with the return values. But I see your point about gen_eip_cur
only updating eip sometimes. I have changed the name to eip_cur_tl, as suggested, and it
writes to a temporary, like eip_next_tl.
r~
^ permalink raw reply [flat|nested] 61+ messages in thread
* Re: [PATCH v2 00/23] target/i386: pc-relative translation blocks
2022-09-06 10:09 [PATCH v2 00/23] target/i386: pc-relative translation blocks Richard Henderson
` (22 preceding siblings ...)
2022-09-06 10:09 ` [PATCH v2 23/23] target/i386: Enable TARGET_TB_PCREL Richard Henderson
@ 2022-09-21 13:32 ` Paolo Bonzini
23 siblings, 0 replies; 61+ messages in thread
From: Paolo Bonzini @ 2022-09-21 13:32 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
Looks good! Just a couple weird parts of the architecture where I need
some more explanation.
Paolo
On Tue, Sep 6, 2022 at 12:09 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This is the x86 specific changes required to reduce the
> amount of translation for address space randomization.
> This is a re-base, with no other significant changes over v1.
>
>
> r~
>
>
> Based-on: 20220906091126.298041-1-richard.henderson@linaro.org
> ("[PATCH v4 0/7] tcg: pc-relative translation blocks")
>
> branch: https://gitlab.com/rth7680/qemu/-/tree/tgt-x86-pcrel
>
>
> Richard Henderson (23):
> target/i386: Remove pc_start
> target/i386: Return bool from disas_insn
> target/i386: Remove cur_eip argument to gen_exception
> target/i386: Remove cur_eip, next_eip arguments to gen_interrupt
> target/i386: Create gen_update_eip_cur
> target/i386: Create gen_update_eip_next
> target/i386: Introduce DISAS_EOB*
> target/i386: Use DISAS_EOB* in gen_movl_seg_T0
> target/i386: Use DISAS_EOB_NEXT
> target/i386: USe DISAS_EOB_ONLY
> target/i386: Create cur_insn_len, cur_insn_len_i32
> target/i386: Remove cur_eip, next_eip arguments to gen_repz*
> target/i386: Introduce DISAS_JUMP
> target/i386: Truncate values for lcall_real to i32
> target/i386: Create eip_next_*
> target/i386: Use DISAS_TOO_MANY to exit after gen_io_start
> target/i386: Create gen_jmp_rel
> target/i386: Use gen_jmp_rel for loop and jecxz insns
> target/i386: Use gen_jmp_rel for gen_jcc
> target/i386: Use gen_jmp_rel for gen_repz*
> target/i386: Use gen_jmp_rel for DISAS_TOO_MANY
> target/i386: Create gen_eip_cur
> target/i386: Enable TARGET_TB_PCREL
>
> target/i386/cpu-param.h | 1 +
> target/i386/helper.h | 2 +-
> target/i386/tcg/seg_helper.c | 6 +-
> target/i386/tcg/tcg-cpu.c | 8 +-
> target/i386/tcg/translate.c | 712 ++++++++++++++++++-----------------
> 5 files changed, 369 insertions(+), 360 deletions(-)
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 61+ messages in thread