target/i386: introduce x86_ld*_code

These take care of advancing s->pc, and will provide a unified point
where to check for the 15-byte instruction length limit.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2017-04-26 13:59:34 +02:00
parent 6a24f34e5c
commit e3af7c788b

View File

@ -1863,6 +1863,41 @@ static void gen_shifti(DisasContext *s1, int op, TCGMemOp ot, int d, int c)
} }
} }
static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
{
uint64_t pc = s->pc;
s->pc += num_bytes;
return pc;
}
static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
{
return cpu_ldub_code(env, advance_pc(env, s, 1));
}
static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s)
{
return cpu_ldsw_code(env, advance_pc(env, s, 2));
}
static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
{
return cpu_lduw_code(env, advance_pc(env, s, 2));
}
static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s)
{
return cpu_ldl_code(env, advance_pc(env, s, 4));
}
#ifdef TARGET_X86_64
static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s)
{
return cpu_ldq_code(env, advance_pc(env, s, 8));
}
#endif
/* Decompose an address. */ /* Decompose an address. */
typedef struct AddressParts { typedef struct AddressParts {
@ -1900,7 +1935,7 @@ static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
case MO_32: case MO_32:
havesib = 0; havesib = 0;
if (rm == 4) { if (rm == 4) {
int code = cpu_ldub_code(env, s->pc++); int code = x86_ldub_code(env, s);
scale = (code >> 6) & 3; scale = (code >> 6) & 3;
index = ((code >> 3) & 7) | REX_X(s); index = ((code >> 3) & 7) | REX_X(s);
if (index == 4) { if (index == 4) {
@ -1914,8 +1949,7 @@ static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
case 0: case 0:
if ((base & 7) == 5) { if ((base & 7) == 5) {
base = -1; base = -1;
disp = (int32_t)cpu_ldl_code(env, s->pc); disp = (int32_t)x86_ldl_code(env, s);
s->pc += 4;
if (CODE64(s) && !havesib) { if (CODE64(s) && !havesib) {
base = -2; base = -2;
disp += s->pc + s->rip_offset; disp += s->pc + s->rip_offset;
@ -1923,12 +1957,11 @@ static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
} }
break; break;
case 1: case 1:
disp = (int8_t)cpu_ldub_code(env, s->pc++); disp = (int8_t)x86_ldub_code(env, s);
break; break;
default: default:
case 2: case 2:
disp = (int32_t)cpu_ldl_code(env, s->pc); disp = (int32_t)x86_ldl_code(env, s);
s->pc += 4;
break; break;
} }
@ -1945,15 +1978,13 @@ static AddressParts gen_lea_modrm_0(CPUX86State *env, DisasContext *s,
if (mod == 0) { if (mod == 0) {
if (rm == 6) { if (rm == 6) {
base = -1; base = -1;
disp = cpu_lduw_code(env, s->pc); disp = x86_lduw_code(env, s);
s->pc += 2;
break; break;
} }
} else if (mod == 1) { } else if (mod == 1) {
disp = (int8_t)cpu_ldub_code(env, s->pc++); disp = (int8_t)x86_ldub_code(env, s);
} else { } else {
disp = (int16_t)cpu_lduw_code(env, s->pc); disp = (int16_t)x86_lduw_code(env, s);
s->pc += 2;
} }
switch (rm) { switch (rm) {
@ -2103,19 +2134,16 @@ static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, TCGMemOp ot)
switch (ot) { switch (ot) {
case MO_8: case MO_8:
ret = cpu_ldub_code(env, s->pc); ret = x86_ldub_code(env, s);
s->pc++;
break; break;
case MO_16: case MO_16:
ret = cpu_lduw_code(env, s->pc); ret = x86_lduw_code(env, s);
s->pc += 2;
break; break;
case MO_32: case MO_32:
#ifdef TARGET_X86_64 #ifdef TARGET_X86_64
case MO_64: case MO_64:
#endif #endif
ret = cpu_ldl_code(env, s->pc); ret = x86_ldl_code(env, s);
s->pc += 4;
break; break;
default: default:
tcg_abort(); tcg_abort();
@ -3041,7 +3069,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
gen_helper_enter_mmx(cpu_env); gen_helper_enter_mmx(cpu_env);
} }
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7); reg = ((modrm >> 3) & 7);
if (is_xmm) if (is_xmm)
reg |= rex_r; reg |= rex_r;
@ -3250,8 +3278,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
if (b1 == 1 && reg != 0) if (b1 == 1 && reg != 0)
goto illegal_op; goto illegal_op;
field_length = cpu_ldub_code(env, s->pc++) & 0x3F; field_length = x86_ldub_code(env, s) & 0x3F;
bit_index = cpu_ldub_code(env, s->pc++) & 0x3F; bit_index = x86_ldub_code(env, s) & 0x3F;
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, tcg_gen_addi_ptr(cpu_ptr0, cpu_env,
offsetof(CPUX86State,xmm_regs[reg])); offsetof(CPUX86State,xmm_regs[reg]));
if (b1 == 1) if (b1 == 1)
@ -3380,7 +3408,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
if (b1 >= 2) { if (b1 >= 2) {
goto unknown_op; goto unknown_op;
} }
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
if (is_xmm) { if (is_xmm) {
tcg_gen_movi_tl(cpu_T0, val); tcg_gen_movi_tl(cpu_T0, val);
tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0))); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));
@ -3537,7 +3565,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
case 0x1c4: case 0x1c4:
s->rip_offset = 1; s->rip_offset = 1;
gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
if (b1) { if (b1) {
val &= 7; val &= 7;
tcg_gen_st16_tl(cpu_T0, cpu_env, tcg_gen_st16_tl(cpu_T0, cpu_env,
@ -3553,7 +3581,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
if (mod != 3) if (mod != 3)
goto illegal_op; goto illegal_op;
ot = mo_64_32(s->dflag); ot = mo_64_32(s->dflag);
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
if (b1) { if (b1) {
val &= 7; val &= 7;
rm = (modrm & 7) | REX_B(s); rm = (modrm & 7) | REX_B(s);
@ -3616,7 +3644,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
if ((b & 0xf0) == 0xf0) { if ((b & 0xf0) == 0xf0) {
goto do_0f_38_fx; goto do_0f_38_fx;
} }
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
rm = modrm & 7; rm = modrm & 7;
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
@ -3693,7 +3721,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
do_0f_38_fx: do_0f_38_fx:
/* Various integer extensions at 0f 38 f[0-f]. */ /* Various integer extensions at 0f 38 f[0-f]. */
b = modrm | (b1 << 8); b = modrm | (b1 << 8);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
switch (b) { switch (b) {
@ -4054,7 +4082,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
case 0x03a: case 0x03a:
case 0x13a: case 0x13a:
b = modrm; b = modrm;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
rm = modrm & 7; rm = modrm & 7;
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
@ -4077,7 +4105,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
if (mod != 3) if (mod != 3)
gen_lea_modrm(env, s, modrm); gen_lea_modrm(env, s, modrm);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
switch (b) { switch (b) {
case 0x14: /* pextrb */ case 0x14: /* pextrb */
tcg_gen_ld8u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, tcg_gen_ld8u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,
@ -4225,7 +4253,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
gen_ldq_env_A0(s, op2_offset); gen_ldq_env_A0(s, op2_offset);
} }
} }
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
if ((b & 0xfc) == 0x60) { /* pcmpXstrX */ if ((b & 0xfc) == 0x60) { /* pcmpXstrX */
set_cc_op(s, CC_OP_EFLAGS); set_cc_op(s, CC_OP_EFLAGS);
@ -4244,7 +4272,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
case 0x33a: case 0x33a:
/* Various integer extensions at 0f 3a f[0-f]. */ /* Various integer extensions at 0f 3a f[0-f]. */
b = modrm | (b1 << 8); b = modrm | (b1 << 8);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
switch (b) { switch (b) {
@ -4256,7 +4284,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
} }
ot = mo_64_32(s->dflag); ot = mo_64_32(s->dflag);
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
b = cpu_ldub_code(env, s->pc++); b = x86_ldub_code(env, s);
if (ot == MO_64) { if (ot == MO_64) {
tcg_gen_rotri_tl(cpu_T0, cpu_T0, b & 63); tcg_gen_rotri_tl(cpu_T0, cpu_T0, b & 63);
} else { } else {
@ -4351,7 +4379,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
} }
switch(b) { switch(b) {
case 0x0f: /* 3DNow! data insns */ case 0x0f: /* 3DNow! data insns */
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
sse_fn_epp = sse_op_table5[val]; sse_fn_epp = sse_op_table5[val];
if (!sse_fn_epp) { if (!sse_fn_epp) {
goto unknown_op; goto unknown_op;
@ -4365,7 +4393,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
break; break;
case 0x70: /* pshufx insn */ case 0x70: /* pshufx insn */
case 0xc6: /* pshufx insn */ case 0xc6: /* pshufx insn */
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);
tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);
/* XXX: introduce a new table? */ /* XXX: introduce a new table? */
@ -4374,7 +4402,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
break; break;
case 0xc2: case 0xc2:
/* compare insns */ /* compare insns */
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
if (val >= 8) if (val >= 8)
goto unknown_op; goto unknown_op;
sse_fn_epp = sse_op_table4[val][b1]; sse_fn_epp = sse_op_table4[val][b1];
@ -4443,8 +4471,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
if (s->pc - pc_start > 14) { if (s->pc - pc_start > 14) {
goto illegal_op; goto illegal_op;
} }
b = cpu_ldub_code(env, s->pc); b = x86_ldub_code(env, s);
s->pc++;
/* Collect prefixes. */ /* Collect prefixes. */
switch (b) { switch (b) {
case 0xf3: case 0xf3:
@ -4501,7 +4528,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
static const int pp_prefix[4] = { static const int pp_prefix[4] = {
0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
}; };
int vex3, vex2 = cpu_ldub_code(env, s->pc); int vex3, vex2 = x86_ldub_code(env, s);
if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) { if (!CODE64(s) && (vex2 & 0xc0) != 0xc0) {
/* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b, /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b,
@ -4523,17 +4550,17 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
rex_r = (~vex2 >> 4) & 8; rex_r = (~vex2 >> 4) & 8;
if (b == 0xc5) { if (b == 0xc5) {
vex3 = vex2; vex3 = vex2;
b = cpu_ldub_code(env, s->pc++); b = x86_ldub_code(env, s);
} else { } else {
#ifdef TARGET_X86_64 #ifdef TARGET_X86_64
s->rex_x = (~vex2 >> 3) & 8; s->rex_x = (~vex2 >> 3) & 8;
s->rex_b = (~vex2 >> 2) & 8; s->rex_b = (~vex2 >> 2) & 8;
#endif #endif
vex3 = cpu_ldub_code(env, s->pc++); vex3 = x86_ldub_code(env, s);
rex_w = (vex3 >> 7) & 1; rex_w = (vex3 >> 7) & 1;
switch (vex2 & 0x1f) { switch (vex2 & 0x1f) {
case 0x01: /* Implied 0f leading opcode bytes. */ case 0x01: /* Implied 0f leading opcode bytes. */
b = cpu_ldub_code(env, s->pc++) | 0x100; b = x86_ldub_code(env, s) | 0x100;
break; break;
case 0x02: /* Implied 0f 38 leading opcode bytes. */ case 0x02: /* Implied 0f 38 leading opcode bytes. */
b = 0x138; b = 0x138;
@ -4585,7 +4612,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0x0f: case 0x0f:
/**************************/ /**************************/
/* extended op code */ /* extended op code */
b = cpu_ldub_code(env, s->pc++) | 0x100; b = x86_ldub_code(env, s) | 0x100;
goto reswitch; goto reswitch;
/**************************/ /**************************/
@ -4607,7 +4634,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
switch(f) { switch(f) {
case 0: /* OP Ev, Gv */ case 0: /* OP Ev, Gv */
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s); rm = (modrm & 7) | REX_B(s);
@ -4628,7 +4655,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_op(s, op, ot, opreg); gen_op(s, op, ot, opreg);
break; break;
case 1: /* OP Gv, Ev */ case 1: /* OP Gv, Ev */
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
rm = (modrm & 7) | REX_B(s); rm = (modrm & 7) | REX_B(s);
@ -4662,7 +4689,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
ot = mo_b_d(b, dflag); ot = mo_b_d(b, dflag);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s); rm = (modrm & 7) | REX_B(s);
op = (modrm >> 3) & 7; op = (modrm >> 3) & 7;
@ -4708,7 +4735,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xf7: case 0xf7:
ot = mo_b_d(b, dflag); ot = mo_b_d(b, dflag);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s); rm = (modrm & 7) | REX_B(s);
op = (modrm >> 3) & 7; op = (modrm >> 3) & 7;
@ -4940,7 +4967,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xff: /* GRP5 */ case 0xff: /* GRP5 */
ot = mo_b_d(b, dflag); ot = mo_b_d(b, dflag);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s); rm = (modrm & 7) | REX_B(s);
op = (modrm >> 3) & 7; op = (modrm >> 3) & 7;
@ -5048,7 +5075,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0x85: case 0x85:
ot = mo_b_d(b, dflag); ot = mo_b_d(b, dflag);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
@ -5120,7 +5147,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0x69: /* imul Gv, Ev, I */ case 0x69: /* imul Gv, Ev, I */
case 0x6b: case 0x6b:
ot = dflag; ot = dflag;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
if (b == 0x69) if (b == 0x69)
s->rip_offset = insn_const_size(ot); s->rip_offset = insn_const_size(ot);
@ -5172,7 +5199,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0x1c0: case 0x1c0:
case 0x1c1: /* xadd Ev, Gv */ case 0x1c1: /* xadd Ev, Gv */
ot = mo_b_d(b, dflag); ot = mo_b_d(b, dflag);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
gen_op_mov_v_reg(ot, cpu_T0, reg); gen_op_mov_v_reg(ot, cpu_T0, reg);
@ -5204,7 +5231,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
TCGv oldv, newv, cmpv; TCGv oldv, newv, cmpv;
ot = mo_b_d(b, dflag); ot = mo_b_d(b, dflag);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
oldv = tcg_temp_new(); oldv = tcg_temp_new();
@ -5256,7 +5283,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
} }
break; break;
case 0x1c7: /* cmpxchg8b */ case 0x1c7: /* cmpxchg8b */
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
if ((mod == 3) || ((modrm & 0x38) != 0x8)) if ((mod == 3) || ((modrm & 0x38) != 0x8))
goto illegal_op; goto illegal_op;
@ -5318,7 +5345,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_push_v(s, cpu_T0); gen_push_v(s, cpu_T0);
break; break;
case 0x8f: /* pop Ev */ case 0x8f: /* pop Ev */
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
ot = gen_pop_T0(s); ot = gen_pop_T0(s);
if (mod == 3) { if (mod == 3) {
@ -5337,9 +5364,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xc8: /* enter */ case 0xc8: /* enter */
{ {
int level; int level;
val = cpu_lduw_code(env, s->pc); val = x86_lduw_code(env, s);
s->pc += 2; level = x86_ldub_code(env, s);
level = cpu_ldub_code(env, s->pc++);
gen_enter(s, val, level); gen_enter(s, val, level);
} }
break; break;
@ -5396,7 +5422,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0x88: case 0x88:
case 0x89: /* mov Gv, Ev */ case 0x89: /* mov Gv, Ev */
ot = mo_b_d(b, dflag); ot = mo_b_d(b, dflag);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
/* generate a generic store */ /* generate a generic store */
@ -5405,7 +5431,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xc6: case 0xc6:
case 0xc7: /* mov Ev, Iv */ case 0xc7: /* mov Ev, Iv */
ot = mo_b_d(b, dflag); ot = mo_b_d(b, dflag);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
if (mod != 3) { if (mod != 3) {
s->rip_offset = insn_const_size(ot); s->rip_offset = insn_const_size(ot);
@ -5422,14 +5448,14 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0x8a: case 0x8a:
case 0x8b: /* mov Ev, Gv */ case 0x8b: /* mov Ev, Gv */
ot = mo_b_d(b, dflag); ot = mo_b_d(b, dflag);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
gen_op_mov_reg_v(ot, reg, cpu_T0); gen_op_mov_reg_v(ot, reg, cpu_T0);
break; break;
case 0x8e: /* mov seg, Gv */ case 0x8e: /* mov seg, Gv */
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = (modrm >> 3) & 7; reg = (modrm >> 3) & 7;
if (reg >= 6 || reg == R_CS) if (reg >= 6 || reg == R_CS)
goto illegal_op; goto illegal_op;
@ -5447,7 +5473,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
} }
break; break;
case 0x8c: /* mov Gv, seg */ case 0x8c: /* mov Gv, seg */
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = (modrm >> 3) & 7; reg = (modrm >> 3) & 7;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
if (reg >= 6) if (reg >= 6)
@ -5472,7 +5498,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
/* s_ot is the sign+size of source */ /* s_ot is the sign+size of source */
s_ot = b & 8 ? MO_SIGN | ot : ot; s_ot = b & 8 ? MO_SIGN | ot : ot;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s); rm = (modrm & 7) | REX_B(s);
@ -5508,7 +5534,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break; break;
case 0x8d: /* lea */ case 0x8d: /* lea */
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
if (mod == 3) if (mod == 3)
goto illegal_op; goto illegal_op;
@ -5532,8 +5558,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
switch (s->aflag) { switch (s->aflag) {
#ifdef TARGET_X86_64 #ifdef TARGET_X86_64
case MO_64: case MO_64:
offset_addr = cpu_ldq_code(env, s->pc); offset_addr = x86_ldq_code(env, s);
s->pc += 8;
break; break;
#endif #endif
default: default:
@ -5570,8 +5595,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
if (dflag == MO_64) { if (dflag == MO_64) {
uint64_t tmp; uint64_t tmp;
/* 64 bit case */ /* 64 bit case */
tmp = cpu_ldq_code(env, s->pc); tmp = x86_ldq_code(env, s);
s->pc += 8;
reg = (b & 7) | REX_B(s); reg = (b & 7) | REX_B(s);
tcg_gen_movi_tl(cpu_T0, tmp); tcg_gen_movi_tl(cpu_T0, tmp);
gen_op_mov_reg_v(MO_64, reg, cpu_T0); gen_op_mov_reg_v(MO_64, reg, cpu_T0);
@ -5595,7 +5619,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0x86: case 0x86:
case 0x87: /* xchg Ev, Gv */ case 0x87: /* xchg Ev, Gv */
ot = mo_b_d(b, dflag); ot = mo_b_d(b, dflag);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
if (mod == 3) { if (mod == 3) {
@ -5632,7 +5656,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
op = R_GS; op = R_GS;
do_lxx: do_lxx:
ot = dflag != MO_16 ? MO_32 : MO_16; ot = dflag != MO_16 ? MO_32 : MO_16;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
if (mod == 3) if (mod == 3)
@ -5660,7 +5684,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
grp2: grp2:
{ {
ot = mo_b_d(b, dflag); ot = mo_b_d(b, dflag);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
op = (modrm >> 3) & 7; op = (modrm >> 3) & 7;
@ -5679,7 +5703,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_shift(s, op, ot, opreg, OR_ECX); gen_shift(s, op, ot, opreg, OR_ECX);
} else { } else {
if (shift == 2) { if (shift == 2) {
shift = cpu_ldub_code(env, s->pc++); shift = x86_ldub_code(env, s);
} }
gen_shifti(s, op, ot, opreg, shift); gen_shifti(s, op, ot, opreg, shift);
} }
@ -5713,7 +5737,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
shift = 0; shift = 0;
do_shiftd: do_shiftd:
ot = dflag; ot = dflag;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s); rm = (modrm & 7) | REX_B(s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
@ -5726,7 +5750,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_op_mov_v_reg(ot, cpu_T1, reg); gen_op_mov_v_reg(ot, cpu_T1, reg);
if (shift) { if (shift) {
TCGv imm = tcg_const_tl(cpu_ldub_code(env, s->pc++)); TCGv imm = tcg_const_tl(x86_ldub_code(env, s));
gen_shiftd_rm_T1(s, ot, opreg, op, imm); gen_shiftd_rm_T1(s, ot, opreg, op, imm);
tcg_temp_free(imm); tcg_temp_free(imm);
} else { } else {
@ -5743,7 +5767,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
break; break;
} }
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
rm = modrm & 7; rm = modrm & 7;
op = ((b & 7) << 3) | ((modrm >> 3) & 7); op = ((b & 7) << 3) | ((modrm >> 3) & 7);
@ -6328,7 +6352,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xe4: case 0xe4:
case 0xe5: case 0xe5:
ot = mo_b_d32(b, dflag); ot = mo_b_d32(b, dflag);
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
tcg_gen_movi_tl(cpu_T0, val); tcg_gen_movi_tl(cpu_T0, val);
gen_check_io(s, ot, pc_start - s->cs_base, gen_check_io(s, ot, pc_start - s->cs_base,
SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes)); SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
@ -6347,7 +6371,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xe6: case 0xe6:
case 0xe7: case 0xe7:
ot = mo_b_d32(b, dflag); ot = mo_b_d32(b, dflag);
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
tcg_gen_movi_tl(cpu_T0, val); tcg_gen_movi_tl(cpu_T0, val);
gen_check_io(s, ot, pc_start - s->cs_base, gen_check_io(s, ot, pc_start - s->cs_base,
svm_is_rep(prefixes)); svm_is_rep(prefixes));
@ -6407,8 +6431,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
/************************/ /************************/
/* control */ /* control */
case 0xc2: /* ret im */ case 0xc2: /* ret im */
val = cpu_ldsw_code(env, s->pc); val = x86_ldsw_code(env, s);
s->pc += 2;
ot = gen_pop_T0(s); ot = gen_pop_T0(s);
gen_stack_update(s, val + (1 << ot)); gen_stack_update(s, val + (1 << ot));
/* Note that gen_pop_T0 uses a zero-extending load. */ /* Note that gen_pop_T0 uses a zero-extending load. */
@ -6425,8 +6448,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_jr(s, cpu_T0); gen_jr(s, cpu_T0);
break; break;
case 0xca: /* lret im */ case 0xca: /* lret im */
val = cpu_ldsw_code(env, s->pc); val = x86_ldsw_code(env, s);
s->pc += 2;
do_lret: do_lret:
if (s->pe && !s->vm86) { if (s->pe && !s->vm86) {
gen_update_cc_op(s); gen_update_cc_op(s);
@ -6563,7 +6585,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break; break;
case 0x190 ... 0x19f: /* setcc Gv */ case 0x190 ... 0x19f: /* setcc Gv */
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
gen_setcc1(s, b, cpu_T0); gen_setcc1(s, b, cpu_T0);
gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1); gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1);
break; break;
@ -6572,7 +6594,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
goto illegal_op; goto illegal_op;
} }
ot = dflag; ot = dflag;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
gen_cmovcc1(env, s, ot, b, modrm, reg); gen_cmovcc1(env, s, ot, b, modrm, reg);
break; break;
@ -6689,7 +6711,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
/* bit operations */ /* bit operations */
case 0x1ba: /* bt/bts/btr/btc Gv, im */ case 0x1ba: /* bt/bts/btr/btc Gv, im */
ot = dflag; ot = dflag;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
op = (modrm >> 3) & 7; op = (modrm >> 3) & 7;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s); rm = (modrm & 7) | REX_B(s);
@ -6703,7 +6725,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_op_mov_v_reg(ot, cpu_T0, rm); gen_op_mov_v_reg(ot, cpu_T0, rm);
} }
/* load shift */ /* load shift */
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
tcg_gen_movi_tl(cpu_T1, val); tcg_gen_movi_tl(cpu_T1, val);
if (op < 4) if (op < 4)
goto unknown_op; goto unknown_op;
@ -6722,7 +6744,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
op = 3; op = 3;
do_btx: do_btx:
ot = dflag; ot = dflag;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s); rm = (modrm & 7) | REX_B(s);
@ -6827,7 +6849,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0x1bc: /* bsf / tzcnt */ case 0x1bc: /* bsf / tzcnt */
case 0x1bd: /* bsr / lzcnt */ case 0x1bd: /* bsr / lzcnt */
ot = dflag; ot = dflag;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
gen_extu(ot, cpu_T0); gen_extu(ot, cpu_T0);
@ -6907,7 +6929,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xd4: /* aam */ case 0xd4: /* aam */
if (CODE64(s)) if (CODE64(s))
goto illegal_op; goto illegal_op;
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
if (val == 0) { if (val == 0) {
gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base); gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base);
} else { } else {
@ -6918,7 +6940,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
case 0xd5: /* aad */ case 0xd5: /* aad */
if (CODE64(s)) if (CODE64(s))
goto illegal_op; goto illegal_op;
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
gen_helper_aad(cpu_env, tcg_const_i32(val)); gen_helper_aad(cpu_env, tcg_const_i32(val));
set_cc_op(s, CC_OP_LOGICB); set_cc_op(s, CC_OP_LOGICB);
break; break;
@ -6952,7 +6974,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base); gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
break; break;
case 0xcd: /* int N */ case 0xcd: /* int N */
val = cpu_ldub_code(env, s->pc++); val = x86_ldub_code(env, s);
if (s->vm86 && s->iopl != 3) { if (s->vm86 && s->iopl != 3) {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else { } else {
@ -7007,7 +7029,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
if (CODE64(s)) if (CODE64(s))
goto illegal_op; goto illegal_op;
ot = dflag; ot = dflag;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = (modrm >> 3) & 7; reg = (modrm >> 3) & 7;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
if (mod == 3) if (mod == 3)
@ -7186,7 +7208,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
} }
break; break;
case 0x100: case 0x100:
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
op = (modrm >> 3) & 7; op = (modrm >> 3) & 7;
switch(op) { switch(op) {
@ -7251,7 +7273,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break; break;
case 0x101: case 0x101:
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
switch (modrm) { switch (modrm) {
CASE_MODRM_MEM_OP(0): /* sgdt */ CASE_MODRM_MEM_OP(0): /* sgdt */
gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ); gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
@ -7596,7 +7618,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
/* d_ot is the size of destination */ /* d_ot is the size of destination */
d_ot = dflag; d_ot = dflag;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
rm = (modrm & 7) | REX_B(s); rm = (modrm & 7) | REX_B(s);
@ -7625,7 +7647,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
t1 = tcg_temp_local_new(); t1 = tcg_temp_local_new();
t2 = tcg_temp_local_new(); t2 = tcg_temp_local_new();
ot = MO_16; ot = MO_16;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = (modrm >> 3) & 7; reg = (modrm >> 3) & 7;
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
rm = modrm & 7; rm = modrm & 7;
@ -7670,7 +7692,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
if (!s->pe || s->vm86) if (!s->pe || s->vm86)
goto illegal_op; goto illegal_op;
ot = dflag != MO_16 ? MO_32 : MO_16; ot = dflag != MO_16 ? MO_32 : MO_16;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
t0 = tcg_temp_local_new(); t0 = tcg_temp_local_new();
@ -7690,7 +7712,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
} }
break; break;
case 0x118: case 0x118:
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
op = (modrm >> 3) & 7; op = (modrm >> 3) & 7;
switch(op) { switch(op) {
@ -7709,7 +7731,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
} }
break; break;
case 0x11a: case 0x11a:
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
if (s->flags & HF_MPX_EN_MASK) { if (s->flags & HF_MPX_EN_MASK) {
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
@ -7799,7 +7821,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_nop_modrm(env, s, modrm); gen_nop_modrm(env, s, modrm);
break; break;
case 0x11b: case 0x11b:
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
if (s->flags & HF_MPX_EN_MASK) { if (s->flags & HF_MPX_EN_MASK) {
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
@ -7901,7 +7923,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_nop_modrm(env, s, modrm); gen_nop_modrm(env, s, modrm);
break; break;
case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */ case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
gen_nop_modrm(env, s, modrm); gen_nop_modrm(env, s, modrm);
break; break;
case 0x120: /* mov reg, crN */ case 0x120: /* mov reg, crN */
@ -7909,7 +7931,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
if (s->cpl != 0) { if (s->cpl != 0) {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else { } else {
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
/* Ignore the mod bits (assume (modrm&0xc0)==0xc0). /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
* AMD documentation (24594.pdf) and testing of * AMD documentation (24594.pdf) and testing of
* intel 386 and 486 processors all show that the mod bits * intel 386 and 486 processors all show that the mod bits
@ -7966,7 +7988,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
if (s->cpl != 0) { if (s->cpl != 0) {
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else { } else {
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
/* Ignore the mod bits (assume (modrm&0xc0)==0xc0). /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
* AMD documentation (24594.pdf) and testing of * AMD documentation (24594.pdf) and testing of
* intel 386 and 486 processors all show that the mod bits * intel 386 and 486 processors all show that the mod bits
@ -8012,7 +8034,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
if (!(s->cpuid_features & CPUID_SSE2)) if (!(s->cpuid_features & CPUID_SSE2))
goto illegal_op; goto illegal_op;
ot = mo_64_32(dflag); ot = mo_64_32(dflag);
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
if (mod == 3) if (mod == 3)
goto illegal_op; goto illegal_op;
@ -8021,7 +8043,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
gen_ldst_modrm(env, s, modrm, ot, reg, 1); gen_ldst_modrm(env, s, modrm, ot, reg, 1);
break; break;
case 0x1ae: case 0x1ae:
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
switch (modrm) { switch (modrm) {
CASE_MODRM_MEM_OP(0): /* fxsave */ CASE_MODRM_MEM_OP(0): /* fxsave */
if (!(s->cpuid_features & CPUID_FXSR) if (!(s->cpuid_features & CPUID_FXSR)
@ -8219,7 +8241,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
break; break;
case 0x10d: /* 3DNow! prefetch(w) */ case 0x10d: /* 3DNow! prefetch(w) */
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
mod = (modrm >> 6) & 3; mod = (modrm >> 6) & 3;
if (mod == 3) if (mod == 3)
goto illegal_op; goto illegal_op;
@ -8241,7 +8263,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT)) if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT))
goto illegal_op; goto illegal_op;
modrm = cpu_ldub_code(env, s->pc++); modrm = x86_ldub_code(env, s);
reg = ((modrm >> 3) & 7) | rex_r; reg = ((modrm >> 3) & 7) | rex_r;
if (s->prefix & PREFIX_DATA) { if (s->prefix & PREFIX_DATA) {