/*
 * New-style TCG opcode generator for i386 instructions
 *
 *  Copyright (c) 2022 Red Hat, Inc.
 *
 * Author: Paolo Bonzini <pbonzini@redhat.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

/*
 * Sometimes, knowing what the backend has can produce better code.
 * The exact opcode to check depends on 32- vs. 64-bit.
 */
#ifdef TARGET_X86_64
#define TCG_TARGET_HAS_extract2_tl      TCG_TARGET_HAS_extract2_i64
#define TCG_TARGET_deposit_tl_valid     TCG_TARGET_deposit_i64_valid
#define TCG_TARGET_extract_tl_valid     TCG_TARGET_extract_i64_valid
#else
#define TCG_TARGET_HAS_extract2_tl      TCG_TARGET_HAS_extract2_i32
#define TCG_TARGET_deposit_tl_valid     TCG_TARGET_deposit_i32_valid
#define TCG_TARGET_extract_tl_valid     TCG_TARGET_extract_i32_valid
#endif

#define MMX_OFFSET(reg)                        \
  ({ assert((reg) >= 0 && (reg) <= 7);         \
     offsetof(CPUX86State, fpregs[reg].mmx); })

#define ZMM_OFFSET(reg)                        \
  ({ assert((reg) >= 0 && (reg) <= 15);        \
     offsetof(CPUX86State, xmm_regs[reg]); })

typedef void (*SSEFunc_i_ep)(TCGv_i32 val, TCGv_ptr env, TCGv_ptr reg);
typedef void (*SSEFunc_l_ep)(TCGv_i64 val, TCGv_ptr env, TCGv_ptr reg);
typedef void (*SSEFunc_0_epp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b);
typedef void (*SSEFunc_0_eppp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
                               TCGv_ptr reg_c);
typedef void (*SSEFunc_0_epppp)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
                                TCGv_ptr reg_c, TCGv_ptr reg_d);
typedef void (*SSEFunc_0_eppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
                               TCGv_i32 val);
typedef void (*SSEFunc_0_epppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
                                TCGv_ptr reg_c, TCGv_i32 val);
typedef void (*SSEFunc_0_ppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_i32 val);
typedef void (*SSEFunc_0_pppi)(TCGv_ptr reg_a, TCGv_ptr reg_b, TCGv_ptr reg_c,
                               TCGv_i32 val);
typedef void (*SSEFunc_0_eppt)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
                               TCGv val);
typedef void (*SSEFunc_0_epppti)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
                                 TCGv_ptr reg_c, TCGv a0, TCGv_i32 scale);
typedef void (*SSEFunc_0_eppppi)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
                                  TCGv_ptr reg_c, TCGv_ptr reg_d, TCGv_i32 flags);
typedef void (*SSEFunc_0_eppppii)(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b,
                                  TCGv_ptr reg_c, TCGv_ptr reg_d, TCGv_i32 even,
                                  TCGv_i32 odd);

static void gen_JMP_m(DisasContext *s, X86DecodedInsn *decode);
static void gen_JMP(DisasContext *s, X86DecodedInsn *decode);

static inline TCGv_i32 tcg_constant8u_i32(uint8_t val)
{
    return tcg_constant_i32(val);
}

static void gen_NM_exception(DisasContext *s)
{
    gen_exception(s, EXCP07_PREX);
}

static void gen_load_ea(DisasContext *s, AddressParts *mem, bool is_vsib)
{
    TCGv ea = gen_lea_modrm_1(s, *mem, is_vsib);
    gen_lea_v_seg(s, ea, mem->def_seg, s->override);
}

static inline int mmx_offset(MemOp ot)
{
    switch (ot) {
    case MO_8:
        return offsetof(MMXReg, MMX_B(0));
    case MO_16:
        return offsetof(MMXReg, MMX_W(0));
    case MO_32:
        return offsetof(MMXReg, MMX_L(0));
    case MO_64:
        return offsetof(MMXReg, MMX_Q(0));
    default:
        g_assert_not_reached();
    }
}

static inline int xmm_offset(MemOp ot)
{
    switch (ot) {
    case MO_8:
        return offsetof(ZMMReg, ZMM_B(0));
    case MO_16:
        return offsetof(ZMMReg, ZMM_W(0));
    case MO_32:
        return offsetof(ZMMReg, ZMM_L(0));
    case MO_64:
        return offsetof(ZMMReg, ZMM_Q(0));
    case MO_128:
        return offsetof(ZMMReg, ZMM_X(0));
    case MO_256:
        return offsetof(ZMMReg, ZMM_Y(0));
    default:
        g_assert_not_reached();
    }
}

static int vector_reg_offset(X86DecodedOp *op)
{
    assert(op->unit == X86_OP_MMX || op->unit == X86_OP_SSE);

    if (op->unit == X86_OP_MMX) {
        return op->offset - mmx_offset(op->ot);
    } else {
        return op->offset - xmm_offset(op->ot);
    }
}

static int vector_elem_offset(X86DecodedOp *op, MemOp ot, int n)
{
    int base_ofs = vector_reg_offset(op);
    switch(ot) {
    case MO_8:
        if (op->unit == X86_OP_MMX) {
            return base_ofs + offsetof(MMXReg, MMX_B(n));
        } else {
            return base_ofs + offsetof(ZMMReg, ZMM_B(n));
        }
    case MO_16:
        if (op->unit == X86_OP_MMX) {
            return base_ofs + offsetof(MMXReg, MMX_W(n));
        } else {
            return base_ofs + offsetof(ZMMReg, ZMM_W(n));
        }
    case MO_32:
        if (op->unit == X86_OP_MMX) {
            return base_ofs + offsetof(MMXReg, MMX_L(n));
        } else {
            return base_ofs + offsetof(ZMMReg, ZMM_L(n));
        }
    case MO_64:
        if (op->unit == X86_OP_MMX) {
            return base_ofs;
        } else {
            return base_ofs + offsetof(ZMMReg, ZMM_Q(n));
        }
    case MO_128:
        assert(op->unit == X86_OP_SSE);
        return base_ofs + offsetof(ZMMReg, ZMM_X(n));
    case MO_256:
        assert(op->unit == X86_OP_SSE);
        return base_ofs + offsetof(ZMMReg, ZMM_Y(n));
    default:
        g_assert_not_reached();
    }
}

static void compute_mmx_offset(X86DecodedOp *op)
{
    if (!op->has_ea) {
        op->offset = MMX_OFFSET(op->n) + mmx_offset(op->ot);
    } else {
        op->offset = offsetof(CPUX86State, mmx_t0) + mmx_offset(op->ot);
    }
}

static void compute_xmm_offset(X86DecodedOp *op)
{
    if (!op->has_ea) {
        op->offset = ZMM_OFFSET(op->n) + xmm_offset(op->ot);
    } else {
        op->offset = offsetof(CPUX86State, xmm_t0) + xmm_offset(op->ot);
    }
}

static void gen_load_sse(DisasContext *s, TCGv temp, MemOp ot, int dest_ofs, bool aligned)
{
    switch(ot) {
    case MO_8:
        gen_op_ld_v(s, MO_8, temp, s->A0);
        tcg_gen_st8_tl(temp, tcg_env, dest_ofs);
        break;
    case MO_16:
        gen_op_ld_v(s, MO_16, temp, s->A0);
        tcg_gen_st16_tl(temp, tcg_env, dest_ofs);
        break;
    case MO_32:
        gen_op_ld_v(s, MO_32, temp, s->A0);
        tcg_gen_st32_tl(temp, tcg_env, dest_ofs);
        break;
    case MO_64:
        gen_ldq_env_A0(s, dest_ofs);
        break;
    case MO_128:
        gen_ldo_env_A0(s, dest_ofs, aligned);
        break;
    case MO_256:
        gen_ldy_env_A0(s, dest_ofs, aligned);
        break;
    default:
        g_assert_not_reached();
    }
}

static bool sse_needs_alignment(DisasContext *s, X86DecodedInsn *decode, MemOp ot)
{
    switch (decode->e.vex_class) {
    case 2:
    case 4:
        if ((s->prefix & PREFIX_VEX) ||
            decode->e.vex_special == X86_VEX_SSEUnaligned) {
            /* MOST legacy SSE instructions require aligned memory operands, but not all.  */
            return false;
        }
        /* fall through */
    case 1:
        return ot >= MO_128;

    default:
        return false;
    }
}

static void gen_load(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv v)
{
    X86DecodedOp *op = &decode->op[opn];

    switch (op->unit) {
    case X86_OP_SKIP:
        return;
    case X86_OP_SEG:
        tcg_gen_ld32u_tl(v, tcg_env,
                         offsetof(CPUX86State,segs[op->n].selector));
        break;
#ifndef CONFIG_USER_ONLY
    case X86_OP_CR:
        if (op->n == 8) {
            translator_io_start(&s->base);
            gen_helper_read_cr8(v, tcg_env);
        } else {
            tcg_gen_ld_tl(v, tcg_env, offsetof(CPUX86State, cr[op->n]));
        }
        break;
    case X86_OP_DR:
        /* CR4.DE tested in the helper.  */
        gen_helper_get_dr(v, tcg_env, tcg_constant_i32(op->n));
        break;
#endif
    case X86_OP_INT:
        if (op->has_ea) {
            if (v == s->T0 && decode->e.special == X86_SPECIAL_SExtT0) {
                gen_op_ld_v(s, op->ot | MO_SIGN, v, s->A0);
            } else {
                gen_op_ld_v(s, op->ot, v, s->A0);
            }

        } else if (op->ot == MO_8 && byte_reg_is_xH(s, op->n)) {
            if (v == s->T0 && decode->e.special == X86_SPECIAL_SExtT0) {
                tcg_gen_sextract_tl(v, cpu_regs[op->n - 4], 8, 8);
            } else {
                tcg_gen_extract_tl(v, cpu_regs[op->n - 4], 8, 8);
            }

        } else if (op->ot < MO_TL && v == s->T0 &&
                   (decode->e.special == X86_SPECIAL_SExtT0 ||
                    decode->e.special == X86_SPECIAL_ZExtT0)) {
            if (decode->e.special == X86_SPECIAL_SExtT0) {
                tcg_gen_ext_tl(v, cpu_regs[op->n], op->ot | MO_SIGN);
            } else {
                tcg_gen_ext_tl(v, cpu_regs[op->n], op->ot);
            }

        } else {
            tcg_gen_mov_tl(v, cpu_regs[op->n]);
        }
        break;
    case X86_OP_IMM:
        tcg_gen_movi_tl(v, op->imm);
        break;

    case X86_OP_MMX:
        compute_mmx_offset(op);
        goto load_vector;

    case X86_OP_SSE:
        compute_xmm_offset(op);
    load_vector:
        if (op->has_ea) {
            bool aligned = sse_needs_alignment(s, decode, op->ot);
            gen_load_sse(s, v, op->ot, op->offset, aligned);
        }
        break;

    default:
        g_assert_not_reached();
    }
}

static TCGv_ptr op_ptr(X86DecodedInsn *decode, int opn)
{
    X86DecodedOp *op = &decode->op[opn];

    assert(op->unit == X86_OP_MMX || op->unit == X86_OP_SSE);
    if (op->v_ptr) {
        return op->v_ptr;
    }
    op->v_ptr = tcg_temp_new_ptr();

    /* The temporary points to the MMXReg or ZMMReg.  */
    tcg_gen_addi_ptr(op->v_ptr, tcg_env, vector_reg_offset(op));
    return op->v_ptr;
}

#define OP_PTR0 op_ptr(decode, 0)
#define OP_PTR1 op_ptr(decode, 1)
#define OP_PTR2 op_ptr(decode, 2)

static void gen_writeback(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv v)
{
    X86DecodedOp *op = &decode->op[opn];
    switch (op->unit) {
    case X86_OP_SKIP:
        break;
    case X86_OP_SEG:
        /* Note that gen_movl_seg takes care of interrupt shadow and TF.  */
        gen_movl_seg(s, op->n, s->T0);
        break;
    case X86_OP_INT:
        if (op->has_ea) {
            gen_op_st_v(s, op->ot, v, s->A0);
        } else {
            gen_op_mov_reg_v(s, op->ot, op->n, v);
        }
        break;
    case X86_OP_MMX:
        break;
    case X86_OP_SSE:
        if (!op->has_ea && (s->prefix & PREFIX_VEX) && op->ot <= MO_128) {
            tcg_gen_gvec_dup_imm(MO_64,
                                 offsetof(CPUX86State, xmm_regs[op->n].ZMM_X(1)),
                                 16, 16, 0);
        }
        break;
#ifndef CONFIG_USER_ONLY
    case X86_OP_CR:
        if (op->n == 8) {
            translator_io_start(&s->base);
        }
        gen_helper_write_crN(tcg_env, tcg_constant_i32(op->n), v);
        s->base.is_jmp = DISAS_EOB_NEXT;
        break;
    case X86_OP_DR:
        /* CR4.DE tested in the helper.  */
        gen_helper_set_dr(tcg_env, tcg_constant_i32(op->n), v);
        s->base.is_jmp = DISAS_EOB_NEXT;
        break;
#endif
    default:
        g_assert_not_reached();
    }
    op->unit = X86_OP_SKIP;
}

static inline int vector_len(DisasContext *s, X86DecodedInsn *decode)
{
    if (decode->e.special == X86_SPECIAL_MMX &&
        !(s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) {
        return 8;
    }
    return s->vex_l ? 32 : 16;
}

static void prepare_update1_cc(X86DecodedInsn *decode, DisasContext *s, CCOp op)
{
    decode->cc_dst = s->T0;
    decode->cc_op = op;
}

static void prepare_update2_cc(X86DecodedInsn *decode, DisasContext *s, CCOp op)
{
    decode->cc_src = s->T1;
    decode->cc_dst = s->T0;
    decode->cc_op = op;
}

static void prepare_update_cc_incdec(X86DecodedInsn *decode, DisasContext *s, CCOp op)
{
    gen_compute_eflags_c(s, s->T1);
    prepare_update2_cc(decode, s, op);
}

static void prepare_update3_cc(X86DecodedInsn *decode, DisasContext *s, CCOp op, TCGv reg)
{
    decode->cc_src2 = reg;
    decode->cc_src = s->T1;
    decode->cc_dst = s->T0;
    decode->cc_op = op;
}

static void gen_store_sse(DisasContext *s, X86DecodedInsn *decode, int src_ofs)
{
    MemOp ot = decode->op[0].ot;
    int vec_len = vector_len(s, decode);
    bool aligned = sse_needs_alignment(s, decode, ot);

    if (!decode->op[0].has_ea) {
        tcg_gen_gvec_mov(MO_64, decode->op[0].offset, src_ofs, vec_len, vec_len);
        return;
    }

    switch (ot) {
    case MO_64:
        gen_stq_env_A0(s, src_ofs);
        break;
    case MO_128:
        gen_sto_env_A0(s, src_ofs, aligned);
        break;
    case MO_256:
        gen_sty_env_A0(s, src_ofs, aligned);
        break;
    default:
        g_assert_not_reached();
    }
}

static void gen_helper_pavgusb(TCGv_ptr env, TCGv_ptr reg_a, TCGv_ptr reg_b)
{
    gen_helper_pavgb_mmx(env, reg_a, reg_a, reg_b);
}

#define FN_3DNOW_MOVE ((SSEFunc_0_epp) (uintptr_t) 1)
static const SSEFunc_0_epp fns_3dnow[] = {
    [0x0c] = gen_helper_pi2fw,
    [0x0d] = gen_helper_pi2fd,
    [0x1c] = gen_helper_pf2iw,
    [0x1d] = gen_helper_pf2id,
    [0x8a] = gen_helper_pfnacc,
    [0x8e] = gen_helper_pfpnacc,
    [0x90] = gen_helper_pfcmpge,
    [0x94] = gen_helper_pfmin,
    [0x96] = gen_helper_pfrcp,
    [0x97] = gen_helper_pfrsqrt,
    [0x9a] = gen_helper_pfsub,
    [0x9e] = gen_helper_pfadd,
    [0xa0] = gen_helper_pfcmpgt,
    [0xa4] = gen_helper_pfmax,
    [0xa6] = FN_3DNOW_MOVE, /* PFRCPIT1; no need to actually increase precision */
    [0xa7] = FN_3DNOW_MOVE, /* PFRSQIT1 */
    [0xb6] = FN_3DNOW_MOVE, /* PFRCPIT2 */
    [0xaa] = gen_helper_pfsubr,
    [0xae] = gen_helper_pfacc,
    [0xb0] = gen_helper_pfcmpeq,
    [0xb4] = gen_helper_pfmul,
    [0xb7] = gen_helper_pmulhrw_mmx,
    [0xbb] = gen_helper_pswapd,
    [0xbf] = gen_helper_pavgusb,
};

static void gen_3dnow(DisasContext *s, X86DecodedInsn *decode)
{
    uint8_t b = decode->immediate;
    SSEFunc_0_epp fn = b < ARRAY_SIZE(fns_3dnow) ? fns_3dnow[b] : NULL;

    if (!fn) {
        gen_illegal_opcode(s);
        return;
    }
    if (s->flags & HF_TS_MASK) {
        gen_NM_exception(s);
        return;
    }
    if (s->flags & HF_EM_MASK) {
        gen_illegal_opcode(s);
        return;
    }

    gen_helper_enter_mmx(tcg_env);
    if (fn == FN_3DNOW_MOVE) {
       tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[1].offset);
       tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset);
    } else {
       fn(tcg_env, OP_PTR0, OP_PTR1);
    }
}

/*
 * 00 = v*ps Vps, Hps, Wpd
 * 66 = v*pd Vpd, Hpd, Wps
 * f3 = v*ss Vss, Hss, Wps
 * f2 = v*sd Vsd, Hsd, Wps
 */
static inline void gen_unary_fp_sse(DisasContext *s, X86DecodedInsn *decode,
                              SSEFunc_0_epp pd_xmm, SSEFunc_0_epp ps_xmm,
                              SSEFunc_0_epp pd_ymm, SSEFunc_0_epp ps_ymm,
                              SSEFunc_0_eppp sd, SSEFunc_0_eppp ss)
{
    if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) != 0) {
        SSEFunc_0_eppp fn = s->prefix & PREFIX_REPZ ? ss : sd;
        if (!fn) {
            gen_illegal_opcode(s);
            return;
        }
        fn(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2);
    } else {
        SSEFunc_0_epp ps, pd, fn;
        ps = s->vex_l ? ps_ymm : ps_xmm;
        pd = s->vex_l ? pd_ymm : pd_xmm;
        fn = s->prefix & PREFIX_DATA ? pd : ps;
        if (!fn) {
            gen_illegal_opcode(s);
            return;
        }
        fn(tcg_env, OP_PTR0, OP_PTR2);
    }
}
#define UNARY_FP_SSE(uname, lname)                                                 \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_unary_fp_sse(s, decode,                                                    \
                     gen_helper_##lname##pd_xmm,                                   \
                     gen_helper_##lname##ps_xmm,                                   \
                     gen_helper_##lname##pd_ymm,                                   \
                     gen_helper_##lname##ps_ymm,                                   \
                     gen_helper_##lname##sd,                                       \
                     gen_helper_##lname##ss);                                      \
}
UNARY_FP_SSE(VSQRT, sqrt)

/*
 * 00 = v*ps Vps, Hps, Wpd
 * 66 = v*pd Vpd, Hpd, Wps
 * f3 = v*ss Vss, Hss, Wps
 * f2 = v*sd Vsd, Hsd, Wps
 */
static inline void gen_fp_sse(DisasContext *s, X86DecodedInsn *decode,
                              SSEFunc_0_eppp pd_xmm, SSEFunc_0_eppp ps_xmm,
                              SSEFunc_0_eppp pd_ymm, SSEFunc_0_eppp ps_ymm,
                              SSEFunc_0_eppp sd, SSEFunc_0_eppp ss)
{
    SSEFunc_0_eppp ps, pd, fn;
    if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) != 0) {
        fn = s->prefix & PREFIX_REPZ ? ss : sd;
    } else {
        ps = s->vex_l ? ps_ymm : ps_xmm;
        pd = s->vex_l ? pd_ymm : pd_xmm;
        fn = s->prefix & PREFIX_DATA ? pd : ps;
    }
    if (fn) {
        fn(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2);
    } else {
        gen_illegal_opcode(s);
    }
}

