static void migration_bitmap_sync_range(ram_addr_t start, ram_addr_t length)

{

    unsigned long *bitmap;

    bitmap = atomic_rcu_read(&migration_bitmap);

    migration_dirty_pages +=

        cpu_physical_memory_sync_dirty_bitmap(bitmap, start, length);

}


static int decode_frame_png(AVCodecContext *avctx,

                        void *data, int *got_frame,

                        AVPacket *avpkt)

{

    PNGDecContext *const s = avctx->priv_data;

    const uint8_t *buf     = avpkt->data;

    int buf_size           = avpkt->size;

    AVFrame *p;

    int64_t sig;

    int ret;

    ff_thread_release_buffer(avctx, &s->last_picture);

    FFSWAP(ThreadFrame, s->picture, s->last_picture);

    p = s->picture.f;

    bytestream2_init(&s->gb, buf, buf_size);

    /* check signature */

    sig = bytestream2_get_be64(&s->gb);

    if (sig != PNGSIG &&

        sig != MNGSIG) {

        av_log(avctx, AV_LOG_ERROR, "Invalid PNG signature 0x%08"PRIX64".\n", sig);

        return AVERROR_INVALIDDATA;

    }

    s->y = s->has_trns = 0;

    s->hdr_state = 0;

    s->pic_state = 0;

    /* init the zlib */

    s->zstream.zalloc = ff_png_zalloc;

    s->zstream.zfree  = ff_png_zfree;

    s->zstream.opaque = NULL;

    ret = inflateInit(&s->zstream);

    if (ret != Z_OK) {

        av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);

        return AVERROR_EXTERNAL;

    }

    if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)

        goto the_end;

    if (avctx->skip_frame == AVDISCARD_ALL) {

        *got_frame = 0;

        ret = bytestream2_tell(&s->gb);

        goto the_end;

    }

    if ((ret = av_frame_ref(data, s->picture.f)) < 0)

        return ret;

    *got_frame = 1;

    ret = bytestream2_tell(&s->gb);

the_end:

    inflateEnd(&s->zstream);

    s->crow_buf = NULL;

    return ret;

}


static int ass_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr,

                            AVPacket *avpkt)

{

    const char *ptr = avpkt->data;

    int len, size = avpkt->size;

    ff_ass_init(data);

    while (size > 0) {

        len = ff_ass_add_rect(data, ptr, 0, 0/* FIXME: duration */, 1);

        if (len < 0)

            return len;

        ptr  += len;

        size -= len;

    }

    *got_sub_ptr = avpkt->size > 0;

    return avpkt->size;

}


int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,

                                              AVFrame *frame,

                                              int *got_frame_ptr,

                                              const AVPacket *avpkt)

{

    AVCodecInternal *avci = avctx->internal;

    int ret = 0;

    *got_frame_ptr = 0;

    if (!avpkt->data && avpkt->size) {

        av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");

        return AVERROR(EINVAL);

    }

    if (!avctx->codec)

        return AVERROR(EINVAL);

    if (avctx->codec->type != AVMEDIA_TYPE_AUDIO) {

        av_log(avctx, AV_LOG_ERROR, "Invalid media type for audio\n");

        return AVERROR(EINVAL);

    }

    av_frame_unref(frame);

    if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) {

        uint8_t *side;

        int side_size;

        uint32_t discard_padding = 0;

        // copy to ensure we do not change avpkt

        AVPacket tmp = *avpkt;

        int did_split = av_packet_split_side_data(&tmp);

        ret = apply_param_change(avctx, &tmp);

        if (ret < 0) {

            av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n");

            if (avctx->err_recognition & AV_EF_EXPLODE)

                goto fail;

        }

        avctx->internal->pkt = &tmp;

        if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)

            ret = ff_thread_decode_frame(avctx, frame, got_frame_ptr, &tmp);

        else {

            ret = avctx->codec->decode(avctx, frame, got_frame_ptr, &tmp);

            frame->pkt_dts = avpkt->dts;

        }

        if (ret >= 0 && *got_frame_ptr) {

            add_metadata_from_side_data(avctx, frame);

            avctx->frame_number++;

            av_frame_set_best_effort_timestamp(frame,

                                               guess_correct_pts(avctx,

                                                                 frame->pkt_pts,

                                                                 frame->pkt_dts));

            if (frame->format == AV_SAMPLE_FMT_NONE)

                frame->format = avctx->sample_fmt;

            if (!frame->channel_layout)

                frame->channel_layout = avctx->channel_layout;

            if (!av_frame_get_channels(frame))

                av_frame_set_channels(frame, avctx->channels);

            if (!frame->sample_rate)

                frame->sample_rate = avctx->sample_rate;

        }

        side= av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);

        if(side && side_size>=10) {

            avctx->internal->skip_samples = AV_RL32(side);

            av_log(avctx, AV_LOG_DEBUG, "skip %d samples due to side data\n",

                   avctx->internal->skip_samples);

            discard_padding = AV_RL32(side + 4);

        }

        if (avctx->internal->skip_samples && *got_frame_ptr) {

            if(frame->nb_samples <= avctx->internal->skip_samples){

                *got_frame_ptr = 0;

                avctx->internal->skip_samples -= frame->nb_samples;

                av_log(avctx, AV_LOG_DEBUG, "skip whole frame, skip left: %d\n",

                       avctx->internal->skip_samples);

            } else {

                av_samples_copy(frame->extended_data, frame->extended_data, 0, avctx->internal->skip_samples,

                                frame->nb_samples - avctx->internal->skip_samples, avctx->channels, frame->format);

                if(avctx->pkt_timebase.num && avctx->sample_rate) {

                    int64_t diff_ts = av_rescale_q(avctx->internal->skip_samples,

                                                   (AVRational){1, avctx->sample_rate},

                                                   avctx->pkt_timebase);

                    if(frame->pkt_pts!=AV_NOPTS_VALUE)

                        frame->pkt_pts += diff_ts;

                    if(frame->pkt_dts!=AV_NOPTS_VALUE)

                        frame->pkt_dts += diff_ts;

                    if (av_frame_get_pkt_duration(frame) >= diff_ts)

                        av_frame_set_pkt_duration(frame, av_frame_get_pkt_duration(frame) - diff_ts);

                } else {

                    av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for skipped samples.\n");

                }

                av_log(avctx, AV_LOG_DEBUG, "skip %d/%d samples\n",

                       avctx->internal->skip_samples, frame->nb_samples);

                frame->nb_samples -= avctx->internal->skip_samples;

                avctx->internal->skip_samples = 0;

            }

        }

        if (discard_padding > 0 && discard_padding <= frame->nb_samples && *got_frame_ptr) {

            if (discard_padding == frame->nb_samples) {

                *got_frame_ptr = 0;

            } else {

                if(avctx->pkt_timebase.num && avctx->sample_rate) {

                    int64_t diff_ts = av_rescale_q(frame->nb_samples - discard_padding,

                                                   (AVRational){1, avctx->sample_rate},

                                                   avctx->pkt_timebase);

                    if (av_frame_get_pkt_duration(frame) >= diff_ts)

                        av_frame_set_pkt_duration(frame, av_frame_get_pkt_duration(frame) - diff_ts);

                } else {

                    av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for discarded samples.\n");

                }

                av_log(avctx, AV_LOG_DEBUG, "discard %d/%d samples\n",

                       discard_padding, frame->nb_samples);

                frame->nb_samples -= discard_padding;

            }

        }

fail:

        avctx->internal->pkt = NULL;

        if (did_split) {

            av_packet_free_side_data(&tmp);

            if(ret == tmp.size)

                ret = avpkt->size;

        }

        if (ret >= 0 && *got_frame_ptr) {

            if (!avctx->refcounted_frames) {

                int err = unrefcount_frame(avci, frame);

                if (err < 0)

                    return err;

            }

        } else

            av_frame_unref(frame);

    }

    return ret;

}


static int parse_dsd_diin(AVFormatContext *s, AVStream *st, uint64_t eof)

{

    AVIOContext *pb = s->pb;

    while (avio_tell(pb) + 12 <= eof) {

        uint32_t tag      = avio_rl32(pb);

        uint64_t size     = avio_rb64(pb);

        uint64_t orig_pos = avio_tell(pb);

        const char * metadata_tag = NULL;

        switch(tag) {

        case MKTAG('D','I','A','R'): metadata_tag = "artist"; break;

        case MKTAG('D','I','T','I'): metadata_tag = "title";  break;

        }

        if (metadata_tag && size > 4) {

            unsigned int tag_size = avio_rb32(pb);

            int ret = get_metadata(s, metadata_tag, FFMIN(tag_size, size - 4));

            if (ret < 0) {

                av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!\n", metadata_tag);

                return ret;

            }

        }

        avio_skip(pb, size - (avio_tell(pb) - orig_pos) + (size & 1));

    }

    return 0;

}


static unsigned tget_short(const uint8_t **p, int le)

{

    unsigned v = le ? AV_RL16(*p) : AV_RB16(*p);

    *p += 2;

    return v;

}


void checkasm_check_vf_interlace(void)

{

    check_lowpass_line(8);

    report("lowpass_line_8");

    check_lowpass_line(16);

    report("lowpass_line_16");

}


static int blk_mig_save_dirty_block(QEMUFile *f, int is_async)

{

    BlkMigDevState *bmds;

    int ret = 1;

    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {

        ret = mig_save_device_dirty(f, bmds, is_async);

        if (ret <= 0) {

            break;

        }

    }

    return ret;

}


static void qtrle_decode_32bpp(QtrleContext *s)

{

    int stream_ptr;

    int header;

    int start_line;

    int lines_to_change;

    signed char rle_code;

    int row_ptr, pixel_ptr;

    int row_inc = s->frame.linesize[0];

    unsigned char r, g, b;

    unsigned int argb;

    unsigned char *rgb = s->frame.data[0];

    int pixel_limit = s->frame.linesize[0] * s->avctx->height;

    /* check if this frame is even supposed to change */

    if (s->size < 8)

        return;

    /* start after the chunk size */

    stream_ptr = 4;

    /* fetch the header */

    CHECK_STREAM_PTR(2);

    header = BE_16(&s->buf[stream_ptr]);

    stream_ptr += 2;

    /* if a header is present, fetch additional decoding parameters */

    if (header & 0x0008) {

        CHECK_STREAM_PTR(8);

        start_line = BE_16(&s->buf[stream_ptr]);

        stream_ptr += 4;

        lines_to_change = BE_16(&s->buf[stream_ptr]);

        stream_ptr += 4;

    } else {

        start_line = 0;

        lines_to_change = s->avctx->height;

    }

    row_ptr = row_inc * start_line;

    while (lines_to_change--) {

        CHECK_STREAM_PTR(2);

        pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 4;

        while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {

            if (rle_code == 0) {

                /* there's another skip code in the stream */

                CHECK_STREAM_PTR(1);

                pixel_ptr += (s->buf[stream_ptr++] - 1) * 4;

                CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */

            } else if (rle_code < 0) {

                /* decode the run length code */

                rle_code = -rle_code;

                CHECK_STREAM_PTR(4);

                stream_ptr++;  /* skip the alpha (?) byte */

                r = s->buf[stream_ptr++];

                g = s->buf[stream_ptr++];

                b = s->buf[stream_ptr++];

                argb = (r << 16) | (g << 8) | (b << 0);

                CHECK_PIXEL_PTR(rle_code * 4);

                while (rle_code--) {

                    *(unsigned int *)(&rgb[pixel_ptr]) = argb;

                    pixel_ptr += 4;

                }

            } else {

                CHECK_STREAM_PTR(rle_code * 4);

                CHECK_PIXEL_PTR(rle_code * 4);

                /* copy pixels directly to output */

                while (rle_code--) {

                    stream_ptr++;  /* skip the alpha (?) byte */

                    r = s->buf[stream_ptr++];

                    g = s->buf[stream_ptr++];

                    b = s->buf[stream_ptr++];

                    argb = (r << 16) | (g << 8) | (b << 0);

                    *(unsigned int *)(&rgb[pixel_ptr]) = argb;

                    pixel_ptr += 4;

                }

            }

        }

        row_ptr += row_inc;

    }

}


