static void gen_sse(CPUX86State *env, DisasContext *s, int b,

                    target_ulong pc_start, int rex_r)

{

    int b1, op1_offset, op2_offset, is_xmm, val;

    int modrm, mod, rm, reg;

    SSEFunc_0_epp sse_fn_epp;

    SSEFunc_0_eppi sse_fn_eppi;

    SSEFunc_0_ppi sse_fn_ppi;

    SSEFunc_0_eppt sse_fn_eppt;

    TCGMemOp ot;

    b &= 0xff;

    if (s->prefix & PREFIX_DATA)

        b1 = 1;

    else if (s->prefix & PREFIX_REPZ)

        b1 = 2;

    else if (s->prefix & PREFIX_REPNZ)

        b1 = 3;

    else

        b1 = 0;

    sse_fn_epp = sse_op_table1[b][b1];

    if (!sse_fn_epp) {

        goto unknown_op;

    }

    if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) {

        is_xmm = 1;

    } else {

        if (b1 == 0) {

            /* MMX case */

            is_xmm = 0;

        } else {

            is_xmm = 1;

        }

    }

    /* simple MMX/SSE operation */

    if (s->flags & HF_TS_MASK) {

        gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);

        return;

    }

    if (s->flags & HF_EM_MASK) {

    illegal_op:

        gen_illegal_opcode(s);

        return;

    }

    if (is_xmm

        && !(s->flags & HF_OSFXSR_MASK)

        && ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))) {

        goto unknown_op;

    }

    if (b == 0x0e) {

        if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {

            /* If we were fully decoding this we might use illegal_op.  */

            goto unknown_op;

        }

        /* femms */

        gen_helper_emms(cpu_env);

        return;

    }

    if (b == 0x77) {

        /* emms */

        gen_helper_emms(cpu_env);

        return;

    }

    /* prepare MMX state (XXX: optimize by storing fptt and fptags in

       the static cpu state) */

    if (!is_xmm) {

        gen_helper_enter_mmx(cpu_env);

    }

    modrm = cpu_ldub_code(env, s->pc++);

    reg = ((modrm >> 3) & 7);

    if (is_xmm)

        reg |= rex_r;

    mod = (modrm >> 6) & 3;

    if (sse_fn_epp == SSE_SPECIAL) {

        b |= (b1 << 8);

        switch(b) {

        case 0x0e7: /* movntq */

            if (mod == 3) {

                goto illegal_op;

            }

            gen_lea_modrm(env, s, modrm);

            gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));

            break;

        case 0x1e7: /* movntdq */

        case 0x02b: /* movntps */

        case 0x12b: /* movntps */

            if (mod == 3)

                goto illegal_op;

            gen_lea_modrm(env, s, modrm);

            gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));

            break;

        case 0x3f0: /* lddqu */

            if (mod == 3)

                goto illegal_op;

            gen_lea_modrm(env, s, modrm);

            gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));

            break;

        case 0x22b: /* movntss */

        case 0x32b: /* movntsd */

            if (mod == 3)

                goto illegal_op;

            gen_lea_modrm(env, s, modrm);

            if (b1 & 1) {

                gen_stq_env_A0(s, offsetof(CPUX86State,

                                           xmm_regs[reg].ZMM_Q(0)));

            } else {

                tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,

                    xmm_regs[reg].ZMM_L(0)));

                gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);

            }

            break;

        case 0x6e: /* movd mm, ea */

#ifdef TARGET_X86_64

            if (s->dflag == MO_64) {

                gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);

                tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx));

            } else

#endif

            {

                gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);

                tcg_gen_addi_ptr(cpu_ptr0, cpu_env,

                                 offsetof(CPUX86State,fpregs[reg].mmx));

                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);

                gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32);

            }

            break;

        case 0x16e: /* movd xmm, ea */

#ifdef TARGET_X86_64

            if (s->dflag == MO_64) {

                gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0);

                tcg_gen_addi_ptr(cpu_ptr0, cpu_env,

                                 offsetof(CPUX86State,xmm_regs[reg]));

                gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T0);

            } else

#endif

            {

                gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0);

                tcg_gen_addi_ptr(cpu_ptr0, cpu_env,

                                 offsetof(CPUX86State,xmm_regs[reg]));

                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);

                gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32);

            }

            break;

        case 0x6f: /* movq mm, ea */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));

            } else {

                rm = (modrm & 7);

                tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,

                               offsetof(CPUX86State,fpregs[rm].mmx));

                tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,

                               offsetof(CPUX86State,fpregs[reg].mmx));

            }

            break;

        case 0x010: /* movups */

        case 0x110: /* movupd */

        case 0x028: /* movaps */

        case 0x128: /* movapd */

        case 0x16f: /* movdqa xmm, ea */

        case 0x26f: /* movdqu xmm, ea */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));

            } else {

                rm = (modrm & 7) | REX_B(s);

                gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]),

                            offsetof(CPUX86State,xmm_regs[rm]));

            }

            break;

        case 0x210: /* movss xmm, ea */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);

                tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));

                tcg_gen_movi_tl(cpu_T0, 0);

                tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));

                tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));

                tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));

            } else {

                rm = (modrm & 7) | REX_B(s);

                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),

                            offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));

            }

            break;

        case 0x310: /* movsd xmm, ea */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_ldq_env_A0(s, offsetof(CPUX86State,

                                           xmm_regs[reg].ZMM_Q(0)));

                tcg_gen_movi_tl(cpu_T0, 0);

                tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));

                tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));

            } else {

                rm = (modrm & 7) | REX_B(s);

                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),

                            offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));

            }

            break;

        case 0x012: /* movlps */

        case 0x112: /* movlpd */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_ldq_env_A0(s, offsetof(CPUX86State,

                                           xmm_regs[reg].ZMM_Q(0)));

            } else {

                /* movhlps */

                rm = (modrm & 7) | REX_B(s);

                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),

                            offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));

            }

            break;

        case 0x212: /* movsldup */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));

            } else {

                rm = (modrm & 7) | REX_B(s);

                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),

                            offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)));

                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),

                            offsetof(CPUX86State,xmm_regs[rm].ZMM_L(2)));

            }

            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),

                        offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));

            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),

                        offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)));

            break;

        case 0x312: /* movddup */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_ldq_env_A0(s, offsetof(CPUX86State,

                                           xmm_regs[reg].ZMM_Q(0)));

            } else {

                rm = (modrm & 7) | REX_B(s);

                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),

                            offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));

            }

            gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),

                        offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));

            break;

        case 0x016: /* movhps */

        case 0x116: /* movhpd */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_ldq_env_A0(s, offsetof(CPUX86State,

                                           xmm_regs[reg].ZMM_Q(1)));

            } else {

                /* movlhps */

                rm = (modrm & 7) | REX_B(s);

                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)),

                            offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));

            }

            break;

        case 0x216: /* movshdup */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));

            } else {

                rm = (modrm & 7) | REX_B(s);

                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)),

                            offsetof(CPUX86State,xmm_regs[rm].ZMM_L(1)));

                gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)),

                            offsetof(CPUX86State,xmm_regs[rm].ZMM_L(3)));

            }

            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)),

                        offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)));

            gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)),

                        offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)));

            break;

        case 0x178:

        case 0x378:

            {

                int bit_index, field_length;

                if (b1 == 1 && reg != 0)

                    goto illegal_op;

                field_length = cpu_ldub_code(env, s->pc++) & 0x3F;

                bit_index = cpu_ldub_code(env, s->pc++) & 0x3F;

                tcg_gen_addi_ptr(cpu_ptr0, cpu_env,

                    offsetof(CPUX86State,xmm_regs[reg]));

                if (b1 == 1)

                    gen_helper_extrq_i(cpu_env, cpu_ptr0,

                                       tcg_const_i32(bit_index),

                                       tcg_const_i32(field_length));

                else

                    gen_helper_insertq_i(cpu_env, cpu_ptr0,

                                         tcg_const_i32(bit_index),

                                         tcg_const_i32(field_length));

            }

            break;

        case 0x7e: /* movd ea, mm */

#ifdef TARGET_X86_64

            if (s->dflag == MO_64) {

                tcg_gen_ld_i64(cpu_T0, cpu_env,

                               offsetof(CPUX86State,fpregs[reg].mmx));

                gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);

            } else

#endif

            {

                tcg_gen_ld32u_tl(cpu_T0, cpu_env,

                                 offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0)));

                gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);

            }

            break;

        case 0x17e: /* movd ea, xmm */

#ifdef TARGET_X86_64

            if (s->dflag == MO_64) {

                tcg_gen_ld_i64(cpu_T0, cpu_env,

                               offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));

                gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1);

            } else