#define FP_SSE(uname, lname)                                                       \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_fp_sse(s, decode,                                                          \
               gen_helper_##lname##pd_xmm,                                         \
               gen_helper_##lname##ps_xmm,                                         \
               gen_helper_##lname##pd_ymm,                                         \
               gen_helper_##lname##ps_ymm,                                         \
               gen_helper_##lname##sd,                                             \
               gen_helper_##lname##ss);                                            \
}
FP_SSE(VADD, add)
FP_SSE(VMUL, mul)
FP_SSE(VSUB, sub)
FP_SSE(VMIN, min)
FP_SSE(VDIV, div)
FP_SSE(VMAX, max)

#define FMA_SSE_PACKED(uname, ptr0, ptr1, ptr2, even, odd)                         \
static void gen_##uname##Px(DisasContext *s, X86DecodedInsn *decode)               \
{                                                                                  \
    SSEFunc_0_eppppii xmm = s->vex_w ? gen_helper_fma4pd_xmm : gen_helper_fma4ps_xmm; \
    SSEFunc_0_eppppii ymm = s->vex_w ? gen_helper_fma4pd_ymm : gen_helper_fma4ps_ymm; \
    SSEFunc_0_eppppii fn = s->vex_l ? ymm : xmm;                                   \
                                                                                   \
    fn(tcg_env, OP_PTR0, ptr0, ptr1, ptr2,                                         \
       tcg_constant_i32(even),                                                     \
       tcg_constant_i32((even) ^ (odd)));                                          \
}

#define FMA_SSE(uname, ptr0, ptr1, ptr2, flags)                                    \
FMA_SSE_PACKED(uname, ptr0, ptr1, ptr2, flags, flags)                              \
static void gen_##uname##Sx(DisasContext *s, X86DecodedInsn *decode)               \
{                                                                                  \
    SSEFunc_0_eppppi fn = s->vex_w ? gen_helper_fma4sd : gen_helper_fma4ss;        \
                                                                                   \
    fn(tcg_env, OP_PTR0, ptr0, ptr1, ptr2,                                         \
       tcg_constant_i32(flags));                                                   \
}                                                                                  \

FMA_SSE(VFMADD231,  OP_PTR1, OP_PTR2, OP_PTR0, 0)
FMA_SSE(VFMADD213,  OP_PTR1, OP_PTR0, OP_PTR2, 0)
FMA_SSE(VFMADD132,  OP_PTR0, OP_PTR2, OP_PTR1, 0)

FMA_SSE(VFNMADD231, OP_PTR1, OP_PTR2, OP_PTR0, float_muladd_negate_product)
FMA_SSE(VFNMADD213, OP_PTR1, OP_PTR0, OP_PTR2, float_muladd_negate_product)
FMA_SSE(VFNMADD132, OP_PTR0, OP_PTR2, OP_PTR1, float_muladd_negate_product)

FMA_SSE(VFMSUB231,  OP_PTR1, OP_PTR2, OP_PTR0, float_muladd_negate_c)
FMA_SSE(VFMSUB213,  OP_PTR1, OP_PTR0, OP_PTR2, float_muladd_negate_c)
FMA_SSE(VFMSUB132,  OP_PTR0, OP_PTR2, OP_PTR1, float_muladd_negate_c)

FMA_SSE(VFNMSUB231, OP_PTR1, OP_PTR2, OP_PTR0, float_muladd_negate_c|float_muladd_negate_product)
FMA_SSE(VFNMSUB213, OP_PTR1, OP_PTR0, OP_PTR2, float_muladd_negate_c|float_muladd_negate_product)
FMA_SSE(VFNMSUB132, OP_PTR0, OP_PTR2, OP_PTR1, float_muladd_negate_c|float_muladd_negate_product)

FMA_SSE_PACKED(VFMADDSUB231, OP_PTR1, OP_PTR2, OP_PTR0, float_muladd_negate_c, 0)
FMA_SSE_PACKED(VFMADDSUB213, OP_PTR1, OP_PTR0, OP_PTR2, float_muladd_negate_c, 0)
FMA_SSE_PACKED(VFMADDSUB132, OP_PTR0, OP_PTR2, OP_PTR1, float_muladd_negate_c, 0)

FMA_SSE_PACKED(VFMSUBADD231, OP_PTR1, OP_PTR2, OP_PTR0, 0, float_muladd_negate_c)
FMA_SSE_PACKED(VFMSUBADD213, OP_PTR1, OP_PTR0, OP_PTR2, 0, float_muladd_negate_c)
FMA_SSE_PACKED(VFMSUBADD132, OP_PTR0, OP_PTR2, OP_PTR1, 0, float_muladd_negate_c)

#define FP_UNPACK_SSE(uname, lname)                                                \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    /* PS maps to the DQ integer instruction, PD maps to QDQ.  */                  \
    gen_fp_sse(s, decode,                                                          \
               gen_helper_##lname##qdq_xmm,                                        \
               gen_helper_##lname##dq_xmm,                                         \
               gen_helper_##lname##qdq_ymm,                                        \
               gen_helper_##lname##dq_ymm,                                         \
               NULL, NULL);                                                        \
}
FP_UNPACK_SSE(VUNPCKLPx, punpckl)
FP_UNPACK_SSE(VUNPCKHPx, punpckh)

/*
 * 00 = v*ps Vps, Wpd
 * f3 = v*ss Vss, Wps
 */
static inline void gen_unary_fp32_sse(DisasContext *s, X86DecodedInsn *decode,
                                      SSEFunc_0_epp ps_xmm,
                                      SSEFunc_0_epp ps_ymm,
                                      SSEFunc_0_eppp ss)
{
    if ((s->prefix & (PREFIX_DATA | PREFIX_REPNZ)) != 0) {
        goto illegal_op;
    } else if (s->prefix & PREFIX_REPZ) {
        if (!ss) {
            goto illegal_op;
        }
        ss(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2);
    } else {
        SSEFunc_0_epp fn = s->vex_l ? ps_ymm : ps_xmm;
        if (!fn) {
            goto illegal_op;
        }
        fn(tcg_env, OP_PTR0, OP_PTR2);
    }
    return;

illegal_op:
    gen_illegal_opcode(s);
}
#define UNARY_FP32_SSE(uname, lname)                                               \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_unary_fp32_sse(s, decode,                                                  \
                       gen_helper_##lname##ps_xmm,                                 \
                       gen_helper_##lname##ps_ymm,                                 \
                       gen_helper_##lname##ss);                                    \
}
UNARY_FP32_SSE(VRSQRT, rsqrt)
UNARY_FP32_SSE(VRCP, rcp)

/*
 * 66 = v*pd Vpd, Hpd, Wpd
 * f2 = v*ps Vps, Hps, Wps
 */
static inline void gen_horizontal_fp_sse(DisasContext *s, X86DecodedInsn *decode,
                                         SSEFunc_0_eppp pd_xmm, SSEFunc_0_eppp ps_xmm,
                                         SSEFunc_0_eppp pd_ymm, SSEFunc_0_eppp ps_ymm)
{
    SSEFunc_0_eppp ps, pd, fn;
    ps = s->vex_l ? ps_ymm : ps_xmm;
    pd = s->vex_l ? pd_ymm : pd_xmm;
    fn = s->prefix & PREFIX_DATA ? pd : ps;
    fn(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2);
}
#define HORIZONTAL_FP_SSE(uname, lname)                                            \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_horizontal_fp_sse(s, decode,                                               \
                          gen_helper_##lname##pd_xmm, gen_helper_##lname##ps_xmm,  \
                          gen_helper_##lname##pd_ymm, gen_helper_##lname##ps_ymm); \
}
HORIZONTAL_FP_SSE(VHADD, hadd)
HORIZONTAL_FP_SSE(VHSUB, hsub)
HORIZONTAL_FP_SSE(VADDSUB, addsub)

static inline void gen_ternary_sse(DisasContext *s, X86DecodedInsn *decode,
                                   int op3, SSEFunc_0_epppp xmm, SSEFunc_0_epppp ymm)
{
    SSEFunc_0_epppp fn = s->vex_l ? ymm : xmm;
    TCGv_ptr ptr3 = tcg_temp_new_ptr();

    /* The format of the fourth input is Lx */
    tcg_gen_addi_ptr(ptr3, tcg_env, ZMM_OFFSET(op3));
    fn(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2, ptr3);
}
#define TERNARY_SSE(uname, uvname, lname)                                          \
static void gen_##uvname(DisasContext *s, X86DecodedInsn *decode)                  \
{                                                                                  \
    gen_ternary_sse(s, decode, (uint8_t)decode->immediate >> 4,                    \
                    gen_helper_##lname##_xmm, gen_helper_##lname##_ymm);           \
}                                                                                  \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_ternary_sse(s, decode, 0,                                                  \
                  gen_helper_##lname##_xmm, gen_helper_##lname##_ymm);             \
}
TERNARY_SSE(BLENDVPS, VBLENDVPS, blendvps)
TERNARY_SSE(BLENDVPD, VBLENDVPD, blendvpd)
TERNARY_SSE(PBLENDVB, VPBLENDVB, pblendvb)

static inline void gen_binary_imm_sse(DisasContext *s, X86DecodedInsn *decode,
                                      SSEFunc_0_epppi xmm, SSEFunc_0_epppi ymm)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    if (!s->vex_l) {
        xmm(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2, imm);
    } else {
        ymm(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2, imm);
    }
}

#define BINARY_IMM_SSE(uname, lname)                                               \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_binary_imm_sse(s, decode,                                                  \
                       gen_helper_##lname##_xmm,                                   \
                       gen_helper_##lname##_ymm);                                  \
}

BINARY_IMM_SSE(VBLENDPD,   blendpd)
BINARY_IMM_SSE(VBLENDPS,   blendps)
BINARY_IMM_SSE(VPBLENDW,   pblendw)
BINARY_IMM_SSE(VDDPS,      dpps)
#define gen_helper_dppd_ymm NULL
BINARY_IMM_SSE(VDDPD,      dppd)
BINARY_IMM_SSE(VMPSADBW,   mpsadbw)
BINARY_IMM_SSE(PCLMULQDQ,  pclmulqdq)


#define UNARY_INT_GVEC(uname, func, ...)                                           \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    int vec_len = vector_len(s, decode);                                          \
                                                                                   \
    func(__VA_ARGS__, decode->op[0].offset,                                        \
         decode->op[2].offset, vec_len, vec_len);                                  \
}
UNARY_INT_GVEC(PABSB,          tcg_gen_gvec_abs, MO_8)
UNARY_INT_GVEC(PABSW,          tcg_gen_gvec_abs, MO_16)
UNARY_INT_GVEC(PABSD,          tcg_gen_gvec_abs, MO_32)
UNARY_INT_GVEC(VBROADCASTx128, tcg_gen_gvec_dup_mem, MO_128)
UNARY_INT_GVEC(VPBROADCASTB,   tcg_gen_gvec_dup_mem, MO_8)
UNARY_INT_GVEC(VPBROADCASTW,   tcg_gen_gvec_dup_mem, MO_16)
UNARY_INT_GVEC(VPBROADCASTD,   tcg_gen_gvec_dup_mem, MO_32)
UNARY_INT_GVEC(VPBROADCASTQ,   tcg_gen_gvec_dup_mem, MO_64)


#define BINARY_INT_GVEC(uname, func, ...)                                          \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    int vec_len = vector_len(s, decode);                                          \
                                                                                   \
    func(__VA_ARGS__,                                                              \
         decode->op[0].offset, decode->op[1].offset,                               \
         decode->op[2].offset, vec_len, vec_len);                                  \
}

BINARY_INT_GVEC(PADDB,   tcg_gen_gvec_add, MO_8)
BINARY_INT_GVEC(PADDW,   tcg_gen_gvec_add, MO_16)
BINARY_INT_GVEC(PADDD,   tcg_gen_gvec_add, MO_32)
BINARY_INT_GVEC(PADDQ,   tcg_gen_gvec_add, MO_64)
BINARY_INT_GVEC(PADDSB,  tcg_gen_gvec_ssadd, MO_8)
BINARY_INT_GVEC(PADDSW,  tcg_gen_gvec_ssadd, MO_16)
BINARY_INT_GVEC(PADDUSB, tcg_gen_gvec_usadd, MO_8)
BINARY_INT_GVEC(PADDUSW, tcg_gen_gvec_usadd, MO_16)
BINARY_INT_GVEC(PAND,    tcg_gen_gvec_and, MO_64)
BINARY_INT_GVEC(PCMPEQB, tcg_gen_gvec_cmp, TCG_COND_EQ, MO_8)
BINARY_INT_GVEC(PCMPEQD, tcg_gen_gvec_cmp, TCG_COND_EQ, MO_32)
BINARY_INT_GVEC(PCMPEQW, tcg_gen_gvec_cmp, TCG_COND_EQ, MO_16)
BINARY_INT_GVEC(PCMPEQQ, tcg_gen_gvec_cmp, TCG_COND_EQ, MO_64)
BINARY_INT_GVEC(PCMPGTB, tcg_gen_gvec_cmp, TCG_COND_GT, MO_8)
BINARY_INT_GVEC(PCMPGTW, tcg_gen_gvec_cmp, TCG_COND_GT, MO_16)
BINARY_INT_GVEC(PCMPGTD, tcg_gen_gvec_cmp, TCG_COND_GT, MO_32)
BINARY_INT_GVEC(PCMPGTQ, tcg_gen_gvec_cmp, TCG_COND_GT, MO_64)
BINARY_INT_GVEC(PMAXSB,  tcg_gen_gvec_smax, MO_8)
BINARY_INT_GVEC(PMAXSW,  tcg_gen_gvec_smax, MO_16)
BINARY_INT_GVEC(PMAXSD,  tcg_gen_gvec_smax, MO_32)
BINARY_INT_GVEC(PMAXUB,  tcg_gen_gvec_umax, MO_8)
BINARY_INT_GVEC(PMAXUW,  tcg_gen_gvec_umax, MO_16)
BINARY_INT_GVEC(PMAXUD,  tcg_gen_gvec_umax, MO_32)
BINARY_INT_GVEC(PMINSB,  tcg_gen_gvec_smin, MO_8)
BINARY_INT_GVEC(PMINSW,  tcg_gen_gvec_smin, MO_16)
BINARY_INT_GVEC(PMINSD,  tcg_gen_gvec_smin, MO_32)
BINARY_INT_GVEC(PMINUB,  tcg_gen_gvec_umin, MO_8)
BINARY_INT_GVEC(PMINUW,  tcg_gen_gvec_umin, MO_16)
BINARY_INT_GVEC(PMINUD,  tcg_gen_gvec_umin, MO_32)
BINARY_INT_GVEC(PMULLW,  tcg_gen_gvec_mul, MO_16)
BINARY_INT_GVEC(PMULLD,  tcg_gen_gvec_mul, MO_32)
BINARY_INT_GVEC(POR,     tcg_gen_gvec_or, MO_64)
BINARY_INT_GVEC(PSUBB,   tcg_gen_gvec_sub, MO_8)
BINARY_INT_GVEC(PSUBW,   tcg_gen_gvec_sub, MO_16)
BINARY_INT_GVEC(PSUBD,   tcg_gen_gvec_sub, MO_32)
BINARY_INT_GVEC(PSUBQ,   tcg_gen_gvec_sub, MO_64)
BINARY_INT_GVEC(PSUBSB,  tcg_gen_gvec_sssub, MO_8)
BINARY_INT_GVEC(PSUBSW,  tcg_gen_gvec_sssub, MO_16)
BINARY_INT_GVEC(PSUBUSB, tcg_gen_gvec_ussub, MO_8)
BINARY_INT_GVEC(PSUBUSW, tcg_gen_gvec_ussub, MO_16)
BINARY_INT_GVEC(PXOR,    tcg_gen_gvec_xor, MO_64)


/*
 * 00 = p*  Pq, Qq (if mmx not NULL; no VEX)
 * 66 = vp* Vx, Hx, Wx
 *
 * These are really the same encoding, because 1) V is the same as P when VEX.V
 * is not present 2) P and Q are the same as H and W apart from MM/XMM
 */
static inline void gen_binary_int_sse(DisasContext *s, X86DecodedInsn *decode,
                                      SSEFunc_0_eppp mmx, SSEFunc_0_eppp xmm, SSEFunc_0_eppp ymm)
{
    assert(!!mmx == !!(decode->e.special == X86_SPECIAL_MMX));

    if (mmx && (s->prefix & PREFIX_VEX) && !(s->prefix & PREFIX_DATA)) {
        /* VEX encoding is not applicable to MMX instructions.  */
        gen_illegal_opcode(s);
        return;
    }
    if (!(s->prefix & PREFIX_DATA)) {
        mmx(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2);
    } else if (!s->vex_l) {
        xmm(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2);
    } else {
        ymm(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2);
    }
}


#define BINARY_INT_MMX(uname, lname)                                               \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_binary_int_sse(s, decode,                                                  \
                          gen_helper_##lname##_mmx,                                \
                          gen_helper_##lname##_xmm,                                \
                          gen_helper_##lname##_ymm);                               \
}
BINARY_INT_MMX(PUNPCKLBW,  punpcklbw)
BINARY_INT_MMX(PUNPCKLWD,  punpcklwd)
BINARY_INT_MMX(PUNPCKLDQ,  punpckldq)
BINARY_INT_MMX(PACKSSWB,   packsswb)
BINARY_INT_MMX(PACKUSWB,   packuswb)
BINARY_INT_MMX(PUNPCKHBW,  punpckhbw)
BINARY_INT_MMX(PUNPCKHWD,  punpckhwd)
BINARY_INT_MMX(PUNPCKHDQ,  punpckhdq)
BINARY_INT_MMX(PACKSSDW,   packssdw)

BINARY_INT_MMX(PAVGB,   pavgb)
BINARY_INT_MMX(PAVGW,   pavgw)
BINARY_INT_MMX(PMADDWD, pmaddwd)
BINARY_INT_MMX(PMULHUW, pmulhuw)
BINARY_INT_MMX(PMULHW,  pmulhw)
BINARY_INT_MMX(PMULUDQ, pmuludq)
BINARY_INT_MMX(PSADBW,  psadbw)

BINARY_INT_MMX(PSLLW_r, psllw)
BINARY_INT_MMX(PSLLD_r, pslld)
BINARY_INT_MMX(PSLLQ_r, psllq)
BINARY_INT_MMX(PSRLW_r, psrlw)
BINARY_INT_MMX(PSRLD_r, psrld)
BINARY_INT_MMX(PSRLQ_r, psrlq)
BINARY_INT_MMX(PSRAW_r, psraw)
BINARY_INT_MMX(PSRAD_r, psrad)

BINARY_INT_MMX(PHADDW,    phaddw)
BINARY_INT_MMX(PHADDSW,   phaddsw)
BINARY_INT_MMX(PHADDD,    phaddd)
BINARY_INT_MMX(PHSUBW,    phsubw)
BINARY_INT_MMX(PHSUBSW,   phsubsw)
BINARY_INT_MMX(PHSUBD,    phsubd)
BINARY_INT_MMX(PMADDUBSW, pmaddubsw)
BINARY_INT_MMX(PSHUFB,    pshufb)
BINARY_INT_MMX(PSIGNB,    psignb)
BINARY_INT_MMX(PSIGNW,    psignw)
BINARY_INT_MMX(PSIGND,    psignd)
BINARY_INT_MMX(PMULHRSW,  pmulhrsw)

/* Instructions with no MMX equivalent.  */
#define BINARY_INT_SSE(uname, lname)                                               \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_binary_int_sse(s, decode,                                                  \
                          NULL,                                                    \
                          gen_helper_##lname##_xmm,                                \
                          gen_helper_##lname##_ymm);                               \
}

/* Instructions with no MMX equivalent.  */
BINARY_INT_SSE(PUNPCKLQDQ, punpcklqdq)
BINARY_INT_SSE(PUNPCKHQDQ, punpckhqdq)
BINARY_INT_SSE(VPACKUSDW,  packusdw)
BINARY_INT_SSE(VPERMILPS,  vpermilps)
BINARY_INT_SSE(VPERMILPD,  vpermilpd)
BINARY_INT_SSE(VMASKMOVPS, vpmaskmovd)
BINARY_INT_SSE(VMASKMOVPD, vpmaskmovq)

BINARY_INT_SSE(PMULDQ,    pmuldq)

BINARY_INT_SSE(VAESDEC, aesdec)
BINARY_INT_SSE(VAESDECLAST, aesdeclast)
BINARY_INT_SSE(VAESENC, aesenc)
BINARY_INT_SSE(VAESENCLAST, aesenclast)