static void scsi_command_complete(SCSIDiskReq *r, int status, int sense)

{

    DPRINTF("Command complete tag=0x%x status=%d sense=%d\n",

            r->req.tag, status, sense);

    scsi_req_set_status(r, status, sense);

    scsi_req_complete(&r->req);

    scsi_remove_request(r);

}


static int vio_make_devnode(VIOsPAPRDevice *dev,

                            void *fdt)

{

    VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);

    int vdevice_off, node_off, ret;

    char *dt_name;

    vdevice_off = fdt_path_offset(fdt, "/vdevice");

    if (vdevice_off < 0) {

        return vdevice_off;

    }

    dt_name = vio_format_dev_name(dev);

    if (!dt_name) {

        return -ENOMEM;

    }

    node_off = fdt_add_subnode(fdt, vdevice_off, dt_name);

    free(dt_name);

    if (node_off < 0) {

        return node_off;

    }

    ret = fdt_setprop_cell(fdt, node_off, "reg", dev->reg);

    if (ret < 0) {

        return ret;

    }

    if (pc->dt_type) {

        ret = fdt_setprop_string(fdt, node_off, "device_type",

                                 pc->dt_type);

        if (ret < 0) {

            return ret;

        }

    }

    if (pc->dt_compatible) {

        ret = fdt_setprop_string(fdt, node_off, "compatible",

                                 pc->dt_compatible);

        if (ret < 0) {

            return ret;

        }

    }

    if (dev->qirq) {

        uint32_t ints_prop[] = {cpu_to_be32(dev->vio_irq_num), 0};

        ret = fdt_setprop(fdt, node_off, "interrupts", ints_prop,

                          sizeof(ints_prop));

        if (ret < 0) {

            return ret;

        }

    }

    if (dev->rtce_window_size) {

        uint32_t dma_prop[] = {cpu_to_be32(dev->reg),

                               0, 0,

                               0, cpu_to_be32(dev->rtce_window_size)};

        ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-address-cells", 2);

        if (ret < 0) {

            return ret;

        }

        ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-size-cells", 2);

        if (ret < 0) {

            return ret;

        }

        ret = fdt_setprop(fdt, node_off, "ibm,my-dma-window", dma_prop,

                          sizeof(dma_prop));

        if (ret < 0) {

            return ret;

        }

    }

    if (pc->devnode) {

        ret = (pc->devnode)(dev, fdt, node_off);

        if (ret < 0) {

            return ret;

        }

    }

    return node_off;

}


static void uc32_cpu_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    CPUClass *cc = CPU_CLASS(oc);
    UniCore32CPUClass *ucc = UNICORE32_CPU_CLASS(oc);
    ucc->parent_realize = dc->realize;
    dc->realize = uc32_cpu_realizefn;
    cc->class_by_name = uc32_cpu_class_by_name;
    cc->has_work = uc32_cpu_has_work;
    cc->do_interrupt = uc32_cpu_do_interrupt;
    cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt;
    cc->dump_state = uc32_cpu_dump_state;
    cc->set_pc = uc32_cpu_set_pc;
#ifdef CONFIG_USER_ONLY
    cc->handle_mmu_fault = uc32_cpu_handle_mmu_fault;
#else
    cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
#endif
    dc->vmsd = &vmstate_uc32_cpu;
}


static int eval_refl(int *refl, const int16_t *coefs, RA144Context *ractx)

{

    int b, i, j;

    int buffer1[10];

    int buffer2[10];

    int *bp1 = buffer1;

    int *bp2 = buffer2;

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

        buffer2[i] = coefs[i];

    refl[9] = bp2[9];

    if ((unsigned) bp2[9] + 0x1000 > 0x1fff) {

        av_log(ractx, AV_LOG_ERROR, "Overflow. Broken sample?\n");

        return 1;

    }

    for (i=8; i >= 0; i--) {

        b = 0x1000-((bp2[i+1] * bp2[i+1]) >> 12);

        if (!b)

            b = -2;

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

            bp1[j] = ((bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12)) * (0x1000000 / b)) >> 12;

        refl[i] = bp1[i];

        if ((unsigned) bp1[i] + 0x1000 > 0x1fff)

            return 1;

        FFSWAP(int *, bp1, bp2);

    }

    return 0;

}


static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,

                                           const char *name,

                                           uint64_t ram_size)

{

    if (mem_path) {

#ifdef __linux__

        Error *err = NULL;

        memory_region_init_ram_from_file(mr, owner, name, ram_size, false,

                                         mem_path, &err);

        /* Legacy behavior: if allocation failed, fall back to

         * regular RAM allocation.

         */

        if (err) {

            error_report_err(err);

            memory_region_init_ram(mr, owner, name, ram_size, &error_abort);

        }

#else

        fprintf(stderr, "-mem-path not supported on this host\n");

        exit(1);

#endif

    } else {

        memory_region_init_ram(mr, owner, name, ram_size, &error_abort);

    }

    vmstate_register_ram_global(mr);

}


static void cmd646_cmd_write(void *opaque, target_phys_addr_t addr,

                             uint64_t data, unsigned size)

{

    CMD646BAR *cmd646bar = opaque;

    if (addr != 2 || size != 1) {

        return;

    }

    ide_cmd_write(cmd646bar->bus, addr + 2, data);

}


static void tcg_out_movi(TCGContext *s, TCGType type,

                         TCGReg ret, tcg_target_long arg)

{

    tcg_target_long hi, lo;

    /* A 13-bit constant sign-extended to 64-bits.  */

    if (check_fit_tl(arg, 13)) {

        tcg_out_movi_imm13(s, ret, arg);

        return;

    }

    /* A 32-bit constant, or 32-bit zero-extended to 64-bits.  */

    if (type == TCG_TYPE_I32 || arg == (uint32_t)arg) {

        tcg_out_sethi(s, ret, arg);

        if (arg & 0x3ff) {

            tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);

        }

        return;

    }

    /* A 32-bit constant sign-extended to 64-bits.  */

    if (check_fit_tl(arg, 32)) {

        tcg_out_sethi(s, ret, ~arg);

        tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);

        return;

    }

    /* A 64-bit constant decomposed into 2 32-bit pieces.  */

    lo = (int32_t)arg;

    if (check_fit_tl(lo, 13)) {

        hi = (arg - lo) >> 32;

        tcg_out_movi(s, TCG_TYPE_I32, ret, hi);

        tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);

        tcg_out_arithi(s, ret, ret, lo, ARITH_ADD);

    } else {

        hi = arg >> 32;

        tcg_out_movi(s, TCG_TYPE_I32, ret, hi);

        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T2, lo);

        tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);

        tcg_out_arith(s, ret, ret, TCG_REG_T2, ARITH_OR);

    }

}


int vnc_display_open(DisplayState *ds, const char *arg)

{

    struct sockaddr *addr;

    struct sockaddr_in iaddr;

#ifndef _WIN32

    struct sockaddr_un uaddr;

#endif

    int reuse_addr, ret;

    socklen_t addrlen;

    const char *p;

    VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;

    vnc_display_close(ds);

    if (strcmp(arg, "none") == 0)

	return 0;

    if (!(vs->display = strdup(arg)))

	return -1;

#ifndef _WIN32

    if (strstart(arg, "unix:", &p)) {

	addr = (struct sockaddr *)&uaddr;

	addrlen = sizeof(uaddr);

	vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);

	if (vs->lsock == -1) {

	    fprintf(stderr, "Could not create socket\n");

	    free(vs->display);

	    vs->display = NULL;

	    return -1;

	}

	uaddr.sun_family = AF_UNIX;

	memset(uaddr.sun_path, 0, 108);

	snprintf(uaddr.sun_path, 108, "%s", p);

	unlink(uaddr.sun_path);

    } else

#endif

    {

	addr = (struct sockaddr *)&iaddr;

	addrlen = sizeof(iaddr);

	if (parse_host_port(&iaddr, arg) < 0) {

	    fprintf(stderr, "Could not parse VNC address\n");

	    free(vs->display);

	    vs->display = NULL;

	    return -1;

	}

	iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);

	vs->lsock = socket(PF_INET, SOCK_STREAM, 0);

	if (vs->lsock == -1) {

	    fprintf(stderr, "Could not create socket\n");

	    free(vs->display);

	    vs->display = NULL;

	    return -1;

	}

	reuse_addr = 1;

	ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,

			 (const char *)&reuse_addr, sizeof(reuse_addr));

	if (ret == -1) {

	    fprintf(stderr, "setsockopt() failed\n");

	    close(vs->lsock);

	    vs->lsock = -1;

	    free(vs->display);

	    vs->display = NULL;

	    return -1;

	}

    }

    if (bind(vs->lsock, addr, addrlen) == -1) {

	fprintf(stderr, "bind() failed\n");

	close(vs->lsock);

	vs->lsock = -1;

	free(vs->display);

	vs->display = NULL;

	return -1;

    }

    if (listen(vs->lsock, 1) == -1) {

	fprintf(stderr, "listen() failed\n");

	close(vs->lsock);

	vs->lsock = -1;

	free(vs->display);

	vs->display = NULL;

	return -1;

    }

    return qemu_set_fd_handler2(vs->lsock, vnc_listen_poll, vnc_listen_read, NULL, vs);

}


static uint64_t msix_table_mmio_read(void *opaque, target_phys_addr_t addr,

                                     unsigned size)

{

    PCIDevice *dev = opaque;

    return pci_get_long(dev->msix_table + addr);

}


PCIBus *pci_device_root_bus(const PCIDevice *d)

{

    PCIBus *bus = d->bus;

    while (!pci_bus_is_root(bus)) {

        d = bus->parent_dev;

        assert(d != NULL);

        bus = d->bus;

    }

    return bus;

}


static int ftp_connect_data_connection(URLContext *h)

{

    int err;

    char buf[CONTROL_BUFFER_SIZE], opts_format[20];

    AVDictionary *opts = NULL;

    FTPContext *s = h->priv_data;

    if (!s->conn_data) {

        /* Enter passive mode */

        if ((err = ftp_passive_mode(s)) < 0) {

            av_dlog(h, "Set passive mode failed\n");

            return err;

        }

        /* Open data connection */

        ff_url_join(buf, sizeof(buf), "tcp", NULL, s->hostname, s->server_data_port, NULL);

        if (s->rw_timeout != -1) {

            snprintf(opts_format, sizeof(opts_format), "%d", s->rw_timeout);

            av_dict_set(&opts, "timeout", opts_format, 0);

        } /* if option is not given, don't pass it and let tcp use its own default */

        err = ffurl_open(&s->conn_data, buf, AVIO_FLAG_READ_WRITE,

                         &h->interrupt_callback, &opts);

        av_dict_free(&opts);

        if (err < 0)

            return err;

        if (s->position)

            if ((err = ftp_restart(s, s->position)) < 0)

                return err;

    }

    s->state = READY;

    return 0;

}


static BlockDriver *find_protocol(const char *filename)

{

    BlockDriver *drv1;

    char protocol[128];

    int len;

    const char *p;

#ifdef _WIN32

    if (is_windows_drive(filename) ||

        is_windows_drive_prefix(filename))

        return bdrv_find_format("raw");

#endif

    p = strchr(filename, ':');

    if (!p)

        return bdrv_find_format("raw");

    len = p - filename;

    if (len > sizeof(protocol) - 1)

        len = sizeof(protocol) - 1;

    memcpy(protocol, filename, len);

    protocol[len] = '\0';

    QLIST_FOREACH(drv1, &bdrv_drivers, list) {

        if (drv1->protocol_name &&

            !strcmp(drv1->protocol_name, protocol)) {

            return drv1;

        }

    }

    return NULL;

}