#endif

            {

                tcg_gen_ld32u_tl(cpu_T0, cpu_env,

                                 offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));

                gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1);

            }

            break;

        case 0x27e: /* movq xmm, ea */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_ldq_env_A0(s, offsetof(CPUX86State,

                                           xmm_regs[reg].ZMM_Q(0)));

            } else {

                rm = (modrm & 7) | REX_B(s);

                gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),

                            offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));

            }

            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));

            break;

        case 0x7f: /* movq ea, mm */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx));

            } else {

                rm = (modrm & 7);

                gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx),

                            offsetof(CPUX86State,fpregs[reg].mmx));

            }

            break;

        case 0x011: /* movups */

        case 0x111: /* movupd */

        case 0x029: /* movaps */

        case 0x129: /* movapd */

        case 0x17f: /* movdqa ea, xmm */

        case 0x27f: /* movdqu ea, xmm */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg]));

            } else {

                rm = (modrm & 7) | REX_B(s);

                gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]),

                            offsetof(CPUX86State,xmm_regs[reg]));

            }

            break;

        case 0x211: /* movss ea, xmm */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));

                gen_op_st_v(s, MO_32, cpu_T0, cpu_A0);

            } else {

                rm = (modrm & 7) | REX_B(s);

                gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)),

                            offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)));

            }

            break;

        case 0x311: /* movsd ea, xmm */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_stq_env_A0(s, offsetof(CPUX86State,

                                           xmm_regs[reg].ZMM_Q(0)));

            } else {

                rm = (modrm & 7) | REX_B(s);

                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),

                            offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));

            }

            break;

        case 0x013: /* movlps */

        case 0x113: /* movlpd */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_stq_env_A0(s, offsetof(CPUX86State,

                                           xmm_regs[reg].ZMM_Q(0)));

            } else {

                goto illegal_op;

            }

            break;

        case 0x017: /* movhps */

        case 0x117: /* movhpd */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_stq_env_A0(s, offsetof(CPUX86State,

                                           xmm_regs[reg].ZMM_Q(1)));

            } else {

                goto illegal_op;

            }

            break;

        case 0x71: /* shift mm, im */

        case 0x72:

        case 0x73:

        case 0x171: /* shift xmm, im */

        case 0x172:

        case 0x173:

            if (b1 >= 2) {

	        goto unknown_op;

            }

            val = cpu_ldub_code(env, s->pc++);

            if (is_xmm) {

                tcg_gen_movi_tl(cpu_T0, val);

                tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));

                tcg_gen_movi_tl(cpu_T0, 0);

                tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(1)));

                op1_offset = offsetof(CPUX86State,xmm_t0);

            } else {

                tcg_gen_movi_tl(cpu_T0, val);

                tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));

                tcg_gen_movi_tl(cpu_T0, 0);

                tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1)));

                op1_offset = offsetof(CPUX86State,mmx_t0);

            }

            sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +

                                       (((modrm >> 3)) & 7)][b1];

            if (!sse_fn_epp) {

                goto unknown_op;

            }

            if (is_xmm) {

                rm = (modrm & 7) | REX_B(s);

                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);

            } else {

                rm = (modrm & 7);

                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);

            }

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);

            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset);

            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);

            break;

        case 0x050: /* movmskps */

            rm = (modrm & 7) | REX_B(s);

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env,

                             offsetof(CPUX86State,xmm_regs[rm]));

            gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0);

            tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);

            break;

        case 0x150: /* movmskpd */

            rm = (modrm & 7) | REX_B(s);

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env,

                             offsetof(CPUX86State,xmm_regs[rm]));

            gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0);

            tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);

            break;

        case 0x02a: /* cvtpi2ps */

        case 0x12a: /* cvtpi2pd */

            gen_helper_enter_mmx(cpu_env);

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                op2_offset = offsetof(CPUX86State,mmx_t0);

                gen_ldq_env_A0(s, op2_offset);

            } else {

                rm = (modrm & 7);

                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);

            }

            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);

            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);

            switch(b >> 8) {

            case 0x0:

                gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1);

                break;

            default:

            case 0x1:

                gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1);

                break;

            }

            break;

        case 0x22a: /* cvtsi2ss */

        case 0x32a: /* cvtsi2sd */

            ot = mo_64_32(s->dflag);

            gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);

            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);

            if (ot == MO_32) {

                SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1];

                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);

                sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32);

            } else {

#ifdef TARGET_X86_64

                SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1];

                sse_fn_epl(cpu_env, cpu_ptr0, cpu_T0);

#else

                goto illegal_op;

#endif

            }

            break;

        case 0x02c: /* cvttps2pi */

        case 0x12c: /* cvttpd2pi */

        case 0x02d: /* cvtps2pi */

        case 0x12d: /* cvtpd2pi */

            gen_helper_enter_mmx(cpu_env);

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                op2_offset = offsetof(CPUX86State,xmm_t0);

                gen_ldo_env_A0(s, op2_offset);

            } else {

                rm = (modrm & 7) | REX_B(s);

                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);

            }

            op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx);

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);

            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);

            switch(b) {

            case 0x02c:

                gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1);

                break;

            case 0x12c:

                gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);

                break;

            case 0x02d:

                gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1);

                break;

            case 0x12d:

                gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1);

                break;

            }

            break;

        case 0x22c: /* cvttss2si */

        case 0x32c: /* cvttsd2si */

        case 0x22d: /* cvtss2si */

        case 0x32d: /* cvtsd2si */

            ot = mo_64_32(s->dflag);

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                if ((b >> 8) & 1) {

                    gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_Q(0)));

                } else {

                    gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);

                    tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0)));

                }

                op2_offset = offsetof(CPUX86State,xmm_t0);

            } else {

                rm = (modrm & 7) | REX_B(s);

                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);

            }

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset);

            if (ot == MO_32) {

                SSEFunc_i_ep sse_fn_i_ep =

                    sse_op_table3bi[((b >> 7) & 2) | (b & 1)];

                sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0);

                tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);

            } else {

#ifdef TARGET_X86_64

                SSEFunc_l_ep sse_fn_l_ep =

                    sse_op_table3bq[((b >> 7) & 2) | (b & 1)];

                sse_fn_l_ep(cpu_T0, cpu_env, cpu_ptr0);

#else

                goto illegal_op;

#endif

            }

            gen_op_mov_reg_v(ot, reg, cpu_T0);

            break;

        case 0xc4: /* pinsrw */

        case 0x1c4:

            s->rip_offset = 1;

            gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);

            val = cpu_ldub_code(env, s->pc++);

            if (b1) {

                val &= 7;

                tcg_gen_st16_tl(cpu_T0, cpu_env,

                                offsetof(CPUX86State,xmm_regs[reg].ZMM_W(val)));

            } else {

                val &= 3;

                tcg_gen_st16_tl(cpu_T0, cpu_env,

                                offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val)));

            }

            break;

        case 0xc5: /* pextrw */

        case 0x1c5:

            if (mod != 3)

                goto illegal_op;

            ot = mo_64_32(s->dflag);

            val = cpu_ldub_code(env, s->pc++);

            if (b1) {

                val &= 7;

                rm = (modrm & 7) | REX_B(s);

                tcg_gen_ld16u_tl(cpu_T0, cpu_env,

                                 offsetof(CPUX86State,xmm_regs[rm].ZMM_W(val)));

            } else {

                val &= 3;

                rm = (modrm & 7);

                tcg_gen_ld16u_tl(cpu_T0, cpu_env,

                                offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));

            }

            reg = ((modrm >> 3) & 7) | rex_r;

            gen_op_mov_reg_v(ot, reg, cpu_T0);

            break;

        case 0x1d6: /* movq ea, xmm */

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                gen_stq_env_A0(s, offsetof(CPUX86State,

                                           xmm_regs[reg].ZMM_Q(0)));

            } else {

                rm = (modrm & 7) | REX_B(s);

                gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)),

                            offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)));

                gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1)));

            }

            break;

        case 0x2d6: /* movq2dq */

            gen_helper_enter_mmx(cpu_env);

            rm = (modrm & 7);

            gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)),

                        offsetof(CPUX86State,fpregs[rm].mmx));

            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)));

            break;

        case 0x3d6: /* movdq2q */

            gen_helper_enter_mmx(cpu_env);

            rm = (modrm & 7) | REX_B(s);

            gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx),

                        offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)));

            break;

        case 0xd7: /* pmovmskb */

        case 0x1d7:

            if (mod != 3)

                goto illegal_op;

            if (b1) {

                rm = (modrm & 7) | REX_B(s);

                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm]));

                gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0);

            } else {

                rm = (modrm & 7);

                tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx));

                gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0);

            }

            reg = ((modrm >> 3) & 7) | rex_r;

            tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32);

            break;

        case 0x138:

        case 0x038:

            b = modrm;

            if ((b & 0xf0) == 0xf0) {

                goto do_0f_38_fx;

            }

            modrm = cpu_ldub_code(env, s->pc++);

            rm = modrm & 7;

            reg = ((modrm >> 3) & 7) | rex_r;

            mod = (modrm >> 6) & 3;

            if (b1 >= 2) {

                goto unknown_op;

            }

            sse_fn_epp = sse_op_table6[b].op[b1];

            if (!sse_fn_epp) {

                goto unknown_op;

            }

            if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask))

                goto illegal_op;

            if (b1) {

                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);

                if (mod == 3) {

                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);

                } else {

                    op2_offset = offsetof(CPUX86State,xmm_t0);

                    gen_lea_modrm(env, s, modrm);

                    switch (b) {

                    case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */

                    case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */

                    case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */

                        gen_ldq_env_A0(s, op2_offset +

                                        offsetof(ZMMReg, ZMM_Q(0)));

                        break;

                    case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */

                    case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */

                        tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,

                                            s->mem_index, MO_LEUL);

                        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +

                                        offsetof(ZMMReg, ZMM_L(0)));

                        break;

                    case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */

                        tcg_gen_qemu_ld_tl(cpu_tmp0, cpu_A0,

                                           s->mem_index, MO_LEUW);

                        tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +

                                        offsetof(ZMMReg, ZMM_W(0)));

                        break;

                    case 0x2a:            /* movntqda */

                        gen_ldo_env_A0(s, op1_offset);

                        return;

                    default:

                        gen_ldo_env_A0(s, op2_offset);

                    }

                }

            } else {

                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);

                if (mod == 3) {

                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);

                } else {

                    op2_offset = offsetof(CPUX86State,mmx_t0);

                    gen_lea_modrm(env, s, modrm);

                    gen_ldq_env_A0(s, op2_offset);

                }

            }

            if (sse_fn_epp == SSE_SPECIAL) {

                goto unknown_op;

            }

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);

            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);

            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);

            if (b == 0x17) {

                set_cc_op(s, CC_OP_EFLAGS);

            }

            break;

        case 0x238:

        case 0x338:

        do_0f_38_fx:

            /* Various integer extensions at 0f 38 f[0-f].  */

            b = modrm | (b1 << 8);

            modrm = cpu_ldub_code(env, s->pc++);

            reg = ((modrm >> 3) & 7) | rex_r;

            switch (b) {

            case 0x3f0: /* crc32 Gd,Eb */

            case 0x3f1: /* crc32 Gd,Ey */

            do_crc32:

                if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) {

                    goto illegal_op;

                }

                if ((b & 0xff) == 0xf0) {

                    ot = MO_8;

                } else if (s->dflag != MO_64) {

                    ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);

                } else {

                    ot = MO_64;

                }

                tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[reg]);

                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);

                gen_helper_crc32(cpu_T0, cpu_tmp2_i32,

                                 cpu_T0, tcg_const_i32(8 << ot));

                ot = mo_64_32(s->dflag);

                gen_op_mov_reg_v(ot, reg, cpu_T0);

                break;

            case 0x1f0: /* crc32 or movbe */

            case 0x1f1:

                /* For these insns, the f3 prefix is supposed to have priority

                   over the 66 prefix, but that's not what we implement above

                   setting b1.  */

                if (s->prefix & PREFIX_REPNZ) {

                    goto do_crc32;

                }

                /* FALLTHRU */

            case 0x0f0: /* movbe Gy,My */

            case 0x0f1: /* movbe My,Gy */

                if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) {

                    goto illegal_op;

                }

                if (s->dflag != MO_64) {

                    ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32);

                } else {

                    ot = MO_64;

                }

                gen_lea_modrm(env, s, modrm);

                if ((b & 1) == 0) {

                    tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,

                                       s->mem_index, ot | MO_BE);

                    gen_op_mov_reg_v(ot, reg, cpu_T0);

                } else {

                    tcg_gen_qemu_st_tl(cpu_regs[reg], cpu_A0,

                                       s->mem_index, ot | MO_BE);

                }

                break;

            case 0x0f2: /* andn Gy, By, Ey */

                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)

                    || !(s->prefix & PREFIX_VEX)

                    || s->vex_l != 0) {

                    goto illegal_op;

                }

                ot = mo_64_32(s->dflag);

                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);

                tcg_gen_andc_tl(cpu_T0, cpu_regs[s->vex_v], cpu_T0);

                gen_op_mov_reg_v(ot, reg, cpu_T0);

                gen_op_update1_cc();

                set_cc_op(s, CC_OP_LOGICB + ot);

                break;

            case 0x0f7: /* bextr Gy, Ey, By */

                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)

                    || !(s->prefix & PREFIX_VEX)

                    || s->vex_l != 0) {

                    goto illegal_op;

                }

                ot = mo_64_32(s->dflag);

                {

                    TCGv bound, zero;

                    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);

                    /* Extract START, and shift the operand.

                       Shifts larger than operand size get zeros.  */

                    tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]);

                    tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_A0);

                    bound = tcg_const_tl(ot == MO_64 ? 63 : 31);

                    zero = tcg_const_tl(0);

                    tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T0, cpu_A0, bound,

                                       cpu_T0, zero);

                    tcg_temp_free(zero);

                    /* Extract the LEN into a mask.  Lengths larger than

                       operand size get all ones.  */

                    tcg_gen_extract_tl(cpu_A0, cpu_regs[s->vex_v], 8, 8);

                    tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound,

                                       cpu_A0, bound);

                    tcg_temp_free(bound);

                    tcg_gen_movi_tl(cpu_T1, 1);

                    tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_A0);

                    tcg_gen_subi_tl(cpu_T1, cpu_T1, 1);

                    tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);

                    gen_op_mov_reg_v(ot, reg, cpu_T0);

                    gen_op_update1_cc();

                    set_cc_op(s, CC_OP_LOGICB + ot);

                }

                break;

            case 0x0f5: /* bzhi Gy, Ey, By */

                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)

                    || !(s->prefix & PREFIX_VEX)

                    || s->vex_l != 0) {

                    goto illegal_op;

                }

                ot = mo_64_32(s->dflag);

                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);

                tcg_gen_ext8u_tl(cpu_T1, cpu_regs[s->vex_v]);

                {

                    TCGv bound = tcg_const_tl(ot == MO_64 ? 63 : 31);

                    /* 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_LT, cpu_cc_src,

                                       cpu_T1, bound);

                    tcg_gen_movcond_tl(TCG_COND_GT, cpu_T1, cpu_T1,

                                       bound, bound, cpu_T1);

                    tcg_temp_free(bound);

                }

                tcg_gen_movi_tl(cpu_A0, -1);

                tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T1);

                tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_A0);

                gen_op_mov_reg_v(ot, reg, cpu_T0);

                gen_op_update1_cc();

                set_cc_op(s, CC_OP_BMILGB + ot);

                break;

            case 0x3f6: /* mulx By, Gy, rdx, Ey */

                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)

                    || !(s->prefix & PREFIX_VEX)

                    || s->vex_l != 0) {

                    goto illegal_op;

                }

                ot = mo_64_32(s->dflag);

                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);

                switch (ot) {

                default:

                    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);

                    tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EDX]);

                    tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,

                                      cpu_tmp2_i32, cpu_tmp3_i32);

                    tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], cpu_tmp2_i32);

                    tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp3_i32);

                    break;