#define UNARY_CMP_SSE(uname, lname)                                                \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    if (!s->vex_l) {                                                               \
        gen_helper_##lname##_xmm(tcg_env, OP_PTR1, OP_PTR2);                       \
    } else {                                                                       \
        gen_helper_##lname##_ymm(tcg_env, OP_PTR1, OP_PTR2);                       \
    }                                                                              \
    assume_cc_op(s, CC_OP_EFLAGS);                                                  \
}
UNARY_CMP_SSE(VPTEST,     ptest)
UNARY_CMP_SSE(VTESTPS,    vtestps)
UNARY_CMP_SSE(VTESTPD,    vtestpd)

static inline void gen_unary_int_sse(DisasContext *s, X86DecodedInsn *decode,
                                     SSEFunc_0_epp xmm, SSEFunc_0_epp ymm)
{
    if (!s->vex_l) {
        xmm(tcg_env, OP_PTR0, OP_PTR2);
    } else {
        ymm(tcg_env, OP_PTR0, OP_PTR2);
    }
}

#define UNARY_INT_SSE(uname, lname)                                                \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_unary_int_sse(s, decode,                                                   \
                      gen_helper_##lname##_xmm,                                    \
                      gen_helper_##lname##_ymm);                                   \
}

UNARY_INT_SSE(VPMOVSXBW,    pmovsxbw)
UNARY_INT_SSE(VPMOVSXBD,    pmovsxbd)
UNARY_INT_SSE(VPMOVSXBQ,    pmovsxbq)
UNARY_INT_SSE(VPMOVSXWD,    pmovsxwd)
UNARY_INT_SSE(VPMOVSXWQ,    pmovsxwq)
UNARY_INT_SSE(VPMOVSXDQ,    pmovsxdq)

UNARY_INT_SSE(VPMOVZXBW,    pmovzxbw)
UNARY_INT_SSE(VPMOVZXBD,    pmovzxbd)
UNARY_INT_SSE(VPMOVZXBQ,    pmovzxbq)
UNARY_INT_SSE(VPMOVZXWD,    pmovzxwd)
UNARY_INT_SSE(VPMOVZXWQ,    pmovzxwq)
UNARY_INT_SSE(VPMOVZXDQ,    pmovzxdq)

UNARY_INT_SSE(VMOVSLDUP,    pmovsldup)
UNARY_INT_SSE(VMOVSHDUP,    pmovshdup)
UNARY_INT_SSE(VMOVDDUP,     pmovdldup)

UNARY_INT_SSE(VCVTDQ2PD, cvtdq2pd)
UNARY_INT_SSE(VCVTPD2DQ, cvtpd2dq)
UNARY_INT_SSE(VCVTTPD2DQ, cvttpd2dq)
UNARY_INT_SSE(VCVTDQ2PS, cvtdq2ps)
UNARY_INT_SSE(VCVTPS2DQ, cvtps2dq)
UNARY_INT_SSE(VCVTTPS2DQ, cvttps2dq)
UNARY_INT_SSE(VCVTPH2PS, cvtph2ps)


static inline void gen_unary_imm_sse(DisasContext *s, X86DecodedInsn *decode,
                                     SSEFunc_0_ppi xmm, SSEFunc_0_ppi ymm)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    if (!s->vex_l) {
        xmm(OP_PTR0, OP_PTR1, imm);
    } else {
        ymm(OP_PTR0, OP_PTR1, imm);
    }
}

#define UNARY_IMM_SSE(uname, lname)                                                \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_unary_imm_sse(s, decode,                                                   \
                      gen_helper_##lname##_xmm,                                    \
                      gen_helper_##lname##_ymm);                                   \
}

UNARY_IMM_SSE(PSHUFD,     pshufd)
UNARY_IMM_SSE(PSHUFHW,    pshufhw)
UNARY_IMM_SSE(PSHUFLW,    pshuflw)
#define gen_helper_vpermq_xmm NULL
UNARY_IMM_SSE(VPERMQ,      vpermq)
UNARY_IMM_SSE(VPERMILPS_i, vpermilps_imm)
UNARY_IMM_SSE(VPERMILPD_i, vpermilpd_imm)

static inline void gen_unary_imm_fp_sse(DisasContext *s, X86DecodedInsn *decode,
                                        SSEFunc_0_eppi xmm, SSEFunc_0_eppi ymm)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    if (!s->vex_l) {
        xmm(tcg_env, OP_PTR0, OP_PTR1, imm);
    } else {
        ymm(tcg_env, OP_PTR0, OP_PTR1, imm);
    }
}

#define UNARY_IMM_FP_SSE(uname, lname)                                             \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_unary_imm_fp_sse(s, decode,                                                \
                      gen_helper_##lname##_xmm,                                    \
                      gen_helper_##lname##_ymm);                                   \
}

UNARY_IMM_FP_SSE(VROUNDPS,    roundps)
UNARY_IMM_FP_SSE(VROUNDPD,    roundpd)

static inline void gen_vexw_avx(DisasContext *s, X86DecodedInsn *decode,
                                SSEFunc_0_eppp d_xmm, SSEFunc_0_eppp q_xmm,
                                SSEFunc_0_eppp d_ymm, SSEFunc_0_eppp q_ymm)
{
    SSEFunc_0_eppp d = s->vex_l ? d_ymm : d_xmm;
    SSEFunc_0_eppp q = s->vex_l ? q_ymm : q_xmm;
    SSEFunc_0_eppp fn = s->vex_w ? q : d;
    fn(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2);
}

/* VEX.W affects whether to operate on 32- or 64-bit elements.  */
#define VEXW_AVX(uname, lname)                                                     \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_vexw_avx(s, decode,                                                        \
                 gen_helper_##lname##d_xmm, gen_helper_##lname##q_xmm,             \
                 gen_helper_##lname##d_ymm, gen_helper_##lname##q_ymm);            \
}
VEXW_AVX(VPSLLV,    vpsllv)
VEXW_AVX(VPSRLV,    vpsrlv)
VEXW_AVX(VPSRAV,    vpsrav)
VEXW_AVX(VPMASKMOV, vpmaskmov)

/* Same as above, but with extra arguments to the helper.  */
static inline void gen_vsib_avx(DisasContext *s, X86DecodedInsn *decode,
                                SSEFunc_0_epppti d_xmm, SSEFunc_0_epppti q_xmm,
                                SSEFunc_0_epppti d_ymm, SSEFunc_0_epppti q_ymm)
{
    SSEFunc_0_epppti d = s->vex_l ? d_ymm : d_xmm;
    SSEFunc_0_epppti q = s->vex_l ? q_ymm : q_xmm;
    SSEFunc_0_epppti fn = s->vex_w ? q : d;
    TCGv_i32 scale = tcg_constant_i32(decode->mem.scale);
    TCGv_ptr index = tcg_temp_new_ptr();

    /* Pass third input as (index, base, scale) */
    tcg_gen_addi_ptr(index, tcg_env, ZMM_OFFSET(decode->mem.index));
    fn(tcg_env, OP_PTR0, OP_PTR1, index, s->A0, scale);

    /*
     * There are two output operands, so zero OP1's high 128 bits
     * in the VEX.128 case.
     */
    if (!s->vex_l) {
        int ymmh_ofs = vector_elem_offset(&decode->op[1], MO_128, 1);
        tcg_gen_gvec_dup_imm(MO_64, ymmh_ofs, 16, 16, 0);
    }
}
#define VSIB_AVX(uname, lname)                                                     \
static void gen_##uname(DisasContext *s, X86DecodedInsn *decode)                   \
{                                                                                  \
    gen_vsib_avx(s, decode,                                                        \
                 gen_helper_##lname##d_xmm, gen_helper_##lname##q_xmm,             \
                 gen_helper_##lname##d_ymm, gen_helper_##lname##q_ymm);            \
}
VSIB_AVX(VPGATHERD, vpgatherd)
VSIB_AVX(VPGATHERQ, vpgatherq)

static void gen_AAA(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_helper_aaa(tcg_env);
    assume_cc_op(s, CC_OP_EFLAGS);
}

static void gen_AAD(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_aad(s->T0, s->T0, s->T1);
    prepare_update1_cc(decode, s, CC_OP_LOGICB);
}

static void gen_AAM(DisasContext *s, X86DecodedInsn *decode)
{
    if (decode->immediate == 0) {
        gen_exception(s, EXCP00_DIVZ);
    } else {
        gen_helper_aam(s->T0, s->T0, s->T1);
        prepare_update1_cc(decode, s, CC_OP_LOGICB);
    }
}

static void gen_AAS(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_helper_aas(tcg_env);
    assume_cc_op(s, CC_OP_EFLAGS);
}

static void gen_ADC(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;
    TCGv c_in = tcg_temp_new();

    gen_compute_eflags_c(s, c_in);
    if (s->prefix & PREFIX_LOCK) {
        tcg_gen_add_tl(s->T0, c_in, s->T1);
        tcg_gen_atomic_add_fetch_tl(s->T0, s->A0, s->T0,
                                    s->mem_index, ot | MO_LE);
    } else {
        tcg_gen_add_tl(s->T0, s->T0, s->T1);
        tcg_gen_add_tl(s->T0, s->T0, c_in);
    }
    prepare_update3_cc(decode, s, CC_OP_ADCB + ot, c_in);
}

static void gen_ADCOX(DisasContext *s, X86DecodedInsn *decode, int cc_op)
{
    MemOp ot = decode->op[0].ot;
    TCGv carry_in = NULL;
    TCGv *carry_out = (cc_op == CC_OP_ADCX ? &decode->cc_dst : &decode->cc_src2);
    TCGv zero;

    decode->cc_op = cc_op;
    *carry_out = tcg_temp_new();
    if (CC_OP_HAS_EFLAGS(s->cc_op)) {
        decode->cc_src = cpu_cc_src;

        /* Re-use the carry-out from a previous round?  */
        if (s->cc_op == cc_op || s->cc_op == CC_OP_ADCOX) {
            carry_in = (cc_op == CC_OP_ADCX ? cpu_cc_dst : cpu_cc_src2);
        }

        /* Preserve the opposite carry from previous rounds?  */
        if (s->cc_op != cc_op && s->cc_op != CC_OP_EFLAGS) {
            decode->cc_op = CC_OP_ADCOX;
            if (carry_out == &decode->cc_dst) {
                decode->cc_src2 = cpu_cc_src2;
            } else {
                decode->cc_dst = cpu_cc_dst;
            }
        }
    } else {
        decode->cc_src = tcg_temp_new();
        gen_mov_eflags(s, decode->cc_src);
    }

    if (!carry_in) {
        /* Get carry_in out of EFLAGS.  */
        carry_in = tcg_temp_new();
        tcg_gen_extract_tl(carry_in, decode->cc_src,
            ctz32(cc_op == CC_OP_ADCX ? CC_C : CC_O), 1);
    }

    switch (ot) {
#ifdef TARGET_X86_64
    case MO_32:
        /* If TL is 64-bit just do everything in 64-bit arithmetic.  */
        tcg_gen_ext32u_tl(s->T0, s->T0);
        tcg_gen_ext32u_tl(s->T1, s->T1);
        tcg_gen_add_i64(s->T0, s->T0, s->T1);
        tcg_gen_add_i64(s->T0, s->T0, carry_in);
        tcg_gen_shri_i64(*carry_out, s->T0, 32);
        break;
#endif
    default:
        zero = tcg_constant_tl(0);
        tcg_gen_add2_tl(s->T0, *carry_out, s->T0, zero, carry_in, zero);
        tcg_gen_add2_tl(s->T0, *carry_out, s->T0, *carry_out, s->T1, zero);
        break;
    }
}

static void gen_ADCX(DisasContext *s, X86DecodedInsn *decode)
{
    gen_ADCOX(s, decode, CC_OP_ADCX);
}

static void gen_ADD(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;

    if (s->prefix & PREFIX_LOCK) {
        tcg_gen_atomic_add_fetch_tl(s->T0, s->A0, s->T1,
                                    s->mem_index, ot | MO_LE);
    } else {
        tcg_gen_add_tl(s->T0, s->T0, s->T1);
    }
    prepare_update2_cc(decode, s, CC_OP_ADDB + ot);
}

static void gen_ADOX(DisasContext *s, X86DecodedInsn *decode)
{
    gen_ADCOX(s, decode, CC_OP_ADOX);
}

static void gen_AND(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;

    if (s->prefix & PREFIX_LOCK) {
        tcg_gen_atomic_and_fetch_tl(s->T0, s->A0, s->T1,
                                    s->mem_index, ot | MO_LE);
    } else {
        tcg_gen_and_tl(s->T0, s->T0, s->T1);
    }
    prepare_update1_cc(decode, s, CC_OP_LOGICB + ot);
}

static void gen_ANDN(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;

    tcg_gen_andc_tl(s->T0, s->T1, s->T0);
    prepare_update1_cc(decode, s, CC_OP_LOGICB + ot);
}

static void gen_ARPL(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv zf = tcg_temp_new();
    TCGv flags = tcg_temp_new();

    gen_mov_eflags(s, flags);

    /* Compute adjusted DST in T1, merging in SRC[RPL].  */
    tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 0, 2);

    /* Z flag set if DST[RPL] < SRC[RPL] */
    tcg_gen_setcond_tl(TCG_COND_LTU, zf, s->T0, s->T1);
    tcg_gen_deposit_tl(flags, flags, zf, ctz32(CC_Z), 1);

    /* Place maximum RPL in DST */
    tcg_gen_umax_tl(s->T0, s->T0, s->T1);

    decode->cc_src = flags;
    decode->cc_op = CC_OP_EFLAGS;
}

static void gen_BEXTR(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    TCGv bound = tcg_constant_tl(ot == MO_64 ? 63 : 31);
    TCGv zero = tcg_constant_tl(0);
    TCGv mone = tcg_constant_tl(-1);

    /*
     * Extract START, and shift the operand.
     * Shifts larger than operand size get zeros.
     */
    tcg_gen_ext8u_tl(s->A0, s->T1);
    tcg_gen_shr_tl(s->T0, s->T0, s->A0);

    tcg_gen_movcond_tl(TCG_COND_LEU, s->T0, s->A0, bound, s->T0, zero);

    /*
     * Extract the LEN into an inverse mask.  Lengths larger than
     * operand size get all zeros, length 0 gets all ones.
     */
    tcg_gen_extract_tl(s->A0, s->T1, 8, 8);
    tcg_gen_shl_tl(s->T1, mone, s->A0);
    tcg_gen_movcond_tl(TCG_COND_LEU, s->T1, s->A0, bound, s->T1, zero);
    tcg_gen_andc_tl(s->T0, s->T0, s->T1);

    prepare_update1_cc(decode, s, CC_OP_LOGICB + ot);
}

static void gen_BLSI(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;

    /* input in T1, which is ready for prepare_update2_cc  */
    tcg_gen_neg_tl(s->T0, s->T1);
    tcg_gen_and_tl(s->T0, s->T0, s->T1);
    prepare_update2_cc(decode, s, CC_OP_BLSIB + ot);
}

static void gen_BLSMSK(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;

    /* input in T1, which is ready for prepare_update2_cc  */
    tcg_gen_subi_tl(s->T0, s->T1, 1);
    tcg_gen_xor_tl(s->T0, s->T0, s->T1);
    prepare_update2_cc(decode, s, CC_OP_BMILGB + ot);
}

static void gen_BLSR(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;

    /* input in T1, which is ready for prepare_update2_cc  */
    tcg_gen_subi_tl(s->T0, s->T1, 1);
    tcg_gen_and_tl(s->T0, s->T0, s->T1);
    prepare_update2_cc(decode, s, CC_OP_BMILGB + ot);
}

static void gen_BOUND(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 op = tcg_temp_new_i32();
    tcg_gen_trunc_tl_i32(op, s->T0);
    if (decode->op[1].ot == MO_16) {
        gen_helper_boundw(tcg_env, s->A0, op);
    } else {
        gen_helper_boundl(tcg_env, s->A0, op);
    }
}

/* Non-standard convention - on entry T0 is zero-extended input, T1 is the output.  */
static void gen_BSF(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;

    /* Only the Z bit is defined and it is related to the input.  */
    decode->cc_dst = tcg_temp_new();
    decode->cc_op = CC_OP_LOGICB + ot;
    tcg_gen_mov_tl(decode->cc_dst, s->T0);

    /*
     * The manual says that the output is undefined when the
     * input is zero, but real hardware leaves it unchanged, and
     * real programs appear to depend on that.  Accomplish this
     * by passing the output as the value to return upon zero.
     */
    tcg_gen_ctz_tl(s->T0, s->T0, s->T1);
}

/* Non-standard convention - on entry T0 is zero-extended input, T1 is the output.  */
static void gen_BSR(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;

    /* Only the Z bit is defined and it is related to the input.  */
    decode->cc_dst = tcg_temp_new();
    decode->cc_op = CC_OP_LOGICB + ot;
    tcg_gen_mov_tl(decode->cc_dst, s->T0);

    /*
     * The manual says that the output is undefined when the
     * input is zero, but real hardware leaves it unchanged, and
     * real programs appear to depend on that.  Accomplish this
     * by passing the output as the value to return upon zero.
     * Plus, return the bit index of the first 1 bit.
     */
    tcg_gen_xori_tl(s->T1, s->T1, TARGET_LONG_BITS - 1);
    tcg_gen_clz_tl(s->T0, s->T0, s->T1);
    tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1);
}

static void gen_BSWAP(DisasContext *s, X86DecodedInsn *decode)
{
#ifdef TARGET_X86_64
    if (s->dflag == MO_64) {
        tcg_gen_bswap64_i64(s->T0, s->T0);
        return;
    }
#endif
    tcg_gen_bswap32_tl(s->T0, s->T0, TCG_BSWAP_OZ);
}

static void gen_BZHI(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    TCGv bound = tcg_constant_tl(ot == MO_64 ? 63 : 31);
    TCGv zero = tcg_constant_tl(0);
    TCGv mone = tcg_constant_tl(-1);

    tcg_gen_ext8u_tl(s->T1, s->T1);

    tcg_gen_shl_tl(s->A0, mone, s->T1);
    tcg_gen_movcond_tl(TCG_COND_LEU, s->A0, s->T1, bound, s->A0, zero);
    tcg_gen_andc_tl(s->T0, s->T0, s->A0);
    /*
     * Note that since we're using BMILG (in order to get O
     * cleared) we need to store the inverse into C.
     */
    tcg_gen_setcond_tl(TCG_COND_LEU, s->T1, s->T1, bound);
    prepare_update2_cc(decode, s, CC_OP_BMILGB + ot);
}

static void gen_CALL(DisasContext *s, X86DecodedInsn *decode)
{
    gen_push_v(s, eip_next_tl(s));
    gen_JMP(s, decode);
}

static void gen_CALL_m(DisasContext *s, X86DecodedInsn *decode)
{
    gen_push_v(s, eip_next_tl(s));
    gen_JMP_m(s, decode);
}

static void gen_CALLF(DisasContext *s, X86DecodedInsn *decode)
{
    gen_far_call(s);
}

static void gen_CALLF_m(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;

    gen_op_ld_v(s, ot, s->T0, s->A0);
    gen_add_A0_im(s, 1 << ot);
    gen_op_ld_v(s, MO_16, s->T1, s->A0);
    gen_far_call(s);
}

static void gen_CBW(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp src_ot = decode->op[0].ot - 1;

    tcg_gen_ext_tl(s->T0, s->T0, src_ot | MO_SIGN);
}

static void gen_CLC(DisasContext *s, X86DecodedInsn *decode)
{
    gen_compute_eflags(s);
    tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
}

static void gen_CLD(DisasContext *s, X86DecodedInsn *decode)
{
    tcg_gen_st_i32(tcg_constant_i32(1), tcg_env, offsetof(CPUX86State, df));
}

static void gen_CLI(DisasContext *s, X86DecodedInsn *decode)
{
    gen_reset_eflags(s, IF_MASK);
}

static void gen_CLTS(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_clts(tcg_env);
    /* abort block because static cpu state changed */
    s->base.is_jmp = DISAS_EOB_NEXT;
}

static void gen_CMC(DisasContext *s, X86DecodedInsn *decode)
{
    gen_compute_eflags(s);
    tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
}

