Unlike the older code in translate.c, mod=11b *is* filtered out earlier by decode_modrm, and it would have returned bogus code. Since the register case is so simple, just inline decode_modrm_address into its caller instead of removing the "if".
Suggested-by: Richard Henderson <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> --- target/i386/tcg/decode-new.c.inc | 64 ++++++++++++-------------------- 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index b00ea3e86e8..662d1d707d0 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc @@ -2007,33 +2007,34 @@ static void decode_root(DisasContext *s, CPUX86State *env, X86OpEntry *entry, ui *entry = opcodes_root[*b]; } -/* Decompose an address. */ -static AddressParts decode_modrm_address(CPUX86State *env, DisasContext *s, - int modrm, bool is_vsib) +/* Decode the MODRM and SIB bytes into a register or memory operand. */ +static void decode_modrm(DisasContext *s, CPUX86State *env, + X86DecodedInsn *decode, X86DecodedOp *op) { - int def_seg, base, index, scale, mod, rm; - target_long disp; - bool havesib; - - def_seg = R_DS; - index = -1; - scale = 0; - disp = 0; - - mod = (modrm >> 6) & 3; - rm = modrm & 7; - base = rm | REX_B(s); + int modrm = get_modrm(s, env); + int mod = (modrm >> 6) & 3; + int rm = modrm & 7; + bool is_vsib = decode->e.vex_class == 12; + bool havesib = false; if (mod == 3) { - /* Normally filtered out earlier, but including this path - simplifies multi-byte nop, as well as bndcl, bndcu, bndcn. */ - goto done; + op->n = rm; + if (op->unit != X86_OP_MMX) { + op->n |= REX_B(s); + } + return; } + /* Decompose an address. */ + int def_seg = R_DS; + int base = rm | REX_B(s); + int index = -1; + int scale = 0; + target_ulong disp = 0; + switch (s->aflag) { case MO_64: case MO_32: - havesib = 0; if (rm == 4) { int code = x86_ldub_code(env, s); scale = (code >> 6) & 3; @@ -2042,7 +2043,7 @@ static AddressParts decode_modrm_address(CPUX86State *env, DisasContext *s, index = -1; /* no index */ } base = (code & 7) | REX_B(s); - havesib = 1; + havesib = true; } switch (mod) { @@ -2127,26 +2128,9 @@ static AddressParts decode_modrm_address(CPUX86State *env, DisasContext *s, g_assert_not_reached(); } - done: - return (AddressParts){ def_seg, base, index, scale, disp }; -} - -static int decode_modrm(DisasContext *s, CPUX86State *env, - X86DecodedInsn *decode, X86DecodedOp *op) -{ - int modrm = get_modrm(s, env); - if ((modrm >> 6) == 3) { - op->n = (modrm & 7); - if (op->unit != X86_OP_MMX) { - op->n |= REX_B(s); - } - } else { - op->has_ea = true; - op->n = -1; - decode->mem = decode_modrm_address(env, s, get_modrm(s, env), - decode->e.vex_class == 12); - } - return modrm; + op->has_ea = true; + op->n = -1; + decode->mem = (AddressParts){ def_seg, base, index, scale, disp }; } static bool decode_op_size(DisasContext *s, X86OpEntry *e, X86OpSize size, MemOp *ot) -- 2.52.0
