static void iothread_complete(UserCreatable *obj, Error **errp)

{

    Error *local_error = NULL;

    IOThread *iothread = IOTHREAD(obj);

    iothread->stopping = false;

    iothread->thread_id = -1;

    iothread->ctx = aio_context_new(&local_error);

    if (!iothread->ctx) {

        error_propagate(errp, local_error);

        return;

    }

    qemu_mutex_init(&iothread->init_done_lock);

    qemu_cond_init(&iothread->init_done_cond);

    /* This assumes we are called from a thread with useful CPU affinity for us

     * to inherit.

     */

    qemu_thread_create(&iothread->thread, "iothread", iothread_run,

                       iothread, QEMU_THREAD_JOINABLE);

    /* Wait for initialization to complete */

    qemu_mutex_lock(&iothread->init_done_lock);

    while (iothread->thread_id == -1) {

        qemu_cond_wait(&iothread->init_done_cond,

                       &iothread->init_done_lock);

    }

    qemu_mutex_unlock(&iothread->init_done_lock);

}


restore_fpu_state(CPUSPARCState *env, qemu_siginfo_fpu_t *fpu)

{

        int err;

#if 0

#ifdef CONFIG_SMP

        if (current->flags & PF_USEDFPU)

                regs->psr &= ~PSR_EF;

#else

        if (current == last_task_used_math) {

                last_task_used_math = 0;

                regs->psr &= ~PSR_EF;

        }

#endif

        current->used_math = 1;

        current->flags &= ~PF_USEDFPU;

#endif

#if 0

        if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))

                return -EFAULT;

#endif

        /* XXX: incorrect */

        err = copy_from_user(&env->fpr[0], fpu->si_float_regs[0],

                             (sizeof(abi_ulong) * 32));

        err |= __get_user(env->fsr, &fpu->si_fsr);

#if 0

        err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);

        if (current->thread.fpqdepth != 0)

                err |= __copy_from_user(&current->thread.fpqueue[0],

                                        &fpu->si_fpqueue[0],

                                        ((sizeof(unsigned long) +

                                        (sizeof(unsigned long *)))*16));

#endif

        return err;

}


static int tta_decode_frame(AVCodecContext *avctx,

        void *data, int *data_size,

        AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    TTAContext *s = avctx->priv_data;

    int i;

    init_get_bits(&s->gb, buf, buf_size*8);

    {

        int cur_chan = 0, framelen = s->frame_length;

        int32_t *p;

        if (*data_size < (framelen * s->channels * 2)) {

            av_log(avctx, AV_LOG_ERROR, "Output buffer size is too small.\n");

            return -1;

        }

        // FIXME: seeking

        s->total_frames--;

        if (!s->total_frames && s->last_frame_length)

            framelen = s->last_frame_length;

        // init per channel states

        for (i = 0; i < s->channels; i++) {

            s->ch_ctx[i].predictor = 0;

            ttafilter_init(&s->ch_ctx[i].filter, ttafilter_configs[s->bps-1][0], ttafilter_configs[s->bps-1][1]);

            rice_init(&s->ch_ctx[i].rice, 10, 10);

        }

        for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) {

            int32_t *predictor = &s->ch_ctx[cur_chan].predictor;

            TTAFilter *filter = &s->ch_ctx[cur_chan].filter;

            TTARice *rice = &s->ch_ctx[cur_chan].rice;

            uint32_t unary, depth, k;

            int32_t value;

            unary = tta_get_unary(&s->gb);

            if (unary == 0) {

                depth = 0;

                k = rice->k0;

            } else {

                depth = 1;

                k = rice->k1;

                unary--;

            }

            if (get_bits_left(&s->gb) < k)

                return -1;

            if (k) {

                if (k > MIN_CACHE_BITS)

                    return -1;

                value = (unary << k) + get_bits(&s->gb, k);

            } else

                value = unary;

            // FIXME: copy paste from original

            switch (depth) {

            case 1:

                rice->sum1 += value - (rice->sum1 >> 4);

                if (rice->k1 > 0 && rice->sum1 < shift_16[rice->k1])

                    rice->k1--;

                else if(rice->sum1 > shift_16[rice->k1 + 1])

                    rice->k1++;

                value += shift_1[rice->k0];

            default:

                rice->sum0 += value - (rice->sum0 >> 4);

                if (rice->k0 > 0 && rice->sum0 < shift_16[rice->k0])

                    rice->k0--;

                else if(rice->sum0 > shift_16[rice->k0 + 1])

                    rice->k0++;

            }

            // extract coded value

#define UNFOLD(x) (((x)&1) ? (++(x)>>1) : (-(x)>>1))

            *p = UNFOLD(value);

            // run hybrid filter

            ttafilter_process(filter, p, 0);

            // fixed order prediction

#define PRED(x, k) (int32_t)((((uint64_t)x << k) - x) >> k)

            switch (s->bps) {

                case 1: *p += PRED(*predictor, 4); break;

                case 2:

                case 3: *p += PRED(*predictor, 5); break;

                case 4: *p += *predictor; break;

            }

            *predictor = *p;

            // flip channels

            if (cur_chan < (s->channels-1))

                cur_chan++;

            else {

                // decorrelate in case of stereo integer

                if (s->channels > 1) {

                    int32_t *r = p - 1;

                    for (*p += *r / 2; r > p - s->channels; r--)

                        *r = *(r + 1) - *r;

                }

                cur_chan = 0;

            }

        }

        if (get_bits_left(&s->gb) < 32)

            return -1;

        skip_bits(&s->gb, 32); // frame crc

        // convert to output buffer

        switch(s->bps) {

            case 2: {

                uint16_t *samples = data;

                for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) {

                    *samples++ = *p;

                }

                *data_size = (uint8_t *)samples - (uint8_t *)data;

                break;

            }

            default:

                av_log(s->avctx, AV_LOG_ERROR, "Error, only 16bit samples supported!\n");

        }

    }

    return buf_size;

}


int qdev_init(DeviceState *dev)

{

    int rc;

    assert(dev->state == DEV_STATE_CREATED);

    rc = dev->info->init(dev, dev->info);

    if (rc < 0) {

        qdev_free(dev);

        return rc;

    }

    qemu_register_reset(qdev_reset, dev);

    if (dev->info->vmsd) {

        vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,

                                       dev->instance_id_alias,

                                       dev->alias_required_for_version);

    }

    dev->state = DEV_STATE_INITIALIZED;

    return 0;

}


static int coroutine_fn copy_sectors(BlockDriverState *bs,

                                     uint64_t start_sect,

                                     uint64_t cluster_offset,

                                     int n_start, int n_end)