static void gen_CMOVcc(DisasContext *s, X86DecodedInsn *decode)
{
    gen_cmovcc1(s, decode->b & 0xf, s->T0, s->T1);
}

static void gen_CMPccXADD(DisasContext *s, X86DecodedInsn *decode)
{
    TCGLabel *label_top = gen_new_label();
    TCGLabel *label_bottom = gen_new_label();
    TCGv oldv = tcg_temp_new();
    TCGv newv = tcg_temp_new();
    TCGv cmpv = tcg_temp_new();
    TCGCond cond;

    TCGv cmp_lhs, cmp_rhs;
    MemOp ot, ot_full;

    int jcc_op = (decode->b >> 1) & 7;
    static const TCGCond cond_table[8] = {
        [JCC_O] = TCG_COND_LT,  /* test sign bit by comparing against 0 */
        [JCC_B] = TCG_COND_LTU,
        [JCC_Z] = TCG_COND_EQ,
        [JCC_BE] = TCG_COND_LEU,
        [JCC_S] = TCG_COND_LT,  /* test sign bit by comparing against 0 */
        [JCC_P] = TCG_COND_TSTEQ,  /* even parity - tests low bit of popcount */
        [JCC_L] = TCG_COND_LT,
        [JCC_LE] = TCG_COND_LE,
    };

    cond = cond_table[jcc_op];
    if (decode->b & 1) {
        cond = tcg_invert_cond(cond);
    }

    ot = decode->op[0].ot;
    ot_full = ot | MO_LE;
    if (jcc_op >= JCC_S) {
        /*
         * Sign-extend values before subtracting for S, P (zero/sign extension
         * does not matter there) L, LE and their inverses.
         */
        ot_full |= MO_SIGN;
    }

    /*
     * cmpv will be moved to cc_src *after* cpu_regs[] is written back, so use
     * tcg_gen_ext_tl instead of gen_ext_tl.
     */
    tcg_gen_ext_tl(cmpv, cpu_regs[decode->op[1].n], ot_full);

    /*
     * Cmpxchg loop starts here.
     * - s->T1: addition operand (from decoder)
     * - s->A0: dest address (from decoder)
     * - s->cc_srcT: memory operand (lhs for comparison)
     * - cmpv: rhs for comparison
     */
    gen_set_label(label_top);
    gen_op_ld_v(s, ot_full, s->cc_srcT, s->A0);
    tcg_gen_sub_tl(s->T0, s->cc_srcT, cmpv);

    /* Compute the comparison result by hand, to avoid clobbering cc_*.  */
    switch (jcc_op) {
    case JCC_O:
        /* (src1 ^ src2) & (src1 ^ dst). newv is only used here for a moment */
        tcg_gen_xor_tl(newv, s->cc_srcT, s->T0);
        tcg_gen_xor_tl(s->tmp0, s->cc_srcT, cmpv);
        tcg_gen_and_tl(s->tmp0, s->tmp0, newv);
        tcg_gen_sextract_tl(s->tmp0, s->tmp0, 0, 8 << ot);
        cmp_lhs = s->tmp0, cmp_rhs = tcg_constant_tl(0);
        break;

    case JCC_P:
        tcg_gen_ext8u_tl(s->tmp0, s->T0);
        tcg_gen_ctpop_tl(s->tmp0, s->tmp0);
        cmp_lhs = s->tmp0, cmp_rhs = tcg_constant_tl(1);
        break;

    case JCC_S:
        tcg_gen_sextract_tl(s->tmp0, s->T0, 0, 8 << ot);
        cmp_lhs = s->tmp0, cmp_rhs = tcg_constant_tl(0);
        break;

    default:
        cmp_lhs = s->cc_srcT, cmp_rhs = cmpv;
        break;
    }

    /* Compute new value: if condition does not hold, just store back s->cc_srcT */
    tcg_gen_add_tl(newv, s->cc_srcT, s->T1);
    tcg_gen_movcond_tl(cond, newv, cmp_lhs, cmp_rhs, newv, s->cc_srcT);
    tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, s->cc_srcT, newv, s->mem_index, ot_full);

    /* Exit unconditionally if cmpxchg succeeded.  */
    tcg_gen_brcond_tl(TCG_COND_EQ, oldv, s->cc_srcT, label_bottom);

    /* Try again if there was actually a store to make.  */
    tcg_gen_brcond_tl(cond, cmp_lhs, cmp_rhs, label_top);
    gen_set_label(label_bottom);

    /* Store old value to registers only after a successful store.  */
    gen_writeback(s, decode, 1, s->cc_srcT);

    decode->cc_dst = s->T0;
    decode->cc_src = cmpv;
    decode->cc_op = CC_OP_SUBB + ot;
}

static void gen_CMPS(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[2].ot;
    if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
        gen_repz_nz(s, ot, gen_cmps);
    } else {
        gen_cmps(s, ot);
    }
}

static void gen_CMPXCHG(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[2].ot;
    TCGv cmpv = tcg_temp_new();
    TCGv oldv = tcg_temp_new();
    TCGv newv = tcg_temp_new();
    TCGv dest;

    tcg_gen_ext_tl(cmpv, cpu_regs[R_EAX], ot);
    tcg_gen_ext_tl(newv, s->T1, ot);
    if (s->prefix & PREFIX_LOCK) {
        tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, cmpv, newv,
                                  s->mem_index, ot | MO_LE);
    } else {
        tcg_gen_ext_tl(oldv, s->T0, ot);
        if (decode->op[0].has_ea) {
            /*
             * Perform an unconditional store cycle like physical cpu;
             * must be before changing accumulator to ensure
             * idempotency if the store faults and the instruction
             * is restarted
             */
            tcg_gen_movcond_tl(TCG_COND_EQ, newv, oldv, cmpv, newv, oldv);
            gen_op_st_v(s, ot, newv, s->A0);
        } else {
            /*
             * Unlike the memory case, where "the destination operand receives
             * a write cycle without regard to the result of the comparison",
             * rm must not be touched altogether if the write fails, including
             * not zero-extending it on 64-bit processors.  So, precompute
             * the result of a successful writeback and perform the movcond
             * directly on cpu_regs.  In case rm is part of RAX, note that this
             * movcond and the one below are mutually exclusive is executed.
             */
            dest = gen_op_deposit_reg_v(s, ot, decode->op[0].n, newv, newv);
            tcg_gen_movcond_tl(TCG_COND_EQ, dest, oldv, cmpv, newv, dest);
        }
        decode->op[0].unit = X86_OP_SKIP;
    }

    /* Write RAX only if the cmpxchg fails.  */
    dest = gen_op_deposit_reg_v(s, ot, R_EAX, s->T0, oldv);
    tcg_gen_movcond_tl(TCG_COND_NE, dest, oldv, cmpv, s->T0, dest);

    tcg_gen_mov_tl(s->cc_srcT, cmpv);
    tcg_gen_sub_tl(cmpv, cmpv, oldv);
    decode->cc_dst = cmpv;
    decode->cc_src = oldv;
    decode->cc_op = CC_OP_SUBB + ot;
}

static void gen_CPUID(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_update_eip_cur(s);
    gen_helper_cpuid(tcg_env);
}

static void gen_CRC32(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[2].ot;

    tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
    gen_helper_crc32(s->T0, s->tmp2_i32, s->T1, tcg_constant_i32(8 << ot));
}

static void gen_CVTPI2Px(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_enter_mmx(tcg_env);
    if (s->prefix & PREFIX_DATA) {
        gen_helper_cvtpi2pd(tcg_env, OP_PTR0, OP_PTR2);
    } else {
        gen_helper_cvtpi2ps(tcg_env, OP_PTR0, OP_PTR2);
    }
}

static void gen_CVTPx2PI(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_enter_mmx(tcg_env);
    if (s->prefix & PREFIX_DATA) {
        gen_helper_cvtpd2pi(tcg_env, OP_PTR0, OP_PTR2);
    } else {
        gen_helper_cvtps2pi(tcg_env, OP_PTR0, OP_PTR2);
    }
}

static void gen_CVTTPx2PI(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_enter_mmx(tcg_env);
    if (s->prefix & PREFIX_DATA) {
        gen_helper_cvttpd2pi(tcg_env, OP_PTR0, OP_PTR2);
    } else {
        gen_helper_cvttps2pi(tcg_env, OP_PTR0, OP_PTR2);
    }
}

static void gen_CWD(DisasContext *s, X86DecodedInsn *decode)
{
    int shift = 8 << decode->op[0].ot;

    tcg_gen_sextract_tl(s->T0, s->T0, shift - 1, 1);
}

static void gen_DAA(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_helper_daa(tcg_env);
    assume_cc_op(s, CC_OP_EFLAGS);
}

static void gen_DAS(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_helper_das(tcg_env);
    assume_cc_op(s, CC_OP_EFLAGS);
}

static void gen_DEC(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;

    tcg_gen_movi_tl(s->T1, -1);
    if (s->prefix & PREFIX_LOCK) {
        tcg_gen_atomic_add_fetch_tl(s->T0, s->A0, s->T1,
                                    s->mem_index, ot | MO_LE);
    } else {
        tcg_gen_add_tl(s->T0, s->T0, s->T1);
    }
    prepare_update_cc_incdec(decode, s, CC_OP_DECB + ot);
}

static void gen_DIV(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;

    switch(ot) {
    case MO_8:
        gen_helper_divb_AL(tcg_env, s->T0);
        break;
    case MO_16:
        gen_helper_divw_AX(tcg_env, s->T0);
        break;
    default:
    case MO_32:
        gen_helper_divl_EAX(tcg_env, s->T0);
        break;
#ifdef TARGET_X86_64
    case MO_64:
        gen_helper_divq_EAX(tcg_env, s->T0);
        break;
#endif
    }
}

static void gen_EMMS(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_emms(tcg_env);
}

static void gen_ENTER(DisasContext *s, X86DecodedInsn *decode)
{
   gen_enter(s, decode->op[1].imm, decode->op[2].imm);
}

static void gen_EXTRQ_i(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 length = tcg_constant_i32(decode->immediate & 63);
    TCGv_i32 index = tcg_constant_i32((decode->immediate >> 8) & 63);

    gen_helper_extrq_i(tcg_env, OP_PTR0, index, length);
}

static void gen_EXTRQ_r(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_extrq_r(tcg_env, OP_PTR0, OP_PTR2);
}

static void gen_FXRSTOR(DisasContext *s, X86DecodedInsn *decode)
{
    if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
        gen_NM_exception(s);
    } else {
        gen_helper_fxrstor(tcg_env, s->A0);
    }
}

static void gen_FXSAVE(DisasContext *s, X86DecodedInsn *decode)
{
    if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
        gen_NM_exception(s);
    } else {
        gen_helper_fxsave(tcg_env, s->A0);
    }
}

static void gen_HLT(DisasContext *s, X86DecodedInsn *decode)
{
#ifdef CONFIG_SYSTEM_ONLY
    gen_update_cc_op(s);
    gen_update_eip_next(s);
    gen_helper_hlt(tcg_env);
    s->base.is_jmp = DISAS_NORETURN;
#endif
}

static void gen_IDIV(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;

    switch(ot) {
    case MO_8:
        gen_helper_idivb_AL(tcg_env, s->T0);
        break;
    case MO_16:
        gen_helper_idivw_AX(tcg_env, s->T0);
        break;
    default:
    case MO_32:
        gen_helper_idivl_EAX(tcg_env, s->T0);
        break;
#ifdef TARGET_X86_64
    case MO_64:
        gen_helper_idivq_EAX(tcg_env, s->T0);
        break;
#endif
    }
}

static void gen_IMUL3(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    TCGv cc_src_rhs;

    switch (ot) {
    case MO_16:
        /* s->T0 already sign-extended */
        tcg_gen_ext16s_tl(s->T1, s->T1);
        tcg_gen_mul_tl(s->T0, s->T0, s->T1);
        /* Compare the full result to the extension of the truncated result.  */
        tcg_gen_ext16s_tl(s->T1, s->T0);
        cc_src_rhs = s->T0;
        break;

    case MO_32:
#ifdef TARGET_X86_64
        if (TCG_TARGET_REG_BITS == 64) {
            /*
             * This produces fewer TCG ops, and better code if flags are needed,
             * but it requires a 64-bit multiply even if they are not.  Use it
             * only if the target has 64-bits registers.
             *
             * s->T0 is already sign-extended.
             */
            tcg_gen_ext32s_tl(s->T1, s->T1);
            tcg_gen_mul_tl(s->T0, s->T0, s->T1);
            /* Compare the full result to the extension of the truncated result.  */
            tcg_gen_ext32s_tl(s->T1, s->T0);
            cc_src_rhs = s->T0;
        } else {
            /* Variant that only needs a 32-bit widening multiply.  */
            TCGv_i32 hi = tcg_temp_new_i32();
            TCGv_i32 lo = tcg_temp_new_i32();
            tcg_gen_trunc_tl_i32(lo, s->T0);
            tcg_gen_trunc_tl_i32(hi, s->T1);
            tcg_gen_muls2_i32(lo, hi, lo, hi);
            tcg_gen_extu_i32_tl(s->T0, lo);

            cc_src_rhs = tcg_temp_new();
            tcg_gen_extu_i32_tl(cc_src_rhs, hi);
            /* Compare the high part to the sign bit of the truncated result */
            tcg_gen_sari_i32(lo, lo, 31);
            tcg_gen_extu_i32_tl(s->T1, lo);
        }
        break;

    case MO_64:
#endif
        cc_src_rhs = tcg_temp_new();
        tcg_gen_muls2_tl(s->T0, cc_src_rhs, s->T0, s->T1);
        /* Compare the high part to the sign bit of the truncated result */
        tcg_gen_sari_tl(s->T1, s->T0, TARGET_LONG_BITS - 1);
        break;

    default:
        g_assert_not_reached();
    }

    tcg_gen_sub_tl(s->T1, s->T1, cc_src_rhs);
    prepare_update2_cc(decode, s, CC_OP_MULB + ot);
}

static void gen_IMUL(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;
    TCGv cc_src_rhs;

    switch (ot) {
    case MO_8:
        /* s->T0 already sign-extended */
        tcg_gen_ext8s_tl(s->T1, s->T1);
        tcg_gen_mul_tl(s->T0, s->T0, s->T1);
        gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
        /* Compare the full result to the extension of the truncated result.  */
        tcg_gen_ext8s_tl(s->T1, s->T0);
        cc_src_rhs = s->T0;
        break;

    case MO_16:
        /* s->T0 already sign-extended */
        tcg_gen_ext16s_tl(s->T1, s->T1);
        tcg_gen_mul_tl(s->T0, s->T0, s->T1);
        gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
        tcg_gen_shri_tl(s->T1, s->T0, 16);
        gen_op_mov_reg_v(s, MO_16, R_EDX, s->T1);
        /* Compare the full result to the extension of the truncated result.  */
        tcg_gen_ext16s_tl(s->T1, s->T0);
        cc_src_rhs = s->T0;
        break;

    case MO_32:
#ifdef TARGET_X86_64
        /* s->T0 already sign-extended */
        tcg_gen_ext32s_tl(s->T1, s->T1);
        tcg_gen_mul_tl(s->T0, s->T0, s->T1);
        tcg_gen_ext32u_tl(cpu_regs[R_EAX], s->T0);
        tcg_gen_shri_tl(cpu_regs[R_EDX], s->T0, 32);
        /* Compare the full result to the extension of the truncated result.  */
        tcg_gen_ext32s_tl(s->T1, s->T0);
        cc_src_rhs = s->T0;
        break;

    case MO_64:
#endif
        tcg_gen_muls2_tl(s->T0, cpu_regs[R_EDX], s->T0, s->T1);
        tcg_gen_mov_tl(cpu_regs[R_EAX], s->T0);

        /* Compare the high part to the sign bit of the truncated result */
        tcg_gen_negsetcondi_tl(TCG_COND_LT, s->T1, s->T0, 0);
        cc_src_rhs = cpu_regs[R_EDX];
        break;

    default:
        g_assert_not_reached();
    }

    tcg_gen_sub_tl(s->T1, s->T1, cc_src_rhs);
    prepare_update2_cc(decode, s, CC_OP_MULB + ot);
}

static void gen_IN(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    TCGv_i32 port = tcg_temp_new_i32();

    tcg_gen_trunc_tl_i32(port, s->T0);
    tcg_gen_ext16u_i32(port, port);
    if (!gen_check_io(s, ot, port, SVM_IOIO_TYPE_MASK)) {
        return;
    }
    translator_io_start(&s->base);
    gen_helper_in_func(ot, s->T0, port);
    gen_writeback(s, decode, 0, s->T0);
    gen_bpt_io(s, port, ot);
}

static void gen_INC(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;

    tcg_gen_movi_tl(s->T1, 1);
    if (s->prefix & PREFIX_LOCK) {
        tcg_gen_atomic_add_fetch_tl(s->T0, s->A0, s->T1,
                                    s->mem_index, ot | MO_LE);
    } else {
        tcg_gen_add_tl(s->T0, s->T0, s->T1);
    }
    prepare_update_cc_incdec(decode, s, CC_OP_INCB + ot);
}

static void gen_INS(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;
    TCGv_i32 port = tcg_temp_new_i32();

    tcg_gen_trunc_tl_i32(port, s->T1);
    tcg_gen_ext16u_i32(port, port);
    if (!gen_check_io(s, ot, port,
                      SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) {
        return;
    }

    translator_io_start(&s->base);
    if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
        gen_repz(s, ot, gen_ins);
    } else {
        gen_ins(s, ot);
    }
}

static void gen_INSERTQ_i(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 length = tcg_constant_i32(decode->immediate & 63);
    TCGv_i32 index = tcg_constant_i32((decode->immediate >> 8) & 63);

    gen_helper_insertq_i(tcg_env, OP_PTR0, OP_PTR1, index, length);
}

static void gen_INSERTQ_r(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_insertq_r(tcg_env, OP_PTR0, OP_PTR2);
}

static void gen_INT(DisasContext *s, X86DecodedInsn *decode)
{
    gen_interrupt(s, decode->immediate);
}

static void gen_INT1(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_update_eip_next(s);
    gen_helper_icebp(tcg_env);
    s->base.is_jmp = DISAS_NORETURN;
}

static void gen_INT3(DisasContext *s, X86DecodedInsn *decode)
{
    gen_interrupt(s, EXCP03_INT3);
}

static void gen_INTO(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_update_eip_cur(s);
    gen_helper_into(tcg_env, cur_insn_len_i32(s));
}

static void gen_IRET(DisasContext *s, X86DecodedInsn *decode)
{
    if (!PE(s) || VM86(s)) {
        gen_helper_iret_real(tcg_env, tcg_constant_i32(s->dflag - 1));
    } else {
        gen_helper_iret_protected(tcg_env, tcg_constant_i32(s->dflag - 1),
                                  eip_next_i32(s));
    }
    assume_cc_op(s, CC_OP_EFLAGS);
    s->base.is_jmp = DISAS_EOB_ONLY;
}

static void gen_Jcc(DisasContext *s, X86DecodedInsn *decode)
{
    gen_bnd_jmp(s);
    gen_jcc(s, decode->b & 0xf, decode->immediate);
}

static void gen_JCXZ(DisasContext *s, X86DecodedInsn *decode)
{
    TCGLabel *taken = gen_new_label();

    gen_update_cc_op(s);
    gen_op_jz_ecx(s, taken);
    gen_conditional_jump_labels(s, decode->immediate, NULL, taken);
}

static void gen_JMP(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_jmp_rel(s, s->dflag, decode->immediate, 0);
}

static void gen_JMP_m(DisasContext *s, X86DecodedInsn *decode)
{
    gen_op_jmp_v(s, s->T0);
    gen_bnd_jmp(s);
    s->base.is_jmp = DISAS_JUMP;
}

static void gen_JMPF(DisasContext *s, X86DecodedInsn *decode)
{
    gen_far_jmp(s);
}

static void gen_JMPF_m(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;

    gen_op_ld_v(s, ot, s->T0, s->A0);
    gen_add_A0_im(s, 1 << ot);
    gen_op_ld_v(s, MO_16, s->T1, s->A0);
    gen_far_jmp(s);
}

static void gen_LAHF(DisasContext *s, X86DecodedInsn *decode)
{
    if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) {
        return gen_illegal_opcode(s);
    }
    gen_compute_eflags(s);
    /* Note: gen_compute_eflags() only gives the condition codes */
    tcg_gen_ori_tl(s->T0, cpu_cc_src, 0x02);
    tcg_gen_deposit_tl(cpu_regs[R_EAX], cpu_regs[R_EAX], s->T0, 8, 8);
}