#ifdef TARGET_X86_64

                case MO_64:

                    tcg_gen_mulu2_i64(cpu_T0, cpu_T1,

                                      cpu_T0, cpu_regs[R_EDX]);

                    tcg_gen_mov_i64(cpu_regs[s->vex_v], cpu_T0);

                    tcg_gen_mov_i64(cpu_regs[reg], cpu_T1);

                    break;

#endif

                }

                break;

            case 0x3f5: /* pdep Gy, By, Ey */

                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)

                    || !(s->prefix & PREFIX_VEX)

                    || s->vex_l != 0) {

                    goto illegal_op;

                }

                ot = mo_64_32(s->dflag);

                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);

                /* Note that by zero-extending the mask operand, we

                   automatically handle zero-extending the result.  */

                if (ot == MO_64) {

                    tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);

                } else {

                    tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);

                }

                gen_helper_pdep(cpu_regs[reg], cpu_T0, cpu_T1);

                break;

            case 0x2f5: /* pext Gy, By, Ey */

                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)

                    || !(s->prefix & PREFIX_VEX)

                    || s->vex_l != 0) {

                    goto illegal_op;

                }

                ot = mo_64_32(s->dflag);

                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);

                /* Note that by zero-extending the mask operand, we

                   automatically handle zero-extending the result.  */

                if (ot == MO_64) {

                    tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]);

                } else {

                    tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]);

                }

                gen_helper_pext(cpu_regs[reg], cpu_T0, cpu_T1);

                break;

            case 0x1f6: /* adcx Gy, Ey */

            case 0x2f6: /* adox Gy, Ey */

                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) {

                    goto illegal_op;

                } else {

                    TCGv carry_in, carry_out, zero;

                    int end_op;

                    ot = mo_64_32(s->dflag);

                    gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);

                    /* Re-use the carry-out from a previous round.  */

                    TCGV_UNUSED(carry_in);

                    carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2);

                    switch (s->cc_op) {

                    case CC_OP_ADCX:

                        if (b == 0x1f6) {

                            carry_in = cpu_cc_dst;

                            end_op = CC_OP_ADCX;

                        } else {

                            end_op = CC_OP_ADCOX;

                        }

                        break;

                    case CC_OP_ADOX:

                        if (b == 0x1f6) {

                            end_op = CC_OP_ADCOX;

                        } else {

                            carry_in = cpu_cc_src2;

                            end_op = CC_OP_ADOX;

                        }

                        break;

                    case CC_OP_ADCOX:

                        end_op = CC_OP_ADCOX;

                        carry_in = carry_out;

                        break;

                    default:

                        end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX);

                        break;

                    }

                    /* If we can't reuse carry-out, get it out of EFLAGS.  */

                    if (TCGV_IS_UNUSED(carry_in)) {

                        if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) {

                            gen_compute_eflags(s);

                        }

                        carry_in = cpu_tmp0;

                        tcg_gen_extract_tl(carry_in, cpu_cc_src,

                                           ctz32(b == 0x1f6 ? CC_C : CC_O), 1);

                    }

                    switch (ot) {

#ifdef TARGET_X86_64

                    case MO_32:

                        /* If we know TL is 64-bit, and we want a 32-bit

                           result, just do everything in 64-bit arithmetic.  */

                        tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]);

                        tcg_gen_ext32u_i64(cpu_T0, cpu_T0);

                        tcg_gen_add_i64(cpu_T0, cpu_T0, cpu_regs[reg]);

                        tcg_gen_add_i64(cpu_T0, cpu_T0, carry_in);

                        tcg_gen_ext32u_i64(cpu_regs[reg], cpu_T0);

                        tcg_gen_shri_i64(carry_out, cpu_T0, 32);

                        break;

