aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2024-08-05 10:31:24 +1000
committerMichael Tokarev <mjt@tls.msk.ru>2024-08-28 08:37:14 +0300
commit3854679d584cfd38ce636668ff06d8edd1127c54 (patch)
tree62d5651cf1e882604c92cb4332ab734d9ea496e1
parent0c6a8ad358f7f063e6ab2acf089166a076de90dc (diff)
target/i386: Fix VSIB decode
With normal SIB, index == 4 indicates no index. With VSIB, there is no exception for VR4/VR12. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2474 Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Link: https://lore.kernel.org/r/20240805003130.1421051-3-richard.henderson@linaro.org Cc: qemu-stable@nongnu.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> (cherry picked from commit ac63755b20013ec6a3d2aef4538d37dc90bc3d10) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru> (Mjt: modify the change to pre-new-decoder introduced past qemu 9.0)
-rw-r--r--target/i386/tcg/decode-new.c.inc3
-rw-r--r--target/i386/tcg/translate.c22
2 files changed, 13 insertions, 12 deletions
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc
index 73aa2c42b7..ffd3a42688 100644
--- a/target/i386/tcg/decode-new.c.inc
+++ b/target/i386/tcg/decode-new.c.inc
@@ -1102,7 +1102,8 @@ static int decode_modrm(DisasContext *s, CPUX86State *env, X86DecodedInsn *decod
} else {
op->has_ea = true;
op->n = -1;
- decode->mem = gen_lea_modrm_0(env, s, get_modrm(s, env));
+ decode->mem = gen_lea_modrm_0(env, s, modrm,
+ decode->e.vex_class == 12);
}
return modrm;
}
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 716a747df7..157348273e 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2159,7 +2159,7 @@ typedef struct AddressParts {
} AddressParts;
static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
- int modrm)
+ int modrm, bool is_vsib)
{
int def_seg, base, index, scale, mod, rm;
target_long disp;
@@ -2188,7 +2188,7 @@ static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
int code = x86_ldub_code(env, s);
scale = (code >> 6) & 3;
index = ((code >> 3) & 7) | REX_X(s);
- if (index == 4) {
+ if (index == 4 && !is_vsib) {
index = -1; /* no index */
}
base = (code & 7) | REX_B(s);
@@ -2318,21 +2318,21 @@ static TCGv gen_lea_modrm_1(DisasContext *s, AddressParts a, bool is_vsib)
static void gen_lea_modrm(CPUX86State *env, DisasContext *s, int modrm)
{
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
TCGv ea = gen_lea_modrm_1(s, a, false);
gen_lea_v_seg(s, s->aflag, ea, a.def_seg, s->override);
}
static void gen_nop_modrm(CPUX86State *env, DisasContext *s, int modrm)
{
- (void)gen_lea_modrm_0(env, s, modrm);
+ (void)gen_lea_modrm_0(env, s, modrm, false);
}
/* Used for BNDCL, BNDCU, BNDCN. */
static void gen_bndck(CPUX86State *env, DisasContext *s, int modrm,
TCGCond cond, TCGv_i64 bndv)
{
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
TCGv ea = gen_lea_modrm_1(s, a, false);
tcg_gen_extu_tl_i64(s->tmp1_i64, ea);
@@ -4156,7 +4156,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op;
reg = ((modrm >> 3) & 7) | REX_R(s);
{
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
TCGv ea = gen_lea_modrm_1(s, a, false);
gen_lea_v_seg(s, s->aflag, ea, -1, -1);
gen_op_mov_reg_v(s, dflag, reg, s->A0);
@@ -4378,7 +4378,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
op = ((b & 7) << 3) | ((modrm >> 3) & 7);
if (mod != 3) {
/* memory op */
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
TCGv ea = gen_lea_modrm_1(s, a, false);
TCGv last_addr = tcg_temp_new();
bool update_fdp = true;
@@ -5322,7 +5322,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
rm = (modrm & 7) | REX_B(s);
gen_op_mov_v_reg(s, MO_32, s->T1, reg);
if (mod != 3) {
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
/* specific case: we need to add a displacement */
gen_exts(ot, s->T1);
tcg_gen_sari_tl(s->tmp0, s->T1, 3 + ot);
@@ -6318,7 +6318,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
} else if (mod != 3) {
/* bndldx */
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
if (reg >= 4
|| (prefixes & PREFIX_LOCK)
|| s->aflag == MO_16
@@ -6362,7 +6362,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|| s->aflag == MO_16) {
goto illegal_op;
}
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
if (a.base >= 0) {
tcg_gen_extu_tl_i64(cpu_bndl[reg], cpu_regs[a.base]);
if (!CODE64(s)) {
@@ -6423,7 +6423,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
}
} else if (mod != 3) {
/* bndstx */
- AddressParts a = gen_lea_modrm_0(env, s, modrm);
+ AddressParts a = gen_lea_modrm_0(env, s, modrm, false);
if (reg >= 4
|| (prefixes & PREFIX_LOCK)
|| s->aflag == MO_16