static void gen_LAR(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    TCGv result = tcg_temp_new();
    TCGv dest;

    gen_compute_eflags(s);
    gen_update_cc_op(s);
    gen_helper_lar(result, tcg_env, s->T0);

    /* Perform writeback here to skip it if ZF=0.  */
    decode->op[0].unit = X86_OP_SKIP;
    dest = gen_op_deposit_reg_v(s, ot, decode->op[0].n, result, result);
    tcg_gen_movcond_tl(TCG_COND_TSTNE, dest, cpu_cc_src, tcg_constant_tl(CC_Z),
                       result, dest);
}

static void gen_LDMXCSR(DisasContext *s, X86DecodedInsn *decode)
{
    tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
    gen_helper_ldmxcsr(tcg_env, s->tmp2_i32);
}

static void gen_lxx_seg(DisasContext *s, X86DecodedInsn *decode, int seg)
{
    MemOp ot = decode->op[0].ot;

    /* Offset already in s->T0.  */
    gen_add_A0_im(s, 1 << ot);
    gen_op_ld_v(s, MO_16, s->T1, s->A0);

    /* load the segment here to handle exceptions properly */
    gen_movl_seg(s, seg, s->T1);
}

static void gen_LDS(DisasContext *s, X86DecodedInsn *decode)
{
    gen_lxx_seg(s, decode, R_DS);
}

static void gen_LEA(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv ea = gen_lea_modrm_1(s, decode->mem, false);
    gen_lea_v_seg_dest(s, s->aflag, s->T0, ea, -1, -1);
}

static void gen_LEAVE(DisasContext *s, X86DecodedInsn *decode)
{
    gen_leave(s);
}

static void gen_LES(DisasContext *s, X86DecodedInsn *decode)
{
    gen_lxx_seg(s, decode, R_ES);
}

static void gen_LFENCE(DisasContext *s, X86DecodedInsn *decode)
{
    tcg_gen_mb(TCG_MO_LD_LD | TCG_BAR_SC);
}

static void gen_LFS(DisasContext *s, X86DecodedInsn *decode)
{
    gen_lxx_seg(s, decode, R_FS);
}

static void gen_LGS(DisasContext *s, X86DecodedInsn *decode)
{
    gen_lxx_seg(s, decode, R_GS);
}

static void gen_LODS(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;
    if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
        gen_repz(s, ot, gen_lods);
    } else {
        gen_lods(s, ot);
    }
}

static void gen_LOOP(DisasContext *s, X86DecodedInsn *decode)
{
    TCGLabel *taken = gen_new_label();

    gen_update_cc_op(s);
    gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
    gen_op_jnz_ecx(s, taken);
    gen_conditional_jump_labels(s, decode->immediate, NULL, taken);
}

static void gen_LOOPE(DisasContext *s, X86DecodedInsn *decode)
{
    TCGLabel *taken = gen_new_label();
    TCGLabel *not_taken = gen_new_label();

    gen_update_cc_op(s);
    gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
    gen_op_jz_ecx(s, not_taken);
    gen_jcc1(s, (JCC_Z << 1), taken); /* jz taken */
    gen_conditional_jump_labels(s, decode->immediate, not_taken, taken);
}

static void gen_LOOPNE(DisasContext *s, X86DecodedInsn *decode)
{
    TCGLabel *taken = gen_new_label();
    TCGLabel *not_taken = gen_new_label();

    gen_update_cc_op(s);
    gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
    gen_op_jz_ecx(s, not_taken);
    gen_jcc1(s, (JCC_Z << 1) | 1, taken); /* jnz taken */
    gen_conditional_jump_labels(s, decode->immediate, not_taken, taken);
}

static void gen_LSL(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    TCGv result = tcg_temp_new();
    TCGv dest;

    gen_compute_eflags(s);
    gen_update_cc_op(s);
    gen_helper_lsl(result, tcg_env, s->T0);

    /* Perform writeback here to skip it if ZF=0.  */
    decode->op[0].unit = X86_OP_SKIP;
    dest = gen_op_deposit_reg_v(s, ot, decode->op[0].n, result, result);
    tcg_gen_movcond_tl(TCG_COND_TSTNE, dest, cpu_cc_src, tcg_constant_tl(CC_Z),
                       result, dest);
}

static void gen_LSS(DisasContext *s, X86DecodedInsn *decode)
{
    gen_lxx_seg(s, decode, R_SS);
}

static void gen_LZCNT(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;

    /* C bit (cc_src) is defined related to the input.  */
    decode->cc_src = tcg_temp_new();
    decode->cc_dst = s->T0;
    decode->cc_op = CC_OP_BMILGB + ot;
    tcg_gen_mov_tl(decode->cc_src, s->T0);

    /*
     * Reduce the target_ulong result by the number of zeros that
     * we expect to find at the top.
     */
    tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS);
    tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - (8 << ot));
}

static void gen_MFENCE(DisasContext *s, X86DecodedInsn *decode)
{
    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
}

static void gen_MOV(DisasContext *s, X86DecodedInsn *decode)
{
    /* nothing to do! */
}
#define gen_NOP gen_MOV

static void gen_MASKMOV(DisasContext *s, X86DecodedInsn *decode)
{
    gen_lea_v_seg(s, cpu_regs[R_EDI], R_DS, s->override);

    if (s->prefix & PREFIX_DATA) {
        gen_helper_maskmov_xmm(tcg_env, OP_PTR1, OP_PTR2, s->A0);
    } else {
        gen_helper_maskmov_mmx(tcg_env, OP_PTR1, OP_PTR2, s->A0);
    }
}

static void gen_MOVBE(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;

    /* M operand type does not load/store */
    if (decode->e.op0 == X86_TYPE_M) {
        tcg_gen_qemu_st_tl(s->T0, s->A0, s->mem_index, ot | MO_BE);
    } else {
        tcg_gen_qemu_ld_tl(s->T0, s->A0, s->mem_index, ot | MO_BE);
    }
}

static void gen_MOVD_from(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[2].ot;

    switch (ot) {
    case MO_32:
#ifdef TARGET_X86_64
        tcg_gen_ld32u_tl(s->T0, tcg_env, decode->op[2].offset);
        break;
    case MO_64:
#endif
        tcg_gen_ld_tl(s->T0, tcg_env, decode->op[2].offset);
        break;
    default:
        abort();
    }
}

static void gen_MOVD_to(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[2].ot;
    int vec_len = vector_len(s, decode);
    int lo_ofs = vector_elem_offset(&decode->op[0], ot, 0);

    tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);

    switch (ot) {
    case MO_32:
#ifdef TARGET_X86_64
        tcg_gen_st32_tl(s->T1, tcg_env, lo_ofs);
        break;
    case MO_64:
#endif
        tcg_gen_st_tl(s->T1, tcg_env, lo_ofs);
        break;
    default:
        g_assert_not_reached();
    }
}

static void gen_MOVDQ(DisasContext *s, X86DecodedInsn *decode)
{
    gen_store_sse(s, decode, decode->op[2].offset);
}

static void gen_MOVMSK(DisasContext *s, X86DecodedInsn *decode)
{
    typeof(gen_helper_movmskps_ymm) *ps, *pd, *fn;
    ps = s->vex_l ? gen_helper_movmskps_ymm : gen_helper_movmskps_xmm;
    pd = s->vex_l ? gen_helper_movmskpd_ymm : gen_helper_movmskpd_xmm;
    fn = s->prefix & PREFIX_DATA ? pd : ps;
    fn(s->tmp2_i32, tcg_env, OP_PTR2);
    tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
}

static void gen_MOVQ(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);
    int lo_ofs = vector_elem_offset(&decode->op[0], MO_64, 0);

    tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[2].offset);
    if (decode->op[0].has_ea) {
        tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
    } else {
        /*
         * tcg_gen_gvec_dup_i64(MO_64, op0.offset, 8, vec_len, s->tmp1_64) would
         * seem to work, but it does not on big-endian platforms; the cleared parts
         * are always at higher addresses, but cross-endian emulation inverts the
         * byte order so that the cleared parts need to be at *lower* addresses.
         * Because oprsz is 8, we see this here even for SSE; but more in general,
         * it disqualifies using oprsz < maxsz to emulate VEX128.
         */
        tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
        tcg_gen_st_i64(s->tmp1_i64, tcg_env, lo_ofs);
    }
}

static void gen_MOVq_dq(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_enter_mmx(tcg_env);
    /* Otherwise the same as any other movq.  */
    return gen_MOVQ(s, decode);
}

static void gen_MOVS(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[2].ot;
    if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
        gen_repz(s, ot, gen_movs);
    } else {
        gen_movs(s, ot);
    }
}

static void gen_MUL(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;

    switch (ot) {
    case MO_8:
        /* s->T0 already zero-extended */
        tcg_gen_ext8u_tl(s->T1, s->T1);
        tcg_gen_mul_tl(s->T0, s->T0, s->T1);
        gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
        tcg_gen_andi_tl(s->T1, s->T0, 0xff00);
        decode->cc_dst = s->T0;
        decode->cc_src = s->T1;
        break;

    case MO_16:
        /* s->T0 already zero-extended */
        tcg_gen_ext16u_tl(s->T1, s->T1);
        tcg_gen_mul_tl(s->T0, s->T0, s->T1);
        gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
        tcg_gen_shri_tl(s->T1, s->T0, 16);
        gen_op_mov_reg_v(s, MO_16, R_EDX, s->T1);
        decode->cc_dst = s->T0;
        decode->cc_src = s->T1;
        break;

    case MO_32:
#ifdef TARGET_X86_64
        /* s->T0 already zero-extended */
        tcg_gen_ext32u_tl(s->T1, s->T1);
        tcg_gen_mul_tl(s->T0, s->T0, s->T1);
        tcg_gen_ext32u_tl(cpu_regs[R_EAX], s->T0);
        tcg_gen_shri_tl(cpu_regs[R_EDX], s->T0, 32);
        decode->cc_dst = cpu_regs[R_EAX];
        decode->cc_src = cpu_regs[R_EDX];
        break;

    case MO_64:
#endif
        tcg_gen_mulu2_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->T0, s->T1);
        decode->cc_dst = cpu_regs[R_EAX];
        decode->cc_src = cpu_regs[R_EDX];
        break;

    default:
        g_assert_not_reached();
    }

    decode->cc_op = CC_OP_MULB + ot;
}

static void gen_MULX(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;

    /* low part of result in VEX.vvvv, high in MODRM */
    switch (ot) {
    case MO_32:
#ifdef TARGET_X86_64
        tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
        tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
        tcg_gen_mulu2_i32(s->tmp2_i32, s->tmp3_i32,
                          s->tmp2_i32, s->tmp3_i32);
        tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], s->tmp2_i32);
        tcg_gen_extu_i32_tl(s->T0, s->tmp3_i32);
        break;

    case MO_64:
#endif
        tcg_gen_mulu2_tl(cpu_regs[s->vex_v], s->T0, s->T0, s->T1);
        break;

    default:
        g_assert_not_reached();
    }
}

static void gen_NEG(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    TCGv oldv = tcg_temp_new();

    if (s->prefix & PREFIX_LOCK) {
        TCGv newv = tcg_temp_new();
        TCGv cmpv = tcg_temp_new();
        TCGLabel *label1 = gen_new_label();

        gen_set_label(label1);
        gen_op_ld_v(s, ot, oldv, s->A0);
        tcg_gen_neg_tl(newv, oldv);
        tcg_gen_atomic_cmpxchg_tl(cmpv, s->A0, oldv, newv,
                                  s->mem_index, ot | MO_LE);
        tcg_gen_brcond_tl(TCG_COND_NE, oldv, cmpv, label1);
    } else {
        tcg_gen_mov_tl(oldv, s->T0);
    }
    tcg_gen_neg_tl(s->T0, oldv);

    decode->cc_dst = s->T0;
    decode->cc_src = oldv;
    tcg_gen_movi_tl(s->cc_srcT, 0);
    decode->cc_op = CC_OP_SUBB + ot;
}

static void gen_NOT(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;

    if (s->prefix & PREFIX_LOCK) {
        tcg_gen_movi_tl(s->T0, ~0);
        tcg_gen_atomic_xor_fetch_tl(s->T0, s->A0, s->T0,
                                    s->mem_index, ot | MO_LE);
    } else {
        tcg_gen_not_tl(s->T0, s->T0);
    }
}

static void gen_OR(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;

    if (s->prefix & PREFIX_LOCK) {
        tcg_gen_atomic_or_fetch_tl(s->T0, s->A0, s->T1,
                                   s->mem_index, ot | MO_LE);
    } else {
        tcg_gen_or_tl(s->T0, s->T0, s->T1);
    }
    prepare_update1_cc(decode, s, CC_OP_LOGICB + ot);
}

static void gen_OUT(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;
    TCGv_i32 port = tcg_temp_new_i32();
    TCGv_i32 value = tcg_temp_new_i32();

    tcg_gen_trunc_tl_i32(port, s->T1);
    tcg_gen_ext16u_i32(port, port);
    if (!gen_check_io(s, ot, port, 0)) {
        return;
    }
    tcg_gen_trunc_tl_i32(value, s->T0);
    translator_io_start(&s->base);
    gen_helper_out_func(ot, port, value);
    gen_bpt_io(s, port, ot);
}

static void gen_OUTS(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;
    TCGv_i32 port = tcg_temp_new_i32();

    tcg_gen_trunc_tl_i32(port, s->T1);
    tcg_gen_ext16u_i32(port, port);
    if (!gen_check_io(s, ot, port, SVM_IOIO_STR_MASK)) {
        return;
    }

    translator_io_start(&s->base);
    if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
        gen_repz(s, ot, gen_outs);
    } else {
        gen_outs(s, ot);
    }
}

static void gen_PALIGNR(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    if (!(s->prefix & PREFIX_DATA)) {
        gen_helper_palignr_mmx(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2, imm);
    } else if (!s->vex_l) {
        gen_helper_palignr_xmm(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2, imm);
    } else {
        gen_helper_palignr_ymm(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2, imm);
    }
}

static void gen_PANDN(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    /* Careful, operand order is reversed!  */
    tcg_gen_gvec_andc(MO_64,
                      decode->op[0].offset, decode->op[2].offset,
                      decode->op[1].offset, vec_len, vec_len);
}

static void gen_PAUSE(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_update_eip_next(s);
    gen_helper_pause(tcg_env);
    s->base.is_jmp = DISAS_NORETURN;
}

static void gen_PCMPESTRI(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    gen_helper_pcmpestri_xmm(tcg_env, OP_PTR1, OP_PTR2, imm);
    assume_cc_op(s, CC_OP_EFLAGS);
}

static void gen_PCMPESTRM(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    gen_helper_pcmpestrm_xmm(tcg_env, OP_PTR1, OP_PTR2, imm);
    assume_cc_op(s, CC_OP_EFLAGS);
    if ((s->prefix & PREFIX_VEX) && !s->vex_l) {
        tcg_gen_gvec_dup_imm(MO_64, offsetof(CPUX86State, xmm_regs[0].ZMM_X(1)),
                             16, 16, 0);
    }
}

static void gen_PCMPISTRI(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    gen_helper_pcmpistri_xmm(tcg_env, OP_PTR1, OP_PTR2, imm);
    assume_cc_op(s, CC_OP_EFLAGS);
}

static void gen_PCMPISTRM(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    gen_helper_pcmpistrm_xmm(tcg_env, OP_PTR1, OP_PTR2, imm);
    assume_cc_op(s, CC_OP_EFLAGS);
    if ((s->prefix & PREFIX_VEX) && !s->vex_l) {
        tcg_gen_gvec_dup_imm(MO_64, offsetof(CPUX86State, xmm_regs[0].ZMM_X(1)),
                             16, 16, 0);
    }
}

static void gen_PDEP(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_pdep(s->T0, s->T0, s->T1);
}

static void gen_PEXT(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_pext(s->T0, s->T0, s->T1);
}

static inline void gen_pextr(DisasContext *s, X86DecodedInsn *decode, MemOp ot)
{
    int vec_len = vector_len(s, decode);
    int mask = (vec_len >> ot) - 1;
    int val = decode->immediate & mask;

    switch (ot) {
    case MO_8:
        tcg_gen_ld8u_tl(s->T0, tcg_env, vector_elem_offset(&decode->op[1], ot, val));
        break;
    case MO_16:
        tcg_gen_ld16u_tl(s->T0, tcg_env, vector_elem_offset(&decode->op[1], ot, val));
        break;
    case MO_32:
#ifdef TARGET_X86_64
        tcg_gen_ld32u_tl(s->T0, tcg_env, vector_elem_offset(&decode->op[1], ot, val));
        break;
    case MO_64:
#endif
        tcg_gen_ld_tl(s->T0, tcg_env, vector_elem_offset(&decode->op[1], ot, val));
        break;
    default:
        abort();
    }
}

static void gen_PEXTRB(DisasContext *s, X86DecodedInsn *decode)
{
    gen_pextr(s, decode, MO_8);
}

static void gen_PEXTRW(DisasContext *s, X86DecodedInsn *decode)
{
    gen_pextr(s, decode, MO_16);
}

static void gen_PEXTR(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    gen_pextr(s, decode, ot);
}

static inline void gen_pinsr(DisasContext *s, X86DecodedInsn *decode, MemOp ot)
{
    int vec_len = vector_len(s, decode);
    int mask = (vec_len >> ot) - 1;
    int val = decode->immediate & mask;

    if (decode->op[1].offset != decode->op[0].offset) {
        assert(vec_len == 16);
        gen_store_sse(s, decode, decode->op[1].offset);
    }

    switch (ot) {
    case MO_8:
        tcg_gen_st8_tl(s->T1, tcg_env, vector_elem_offset(&decode->op[0], ot, val));
        break;
    case MO_16:
        tcg_gen_st16_tl(s->T1, tcg_env, vector_elem_offset(&decode->op[0], ot, val));
        break;
    case MO_32:
#ifdef TARGET_X86_64
        tcg_gen_st32_tl(s->T1, tcg_env, vector_elem_offset(&decode->op[0], ot, val));
        break;
    case MO_64:
#endif
        tcg_gen_st_tl(s->T1, tcg_env, vector_elem_offset(&decode->op[0], ot, val));
        break;
    default:
        abort();
    }
}

static void gen_PINSRB(DisasContext *s, X86DecodedInsn *decode)
{
    gen_pinsr(s, decode, MO_8);
}

static void gen_PINSRW(DisasContext *s, X86DecodedInsn *decode)
{
    gen_pinsr(s, decode, MO_16);
}

static void gen_PINSR(DisasContext *s, X86DecodedInsn *decode)
{
    gen_pinsr(s, decode, decode->op[2].ot);
}

static void gen_pmovmskb_i64(TCGv_i64 d, TCGv_i64 s)
{
    TCGv_i64 t = tcg_temp_new_i64();

    tcg_gen_andi_i64(d, s, 0x8080808080808080ull);

    /*
     * After each shift+or pair:
     * 0:  a.......b.......c.......d.......e.......f.......g.......h.......
     * 7:  ab......bc......cd......de......ef......fg......gh......h.......
     * 14: abcd....bcde....cdef....defg....efgh....fgh.....gh......h.......
     * 28: abcdefghbcdefgh.cdefgh..defgh...efgh....fgh.....gh......h.......
     * The result is left in the high bits of the word.
     */
    tcg_gen_shli_i64(t, d, 7);
    tcg_gen_or_i64(d, d, t);
    tcg_gen_shli_i64(t, d, 14);
    tcg_gen_or_i64(d, d, t);
    tcg_gen_shli_i64(t, d, 28);
    tcg_gen_or_i64(d, d, t);
}

static void gen_pmovmskb_vec(unsigned vece, TCGv_vec d, TCGv_vec s)
{
    TCGv_vec t = tcg_temp_new_vec_matching(d);
    TCGv_vec m = tcg_constant_vec_matching(d, MO_8, 0x80);

    /* See above */
    tcg_gen_and_vec(vece, d, s, m);
    tcg_gen_shli_vec(vece, t, d, 7);
    tcg_gen_or_vec(vece, d, d, t);
    tcg_gen_shli_vec(vece, t, d, 14);
    tcg_gen_or_vec(vece, d, d, t);
    tcg_gen_shli_vec(vece, t, d, 28);
    tcg_gen_or_vec(vece, d, d, t);
}

