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