static void virtio_net_device_realize(DeviceState *dev, Error **errp)

{

    VirtIODevice *vdev = VIRTIO_DEVICE(dev);

    VirtIONet *n = VIRTIO_NET(dev);

    NetClientState *nc;

    int i;

    virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size);

    n->max_queues = MAX(n->nic_conf.queues, 1);

    n->vqs = g_malloc0(sizeof(VirtIONetQueue) * n->max_queues);

    n->vqs[0].rx_vq = virtio_add_queue(vdev, 256, virtio_net_handle_rx);

    n->curr_queues = 1;

    n->vqs[0].n = n;

    n->tx_timeout = n->net_conf.txtimer;

    if (n->net_conf.tx && strcmp(n->net_conf.tx, "timer")

                       && strcmp(n->net_conf.tx, "bh")) {

        error_report("virtio-net: "

                     "Unknown option tx=%s, valid options: \"timer\" \"bh\"",

                     n->net_conf.tx);

        error_report("Defaulting to \"bh\"");

    }

    if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) {

        n->vqs[0].tx_vq = virtio_add_queue(vdev, 256,

                                           virtio_net_handle_tx_timer);

        n->vqs[0].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, virtio_net_tx_timer,

                                               &n->vqs[0]);

    } else {

        n->vqs[0].tx_vq = virtio_add_queue(vdev, 256,

                                           virtio_net_handle_tx_bh);

        n->vqs[0].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[0]);

    }

    n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl);

    qemu_macaddr_default_if_unset(&n->nic_conf.macaddr);

    memcpy(&n->mac[0], &n->nic_conf.macaddr, sizeof(n->mac));

    n->status = VIRTIO_NET_S_LINK_UP;

    if (n->netclient_type) {

        /*

         * Happen when virtio_net_set_netclient_name has been called.

         */

        n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf,

                              n->netclient_type, n->netclient_name, n);

    } else {

        n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf,

                              object_get_typename(OBJECT(dev)), dev->id, n);

    }

    peer_test_vnet_hdr(n);

    if (peer_has_vnet_hdr(n)) {

        for (i = 0; i < n->max_queues; i++) {

            qemu_peer_using_vnet_hdr(qemu_get_subqueue(n->nic, i), true);

        }

        n->host_hdr_len = sizeof(struct virtio_net_hdr);

    } else {

        n->host_hdr_len = 0;

    }

    qemu_format_nic_info_str(qemu_get_queue(n->nic), n->nic_conf.macaddr.a);

    n->vqs[0].tx_waiting = 0;

    n->tx_burst = n->net_conf.txburst;

    virtio_net_set_mrg_rx_bufs(n, 0);

    n->promisc = 1; /* for compatibility */

    n->mac_table.macs = g_malloc0(MAC_TABLE_ENTRIES * ETH_ALEN);

    n->vlans = g_malloc0(MAX_VLAN >> 3);

    nc = qemu_get_queue(n->nic);

    nc->rxfilter_notify_enabled = 1;

    n->qdev = dev;

    register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION,

                    virtio_net_save, virtio_net_load, n);

    add_boot_device_path(n->nic_conf.bootindex, dev, "/ethernet-phy@0");

}


static int usbredir_handle_control(USBDevice *udev, USBPacket *p,

        int request, int value, int index, int length, uint8_t *data)

{

    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);

    struct usb_redir_control_packet_header control_packet;

    AsyncURB *aurb;

    /* Special cases for certain standard device requests */

    switch (request) {

    case DeviceOutRequest | USB_REQ_SET_ADDRESS:

        DPRINTF("set address %d\n", value);

        dev->dev.addr = value;

        return 0;

    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:

        return usbredir_set_config(dev, p, value & 0xff);

    case DeviceRequest | USB_REQ_GET_CONFIGURATION:

        return usbredir_get_config(dev, p);

    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:

        return usbredir_set_interface(dev, p, index, value);

    case InterfaceRequest | USB_REQ_GET_INTERFACE:

        return usbredir_get_interface(dev, p, index);

    }

    /* "Normal" ctrl requests */

    aurb = async_alloc(dev, p);

    /* Note request is (bRequestType << 8) | bRequest */

    DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",

            request >> 8, request & 0xff, value, index, length,

            aurb->packet_id);

    control_packet.request     = request & 0xFF;

    control_packet.requesttype = request >> 8;

    control_packet.endpoint    = control_packet.requesttype & USB_DIR_IN;

    control_packet.value       = value;

    control_packet.index       = index;

    control_packet.length      = length;

    aurb->control_packet       = control_packet;

    if (control_packet.requesttype & USB_DIR_IN) {

        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,

                                           &control_packet, NULL, 0);

    } else {

        usbredir_log_data(dev, "ctrl data out:", data, length);

        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,

                                           &control_packet, data, length);

    }

    usbredirparser_do_write(dev->parser);

    return USB_RET_ASYNC;

}


void helper_ldl_kernel(uint64_t t0, uint64_t t1)

{

    ldl_kernel(t1, t0);

}


static void test_visitor_out_any(TestOutputVisitorData *data,

                                 const void *unused)

{

    QObject *qobj;

    QInt *qint;

    QBool *qbool;

    QString *qstring;

    QDict *qdict;

    QObject *obj;

    qobj = QOBJECT(qint_from_int(-42));

    visit_type_any(data->ov, NULL, &qobj, &error_abort);

    obj = visitor_get(data);

    g_assert(qobject_type(obj) == QTYPE_QINT);

    g_assert_cmpint(qint_get_int(qobject_to_qint(obj)), ==, -42);

    qobject_decref(qobj);

    visitor_reset(data);

    qdict = qdict_new();

    qdict_put(qdict, "integer", qint_from_int(-42));

    qdict_put(qdict, "boolean", qbool_from_bool(true));

    qdict_put(qdict, "string", qstring_from_str("foo"));

    qobj = QOBJECT(qdict);

    visit_type_any(data->ov, NULL, &qobj, &error_abort);

    qobject_decref(qobj);

    qdict = qobject_to_qdict(visitor_get(data));

    g_assert(qdict);

    qobj = qdict_get(qdict, "integer");

    g_assert(qobj);

    qint = qobject_to_qint(qobj);

    g_assert(qint);

    g_assert_cmpint(qint_get_int(qint), ==, -42);

    qobj = qdict_get(qdict, "boolean");

    g_assert(qobj);

    qbool = qobject_to_qbool(qobj);

    g_assert(qbool);

    g_assert(qbool_get_bool(qbool) == true);

    qstring = qobject_to_qstring(qdict_get(qdict, "string"));

    g_assert(qstring);

    g_assert_cmpstr(qstring_get_str(qstring), ==, "foo");

}


static void handle_user_command(Monitor *mon, const char *cmdline)

{

    QDict *qdict;

    const mon_cmd_t *cmd;

    qdict = qdict_new();

    cmd = monitor_parse_command(mon, cmdline, qdict);

    if (!cmd)

        goto out;

    if (monitor_handler_is_async(cmd)) {

        user_async_cmd_handler(mon, cmd, qdict);

    } else if (monitor_handler_ported(cmd)) {

        monitor_call_handler(mon, cmd, qdict);

    } else {

        cmd->mhandler.cmd(mon, qdict);

    }

    if (monitor_has_error(mon))

        monitor_print_error(mon);

out:

    QDECREF(qdict);

}


static inline void RENAME(uyvytoyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,

	long width, long height,

	long lumStride, long chromStride, long srcStride)

{

	long y;

	const long chromWidth= width>>1;

	for(y=0; y<height; y+=2)

	{

#ifdef HAVE_MMX

		asm volatile(

			"xorl %%eax, %%eax		\n\t"

			"pcmpeqw %%mm7, %%mm7		\n\t"

			"psrlw $8, %%mm7		\n\t" // FF,00,FF,00...

			ASMALIGN16

			"1:				\n\t"

			PREFETCH" 64(%0, %%eax, 4)	\n\t"

			"movq (%0, %%eax, 4), %%mm0	\n\t" // UYVY UYVY(0)

			"movq 8(%0, %%eax, 4), %%mm1	\n\t" // UYVY UYVY(4)

			"movq %%mm0, %%mm2		\n\t" // UYVY UYVY(0)

			"movq %%mm1, %%mm3		\n\t" // UYVY UYVY(4)

			"pand %%mm7, %%mm0		\n\t" // U0V0 U0V0(0)

			"pand %%mm7, %%mm1		\n\t" // U0V0 U0V0(4)

			"psrlw $8, %%mm2		\n\t" // Y0Y0 Y0Y0(0)

			"psrlw $8, %%mm3		\n\t" // Y0Y0 Y0Y0(4)

			"packuswb %%mm1, %%mm0		\n\t" // UVUV UVUV(0)

			"packuswb %%mm3, %%mm2		\n\t" // YYYY YYYY(0)

			MOVNTQ" %%mm2, (%1, %%eax, 2)	\n\t"

			"movq 16(%0, %%eax, 4), %%mm1	\n\t" // UYVY UYVY(8)

			"movq 24(%0, %%eax, 4), %%mm2	\n\t" // UYVY UYVY(12)

			"movq %%mm1, %%mm3		\n\t" // UYVY UYVY(8)

			"movq %%mm2, %%mm4		\n\t" // UYVY UYVY(12)

			"pand %%mm7, %%mm1		\n\t" // U0V0 U0V0(8)

			"pand %%mm7, %%mm2		\n\t" // U0V0 U0V0(12)

			"psrlw $8, %%mm3		\n\t" // Y0Y0 Y0Y0(8)

			"psrlw $8, %%mm4		\n\t" // Y0Y0 Y0Y0(12)

			"packuswb %%mm2, %%mm1		\n\t" // UVUV UVUV(8)

			"packuswb %%mm4, %%mm3		\n\t" // YYYY YYYY(8)

			MOVNTQ" %%mm3, 8(%1, %%eax, 2)	\n\t"

			"movq %%mm0, %%mm2		\n\t" // UVUV UVUV(0)

			"movq %%mm1, %%mm3		\n\t" // UVUV UVUV(8)

			"psrlw $8, %%mm0		\n\t" // V0V0 V0V0(0)

			"psrlw $8, %%mm1		\n\t" // V0V0 V0V0(8)

			"pand %%mm7, %%mm2		\n\t" // U0U0 U0U0(0)

			"pand %%mm7, %%mm3		\n\t" // U0U0 U0U0(8)

			"packuswb %%mm1, %%mm0		\n\t" // VVVV VVVV(0)

			"packuswb %%mm3, %%mm2		\n\t" // UUUU UUUU(0)

			MOVNTQ" %%mm0, (%3, %%eax)	\n\t"

			MOVNTQ" %%mm2, (%2, %%eax)	\n\t"

			"addl $8, %%eax			\n\t"

			"cmpl %4, %%eax			\n\t"

			" jb 1b				\n\t"

			::"r"(src), "r"(ydst), "r"(udst), "r"(vdst), "g" (chromWidth)

			: "memory", "%eax"

		);

		ydst += lumStride;

		src  += srcStride;

		asm volatile(

			"xorl %%eax, %%eax		\n\t"

			ASMALIGN16

			"1:				\n\t"

			PREFETCH" 64(%0, %%eax, 4)	\n\t"

			"movq (%0, %%eax, 4), %%mm0	\n\t" // YUYV YUYV(0)

			"movq 8(%0, %%eax, 4), %%mm1	\n\t" // YUYV YUYV(4)

			"movq 16(%0, %%eax, 4), %%mm2	\n\t" // YUYV YUYV(8)

			"movq 24(%0, %%eax, 4), %%mm3	\n\t" // YUYV YUYV(12)

			"psrlw $8, %%mm0		\n\t" // Y0Y0 Y0Y0(0)

			"psrlw $8, %%mm1		\n\t" // Y0Y0 Y0Y0(4)

			"psrlw $8, %%mm2		\n\t" // Y0Y0 Y0Y0(8)

			"psrlw $8, %%mm3		\n\t" // Y0Y0 Y0Y0(12)

			"packuswb %%mm1, %%mm0		\n\t" // YYYY YYYY(0)

			"packuswb %%mm3, %%mm2		\n\t" // YYYY YYYY(8)

			MOVNTQ" %%mm0, (%1, %%eax, 2)	\n\t"

			MOVNTQ" %%mm2, 8(%1, %%eax, 2)	\n\t"

			"addl $8, %%eax			\n\t"

			"cmpl %4, %%eax			\n\t"

			" jb 1b				\n\t"

			::"r"(src), "r"(ydst), "r"(udst), "r"(vdst), "g" (chromWidth)

			: "memory", "%eax"

		);

#else

		long i;

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

		{

			udst[i] 	= src[4*i+0];

			ydst[2*i+0] 	= src[4*i+1];

			vdst[i] 	= src[4*i+2];

			ydst[2*i+1] 	= src[4*i+3];

		}

		ydst += lumStride;

		src  += srcStride;

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

		{

			ydst[2*i+0] 	= src[4*i+1];

			ydst[2*i+1] 	= src[4*i+3];

		}

#endif

		udst += chromStride;

		vdst += chromStride;

		ydst += lumStride;

		src  += srcStride;

	}

#ifdef HAVE_MMX

asm volatile(   EMMS" \n\t"

        	SFENCE" \n\t"

        	:::"memory");

#endif

}