#endif

                    default:

                        /* Otherwise compute the carry-out in two steps.  */

                        zero = tcg_const_tl(0);

                        tcg_gen_add2_tl(cpu_T0, carry_out,

                                        cpu_T0, zero,

                                        carry_in, zero);

                        tcg_gen_add2_tl(cpu_regs[reg], carry_out,

                                        cpu_regs[reg], carry_out,

                                        cpu_T0, zero);

                        tcg_temp_free(zero);

                        break;

                    }

                    set_cc_op(s, end_op);

                }

                break;

            case 0x1f7: /* shlx Gy, Ey, By */

            case 0x2f7: /* sarx Gy, Ey, By */

            case 0x3f7: /* shrx Gy, Ey, By */

                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)

                    || !(s->prefix & PREFIX_VEX)

                    || s->vex_l != 0) {

                    goto illegal_op;

                }

                ot = mo_64_32(s->dflag);

                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);

                if (ot == MO_64) {

                    tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 63);

                } else {

                    tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 31);

                }

                if (b == 0x1f7) {

                    tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1);

                } else if (b == 0x2f7) {

                    if (ot != MO_64) {

                        tcg_gen_ext32s_tl(cpu_T0, cpu_T0);

                    }

                    tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1);

                } else {

                    if (ot != MO_64) {

                        tcg_gen_ext32u_tl(cpu_T0, cpu_T0);

                    }

                    tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1);

                }

                gen_op_mov_reg_v(ot, reg, cpu_T0);

                break;

            case 0x0f3:

            case 0x1f3:

            case 0x2f3:

            case 0x3f3: /* Group 17 */

                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1)

                    || !(s->prefix & PREFIX_VEX)

                    || s->vex_l != 0) {

                    goto illegal_op;

                }

                ot = mo_64_32(s->dflag);

                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);

                switch (reg & 7) {

                case 1: /* blsr By,Ey */

                    tcg_gen_neg_tl(cpu_T1, cpu_T0);

                    tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);

                    gen_op_mov_reg_v(ot, s->vex_v, cpu_T0);

                    gen_op_update2_cc();

                    set_cc_op(s, CC_OP_BMILGB + ot);

                    break;

                case 2: /* blsmsk By,Ey */

                    tcg_gen_mov_tl(cpu_cc_src, cpu_T0);

                    tcg_gen_subi_tl(cpu_T0, cpu_T0, 1);

                    tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_cc_src);

                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);

                    set_cc_op(s, CC_OP_BMILGB + ot);

                    break;

                case 3: /* blsi By, Ey */

                    tcg_gen_mov_tl(cpu_cc_src, cpu_T0);

                    tcg_gen_subi_tl(cpu_T0, cpu_T0, 1);

                    tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_cc_src);

                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);

                    set_cc_op(s, CC_OP_BMILGB + ot);

                    break;

                default:

                    goto unknown_op;

                }

                break;

            default:

                goto unknown_op;

            }

            break;

        case 0x03a:

        case 0x13a:

            b = modrm;

            modrm = cpu_ldub_code(env, s->pc++);

            rm = modrm & 7;

            reg = ((modrm >> 3) & 7) | rex_r;

            mod = (modrm >> 6) & 3;

            if (b1 >= 2) {

                goto unknown_op;

            }

            sse_fn_eppi = sse_op_table7[b].op[b1];

            if (!sse_fn_eppi) {

                goto unknown_op;

            }

            if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask))

                goto illegal_op;

            s->rip_offset = 1;

            if (sse_fn_eppi == SSE_SPECIAL) {

                ot = mo_64_32(s->dflag);

                rm = (modrm & 7) | REX_B(s);

                if (mod != 3)

                    gen_lea_modrm(env, s, modrm);

                reg = ((modrm >> 3) & 7) | rex_r;

                val = cpu_ldub_code(env, s->pc++);

                switch (b) {

                case 0x14: /* pextrb */

                    tcg_gen_ld8u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,

                                            xmm_regs[reg].ZMM_B(val & 15)));

                    if (mod == 3) {

                        gen_op_mov_reg_v(ot, rm, cpu_T0);

                    } else {

                        tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,

                                           s->mem_index, MO_UB);

                    }

                    break;

                case 0x15: /* pextrw */

                    tcg_gen_ld16u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,

                                            xmm_regs[reg].ZMM_W(val & 7)));

                    if (mod == 3) {

                        gen_op_mov_reg_v(ot, rm, cpu_T0);

                    } else {

                        tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,

                                           s->mem_index, MO_LEUW);

                    }

                    break;

                case 0x16:

                    if (ot == MO_32) { /* pextrd */

                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,

                                        offsetof(CPUX86State,

                                                xmm_regs[reg].ZMM_L(val & 3)));

                        if (mod == 3) {

                            tcg_gen_extu_i32_tl(cpu_regs[rm], cpu_tmp2_i32);

                        } else {

                            tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,

                                                s->mem_index, MO_LEUL);

                        }

                    } else { /* pextrq */

#ifdef TARGET_X86_64

                        tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env,

                                        offsetof(CPUX86State,

                                                xmm_regs[reg].ZMM_Q(val & 1)));

                        if (mod == 3) {

                            tcg_gen_mov_i64(cpu_regs[rm], cpu_tmp1_i64);

                        } else {

                            tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,

                                                s->mem_index, MO_LEQ);

                        }

#else

                        goto illegal_op;

#endif

                    }

                    break;

                case 0x17: /* extractps */

                    tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,

                                            xmm_regs[reg].ZMM_L(val & 3)));

                    if (mod == 3) {

                        gen_op_mov_reg_v(ot, rm, cpu_T0);

                    } else {

                        tcg_gen_qemu_st_tl(cpu_T0, cpu_A0,

                                           s->mem_index, MO_LEUL);

                    }

                    break;

                case 0x20: /* pinsrb */

                    if (mod == 3) {

                        gen_op_mov_v_reg(MO_32, cpu_T0, rm);

                    } else {

                        tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0,

                                           s->mem_index, MO_UB);

                    }

                    tcg_gen_st8_tl(cpu_T0, cpu_env, offsetof(CPUX86State,

                                            xmm_regs[reg].ZMM_B(val & 15)));

                    break;

                case 0x21: /* insertps */

                    if (mod == 3) {

                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,

                                        offsetof(CPUX86State,xmm_regs[rm]

                                                .ZMM_L((val >> 6) & 3)));

                    } else {

                        tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,

                                            s->mem_index, MO_LEUL);

                    }

                    tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,

                                    offsetof(CPUX86State,xmm_regs[reg]

                                            .ZMM_L((val >> 4) & 3)));

                    if ((val >> 0) & 1)

                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),

                                        cpu_env, offsetof(CPUX86State,

                                                xmm_regs[reg].ZMM_L(0)));

                    if ((val >> 1) & 1)

                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),

                                        cpu_env, offsetof(CPUX86State,

                                                xmm_regs[reg].ZMM_L(1)));

                    if ((val >> 2) & 1)

                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),

                                        cpu_env, offsetof(CPUX86State,

                                                xmm_regs[reg].ZMM_L(2)));

                    if ((val >> 3) & 1)

                        tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/),

                                        cpu_env, offsetof(CPUX86State,

                                                xmm_regs[reg].ZMM_L(3)));

                    break;

                case 0x22:

                    if (ot == MO_32) { /* pinsrd */

                        if (mod == 3) {

                            tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[rm]);

                        } else {

                            tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,

                                                s->mem_index, MO_LEUL);

                        }

                        tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,

                                        offsetof(CPUX86State,

                                                xmm_regs[reg].ZMM_L(val & 3)));

                    } else { /* pinsrq */

#ifdef TARGET_X86_64

                        if (mod == 3) {

                            gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);

                        } else {

                            tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,

                                                s->mem_index, MO_LEQ);

                        }

                        tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,

                                        offsetof(CPUX86State,

                                                xmm_regs[reg].ZMM_Q(val & 1)));

#else

                        goto illegal_op;

#endif

                    }

                    break;

                }

                return;

            }

            if (b1) {

                op1_offset = offsetof(CPUX86State,xmm_regs[reg]);

                if (mod == 3) {

                    op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]);

                } else {

                    op2_offset = offsetof(CPUX86State,xmm_t0);

                    gen_lea_modrm(env, s, modrm);

                    gen_ldo_env_A0(s, op2_offset);

                }

            } else {

                op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);

                if (mod == 3) {

                    op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);

                } else {

                    op2_offset = offsetof(CPUX86State,mmx_t0);

                    gen_lea_modrm(env, s, modrm);

                    gen_ldq_env_A0(s, op2_offset);

                }

            }

            val = cpu_ldub_code(env, s->pc++);

            if ((b & 0xfc) == 0x60) { /* pcmpXstrX */

                set_cc_op(s, CC_OP_EFLAGS);

                if (s->dflag == MO_64) {

                    /* The helper must use entire 64-bit gp registers */

                    val |= 1 << 8;

                }

            }

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);

            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);

            sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val));

            break;

        case 0x33a:

            /* Various integer extensions at 0f 3a f[0-f].  */

            b = modrm | (b1 << 8);

            modrm = cpu_ldub_code(env, s->pc++);

            reg = ((modrm >> 3) & 7) | rex_r;

            switch (b) {

            case 0x3f0: /* rorx Gy,Ey, Ib */

                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2)

                    || !(s->prefix & PREFIX_VEX)

                    || s->vex_l != 0) {

                    goto illegal_op;

                }

                ot = mo_64_32(s->dflag);

                gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);

                b = cpu_ldub_code(env, s->pc++);

                if (ot == MO_64) {

                    tcg_gen_rotri_tl(cpu_T0, cpu_T0, b & 63);

                } else {

                    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);

                    tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31);

                    tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32);

                }

                gen_op_mov_reg_v(ot, reg, cpu_T0);

                break;

            default:

                goto unknown_op;

            }

            break;

        default:

        unknown_op:

            gen_unknown_opcode(env, s);

            return;

        }

    } else {

        /* generic MMX or SSE operation */

        switch(b) {

        case 0x70: /* pshufx insn */

        case 0xc6: /* pshufx insn */

        case 0xc2: /* compare insns */

            s->rip_offset = 1;

            break;

        default:

            break;

        }

        if (is_xmm) {

            op1_offset = offsetof(CPUX86State,xmm_regs[reg]);

            if (mod != 3) {

                int sz = 4;

                gen_lea_modrm(env, s, modrm);

                op2_offset = offsetof(CPUX86State,xmm_t0);

                switch (b) {

                case 0x50 ... 0x5a:

                case 0x5c ... 0x5f:

                case 0xc2:

                    /* Most sse scalar operations.  */

                    if (b1 == 2) {

                        sz = 2;

                    } else if (b1 == 3) {

                        sz = 3;

                    }

                    break;

                case 0x2e:  /* ucomis[sd] */

                case 0x2f:  /* comis[sd] */

                    if (b1 == 0) {

                        sz = 2;

                    } else {

                        sz = 3;

                    }

                    break;

                }

                switch (sz) {

                case 2:

                    /* 32 bit access */

                    gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0);

                    tcg_gen_st32_tl(cpu_T0, cpu_env,

                                    offsetof(CPUX86State,xmm_t0.ZMM_L(0)));

                    break;

                case 3:

                    /* 64 bit access */

                    gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0)));

                    break;

                default:

                    /* 128 bit access */

                    gen_ldo_env_A0(s, op2_offset);

                    break;

                }

            } else {

                rm = (modrm & 7) | REX_B(s);

                op2_offset = offsetof(CPUX86State,xmm_regs[rm]);

            }

        } else {

            op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);

            if (mod != 3) {

                gen_lea_modrm(env, s, modrm);

                op2_offset = offsetof(CPUX86State,mmx_t0);

                gen_ldq_env_A0(s, op2_offset);

            } else {

                rm = (modrm & 7);

                op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);

            }

        }

        switch(b) {

        case 0x0f: /* 3DNow! data insns */

            val = cpu_ldub_code(env, s->pc++);

            sse_fn_epp = sse_op_table5[val];

            if (!sse_fn_epp) {

                goto unknown_op;

            }

            if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {

                goto illegal_op;

            }

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);

            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);

            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);

            break;

        case 0x70: /* pshufx insn */

        case 0xc6: /* pshufx insn */

            val = cpu_ldub_code(env, s->pc++);

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);

            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);

            /* XXX: introduce a new table? */

            sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp;

            sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val));

            break;

        case 0xc2:

            /* compare insns */

            val = cpu_ldub_code(env, s->pc++);

            if (val >= 8)

                goto unknown_op;

            sse_fn_epp = sse_op_table4[val][b1];

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);

            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);

            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);

            break;

        case 0xf7:

            /* maskmov : we must prepare A0 */

            if (mod != 3)

                goto illegal_op;

            tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EDI]);

            gen_extu(s->aflag, cpu_A0);

            gen_add_A0_ds_seg(s);

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);

            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);

            /* XXX: introduce a new table? */

            sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp;

            sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0);

            break;

        default:

            tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset);

            tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset);

            sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1);

            break;

        }

        if (b == 0x2e || b == 0x2f) {

            set_cc_op(s, CC_OP_EFLAGS);

        }

    }

}