{

    BDRVQcowState *s = bs->opaque;

    QEMUIOVector qiov;

    struct iovec iov;

    int n, ret;

    /*

     * If this is the last cluster and it is only partially used, we must only

     * copy until the end of the image, or bdrv_check_request will fail for the

     * bdrv_read/write calls below.

     */

    if (start_sect + n_end > bs->total_sectors) {

        n_end = bs->total_sectors - start_sect;

    }

    n = n_end - n_start;

    if (n <= 0) {

        return 0;

    }

    iov.iov_len = n * BDRV_SECTOR_SIZE;

    iov.iov_base = qemu_blockalign(bs, iov.iov_len);

    qemu_iovec_init_external(&qiov, &iov, 1);

    BLKDBG_EVENT(bs->file, BLKDBG_COW_READ);

    if (!bs->drv) {

        return -ENOMEDIUM;

    }

    /* Call .bdrv_co_readv() directly instead of using the public block-layer

     * interface.  This avoids double I/O throttling and request tracking,

     * which can lead to deadlock when block layer copy-on-read is enabled.

     */

    ret = bs->drv->bdrv_co_readv(bs, start_sect + n_start, n, &qiov);

    if (ret < 0) {

        goto out;

    }

    if (s->crypt_method) {

        qcow2_encrypt_sectors(s, start_sect + n_start,

                        iov.iov_base, iov.iov_base, n, 1,

                        &s->aes_encrypt_key);

    }

    ret = qcow2_pre_write_overlap_check(bs, 0,

            cluster_offset + n_start * BDRV_SECTOR_SIZE, n * BDRV_SECTOR_SIZE);

    if (ret < 0) {

        goto out;

    }

    BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);

    ret = bdrv_co_writev(bs->file, (cluster_offset >> 9) + n_start, n, &qiov);

    if (ret < 0) {

        goto out;

    }

    ret = 0;

out:

    qemu_vfree(iov.iov_base);

    return ret;

}


static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid,

                               unsigned int epid, TRBCCode report)

{

    XHCISlot *slot;

    XHCIEPContext *epctx;

    int i, xferi, killed = 0;

    USBEndpoint *ep = NULL;

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

    assert(epid >= 1 && epid <= 31);

    DPRINTF("xhci_ep_nuke_xfers(%d, %d)\n", slotid, epid);

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

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

        return 0;

    }

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

    xferi = epctx->next_xfer;

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

        killed += xhci_ep_nuke_one_xfer(&epctx->transfers[xferi], report);

        if (killed) {

            report = 0; /* Only report once */

        }

        epctx->transfers[xferi].packet.ep = NULL;

        xferi = (xferi + 1) % TD_QUEUE;

    }

    ep = xhci_epid_to_usbep(xhci, slotid, epid);

    if (ep) {

        usb_device_ep_stopped(ep->dev, ep);

    }

    return killed;

}


static inline void gen_branch_slot(uint32_t delayed_pc, int t)

{

    TCGv sr;

    int label = gen_new_label();

    tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);

    sr = tcg_temp_new();

    tcg_gen_andi_i32(sr, cpu_sr, SR_T);

    tcg_gen_brcondi_i32(t ? TCG_COND_EQ:TCG_COND_NE, sr, 0, label);

    tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);

    gen_set_label(label);

}


static void put_fid(V9fsPDU *pdu, V9fsFidState *fidp)

{

    BUG_ON(!fidp->ref);

    fidp->ref--;

    /*

     * Don't free the fid if it is in reclaim list

     */

    if (!fidp->ref && fidp->clunked) {

        if (fidp->fid == pdu->s->root_fid) {

            /*

             * if the clunked fid is root fid then we

             * have unmounted the fs on the client side.

             * delete the migration blocker. Ideally, this

             * should be hooked to transport close notification

             */

            if (pdu->s->migration_blocker) {

                migrate_del_blocker(pdu->s->migration_blocker);

                error_free(pdu->s->migration_blocker);

                pdu->s->migration_blocker = NULL;

            }

        }

        free_fid(pdu, fidp);

    }

}


static inline void RENAME(rgb16to15)(const uint8_t *src,uint8_t *dst,unsigned src_size)

{

  register const uint8_t* s=src;

  register uint8_t* d=dst;

  register const uint8_t *end;

  const uint8_t *mm_end;

  end = s + src_size;

#ifdef HAVE_MMX

  __asm __volatile(PREFETCH"	%0"::"m"(*s));

  __asm __volatile("movq	%0, %%mm7"::"m"(mask15rg));

  __asm __volatile("movq	%0, %%mm6"::"m"(mask15b));

  mm_end = end - 15;

  while(s<mm_end)

  {

	__asm __volatile(

		PREFETCH"	32%1\n\t"

		"movq	%1, %%mm0\n\t"

		"movq	8%1, %%mm2\n\t"

		"movq	%%mm0, %%mm1\n\t"

		"movq	%%mm2, %%mm3\n\t"

		"psrlq	$1, %%mm0\n\t"

		"psrlq	$1, %%mm2\n\t"

		"pand	%%mm7, %%mm0\n\t"

		"pand	%%mm7, %%mm2\n\t"

		"pand	%%mm6, %%mm1\n\t"

		"pand	%%mm6, %%mm3\n\t"

		"por	%%mm1, %%mm0\n\t"

		"por	%%mm3, %%mm2\n\t"

		MOVNTQ"	%%mm0, %0\n\t"

		MOVNTQ"	%%mm2, 8%0"

		:"=m"(*d)

		:"m"(*s)

		);

	d+=16;

	s+=16;

  }

  __asm __volatile(SFENCE:::"memory");

  __asm __volatile(EMMS:::"memory");

#endif

    mm_end = end - 3;

    while(s < mm_end)

    {

	register uint32_t x= *((uint32_t *)s);

	*((uint32_t *)d) = ((x>>1)&0x7FE07FE0) | (x&0x001F001F);

	s+=4;

	d+=4;

    }

    if(s < end)

    {

	register uint16_t x= *((uint16_t *)s);

	*((uint16_t *)d) = ((x>>1)&0x7FE0) | (x&0x001F);

	s+=2;

	d+=2;

    }

}


static void moxiesim_init(MachineState *machine)

