qemu-devel.nongnu.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).