static void gen_PMOVMSKB(DisasContext *s, X86DecodedInsn *decode)
{
    static const TCGOpcode vecop_list[] = { INDEX_op_shli_vec, 0 };
    static const GVecGen2 g = {
        .fni8 = gen_pmovmskb_i64,
        .fniv = gen_pmovmskb_vec,
        .opt_opc = vecop_list,
        .vece = MO_64,
        .prefer_i64 = TCG_TARGET_REG_BITS == 64
    };
    MemOp ot = decode->op[2].ot;
    int vec_len = vector_len(s, decode);
    TCGv t = tcg_temp_new();

    tcg_gen_gvec_2(offsetof(CPUX86State, xmm_t0) + xmm_offset(ot), decode->op[2].offset,
                   vec_len, vec_len, &g);
    tcg_gen_ld8u_tl(s->T0, tcg_env, offsetof(CPUX86State, xmm_t0.ZMM_B(vec_len - 1)));
    while (vec_len > 8) {
        vec_len -= 8;
        if (TCG_TARGET_HAS_extract2_tl) {
            /*
             * Load the next byte of the result into the high byte of T.
             * TCG does a similar expansion of deposit to shl+extract2; by
             * loading the whole word, the shift left is avoided.
             */
#ifdef TARGET_X86_64
            tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, xmm_t0.ZMM_Q((vec_len - 1) / 8)));
#else
            tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, xmm_t0.ZMM_L((vec_len - 1) / 4)));
#endif

            tcg_gen_extract2_tl(s->T0, t, s->T0, TARGET_LONG_BITS - 8);
        } else {
            /*
             * The _previous_ value is deposited into bits 8 and higher of t.  Because
             * those bits are known to be zero after ld8u, this becomes a shift+or
             * if deposit is not available.
             */
            tcg_gen_ld8u_tl(t, tcg_env, offsetof(CPUX86State, xmm_t0.ZMM_B(vec_len - 1)));
            tcg_gen_deposit_tl(s->T0, t, s->T0, 8, TARGET_LONG_BITS - 8);
        }
    }
}

static void gen_POP(DisasContext *s, X86DecodedInsn *decode)
{
    X86DecodedOp *op = &decode->op[0];
    MemOp ot = gen_pop_T0(s);

    assert(ot >= op->ot);
    if (op->has_ea || op->unit == X86_OP_SEG) {
        /* NOTE: order is important for MMU exceptions */
        gen_writeback(s, decode, 0, s->T0);
    }

    /* NOTE: writing back registers after update is important for pop %sp */
    gen_pop_update(s, ot);
}

static void gen_POPA(DisasContext *s, X86DecodedInsn *decode)
{
    gen_popa(s);
}

static void gen_POPCNT(DisasContext *s, X86DecodedInsn *decode)
{
    decode->cc_dst = tcg_temp_new();
    decode->cc_op = CC_OP_POPCNT;

    tcg_gen_mov_tl(decode->cc_dst, s->T0);
    tcg_gen_ctpop_tl(s->T0, s->T0);
}

static void gen_POPF(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot;
    int mask = TF_MASK | AC_MASK | ID_MASK | NT_MASK;

    if (CPL(s) == 0) {
        mask |= IF_MASK | IOPL_MASK;
    } else if (CPL(s) <= IOPL(s)) {
        mask |= IF_MASK;
    }
    if (s->dflag == MO_16) {
        mask &= 0xffff;
    }

    ot = gen_pop_T0(s);
    gen_helper_write_eflags(tcg_env, s->T0, tcg_constant_i32(mask));
    gen_pop_update(s, ot);
    set_cc_op(s, CC_OP_EFLAGS);
    /* abort translation because TF/AC flag may change */
    s->base.is_jmp = DISAS_EOB_NEXT;
}

static void gen_PSHUFW(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    gen_helper_pshufw_mmx(OP_PTR0, OP_PTR1, imm);
}

static void gen_PSRLW_i(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    if (decode->immediate >= 16) {
        tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
    } else {
        tcg_gen_gvec_shri(MO_16,
                          decode->op[0].offset, decode->op[1].offset,
                          decode->immediate, vec_len, vec_len);
    }
}

static void gen_PSLLW_i(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    if (decode->immediate >= 16) {
        tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
    } else {
        tcg_gen_gvec_shli(MO_16,
                          decode->op[0].offset, decode->op[1].offset,
                          decode->immediate, vec_len, vec_len);
    }
}

static void gen_PSRAW_i(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    if (decode->immediate >= 16) {
        decode->immediate = 15;
    }
    tcg_gen_gvec_sari(MO_16,
                      decode->op[0].offset, decode->op[1].offset,
                      decode->immediate, vec_len, vec_len);
}

static void gen_PSRLD_i(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    if (decode->immediate >= 32) {
        tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
    } else {
        tcg_gen_gvec_shri(MO_32,
                          decode->op[0].offset, decode->op[1].offset,
                          decode->immediate, vec_len, vec_len);
    }
}

static void gen_PSLLD_i(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    if (decode->immediate >= 32) {
        tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
    } else {
        tcg_gen_gvec_shli(MO_32,
                          decode->op[0].offset, decode->op[1].offset,
                          decode->immediate, vec_len, vec_len);
    }
}

static void gen_PSRAD_i(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    if (decode->immediate >= 32) {
        decode->immediate = 31;
    }
    tcg_gen_gvec_sari(MO_32,
                      decode->op[0].offset, decode->op[1].offset,
                      decode->immediate, vec_len, vec_len);
}

static void gen_PSRLQ_i(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    if (decode->immediate >= 64) {
        tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
    } else {
        tcg_gen_gvec_shri(MO_64,
                          decode->op[0].offset, decode->op[1].offset,
                          decode->immediate, vec_len, vec_len);
    }
}

static void gen_PSLLQ_i(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    if (decode->immediate >= 64) {
        tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
    } else {
        tcg_gen_gvec_shli(MO_64,
                          decode->op[0].offset, decode->op[1].offset,
                          decode->immediate, vec_len, vec_len);
    }
}

static TCGv_ptr make_imm8u_xmm_vec(uint8_t imm, int vec_len)
{
    MemOp ot = vec_len == 16 ? MO_128 : MO_256;
    TCGv_i32 imm_v = tcg_constant8u_i32(imm);
    TCGv_ptr ptr = tcg_temp_new_ptr();

    tcg_gen_gvec_dup_imm(MO_64, offsetof(CPUX86State, xmm_t0) + xmm_offset(ot),
                         vec_len, vec_len, 0);

    tcg_gen_addi_ptr(ptr, tcg_env, offsetof(CPUX86State, xmm_t0));
    tcg_gen_st_i32(imm_v, tcg_env, offsetof(CPUX86State, xmm_t0.ZMM_L(0)));
    return ptr;
}

static void gen_PSRLDQ_i(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);
    TCGv_ptr imm_vec = make_imm8u_xmm_vec(decode->immediate, vec_len);

    if (s->vex_l) {
        gen_helper_psrldq_ymm(tcg_env, OP_PTR0, OP_PTR1, imm_vec);
    } else {
        gen_helper_psrldq_xmm(tcg_env, OP_PTR0, OP_PTR1, imm_vec);
    }
}

static void gen_PSLLDQ_i(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);
    TCGv_ptr imm_vec = make_imm8u_xmm_vec(decode->immediate, vec_len);

    if (s->vex_l) {
        gen_helper_pslldq_ymm(tcg_env, OP_PTR0, OP_PTR1, imm_vec);
    } else {
        gen_helper_pslldq_xmm(tcg_env, OP_PTR0, OP_PTR1, imm_vec);
    }
}

static void gen_PUSH(DisasContext *s, X86DecodedInsn *decode)
{
    gen_push_v(s, s->T0);
}

static void gen_PUSHA(DisasContext *s, X86DecodedInsn *decode)
{
    gen_pusha(s);
}

static void gen_PUSHF(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_helper_read_eflags(s->T0, tcg_env);
    gen_push_v(s, s->T0);
}

static MemOp gen_shift_count(DisasContext *s, X86DecodedInsn *decode,
                             bool *can_be_zero, TCGv *count, int unit)
{
    MemOp ot = decode->op[0].ot;
    int mask = (ot <= MO_32 ? 0x1f : 0x3f);

    *can_be_zero = false;
    switch (unit) {
    case X86_OP_INT:
        *count = tcg_temp_new();
        tcg_gen_andi_tl(*count, cpu_regs[R_ECX], mask);
        *can_be_zero = true;
        break;

    case X86_OP_IMM:
        if ((decode->immediate & mask) == 0) {
            *count = NULL;
            break;
        }
        *count = tcg_temp_new();
        tcg_gen_movi_tl(*count, decode->immediate & mask);
        break;

    case X86_OP_SKIP:
        *count = tcg_temp_new();
        tcg_gen_movi_tl(*count, 1);
        break;

    default:
        g_assert_not_reached();
    }

    return ot;
}

/*
 * Compute existing flags in decode->cc_src, for gen_* functions that wants
 * to set the cc_op set to CC_OP_ADCOX.  In particular, this allows rotate
 * operations to compute the carry in decode->cc_dst and the overflow in
 * decode->cc_src2.
 *
 * If need_flags is true, decode->cc_dst and decode->cc_src2 are preloaded
 * with the value of CF and OF before the instruction, so that it is possible
 * to keep the flags unmodified.
 *
 * Return true if carry could be made available cheaply as a 1-bit value in
 * decode->cc_dst (trying a bit harder if want_carry is true).  If false is
 * returned, decode->cc_dst is uninitialized and the carry is only available
 * as bit 0 of decode->cc_src.
 */
static bool gen_eflags_adcox(DisasContext *s, X86DecodedInsn *decode, bool want_carry, bool need_flags)
{
    bool got_cf = false;
    bool got_of = false;

    decode->cc_dst = tcg_temp_new();
    decode->cc_src = tcg_temp_new();
    decode->cc_src2 = tcg_temp_new();
    decode->cc_op = CC_OP_ADCOX;

    /* A lot more cc_ops could be "optimized" to avoid the extracts at
     * the end (INC/DEC, BMILG, MUL), but they are all really unlikely
     * to be followed by rotations within the same basic block.
     */
    switch (s->cc_op) {
    case CC_OP_ADCOX:
        /* No need to compute the full EFLAGS, CF/OF are already isolated.  */
        tcg_gen_mov_tl(decode->cc_src, cpu_cc_src);
        if (need_flags) {
            tcg_gen_mov_tl(decode->cc_src2, cpu_cc_src2);
            got_of = true;
        }
        if (want_carry || need_flags) {
            tcg_gen_mov_tl(decode->cc_dst, cpu_cc_dst);
            got_cf = true;
        }
        break;

    case CC_OP_LOGICB ... CC_OP_LOGICQ:
        /* CF and OF are zero, do it just because it's easy.  */
        gen_mov_eflags(s, decode->cc_src);
        if (need_flags) {
            tcg_gen_movi_tl(decode->cc_src2, 0);
            got_of = true;
        }
        if (want_carry || need_flags) {
            tcg_gen_movi_tl(decode->cc_dst, 0);
            got_cf = true;
        }
        break;

    case CC_OP_SARB ... CC_OP_SARQ:
        /*
         * SHR/RCR/SHR/RCR/... is a relatively common occurrence of RCR.
         * By computing CF without using eflags, the calls to cc_compute_all
         * can be eliminated as dead code (except for the last RCR).
         */
        if (want_carry || need_flags) {
            tcg_gen_andi_tl(decode->cc_dst, cpu_cc_src, 1);
            got_cf = true;
        }
        gen_mov_eflags(s, decode->cc_src);
        break;

    case CC_OP_SHLB ... CC_OP_SHLQ:
        /*
         * Likewise for SHL/RCL/SHL/RCL/... but, if CF is not in the sign
         * bit, we might as well fish CF out of EFLAGS and save a shift.
         */
        if (want_carry && (!need_flags || s->cc_op == CC_OP_SHLB + MO_TL)) {
            tcg_gen_shri_tl(decode->cc_dst, cpu_cc_src, (8 << (s->cc_op - CC_OP_SHLB)) - 1);
            got_cf = true;
        }
        gen_mov_eflags(s, decode->cc_src);
        break;

    default:
        gen_mov_eflags(s, decode->cc_src);
        break;
    }

    if (need_flags) {
        /* If the flags could be left unmodified, always load them.  */
        if (!got_of) {
            tcg_gen_extract_tl(decode->cc_src2, decode->cc_src, ctz32(CC_O), 1);
            got_of = true;
        }
        if (!got_cf) {
            tcg_gen_extract_tl(decode->cc_dst, decode->cc_src, ctz32(CC_C), 1);
            got_cf = true;
        }
    }
    return got_cf;
}

static void gen_rot_overflow(X86DecodedInsn *decode, TCGv result, TCGv old,
                             bool can_be_zero, TCGv count)
{
    MemOp ot = decode->op[0].ot;
    TCGv temp = can_be_zero ? tcg_temp_new() : decode->cc_src2;

    tcg_gen_xor_tl(temp, old, result);
    tcg_gen_extract_tl(temp, temp, (8 << ot) - 1, 1);
    if (can_be_zero) {
        tcg_gen_movcond_tl(TCG_COND_EQ, decode->cc_src2, count, tcg_constant_tl(0),
                           decode->cc_src2, temp);
    }
}

/*
 * RCx operations are invariant modulo 8*operand_size+1.  For 8 and 16-bit operands,
 * this is less than 0x1f (the mask applied by gen_shift_count) so reduce further.
 */
static void gen_rotc_mod(MemOp ot, TCGv count)
{
    TCGv temp;

    switch (ot) {
    case MO_8:
        temp = tcg_temp_new();
        tcg_gen_subi_tl(temp, count, 18);
        tcg_gen_movcond_tl(TCG_COND_GE, count, temp, tcg_constant_tl(0), temp, count);
        tcg_gen_subi_tl(temp, count, 9);
        tcg_gen_movcond_tl(TCG_COND_GE, count, temp, tcg_constant_tl(0), temp, count);
        break;

    case MO_16:
        temp = tcg_temp_new();
        tcg_gen_subi_tl(temp, count, 17);
        tcg_gen_movcond_tl(TCG_COND_GE, count, temp, tcg_constant_tl(0), temp, count);
        break;

    default:
        break;
    }
}

/*
 * The idea here is that the bit to the right of the new bit 0 is the
 * new carry, and the bit to the right of the old bit 0 is the old carry.
 * Just like a regular rotation, the result of the rotation is composed
 * from a right shifted part and a left shifted part of s->T0.  The new carry
 * is extracted from the right-shifted portion, and the old carry is
 * inserted at the end of the left-shifted portion.
 *
 * Because of the separate shifts involving the carry, gen_RCL and gen_RCR
 * mostly operate on count-1.  This also comes in handy when computing
 * length - count, because (length-1) - (count-1) can be computed with
 * a XOR, and that is commutative unlike subtraction.
 */
static void gen_RCL(DisasContext *s, X86DecodedInsn *decode)
{
    bool have_1bit_cin, can_be_zero;
    TCGv count;
    TCGLabel *zero_label = NULL;
    MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);
    TCGv low, high, low_count;

    if (!count) {
        return;
    }

    low = tcg_temp_new();
    high = tcg_temp_new();
    low_count = tcg_temp_new();

    gen_rotc_mod(ot, count);
    have_1bit_cin = gen_eflags_adcox(s, decode, true, can_be_zero);
    if (can_be_zero) {
        zero_label = gen_new_label();
        tcg_gen_brcondi_tl(TCG_COND_EQ, count, 0, zero_label);
    }

    /* Compute high part, including incoming carry.  */
    if (!have_1bit_cin || TCG_TARGET_deposit_tl_valid(1, TARGET_LONG_BITS - 1)) {
        /* high = (T0 << 1) | cin */
        TCGv cin = have_1bit_cin ? decode->cc_dst : decode->cc_src;
        tcg_gen_deposit_tl(high, cin, s->T0, 1, TARGET_LONG_BITS - 1);
    } else {
        /* Same as above but without deposit; cin in cc_dst.  */
        tcg_gen_add_tl(high, s->T0, decode->cc_dst);
        tcg_gen_add_tl(high, high, s->T0);
    }
    tcg_gen_subi_tl(count, count, 1);
    tcg_gen_shl_tl(high, high, count);

    /* Compute low part and outgoing carry, incoming s->T0 is zero extended */
    tcg_gen_xori_tl(low_count, count, (8 << ot) - 1); /* LENGTH - 1 - (count - 1) */
    tcg_gen_shr_tl(low, s->T0, low_count);
    tcg_gen_andi_tl(decode->cc_dst, low, 1);
    tcg_gen_shri_tl(low, low, 1);

    /* Compute result and outgoing overflow */
    tcg_gen_mov_tl(decode->cc_src2, s->T0);
    tcg_gen_or_tl(s->T0, low, high);
    gen_rot_overflow(decode, s->T0, decode->cc_src2, false, NULL);

    if (zero_label) {
        gen_set_label(zero_label);
    }
}

static void gen_RCR(DisasContext *s, X86DecodedInsn *decode)
{
    bool have_1bit_cin, can_be_zero;
    TCGv count;
    TCGLabel *zero_label = NULL;
    MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);
    TCGv low, high, high_count;

    if (!count) {
        return;
    }

    low = tcg_temp_new();
    high = tcg_temp_new();
    high_count = tcg_temp_new();

    gen_rotc_mod(ot, count);
    have_1bit_cin = gen_eflags_adcox(s, decode, true, can_be_zero);
    if (can_be_zero) {
        zero_label = gen_new_label();
        tcg_gen_brcondi_tl(TCG_COND_EQ, count, 0, zero_label);
    }

    /* Save incoming carry into high, it will be shifted later.  */
    if (!have_1bit_cin || TCG_TARGET_deposit_tl_valid(1, TARGET_LONG_BITS - 1)) {
        TCGv cin = have_1bit_cin ? decode->cc_dst : decode->cc_src;
        tcg_gen_deposit_tl(high, cin, s->T0, 1, TARGET_LONG_BITS - 1);
    } else {
        /* Same as above but without deposit; cin in cc_dst.  */
        tcg_gen_add_tl(high, s->T0, decode->cc_dst);
        tcg_gen_add_tl(high, high, s->T0);
    }

    /* Compute low part and outgoing carry, incoming s->T0 is zero extended */
    tcg_gen_subi_tl(count, count, 1);
    tcg_gen_shr_tl(low, s->T0, count);
    tcg_gen_andi_tl(decode->cc_dst, low, 1);
    tcg_gen_shri_tl(low, low, 1);

    /* Move high part to the right position */
    tcg_gen_xori_tl(high_count, count, (8 << ot) - 1); /* LENGTH - 1 - (count - 1) */
    tcg_gen_shl_tl(high, high, high_count);

    /* Compute result and outgoing overflow */
    tcg_gen_mov_tl(decode->cc_src2, s->T0);
    tcg_gen_or_tl(s->T0, low, high);
    gen_rot_overflow(decode, s->T0, decode->cc_src2, false, NULL);

    if (zero_label) {
        gen_set_label(zero_label);
    }
}

#ifdef CONFIG_USER_ONLY
static void gen_unreachable(DisasContext *s, X86DecodedInsn *decode)
{
    g_assert_not_reached();
}
#endif

#ifndef CONFIG_USER_ONLY
static void gen_RDMSR(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_update_eip_cur(s);
    gen_helper_rdmsr(tcg_env);
}
#else
#define gen_RDMSR gen_unreachable
#endif

static void gen_RDPMC(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_update_eip_cur(s);
    translator_io_start(&s->base);
    gen_helper_rdpmc(tcg_env);
    s->base.is_jmp = DISAS_NORETURN;
}

static void gen_RDTSC(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_update_eip_cur(s);
    translator_io_start(&s->base);
    gen_helper_rdtsc(tcg_env);
}

static void gen_RDxxBASE(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv base = cpu_seg_base[s->modrm & 8 ? R_GS : R_FS];

    /* Preserve hflags bits by testing CR4 at runtime.  */
    gen_helper_cr4_testbit(tcg_env, tcg_constant_i32(CR4_FSGSBASE_MASK));
    tcg_gen_mov_tl(s->T0, base);
}