void kvmppc_check_papr_resize_hpt(Error **errp)

{

    if (!kvm_enabled()) {

        return;

    }

    /* TODO: Check for resize-capable KVM implementations */

    error_setg(errp,

               "Hash page table resizing not available with this KVM version");

}


static void v9fs_walk(void *opaque)

{

    int name_idx;

    V9fsQID *qids = NULL;

    int i, err = 0;

    V9fsPath dpath, path;

    uint16_t nwnames;

    struct stat stbuf;

    size_t offset = 7;

    int32_t fid, newfid;

    V9fsString *wnames = NULL;

    V9fsFidState *fidp;

    V9fsFidState *newfidp = NULL;

    V9fsPDU *pdu = opaque;

    V9fsState *s = pdu->s;

    offset += pdu_unmarshal(pdu, offset, "ddw", &fid,

                            &newfid, &nwnames);

    trace_v9fs_walk(pdu->tag, pdu->id, fid, newfid, nwnames);

    if (nwnames && nwnames <= P9_MAXWELEM) {

        wnames = g_malloc0(sizeof(wnames[0]) * nwnames);

        qids   = g_malloc0(sizeof(qids[0]) * nwnames);

        for (i = 0; i < nwnames; i++) {

            offset += pdu_unmarshal(pdu, offset, "s", &wnames[i]);

        }

    } else if (nwnames > P9_MAXWELEM) {

        err = -EINVAL;

        goto out_nofid;

    }

    fidp = get_fid(pdu, fid);

    if (fidp == NULL) {

        err = -ENOENT;

        goto out_nofid;

    }

    v9fs_path_init(&dpath);

    v9fs_path_init(&path);

    /*

     * Both dpath and path initially poin to fidp.

     * Needed to handle request with nwnames == 0

     */

    v9fs_path_copy(&dpath, &fidp->path);

    v9fs_path_copy(&path, &fidp->path);

    for (name_idx = 0; name_idx < nwnames; name_idx++) {

        err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data, &path);

        if (err < 0) {

            goto out;

        }

        err = v9fs_co_lstat(pdu, &path, &stbuf);

        if (err < 0) {

            goto out;

        }

        stat_to_qid(&stbuf, &qids[name_idx]);

        v9fs_path_copy(&dpath, &path);

    }

    if (fid == newfid) {

        BUG_ON(fidp->fid_type != P9_FID_NONE);

        v9fs_path_copy(&fidp->path, &path);

    } else {

        newfidp = alloc_fid(s, newfid);

        if (newfidp == NULL) {

            err = -EINVAL;

            goto out;

        }

        newfidp->uid = fidp->uid;

        v9fs_path_copy(&newfidp->path, &path);

    }

    err = v9fs_walk_marshal(pdu, nwnames, qids);

    trace_v9fs_walk_return(pdu->tag, pdu->id, nwnames, qids);

out:

    put_fid(pdu, fidp);

    if (newfidp) {

        put_fid(pdu, newfidp);

    }

    v9fs_path_free(&dpath);

    v9fs_path_free(&path);

out_nofid:

    complete_pdu(s, pdu, err);

    if (nwnames && nwnames <= P9_MAXWELEM) {

        for (name_idx = 0; name_idx < nwnames; name_idx++) {

            v9fs_string_free(&wnames[name_idx]);

        }

        g_free(wnames);

        g_free(qids);

    }

    return;

}


static int mmu_translate_pte(CPUS390XState *env, target_ulong vaddr,

                             uint64_t asc, uint64_t pt_entry,

                             target_ulong *raddr, int *flags, int rw, bool exc)

{

    if (pt_entry & _PAGE_INVALID) {

        DPRINTF("%s: PTE=0x%" PRIx64 " invalid\n", __func__, pt_entry);

        trigger_page_fault(env, vaddr, PGM_PAGE_TRANS, asc, rw, exc);

        return -1;

    }

    if (pt_entry & _PAGE_RO) {

        *flags &= ~PAGE_WRITE;

    }

    *raddr = pt_entry & _ASCE_ORIGIN;

    PTE_DPRINTF("%s: PTE=0x%" PRIx64 "\n", __func__, pt_entry);

    return 0;

}


static void dbdma_cmdptr_load(DBDMA_channel *ch)

{

    DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n",

                  be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]));

    cpu_physical_memory_read(be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]),

                             (uint8_t*)&ch->current, sizeof(dbdma_cmd));

}


static int img_check(int argc, char **argv)

{

    int c, ret;

    const char *filename, *fmt;

    BlockDriverState *bs;

    BdrvCheckResult result;

    int fix = 0;

    int flags = BDRV_O_FLAGS;

    fmt = NULL;

    for(;;) {

        c = getopt(argc, argv, "f:hr:");

        if (c == -1) {

            break;

        }

        switch(c) {

        case '?':

        case 'h':

            help();

            break;

        case 'f':

            fmt = optarg;

            break;

        case 'r':

            flags |= BDRV_O_RDWR;

            if (!strcmp(optarg, "leaks")) {

                fix = BDRV_FIX_LEAKS;

            } else if (!strcmp(optarg, "all")) {

                fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;

            } else {

                help();

            }

            break;

        }

    }

    if (optind >= argc) {

        help();

    }

    filename = argv[optind++];

    bs = bdrv_new_open(filename, fmt, flags);

    if (!bs) {

        return 1;

    }

    ret = bdrv_check(bs, &result, fix);

    if (ret == -ENOTSUP) {

        error_report("This image format does not support checks");

        bdrv_delete(bs);

        return 1;

    }

    if (result.corruptions_fixed || result.leaks_fixed) {

        printf("The following inconsistencies were found and repaired:\n\n"

               "    %d leaked clusters\n"

               "    %d corruptions\n\n"

               "Double checking the fixed image now...\n",

               result.leaks_fixed,

               result.corruptions_fixed);

        ret = bdrv_check(bs, &result, 0);

    }

    if (!(result.corruptions || result.leaks || result.check_errors)) {

        printf("No errors were found on the image.\n");

    } else {

        if (result.corruptions) {

            printf("\n%d errors were found on the image.\n"

                "Data may be corrupted, or further writes to the image "

                "may corrupt it.\n",

                result.corruptions);

        }

        if (result.leaks) {

            printf("\n%d leaked clusters were found on the image.\n"

                "This means waste of disk space, but no harm to data.\n",

                result.leaks);

        }

        if (result.check_errors) {

            printf("\n%d internal errors have occurred during the check.\n",

                result.check_errors);

        }

    }

    if (result.bfi.total_clusters != 0 && result.bfi.allocated_clusters != 0) {

        printf("%" PRId64 "/%" PRId64 "= %0.2f%% allocated, %0.2f%% fragmented\n",

        result.bfi.allocated_clusters, result.bfi.total_clusters,

        result.bfi.allocated_clusters * 100.0 / result.bfi.total_clusters,

        result.bfi.fragmented_clusters * 100.0 / result.bfi.allocated_clusters);

    }

    bdrv_delete(bs);

    if (ret < 0 || result.check_errors) {

        printf("\nAn error has occurred during the check: %s\n"

            "The check is not complete and may have missed error.\n",

            strerror(-ret));

        return 1;

    }

    if (result.corruptions) {

        return 2;

    } else if (result.leaks) {

        return 3;

    } else {

        return 0;

    }

}


static void decode_profile_tier_level(GetBitContext *gb, AVCodecContext *avctx,

                                      PTLCommon *ptl)