static int do_create(struct iovec *iovec)

{

    int ret;

    V9fsString path;

    int flags, mode, uid, gid, cur_uid, cur_gid;

    v9fs_string_init(&path);

    ret = proxy_unmarshal(iovec, PROXY_HDR_SZ, "sdddd",

                          &path, &flags, &mode, &uid, &gid);

    if (ret < 0) {

        goto unmarshal_err_out;

    }

    cur_uid = geteuid();

    cur_gid = getegid();

    ret = setfsugid(uid, gid);

    if (ret < 0) {

        /*

         * On failure reset back to the

         * old uid/gid

         */

        ret = -errno;

        goto err_out;

    }

    ret = open(path.data, flags, mode);

    if (ret < 0) {

        ret = -errno;

    }

err_out:

    setfsugid(cur_uid, cur_gid);

unmarshal_err_out:

    v9fs_string_free(&path);

    return ret;

}


static unsigned int dec_movem_rm(DisasContext *dc)

{

	TCGv tmp;

	TCGv addr;

	int i;

	DIS(fprintf (logfile, "movem $r%u, [$r%u%s\n", dc->op2, dc->op1,

		     dc->postinc ? "+]" : "]"));

	cris_flush_cc_state(dc);

	tmp = tcg_temp_new(TCG_TYPE_TL);

	addr = tcg_temp_new(TCG_TYPE_TL);

	tcg_gen_movi_tl(tmp, 4);

	tcg_gen_mov_tl(addr, cpu_R[dc->op1]);

	for (i = 0; i <= dc->op2; i++) {

		/* Displace addr.  */

		/* Perform the store.  */

		gen_store(dc, addr, cpu_R[i], 4);

		tcg_gen_add_tl(addr, addr, tmp);

	}

	if (dc->postinc)

		tcg_gen_mov_tl(cpu_R[dc->op1], addr);

	cris_cc_mask(dc, 0);

	tcg_temp_free(tmp);

	tcg_temp_free(addr);

	return 2;

}


void event_notifier_init_fd(EventNotifier *e, int fd)

{

    e->fd = fd;

}


static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)

{

    /* smallest possible positive score so that raw is used if and only if no

     * other block driver works

     */

    return 1;

}


void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)

{

    int64_t value;

    if (v->type_uint64) {

        v->type_uint64(v, obj, name, errp);

    } else {

        value = *obj;

        v->type_int64(v, &value, name, errp);

        *obj = value;

    }

}


void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2,

                  uint32_t crfD)

{

    CPU_DoubleU farg1, farg2;

    uint32_t ret = 0;

    farg1.ll = arg1;

    farg2.ll = arg2;

    if (unlikely(float64_is_any_nan(farg1.d) ||

                 float64_is_any_nan(farg2.d))) {

        ret = 0x01UL;

    } else if (float64_lt(farg1.d, farg2.d, &env->fp_status)) {

        ret = 0x08UL;

    } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) {

        ret = 0x04UL;

    } else {

        ret = 0x02UL;

    }

    env->fpscr &= ~(0x0F << FPSCR_FPRF);

    env->fpscr |= ret << FPSCR_FPRF;

    env->crf[crfD] = ret;

    if (unlikely(ret == 0x01UL

                 && (float64_is_signaling_nan(farg1.d) ||

                     float64_is_signaling_nan(farg2.d)))) {

        /* sNaN comparison */

        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);

    }

}


static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)

{

    const char *rn = "invalid";

    if (sel != 0)

        check_insn(env, ctx, ISA_MIPS64);

    switch (reg) {

    case 0:

        switch (sel) {

        case 0:

            gen_op_mtc0_index();

            rn = "Index";

            break;

        case 1:

            check_mips_mt(env, ctx);

            gen_op_mtc0_mvpcontrol();

            rn = "MVPControl";

            break;

        case 2:

            check_mips_mt(env, ctx);

            /* ignored */

            rn = "MVPConf0";

            break;

        case 3:

            check_mips_mt(env, ctx);

            /* ignored */

            rn = "MVPConf1";

            break;

        default:

            goto die;

        }

        break;

    case 1:

        switch (sel) {

        case 0:

            /* ignored */

            rn = "Random";

            break;

        case 1:

            check_mips_mt(env, ctx);

            gen_op_mtc0_vpecontrol();

            rn = "VPEControl";

            break;

        case 2:

            check_mips_mt(env, ctx);

            gen_op_mtc0_vpeconf0();

            rn = "VPEConf0";

            break;

        case 3:

            check_mips_mt(env, ctx);

            gen_op_mtc0_vpeconf1();

            rn = "VPEConf1";

            break;

        case 4:

            check_mips_mt(env, ctx);

            gen_op_mtc0_yqmask();

            rn = "YQMask";

            break;

        case 5:

            check_mips_mt(env, ctx);

            gen_op_mtc0_vpeschedule();

            rn = "VPESchedule";

            break;

        case 6:

            check_mips_mt(env, ctx);

            gen_op_mtc0_vpeschefback();

            rn = "VPEScheFBack";

            break;

        case 7:

            check_mips_mt(env, ctx);

            gen_op_mtc0_vpeopt();

            rn = "VPEOpt";

            break;

        default:

            goto die;

        }

        break;

    case 2:

        switch (sel) {

        case 0:

            gen_op_mtc0_entrylo0();

            rn = "EntryLo0";

            break;

        case 1:

            check_mips_mt(env, ctx);

            gen_op_mtc0_tcstatus();

            rn = "TCStatus";

            break;

        case 2:

            check_mips_mt(env, ctx);

            gen_op_mtc0_tcbind();

            rn = "TCBind";

            break;

        case 3:

            check_mips_mt(env, ctx);

            gen_op_mtc0_tcrestart();

            rn = "TCRestart";

            break;

        case 4:

            check_mips_mt(env, ctx);

            gen_op_mtc0_tchalt();

            rn = "TCHalt";

            break;

        case 5:

            check_mips_mt(env, ctx);

            gen_op_mtc0_tccontext();

            rn = "TCContext";

            break;

        case 6:

            check_mips_mt(env, ctx);

            gen_op_mtc0_tcschedule();

            rn = "TCSchedule";

            break;

        case 7:

            check_mips_mt(env, ctx);

            gen_op_mtc0_tcschefback();

            rn = "TCScheFBack";

            break;

        default:

            goto die;

        }

        break;

    case 3:

        switch (sel) {

        case 0:

            gen_op_mtc0_entrylo1();

            rn = "EntryLo1";

            break;

        default:

            goto die;

        }

        break;

    case 4:

        switch (sel) {

        case 0:

            gen_op_mtc0_context();

            rn = "Context";

            break;

        case 1:

//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */

            rn = "ContextConfig";

//           break;

        default:

            goto die;

        }

        break;

    case 5:

        switch (sel) {

        case 0:

            gen_op_mtc0_pagemask();

            rn = "PageMask";

            break;

        case 1:

            check_insn(env, ctx, ISA_MIPS32R2);

            gen_op_mtc0_pagegrain();

            rn = "PageGrain";

            break;

        default:

            goto die;

        }

        break;

    case 6:

        switch (sel) {

        case 0:

            gen_op_mtc0_wired();

            rn = "Wired";

            break;

        case 1:

            check_insn(env, ctx, ISA_MIPS32R2);

            gen_op_mtc0_srsconf0();

            rn = "SRSConf0";

            break;

        case 2:

            check_insn(env, ctx, ISA_MIPS32R2);

            gen_op_mtc0_srsconf1();

            rn = "SRSConf1";

            break;

        case 3:

            check_insn(env, ctx, ISA_MIPS32R2);

            gen_op_mtc0_srsconf2();

            rn = "SRSConf2";

            break;

        case 4:

            check_insn(env, ctx, ISA_MIPS32R2);

            gen_op_mtc0_srsconf3();

            rn = "SRSConf3";

            break;

        case 5:

            check_insn(env, ctx, ISA_MIPS32R2);

            gen_op_mtc0_srsconf4();

            rn = "SRSConf4";

            break;

        default:

            goto die;

        }

        break;

    case 7:

        switch (sel) {

        case 0:

            check_insn(env, ctx, ISA_MIPS32R2);

            gen_op_mtc0_hwrena();

            rn = "HWREna";

            break;

        default:

            goto die;

        }

        break;

    case 8:

        /* ignored */

        rn = "BadVaddr";

        break;

    case 9:

        switch (sel) {

        case 0:

            gen_op_mtc0_count();

            rn = "Count";

            break;

        /* 6,7 are implementation dependent */

        default:

            goto die;

        }

        /* Stop translation as we may have switched the execution mode */

        ctx->bstate = BS_STOP;

        break;

    case 10:

        switch (sel) {

        case 0:

            gen_op_mtc0_entryhi();

            rn = "EntryHi";

            break;

        default:

            goto die;

        }

        break;

    case 11:

        switch (sel) {

        case 0:

            gen_op_mtc0_compare();

            rn = "Compare";

            break;

        /* 6,7 are implementation dependent */

        default:

            goto die;

        }

        /* Stop translation as we may have switched the execution mode */

        ctx->bstate = BS_STOP;

        break;

    case 12:

        switch (sel) {

        case 0:

            gen_op_mtc0_status();

            /* BS_STOP isn't good enough here, hflags may have changed. */

            gen_save_pc(ctx->pc + 4);

            ctx->bstate = BS_EXCP;

            rn = "Status";

            break;

        case 1:

            check_insn(env, ctx, ISA_MIPS32R2);

            gen_op_mtc0_intctl();

            /* Stop translation as we may have switched the execution mode */

            ctx->bstate = BS_STOP;

            rn = "IntCtl";

            break;

        case 2:

            check_insn(env, ctx, ISA_MIPS32R2);

            gen_op_mtc0_srsctl();

            /* Stop translation as we may have switched the execution mode */

            ctx->bstate = BS_STOP;

            rn = "SRSCtl";

            break;

        case 3:

            check_insn(env, ctx, ISA_MIPS32R2);

            gen_op_mtc0_srsmap();

            /* Stop translation as we may have switched the execution mode */

            ctx->bstate = BS_STOP;

            rn = "SRSMap";

            break;

        default:

            goto die;

        }

        break;

    case 13:

        switch (sel) {

        case 0:

            gen_op_mtc0_cause();

            rn = "Cause";

            break;

        default:

            goto die;

        }

        /* Stop translation as we may have switched the execution mode */

        ctx->bstate = BS_STOP;

        break;

    case 14:

        switch (sel) {

        case 0:

            gen_op_mtc0_epc();

            rn = "EPC";

            break;

        default:

            goto die;

        }

        break;

    case 15:

        switch (sel) {

        case 0:

            /* ignored */

            rn = "PRid";

            break;

        case 1:

            check_insn(env, ctx, ISA_MIPS32R2);

            gen_op_mtc0_ebase();

            rn = "EBase";

            break;

        default:

            goto die;

        }

        break;

    case 16:

        switch (sel) {

        case 0:

            gen_op_mtc0_config0();

            rn = "Config";

            /* Stop translation as we may have switched the execution mode */

            ctx->bstate = BS_STOP;

            break;

        case 1:

            /* ignored */

            rn = "Config1";

            break;

        case 2:

            gen_op_mtc0_config2();

            rn = "Config2";

            /* Stop translation as we may have switched the execution mode */

            ctx->bstate = BS_STOP;

            break;

        case 3:

            /* ignored */

            rn = "Config3";

            break;

        /* 6,7 are implementation dependent */

        default:

            rn = "Invalid config selector";

            goto die;

        }

        break;

    case 17:

        switch (sel) {

        case 0:

            /* ignored */

            rn = "LLAddr";

            break;

        default:

            goto die;

        }

        break;

    case 18:

        switch (sel) {

        case 0 ... 7:

            gen_op_mtc0_watchlo(sel);

            rn = "WatchLo";

            break;

        default:

            goto die;

        }

        break;

    case 19:

        switch (sel) {

        case 0 ... 7:

            gen_op_mtc0_watchhi(sel);

            rn = "WatchHi";

            break;

        default:

            goto die;

        }

        break;

    case 20:

        switch (sel) {

        case 0:

            check_insn(env, ctx, ISA_MIPS3);

            gen_op_mtc0_xcontext();

            rn = "XContext";

            break;

        default:

            goto die;

        }

        break;

    case 21:

       /* Officially reserved, but sel 0 is used for R1x000 framemask */

        switch (sel) {

        case 0:

            gen_op_mtc0_framemask();

            rn = "Framemask";

            break;

        default:

            goto die;

        }

        break;

    case 22:

        /* ignored */

        rn = "Diagnostic"; /* implementation dependent */

        break;

    case 23:

        switch (sel) {

        case 0:

            gen_op_mtc0_debug(); /* EJTAG support */

            /* BS_STOP isn't good enough here, hflags may have changed. */

            gen_save_pc(ctx->pc + 4);

            ctx->bstate = BS_EXCP;

            rn = "Debug";

            break;

        case 1:

//            gen_op_mtc0_tracecontrol(); /* PDtrace support */

            /* Stop translation as we may have switched the execution mode */

            ctx->bstate = BS_STOP;

            rn = "TraceControl";

//            break;

        case 2:

//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */

            /* Stop translation as we may have switched the execution mode */

            ctx->bstate = BS_STOP;

            rn = "TraceControl2";

//            break;

        case 3:

//            gen_op_mtc0_usertracedata(); /* PDtrace support */

            /* Stop translation as we may have switched the execution mode */

            ctx->bstate = BS_STOP;

            rn = "UserTraceData";

//            break;

        case 4:

//            gen_op_mtc0_debug(); /* PDtrace support */

            /* Stop translation as we may have switched the execution mode */

            ctx->bstate = BS_STOP;

            rn = "TraceBPC";

//            break;

        default:

            goto die;

        }

        break;

    case 24:

        switch (sel) {

        case 0:

            gen_op_mtc0_depc(); /* EJTAG support */

            rn = "DEPC";

            break;

        default:

            goto die;

        }

        break;

    case 25:

        switch (sel) {

        case 0:

            gen_op_mtc0_performance0();

            rn = "Performance0";

            break;

        case 1:

//            gen_op_mtc0_performance1();

            rn = "Performance1";

//            break;

        case 2:

//            gen_op_mtc0_performance2();

            rn = "Performance2";

//            break;

        case 3:

//            gen_op_mtc0_performance3();

            rn = "Performance3";

//            break;

        case 4:

//            gen_op_mtc0_performance4();

            rn = "Performance4";

//            break;

        case 5:

//            gen_op_mtc0_performance5();

            rn = "Performance5";

//            break;

        case 6:

//            gen_op_mtc0_performance6();

            rn = "Performance6";

//            break;

        case 7:

//            gen_op_mtc0_performance7();

            rn = "Performance7";

//            break;

        default:

            goto die;

        }

        break;

    case 26:

        /* ignored */

        rn = "ECC";

        break;

    case 27:

        switch (sel) {

        case 0 ... 3:

            /* ignored */

            rn = "CacheErr";

            break;

        default:

            goto die;

        }

        break;

    case 28:

        switch (sel) {

        case 0:

        case 2:

        case 4:

        case 6:

            gen_op_mtc0_taglo();

            rn = "TagLo";

            break;

        case 1:

        case 3:

        case 5:

        case 7:

            gen_op_mtc0_datalo();

            rn = "DataLo";

            break;

        default:

            goto die;

        }

        break;

    case 29:

        switch (sel) {

        case 0:

        case 2:

        case 4:

        case 6:

            gen_op_mtc0_taghi();

            rn = "TagHi";

            break;

        case 1:

        case 3:

        case 5:

        case 7:

            gen_op_mtc0_datahi();

            rn = "DataHi";

            break;

        default:

            rn = "invalid sel";

            goto die;

        }

        break;

    case 30:

        switch (sel) {

        case 0:

            gen_op_mtc0_errorepc();

            rn = "ErrorEPC";

            break;

        default:

            goto die;

        }

        break;

    case 31:

        switch (sel) {

        case 0:

            gen_op_mtc0_desave(); /* EJTAG support */

            rn = "DESAVE";

            break;

        default:

            goto die;

        }

        /* Stop translation as we may have switched the execution mode */

        ctx->bstate = BS_STOP;

        break;

    default:

        goto die;

    }

#if defined MIPS_DEBUG_DISAS

    if (loglevel & CPU_LOG_TB_IN_ASM) {

        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",

                rn, reg, sel);

    }

