Commit 46edf3255b for qemu.org

commit 46edf3255b7a78b071335551151875f5d78356dd
Author: Paolo Bonzini <pbonzini@redhat.com>
Date:   Fri Oct 9 20:41:42 2026 +0200

    target/i386/tcg: change popl_esp_hack to an X86InsnSpecial

    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 3845fab5c8..2756953c74 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -1615,8 +1615,7 @@ static void decode_group1A(DisasContext *s, CPUX86State *env, X86OpEntry *entry,
         *entry = UNKNOWN_OPCODE;
     } else {
         entry->gen = gen_POP;
-        /* The address must use the value of ESP after the pop.  */
-        s->popl_esp_hack = 1 << mo_pushpop(s, s->dflag);
+        entry->special = X86_SPECIAL_PopESP;
     }
 }

@@ -2360,8 +2359,8 @@ static void decode_modrm(DisasContext *s, CPUX86State *env,
         }

         /* For correct popl handling with esp.  */
-        if (base == R_ESP && s->popl_esp_hack) {
-            disp += s->popl_esp_hack;
+        if (base == R_ESP && decode->e.special == X86_SPECIAL_PopESP) {
+            disp += 1 << mo_pushpop(s, s->dflag);
         }
         if (base == R_EBP || base == R_ESP) {
             def_seg = R_SS;
@@ -3287,7 +3286,6 @@ static void disas_insn(DisasContext *s, CPUState *cpu)

     s->pc = s->base.pc_next;
     s->override = -1;
-    s->popl_esp_hack = 0;
 #ifdef TARGET_X86_64
     s->rex_r = 0;
     s->rex_x = 0;
diff --git a/target/i386/tcg/decode-new.h b/target/i386/tcg/decode-new.h
index 5f76b0c1b7..a823143bbd 100644
--- a/target/i386/tcg/decode-new.h
+++ b/target/i386/tcg/decode-new.h
@@ -242,6 +242,12 @@ typedef enum X86InsnSpecial {

     /* Memory operand size of MOV from segment register is MO_16 */
     X86_SPECIAL_Op0_Mw,
+
+    /*
+     * If the address uses ESP as the base register, use the value
+     * of ESP after the pop.
+     */
+    X86_SPECIAL_PopESP,
 } X86InsnSpecial;

 /*
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 5199c330ac..b2cbce046c 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -108,7 +108,6 @@ typedef struct DisasContext {
     uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
     bool vex_ndd; /* is this a 3-operand instruction? */
     bool vex_w; /* used by AVX even on 32-bit processors */
-    uint8_t popl_esp_hack; /* for correct popl with esp base handling */
     uint8_t rip_offset; /* only used in x86_64, but left for simplicity */

     uint8_t rex_r; /* 0 for i386, but left for simplicity */