Treat this flag exactly like we treat rex_b and rex_x. Signed-off-by: Richard Henderson <richard.hender...@linaro.org> Reviewed-by: Paolo Bonzini <pbonz...@redhat.com> Message-Id: <20210514151342.384376-18-richard.hender...@linaro.org> --- target/i386/tcg/translate.c | 84 ++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 39 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 9bb37215d8..22175c6628 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -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; -- 2.25.1