#endif

    return;

die:

#if defined MIPS_DEBUG_DISAS

    if (loglevel & CPU_LOG_TB_IN_ASM) {

        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",

                rn, reg, sel);

    }

#endif

    generate_exception(ctx, EXCP_RI);

}


static void scsi_write_data(SCSIRequest *req)

{

    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);

    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);

    SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));

    /* No data transfer may already be in progress */

    assert(r->req.aiocb == NULL);

    /* The request is used as the AIO opaque value, so add a ref.  */

    scsi_req_ref(&r->req);

    if (r->req.cmd.mode != SCSI_XFER_TO_DEV) {

        DPRINTF("Data transfer direction invalid\n");

        scsi_write_complete_noio(r, -EINVAL);

        return;

    }

    if (!r->req.sg && !r->qiov.size) {

        /* Called for the first time.  Ask the driver to send us more data.  */

        r->started = true;

        scsi_write_complete_noio(r, 0);

        return;

    }

    if (s->tray_open) {

        scsi_write_complete_noio(r, -ENOMEDIUM);

        return;

    }

    if (r->req.cmd.buf[0] == VERIFY_10 || r->req.cmd.buf[0] == VERIFY_12 ||

        r->req.cmd.buf[0] == VERIFY_16) {

        if (r->req.sg) {

            scsi_dma_complete_noio(r, 0);

        } else {

            scsi_write_complete_noio(r, 0);

        }

        return;

    }

    if (r->req.sg) {

        dma_acct_start(s->qdev.conf.blk, &r->acct, r->req.sg, BLOCK_ACCT_WRITE);

        r->req.resid -= r->req.sg->size;

        r->req.aiocb = dma_blk_io(blk_get_aio_context(s->qdev.conf.blk),

                                  r->req.sg, r->sector << BDRV_SECTOR_BITS,

                                  sdc->dma_writev, r, scsi_dma_complete, r,

                                  DMA_DIRECTION_TO_DEVICE);

    } else {

        block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,

                         r->qiov.size, BLOCK_ACCT_WRITE);

        r->req.aiocb = sdc->dma_writev(r->sector << BDRV_SECTOR_BITS, &r->qiov,

                                       scsi_write_complete, r, r);

    }

}


static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,

                                        const uint8_t *in, uint32_t in_len,

                                        uint8_t *out, uint32_t out_len)

{

    int ret;

    tpm_pt->tpm_op_canceled = false;

    tpm_pt->tpm_executing = true;

    ret = tpm_passthrough_unix_write(tpm_pt->tpm_fd, in, in_len);

    if (ret != in_len) {

        if (!tpm_pt->tpm_op_canceled ||

            (tpm_pt->tpm_op_canceled && errno != ECANCELED)) {

            error_report("tpm_passthrough: error while transmitting data "

                         "to TPM: %s (%i)\n",

                         strerror(errno), errno);

        }

        goto err_exit;

    }

    tpm_pt->tpm_executing = false;

    ret = tpm_passthrough_unix_read(tpm_pt->tpm_fd, out, out_len);

    if (ret < 0) {

        if (!tpm_pt->tpm_op_canceled ||

            (tpm_pt->tpm_op_canceled && errno != ECANCELED)) {

            error_report("tpm_passthrough: error while reading data from "

                         "TPM: %s (%i)\n",

                         strerror(errno), errno);

        }

    } else if (ret < sizeof(struct tpm_resp_hdr) ||

               tpm_passthrough_get_size_from_buffer(out) != ret) {

        ret = -1;

        error_report("tpm_passthrough: received invalid response "

                     "packet from TPM\n");

    }

err_exit:

    if (ret < 0) {

        tpm_write_fatal_error_response(out, out_len);

    }

    tpm_pt->tpm_executing = false;

    return ret;

}


static int get_str(char *buf, int buf_size, const char **pp)

{

    const char *p;

    char *q;

    int c;

    q = buf;

    p = *pp;

    while (qemu_isspace(*p))

        p++;

    if (*p == '\0') {

    fail:

        *q = '\0';

        *pp = p;

        return -1;

    }

    if (*p == '\"') {

        p++;

        while (*p != '\0' && *p != '\"') {

            if (*p == '\\') {

                p++;

                c = *p++;

                switch(c) {

                case 'n':

                    c = '\n';

                    break;

                case 'r':

                    c = '\r';

                    break;

                case '\\':

                case '\'':

                case '\"':

                    break;

                default:

                    qemu_printf("unsupported escape code: '\\%c'\n", c);

                    goto fail;

                }

                if ((q - buf) < buf_size - 1) {

                    *q++ = c;

                }

            } else {

                if ((q - buf) < buf_size - 1) {

                    *q++ = *p;

                }

                p++;

            }

        }

        if (*p != '\"') {

            qemu_printf("unterminated string\n");

            goto fail;

        }

        p++;

    } else {

        while (*p != '\0' && !qemu_isspace(*p)) {

            if ((q - buf) < buf_size - 1) {

                *q++ = *p;

            }

            p++;

        }

    }

    *q = '\0';

    *pp = p;

    return 0;

}