static void gen_RET(DisasContext *s, X86DecodedInsn *decode)
{
    int16_t adjust = decode->e.op1 == X86_TYPE_I ? decode->immediate : 0;

    MemOp ot = gen_pop_T0(s);
    gen_stack_update(s, adjust + (1 << ot));
    gen_op_jmp_v(s, s->T0);
    gen_bnd_jmp(s);
    s->base.is_jmp = DISAS_JUMP;
}

static void gen_RETF(DisasContext *s, X86DecodedInsn *decode)
{
    int16_t adjust = decode->e.op1 == X86_TYPE_I ? decode->immediate : 0;

    if (!PE(s) || VM86(s)) {
        gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], 0);
        /* pop offset */
        gen_op_ld_v(s, s->dflag, s->T0, s->A0);
        /* NOTE: keeping EIP updated is not a problem in case of
           exception */
        gen_op_jmp_v(s, s->T0);
        /* pop selector */
        gen_add_A0_im(s, 1 << s->dflag);
        gen_op_ld_v(s, s->dflag, s->T0, s->A0);
        gen_op_movl_seg_real(s, R_CS, s->T0);
        /* add stack offset */
        gen_stack_update(s, adjust + (2 << s->dflag));
    } else {
        gen_update_cc_op(s);
        gen_update_eip_cur(s);
        gen_helper_lret_protected(tcg_env, tcg_constant_i32(s->dflag - 1),
                                  tcg_constant_i32(adjust));
    }
    s->base.is_jmp = DISAS_EOB_ONLY;
}

/*
 * Return non-NULL if a 32-bit rotate works, after possibly replicating the input.
 * The input has already been zero-extended upon operand decode.
 */
static TCGv_i32 gen_rot_replicate(MemOp ot, TCGv in)
{
    TCGv_i32 temp;
    switch (ot) {
    case MO_8:
        temp = tcg_temp_new_i32();
        tcg_gen_trunc_tl_i32(temp, in);
        tcg_gen_muli_i32(temp, temp, 0x01010101);
        return temp;

    case MO_16:
        temp = tcg_temp_new_i32();
        tcg_gen_trunc_tl_i32(temp, in);
        tcg_gen_deposit_i32(temp, temp, temp, 16, 16);
        return temp;

#ifdef TARGET_X86_64
    case MO_32:
        temp = tcg_temp_new_i32();
        tcg_gen_trunc_tl_i32(temp, in);
        return temp;
#endif

    default:
        return NULL;
    }
}

static void gen_rot_carry(X86DecodedInsn *decode, TCGv result,
                          bool can_be_zero, TCGv count, int bit)
{
    if (!can_be_zero) {
        tcg_gen_extract_tl(decode->cc_dst, result, bit, 1);
    } else {
        TCGv temp = tcg_temp_new();
        tcg_gen_extract_tl(temp, result, bit, 1);
        tcg_gen_movcond_tl(TCG_COND_EQ, decode->cc_dst, count, tcg_constant_tl(0),
                           decode->cc_dst, temp);
    }
}

static void gen_ROL(DisasContext *s, X86DecodedInsn *decode)
{
    bool can_be_zero;
    TCGv count;
    MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);
    TCGv_i32 temp32, count32;
    TCGv old = tcg_temp_new();

    if (!count) {
        return;
    }

    gen_eflags_adcox(s, decode, false, can_be_zero);
    tcg_gen_mov_tl(old, s->T0);
    temp32 = gen_rot_replicate(ot, s->T0);
    if (temp32) {
        count32 = tcg_temp_new_i32();
        tcg_gen_trunc_tl_i32(count32, count);
        tcg_gen_rotl_i32(temp32, temp32, count32);
        /* Zero extend to facilitate later optimization.  */
        tcg_gen_extu_i32_tl(s->T0, temp32);
    } else {
        tcg_gen_rotl_tl(s->T0, s->T0, count);
    }
    gen_rot_carry(decode, s->T0, can_be_zero, count, 0);
    gen_rot_overflow(decode, s->T0, old, can_be_zero, count);
}

static void gen_ROR(DisasContext *s, X86DecodedInsn *decode)
{
    bool can_be_zero;
    TCGv count;
    MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);
    TCGv_i32 temp32, count32;
    TCGv old = tcg_temp_new();

    if (!count) {
        return;
    }

    gen_eflags_adcox(s, decode, false, can_be_zero);
    tcg_gen_mov_tl(old, s->T0);
    temp32 = gen_rot_replicate(ot, s->T0);
    if (temp32) {
        count32 = tcg_temp_new_i32();
        tcg_gen_trunc_tl_i32(count32, count);
        tcg_gen_rotr_i32(temp32, temp32, count32);
        /* Zero extend to facilitate later optimization.  */
        tcg_gen_extu_i32_tl(s->T0, temp32);
        gen_rot_carry(decode, s->T0, can_be_zero, count, 31);
    } else {
        tcg_gen_rotr_tl(s->T0, s->T0, count);
        gen_rot_carry(decode, s->T0, can_be_zero, count, TARGET_LONG_BITS - 1);
    }
    gen_rot_overflow(decode, s->T0, old, can_be_zero, count);
}

static void gen_RORX(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    int mask = ot == MO_64 ? 63 : 31;
    int b = decode->immediate & mask;

    switch (ot) {
    case MO_32:
#ifdef TARGET_X86_64
        tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
        tcg_gen_rotri_i32(s->tmp2_i32, s->tmp2_i32, b);
        tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
        break;

    case MO_64:
#endif
        tcg_gen_rotri_tl(s->T0, s->T0, b);
        break;

    default:
        g_assert_not_reached();
    }
}

#ifndef CONFIG_USER_ONLY
static void gen_RSM(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_rsm(tcg_env);
    assume_cc_op(s, CC_OP_EFLAGS);
    s->base.is_jmp = DISAS_EOB_ONLY;
}
#else
#define gen_RSM gen_UD
#endif

static void gen_SAHF(DisasContext *s, X86DecodedInsn *decode)
{
    if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) {
        return gen_illegal_opcode(s);
    }
    tcg_gen_shri_tl(s->T0, cpu_regs[R_EAX], 8);
    gen_compute_eflags(s);
    tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
    tcg_gen_andi_tl(s->T0, s->T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, s->T0);
}

static void gen_SALC(DisasContext *s, X86DecodedInsn *decode)
{
    gen_compute_eflags_c(s, s->T0);
    tcg_gen_neg_tl(s->T0, s->T0);
}

static void gen_shift_dynamic_flags(DisasContext *s, X86DecodedInsn *decode, TCGv count, CCOp cc_op)
{
    TCGv_i32 count32 = tcg_temp_new_i32();
    TCGv_i32 old_cc_op;

    decode->cc_op = CC_OP_DYNAMIC;
    decode->cc_op_dynamic = tcg_temp_new_i32();

    assert(decode->cc_dst == s->T0);
    if (cc_op_live[s->cc_op] & USES_CC_DST) {
        decode->cc_dst = tcg_temp_new();
        tcg_gen_movcond_tl(TCG_COND_EQ, decode->cc_dst, count, tcg_constant_tl(0),
                           cpu_cc_dst, s->T0);
    }

    if (cc_op_live[s->cc_op] & USES_CC_SRC) {
        tcg_gen_movcond_tl(TCG_COND_EQ, decode->cc_src, count, tcg_constant_tl(0),
                           cpu_cc_src, decode->cc_src);
    }

    tcg_gen_trunc_tl_i32(count32, count);
    if (s->cc_op == CC_OP_DYNAMIC) {
        old_cc_op = cpu_cc_op;
    } else {
        old_cc_op = tcg_constant_i32(s->cc_op);
    }
    tcg_gen_movcond_i32(TCG_COND_EQ, decode->cc_op_dynamic, count32, tcg_constant_i32(0),
                        old_cc_op, tcg_constant_i32(cc_op));
}

static void gen_SAR(DisasContext *s, X86DecodedInsn *decode)
{
    bool can_be_zero;
    TCGv count;
    MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);

    if (!count) {
        return;
    }

    decode->cc_dst = s->T0;
    decode->cc_src = tcg_temp_new();
    tcg_gen_subi_tl(decode->cc_src, count, 1);
    tcg_gen_sar_tl(decode->cc_src, s->T0, decode->cc_src);
    tcg_gen_sar_tl(s->T0, s->T0, count);
    if (can_be_zero) {
        gen_shift_dynamic_flags(s, decode, count, CC_OP_SARB + ot);
    } else {
        decode->cc_op = CC_OP_SARB + ot;
    }
}

static void gen_SARX(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    int mask;

    mask = ot == MO_64 ? 63 : 31;
    tcg_gen_andi_tl(s->T1, s->T1, mask);
    tcg_gen_sar_tl(s->T0, s->T0, s->T1);
}

static void gen_SBB(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    TCGv c_in = tcg_temp_new();

    gen_compute_eflags_c(s, c_in);
    if (s->prefix & PREFIX_LOCK) {
        tcg_gen_add_tl(s->T0, s->T1, c_in);
        tcg_gen_neg_tl(s->T0, s->T0);
        tcg_gen_atomic_add_fetch_tl(s->T0, s->A0, s->T0,
                                    s->mem_index, ot | MO_LE);
    } else {
        /*
         * TODO: SBB reg, reg could use gen_prepare_eflags_c followed by
         * negsetcond, and CC_OP_SUBB as the cc_op.
         */
        tcg_gen_sub_tl(s->T0, s->T0, s->T1);
        tcg_gen_sub_tl(s->T0, s->T0, c_in);
    }
    prepare_update3_cc(decode, s, CC_OP_SBBB + ot, c_in);
}

static void gen_SCAS(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[2].ot;
    if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
        gen_repz_nz(s, ot, gen_scas);
    } else {
        gen_scas(s, ot);
    }
}

static void gen_SETcc(DisasContext *s, X86DecodedInsn *decode)
{
    gen_setcc1(s, decode->b & 0xf, s->T0);
}

static void gen_SFENCE(DisasContext *s, X86DecodedInsn *decode)
{
    tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
}

static void gen_SHA1NEXTE(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_sha1nexte(OP_PTR0, OP_PTR1, OP_PTR2);
}

static void gen_SHA1MSG1(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_sha1msg1(OP_PTR0, OP_PTR1, OP_PTR2);
}

static void gen_SHA1MSG2(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_sha1msg2(OP_PTR0, OP_PTR1, OP_PTR2);
}

static void gen_SHA1RNDS4(DisasContext *s, X86DecodedInsn *decode)
{
    switch(decode->immediate & 3) {
    case 0:
        gen_helper_sha1rnds4_f0(OP_PTR0, OP_PTR0, OP_PTR1);
        break;
    case 1:
        gen_helper_sha1rnds4_f1(OP_PTR0, OP_PTR0, OP_PTR1);
        break;
    case 2:
        gen_helper_sha1rnds4_f2(OP_PTR0, OP_PTR0, OP_PTR1);
        break;
    case 3:
        gen_helper_sha1rnds4_f3(OP_PTR0, OP_PTR0, OP_PTR1);
        break;
    }
}

static void gen_SHA256MSG1(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_sha256msg1(OP_PTR0, OP_PTR1, OP_PTR2);
}

static void gen_SHA256MSG2(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_sha256msg2(OP_PTR0, OP_PTR1, OP_PTR2);
}

static void gen_SHA256RNDS2(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 wk0 = tcg_temp_new_i32();
    TCGv_i32 wk1 = tcg_temp_new_i32();

    tcg_gen_ld_i32(wk0, tcg_env, ZMM_OFFSET(0) + offsetof(ZMMReg, ZMM_L(0)));
    tcg_gen_ld_i32(wk1, tcg_env, ZMM_OFFSET(0) + offsetof(ZMMReg, ZMM_L(1)));

    gen_helper_sha256rnds2(OP_PTR0, OP_PTR1, OP_PTR2, wk0, wk1);
}

static void gen_SHL(DisasContext *s, X86DecodedInsn *decode)
{
    bool can_be_zero;
    TCGv count;
    MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);

    if (!count) {
        return;
    }

    decode->cc_dst = s->T0;
    decode->cc_src = tcg_temp_new();
    tcg_gen_subi_tl(decode->cc_src, count, 1);
    tcg_gen_shl_tl(decode->cc_src, s->T0, decode->cc_src);
    tcg_gen_shl_tl(s->T0, s->T0, count);
    if (can_be_zero) {
        gen_shift_dynamic_flags(s, decode, count, CC_OP_SHLB + ot);
    } else {
        decode->cc_op = CC_OP_SHLB + ot;
    }
}

static void gen_SHLD(DisasContext *s, X86DecodedInsn *decode)
{
    bool can_be_zero;
    TCGv count;
    int unit = decode->e.op3 == X86_TYPE_I ? X86_OP_IMM : X86_OP_INT;
    MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, unit);

    if (!count) {
        return;
    }

    decode->cc_dst = s->T0;
    decode->cc_src = s->tmp0;
    gen_shiftd_rm_T1(s, ot, false, count);
    if (can_be_zero) {
        gen_shift_dynamic_flags(s, decode, count, CC_OP_SHLB + ot);
    } else {
        decode->cc_op = CC_OP_SHLB + ot;
    }
}

static void gen_SHLX(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    int mask;

    mask = ot == MO_64 ? 63 : 31;
    tcg_gen_andi_tl(s->T1, s->T1, mask);
    tcg_gen_shl_tl(s->T0, s->T0, s->T1);
}

static void gen_SHR(DisasContext *s, X86DecodedInsn *decode)
{
    bool can_be_zero;
    TCGv count;
    MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);

    if (!count) {
        return;
    }

    decode->cc_dst = s->T0;
    decode->cc_src = tcg_temp_new();
    tcg_gen_subi_tl(decode->cc_src, count, 1);
    tcg_gen_shr_tl(decode->cc_src, s->T0, decode->cc_src);
    tcg_gen_shr_tl(s->T0, s->T0, count);
    if (can_be_zero) {
        gen_shift_dynamic_flags(s, decode, count, CC_OP_SARB + ot);
    } else {
        decode->cc_op = CC_OP_SARB + ot;
    }
}

static void gen_SHRD(DisasContext *s, X86DecodedInsn *decode)
{
    bool can_be_zero;
    TCGv count;
    int unit = decode->e.op3 == X86_TYPE_I ? X86_OP_IMM : X86_OP_INT;
    MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, unit);

    if (!count) {
        return;
    }

    decode->cc_dst = s->T0;
    decode->cc_src = s->tmp0;
    gen_shiftd_rm_T1(s, ot, true, count);
    if (can_be_zero) {
        gen_shift_dynamic_flags(s, decode, count, CC_OP_SARB + ot);
    } else {
        decode->cc_op = CC_OP_SARB + ot;
    }
}

static void gen_SHRX(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;
    int mask;

    mask = ot == MO_64 ? 63 : 31;
    tcg_gen_andi_tl(s->T1, s->T1, mask);
    tcg_gen_shr_tl(s->T0, s->T0, s->T1);
}

static void gen_STC(DisasContext *s, X86DecodedInsn *decode)
{
    gen_compute_eflags(s);
    tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
}

static void gen_STD(DisasContext *s, X86DecodedInsn *decode)
{
    tcg_gen_st_i32(tcg_constant_i32(-1), tcg_env, offsetof(CPUX86State, df));
}

static void gen_STI(DisasContext *s, X86DecodedInsn *decode)
{
    gen_set_eflags(s, IF_MASK);
    s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
}

static void gen_VAESKEYGEN(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    assert(!s->vex_l);
    gen_helper_aeskeygenassist_xmm(tcg_env, OP_PTR0, OP_PTR1, imm);
}

static void gen_STMXCSR(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_update_mxcsr(tcg_env);
    tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, mxcsr));
}

static void gen_STOS(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;
    if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
        gen_repz(s, ot, gen_stos);
    } else {
        gen_stos(s, ot);
    }
}

static void gen_SUB(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;

    if (s->prefix & PREFIX_LOCK) {
        tcg_gen_neg_tl(s->T0, s->T1);
        tcg_gen_atomic_fetch_add_tl(s->cc_srcT, s->A0, s->T0,
                                    s->mem_index, ot | MO_LE);
        tcg_gen_sub_tl(s->T0, s->cc_srcT, s->T1);
    } else {
        tcg_gen_mov_tl(s->cc_srcT, s->T0);
        tcg_gen_sub_tl(s->T0, s->T0, s->T1);
    }
    prepare_update2_cc(decode, s, CC_OP_SUBB + ot);
}

static void gen_SYSCALL(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_update_eip_cur(s);
    gen_helper_syscall(tcg_env, cur_insn_len_i32(s));
    if (LMA(s)) {
        assume_cc_op(s, CC_OP_EFLAGS);
    }

    /*
     * TF handling for the syscall insn is different. The TF bit is checked
     * after the syscall insn completes. This allows #DB to not be
     * generated after one has entered CPL0 if TF is set in FMASK.
     */
    s->base.is_jmp = DISAS_EOB_RECHECK_TF;
}

static void gen_SYSENTER(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_sysenter(tcg_env);
    s->base.is_jmp = DISAS_EOB_ONLY;
}

static void gen_SYSEXIT(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_sysexit(tcg_env, tcg_constant_i32(s->dflag - 1));
    s->base.is_jmp = DISAS_EOB_ONLY;
}

static void gen_SYSRET(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_sysret(tcg_env, tcg_constant_i32(s->dflag - 1));
    if (LMA(s)) {
        assume_cc_op(s, CC_OP_EFLAGS);
    }

    /*
     * TF handling for the sysret insn is different. The TF bit is checked
     * after the sysret insn completes. This allows #DB to be
     * generated "as if" the syscall insn in userspace has just
     * completed.
     */
    s->base.is_jmp = DISAS_EOB_RECHECK_TF;
}

static void gen_TZCNT(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[0].ot;

    /* C bit (cc_src) is defined related to the input.  */
    decode->cc_src = tcg_temp_new();
    decode->cc_dst = s->T0;
    decode->cc_op = CC_OP_BMILGB + ot;
    tcg_gen_mov_tl(decode->cc_src, s->T0);

    /* A zero input returns the operand size.  */
    tcg_gen_ctzi_tl(s->T0, s->T0, 8 << ot);
}

static void gen_UD(DisasContext *s, X86DecodedInsn *decode)
{
    gen_illegal_opcode(s);
}

static void gen_VAESIMC(DisasContext *s, X86DecodedInsn *decode)
{
    assert(!s->vex_l);
    gen_helper_aesimc_xmm(tcg_env, OP_PTR0, OP_PTR2);
}

/*
 * 00 = v*ps Vps, Hps, Wpd
 * 66 = v*pd Vpd, Hpd, Wps
 * f3 = v*ss Vss, Hss, Wps
 * f2 = v*sd Vsd, Hsd, Wps
 */
#define SSE_CMP(x) { \
    gen_helper_ ## x ## ps ## _xmm, gen_helper_ ## x ## pd ## _xmm, \
    gen_helper_ ## x ## ss, gen_helper_ ## x ## sd, \
    gen_helper_ ## x ## ps ## _ymm, gen_helper_ ## x ## pd ## _ymm}
static const SSEFunc_0_eppp gen_helper_cmp_funcs[32][6] = {
    SSE_CMP(cmpeq),
    SSE_CMP(cmplt),
    SSE_CMP(cmple),
    SSE_CMP(cmpunord),
    SSE_CMP(cmpneq),
    SSE_CMP(cmpnlt),
    SSE_CMP(cmpnle),
    SSE_CMP(cmpord),

    SSE_CMP(cmpequ),
    SSE_CMP(cmpnge),
    SSE_CMP(cmpngt),
    SSE_CMP(cmpfalse),
    SSE_CMP(cmpnequ),
    SSE_CMP(cmpge),
    SSE_CMP(cmpgt),
    SSE_CMP(cmptrue),

    SSE_CMP(cmpeqs),
    SSE_CMP(cmpltq),
    SSE_CMP(cmpleq),
    SSE_CMP(cmpunords),
    SSE_CMP(cmpneqq),
    SSE_CMP(cmpnltq),
    SSE_CMP(cmpnleq),
    SSE_CMP(cmpords),

    SSE_CMP(cmpequs),
    SSE_CMP(cmpngeq),
    SSE_CMP(cmpngtq),
    SSE_CMP(cmpfalses),
    SSE_CMP(cmpnequs),
    SSE_CMP(cmpgeq),
    SSE_CMP(cmpgtq),
    SSE_CMP(cmptrues),
};
#undef SSE_CMP