{

    MoxieCPU *cpu = NULL;

    ram_addr_t ram_size = machine->ram_size;

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = machine->kernel_filename;

    const char *kernel_cmdline = machine->kernel_cmdline;

    const char *initrd_filename = machine->initrd_filename;

    CPUMoxieState *env;

    MemoryRegion *address_space_mem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    MemoryRegion *rom = g_new(MemoryRegion, 1);

    hwaddr ram_base = 0x200000;

    LoaderParams loader_params;

    /* Init CPUs. */

    if (cpu_model == NULL) {

        cpu_model = "MoxieLite-moxie-cpu";

    }

    cpu = MOXIE_CPU(cpu_generic_init(TYPE_MOXIE_CPU, cpu_model));

    if (!cpu) {

        fprintf(stderr, "Unable to find CPU definition\n");

        exit(1);

    }

    env = &cpu->env;

    qemu_register_reset(main_cpu_reset, cpu);

    /* Allocate RAM. */

    memory_region_init_ram(ram, NULL, "moxiesim.ram", ram_size, &error_fatal);

    memory_region_add_subregion(address_space_mem, ram_base, ram);

    memory_region_init_ram(rom, NULL, "moxie.rom", 128 * 0x1000, &error_fatal);

    memory_region_add_subregion(get_system_memory(), 0x1000, rom);

    if (kernel_filename) {

        loader_params.ram_size = ram_size;

        loader_params.kernel_filename = kernel_filename;

        loader_params.kernel_cmdline = kernel_cmdline;

        loader_params.initrd_filename = initrd_filename;

        load_kernel(cpu, &loader_params);

    }

    /* A single 16450 sits at offset 0x3f8.  */

    if (serial_hds[0]) {

        serial_mm_init(address_space_mem, 0x3f8, 0, env->irq[4],

                       8000000/16, serial_hds[0], DEVICE_LITTLE_ENDIAN);

    }

}


static void build_guest_fsinfo_for_virtual_device(char const *syspath,

                                                  GuestFilesystemInfo *fs,

                                                  Error **errp)

{

    DIR *dir;

    char *dirpath;

    struct dirent entry, *result;

    dirpath = g_strdup_printf("%s/slaves", syspath);

    dir = opendir(dirpath);

    if (!dir) {

        error_setg_errno(errp, errno, "opendir(\"%s\")", dirpath);

        g_free(dirpath);

        return;

    }

    g_free(dirpath);

    for (;;) {

        if (readdir_r(dir, &entry, &result) != 0) {

            error_setg_errno(errp, errno, "readdir_r(\"%s\")", dirpath);

            break;

        }

        if (!result) {

            break;

        }

        if (entry.d_type == DT_LNK) {

            g_debug(" slave device '%s'", entry.d_name);

            dirpath = g_strdup_printf("%s/slaves/%s", syspath, entry.d_name);

            build_guest_fsinfo_for_device(dirpath, fs, errp);

            g_free(dirpath);

            if (*errp) {

                break;

            }

        }

    }

    closedir(dir);

}


void write_video_frame(AVFormatContext *oc, AVStream *st)

{

    int x, y, i, out_size;

    AVCodecContext *c;

    c = &st->codec;

    /* prepare a dummy image */

    /* Y */

    i = frame_count++;

    for(y=0;y<c->height;y++) {

        for(x=0;x<c->width;x++) {

            picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;

        }

    }

    /* Cb and Cr */

    for(y=0;y<c->height/2;y++) {

        for(x=0;x<c->width/2;x++) {

            picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;

            picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;

        }

    }

    /* encode the image */

    out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);

    /* write the compressed frame in the media file */

    if (av_write_frame(oc, st->index, video_outbuf, out_size) != 0) {

        fprintf(stderr, "Error while writing video frame\n");

        exit(1);

    }

}


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 illegal_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_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);

        return;

    }

    if (is_xmm && !(s->flags & HF_OSFXSR_MASK))

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

            goto illegal_op;

    if (b == 0x0e) {

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

            goto illegal_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].XMM_Q(0)));

            } else {

                tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,

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

                gen_op_st_v(s, MO_32, cpu_T[0], 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_T[0], 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_T[0]);

                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_T[0]);

            } 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_T[0]);

                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_T[0], cpu_A0);

                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));

                tcg_gen_movi_tl(cpu_T[0], 0);

                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));

                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));

                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));

            } else {

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

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

                            offsetof(CPUX86State,xmm_regs[rm].XMM_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].XMM_Q(0)));

                tcg_gen_movi_tl(cpu_T[0], 0);

                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(2)));

                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(3)));

            } else {

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

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

                            offsetof(CPUX86State,xmm_regs[rm].XMM_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].XMM_Q(0)));

            } else {

                /* movhlps */

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

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

                            offsetof(CPUX86State,xmm_regs[rm].XMM_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].XMM_L(0)),

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

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

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

            }

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

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

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

                        offsetof(CPUX86State,xmm_regs[reg].XMM_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].XMM_Q(0)));

            } else {

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

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

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

            }

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

                        offsetof(CPUX86State,xmm_regs[reg].XMM_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].XMM_Q(1)));

            } else {

                /* movlhps */

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

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

                            offsetof(CPUX86State,xmm_regs[rm].XMM_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].XMM_L(1)),

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

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

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

            }

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

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

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

                        offsetof(CPUX86State,xmm_regs[reg].XMM_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_T[0], 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_T[0], 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_T[0], cpu_env,

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

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

            } else

#endif

            {

                tcg_gen_ld32u_tl(cpu_T[0], cpu_env,

                                 offsetof(CPUX86State,xmm_regs[reg].XMM_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].XMM_Q(0)));

            } else {

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

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

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

            }

            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_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_T[0], cpu_env, offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));

                gen_op_st_v(s, MO_32, cpu_T[0], cpu_A0);

            } else {

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

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

                            offsetof(CPUX86State,xmm_regs[reg].XMM_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].XMM_Q(0)));

            } else {

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

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

                            offsetof(CPUX86State,xmm_regs[reg].XMM_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].XMM_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].XMM_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 illegal_op;

            }

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

            if (is_xmm) {

                tcg_gen_movi_tl(cpu_T[0], val);

                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(0)));

                tcg_gen_movi_tl(cpu_T[0], 0);

                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_L(1)));

                op1_offset = offsetof(CPUX86State,xmm_t0);

            } else {

                tcg_gen_movi_tl(cpu_T[0], val);

                tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0)));

                tcg_gen_movi_tl(cpu_T[0], 0);

                tcg_gen_st32_tl(cpu_T[0], 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 illegal_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_T[0]);

                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_T[0]);

#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.XMM_Q(0)));

                } else {

                    gen_op_ld_v(s, MO_32, cpu_T[0], cpu_A0);

                    tcg_gen_st32_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,xmm_t0.XMM_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_T[0], 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_T[0], cpu_env, cpu_ptr0);

#else

                goto illegal_op;