{

    int i;

    ptl->profile_space = get_bits(gb, 2);

    ptl->tier_flag     = get_bits1(gb);

    ptl->profile_idc   = get_bits(gb, 5);

    if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN)

        av_log(avctx, AV_LOG_DEBUG, "Main profile bitstream\n");

    else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_10)

        av_log(avctx, AV_LOG_DEBUG, "Main 10 profile bitstream\n");

    else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_STILL_PICTURE)

        av_log(avctx, AV_LOG_DEBUG, "Main Still Picture profile bitstream\n");

    else

        av_log(avctx, AV_LOG_WARNING, "Unknown HEVC profile: %d\n", ptl->profile_idc);

    for (i = 0; i < 32; i++)

        ptl->profile_compatibility_flag[i] = get_bits1(gb);

    ptl->progressive_source_flag    = get_bits1(gb);

    ptl->interlaced_source_flag     = get_bits1(gb);

    ptl->non_packed_constraint_flag = get_bits1(gb);

    ptl->frame_only_constraint_flag = get_bits1(gb);

    skip_bits(gb, 16); // XXX_reserved_zero_44bits[0..15]

    skip_bits(gb, 16); // XXX_reserved_zero_44bits[16..31]

    skip_bits(gb, 12); // XXX_reserved_zero_44bits[32..43]

}


xen_igd_passthrough_isa_bridge_create(XenPCIPassthroughState *s,

                                      XenHostPCIDevice *dev)

{

    uint16_t gpu_dev_id;

    PCIDevice *d = &s->dev;

    gpu_dev_id = dev->device_id;

    igd_passthrough_isa_bridge_create(d->bus, gpu_dev_id);

}


qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num,

                            enum xics_irq_type type)

{

    uint32_t irq;

    qemu_irq qirq;

    if (hint) {

        irq = hint;

        /* FIXME: we should probably check for collisions somehow */

    } else {

        irq = spapr->next_irq++;

    }

    qirq = xics_assign_irq(spapr->icp, irq, type);

    if (!qirq) {

        return NULL;

    }

    if (irq_num) {

        *irq_num = irq;

    }

    return qirq;

}


static void omap_mcbsp_write(void *opaque, target_phys_addr_t addr,

                             uint64_t value, unsigned size)

{

    switch (size) {

    case 2: return omap_mcbsp_writeh(opaque, addr, value);

    case 4: return omap_mcbsp_writew(opaque, addr, value);

    default: return omap_badwidth_write16(opaque, addr, value);

    }

}


vnc_display_setup_auth(VncDisplay *vs,

                       bool password,

                       bool sasl,

                       bool tls,

                       bool x509)

{

    /*

     * We have a choice of 3 authentication options

     *

     *   1. none

     *   2. vnc

     *   3. sasl

     *

     * The channel can be run in 2 modes

     *

     *   1. clear

     *   2. tls

     *

     * And TLS can use 2 types of credentials

     *

     *   1. anon

     *   2. x509

     *

     * We thus have 9 possible logical combinations

     *

     *   1. clear + none

     *   2. clear + vnc

     *   3. clear + sasl

     *   4. tls + anon + none

     *   5. tls + anon + vnc

     *   6. tls + anon + sasl

     *   7. tls + x509 + none

     *   8. tls + x509 + vnc

     *   9. tls + x509 + sasl

     *

     * These need to be mapped into the VNC auth schemes

     * in an appropriate manner. In regular VNC, all the

     * TLS options get mapped into VNC_AUTH_VENCRYPT

     * sub-auth types.

     */

    if (password) {

        if (tls) {

            vs->auth = VNC_AUTH_VENCRYPT;

            if (x509) {

                VNC_DEBUG("Initializing VNC server with x509 password auth\n");

                vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;

            } else {

                VNC_DEBUG("Initializing VNC server with TLS password auth\n");

                vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;

            }

        } else {

            VNC_DEBUG("Initializing VNC server with password auth\n");

            vs->auth = VNC_AUTH_VNC;

            vs->subauth = VNC_AUTH_INVALID;

        }

    } else if (sasl) {

        if (tls) {

            vs->auth = VNC_AUTH_VENCRYPT;

            if (x509) {

                VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");

                vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;

            } else {

                VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");

                vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;

            }

        } else {

            VNC_DEBUG("Initializing VNC server with SASL auth\n");

            vs->auth = VNC_AUTH_SASL;

            vs->subauth = VNC_AUTH_INVALID;

        }

    } else {

        if (tls) {

            vs->auth = VNC_AUTH_VENCRYPT;

            if (x509) {

                VNC_DEBUG("Initializing VNC server with x509 no auth\n");

                vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;

            } else {

                VNC_DEBUG("Initializing VNC server with TLS no auth\n");

                vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;

            }

        } else {

            VNC_DEBUG("Initializing VNC server with no auth\n");

            vs->auth = VNC_AUTH_NONE;

            vs->subauth = VNC_AUTH_INVALID;

        }

    }

}


void usb_info(Monitor *mon)

{

    USBBus *bus;

    USBDevice *dev;

    USBPort *port;

    if (TAILQ_EMPTY(&busses)) {

        monitor_printf(mon, "USB support not enabled\n");

        return;

    }

    TAILQ_FOREACH(bus, &busses, next) {

        TAILQ_FOREACH(port, &bus->used, next) {

            dev = port->dev;

            if (!dev)

                continue;

            monitor_printf(mon, "  Device %d.%d, Speed %s Mb/s, Product %s\n",

                           bus->busnr, dev->addr, usb_speed(dev->speed), dev->devname);

        }

    }

}


void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, int label)

{

    if (cond == TCG_COND_ALWAYS) {

        tcg_gen_br(label);

    } else if (cond != TCG_COND_NEVER) {

        if (TCG_TARGET_REG_BITS == 32) {

            tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1),

                              TCGV_HIGH(arg1), TCGV_LOW(arg2),

                              TCGV_HIGH(arg2), cond, label);

        } else {

            tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond, label);

        }

    }

}


static QList *channel_list_get(void)

{

    return NULL;

}


static int ssd0323_init(SSISlave *dev)

{

    ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev);

    s->col_end = 63;

    s->row_end = 79;

    s->con = graphic_console_init(ssd0323_update_display,

                                  ssd0323_invalidate_display,

                                  NULL, NULL, s);

    qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);

    qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);

    register_savevm(&dev->qdev, "ssd0323_oled", -1, 1,

                    ssd0323_save, ssd0323_load, s);

    return 0;

}


static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,

                                   int sector_size)

{

    s->lba = lba;

    s->packet_transfer_size = nb_sectors * sector_size;

    s->elementary_transfer_size = 0;

    s->io_buffer_index = sector_size;

    s->cd_sector_size = sector_size;

    s->status = READY_STAT;

    ide_atapi_cmd_reply_end(s);

}


static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t val)

{

    PCIXenPlatformState *s = opaque;

    switch (addr) {

    case 0: {

        PCIDevice *pci_dev = PCI_DEVICE(s);

        /* Unplug devices.  Value is a bitmask of which devices to

           unplug, with bit 0 the disk devices, bit 1 the network

           devices, and bit 2 the non-primary-master IDE devices. */

        if (val & UNPLUG_ALL_DISKS) {

            DPRINTF("unplug disks\n");

            pci_unplug_disks(pci_dev->bus);

        }

        if (val & UNPLUG_ALL_NICS) {

            DPRINTF("unplug nics\n");

            pci_unplug_nics(pci_dev->bus);

        }

        if (val & UNPLUG_AUX_IDE_DISKS) {

            DPRINTF("unplug auxiliary disks not supported\n");

        }

        break;

    }

    case 2:

        switch (val) {

        case 1:

            DPRINTF("Citrix Windows PV drivers loaded in guest\n");

            break;

        case 0:

            DPRINTF("Guest claimed to be running PV product 0?\n");

            break;

        default:

            DPRINTF("Unknown PV product %d loaded in guest\n", val);

            break;

        }

        s->driver_product_version = val;

        break;

    }

}


static int xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s,

                                    XenPTReg *cfg_entry, uint16_t *val,

                                    uint16_t dev_value, uint16_t valid_mask)

{

    XenPTRegInfo *reg = cfg_entry->reg;

    XenPTMSI *msi = s->msi;

    uint16_t writable_mask = 0;

    uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);

    /* Currently no support for multi-vector */

    if (*val & PCI_MSI_FLAGS_QSIZE) {

        XEN_PT_WARN(&s->dev, "Tries to set more than 1 vector ctrl %x\n", *val);

    }

    /* modify emulate register */

    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;

    cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);

    msi->flags |= cfg_entry->data & ~PCI_MSI_FLAGS_ENABLE;

    /* create value for writing to I/O device register */

    *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask);

    /* update MSI */

    if (*val & PCI_MSI_FLAGS_ENABLE) {

        /* setup MSI pirq for the first time */

        if (!msi->initialized) {

            /* Init physical one */

            XEN_PT_LOG(&s->dev, "setup MSI (register: %x).\n", *val);

            if (xen_pt_msi_setup(s)) {

                /* We do not broadcast the error to the framework code, so

                 * that MSI errors are contained in MSI emulation code and

                 * QEMU can go on running.

                 * Guest MSI would be actually not working.

                 */

                *val &= ~PCI_MSI_FLAGS_ENABLE;

                XEN_PT_WARN(&s->dev, "Can not map MSI (register: %x)!\n", *val);

                return 0;

            }

            if (xen_pt_msi_update(s)) {

                *val &= ~PCI_MSI_FLAGS_ENABLE;

                XEN_PT_WARN(&s->dev, "Can not bind MSI (register: %x)!\n", *val);

                return 0;

            }

            msi->initialized = true;

            msi->mapped = true;

        }

        msi->flags |= PCI_MSI_FLAGS_ENABLE;

    } else if (msi->mapped) {

        xen_pt_msi_disable(s);

    }

    return 0;

}


static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp)

