mirror of
https://github.com/qemu/qemu.git
synced 2024-12-12 21:23:36 +08:00
target/i386: Move rex_r into DisasContext
Treat this flag exactly like we treat rex_b and rex_x. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20210514151342.384376-18-richard.henderson@linaro.org>
This commit is contained in:
parent
915ffe89a5
commit
bbdb4237c5
@ -92,6 +92,7 @@ typedef struct DisasContext {
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_X86_64
|
||||
uint8_t rex_r;
|
||||
uint8_t rex_x;
|
||||
uint8_t rex_b;
|
||||
#endif
|
||||
@ -166,10 +167,12 @@ typedef struct DisasContext {
|
||||
|
||||
#ifdef TARGET_X86_64
|
||||
#define REX_PREFIX(S) (((S)->prefix & PREFIX_REX) != 0)
|
||||
#define REX_R(S) ((S)->rex_r + 0)
|
||||
#define REX_X(S) ((S)->rex_x + 0)
|
||||
#define REX_B(S) ((S)->rex_b + 0)
|
||||
#else
|
||||
#define REX_PREFIX(S) false
|
||||
#define REX_R(S) 0
|
||||
#define REX_X(S) 0
|
||||
#define REX_B(S) 0
|
||||
#endif
|
||||
@ -3094,7 +3097,7 @@ static const struct SSEOpHelper_eppi sse_op_table7[256] = {
|
||||
};
|
||||
|
||||
static void gen_sse(CPUX86State *env, DisasContext *s, int b,
|
||||
target_ulong pc_start, int rex_r)
|
||||
target_ulong pc_start)
|
||||
{
|
||||
int b1, op1_offset, op2_offset, is_xmm, val;
|
||||
int modrm, mod, rm, reg;
|
||||
@ -3164,8 +3167,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
|
||||
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7);
|
||||
if (is_xmm)
|
||||
reg |= rex_r;
|
||||
if (is_xmm) {
|
||||
reg |= REX_R(s);
|
||||
}
|
||||
mod = (modrm >> 6) & 3;
|
||||
if (sse_fn_epp == SSE_SPECIAL) {
|
||||
b |= (b1 << 8);
|
||||
@ -3699,7 +3703,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
|
||||
tcg_gen_ld16u_tl(s->T0, cpu_env,
|
||||
offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
|
||||
}
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
gen_op_mov_reg_v(s, ot, reg, s->T0);
|
||||
break;
|
||||
case 0x1d6: /* movq ea, xmm */
|
||||
@ -3743,7 +3747,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
|
||||
offsetof(CPUX86State, fpregs[rm].mmx));
|
||||
gen_helper_pmovmskb_mmx(s->tmp2_i32, cpu_env, s->ptr0);
|
||||
}
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
|
||||
break;
|
||||
|
||||
@ -3755,7 +3759,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
|
||||
}
|
||||
modrm = x86_ldub_code(env, s);
|
||||
rm = modrm & 7;
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
mod = (modrm >> 6) & 3;
|
||||
if (b1 >= 2) {
|
||||
goto unknown_op;
|
||||
@ -3831,7 +3835,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
|
||||
/* Various integer extensions at 0f 38 f[0-f]. */
|
||||
b = modrm | (b1 << 8);
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
|
||||
switch (b) {
|
||||
case 0x3f0: /* crc32 Gd,Eb */
|
||||
@ -4185,7 +4189,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
|
||||
b = modrm;
|
||||
modrm = x86_ldub_code(env, s);
|
||||
rm = modrm & 7;
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
mod = (modrm >> 6) & 3;
|
||||
if (b1 >= 2) {
|
||||
goto unknown_op;
|
||||
@ -4205,7 +4209,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
if (mod != 3)
|
||||
gen_lea_modrm(env, s, modrm);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
val = x86_ldub_code(env, s);
|
||||
switch (b) {
|
||||
case 0x14: /* pextrb */
|
||||
@ -4374,7 +4378,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
|
||||
/* Various integer extensions at 0f 3a f[0-f]. */
|
||||
b = modrm | (b1 << 8);
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
|
||||
switch (b) {
|
||||
case 0x3f0: /* rorx Gy,Ey, Ib */
|
||||
@ -4548,12 +4552,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
MemOp ot, aflag, dflag;
|
||||
int modrm, reg, rm, mod, op, opreg, val;
|
||||
target_ulong next_eip, tval;
|
||||
int rex_w, rex_r;
|
||||
int rex_w;
|
||||
target_ulong pc_start = s->base.pc_next;
|
||||
|
||||
s->pc_start = s->pc = pc_start;
|
||||
s->override = -1;
|
||||
#ifdef TARGET_X86_64
|
||||
s->rex_r = 0;
|
||||
s->rex_x = 0;
|
||||
s->rex_b = 0;
|
||||
#endif
|
||||
@ -4567,7 +4572,6 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
|
||||
prefixes = 0;
|
||||
rex_w = -1;
|
||||
rex_r = 0;
|
||||
|
||||
next_byte:
|
||||
b = x86_ldub_code(env, s);
|
||||
@ -4612,7 +4616,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
/* REX prefix */
|
||||
prefixes |= PREFIX_REX;
|
||||
rex_w = (b >> 3) & 1;
|
||||
rex_r = (b & 0x4) << 1;
|
||||
s->rex_r = (b & 0x4) << 1;
|
||||
s->rex_x = (b & 0x2) << 2;
|
||||
s->rex_b = (b & 0x1) << 3;
|
||||
goto next_byte;
|
||||
@ -4641,7 +4645,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
| PREFIX_LOCK | PREFIX_DATA | PREFIX_REX)) {
|
||||
goto illegal_op;
|
||||
}
|
||||
rex_r = (~vex2 >> 4) & 8;
|
||||
#ifdef TARGET_X86_64
|
||||
s->rex_r = (~vex2 >> 4) & 8;
|
||||
#endif
|
||||
if (b == 0xc5) {
|
||||
/* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
|
||||
vex3 = vex2;
|
||||
@ -4731,7 +4737,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
switch(f) {
|
||||
case 0: /* OP Ev, Gv */
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
mod = (modrm >> 6) & 3;
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
if (mod != 3) {
|
||||
@ -4753,7 +4759,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
case 1: /* OP Gv, Ev */
|
||||
modrm = x86_ldub_code(env, s);
|
||||
mod = (modrm >> 6) & 3;
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
if (mod != 3) {
|
||||
gen_lea_modrm(env, s, modrm);
|
||||
@ -5179,7 +5185,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
ot = mo_b_d(b, dflag);
|
||||
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
|
||||
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
|
||||
gen_op_mov_v_reg(s, ot, s->T1, reg);
|
||||
@ -5251,7 +5257,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
case 0x6b:
|
||||
ot = dflag;
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
if (b == 0x69)
|
||||
s->rip_offset = insn_const_size(ot);
|
||||
else if (b == 0x6b)
|
||||
@ -5303,7 +5309,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
case 0x1c1: /* xadd Ev, Gv */
|
||||
ot = mo_b_d(b, dflag);
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
mod = (modrm >> 6) & 3;
|
||||
gen_op_mov_v_reg(s, ot, s->T0, reg);
|
||||
if (mod == 3) {
|
||||
@ -5335,7 +5341,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
|
||||
ot = mo_b_d(b, dflag);
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
mod = (modrm >> 6) & 3;
|
||||
oldv = tcg_temp_new();
|
||||
newv = tcg_temp_new();
|
||||
@ -5557,7 +5563,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
case 0x89: /* mov Gv, Ev */
|
||||
ot = mo_b_d(b, dflag);
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
|
||||
/* generate a generic store */
|
||||
gen_ldst_modrm(env, s, modrm, ot, reg, 1);
|
||||
@ -5583,7 +5589,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
case 0x8b: /* mov Ev, Gv */
|
||||
ot = mo_b_d(b, dflag);
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
|
||||
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
|
||||
gen_op_mov_reg_v(s, ot, reg, s->T0);
|
||||
@ -5633,7 +5639,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
s_ot = b & 8 ? MO_SIGN | ot : ot;
|
||||
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
mod = (modrm >> 6) & 3;
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
|
||||
@ -5672,7 +5678,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
mod = (modrm >> 6) & 3;
|
||||
if (mod == 3)
|
||||
goto illegal_op;
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
{
|
||||
AddressParts a = gen_lea_modrm_0(env, s, modrm);
|
||||
TCGv ea = gen_lea_modrm_1(s, a);
|
||||
@ -5754,7 +5760,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
case 0x87: /* xchg Ev, Gv */
|
||||
ot = mo_b_d(b, dflag);
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
mod = (modrm >> 6) & 3;
|
||||
if (mod == 3) {
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
@ -5791,7 +5797,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
do_lxx:
|
||||
ot = dflag != MO_16 ? MO_32 : MO_16;
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
mod = (modrm >> 6) & 3;
|
||||
if (mod == 3)
|
||||
goto illegal_op;
|
||||
@ -5874,7 +5880,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
modrm = x86_ldub_code(env, s);
|
||||
mod = (modrm >> 6) & 3;
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
if (mod != 3) {
|
||||
gen_lea_modrm(env, s, modrm);
|
||||
opreg = OR_TMP0;
|
||||
@ -6728,7 +6734,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
}
|
||||
ot = dflag;
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
gen_cmovcc1(env, s, ot, b, modrm, reg);
|
||||
break;
|
||||
|
||||
@ -6874,7 +6880,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
do_btx:
|
||||
ot = dflag;
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
mod = (modrm >> 6) & 3;
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
gen_op_mov_v_reg(s, MO_32, s->T1, reg);
|
||||
@ -6979,7 +6985,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
case 0x1bd: /* bsr / lzcnt */
|
||||
ot = dflag;
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
|
||||
gen_extu(ot, s->T0);
|
||||
|
||||
@ -7706,7 +7712,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
d_ot = dflag;
|
||||
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
mod = (modrm >> 6) & 3;
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
|
||||
@ -7780,7 +7786,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
goto illegal_op;
|
||||
ot = dflag != MO_16 ? MO_32 : MO_16;
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
|
||||
t0 = tcg_temp_local_new();
|
||||
gen_update_cc_op(s);
|
||||
@ -7821,7 +7827,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
modrm = x86_ldub_code(env, s);
|
||||
if (s->flags & HF_MPX_EN_MASK) {
|
||||
mod = (modrm >> 6) & 3;
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
if (prefixes & PREFIX_REPZ) {
|
||||
/* bndcl */
|
||||
if (reg >= 4
|
||||
@ -7911,7 +7917,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
modrm = x86_ldub_code(env, s);
|
||||
if (s->flags & HF_MPX_EN_MASK) {
|
||||
mod = (modrm >> 6) & 3;
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
if (mod != 3 && (prefixes & PREFIX_REPZ)) {
|
||||
/* bndmk */
|
||||
if (reg >= 4
|
||||
@ -8023,7 +8029,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
* are assumed to be 1's, regardless of actual values.
|
||||
*/
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
if (CODE64(s))
|
||||
ot = MO_64;
|
||||
else
|
||||
@ -8076,7 +8082,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
* are assumed to be 1's, regardless of actual values.
|
||||
*/
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
if (CODE64(s))
|
||||
ot = MO_64;
|
||||
else
|
||||
@ -8118,7 +8124,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
mod = (modrm >> 6) & 3;
|
||||
if (mod == 3)
|
||||
goto illegal_op;
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
/* generate a generic store */
|
||||
gen_ldst_modrm(env, s, modrm, ot, reg, 1);
|
||||
break;
|
||||
@ -8350,7 +8356,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
goto illegal_op;
|
||||
|
||||
modrm = x86_ldub_code(env, s);
|
||||
reg = ((modrm >> 3) & 7) | rex_r;
|
||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||
|
||||
if (s->prefix & PREFIX_DATA) {
|
||||
ot = MO_16;
|
||||
@ -8378,7 +8384,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
|
||||
case 0x1c2:
|
||||
case 0x1c4 ... 0x1c6:
|
||||
case 0x1d0 ... 0x1fe:
|
||||
gen_sse(env, s, b, pc_start, rex_r);
|
||||
gen_sse(env, s, b, pc_start);
|
||||
break;
|
||||
default:
|
||||
goto unknown_op;
|
||||
|
Loading…
Reference in New Issue
Block a user