#endif

            }

            gen_op_mov_reg_v(ot, reg, cpu_T[0]);

            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_T[0], cpu_env,

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

            } else {

                val &= 3;

                tcg_gen_st16_tl(cpu_T[0], 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_T[0], cpu_env,

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

            } else {

                val &= 3;

                rm = (modrm & 7);

                tcg_gen_ld16u_tl(cpu_T[0], cpu_env,

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

            }

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

            gen_op_mov_reg_v(ot, reg, cpu_T[0]);

            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].XMM_Q(0)));

            } else {

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

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

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

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

            }

            break;

        case 0x2d6: /* movq2dq */

            gen_helper_enter_mmx(cpu_env);

            rm = (modrm & 7);

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

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

            gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].XMM_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].XMM_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 illegal_op;

            }

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

            if (!sse_fn_epp) {

                goto illegal_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(XMMReg, XMM_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(XMMReg, XMM_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(XMMReg, XMM_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 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);

            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_T[0], cpu_tmp2_i32,

                                 cpu_T[0], tcg_const_i32(8 << ot));

                ot = mo_64_32(s->dflag);

                gen_op_mov_reg_v(ot, reg, cpu_T[0]);

                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_T[0], cpu_A0,

                                       s->mem_index, ot | MO_BE);

                    gen_op_mov_reg_v(ot, reg, cpu_T[0]);

                } 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_T[0], cpu_regs[s->vex_v], cpu_T[0]);

                gen_op_mov_reg_v(ot, reg, cpu_T[0]);

                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_T[0], cpu_T[0], cpu_A0);

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

                    zero = tcg_const_tl(0);

                    tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T[0], cpu_A0, bound,

                                       cpu_T[0], zero);

                    tcg_temp_free(zero);

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

                       operand size get all ones.  */

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

                    tcg_gen_ext8u_tl(cpu_A0, cpu_A0);

                    tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound,

                                       cpu_A0, bound);

                    tcg_temp_free(bound);

                    tcg_gen_movi_tl(cpu_T[1], 1);

                    tcg_gen_shl_tl(cpu_T[1], cpu_T[1], cpu_A0);

                    tcg_gen_subi_tl(cpu_T[1], cpu_T[1], 1);

                    tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);

                    gen_op_mov_reg_v(ot, reg, cpu_T[0]);

                    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_T[1], 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_T[1], bound);

                    tcg_gen_movcond_tl(TCG_COND_GT, cpu_T[1], cpu_T[1],

                                       bound, bound, cpu_T[1]);

                    tcg_temp_free(bound);

                }

                tcg_gen_movi_tl(cpu_A0, -1);

                tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T[1]);

                tcg_gen_andc_tl(cpu_T[0], cpu_T[0], cpu_A0);

                gen_op_mov_reg_v(ot, reg, cpu_T[0]);

                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_T[0]);

                    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_regs[s->vex_v], cpu_regs[reg],

                                      cpu_T[0], cpu_regs[R_EDX]);

                    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_T[1], cpu_regs[s->vex_v]);

                } else {

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

                }

                gen_helper_pdep(cpu_regs[reg], cpu_T[0], cpu_T[1]);

                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_T[1], cpu_regs[s->vex_v]);

                } else {

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

                }

                gen_helper_pext(cpu_regs[reg], cpu_T[0], cpu_T[1]);

                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_shri_tl(carry_in, cpu_cc_src,

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

                        tcg_gen_andi_tl(carry_in, carry_in, 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_T[0], cpu_T[0]);

                        tcg_gen_add_i64(cpu_T[0], cpu_T[0], cpu_regs[reg]);

                        tcg_gen_add_i64(cpu_T[0], cpu_T[0], carry_in);

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

                        tcg_gen_shri_i64(carry_out, cpu_T[0], 32);

                        break;

#endif

                    default:

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

                        zero = tcg_const_tl(0);

                        tcg_gen_add2_tl(cpu_T[0], carry_out,

                                        cpu_T[0], zero,

                                        carry_in, zero);

                        tcg_gen_add2_tl(cpu_regs[reg], carry_out,

                                        cpu_regs[reg], carry_out,

                                        cpu_T[0], 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_T[1], cpu_regs[s->vex_v], 63);

                } else {

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

                }

                if (b == 0x1f7) {

                    tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);

                } else if (b == 0x2f7) {

                    if (ot != MO_64) {

                        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);

                    }

                    tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);

                } else {

                    if (ot != MO_64) {

                        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);

                    }

                    tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);

                }

                gen_op_mov_reg_v(ot, reg, cpu_T[0]);

                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_T[1], cpu_T[0]);

                    tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);

                    gen_op_mov_reg_v(ot, s->vex_v, cpu_T[0]);

                    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_T[0]);

                    tcg_gen_subi_tl(cpu_T[0], cpu_T[0], 1);

                    tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_cc_src);

                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);

                    set_cc_op(s, CC_OP_BMILGB + ot);

                    break;

                case 3: /* blsi By, Ey */

                    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);

                    tcg_gen_subi_tl(cpu_T[0], cpu_T[0], 1);

                    tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_cc_src);

                    tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);

                    set_cc_op(s, CC_OP_BMILGB + ot);

                    break;

                default:

                    goto illegal_op;

                }

                break;

            default:

                goto illegal_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 illegal_op;

            }

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

            if (!sse_fn_eppi) {

                goto illegal_op;

            }

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

                goto illegal_op;

            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_T[0], cpu_env, offsetof(CPUX86State,

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

                    if (mod == 3) {

                        gen_op_mov_reg_v(ot, rm, cpu_T[0]);

                    } else {

                        tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0,

                                           s->mem_index, MO_UB);

                    }

                    break;

                case 0x15: /* pextrw */

                    tcg_gen_ld16u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,

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

                    if (mod == 3) {

                        gen_op_mov_reg_v(ot, rm, cpu_T[0]);

                    } else {

                        tcg_gen_qemu_st_tl(cpu_T[0], 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].XMM_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].XMM_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_T[0], cpu_env, offsetof(CPUX86State,

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

                    if (mod == 3) {

                        gen_op_mov_reg_v(ot, rm, cpu_T[0]);

                    } else {

                        tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0,

                                           s->mem_index, MO_LEUL);

                    }

                    break;

                case 0x20: /* pinsrb */

                    if (mod == 3) {

                        gen_op_mov_v_reg(MO_32, cpu_T[0], rm);

                    } else {

                        tcg_gen_qemu_ld_tl(cpu_T[0], cpu_A0,

                                           s->mem_index, MO_UB);

                    }

                    tcg_gen_st8_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,

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

                    break;

                case 0x21: /* insertps */

                    if (mod == 3) {

                        tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env,

                                        offsetof(CPUX86State,xmm_regs[rm]

                                                .XMM_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]

                                            .XMM_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].XMM_L(0)));

                    if ((val >> 1) & 1)

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

                                        cpu_env, offsetof(CPUX86State,

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

                    if ((val >> 2) & 1)

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

                                        cpu_env, offsetof(CPUX86State,

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

                    if ((val >> 3) & 1)

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

                                        cpu_env, offsetof(CPUX86State,

                                                xmm_regs[reg].XMM_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].XMM_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].XMM_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_T[0], cpu_T[0], b & 63);

                } else {

                    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);

                    tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31);

                    tcg_gen_extu_i32_tl(cpu_T[0], cpu_tmp2_i32);

                }

                gen_op_mov_reg_v(ot, reg, cpu_T[0]);

                break;

            default:

                goto illegal_op;

            }

            break;

        default:

            goto illegal_op;

        }

    } 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_T[0], cpu_A0);

                    tcg_gen_st32_tl(cpu_T[0], cpu_env,

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

                    break;

                case 3:

                    /* 64 bit access */

                    gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.XMM_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 */

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

                goto illegal_op;

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

            sse_fn_epp = sse_op_table5[val];

            if (!sse_fn_epp) {

                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 illegal_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 do_subfzeo_64 (void)

{

    T1 = T0;

    T0 = ~T0 + xer_ca;

    if (likely(!(((uint64_t)~T1 ^ UINT64_MAX) &

                 ((uint64_t)(~T1) ^ (uint64_t)T0) & (1ULL << 63)))) {

        xer_ov = 0;

    } else {

        xer_ov = 1;

        xer_so = 1;

    }

    if (likely((uint64_t)T0 >= (uint64_t)~T1)) {

        xer_ca = 0;

    } else {

        xer_ca = 1;

    }

}


av_cold int MPV_encode_init(AVCodecContext *avctx)

{

    MpegEncContext *s = avctx->priv_data;

    int i;

    int chroma_h_shift, chroma_v_shift;

    MPV_encode_defaults(s);

    switch (avctx->codec_id) {

    case CODEC_ID_MPEG2VIDEO:

        if(avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P){

            av_log(avctx, AV_LOG_ERROR, "only YUV420 and YUV422 are supported\n");

            return -1;

        }

        break;

    case CODEC_ID_LJPEG:

        if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P && avctx->pix_fmt != PIX_FMT_YUVJ444P && avctx->pix_fmt != PIX_FMT_RGB32 &&

           ((avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P && avctx->pix_fmt != PIX_FMT_YUV444P) || avctx->strict_std_compliance>FF_COMPLIANCE_UNOFFICIAL)){

            av_log(avctx, AV_LOG_ERROR, "colorspace not supported in LJPEG\n");

            return -1;

        }

        break;

    case CODEC_ID_MJPEG:

        if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P &&

           ((avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P) || avctx->strict_std_compliance>FF_COMPLIANCE_UNOFFICIAL)){

            av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n");

            return -1;

        }

        break;

    default:

        if(avctx->pix_fmt != PIX_FMT_YUV420P){

            av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n");

            return -1;

        }

    }

    switch (avctx->pix_fmt) {

    case PIX_FMT_YUVJ422P:

    case PIX_FMT_YUV422P:

        s->chroma_format = CHROMA_422;

        break;

    case PIX_FMT_YUVJ420P:

    case PIX_FMT_YUV420P:

    default:

        s->chroma_format = CHROMA_420;

        break;

    }

    s->bit_rate = avctx->bit_rate;

    s->width = avctx->width;

    s->height = avctx->height;

    if(avctx->gop_size > 600 && avctx->strict_std_compliance>FF_COMPLIANCE_EXPERIMENTAL){

        av_log(avctx, AV_LOG_ERROR, "Warning keyframe interval too large! reducing it ...\n");

        avctx->gop_size=600;

    }

    s->gop_size = avctx->gop_size;

    s->avctx = avctx;

    s->flags= avctx->flags;

    s->flags2= avctx->flags2;

    s->max_b_frames= avctx->max_b_frames;

    s->codec_id= avctx->codec->id;

    s->luma_elim_threshold  = avctx->luma_elim_threshold;

    s->chroma_elim_threshold= avctx->chroma_elim_threshold;

    s->strict_std_compliance= avctx->strict_std_compliance;

    s->data_partitioning= avctx->flags & CODEC_FLAG_PART;

    s->quarter_sample= (avctx->flags & CODEC_FLAG_QPEL)!=0;

    s->mpeg_quant= avctx->mpeg_quant;

    s->rtp_mode= !!avctx->rtp_payload_size;

    s->intra_dc_precision= avctx->intra_dc_precision;

    s->user_specified_pts = AV_NOPTS_VALUE;

    if (s->gop_size <= 1) {

        s->intra_only = 1;

        s->gop_size = 12;

    } else {

        s->intra_only = 0;

    }

    s->me_method = avctx->me_method;

    /* Fixed QSCALE */

    s->fixed_qscale = !!(avctx->flags & CODEC_FLAG_QSCALE);

    s->adaptive_quant= (   s->avctx->lumi_masking

                        || s->avctx->dark_masking

                        || s->avctx->temporal_cplx_masking

                        || s->avctx->spatial_cplx_masking

                        || s->avctx->p_masking

                        || s->avctx->border_masking

                        || (s->flags&CODEC_FLAG_QP_RD))

                       && !s->fixed_qscale;

    s->obmc= !!(s->flags & CODEC_FLAG_OBMC);

    s->loop_filter= !!(s->flags & CODEC_FLAG_LOOP_FILTER);

    s->alternate_scan= !!(s->flags & CODEC_FLAG_ALT_SCAN);

    s->intra_vlc_format= !!(s->flags2 & CODEC_FLAG2_INTRA_VLC);

    s->q_scale_type= !!(s->flags2 & CODEC_FLAG2_NON_LINEAR_QUANT);

    if(avctx->rc_max_rate && !avctx->rc_buffer_size){

        av_log(avctx, AV_LOG_ERROR, "a vbv buffer size is needed, for encoding with a maximum bitrate\n");

        return -1;

    }

    if(avctx->rc_min_rate && avctx->rc_max_rate != avctx->rc_min_rate){

        av_log(avctx, AV_LOG_INFO, "Warning min_rate > 0 but min_rate != max_rate isn't recommended!\n");

    }

    if(avctx->rc_min_rate && avctx->rc_min_rate > avctx->bit_rate){

        av_log(avctx, AV_LOG_ERROR, "bitrate below min bitrate\n");

        return -1;

    }

    if(avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate){

        av_log(avctx, AV_LOG_INFO, "bitrate above max bitrate\n");

        return -1;

    }

    if(avctx->rc_max_rate && avctx->rc_max_rate == avctx->bit_rate && avctx->rc_max_rate != avctx->rc_min_rate){

        av_log(avctx, AV_LOG_INFO, "impossible bitrate constraints, this will fail\n");

    }

    if(avctx->rc_buffer_size && avctx->bit_rate*(int64_t)avctx->time_base.num > avctx->rc_buffer_size * (int64_t)avctx->time_base.den){

        av_log(avctx, AV_LOG_ERROR, "VBV buffer too small for bitrate\n");

        return -1;

    }

    if(!s->fixed_qscale && avctx->bit_rate*av_q2d(avctx->time_base) > avctx->bit_rate_tolerance){

        av_log(avctx, AV_LOG_ERROR, "bitrate tolerance too small for bitrate\n");

        return -1;

    }

    if(   s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate

       && (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO)

       && 90000LL * (avctx->rc_buffer_size-1) > s->avctx->rc_max_rate*0xFFFFLL){

        av_log(avctx, AV_LOG_INFO, "Warning vbv_delay will be set to 0xFFFF (=VBR) as the specified vbv buffer is too large for the given bitrate!\n");

    }

    if((s->flags & CODEC_FLAG_4MV) && s->codec_id != CODEC_ID_MPEG4

       && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P && s->codec_id != CODEC_ID_FLV1){

        av_log(avctx, AV_LOG_ERROR, "4MV not supported by codec\n");

        return -1;

    }

    if(s->obmc && s->avctx->mb_decision != FF_MB_DECISION_SIMPLE){

        av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with simple mb decision\n");

        return -1;

    }

    if(s->obmc && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P){

        av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with H263(+)\n");

        return -1;

    }

    if(s->quarter_sample && s->codec_id != CODEC_ID_MPEG4){

        av_log(avctx, AV_LOG_ERROR, "qpel not supported by codec\n");

        return -1;

    }

    if(s->data_partitioning && s->codec_id != CODEC_ID_MPEG4){

        av_log(avctx, AV_LOG_ERROR, "data partitioning not supported by codec\n");

        return -1;

    }

    if(s->max_b_frames && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO){

        av_log(avctx, AV_LOG_ERROR, "b frames not supported by codec\n");

        return -1;

    }

    if ((s->codec_id == CODEC_ID_MPEG4 || s->codec_id == CODEC_ID_H263 ||

         s->codec_id == CODEC_ID_H263P) &&

        (avctx->sample_aspect_ratio.num > 255 || avctx->sample_aspect_ratio.den > 255)) {

        av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i, limit is 255/255\n",

               avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);

        return -1;

    }

    if((s->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN))

       && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG2VIDEO){

        av_log(avctx, AV_LOG_ERROR, "interlacing not supported by codec\n");

        return -1;

    }

    if(s->mpeg_quant && s->codec_id != CODEC_ID_MPEG4){ //FIXME mpeg2 uses that too

        av_log(avctx, AV_LOG_ERROR, "mpeg2 style quantization not supported by codec\n");

        return -1;

    }

    if((s->flags & CODEC_FLAG_CBP_RD) && !avctx->trellis){

        av_log(avctx, AV_LOG_ERROR, "CBP RD needs trellis quant\n");

        return -1;

    }

    if((s->flags & CODEC_FLAG_QP_RD) && s->avctx->mb_decision != FF_MB_DECISION_RD){

        av_log(avctx, AV_LOG_ERROR, "QP RD needs mbd=2\n");

        return -1;

    }

    if(s->avctx->scenechange_threshold < 1000000000 && (s->flags & CODEC_FLAG_CLOSED_GOP)){

        av_log(avctx, AV_LOG_ERROR, "closed gop with scene change detection are not supported yet, set threshold to 1000000000\n");

        return -1;

    }

    if((s->flags2 & CODEC_FLAG2_INTRA_VLC) && s->codec_id != CODEC_ID_MPEG2VIDEO){

        av_log(avctx, AV_LOG_ERROR, "intra vlc table not supported by codec\n");

        return -1;

    }

    if(s->flags & CODEC_FLAG_LOW_DELAY){

        if (s->codec_id != CODEC_ID_MPEG2VIDEO){

            av_log(avctx, AV_LOG_ERROR, "low delay forcing is only available for mpeg2\n");

            return -1;

        }

        if (s->max_b_frames != 0){

            av_log(avctx, AV_LOG_ERROR, "b frames cannot be used with low delay\n");

            return -1;

        }

    }

    if(s->q_scale_type == 1){

        if(s->codec_id != CODEC_ID_MPEG2VIDEO){

            av_log(avctx, AV_LOG_ERROR, "non linear quant is only available for mpeg2\n");

            return -1;

        }

        if(avctx->qmax > 12){

            av_log(avctx, AV_LOG_ERROR, "non linear quant only supports qmax <= 12 currently\n");

            return -1;

        }

    }

    if(s->avctx->thread_count > 1 && s->codec_id != CODEC_ID_MPEG4

       && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO

       && (s->codec_id != CODEC_ID_H263P || !(s->flags & CODEC_FLAG_H263P_SLICE_STRUCT))){

        av_log(avctx, AV_LOG_ERROR, "multi threaded encoding not supported by codec\n");

        return -1;

    }

    if(s->avctx->thread_count < 1){

        av_log(avctx, AV_LOG_ERROR, "automatic thread number detection not supported by codec, patch welcome\n");

        return -1;

    }

    if(s->avctx->thread_count > 1)

        s->rtp_mode= 1;

    if(!avctx->time_base.den || !avctx->time_base.num){

        av_log(avctx, AV_LOG_ERROR, "framerate not set\n");

        return -1;

    }

    i= (INT_MAX/2+128)>>8;

    if(avctx->me_threshold >= i){

        av_log(avctx, AV_LOG_ERROR, "me_threshold too large, max is %d\n", i - 1);

        return -1;

    }

    if(avctx->mb_threshold >= i){

        av_log(avctx, AV_LOG_ERROR, "mb_threshold too large, max is %d\n", i - 1);

        return -1;

    }

    if(avctx->b_frame_strategy && (avctx->flags&CODEC_FLAG_PASS2)){

        av_log(avctx, AV_LOG_INFO, "notice: b_frame_strategy only affects the first pass\n");

        avctx->b_frame_strategy = 0;

    }

    i= av_gcd(avctx->time_base.den, avctx->time_base.num);

    if(i > 1){

        av_log(avctx, AV_LOG_INFO, "removing common factors from framerate\n");

        avctx->time_base.den /= i;

        avctx->time_base.num /= i;

//        return -1;

    }

    if(s->mpeg_quant || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO || s->codec_id==CODEC_ID_MJPEG){

        s->intra_quant_bias= 3<<(QUANT_BIAS_SHIFT-3); //(a + x*3/8)/x

        s->inter_quant_bias= 0;

    }else{

        s->intra_quant_bias=0;

        s->inter_quant_bias=-(1<<(QUANT_BIAS_SHIFT-2)); //(a - x/4)/x

    }

    if(avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS)

        s->intra_quant_bias= avctx->intra_quant_bias;

    if(avctx->inter_quant_bias != FF_DEFAULT_QUANT_BIAS)

        s->inter_quant_bias= avctx->inter_quant_bias;

    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift);

    if(avctx->codec_id == CODEC_ID_MPEG4 && s->avctx->time_base.den > (1<<16)-1){

        av_log(avctx, AV_LOG_ERROR, "timebase not supported by mpeg 4 standard\n");

        return -1;

    }

    s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1;

    switch(avctx->codec->id) {

    case CODEC_ID_MPEG1VIDEO:

        s->out_format = FMT_MPEG1;

        s->low_delay= !!(s->flags & CODEC_FLAG_LOW_DELAY);

        avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1);

        break;

    case CODEC_ID_MPEG2VIDEO:

        s->out_format = FMT_MPEG1;

        s->low_delay= !!(s->flags & CODEC_FLAG_LOW_DELAY);

        avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1);

        s->rtp_mode= 1;

        break;

    case CODEC_ID_LJPEG:

    case CODEC_ID_MJPEG:

        s->out_format = FMT_MJPEG;

        s->intra_only = 1; /* force intra only for jpeg */

        if(avctx->codec->id == CODEC_ID_LJPEG && avctx->pix_fmt == PIX_FMT_BGRA){

            s->mjpeg_vsample[0] = s->mjpeg_hsample[0] =

            s->mjpeg_vsample[1] = s->mjpeg_hsample[1] =

            s->mjpeg_vsample[2] = s->mjpeg_hsample[2] = 1;

        }else{

            s->mjpeg_vsample[0] = 2;

            s->mjpeg_vsample[1] = 2>>chroma_v_shift;

            s->mjpeg_vsample[2] = 2>>chroma_v_shift;

            s->mjpeg_hsample[0] = 2;

            s->mjpeg_hsample[1] = 2>>chroma_h_shift;

            s->mjpeg_hsample[2] = 2>>chroma_h_shift;

        }

        if (!(CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER)

            || ff_mjpeg_encode_init(s) < 0)

            return -1;

        avctx->delay=0;

        s->low_delay=1;

        break;

    case CODEC_ID_H261:

        if (!CONFIG_H261_ENCODER)  return -1;

        if (ff_h261_get_picture_format(s->width, s->height) < 0) {

            av_log(avctx, AV_LOG_ERROR, "The specified picture size of %dx%d is not valid for the H.261 codec.\nValid sizes are 176x144, 352x288\n", s->width, s->height);

            return -1;

        }

        s->out_format = FMT_H261;

        avctx->delay=0;

        s->low_delay=1;

        break;

    case CODEC_ID_H263:

        if (!CONFIG_H263_ENCODER)  return -1;

        if (ff_match_2uint16(h263_format, FF_ARRAY_ELEMS(h263_format), s->width, s->height) == 8) {

            av_log(avctx, AV_LOG_INFO, "The specified picture size of %dx%d is not valid for the H.263 codec.\nValid sizes are 128x96, 176x144, 352x288, 704x576, and 1408x1152. Try H.263+.\n", s->width, s->height);

            return -1;

        }

        s->out_format = FMT_H263;

        s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0;

        avctx->delay=0;

        s->low_delay=1;

        break;

    case CODEC_ID_H263P:

        s->out_format = FMT_H263;

        s->h263_plus = 1;

        /* Fx */

        s->umvplus = (avctx->flags & CODEC_FLAG_H263P_UMV) ? 1:0;

        s->h263_aic= (avctx->flags & CODEC_FLAG_AC_PRED) ? 1:0;

        s->modified_quant= s->h263_aic;

        s->alt_inter_vlc= (avctx->flags & CODEC_FLAG_H263P_AIV) ? 1:0;

        s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0;

        s->loop_filter= (avctx->flags & CODEC_FLAG_LOOP_FILTER) ? 1:0;

        s->unrestricted_mv= s->obmc || s->loop_filter || s->umvplus;

        s->h263_slice_structured= (s->flags & CODEC_FLAG_H263P_SLICE_STRUCT) ? 1:0;

        /* /Fx */

        /* These are just to be sure */

        avctx->delay=0;

        s->low_delay=1;

        break;

    case CODEC_ID_FLV1:

        s->out_format = FMT_H263;

        s->h263_flv = 2; /* format = 1; 11-bit codes */

        s->unrestricted_mv = 1;

        s->rtp_mode=0; /* don't allow GOB */

        avctx->delay=0;

        s->low_delay=1;

        break;

    case CODEC_ID_RV10:

        s->out_format = FMT_H263;

        avctx->delay=0;

        s->low_delay=1;

        break;

    case CODEC_ID_RV20:

        s->out_format = FMT_H263;

        avctx->delay=0;

        s->low_delay=1;

        s->modified_quant=1;

        s->h263_aic=1;

        s->h263_plus=1;

        s->loop_filter=1;

        s->unrestricted_mv= 0;

        break;

    case CODEC_ID_MPEG4:

        s->out_format = FMT_H263;

        s->h263_pred = 1;

        s->unrestricted_mv = 1;

        s->low_delay= s->max_b_frames ? 0 : 1;

        avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1);

        break;

    case CODEC_ID_MSMPEG4V1:

        s->out_format = FMT_H263;

        s->h263_msmpeg4 = 1;

        s->h263_pred = 1;

        s->unrestricted_mv = 1;

        s->msmpeg4_version= 1;

        avctx->delay=0;

        s->low_delay=1;

        break;

    case CODEC_ID_MSMPEG4V2:

        s->out_format = FMT_H263;

        s->h263_msmpeg4 = 1;

        s->h263_pred = 1;

        s->unrestricted_mv = 1;

        s->msmpeg4_version= 2;

        avctx->delay=0;

        s->low_delay=1;

        break;

    case CODEC_ID_MSMPEG4V3:

        s->out_format = FMT_H263;

        s->h263_msmpeg4 = 1;

        s->h263_pred = 1;

        s->unrestricted_mv = 1;

        s->msmpeg4_version= 3;

        s->flipflop_rounding=1;

        avctx->delay=0;

        s->low_delay=1;

        break;

    case CODEC_ID_WMV1:

        s->out_format = FMT_H263;

        s->h263_msmpeg4 = 1;

        s->h263_pred = 1;

        s->unrestricted_mv = 1;

        s->msmpeg4_version= 4;

        s->flipflop_rounding=1;

        avctx->delay=0;

        s->low_delay=1;

        break;

    case CODEC_ID_WMV2:

        s->out_format = FMT_H263;

        s->h263_msmpeg4 = 1;

        s->h263_pred = 1;

        s->unrestricted_mv = 1;

        s->msmpeg4_version= 5;

        s->flipflop_rounding=1;

        avctx->delay=0;

        s->low_delay=1;

        break;

    default:

        return -1;

    }

    avctx->has_b_frames= !s->low_delay;

    s->encoding = 1;

    s->progressive_frame=

    s->progressive_sequence= !(avctx->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN));

    /* init */

    if (MPV_common_init(s) < 0)

        return -1;

    if(!s->dct_quantize)

        s->dct_quantize = dct_quantize_c;

    if(!s->denoise_dct)

        s->denoise_dct = denoise_dct_c;

    s->fast_dct_quantize = s->dct_quantize;

    if(avctx->trellis)

        s->dct_quantize = dct_quantize_trellis_c;

    if((CONFIG_H263P_ENCODER || CONFIG_RV20_ENCODER) && s->modified_quant)

        s->chroma_qscale_table= ff_h263_chroma_qscale_table;

    s->quant_precision=5;

    ff_set_cmp(&s->dsp, s->dsp.ildct_cmp, s->avctx->ildct_cmp);

    ff_set_cmp(&s->dsp, s->dsp.frame_skip_cmp, s->avctx->frame_skip_cmp);

    if (CONFIG_H261_ENCODER && s->out_format == FMT_H261)

        ff_h261_encode_init(s);

    if (CONFIG_H263_ENCODER && s->out_format == FMT_H263)

        h263_encode_init(s);

    if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version)

        ff_msmpeg4_encode_init(s);

    if ((CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)

        && s->out_format == FMT_MPEG1)

        ff_mpeg1_encode_init(s);

    /* init q matrix */

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

        int j= s->dsp.idct_permutation[i];

        if(CONFIG_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4 && s->mpeg_quant){

            s->intra_matrix[j] = ff_mpeg4_default_intra_matrix[i];

            s->inter_matrix[j] = ff_mpeg4_default_non_intra_matrix[i];

        }else if(s->out_format == FMT_H263 || s->out_format == FMT_H261){

            s->intra_matrix[j] =

            s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];

        }else

        { /* mpeg1/2 */

            s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i];

            s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];

        }

        if(s->avctx->intra_matrix)

            s->intra_matrix[j] = s->avctx->intra_matrix[i];

        if(s->avctx->inter_matrix)

            s->inter_matrix[j] = s->avctx->inter_matrix[i];

    }

    /* precompute matrix */

    /* for mjpeg, we do include qscale in the matrix */

    if (s->out_format != FMT_MJPEG) {

        ff_convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16,

                       s->intra_matrix, s->intra_quant_bias, avctx->qmin, 31, 1);

        ff_convert_matrix(&s->dsp, s->q_inter_matrix, s->q_inter_matrix16,

                       s->inter_matrix, s->inter_quant_bias, avctx->qmin, 31, 0);

    }

    if(ff_rate_control_init(s) < 0)

        return -1;

    return 0;

}