{

    BDRVQcow2State *s = bs->opaque;

    if (bs->encrypted) {

        /* Encryption works on a sector granularity */

        bs->request_alignment = BDRV_SECTOR_SIZE;

    }

    bs->bl.pwrite_zeroes_alignment = s->cluster_size;

}


static void set_string(Object *obj, Visitor *v, void *opaque,

                       const char *name, Error **errp)

{

    DeviceState *dev = DEVICE(obj);

    Property *prop = opaque;

    char **ptr = qdev_get_prop_ptr(dev, prop);

    Error *local_err = NULL;

    char *str;

    if (dev->realized) {

        qdev_prop_set_after_realize(dev, name, errp);

        return;

    }

    visit_type_str(v, &str, name, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        return;

    }

    if (*ptr) {

        g_free(*ptr);

    }

    *ptr = str;

}


void OPPROTO op_idivb_AL_T0(void)

{

    int num, den, q, r;

    num = (int16_t)EAX;

    den = (int8_t)T0;

    if (den == 0) {

        raise_exception(EXCP00_DIVZ);

    }

    q = (num / den) & 0xff;

    r = (num % den) & 0xff;

    EAX = (EAX & ~0xffff) | (r << 8) | q;

}


static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len)

{

    uint8_t *ptr = qdev_get_prop_ptr(dev, prop);

    return snprintf(dest, len, "%" PRIu8, *ptr);

}


static int init_image(TiffContext *s, ThreadFrame *frame)

{

    int ret;

    switch (s->planar * 1000 + s->bpp * 10 + s->bppcount) {

    case 11:

        if (!s->palette_is_set) {

            s->avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;

            break;

        }

    case 21:

    case 41:

    case 81:

        s->avctx->pix_fmt = s->palette_is_set ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;

        break;

    case 243:

        if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) {

            if (s->subsampling[0] == 1 && s->subsampling[1] == 1) {

                s->avctx->pix_fmt = AV_PIX_FMT_YUV444P;

            } else if (s->subsampling[0] == 2 && s->subsampling[1] == 1) {

                s->avctx->pix_fmt = AV_PIX_FMT_YUV422P;

            } else if (s->subsampling[0] == 4 && s->subsampling[1] == 1) {

                s->avctx->pix_fmt = AV_PIX_FMT_YUV411P;

            } else if (s->subsampling[0] == 1 && s->subsampling[1] == 2) {

                s->avctx->pix_fmt = AV_PIX_FMT_YUV440P;

            } else if (s->subsampling[0] == 2 && s->subsampling[1] == 2) {

                s->avctx->pix_fmt = AV_PIX_FMT_YUV420P;

            } else if (s->subsampling[0] == 4 && s->subsampling[1] == 4) {

                s->avctx->pix_fmt = AV_PIX_FMT_YUV410P;

            } else {

                av_log(s->avctx, AV_LOG_ERROR, "Unsupported YCbCr subsampling\n");

                return AVERROR_PATCHWELCOME;

            }

        } else

            s->avctx->pix_fmt = AV_PIX_FMT_RGB24;

        break;

    case 161:

        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GRAY16LE : AV_PIX_FMT_GRAY16BE;

        break;

    case 162:

        s->avctx->pix_fmt = AV_PIX_FMT_YA8;

        break;

    case 322:

        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_YA16LE : AV_PIX_FMT_YA16BE;

        break;

    case 324:

        s->avctx->pix_fmt = AV_PIX_FMT_RGBA;

        break;

    case 483:

        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGB48LE  : AV_PIX_FMT_RGB48BE;

        break;

    case 644:

        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGBA64LE  : AV_PIX_FMT_RGBA64BE;

        break;

    case 1243:

        s->avctx->pix_fmt = AV_PIX_FMT_GBRP;

        break;

    case 1324:

        s->avctx->pix_fmt = AV_PIX_FMT_GBRAP;

        break;

    case 1483:

        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRP16LE : AV_PIX_FMT_GBRP16BE;

        break;

    case 1644:

        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRAP16LE : AV_PIX_FMT_GBRAP16BE;

        break;

    default:

        av_log(s->avctx, AV_LOG_ERROR,

               "This format is not supported (bpp=%d, bppcount=%d)\n",

               s->bpp, s->bppcount);

        return AVERROR_INVALIDDATA;

    }

    if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) {

        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);

        if((desc->flags & AV_PIX_FMT_FLAG_RGB) || desc->nb_components < 3) {

            av_log(s->avctx, AV_LOG_ERROR, "Unsupported YCbCr variant\n");

            return AVERROR_INVALIDDATA;

        }

    }

    if (s->width != s->avctx->width || s->height != s->avctx->height) {

        ret = ff_set_dimensions(s->avctx, s->width, s->height);

        if (ret < 0)

            return ret;

    }

    if ((ret = ff_thread_get_buffer(s->avctx, frame, 0)) < 0)

        return ret;

    if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {

        memcpy(frame->f->data[1], s->palette, sizeof(s->palette));

    }

    return 0;

}


static int connect_to_sdog(const char *addr, const char *port)

{

    char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];

    int fd, ret;

    struct addrinfo hints, *res, *res0;

    if (!addr) {

        addr = SD_DEFAULT_ADDR;

        port = SD_DEFAULT_PORT;

    }

    memset(&hints, 0, sizeof(hints));

    hints.ai_socktype = SOCK_STREAM;

    ret = getaddrinfo(addr, port, &hints, &res0);

    if (ret) {

        error_report("unable to get address info %s, %s",

                     addr, strerror(errno));

        return -errno;

    }

    for (res = res0; res; res = res->ai_next) {

        ret = getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),

                          sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);

        if (ret) {

            continue;

        }

        fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

        if (fd < 0) {

            continue;

        }

    reconnect:

        ret = connect(fd, res->ai_addr, res->ai_addrlen);

        if (ret < 0) {

            if (errno == EINTR) {

                goto reconnect;

            }

            break;

        }

        dprintf("connected to %s:%s\n", addr, port);

        goto success;

    }

    fd = -errno;

    error_report("failed connect to %s:%s", addr, port);

success:

    freeaddrinfo(res0);

    return fd;

}


int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,

                         int *frame_size_ptr,

                         AVPacket *avpkt)

{

    AVFrame frame;

    int ret, got_frame = 0;

    if (avctx->get_buffer != avcodec_default_get_buffer) {

        av_log(avctx, AV_LOG_ERROR, "A custom get_buffer() cannot be used with "

               "avcodec_decode_audio3()\n");

        return AVERROR(EINVAL);

    }

    ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt);

    if (ret >= 0 && got_frame) {

        int ch, plane_size;

        int planar = av_sample_fmt_is_planar(avctx->sample_fmt);

        int data_size = av_samples_get_buffer_size(&plane_size, avctx->channels,

                                                   frame.nb_samples,

                                                   avctx->sample_fmt, 1);

        if (*frame_size_ptr < data_size) {

            av_log(avctx, AV_LOG_ERROR, "output buffer size is too small for "

                   "the current frame (%d < %d)\n", *frame_size_ptr, data_size);

            return AVERROR(EINVAL);

        }

        memcpy(samples, frame.extended_data[0], plane_size);

        if (planar && avctx->channels > 1) {

            uint8_t *out = ((uint8_t *)samples) + plane_size;

            for (ch = 1; ch < avctx->channels; ch++) {

                memcpy(out, frame.extended_data[ch], plane_size);

                out += plane_size;

            }

        }

        *frame_size_ptr = data_size;

    } else {

        *frame_size_ptr = 0;

    }

    return ret;

}


static int qemu_chr_open_win_con(QemuOpts *opts, CharDriverState **chr)

{

    return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE), chr);

}


static void dca_exss_parse_header(DCAContext *s)
{
    int asset_size[8];
    int ss_index;
    int blownup;
    int num_audiop = 1;
    int num_assets = 1;
    int active_ss_mask[8];
    int i, j;
    int start_posn;
    int hdrsize;
    uint32_t mkr;
    if (get_bits_left(&s->gb) < 52)
        return;
    start_posn = get_bits_count(&s->gb) - 32;
    skip_bits(&s->gb, 8); // user data
    ss_index = get_bits(&s->gb, 2);
    blownup = get_bits1(&s->gb);
    hdrsize = get_bits(&s->gb,  8 + 4 * blownup) + 1; // header_size
    skip_bits(&s->gb, 16 + 4 * blownup); // hd_size
    s->static_fields = get_bits1(&s->gb);
    if (s->static_fields) {
        skip_bits(&s->gb, 2); // reference clock code
        skip_bits(&s->gb, 3); // frame duration code
        if (get_bits1(&s->gb))
            skip_bits_long(&s->gb, 36); // timestamp
        /* a single stream can contain multiple audio assets that can be
         * combined to form multiple audio presentations */
        num_audiop = get_bits(&s->gb, 3) + 1;
        if (num_audiop > 1) {
            avpriv_request_sample(s->avctx,
                                  "Multiple DTS-HD audio presentations");
            /* ignore such streams for now */
            return;
        }
        num_assets = get_bits(&s->gb, 3) + 1;
        if (num_assets > 1) {
            avpriv_request_sample(s->avctx, "Multiple DTS-HD audio assets");
            /* ignore such streams for now */
            return;
        }
        for (i = 0; i < num_audiop; i++)
            active_ss_mask[i] = get_bits(&s->gb, ss_index + 1);
        for (i = 0; i < num_audiop; i++)
            for (j = 0; j <= ss_index; j++)
                if (active_ss_mask[i] & (1 << j))
                    skip_bits(&s->gb, 8); // active asset mask
        s->mix_metadata = get_bits1(&s->gb);
        if (s->mix_metadata) {
            int mix_out_mask_size;
            skip_bits(&s->gb, 2); // adjustment level
            mix_out_mask_size  = (get_bits(&s->gb, 2) + 1) << 2;
            s->num_mix_configs =  get_bits(&s->gb, 2) + 1;
            for (i = 0; i < s->num_mix_configs; i++) {
                int mix_out_mask        = get_bits(&s->gb, mix_out_mask_size);
                s->mix_config_num_ch[i] = dca_exss_mask2count(mix_out_mask);
            }
        }
    }
    for (i = 0; i < num_assets; i++)
        asset_size[i] = get_bits_long(&s->gb, 16 + 4 * blownup);
    for (i = 0; i < num_assets; i++) {
        if (dca_exss_parse_asset_header(s))
            return;
    }
    /* not parsed further, we were only interested in the extensions mask
     * from the asset header */
        j = get_bits_count(&s->gb);
        if (start_posn + hdrsize * 8 > j)
            skip_bits_long(&s->gb, start_posn + hdrsize * 8 - j);
        for (i = 0; i < num_assets; i++) {
            start_posn = get_bits_count(&s->gb);
            mkr        = get_bits_long(&s->gb, 32);
            /* parse extensions that we know about */
            if (mkr == 0x655e315e) {
                dca_xbr_parse_frame(s);
            } else if (mkr == 0x47004a03) {
                dca_xxch_decode_frame(s);
                s->core_ext_mask |= DCA_EXT_XXCH; /* xxx use for chan reordering */
            } else {
                av_log(s->avctx, AV_LOG_DEBUG,
                       "DTS-ExSS: unknown marker = 0x%08x\n", mkr);
            }
            /* skip to end of block */
            j = get_bits_count(&s->gb);
            if (start_posn + asset_size[i] * 8 > j)
                skip_bits_long(&s->gb, start_posn + asset_size[i] * 8 - j);
        }
}