static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
{
    // For PCE based channel configurations map the channels solely based on tags.
    if (!ac->oc[1].m4ac.chan_config) {
        return ac->tag_che_map[type][elem_id];
    }
    // Allow single CPE stereo files to be signalled with mono configuration.
    if (!ac->tags_mapped && type == TYPE_CPE && ac->oc[1].m4ac.chan_config == 1) {
        uint8_t layout_map[MAX_ELEM_ID*4][3];
        int layout_map_tags;
        push_output_configuration(ac);
        if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags,
                                       2) < 0)
            return NULL;
        if (output_configure(ac, layout_map, layout_map_tags,
                             2, OC_TRIAL_FRAME) < 0)
            return NULL;
        ac->oc[1].m4ac.chan_config = 2;
    }
    // And vice-versa
    if (!ac->tags_mapped && type == TYPE_SCE && ac->oc[1].m4ac.chan_config == 2 && 0) {
        uint8_t layout_map[MAX_ELEM_ID*4][3];
        int layout_map_tags;
        push_output_configuration(ac);
        av_log(ac->avctx, AV_LOG_DEBUG, "stereo with SCE\n");
        if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags,
                                       1) < 0)
            return NULL;
        if (output_configure(ac, layout_map, layout_map_tags,
                             1, OC_TRIAL_FRAME) < 0)
            return NULL;
        ac->oc[1].m4ac.chan_config = 1;
    }
    // For indexed channel configurations map the channels solely based on position.
    switch (ac->oc[1].m4ac.chan_config) {
    case 7:
        if (ac->tags_mapped == 3 && type == TYPE_CPE) {
            ac->tags_mapped++;
            return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2];
        }
    case 6:
        /* Some streams incorrectly code 5.1 audio as SCE[0] CPE[0] CPE[1] SCE[1]
           instead of SCE[0] CPE[0] CPE[1] LFE[0]. If we seem to have
           encountered such a stream, transfer the LFE[0] element to the SCE[1]'s mapping */
        if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
            ac->tags_mapped++;
            return ac->tag_che_map[type][elem_id] = ac->che[TYPE_LFE][0];
        }
    case 5:
        if (ac->tags_mapped == 2 && type == TYPE_CPE) {
            ac->tags_mapped++;
            return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][1];
        }
    case 4:
        if (ac->tags_mapped == 2 && ac->oc[1].m4ac.chan_config == 4 && type == TYPE_SCE) {
            ac->tags_mapped++;
            return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1];
        }
    case 3:
    case 2:
        if (ac->tags_mapped == (ac->oc[1].m4ac.chan_config != 2) && type == TYPE_CPE) {
            ac->tags_mapped++;
            return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][0];
        } else if (ac->oc[1].m4ac.chan_config == 2) {
            return NULL;
        }
    case 1:
        if (!ac->tags_mapped && type == TYPE_SCE) {
            ac->tags_mapped++;
            return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][0];
        }
    default:
        return NULL;
    }
}


static void hpet_reset(void *opaque) {

    HPETState *s = opaque;

    int i;

    static int count = 0;

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

        HPETTimer *timer = &s->timer[i];

        hpet_del_timer(timer);

        timer->tn = i;

        timer->cmp = ~0ULL;

        timer->config =  HPET_TN_PERIODIC_CAP | HPET_TN_SIZE_CAP;

        /* advertise availability of ioapic inti2 */

        timer->config |=  0x00000004ULL << 32;

        timer->state = s;

        timer->period = 0ULL;

        timer->wrap_flag = 0;

    }

    s->hpet_counter = 0ULL;

    s->hpet_offset = 0ULL;

    /* 64-bit main counter; 3 timers supported; LegacyReplacementRoute. */

    s->capability = 0x8086a201ULL;

    s->capability |= ((HPET_CLK_PERIOD) << 32);

    s->config = 0ULL;

    if (count > 0)

        /* we don't enable pit when hpet_reset is first called (by hpet_init)

         * because hpet is taking over for pit here. On subsequent invocations,

         * hpet_reset is called due to system reset. At this point control must

         * be returned to pit until SW reenables hpet.

         */

        hpet_pit_enable();

    count = 1;

}


int bdrv_pread(BlockDriverState *bs, int64_t offset,

               void *buf1, int count1)

{

    BlockDriver *drv = bs->drv;

    if (!drv)

        return -ENOMEDIUM;

    if (!drv->bdrv_pread)

        return bdrv_pread_em(bs, offset, buf1, count1);

    return drv->bdrv_pread(bs, offset, buf1, count1);

}


static void schedule_refresh(VideoState *is, int delay)

{

    if(!delay) delay=1; //SDL seems to be buggy when the delay is 0

    SDL_AddTimer(delay, sdl_refresh_timer_cb, is);

}


static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, int frame_off)

{

    int val, saved_val = 0;

    int tmplen = src_len;

    const uint8_t *src, *source_end = source + src_len;

    uint8_t *frame_end = frame + SCREEN_WIDE * SCREEN_HIGH;

    uint8_t *dst, *dst_end;

    int len, mask;

    int forward = (frame_off <= -SCREEN_WIDE) || (frame_off >= 0);

    int read_two_nibbles, flag;

    int advance_mode;

    int mode = 0;

    int i;

    if (src_len <= 0)

        return -1;

    if (forward) {

        src = source;

        dst = frame;

        dst_end = frame_end;

    } else {

        src = source + src_len - 1;

        dst = frame_end - 1;

        dst_end = frame - 1;

    }

    for (;;) {

        int shift = 0;

        flag = 0;

        /* The mode/len decoding is a bit strange:

         * values are coded as variable-length codes with nibble units,

         * code end is signalled by two top bits in the nibble being nonzero.

         * And since data is bytepacked and we read two nibbles at a time,

         * we may get a nibble belonging to the next code.

         * Hence this convoluted loop.

         */

        if (!mode || (tmplen == 4)) {

            if (src < source || src >= source_end)

                return -1;

            val = *src;

            read_two_nibbles = 1;

        } else {

            val = saved_val;

            read_two_nibbles = 0;

        }

        if (!(val & 0xC)) {

            for (;;) {

                if (!read_two_nibbles) {

                    if (src < source || src >= source_end)

                        return -1;

                    shift += 2;

                    val |= *src << shift;

                    if (*src & 0xC)

                        break;

                }

                // two upper bits of the nibble is zero,

                // so shift top nibble value down into their place

                read_two_nibbles = 0;

                shift += 2;

                mask = (1 << shift) - 1;

                val = ((val >> 2) & ~mask) | (val & mask);

                NEXT_BYTE(src);

                if ((val & (0xC << shift))) {

                    flag = 1;

                    break;

                }

            }

        } else if (mode) {

            flag = tmplen != 4;

        }

        if (flag) {

            tmplen = 4;

        } else {

            saved_val = val >> (4 + shift);

            tmplen = 0;

            val &= (1 << (shift + 4)) - 1;

            NEXT_BYTE(src);

        }

        advance_mode = val & 1;

        len = (val >> 1) - 1;

        mode += 1 + advance_mode;

        if (mode >= 4)

            mode -= 3;

        if (FFABS(dst_end - dst) < len)

            return -1;

        switch (mode) {

        case 1:

            if (forward) {

                if (dst - frame + SCREEN_WIDE < frame_off ||

                        frame_end - dst < frame_off + len)

                    return -1;

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

                    dst[i] = dst[frame_off + i];

                dst += len;

            } else {

                dst -= len;

                if (dst - frame + SCREEN_WIDE < frame_off ||

                        frame_end - dst < frame_off + len)

                    return -1;

                for (i = len - 1; i >= 0; i--)

                    dst[i] = dst[frame_off + i];

            }

            break;

        case 2:

            if (forward) {

                if (source + src_len - src < len)

                    return -1;

                memcpy(dst, src, len);

                dst += len;

                src += len;

            } else {

                if (src - source < len)

                    return -1;

                dst -= len;

                src -= len;

                memcpy(dst, src, len);

            }

            break;

        case 3:

            val = forward ? dst[-1] : dst[1];

            if (forward) {

                memset(dst, val, len);

                dst += len;

            } else {

                dst -= len;

                memset(dst, val, len);

            }

            break;

        default:

            break;

        }

        if (dst == dst_end)

            return 0;

    }

    return 0;

}


static inline void encode_dc(MpegEncContext *s, int diff, int component)

{

    if (((unsigned) (diff + 255)) >= 511) {

        int index;

        if (diff < 0) {

            index = av_log2_16bit(-2 * diff);

            diff--;

        } else {

            index = av_log2_16bit(2 * diff);

        }

        if (component == 0)

            put_bits(&s->pb,

                     ff_mpeg12_vlc_dc_lum_bits[index] + index,

                     (ff_mpeg12_vlc_dc_lum_code[index] << index) +

                     (diff & ((1 << index) - 1)));

        else

            put_bits(&s->pb,

                     ff_mpeg12_vlc_dc_chroma_bits[index] + index,

                     (ff_mpeg12_vlc_dc_chroma_code[index] << index) +

                     (diff & ((1 << index) - 1)));

    } else {

        if (component == 0)

            put_bits(&s->pb,

                     mpeg1_lum_dc_uni[diff + 255] & 0xFF,

                     mpeg1_lum_dc_uni[diff + 255] >> 8);

        else

            put_bits(&s->pb,

                     mpeg1_chr_dc_uni[diff + 255] & 0xFF,

                     mpeg1_chr_dc_uni[diff + 255] >> 8);

    }

}


static int tgv_decode_inter(TgvContext * s, const uint8_t *buf, const uint8_t *buf_end){

    unsigned char *frame0_end = s->last_frame.data[0] + s->avctx->width*s->last_frame.linesize[0];

    int num_mvs;

    int num_blocks_raw;

    int num_blocks_packed;

    int vector_bits;

    int i,j,x,y;

    GetBitContext gb;

    int mvbits;

    const unsigned char *blocks_raw;

    if(buf+12>buf_end)

        return -1;

    num_mvs           = AV_RL16(&buf[0]);

    num_blocks_raw    = AV_RL16(&buf[2]);

    num_blocks_packed = AV_RL16(&buf[4]);

    vector_bits       = AV_RL16(&buf[6]);

    buf += 12;

    /* allocate codebook buffers as necessary */

    if (num_mvs > s->num_mvs) {

        s->mv_codebook = av_realloc(s->mv_codebook, num_mvs*2*sizeof(int));

        s->num_mvs = num_mvs;

    }

    if (num_blocks_packed > s->num_blocks_packed) {

        s->block_codebook = av_realloc(s->block_codebook, num_blocks_packed*16*sizeof(unsigned char));

        s->num_blocks_packed = num_blocks_packed;

    }

    /* read motion vectors */

    mvbits = (num_mvs*2*10+31) & ~31;

    if (buf+(mvbits>>3)+16*num_blocks_raw+8*num_blocks_packed>buf_end)

        return -1;

    init_get_bits(&gb, buf, mvbits);

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

        s->mv_codebook[i][0] = get_sbits(&gb, 10);

        s->mv_codebook[i][1] = get_sbits(&gb, 10);

    }

    buf += mvbits>>3;

    /* note ptr to uncompressed blocks */

    blocks_raw = buf;

    buf += num_blocks_raw*16;

    /* read compressed blocks */

    init_get_bits(&gb, buf, (buf_end-buf)<<3);

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

        int tmp[4];

        for(j=0; j<4; j++)

            tmp[j] = get_bits(&gb, 8);

        for(j=0; j<16; j++)

            s->block_codebook[i][15-j] = tmp[get_bits(&gb, 2)];

    }

    if (get_bits_left(&gb) < vector_bits *

        (s->avctx->height/4) * (s->avctx->width/4))

        return -1;

    /* read vectors and build frame */

    for(y=0; y<s->avctx->height/4; y++)

    for(x=0; x<s->avctx->width/4; x++) {

        unsigned int vector = get_bits(&gb, vector_bits);

        const unsigned char *src;

        int src_stride;

        if (vector < num_mvs) {

            src = s->last_frame.data[0] +

                  (y*4 + s->mv_codebook[vector][1])*s->last_frame.linesize[0] +

                   x*4 + s->mv_codebook[vector][0];

            src_stride = s->last_frame.linesize[0];

            if (src+3*src_stride+3>=frame0_end)

                continue;

        }else{

            int offset = vector - num_mvs;

            if (offset<num_blocks_raw)

                src = blocks_raw + 16*offset;

            else if (offset-num_blocks_raw<num_blocks_packed)

                src = s->block_codebook[offset-num_blocks_raw];

            else

                continue;

            src_stride = 4;

        }

        for(j=0; j<4; j++)

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

            s->frame.data[0][ (y*4+j)*s->frame.linesize[0] + (x*4+i)  ] =

               src[j*src_stride + i];

    }

    return 0;

}