static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,

                                    TCGReg r1, int i2, int labelno)

{

    TCGLabel* l = &s->labels[labelno];

    tcg_target_long off;

    if (l->has_value) {

        off = l->u.value_ptr - s->code_ptr;

    } else {

        /* We need to keep the offset unchanged for retranslation.  */

        off = s->code_ptr[1];

        tcg_out_reloc(s, s->code_ptr + 1, R_390_PC16DBL, labelno, -2);

    }

    tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);

    tcg_out16(s, off);

    tcg_out16(s, (i2 << 8) | (opc & 0xff));

}


int find_utlb_entry(CPUState * env, target_ulong address, int use_asid)

{

    uint8_t urb, urc;

    /* Increment URC */

    urb = ((env->mmucr) >> 18) & 0x3f;

    urc = ((env->mmucr) >> 10) & 0x3f;

    urc++;

    if (urc == urb || urc == UTLB_SIZE - 1)

	urc = 0;

    env->mmucr = (env->mmucr & 0xffff03ff) | (urc << 10);

    /* Return entry */

    return find_tlb_entry(env, address, env->utlb, UTLB_SIZE, use_asid);

}


static void combine_addr(char *buf, size_t len, const char* address,

                         uint16_t port)

{

    /* If the address-part contains a colon, it's an IPv6 IP so needs [] */

    if (strstr(address, ":")) {

        snprintf(buf, len, "[%s]:%u", address, port);

    } else {

        snprintf(buf, len, "%s:%u", address, port);

    }

}


