All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/23] target/i386: pc-relative translation blocks
@ 2022-09-06 10:09 Richard Henderson
  2022-09-06 10:09 ` [PATCH v2 01/23] target/i386: Remove pc_start Richard Henderson
                   ` (23 more replies)
  0 siblings, 24 replies; 61+ messages in thread
From: Richard Henderson @ 2022-09-06 10:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini

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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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

* [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 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 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 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 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 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 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 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

* 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

* 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

* 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

* 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

* 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

* 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

* 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

* 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

* 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

* 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

* 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 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

* 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

* 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

* 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 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

* 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 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

* 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

* 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

* 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 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

* 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

* 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

* 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 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 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 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

* 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

end of thread, other threads:[~2022-10-01 14:01 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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-21 11:49   ` Paolo Bonzini
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
2022-09-21 17:51       ` Philippe Mathieu-Daudé via
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
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
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
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
2022-09-06 10:09 ` [PATCH v2 07/23] target/i386: Introduce DISAS_EOB* 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
2022-09-21 12:09   ` Paolo Bonzini
2022-09-06 10:09 ` [PATCH v2 09/23] target/i386: Use DISAS_EOB_NEXT 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
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
2022-09-06 14:49   ` Philippe Mathieu-Daudé via
2022-09-21 12:25     ` Paolo Bonzini
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
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
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
2022-09-06 10:09 ` [PATCH v2 15/23] target/i386: Create eip_next_* 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
2022-09-21 12:38   ` Paolo Bonzini
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
2022-10-01  6:54       ` Paolo Bonzini
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
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
2022-10-01  7:03       ` Paolo Bonzini
2022-10-01 13:58         ` Richard Henderson
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
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
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
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
2022-09-21 13:32 ` [PATCH v2 00/23] target/i386: pc-relative translation blocks Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.