static int hls_transform_unit(HEVCContext *s, int x0, int y0,

                              int xBase, int yBase, int cb_xBase, int cb_yBase,

                              int log2_cb_size, int log2_trafo_size,

                              int trafo_depth, int blk_idx,

                              int cbf_luma, int *cbf_cb, int *cbf_cr)

{

    HEVCLocalContext *lc = s->HEVClc;

    const int log2_trafo_size_c = log2_trafo_size - s->sps->hshift[1];

    int i;

    if (lc->cu.pred_mode == MODE_INTRA) {

        int trafo_size = 1 << log2_trafo_size;

        ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size);

        s->hpc.intra_pred[log2_trafo_size - 2](s, x0, y0, 0);

    }

    if (cbf_luma || cbf_cb[0] || cbf_cr[0] ||

        (s->sps->chroma_format_idc == 2 && (cbf_cb[1] || cbf_cr[1]))) {

        int scan_idx   = SCAN_DIAG;

        int scan_idx_c = SCAN_DIAG;

        int cbf_chroma = cbf_cb[0] || cbf_cr[0] ||

                         (s->sps->chroma_format_idc == 2 &&

                         (cbf_cb[1] || cbf_cr[1]));

        if (s->pps->cu_qp_delta_enabled_flag && !lc->tu.is_cu_qp_delta_coded) {

            lc->tu.cu_qp_delta = ff_hevc_cu_qp_delta_abs(s);

            if (lc->tu.cu_qp_delta != 0)

                if (ff_hevc_cu_qp_delta_sign_flag(s) == 1)

                    lc->tu.cu_qp_delta = -lc->tu.cu_qp_delta;

            lc->tu.is_cu_qp_delta_coded = 1;

            if (lc->tu.cu_qp_delta < -(26 + s->sps->qp_bd_offset / 2) ||

                lc->tu.cu_qp_delta >  (25 + s->sps->qp_bd_offset / 2)) {

                av_log(s->avctx, AV_LOG_ERROR,

                       "The cu_qp_delta %d is outside the valid range "

                       "[%d, %d].\n",

                       lc->tu.cu_qp_delta,

                       -(26 + s->sps->qp_bd_offset / 2),

                        (25 + s->sps->qp_bd_offset / 2));

                return AVERROR_INVALIDDATA;

            }

            ff_hevc_set_qPy(s, cb_xBase, cb_yBase, log2_cb_size);

        }

        if (s->sh.cu_chroma_qp_offset_enabled_flag && cbf_chroma &&

            !lc->cu.cu_transquant_bypass_flag  &&  !lc->tu.is_cu_chroma_qp_offset_coded) {

            int cu_chroma_qp_offset_flag = ff_hevc_cu_chroma_qp_offset_flag(s);

            if (cu_chroma_qp_offset_flag) {

                int cu_chroma_qp_offset_idx  = 0;

                if (s->pps->chroma_qp_offset_list_len_minus1 > 0) {

                    cu_chroma_qp_offset_idx = ff_hevc_cu_chroma_qp_offset_idx(s);

                    av_log(s->avctx, AV_LOG_ERROR,

                        "cu_chroma_qp_offset_idx not yet tested.\n");

                }

                lc->tu.cu_qp_offset_cb = s->pps->cb_qp_offset_list[cu_chroma_qp_offset_idx];

                lc->tu.cu_qp_offset_cr = s->pps->cr_qp_offset_list[cu_chroma_qp_offset_idx];

            } else {

                lc->tu.cu_qp_offset_cb = 0;

                lc->tu.cu_qp_offset_cr = 0;

            }

            lc->tu.is_cu_chroma_qp_offset_coded = 1;

        }

        if (lc->cu.pred_mode == MODE_INTRA && log2_trafo_size < 4) {

            if (lc->tu.intra_pred_mode >= 6 &&

                lc->tu.intra_pred_mode <= 14) {

                scan_idx = SCAN_VERT;

            } else if (lc->tu.intra_pred_mode >= 22 &&

                       lc->tu.intra_pred_mode <= 30) {

                scan_idx = SCAN_HORIZ;

            }

            if (lc->tu.intra_pred_mode_c >=  6 &&

                lc->tu.intra_pred_mode_c <= 14) {

                scan_idx_c = SCAN_VERT;

            } else if (lc->tu.intra_pred_mode_c >= 22 &&

                       lc->tu.intra_pred_mode_c <= 30) {

                scan_idx_c = SCAN_HORIZ;

            }

        }

        lc->tu.cross_pf = 0;

        if (cbf_luma)

            ff_hevc_hls_residual_coding(s, x0, y0, log2_trafo_size, scan_idx, 0);

        if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) {

            int trafo_size_h = 1 << (log2_trafo_size_c + s->sps->hshift[1]);

            int trafo_size_v = 1 << (log2_trafo_size_c + s->sps->vshift[1]);

            lc->tu.cross_pf  = (s->pps->cross_component_prediction_enabled_flag && cbf_luma &&

                                (lc->cu.pred_mode == MODE_INTER ||

                                 (lc->tu.chroma_mode_c ==  4)));

            if (lc->tu.cross_pf) {

                hls_cross_component_pred(s, 0);

            }

            for (i = 0; i < (s->sps->chroma_format_idc == 2 ? 2 : 1); i++) {

                if (lc->cu.pred_mode == MODE_INTRA) {

                    ff_hevc_set_neighbour_available(s, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v);

                    s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (i << log2_trafo_size_c), 1);

                }

                if (cbf_cb[i])

                    ff_hevc_hls_residual_coding(s, x0, y0 + (i << log2_trafo_size_c),

                                                log2_trafo_size_c, scan_idx_c, 1);

                else

                    if (lc->tu.cross_pf) {

                        ptrdiff_t stride = s->frame->linesize[1];

                        int hshift = s->sps->hshift[1];

                        int vshift = s->sps->vshift[1];

                        int16_t *coeffs_y = lc->tu.coeffs[0];

                        int16_t *coeffs =   lc->tu.coeffs[1];

                        int size = 1 << log2_trafo_size_c;

                        uint8_t *dst = &s->frame->data[1][(y0 >> vshift) * stride +

                                                              ((x0 >> hshift) << s->sps->pixel_shift)];

                        for (i = 0; i < (size * size); i++) {

                            coeffs[i] = ((lc->tu.res_scale_val * coeffs_y[i]) >> 3);

                        }

                        s->hevcdsp.transform_add[log2_trafo_size-2](dst, coeffs, stride);

                    }

            }

            if (lc->tu.cross_pf) {

                hls_cross_component_pred(s, 1);

            }

            for (i = 0; i < (s->sps->chroma_format_idc == 2 ? 2 : 1); i++) {

                if (lc->cu.pred_mode == MODE_INTRA) {

                    ff_hevc_set_neighbour_available(s, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v);

                    s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (i << log2_trafo_size_c), 2);

                }

                if (cbf_cr[i])

                    ff_hevc_hls_residual_coding(s, x0, y0 + (i << log2_trafo_size_c),

                                                log2_trafo_size_c, scan_idx_c, 2);

                else

                    if (lc->tu.cross_pf) {

                        ptrdiff_t stride = s->frame->linesize[2];

                        int hshift = s->sps->hshift[2];

                        int vshift = s->sps->vshift[2];

                        int16_t *coeffs_y = lc->tu.coeffs[0];

                        int16_t *coeffs =   lc->tu.coeffs[1];

                        int size = 1 << log2_trafo_size_c;

                        uint8_t *dst = &s->frame->data[2][(y0 >> vshift) * stride +

                                                          ((x0 >> hshift) << s->sps->pixel_shift)];

                        for (i = 0; i < (size * size); i++) {

                            coeffs[i] = ((lc->tu.res_scale_val * coeffs_y[i]) >> 3);

                        }

                        s->hevcdsp.transform_add[log2_trafo_size-2](dst, coeffs, stride);

                    }

            }

        } else if (blk_idx == 3) {

            int trafo_size_h = 1 << (log2_trafo_size + 1);

            int trafo_size_v = 1 << (log2_trafo_size + s->sps->vshift[1]);

            for (i = 0; i < (s->sps->chroma_format_idc == 2 ? 2 : 1); i++) {

                if (lc->cu.pred_mode == MODE_INTRA) {

                    ff_hevc_set_neighbour_available(s, xBase, yBase + (i << log2_trafo_size),

                                                    trafo_size_h, trafo_size_v);

                    s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (i << log2_trafo_size), 1);

                }

                if (cbf_cb[i])

                    ff_hevc_hls_residual_coding(s, xBase, yBase + (i << log2_trafo_size),

                                                log2_trafo_size, scan_idx_c, 1);

            }

            for (i = 0; i < (s->sps->chroma_format_idc == 2 ? 2 : 1); i++) {

                if (lc->cu.pred_mode == MODE_INTRA) {

                    ff_hevc_set_neighbour_available(s, xBase, yBase + (i << log2_trafo_size),

                                                trafo_size_h, trafo_size_v);

                    s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (i << log2_trafo_size), 2);

                }

                if (cbf_cr[i])

                    ff_hevc_hls_residual_coding(s, xBase, yBase + (i << log2_trafo_size),

                                                log2_trafo_size, scan_idx_c, 2);

            }

        }

    } else if (lc->cu.pred_mode == MODE_INTRA) {

        if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) {

            int trafo_size_h = 1 << (log2_trafo_size_c + s->sps->hshift[1]);

            int trafo_size_v = 1 << (log2_trafo_size_c + s->sps->vshift[1]);

            ff_hevc_set_neighbour_available(s, x0, y0, trafo_size_h, trafo_size_v);

            s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0, 1);

            s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0, 2);

            if (s->sps->chroma_format_idc == 2) {

                ff_hevc_set_neighbour_available(s, x0, y0 + (1 << log2_trafo_size_c),

                                                trafo_size_h, trafo_size_v);

                s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (1 << log2_trafo_size_c), 1);

                s->hpc.intra_pred[log2_trafo_size_c - 2](s, x0, y0 + (1 << log2_trafo_size_c), 2);

            }

        } else if (blk_idx == 3) {

            int trafo_size_h = 1 << (log2_trafo_size + 1);

            int trafo_size_v = 1 << (log2_trafo_size + s->sps->vshift[1]);

            ff_hevc_set_neighbour_available(s, xBase, yBase,

                                            trafo_size_h, trafo_size_v);

            s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase, 1);

            s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase, 2);

            if (s->sps->chroma_format_idc == 2) {

                ff_hevc_set_neighbour_available(s, xBase, yBase + (1 << (log2_trafo_size)),

                                                trafo_size_h, trafo_size_v);

                s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (1 << (log2_trafo_size)), 1);

                s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase + (1 << (log2_trafo_size)), 2);

            }

        }

    }

    return 0;

}


av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp)

{

#if HAVE_YASM

    int cpu_flags;

    if (bpp != 8) return;

    cpu_flags = av_get_cpu_flags();

#define init_fpel(idx1, idx2, sz, type, opt) \

    dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][0][0] = \

    dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = \

    dsp->mc[idx1][FILTER_8TAP_SHARP  ][idx2][0][0] = \

    dsp->mc[idx1][FILTER_BILINEAR    ][idx2][0][0] = ff_vp9_##type##sz##_##opt

#define init_subpel1(idx1, idx2, idxh, idxv, sz, dir, type, opt) \

    dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][idxh][idxv] = type##_8tap_smooth_##sz##dir##_##opt; \

    dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][idxh][idxv] = type##_8tap_regular_##sz##dir##_##opt; \

    dsp->mc[idx1][FILTER_8TAP_SHARP  ][idx2][idxh][idxv] = type##_8tap_sharp_##sz##dir##_##opt

#define init_subpel2(idx1, idx2, sz, type, opt) \

    init_subpel1(idx1, idx2, 1, 1, sz, hv, type, opt); \

    init_subpel1(idx1, idx2, 0, 1, sz, v,  type, opt); \

    init_subpel1(idx1, idx2, 1, 0, sz, h,  type, opt)