static int inline get_mb_score(MpegEncContext * s, int mx, int my, int src_index,

                               int ref_index)

{

//    const int check_luma= s->dsp.me_sub_cmp != s->dsp.mb_cmp;

    MotionEstContext * const c= &s->me;

    const int size= 0;

    const int h= 16;

    const int penalty_factor= c->mb_penalty_factor;

    const int flags= c->mb_flags;

    const int qpel= flags & FLAG_QPEL;

    const int mask= 1+2*qpel;

    me_cmp_func cmp_sub, chroma_cmp_sub;

    int d;

    LOAD_COMMON

 //FIXME factorize

    cmp_sub= s->dsp.mb_cmp[size];

    chroma_cmp_sub= s->dsp.mb_cmp[size+1];

    assert(!c->skip);

    assert(c->avctx->me_sub_cmp != c->avctx->mb_cmp);

    d= cmp(s, mx>>(qpel+1), my>>(qpel+1), mx&mask, my&mask, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);

    //FIXME check cbp before adding penalty for (0,0) vector

    if(mx || my || size>0)

        d += (mv_penalty[mx - pred_x] + mv_penalty[my - pred_y])*penalty_factor;

    return d;

}


av_cold void ff_dcadsp_init(DCADSPContext *s)

{

    s->lfe_fir[0] = dca_lfe_fir0_c;

    s->lfe_fir[1] = dca_lfe_fir1_c;

    s->qmf_32_subbands = dca_qmf_32_subbands;

    s->int8x8_fmul_int32 = int8x8_fmul_int32_c;

    if (ARCH_ARM) ff_dcadsp_init_arm(s);

    if (ARCH_X86) ff_dcadsp_init_x86(s);

}