target/i386: introduce insn_get_addr

The "O" operand type in the Intel SDM needs to load an 8- to 64-bit
unsigned value, while insn_get is limited to 32 bits.  Extract the code
out of disas_insn and into a separate function.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2022-08-23 15:50:48 +02:00
parent 5c2f60bd1b
commit efcca7ef17
1 changed files with 26 additions and 10 deletions

View File

@ -2289,6 +2289,31 @@ static void gen_ldst_modrm(CPUX86State *env, DisasContext *s, int modrm,
}
}
static target_ulong insn_get_addr(CPUX86State *env, DisasContext *s, MemOp ot)
{
target_ulong ret;
switch (ot) {
case MO_8:
ret = x86_ldub_code(env, s);
break;
case MO_16:
ret = x86_lduw_code(env, s);
break;
case MO_32:
ret = x86_ldl_code(env, s);
break;
#ifdef TARGET_X86_64
case MO_64:
ret = x86_ldq_code(env, s);
break;
#endif
default:
g_assert_not_reached();
}
return ret;
}
static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, MemOp ot)
{
uint32_t ret;
@ -5851,16 +5876,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
target_ulong offset_addr;
ot = mo_b_d(b, dflag);
switch (s->aflag) {
#ifdef TARGET_X86_64
case MO_64:
offset_addr = x86_ldq_code(env, s);
break;
#endif
default:
offset_addr = insn_get(env, s, s->aflag);
break;
}
offset_addr = insn_get_addr(env, s, s->aflag);
tcg_gen_movi_tl(s->A0, offset_addr);
gen_add_A0_ds_seg(s);
if ((b & 2) == 0) {