static void gen_VCMP(DisasContext *s, X86DecodedInsn *decode)
{
    int index = decode->immediate & (s->prefix & PREFIX_VEX ? 31 : 7);
    int b =
        s->prefix & PREFIX_REPZ  ? 2 /* ss */ :
        s->prefix & PREFIX_REPNZ ? 3 /* sd */ :
        !!(s->prefix & PREFIX_DATA) /* pd */ + (s->vex_l << 2);

    gen_helper_cmp_funcs[index][b](tcg_env, OP_PTR0, OP_PTR1, OP_PTR2);
}

static void gen_VCOMI(DisasContext *s, X86DecodedInsn *decode)
{
    SSEFunc_0_epp fn;
    fn = s->prefix & PREFIX_DATA ? gen_helper_comisd : gen_helper_comiss;
    fn(tcg_env, OP_PTR1, OP_PTR2);
    assume_cc_op(s, CC_OP_EFLAGS);
}

static void gen_VCVTPD2PS(DisasContext *s, X86DecodedInsn *decode)
{
    if (s->vex_l) {
        gen_helper_cvtpd2ps_ymm(tcg_env, OP_PTR0, OP_PTR2);
    } else {
        gen_helper_cvtpd2ps_xmm(tcg_env, OP_PTR0, OP_PTR2);
    }
}

static void gen_VCVTPS2PD(DisasContext *s, X86DecodedInsn *decode)
{
    if (s->vex_l) {
        gen_helper_cvtps2pd_ymm(tcg_env, OP_PTR0, OP_PTR2);
    } else {
        gen_helper_cvtps2pd_xmm(tcg_env, OP_PTR0, OP_PTR2);
    }
}

static void gen_VCVTPS2PH(DisasContext *s, X86DecodedInsn *decode)
{
    gen_unary_imm_fp_sse(s, decode,
                      gen_helper_cvtps2ph_xmm,
                      gen_helper_cvtps2ph_ymm);
    /*
     * VCVTPS2PH is the only instruction that performs an operation on a
     * register source and then *stores* into memory.
     */
    if (decode->op[0].has_ea) {
        gen_store_sse(s, decode, decode->op[0].offset);
    }
}

static void gen_VCVTSD2SS(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_cvtsd2ss(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2);
}

static void gen_VCVTSS2SD(DisasContext *s, X86DecodedInsn *decode)
{
    gen_helper_cvtss2sd(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2);
}

static void gen_VCVTSI2Sx(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);
    TCGv_i32 in;

    tcg_gen_gvec_mov(MO_64, decode->op[0].offset, decode->op[1].offset, vec_len, vec_len);

#ifdef TARGET_X86_64
    MemOp ot = decode->op[2].ot;
    if (ot == MO_64) {
        if (s->prefix & PREFIX_REPNZ) {
            gen_helper_cvtsq2sd(tcg_env, OP_PTR0, s->T1);
        } else {
            gen_helper_cvtsq2ss(tcg_env, OP_PTR0, s->T1);
        }
        return;
    }
    in = s->tmp2_i32;
    tcg_gen_trunc_tl_i32(in, s->T1);
#else
    in = s->T1;
#endif

    if (s->prefix & PREFIX_REPNZ) {
        gen_helper_cvtsi2sd(tcg_env, OP_PTR0, in);
    } else {
        gen_helper_cvtsi2ss(tcg_env, OP_PTR0, in);
    }
}

static inline void gen_VCVTtSx2SI(DisasContext *s, X86DecodedInsn *decode,
                                  SSEFunc_i_ep ss2si, SSEFunc_l_ep ss2sq,
                                  SSEFunc_i_ep sd2si, SSEFunc_l_ep sd2sq)
{
    TCGv_i32 out;

#ifdef TARGET_X86_64
    MemOp ot = decode->op[0].ot;
    if (ot == MO_64) {
        if (s->prefix & PREFIX_REPNZ) {
            sd2sq(s->T0, tcg_env, OP_PTR2);
        } else {
            ss2sq(s->T0, tcg_env, OP_PTR2);
        }
        return;
    }

    out = s->tmp2_i32;
#else
    out = s->T0;
#endif
    if (s->prefix & PREFIX_REPNZ) {
        sd2si(out, tcg_env, OP_PTR2);
    } else {
        ss2si(out, tcg_env, OP_PTR2);
    }
#ifdef TARGET_X86_64
    tcg_gen_extu_i32_tl(s->T0, out);
#endif
}

#ifndef TARGET_X86_64
#define gen_helper_cvtss2sq NULL
#define gen_helper_cvtsd2sq NULL
#define gen_helper_cvttss2sq NULL
#define gen_helper_cvttsd2sq NULL
#endif

static void gen_VCVTSx2SI(DisasContext *s, X86DecodedInsn *decode)
{
    gen_VCVTtSx2SI(s, decode,
                   gen_helper_cvtss2si, gen_helper_cvtss2sq,
                   gen_helper_cvtsd2si, gen_helper_cvtsd2sq);
}

static void gen_VCVTTSx2SI(DisasContext *s, X86DecodedInsn *decode)
{
    gen_VCVTtSx2SI(s, decode,
                   gen_helper_cvttss2si, gen_helper_cvttss2sq,
                   gen_helper_cvttsd2si, gen_helper_cvttsd2sq);
}

static void gen_VEXTRACTx128(DisasContext *s, X86DecodedInsn *decode)
{
    int mask = decode->immediate & 1;
    int src_ofs = vector_elem_offset(&decode->op[1], MO_128, mask);
    if (decode->op[0].has_ea) {
        /* VEX-only instruction, no alignment requirements.  */
        gen_sto_env_A0(s, src_ofs, false);
    } else {
        tcg_gen_gvec_mov(MO_64, decode->op[0].offset, src_ofs, 16, 16);
    }
}

static void gen_VEXTRACTPS(DisasContext *s, X86DecodedInsn *decode)
{
    gen_pextr(s, decode, MO_32);
}

static void gen_vinsertps(DisasContext *s, X86DecodedInsn *decode)
{
    int val = decode->immediate;
    int dest_word = (val >> 4) & 3;
    int new_mask = (val & 15) | (1 << dest_word);
    int vec_len = 16;

    assert(!s->vex_l);

    if (new_mask == 15) {
        /* All zeroes except possibly for the inserted element */
        tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
    } else if (decode->op[1].offset != decode->op[0].offset) {
        gen_store_sse(s, decode, decode->op[1].offset);
    }

    if (new_mask != (val & 15)) {
        tcg_gen_st_i32(s->tmp2_i32, tcg_env,
                       vector_elem_offset(&decode->op[0], MO_32, dest_word));
    }

    if (new_mask != 15) {
        TCGv_i32 zero = tcg_constant_i32(0); /* float32_zero */
        int i;
        for (i = 0; i < 4; i++) {
            if ((val >> i) & 1) {
                tcg_gen_st_i32(zero, tcg_env,
                               vector_elem_offset(&decode->op[0], MO_32, i));
            }
        }
    }
}

static void gen_VINSERTPS_r(DisasContext *s, X86DecodedInsn *decode)
{
    int val = decode->immediate;
    tcg_gen_ld_i32(s->tmp2_i32, tcg_env,
                   vector_elem_offset(&decode->op[2], MO_32, (val >> 6) & 3));
    gen_vinsertps(s, decode);
}

static void gen_VINSERTPS_m(DisasContext *s, X86DecodedInsn *decode)
{
    tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
    gen_vinsertps(s, decode);
}

static void gen_VINSERTx128(DisasContext *s, X86DecodedInsn *decode)
{
    int mask = decode->immediate & 1;
    tcg_gen_gvec_mov(MO_64,
                     decode->op[0].offset + offsetof(YMMReg, YMM_X(mask)),
                     decode->op[2].offset + offsetof(YMMReg, YMM_X(0)), 16, 16);
    tcg_gen_gvec_mov(MO_64,
                     decode->op[0].offset + offsetof(YMMReg, YMM_X(!mask)),
                     decode->op[1].offset + offsetof(YMMReg, YMM_X(!mask)), 16, 16);
}

static inline void gen_maskmov(DisasContext *s, X86DecodedInsn *decode,
                               SSEFunc_0_eppt xmm, SSEFunc_0_eppt ymm)
{
    if (!s->vex_l) {
        xmm(tcg_env, OP_PTR2, OP_PTR1, s->A0);
    } else {
        ymm(tcg_env, OP_PTR2, OP_PTR1, s->A0);
    }
}

static void gen_VMASKMOVPD_st(DisasContext *s, X86DecodedInsn *decode)
{
    gen_maskmov(s, decode, gen_helper_vpmaskmovq_st_xmm, gen_helper_vpmaskmovq_st_ymm);
}

static void gen_VMASKMOVPS_st(DisasContext *s, X86DecodedInsn *decode)
{
    gen_maskmov(s, decode, gen_helper_vpmaskmovd_st_xmm, gen_helper_vpmaskmovd_st_ymm);
}

static void gen_VMOVHPx_ld(DisasContext *s, X86DecodedInsn *decode)
{
    gen_ldq_env_A0(s, decode->op[0].offset + offsetof(XMMReg, XMM_Q(1)));
    if (decode->op[0].offset != decode->op[1].offset) {
        tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[1].offset + offsetof(XMMReg, XMM_Q(0)));
        tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
    }
}

static void gen_VMOVHPx_st(DisasContext *s, X86DecodedInsn *decode)
{
    gen_stq_env_A0(s, decode->op[2].offset + offsetof(XMMReg, XMM_Q(1)));
}

static void gen_VMOVHPx(DisasContext *s, X86DecodedInsn *decode)
{
    if (decode->op[0].offset != decode->op[2].offset) {
        tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[2].offset + offsetof(XMMReg, XMM_Q(1)));
        tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(1)));
    }
    if (decode->op[0].offset != decode->op[1].offset) {
        tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[1].offset + offsetof(XMMReg, XMM_Q(0)));
        tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
    }
}

static void gen_VMOVHLPS(DisasContext *s, X86DecodedInsn *decode)
{
    tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[2].offset + offsetof(XMMReg, XMM_Q(1)));
    tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
    if (decode->op[0].offset != decode->op[1].offset) {
        tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[1].offset + offsetof(XMMReg, XMM_Q(1)));
        tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(1)));
    }
}

static void gen_VMOVLHPS(DisasContext *s, X86DecodedInsn *decode)
{
    tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[2].offset);
    tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(1)));
    if (decode->op[0].offset != decode->op[1].offset) {
        tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[1].offset + offsetof(XMMReg, XMM_Q(0)));
        tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
    }
}

/*
 * Note that MOVLPx supports 256-bit operation unlike MOVHLPx, MOVLHPx, MOXHPx.
 * Use a gvec move to move everything above the bottom 64 bits.
 */

static void gen_VMOVLPx(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[2].offset + offsetof(XMMReg, XMM_Q(0)));
    tcg_gen_gvec_mov(MO_64, decode->op[0].offset, decode->op[1].offset, vec_len, vec_len);
    tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
}

static void gen_VMOVLPx_ld(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
    tcg_gen_gvec_mov(MO_64, decode->op[0].offset, decode->op[1].offset, vec_len, vec_len);
    tcg_gen_st_i64(s->tmp1_i64, OP_PTR0, offsetof(ZMMReg, ZMM_Q(0)));
}

static void gen_VMOVLPx_st(DisasContext *s, X86DecodedInsn *decode)
{
    tcg_gen_ld_i64(s->tmp1_i64, OP_PTR2, offsetof(ZMMReg, ZMM_Q(0)));
    tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
}

static void gen_VMOVSD_ld(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i64 zero = tcg_constant_i64(0);

    tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
    tcg_gen_st_i64(zero, OP_PTR0, offsetof(ZMMReg, ZMM_Q(1)));
    tcg_gen_st_i64(s->tmp1_i64, OP_PTR0, offsetof(ZMMReg, ZMM_Q(0)));
}

static void gen_VMOVSS(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    tcg_gen_ld_i32(s->tmp2_i32, OP_PTR2, offsetof(ZMMReg, ZMM_L(0)));
    tcg_gen_gvec_mov(MO_64, decode->op[0].offset, decode->op[1].offset, vec_len, vec_len);
    tcg_gen_st_i32(s->tmp2_i32, OP_PTR0, offsetof(ZMMReg, ZMM_L(0)));
}

static void gen_VMOVSS_ld(DisasContext *s, X86DecodedInsn *decode)
{
    int vec_len = vector_len(s, decode);

    tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
    tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
    tcg_gen_st_i32(s->tmp2_i32, OP_PTR0, offsetof(ZMMReg, ZMM_L(0)));
}

static void gen_VMOVSS_st(DisasContext *s, X86DecodedInsn *decode)
{
    tcg_gen_ld_i32(s->tmp2_i32, OP_PTR2, offsetof(ZMMReg, ZMM_L(0)));
    tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
}

static void gen_VPMASKMOV_st(DisasContext *s, X86DecodedInsn *decode)
{
    if (s->vex_w) {
        gen_VMASKMOVPD_st(s, decode);
    } else {
        gen_VMASKMOVPS_st(s, decode);
    }
}

static void gen_VPERMD(DisasContext *s, X86DecodedInsn *decode)
{
    assert(s->vex_l);
    gen_helper_vpermd_ymm(OP_PTR0, OP_PTR1, OP_PTR2);
}

static void gen_VPERM2x128(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    assert(s->vex_l);
    gen_helper_vpermdq_ymm(OP_PTR0, OP_PTR1, OP_PTR2, imm);
}

static void gen_VPHMINPOSUW(DisasContext *s, X86DecodedInsn *decode)
{
    assert(!s->vex_l);
    gen_helper_phminposuw_xmm(tcg_env, OP_PTR0, OP_PTR2);
}

static void gen_VROUNDSD(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    assert(!s->vex_l);
    gen_helper_roundsd_xmm(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2, imm);
}

static void gen_VROUNDSS(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
    assert(!s->vex_l);
    gen_helper_roundss_xmm(tcg_env, OP_PTR0, OP_PTR1, OP_PTR2, imm);
}

static void gen_VSHUF(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i32 imm = tcg_constant_i32(decode->immediate);
    SSEFunc_0_pppi ps, pd, fn;
    ps = s->vex_l ? gen_helper_shufps_ymm : gen_helper_shufps_xmm;
    pd = s->vex_l ? gen_helper_shufpd_ymm : gen_helper_shufpd_xmm;
    fn = s->prefix & PREFIX_DATA ? pd : ps;
    fn(OP_PTR0, OP_PTR1, OP_PTR2, imm);
}

static void gen_VUCOMI(DisasContext *s, X86DecodedInsn *decode)
{
    SSEFunc_0_epp fn;
    fn = s->prefix & PREFIX_DATA ? gen_helper_ucomisd : gen_helper_ucomiss;
    fn(tcg_env, OP_PTR1, OP_PTR2);
    assume_cc_op(s, CC_OP_EFLAGS);
}

static void gen_VZEROALL(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_ptr ptr = tcg_temp_new_ptr();

    tcg_gen_addi_ptr(ptr, tcg_env, offsetof(CPUX86State, xmm_regs));
    gen_helper_memset(ptr, ptr, tcg_constant_i32(0),
                      tcg_constant_ptr(CPU_NB_REGS * sizeof(ZMMReg)));
}

static void gen_VZEROUPPER(DisasContext *s, X86DecodedInsn *decode)
{
    int i;

    for (i = 0; i < CPU_NB_REGS; i++) {
        int offset = offsetof(CPUX86State, xmm_regs[i].ZMM_X(1));
        tcg_gen_gvec_dup_imm(MO_64, offset, 16, 16, 0);
    }
}

static void gen_WAIT(DisasContext *s, X86DecodedInsn *decode)
{
    if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) == (HF_MP_MASK | HF_TS_MASK)) {
        gen_NM_exception(s);
    } else {
        /* needs to be treated as I/O because of ferr_irq */
        translator_io_start(&s->base);
        gen_helper_fwait(tcg_env);
    }
}

#ifndef CONFIG_USER_ONLY
static void gen_WRMSR(DisasContext *s, X86DecodedInsn *decode)
{
    gen_update_cc_op(s);
    gen_update_eip_cur(s);
    gen_helper_wrmsr(tcg_env);
    s->base.is_jmp = DISAS_EOB_NEXT;
}
#else
#define gen_WRMSR gen_unreachable
#endif

static void gen_WRxxBASE(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv base = cpu_seg_base[s->modrm & 8 ? R_GS : R_FS];

    /* Preserve hflags bits by testing CR4 at runtime.  */
    gen_helper_cr4_testbit(tcg_env, tcg_constant_i32(CR4_FSGSBASE_MASK));
    tcg_gen_mov_tl(base, s->T0);
}

static void gen_XADD(DisasContext *s, X86DecodedInsn *decode)
{
    MemOp ot = decode->op[1].ot;

    decode->cc_dst = tcg_temp_new();
    decode->cc_src = s->T1;
    decode->cc_op = CC_OP_ADDB + ot;

    if (s->prefix & PREFIX_LOCK) {
        tcg_gen_atomic_fetch_add_tl(s->T0, s->A0, s->T1, s->mem_index, ot | MO_LE);
        tcg_gen_add_tl(decode->cc_dst, s->T0, s->T1);
    } else {
        tcg_gen_add_tl(decode->cc_dst, s->T0, s->T1);
        /*
         * NOTE: writing memory first is important for MMU exceptions,
         * but "new result" wins for XADD AX, AX.
         */
        gen_writeback(s, decode, 0, decode->cc_dst);
    }
    if (decode->op[0].has_ea || decode->op[2].n != decode->op[0].n) {
        gen_writeback(s, decode, 2, s->T0);
    }
}

static void gen_XCHG(DisasContext *s, X86DecodedInsn *decode)
{
    if (s->prefix & PREFIX_LOCK) {
        tcg_gen_atomic_xchg_tl(s->T0, s->A0, s->T1,
                               s->mem_index, decode->op[0].ot | MO_LE);
        /* now store old value into register operand */
        gen_op_mov_reg_v(s, decode->op[2].ot, decode->op[2].n, s->T0);
    } else {
        /* move destination value into source operand, source preserved in T1 */
        gen_op_mov_reg_v(s, decode->op[2].ot, decode->op[2].n, s->T0);
        tcg_gen_mov_tl(s->T0, s->T1);
    }
}

static void gen_XLAT(DisasContext *s, X86DecodedInsn *decode)
{
    /* AL is already zero-extended into s->T0.  */
    tcg_gen_add_tl(s->A0, cpu_regs[R_EBX], s->T0);
    gen_lea_v_seg(s, s->A0, R_DS, s->override);
    gen_op_ld_v(s, MO_8, s->T0, s->A0);
}

static void gen_XOR(DisasContext *s, X86DecodedInsn *decode)
{
    /* special case XOR reg, reg */
    if (decode->op[1].unit == X86_OP_INT &&
        decode->op[2].unit == X86_OP_INT &&
        decode->op[1].n == decode->op[2].n) {
        tcg_gen_movi_tl(s->T0, 0);
        decode->cc_op = CC_OP_CLR;
    } else {
        MemOp ot = decode->op[1].ot;

        if (s->prefix & PREFIX_LOCK) {
            tcg_gen_atomic_xor_fetch_tl(s->T0, s->A0, s->T1,
                                        s->mem_index, ot | MO_LE);
        } else {
            tcg_gen_xor_tl(s->T0, s->T0, s->T1);
        }
        prepare_update1_cc(decode, s, CC_OP_LOGICB + ot);
    }
}

static void gen_XRSTOR(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i64 features = tcg_temp_new_i64();

    tcg_gen_concat_tl_i64(features, cpu_regs[R_EAX], cpu_regs[R_EDX]);
    gen_helper_xrstor(tcg_env, s->A0, features);
    if (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_MPX) {
        /*
         * XRSTOR is how MPX is enabled, which changes how
         * we translate.  Thus we need to end the TB.
         */
        s->base.is_jmp = DISAS_EOB_NEXT;
    }
}

static void gen_XSAVE(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i64 features = tcg_temp_new_i64();

    tcg_gen_concat_tl_i64(features, cpu_regs[R_EAX], cpu_regs[R_EDX]);
    gen_helper_xsave(tcg_env, s->A0, features);
}

static void gen_XSAVEOPT(DisasContext *s, X86DecodedInsn *decode)
{
    TCGv_i64 features = tcg_temp_new_i64();

    tcg_gen_concat_tl_i64(features, cpu_regs[R_EAX], cpu_regs[R_EDX]);
    gen_helper_xsave(tcg_env, s->A0, features);
}