static int idcin_read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    IdcinDemuxContext *idcin = s->priv_data;
    AVStream *st;
    unsigned int width, height;
    unsigned int sample_rate, bytes_per_sample, channels;
    /* get the 5 header parameters */
    width = avio_rl32(pb);
    height = avio_rl32(pb);
    sample_rate = avio_rl32(pb);
    bytes_per_sample = avio_rl32(pb);
    channels = avio_rl32(pb);
    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    avpriv_set_pts_info(st, 33, 1, IDCIN_FPS);
    idcin->video_stream_index = st->index;
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id = AV_CODEC_ID_IDCIN;
    st->codec->codec_tag = 0;  /* no fourcc */
    st->codec->width = width;
    st->codec->height = height;
    /* load up the Huffman tables into extradata */
    st->codec->extradata_size = HUFFMAN_TABLE_SIZE;
    st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE);
    if (avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) !=
        HUFFMAN_TABLE_SIZE)
        return AVERROR(EIO);
    /* if sample rate is 0, assume no audio */
    if (sample_rate) {
        idcin->audio_present = 1;
        st = avformat_new_stream(s, NULL);
        if (!st)
            return AVERROR(ENOMEM);
        avpriv_set_pts_info(st, 33, 1, IDCIN_FPS);
        idcin->audio_stream_index = st->index;
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_tag = 1;
        st->codec->channels = channels;
        st->codec->sample_rate = sample_rate;
        st->codec->bits_per_coded_sample = bytes_per_sample * 8;
        st->codec->bit_rate = sample_rate * bytes_per_sample * 8 * channels;
        st->codec->block_align = bytes_per_sample * channels;
        if (bytes_per_sample == 1)
            st->codec->codec_id = AV_CODEC_ID_PCM_U8;
        else
            st->codec->codec_id = AV_CODEC_ID_PCM_S16LE;
        if (sample_rate % 14 != 0) {
            idcin->audio_chunk_size1 = (sample_rate / 14) *
            bytes_per_sample * channels;
            idcin->audio_chunk_size2 = (sample_rate / 14 + 1) *
                bytes_per_sample * channels;
        } else {
            idcin->audio_chunk_size1 = idcin->audio_chunk_size2 =
                (sample_rate / 14) * bytes_per_sample * channels;
        idcin->current_audio_chunk = 0;
    } else
        idcin->audio_present = 1;
    idcin->next_chunk_is_video = 1;
    idcin->pts = 0;
    return 0;


static void xilinx_enet_init(Object *obj)

{

    XilinxAXIEnet *s = XILINX_AXI_ENET(obj);

    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE,

                             (Object **) &s->tx_data_dev, &error_abort);

    object_property_add_link(obj, "axistream-control-connected",

                             TYPE_STREAM_SLAVE,

                             (Object **) &s->tx_control_dev, &error_abort);

    object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),

                      TYPE_XILINX_AXI_ENET_DATA_STREAM);

    object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev),

                      TYPE_XILINX_AXI_ENET_CONTROL_STREAM);

    object_property_add_child(OBJECT(s), "axistream-connected-target",

                              (Object *)&s->rx_data_dev, &error_abort);

    object_property_add_child(OBJECT(s), "axistream-control-connected-target",

                              (Object *)&s->rx_control_dev, &error_abort);

    sysbus_init_irq(sbd, &s->irq);

    memory_region_init_io(&s->iomem, OBJECT(s), &enet_ops, s, "enet", 0x40000);

    sysbus_init_mmio(sbd, &s->iomem);

}


static int update_size(AVCodecContext *ctx, int w, int h, enum AVPixelFormat fmt)

{

    VP9Context *s = ctx->priv_data;

    uint8_t *p;

    int bytesperpixel = s->bytesperpixel;

    av_assert0(w > 0 && h > 0);

    if (s->intra_pred_data[0] && w == ctx->width && h == ctx->height && ctx->pix_fmt == fmt)

        return 0;

    ctx->width   = w;

    ctx->height  = h;

    ctx->pix_fmt = fmt;

    s->sb_cols   = (w + 63) >> 6;

    s->sb_rows   = (h + 63) >> 6;

    s->cols      = (w + 7) >> 3;

    s->rows      = (h + 7) >> 3;

#define assign(var, type, n) var = (type) p; p += s->sb_cols * (n) * sizeof(*var)

    av_freep(&s->intra_pred_data[0]);

    // FIXME we slightly over-allocate here for subsampled chroma, but a little

    // bit of padding shouldn't affect performance...

    p = av_malloc(s->sb_cols * (128 + 192 * bytesperpixel +

                                sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx)));

    if (!p)

        return AVERROR(ENOMEM);

    assign(s->intra_pred_data[0],  uint8_t *,             64 * bytesperpixel);

    assign(s->intra_pred_data[1],  uint8_t *,             64 * bytesperpixel);

    assign(s->intra_pred_data[2],  uint8_t *,             64 * bytesperpixel);

    assign(s->above_y_nnz_ctx,     uint8_t *,             16);

    assign(s->above_mode_ctx,      uint8_t *,             16);

    assign(s->above_mv_ctx,        VP56mv(*)[2],          16);

    assign(s->above_uv_nnz_ctx[0], uint8_t *,             16);

    assign(s->above_uv_nnz_ctx[1], uint8_t *,             16);

    assign(s->above_partition_ctx, uint8_t *,              8);

    assign(s->above_skip_ctx,      uint8_t *,              8);

    assign(s->above_txfm_ctx,      uint8_t *,              8);

    assign(s->above_segpred_ctx,   uint8_t *,              8);

    assign(s->above_intra_ctx,     uint8_t *,              8);

    assign(s->above_comp_ctx,      uint8_t *,              8);

    assign(s->above_ref_ctx,       uint8_t *,              8);

    assign(s->above_filter_ctx,    uint8_t *,              8);

    assign(s->lflvl,               struct VP9Filter *,     1);

#undef assign

    // these will be re-allocated a little later

    av_freep(&s->b_base);

    av_freep(&s->block_base);

    if (s->bpp != s->last_bpp) {

        ff_vp9dsp_init(&s->dsp, s->bpp);

        ff_videodsp_init(&s->vdsp, s->bpp);

        s->last_bpp = s->bpp;

    }

    return 0;

}


static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid,

                              unsigned int epid)

{

    XHCISlot *slot;

    XHCIEPContext *epctx;

    USBDevice *dev;

    trace_usb_xhci_ep_reset(slotid, epid);

    assert(slotid >= 1 && slotid <= xhci->numslots);

    if (epid < 1 || epid > 31) {

        fprintf(stderr, "xhci: bad ep %d\n", epid);

        return CC_TRB_ERROR;

    }

    slot = &xhci->slots[slotid-1];

    if (!slot->eps[epid-1]) {

        DPRINTF("xhci: slot %d ep %d not enabled\n", slotid, epid);

        return CC_EP_NOT_ENABLED_ERROR;

    }

    epctx = slot->eps[epid-1];

    if (epctx->state != EP_HALTED) {

        fprintf(stderr, "xhci: reset EP while EP %d not halted (%d)\n",

                epid, epctx->state);

        return CC_CONTEXT_STATE_ERROR;

    }

    if (xhci_ep_nuke_xfers(xhci, slotid, epid) > 0) {

        fprintf(stderr, "xhci: FIXME: endpoint reset w/ xfers running, "

                "data might be lost\n");

    }

    uint8_t ep = epid>>1;

    if (epid & 1) {

        ep |= 0x80;

    }

    dev = xhci->slots[slotid-1].uport->dev;

    if (!dev) {

        return CC_USB_TRANSACTION_ERROR;

    }

    xhci_set_ep_state(xhci, epctx, NULL, EP_STOPPED);

    if (epctx->nr_pstreams) {

        xhci_reset_streams(epctx);

    }

    return CC_SUCCESS;

}


static int64_t mmsh_seek(URLContext *h, int64_t pos, int whence)

{

    MMSHContext *mmsh = h->priv_data;

    MMSContext *mms   = &mmsh->mms;

    if(pos == 0 && whence == SEEK_CUR)

        return mms->asf_header_read_size + mms->remaining_in_len + mmsh->chunk_seq * mms->asf_packet_len;

    return AVERROR(ENOSYS);

}