#define init_subpel3_32_64(idx, type, opt) \

    init_subpel2(0, idx, 64, type, opt); \

    init_subpel2(1, idx, 32, type, opt)

#define init_subpel3_8to64(idx, type, opt) \

    init_subpel3_32_64(idx, type, opt); \

    init_subpel2(2, idx, 16, type, opt); \

    init_subpel2(3, idx,  8, type, opt)

#define init_subpel3(idx, type, opt) \

    init_subpel3_8to64(idx, type, opt); \

    init_subpel2(4, idx,  4, type, opt)

#define init_lpf(opt) do { \

    dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_##opt; \

    dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_##opt; \

    dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_##opt; \

    dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_##opt; \

    dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_##opt; \

    dsp->loop_filter_mix2[0][1][1] = ff_vp9_loop_filter_v_48_16_##opt; \

    dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_##opt; \

    dsp->loop_filter_mix2[1][0][1] = ff_vp9_loop_filter_v_84_16_##opt; \

    dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_##opt; \

    dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_##opt; \

} while (0)

#define init_ipred(sz, opt, t, e) \

    dsp->intra_pred[TX_##sz##X##sz][e##_PRED] = ff_vp9_ipred_##t##_##sz##x##sz##_##opt

#define ff_vp9_ipred_hd_4x4_ssse3 ff_vp9_ipred_hd_4x4_mmxext

#define ff_vp9_ipred_vl_4x4_ssse3 ff_vp9_ipred_vl_4x4_mmxext

#define init_dir_tm_ipred(sz, opt) do { \

    init_ipred(sz, opt, dl, DIAG_DOWN_LEFT); \

    init_ipred(sz, opt, dr, DIAG_DOWN_RIGHT); \

    init_ipred(sz, opt, hd, HOR_DOWN); \

    init_ipred(sz, opt, vl, VERT_LEFT); \

    init_ipred(sz, opt, hu, HOR_UP); \

    init_ipred(sz, opt, tm, TM_VP8); \

    init_ipred(sz, opt, vr, VERT_RIGHT); \

} while (0)

#define init_dir_tm_h_ipred(sz, opt) do { \

    init_dir_tm_ipred(sz, opt); \

    init_ipred(sz, opt, h,  HOR); \

} while (0)

#define init_dc_ipred(sz, opt) do { \

    init_ipred(sz, opt, dc,      DC); \

    init_ipred(sz, opt, dc_left, LEFT_DC); \

    init_ipred(sz, opt, dc_top,  TOP_DC); \

} while (0)

#define init_all_ipred(sz, opt) do { \

    init_dc_ipred(sz, opt); \

    init_dir_tm_h_ipred(sz, opt); \

} while (0)

    if (EXTERNAL_MMX(cpu_flags)) {

        init_fpel(4, 0,  4, put, mmx);

        init_fpel(3, 0,  8, put, mmx);

        dsp->itxfm_add[4 /* lossless */][DCT_DCT] =

        dsp->itxfm_add[4 /* lossless */][ADST_DCT] =

        dsp->itxfm_add[4 /* lossless */][DCT_ADST] =

        dsp->itxfm_add[4 /* lossless */][ADST_ADST] = ff_vp9_iwht_iwht_4x4_add_mmx;

        init_ipred(8, mmx, v, VERT);

    }

    if (EXTERNAL_MMXEXT(cpu_flags)) {

        init_subpel2(4, 0, 4, put, mmxext);

        init_subpel2(4, 1, 4, avg, mmxext);

        init_fpel(4, 1,  4, avg, mmxext);

        init_fpel(3, 1,  8, avg, mmxext);

        dsp->itxfm_add[TX_4X4][DCT_DCT] = ff_vp9_idct_idct_4x4_add_mmxext;

        init_dc_ipred(4, mmxext);

        init_dc_ipred(8, mmxext);

        init_dir_tm_ipred(4, mmxext);

    }

    if (EXTERNAL_SSE(cpu_flags)) {

        init_fpel(2, 0, 16, put, sse);

        init_fpel(1, 0, 32, put, sse);

        init_fpel(0, 0, 64, put, sse);

        init_ipred(16, sse, v, VERT);

        init_ipred(32, sse, v, VERT);

    }

    if (EXTERNAL_SSE2(cpu_flags)) {

        init_subpel3_8to64(0, put, sse2);

        init_subpel3_8to64(1, avg, sse2);

        init_fpel(2, 1, 16, avg, sse2);

        init_fpel(1, 1, 32, avg, sse2);

        init_fpel(0, 1, 64, avg, sse2);

        init_lpf(sse2);

        dsp->itxfm_add[TX_4X4][ADST_DCT]  = ff_vp9_idct_iadst_4x4_add_sse2;

        dsp->itxfm_add[TX_4X4][DCT_ADST]  = ff_vp9_iadst_idct_4x4_add_sse2;

        dsp->itxfm_add[TX_4X4][ADST_ADST] = ff_vp9_iadst_iadst_4x4_add_sse2;

        dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_sse2;

        dsp->itxfm_add[TX_8X8][ADST_DCT]  = ff_vp9_idct_iadst_8x8_add_sse2;

        dsp->itxfm_add[TX_8X8][DCT_ADST]  = ff_vp9_iadst_idct_8x8_add_sse2;

        dsp->itxfm_add[TX_8X8][ADST_ADST] = ff_vp9_iadst_iadst_8x8_add_sse2;

        dsp->itxfm_add[TX_16X16][DCT_DCT]   = ff_vp9_idct_idct_16x16_add_sse2;

        dsp->itxfm_add[TX_16X16][ADST_DCT]  = ff_vp9_idct_iadst_16x16_add_sse2;

        dsp->itxfm_add[TX_16X16][DCT_ADST]  = ff_vp9_iadst_idct_16x16_add_sse2;

        dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_sse2;

        dsp->itxfm_add[TX_32X32][ADST_ADST] =

        dsp->itxfm_add[TX_32X32][ADST_DCT] =

        dsp->itxfm_add[TX_32X32][DCT_ADST] =

        dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_sse2;

        init_dc_ipred(16, sse2);

        init_dc_ipred(32, sse2);

        init_dir_tm_h_ipred(8, sse2);

        init_dir_tm_h_ipred(16, sse2);

        init_dir_tm_h_ipred(32, sse2);

        init_ipred(4, sse2, h, HOR);

    }

    if (EXTERNAL_SSSE3(cpu_flags)) {

        init_subpel3(0, put, ssse3);

        init_subpel3(1, avg, ssse3);

        dsp->itxfm_add[TX_4X4][DCT_DCT] = ff_vp9_idct_idct_4x4_add_ssse3;

        dsp->itxfm_add[TX_4X4][ADST_DCT]  = ff_vp9_idct_iadst_4x4_add_ssse3;

        dsp->itxfm_add[TX_4X4][DCT_ADST]  = ff_vp9_iadst_idct_4x4_add_ssse3;

        dsp->itxfm_add[TX_4X4][ADST_ADST] = ff_vp9_iadst_iadst_4x4_add_ssse3;

        dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_ssse3;

        dsp->itxfm_add[TX_8X8][ADST_DCT]  = ff_vp9_idct_iadst_8x8_add_ssse3;

        dsp->itxfm_add[TX_8X8][DCT_ADST]  = ff_vp9_iadst_idct_8x8_add_ssse3;

        dsp->itxfm_add[TX_8X8][ADST_ADST] = ff_vp9_iadst_iadst_8x8_add_ssse3;

        dsp->itxfm_add[TX_16X16][DCT_DCT]   = ff_vp9_idct_idct_16x16_add_ssse3;

        dsp->itxfm_add[TX_16X16][ADST_DCT]  = ff_vp9_idct_iadst_16x16_add_ssse3;

        dsp->itxfm_add[TX_16X16][DCT_ADST]  = ff_vp9_iadst_idct_16x16_add_ssse3;

        dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_ssse3;

        dsp->itxfm_add[TX_32X32][ADST_ADST] =

        dsp->itxfm_add[TX_32X32][ADST_DCT] =

        dsp->itxfm_add[TX_32X32][DCT_ADST] =

        dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_ssse3;

        init_lpf(ssse3);

        init_all_ipred(4, ssse3);

        init_all_ipred(8, ssse3);

        init_all_ipred(16, ssse3);

        init_all_ipred(32, ssse3);

    }

    if (EXTERNAL_AVX(cpu_flags)) {

        dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_avx;

        dsp->itxfm_add[TX_8X8][ADST_DCT]  = ff_vp9_idct_iadst_8x8_add_avx;

        dsp->itxfm_add[TX_8X8][DCT_ADST]  = ff_vp9_iadst_idct_8x8_add_avx;

        dsp->itxfm_add[TX_8X8][ADST_ADST] = ff_vp9_iadst_iadst_8x8_add_avx;

        dsp->itxfm_add[TX_16X16][DCT_DCT] = ff_vp9_idct_idct_16x16_add_avx;

        dsp->itxfm_add[TX_16X16][ADST_DCT]  = ff_vp9_idct_iadst_16x16_add_avx;

        dsp->itxfm_add[TX_16X16][DCT_ADST]  = ff_vp9_iadst_idct_16x16_add_avx;

        dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_avx;

        dsp->itxfm_add[TX_32X32][ADST_ADST] =

        dsp->itxfm_add[TX_32X32][ADST_DCT] =

        dsp->itxfm_add[TX_32X32][DCT_ADST] =

        dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_avx;

        init_fpel(1, 0, 32, put, avx);

        init_fpel(0, 0, 64, put, avx);

        init_lpf(avx);

        init_dir_tm_h_ipred(8, avx);

        init_dir_tm_h_ipred(16, avx);

        init_dir_tm_h_ipred(32, avx);

        init_ipred(32, avx, v, VERT);

    }

    if (EXTERNAL_AVX2(cpu_flags)) {

        init_fpel(1, 1, 32, avg, avx2);

        init_fpel(0, 1, 64, avg, avx2);

        if (ARCH_X86_64) {

#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL

            init_subpel3_32_64(0, put, avx2);

            init_subpel3_32_64(1, avg, avx2);

#endif

        }

        init_dc_ipred(32, avx2);

        init_ipred(32, avx2, h,  HOR);

        init_ipred(32, avx2, tm, TM_VP8);

    }

#undef init_fpel

#undef init_subpel1

#undef init_subpel2

#undef init_subpel3

#endif /* HAVE_YASM */

}


int av_fifo_generic_read(AVFifoBuffer *f, int buf_size, void (*func)(void*, void*, int), void* dest)

{

    int size = av_fifo_size(f);

    if (size < buf_size)

        return -1;

    while (buf_size > 0) {

        int len = FFMIN(f->end - f->rptr, buf_size);

        if(func) func(dest, f->rptr, len);

        else{

            memcpy(dest, f->rptr, len);

            dest = (uint8_t*)dest + len;

        }

        av_fifo_drain(f, len);

        buf_size -= len;

    }

    return 0;

}


BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,

        unsigned long int req, void *buf,

        BlockCompletionFunc *cb, void *opaque)

{

    BlockAIOCBCoroutine *acb = qemu_aio_get(&bdrv_em_co_aiocb_info,

                                            bs, cb, opaque);

    Coroutine *co;

    acb->need_bh = true;

    acb->req.error = -EINPROGRESS;

    acb->req.req = req;

    acb->req.buf = buf;

    co = qemu_coroutine_create(bdrv_co_aio_ioctl_entry);

    qemu_coroutine_enter(co, acb);

    bdrv_co_maybe_schedule_bh(acb);

    return &acb->common;

}


static void gen_rfi(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    /* FIXME: This instruction doesn't exist anymore on 64-bit server

     * processors compliant with arch 2.x, we should remove it there,

     * but we need to fix OpenBIOS not to use it on 970 first

     */

    /* Restore CPU state */

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    gen_update_cfar(ctx, ctx->nip);

    gen_helper_rfi(cpu_env);

    gen_sync_exception(ctx);

#endif

}