static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)

{

    if (pkt->size >= 7 &&

        pkt->size < INT_MAX - AVPROBE_PADDING_SIZE &&

        !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) {

        uint8_t desc[256];

        int score      = AVPROBE_SCORE_EXTENSION, ret;

        AVIStream *ast = st->priv_data;

        AVInputFormat *sub_demuxer;

        AVRational time_base;

        int size;

        AVIOContext *pb = avio_alloc_context(pkt->data + 7,

                                             pkt->size - 7,

                                             0, NULL, NULL, NULL, NULL);

        AVProbeData pd;

        unsigned int desc_len = avio_rl32(pb);

        if (desc_len > pb->buf_end - pb->buf_ptr)

            goto error;

        ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));

        avio_skip(pb, desc_len - ret);

        if (*desc)

            av_dict_set(&st->metadata, "title", desc, 0);

        avio_rl16(pb);   /* flags? */

        avio_rl32(pb);   /* data size */

        size = pb->buf_end - pb->buf_ptr;

        pd = (AVProbeData) { .buf      = av_mallocz(size + AVPROBE_PADDING_SIZE),

                             .buf_size = size };

        if (!pd.buf)

            goto error;

        memcpy(pd.buf, pb->buf_ptr, size);

        sub_demuxer = av_probe_input_format2(&pd, 1, &score);

        av_freep(&pd.buf);

        if (!sub_demuxer)

            goto error;

        if (!(ast->sub_ctx = avformat_alloc_context()))

            goto error;

        ast->sub_ctx->pb = pb;

        av_assert0(!ast->sub_ctx->codec_whitelist && !ast->sub_ctx->format_whitelist);

        ast->sub_ctx-> codec_whitelist = av_strdup(s->codec_whitelist);

        ast->sub_ctx->format_whitelist = av_strdup(s->format_whitelist);

        if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {

            ff_read_packet(ast->sub_ctx, &ast->sub_pkt);

            *st->codec = *ast->sub_ctx->streams[0]->codec;

            ast->sub_ctx->streams[0]->codec->extradata = NULL;

            time_base = ast->sub_ctx->streams[0]->time_base;

            avpriv_set_pts_info(st, 64, time_base.num, time_base.den);

        }

        ast->sub_buffer = pkt->data;

        memset(pkt, 0, sizeof(*pkt));

        return 1;

error:

        av_freep(&pb);

    }

    return 0;

}


void qvirtio_pci_device_enable(QVirtioPCIDevice *d)

{

    qpci_device_enable(d->pdev);

    d->addr = qpci_iomap(d->pdev, 0, NULL);

    g_assert(d->addr != NULL);

}


static int movie_request_frame(AVFilterLink *outlink)

{

    AVFilterBufferRef *outpicref;

    MovieContext *movie = outlink->src->priv;

    int ret;

    if (movie->is_done)

        return AVERROR_EOF;

    if ((ret = movie_get_frame(outlink)) < 0)

        return ret;

    outpicref = avfilter_ref_buffer(movie->picref, ~0);

    ff_start_frame(outlink, outpicref);

    ff_draw_slice(outlink, 0, outlink->h, 1);

    ff_end_frame(outlink);

    avfilter_unref_buffer(movie->picref);

    movie->picref = NULL;

    return 0;

}


static void process_client(AVIOContext *client, const char *in_uri)

{

    AVIOContext *input = NULL;

    uint8_t buf[1024];

    int ret, n, reply_code;

    uint8_t *resource = NULL;

    while ((ret = avio_handshake(client)) > 0) {

        av_opt_get(client, "resource", AV_OPT_SEARCH_CHILDREN, &resource);

        // check for strlen(resource) is necessary, because av_opt_get()

        // may return empty string.

        if (resource && strlen(resource))

            break;

    }

    if (ret < 0)

        goto end;

    av_log(client, AV_LOG_TRACE, "resource=%p\n", resource);

    if (resource && resource[0] == '/' && !strcmp((resource + 1), in_uri)) {

        reply_code = 200;

    } else {

        reply_code = AVERROR_HTTP_NOT_FOUND;

    }

    if ((ret = av_opt_set_int(client, "reply_code", reply_code, AV_OPT_SEARCH_CHILDREN)) < 0) {

        av_log(client, AV_LOG_ERROR, "Failed to set reply_code: %s.\n", av_err2str(ret));

        goto end;

    }

    av_log(client, AV_LOG_TRACE, "Set reply code to %d\n", reply_code);

    while ((ret = avio_handshake(client)) > 0);

    if (ret < 0)

        goto end;

    fprintf(stderr, "Handshake performed.\n");

    if (reply_code != 200)

        goto end;

    fprintf(stderr, "Opening input file.\n");

    if ((ret = avio_open2(&input, in_uri, AVIO_FLAG_READ, NULL, NULL)) < 0) {

        av_log(input, AV_LOG_ERROR, "Failed to open input: %s: %s.\n", in_uri,

               av_err2str(ret));

        goto end;

    }

    for(;;) {

        n = avio_read(input, buf, sizeof(buf));

        if (n < 0) {

            if (n == AVERROR_EOF)

                break;

            av_log(input, AV_LOG_ERROR, "Error reading from input: %s.\n",

                   av_err2str(n));

            break;

        }

        avio_write(client, buf, n);

        avio_flush(client);

    }

end:

    fprintf(stderr, "Flushing client\n");

    avio_flush(client);

    fprintf(stderr, "Closing client\n");

    avio_close(client);

    fprintf(stderr, "Closing input\n");

    avio_close(input);

}


static inline void pred_direct_motion(H264Context * const h, int *mb_type){

    MpegEncContext * const s = &h->s;

    const int mb_xy =   s->mb_x +   s->mb_y*s->mb_stride;

    const int b8_xy = 2*s->mb_x + 2*s->mb_y*h->b8_stride;

    const int b4_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride;

    const int mb_type_col = h->ref_list[1][0].mb_type[mb_xy];

    const int16_t (*l1mv0)[2] = (const int16_t (*)[2]) &h->ref_list[1][0].motion_val[0][b4_xy];

    const int16_t (*l1mv1)[2] = (const int16_t (*)[2]) &h->ref_list[1][0].motion_val[1][b4_xy];

    const int8_t *l1ref0 = &h->ref_list[1][0].ref_index[0][b8_xy];

    const int8_t *l1ref1 = &h->ref_list[1][0].ref_index[1][b8_xy];

    const int is_b8x8 = IS_8X8(*mb_type);

    int sub_mb_type;

    int i8, i4;

    if(IS_8X8(mb_type_col) && !h->sps.direct_8x8_inference_flag){

        /* FIXME save sub mb types from previous frames (or derive from MVs)

         * so we know exactly what block size to use */

        sub_mb_type = MB_TYPE_8x8|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_4x4 */

        *mb_type =    MB_TYPE_8x8|MB_TYPE_L0L1;

    }else if(!is_b8x8 && (IS_16X16(mb_type_col) || IS_INTRA(mb_type_col))){

        sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */

        *mb_type =    MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_16x16 */

    }else{

        sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */

        *mb_type =    MB_TYPE_8x8|MB_TYPE_L0L1;

    }

    if(!is_b8x8)

        *mb_type |= MB_TYPE_DIRECT2;

    tprintf("mb_type = %08x, sub_mb_type = %08x, is_b8x8 = %d, mb_type_col = %08x\n", *mb_type, sub_mb_type, is_b8x8, mb_type_col);

    if(h->direct_spatial_mv_pred){

        int ref[2];

        int mv[2][2];

        int list;

        /* ref = min(neighbors) */

        for(list=0; list<2; list++){

            int refa = h->ref_cache[list][scan8[0] - 1];

            int refb = h->ref_cache[list][scan8[0] - 8];

            int refc = h->ref_cache[list][scan8[0] - 8 + 4];

            if(refc == -2)

                refc = h->ref_cache[list][scan8[0] - 8 - 1];

            ref[list] = refa;

            if(ref[list] < 0 || (refb < ref[list] && refb >= 0))

                ref[list] = refb;

            if(ref[list] < 0 || (refc < ref[list] && refc >= 0))

                ref[list] = refc;

            if(ref[list] < 0)

                ref[list] = -1;

        }

        if(ref[0] < 0 && ref[1] < 0){

            ref[0] = ref[1] = 0;

            mv[0][0] = mv[0][1] =

            mv[1][0] = mv[1][1] = 0;

        }else{

            for(list=0; list<2; list++){

                if(ref[list] >= 0)

                    pred_motion(h, 0, 4, list, ref[list], &mv[list][0], &mv[list][1]);

                else

                    mv[list][0] = mv[list][1] = 0;

            }

        }

        if(ref[1] < 0){

            *mb_type &= ~MB_TYPE_P0L1;

            sub_mb_type &= ~MB_TYPE_P0L1;

        }else if(ref[0] < 0){

            *mb_type &= ~MB_TYPE_P0L0;

            sub_mb_type &= ~MB_TYPE_P0L0;

        }

        if(IS_16X16(*mb_type)){

            fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref[0], 1);

            fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, ref[1], 1);

            if(!IS_INTRA(mb_type_col)

               && (   (l1ref0[0] == 0 && ABS(l1mv0[0][0]) <= 1 && ABS(l1mv0[0][1]) <= 1)

                   || (l1ref0[0]  < 0 && l1ref1[0] == 0 && ABS(l1mv1[0][0]) <= 1 && ABS(l1mv1[0][1]) <= 1

                       && (h->x264_build>33 || !h->x264_build)))){

                if(ref[0] > 0)

                    fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mv[0][0],mv[0][1]), 4);

                else

                    fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);

                if(ref[1] > 0)

                    fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, pack16to32(mv[1][0],mv[1][1]), 4);

                else

                    fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, 0, 4);

            }else{

                fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mv[0][0],mv[0][1]), 4);

                fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, pack16to32(mv[1][0],mv[1][1]), 4);

            }

        }else{

            for(i8=0; i8<4; i8++){

                const int x8 = i8&1;

                const int y8 = i8>>1;

                if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))

                    continue;

                h->sub_mb_type[i8] = sub_mb_type;

                fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mv[0][0],mv[0][1]), 4);

                fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mv[1][0],mv[1][1]), 4);

                fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref[0], 1);

                fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, ref[1], 1);

                /* col_zero_flag */

                if(!IS_INTRA(mb_type_col) && (   l1ref0[x8 + y8*h->b8_stride] == 0

                                              || (l1ref0[x8 + y8*h->b8_stride] < 0 && l1ref1[x8 + y8*h->b8_stride] == 0

                                                  && (h->x264_build>33 || !h->x264_build)))){

                    const int16_t (*l1mv)[2]= l1ref0[x8 + y8*h->b8_stride] == 0 ? l1mv0 : l1mv1;

                    for(i4=0; i4<4; i4++){

                        const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride];

                        if(ABS(mv_col[0]) <= 1 && ABS(mv_col[1]) <= 1){

                            if(ref[0] == 0)

                                *(uint32_t*)h->mv_cache[0][scan8[i8*4+i4]] = 0;

                            if(ref[1] == 0)

                                *(uint32_t*)h->mv_cache[1][scan8[i8*4+i4]] = 0;

                        }

                    }

                }

            }

        }

    }else{ /* direct temporal mv pred */

        if(IS_16X16(*mb_type)){

            fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1);

            if(IS_INTRA(mb_type_col)){

                fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1);

                fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);

                fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, 0, 4);

            }else{

                const int ref0 = l1ref0[0] >= 0 ? h->map_col_to_list0[0][l1ref0[0]]

                                                : h->map_col_to_list0[1][l1ref1[0]];

                const int dist_scale_factor = h->dist_scale_factor[ref0];

                const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0];

                int mv_l0[2];

                mv_l0[0] = (dist_scale_factor * mv_col[0] + 128) >> 8;

                mv_l0[1] = (dist_scale_factor * mv_col[1] + 128) >> 8;

                fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref0, 1);

                fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mv_l0[0],mv_l0[1]), 4);

                fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]), 4);

            }

        }else{

            for(i8=0; i8<4; i8++){

                const int x8 = i8&1;

                const int y8 = i8>>1;

                int ref0, dist_scale_factor;

                const int16_t (*l1mv)[2]= l1mv0;

                if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))

                    continue;

                h->sub_mb_type[i8] = sub_mb_type;

                if(IS_INTRA(mb_type_col)){

                    fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1);

                    fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1);

                    fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4);

                    fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4);

                    continue;

                }

                ref0 = l1ref0[x8 + y8*h->b8_stride];

                if(ref0 >= 0)

                    ref0 = h->map_col_to_list0[0][ref0];

                else{

                    ref0 = h->map_col_to_list0[1][l1ref1[x8 + y8*h->b8_stride]];

                    l1mv= l1mv1;

                }

                dist_scale_factor = h->dist_scale_factor[ref0];

                fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1);

                fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1);

                for(i4=0; i4<4; i4++){

                    const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride];

                    int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]];

                    mv_l0[0] = (dist_scale_factor * mv_col[0] + 128) >> 8;

                    mv_l0[1] = (dist_scale_factor * mv_col[1] + 128) >> 8;

                    *(uint32_t*)h->mv_cache[1][scan8[i8*4+i4]] =

                        pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]);

                }

            }

        }

    }

}


static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,

                         Error **errp)

{

    BDRVQEDState *s = bs->opaque;

    QEDHeader le_header;

    int64_t file_size;

    int ret;

    s->bs = bs;

    QSIMPLEQ_INIT(&s->allocating_write_reqs);

    ret = bdrv_pread(bs->file, 0, &le_header, sizeof(le_header));

    if (ret < 0) {

        return ret;

    }

    qed_header_le_to_cpu(&le_header, &s->header);

    if (s->header.magic != QED_MAGIC) {

        error_setg(errp, "Image not in QED format");

        return -EINVAL;

    }

    if (s->header.features & ~QED_FEATURE_MASK) {

        /* image uses unsupported feature bits */

        char buf[64];

        snprintf(buf, sizeof(buf), "%" PRIx64,

            s->header.features & ~QED_FEATURE_MASK);

        error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,

            bdrv_get_device_name(bs), "QED", buf);

        return -ENOTSUP;

    }

    if (!qed_is_cluster_size_valid(s->header.cluster_size)) {

        return -EINVAL;

    }

    /* Round down file size to the last cluster */

    file_size = bdrv_getlength(bs->file);

    if (file_size < 0) {

        return file_size;

    }

    s->file_size = qed_start_of_cluster(s, file_size);

    if (!qed_is_table_size_valid(s->header.table_size)) {

        return -EINVAL;

    }

    if (!qed_is_image_size_valid(s->header.image_size,

                                 s->header.cluster_size,

                                 s->header.table_size)) {

        return -EINVAL;

    }

    if (!qed_check_table_offset(s, s->header.l1_table_offset)) {

        return -EINVAL;

    }

    s->table_nelems = (s->header.cluster_size * s->header.table_size) /

                      sizeof(uint64_t);

    s->l2_shift = ffs(s->header.cluster_size) - 1;

    s->l2_mask = s->table_nelems - 1;

    s->l1_shift = s->l2_shift + ffs(s->table_nelems) - 1;

    /* Header size calculation must not overflow uint32_t */

    if (s->header.header_size > UINT32_MAX / s->header.cluster_size) {

        return -EINVAL;

    }

    if ((s->header.features & QED_F_BACKING_FILE)) {

        if ((uint64_t)s->header.backing_filename_offset +

            s->header.backing_filename_size >

            s->header.cluster_size * s->header.header_size) {

            return -EINVAL;

        }

        ret = qed_read_string(bs->file, s->header.backing_filename_offset,

                              s->header.backing_filename_size, bs->backing_file,

                              sizeof(bs->backing_file));

        if (ret < 0) {

            return ret;

        }

        if (s->header.features & QED_F_BACKING_FORMAT_NO_PROBE) {

            pstrcpy(bs->backing_format, sizeof(bs->backing_format), "raw");

        }

    }

    /* Reset unknown autoclear feature bits.  This is a backwards

     * compatibility mechanism that allows images to be opened by older

     * programs, which "knock out" unknown feature bits.  When an image is

     * opened by a newer program again it can detect that the autoclear

     * feature is no longer valid.

     */

    if ((s->header.autoclear_features & ~QED_AUTOCLEAR_FEATURE_MASK) != 0 &&

        !bdrv_is_read_only(bs->file) && !(flags & BDRV_O_INCOMING)) {

        s->header.autoclear_features &= QED_AUTOCLEAR_FEATURE_MASK;

        ret = qed_write_header_sync(s);

        if (ret) {

            return ret;

        }

        /* From here on only known autoclear feature bits are valid */

        bdrv_flush(bs->file);

    }

    s->l1_table = qed_alloc_table(s);

    qed_init_l2_cache(&s->l2_cache);

    ret = qed_read_l1_table_sync(s);

    if (ret) {

        goto out;

    }

    /* If image was not closed cleanly, check consistency */

    if (!(flags & BDRV_O_CHECK) && (s->header.features & QED_F_NEED_CHECK)) {

        /* Read-only images cannot be fixed.  There is no risk of corruption

         * since write operations are not possible.  Therefore, allow

         * potentially inconsistent images to be opened read-only.  This can

         * aid data recovery from an otherwise inconsistent image.

         */

        if (!bdrv_is_read_only(bs->file) &&

            !(flags & BDRV_O_INCOMING)) {

            BdrvCheckResult result = {0};

            ret = qed_check(s, &result, true);

            if (ret) {

                goto out;

            }

        }

    }

    bdrv_qed_attach_aio_context(bs, bdrv_get_aio_context(bs));

out:

    if (ret) {

        qed_free_l2_cache(&s->l2_cache);

        qemu_vfree(s->l1_table);

    }

    return ret;

}


void ff_put_h264_qpel8_mc31_msa(uint8_t *dst, const uint8_t *src,

                                ptrdiff_t stride)

{

    avc_luma_hv_qrt_8w_msa(src - 2,

                           src - (stride * 2) +

                           sizeof(uint8_t), stride, dst, stride, 8);

}


static CharDriverState *qemu_chr_open_pipe(const char *id,

                                           ChardevBackend *backend,

                                           ChardevReturn *ret,

                                           Error **errp)

{

    ChardevHostdev *opts = backend->u.pipe;

    const char *filename = opts->device;

    CharDriverState *chr;

    WinCharState *s;

    chr = qemu_chr_alloc();

    s = g_new0(WinCharState, 1);

    chr->opaque = s;

    chr->chr_write = win_chr_write;

    chr->chr_close = win_chr_close;

    if (win_chr_pipe_init(chr, filename, errp) < 0) {

        g_free(s);

        g_free(chr);

        return NULL;

    }

    return chr;

}


uint32_t HELPER(clz)(uint32_t x)

{

    int count;

    for (count = 32; x; count--)

        x >>= 1;

    return count;

}


static void kvm_get_fallback_smmu_info(PowerPCCPU *cpu,

                                       struct kvm_ppc_smmu_info *info)

{

    CPUPPCState *env = &cpu->env;

    CPUState *cs = CPU(cpu);

    memset(info, 0, sizeof(*info));

    /* We don't have the new KVM_PPC_GET_SMMU_INFO ioctl, so

     * need to "guess" what the supported page sizes are.

     *

     * For that to work we make a few assumptions:

     *

     * - If KVM_CAP_PPC_GET_PVINFO is supported we are running "PR"

     *   KVM which only supports 4K and 16M pages, but supports them

     *   regardless of the backing store characteritics. We also don't

     *   support 1T segments.

     *

     *   This is safe as if HV KVM ever supports that capability or PR

     *   KVM grows supports for more page/segment sizes, those versions

     *   will have implemented KVM_CAP_PPC_GET_SMMU_INFO and thus we

     *   will not hit this fallback

     *

     * - Else we are running HV KVM. This means we only support page

     *   sizes that fit in the backing store. Additionally we only

     *   advertize 64K pages if the processor is ARCH 2.06 and we assume

     *   P7 encodings for the SLB and hash table. Here too, we assume

     *   support for any newer processor will mean a kernel that

     *   implements KVM_CAP_PPC_GET_SMMU_INFO and thus doesn't hit

     *   this fallback.

     */

    if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO)) {

        /* No flags */

        info->flags = 0;

        info->slb_size = 64;

        /* Standard 4k base page size segment */

        info->sps[0].page_shift = 12;

        info->sps[0].slb_enc = 0;

        info->sps[0].enc[0].page_shift = 12;

        info->sps[0].enc[0].pte_enc = 0;

        /* Standard 16M large page size segment */

        info->sps[1].page_shift = 24;

        info->sps[1].slb_enc = SLB_VSID_L;

        info->sps[1].enc[0].page_shift = 24;

        info->sps[1].enc[0].pte_enc = 0;

    } else {

        int i = 0;

        /* HV KVM has backing store size restrictions */

        info->flags = KVM_PPC_PAGE_SIZES_REAL;

        if (env->mmu_model & POWERPC_MMU_1TSEG) {

            info->flags |= KVM_PPC_1T_SEGMENTS;

        }

        if (env->mmu_model == POWERPC_MMU_2_06 ||

            env->mmu_model == POWERPC_MMU_2_07) {

            info->slb_size = 32;

        } else {

            info->slb_size = 64;

        }

        /* Standard 4k base page size segment */

        info->sps[i].page_shift = 12;

        info->sps[i].slb_enc = 0;

        info->sps[i].enc[0].page_shift = 12;

        info->sps[i].enc[0].pte_enc = 0;

        i++;

        /* 64K on MMU 2.06 and later */

        if (env->mmu_model == POWERPC_MMU_2_06 ||

            env->mmu_model == POWERPC_MMU_2_07) {

            info->sps[i].page_shift = 16;

            info->sps[i].slb_enc = 0x110;

            info->sps[i].enc[0].page_shift = 16;

            info->sps[i].enc[0].pte_enc = 1;

            i++;

        }

        /* Standard 16M large page size segment */

        info->sps[i].page_shift = 24;

        info->sps[i].slb_enc = SLB_VSID_L;

        info->sps[i].enc[0].page_shift = 24;

        info->sps[i].enc[0].pte_enc = 0;

    }

}


void helper_iret_protected(int shift)

{

    helper_ret_protected(shift, 1, 0);

}


void qemu_bh_schedule(QEMUBH *bh)

{

    AioContext *ctx;

    ctx = bh->ctx;

    bh->idle = 0;

    /* The memory barrier implicit in atomic_xchg makes sure that:

     * 1. idle & any writes needed by the callback are done before the

     *    locations are read in the aio_bh_poll.

     * 2. ctx is loaded before scheduled is set and the callback has a chance

     *    to execute.

     */

    if (atomic_xchg(&bh->scheduled, 1) == 0) {

        aio_notify(ctx);

    }

}


static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)

{

    SpiceTimer *timer;

    timer = qemu_mallocz(sizeof(*timer));

    timer->timer = qemu_new_timer(rt_clock, func, opaque);

    QTAILQ_INSERT_TAIL(&timers, timer, next);

    return timer;

}


static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,

                                        unsigned int queue_no,

                                        unsigned int vector,

                                        MSIMessage msg)

{

    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);

    EventNotifier *n = virtio_queue_get_guest_notifier(vq);

    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];

    int ret;

    if (irqfd->users == 0) {

        ret = kvm_irqchip_add_msi_route(kvm_state, msg);

        if (ret < 0) {

            return ret;

        }

        irqfd->virq = ret;

    }

    irqfd->users++;

    ret = kvm_irqchip_add_irq_notifier(kvm_state, n, irqfd->virq);

    if (ret < 0) {

        if (--irqfd->users == 0) {

            kvm_irqchip_release_virq(kvm_state, irqfd->virq);

        }

        return ret;

    }

    virtio_queue_set_guest_notifier_fd_handler(vq, true, true);

    return 0;

}


static int output_packet(InputStream *ist,

                         OutputStream *ost_table, int nb_ostreams,

                         const AVPacket *pkt)

{

    int ret = 0, i;

    int got_output;

    int64_t pkt_pts = AV_NOPTS_VALUE;

    AVPacket avpkt;

    if (ist->next_dts == AV_NOPTS_VALUE)

        ist->next_dts = ist->dts;

    if (ist->next_pts == AV_NOPTS_VALUE)

        ist->next_pts = ist->pts;

    if (pkt == NULL) {

        /* EOF handling */

        av_init_packet(&avpkt);

        avpkt.data = NULL;

        avpkt.size = 0;

        goto handle_eof;

    } else {

        avpkt = *pkt;

    }

    if (pkt->dts != AV_NOPTS_VALUE) {

        ist->next_dts = ist->dts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);

        if (ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || !ist->decoding_needed)

            ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);

    }

    if(pkt->pts != AV_NOPTS_VALUE)

        pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q);

    // while we have more to decode or while the decoder did output something on EOF

    while (ist->decoding_needed && (avpkt.size > 0 || (!pkt && got_output))) {

        int duration;

    handle_eof:

        ist->pts = ist->next_pts;

        ist->dts = ist->next_dts;

        if (avpkt.size && avpkt.size != pkt->size) {

            av_log(NULL, ist->showed_multi_packet_warning ? AV_LOG_VERBOSE : AV_LOG_WARNING,

                   "Multiple frames in a packet from stream %d\n", pkt->stream_index);

            ist->showed_multi_packet_warning = 1;

        }

        switch (ist->st->codec->codec_type) {

        case AVMEDIA_TYPE_AUDIO:

            ret = transcode_audio    (ist, &avpkt, &got_output);

            break;

        case AVMEDIA_TYPE_VIDEO:

            ret = transcode_video    (ist, &avpkt, &got_output, &pkt_pts);

            if (avpkt.duration) {

                duration = av_rescale_q(avpkt.duration, ist->st->time_base, AV_TIME_BASE_Q);

            } else if(ist->st->codec->time_base.num != 0) {

                int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame;

                duration = ((int64_t)AV_TIME_BASE *

                                ist->st->codec->time_base.num * ticks) /

                                ist->st->codec->time_base.den;

            } else

                duration = 0;

            if(ist->dts != AV_NOPTS_VALUE && duration) {

                ist->next_dts += duration;

            }else

                ist->next_dts = AV_NOPTS_VALUE;

            if (got_output)

                ist->next_pts += duration; //FIXME the duration is not correct in some cases

            break;

        case AVMEDIA_TYPE_SUBTITLE:

            ret = transcode_subtitles(ist, &avpkt, &got_output);

            break;

        default:

            return -1;

        }

        if (ret < 0)

            return ret;

        avpkt.dts=

        avpkt.pts= AV_NOPTS_VALUE;

        // touch data and size only if not EOF

        if (pkt) {

            if(ist->st->codec->codec_type != AVMEDIA_TYPE_AUDIO)

                ret = avpkt.size;

            avpkt.data += ret;

            avpkt.size -= ret;

        }

        if (!got_output) {

            continue;

        }

    }

    /* handle stream copy */

    if (!ist->decoding_needed) {

        rate_emu_sleep(ist);

        ist->dts = ist->next_dts;

        switch (ist->st->codec->codec_type) {

        case AVMEDIA_TYPE_AUDIO:

            ist->next_dts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) /

                             ist->st->codec->sample_rate;

            break;

        case AVMEDIA_TYPE_VIDEO:

            if (pkt->duration) {

                ist->next_dts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);

            } else if(ist->st->codec->time_base.num != 0) {

                int ticks= ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->st->codec->ticks_per_frame;

                ist->next_dts += ((int64_t)AV_TIME_BASE *

                                  ist->st->codec->time_base.num * ticks) /

                                  ist->st->codec->time_base.den;

            }

            break;

        }

        ist->pts = ist->dts;

        ist->next_pts = ist->next_dts;

    }

    for (i = 0; pkt && i < nb_ostreams; i++) {

        OutputStream *ost = &ost_table[i];

        if (!check_output_constraints(ist, ost) || ost->encoding_needed)

            continue;

        do_streamcopy(ist, ost, pkt);

    }

    return 0;

}


static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s,

                                       SingleChannelElement *sce,

                                       const float lambda)

{

    int q, w, w2, g, start = 0;

    int i, j;

    int idx;

    TrellisPath paths[TRELLIS_STAGES][TRELLIS_STATES];

    int bandaddr[TRELLIS_STAGES];

    int minq;

    float mincost;

    float q0f = FLT_MAX, q1f = 0.0f, qnrgf = 0.0f;

    int q0, q1, qcnt = 0;

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

        float t = fabsf(sce->coeffs[i]);

        if (t > 0.0f) {

            q0f = FFMIN(q0f, t);

            q1f = FFMAX(q1f, t);

            qnrgf += t*t;

            qcnt++;

        }

    }

    if (!qcnt) {

        memset(sce->sf_idx, 0, sizeof(sce->sf_idx));

        memset(sce->zeroes, 1, sizeof(sce->zeroes));

        return;

    }

    //minimum scalefactor index is when minimum nonzero coefficient after quantizing is not clipped

    q0 = av_clip_uint8(log2(q0f)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512);

    //maximum scalefactor index is when maximum coefficient after quantizing is still not zero

    q1 = av_clip_uint8(log2(q1f)*4 +  6 + SCALE_ONE_POS - SCALE_DIV_512);

    //av_log(NULL, AV_LOG_ERROR, "q0 %d, q1 %d\n", q0, q1);

    if (q1 - q0 > 60) {

        int q0low  = q0;

        int q1high = q1;

        //minimum scalefactor index is when maximum nonzero coefficient after quantizing is not clipped

        int qnrg = av_clip_uint8(log2(sqrt(qnrgf/qcnt))*4 - 31 + SCALE_ONE_POS - SCALE_DIV_512);

        q1 = qnrg + 30;

        q0 = qnrg - 30;

    //av_log(NULL, AV_LOG_ERROR, "q0 %d, q1 %d\n", q0, q1);

        if (q0 < q0low) {

            q1 += q0low - q0;

            q0  = q0low;

        } else if (q1 > q1high) {

            q0 -= q1 - q1high;

            q1  = q1high;

        }

    }

    //av_log(NULL, AV_LOG_ERROR, "q0 %d, q1 %d\n", q0, q1);

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

        paths[0][i].cost    = 0.0f;

        paths[0][i].prev    = -1;

    }

    for (j = 1; j < TRELLIS_STAGES; j++) {

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

            paths[j][i].cost    = INFINITY;

            paths[j][i].prev    = -2;

        }

    }

    idx = 1;

    abs_pow34_v(s->scoefs, sce->coeffs, 1024);

    for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {

        start = w*128;

        for (g = 0; g < sce->ics.num_swb; g++) {

            const float *coefs = sce->coeffs + start;

            float qmin, qmax;

            int nz = 0;

            bandaddr[idx] = w * 16 + g;

            qmin = INT_MAX;

            qmax = 0.0f;

            for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {

                FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];

                if (band->energy <= band->threshold || band->threshold == 0.0f) {

                    sce->zeroes[(w+w2)*16+g] = 1;

                    continue;

                }

                sce->zeroes[(w+w2)*16+g] = 0;

                nz = 1;

                for (i = 0; i < sce->ics.swb_sizes[g]; i++) {

                    float t = fabsf(coefs[w2*128+i]);

                    if (t > 0.0f)

                        qmin = FFMIN(qmin, t);

                    qmax = FFMAX(qmax, t);

                }

            }

            if (nz) {

                int minscale, maxscale;

                float minrd = INFINITY;

                //minimum scalefactor index is when minimum nonzero coefficient after quantizing is not clipped

                minscale = av_clip_uint8(log2(qmin)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512);

                //maximum scalefactor index is when maximum coefficient after quantizing is still not zero

                maxscale = av_clip_uint8(log2(qmax)*4 +  6 + SCALE_ONE_POS - SCALE_DIV_512);

                minscale = av_clip(minscale - q0, 0, TRELLIS_STATES - 1);

                maxscale = av_clip(maxscale - q0, 0, TRELLIS_STATES);

                for (q = minscale; q < maxscale; q++) {

                    float dist = 0;

                    int cb = find_min_book(sce->sf_idx[w*16+g], sce->ics.group_len[w], sce->ics.swb_sizes[g], s->scoefs+start);

                    for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {

                        FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];

                        dist += quantize_band_cost(s, coefs + w2*128, s->scoefs + start + w2*128, sce->ics.swb_sizes[g],

                                                            q + q0, cb, lambda / band->threshold, INFINITY, NULL);

                    }

                    minrd = FFMIN(minrd, dist);

                    for (i = 0; i < q1 - q0; i++) {

                        float cost;

                        if (isinf(paths[idx - 1][i].cost))

                            continue;

                        cost = paths[idx - 1][i].cost + dist

                               + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];

                        if (cost < paths[idx][q].cost) {

                            paths[idx][q].cost    = cost;

                            paths[idx][q].prev    = i;

                        }

                    }

                }

            } else {

                for (q = 0; q < q1 - q0; q++) {

                    if (!isinf(paths[idx - 1][q].cost)) {

                        paths[idx][q].cost = paths[idx - 1][q].cost + 1;

                        paths[idx][q].prev = q;

                        continue;

                    }

                    for (i = 0; i < q1 - q0; i++) {

                        float cost;

                        if (isinf(paths[idx - 1][i].cost))

                            continue;

                        cost = paths[idx - 1][i].cost + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];

                        if (cost < paths[idx][q].cost) {

                            paths[idx][q].cost    = cost;

                            paths[idx][q].prev    = i;

                        }

                    }

                }

            }

            sce->zeroes[w*16+g] = !nz;

            start += sce->ics.swb_sizes[g];

            idx++;

        }

    }

    idx--;

    mincost = paths[idx][0].cost;

    minq    = 0;

    for (i = 1; i < TRELLIS_STATES; i++) {

        if (paths[idx][i].cost < mincost) {

            mincost = paths[idx][i].cost;

            minq = i;

        }

    }

    while (idx) {

        sce->sf_idx[bandaddr[idx]] = minq + q0;

        minq = paths[idx][minq].prev;

        idx--;

    }

    //set the same quantizers inside window groups

    for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])

        for (g = 0;  g < sce->ics.num_swb; g++)

            for (w2 = 1; w2 < sce->ics.group_len[w]; w2++)

                sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];

}


static int create_fixed_disk(int fd, uint8_t *buf, int64_t total_size)

{

    int ret = -EIO;

    /* Add footer to total size */

    total_size += 512;

    if (ftruncate(fd, total_size) != 0) {

        ret = -errno;

        goto fail;

    }

    if (lseek(fd, -512, SEEK_END) < 0) {

        goto fail;

    }

    if (write(fd, buf, HEADER_SIZE) != HEADER_SIZE) {

        goto fail;

    }

    ret = 0;

 fail:

    return ret;

}


static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,

                           struct dirent *entry,

                           struct dirent **result)

{

    return readdir_r(fs->dir, entry, result);

}


static int zrle_send_framebuffer_update(VncState *vs, int x, int y,

                                        int w, int h)

{

    bool be = !!(vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG);

    size_t bytes;

    int zywrle_level;

    if (vs->zrle.type == VNC_ENCODING_ZYWRLE) {

        if (!vs->vd->lossy || vs->tight.quality < 0 || vs->tight.quality == 9) {

            zywrle_level = 0;

            vs->zrle.type = VNC_ENCODING_ZRLE;

        } else if (vs->tight.quality < 3) {

            zywrle_level = 3;

        } else if (vs->tight.quality < 6) {

            zywrle_level = 2;

        } else {

            zywrle_level = 1;

        }

    } else {

        zywrle_level = 0;

    }

    vnc_zrle_start(vs);

    switch(vs->clientds.pf.bytes_per_pixel) {

    case 1:

        zrle_encode_8ne(vs, x, y, w, h, zywrle_level);

        break;

    case 2:

        if (vs->clientds.pf.gmax > 0x1F) {

            if (be) {

                zrle_encode_16be(vs, x, y, w, h, zywrle_level);

            } else {

                zrle_encode_16le(vs, x, y, w, h, zywrle_level);

            }

        } else {

            if (be) {

                zrle_encode_15be(vs, x, y, w, h, zywrle_level);

            } else {

                zrle_encode_15le(vs, x, y, w, h, zywrle_level);

            }

        }

        break;

    case 4:

    {

        bool fits_in_ls3bytes;

        bool fits_in_ms3bytes;

        fits_in_ls3bytes =

            ((vs->clientds.pf.rmax << vs->clientds.pf.rshift) < (1 << 24) &&

             (vs->clientds.pf.gmax << vs->clientds.pf.gshift) < (1 << 24) &&

             (vs->clientds.pf.bmax << vs->clientds.pf.bshift) < (1 << 24));

        fits_in_ms3bytes = (vs->clientds.pf.rshift > 7 &&

                            vs->clientds.pf.gshift > 7 &&

                            vs->clientds.pf.bshift > 7);

        if ((fits_in_ls3bytes && !be) || (fits_in_ms3bytes && be)) {

            if (be) {

                zrle_encode_24abe(vs, x, y, w, h, zywrle_level);

            } else {

                zrle_encode_24ale(vs, x, y, w, h, zywrle_level);

          }

        } else if ((fits_in_ls3bytes && be) || (fits_in_ms3bytes && !be)) {

            if (be) {

                zrle_encode_24bbe(vs, x, y, w, h, zywrle_level);

            } else {

                zrle_encode_24ble(vs, x, y, w, h, zywrle_level);

            }

        } else {

            if (be) {

                zrle_encode_32be(vs, x, y, w, h, zywrle_level);

            } else {

                zrle_encode_32le(vs, x, y, w, h, zywrle_level);

            }

        }

    }

    break;

    }

    vnc_zrle_stop(vs);

    bytes = zrle_compress_data(vs, Z_DEFAULT_COMPRESSION);

    vnc_framebuffer_update(vs, x, y, w, h, vs->zrle.type);

    vnc_write_u32(vs, bytes);

    vnc_write(vs, vs->zrle.zlib.buffer, vs->zrle.zlib.offset);

    return 1;

}


static uint64_t mmio_ide_status_read(void *opaque, target_phys_addr_t addr,

                                     unsigned size)

{

    MMIOState *s= opaque;

    return ide_status_read(&s->bus, 0);

}


void tlb_flush_page(CPUState *env, target_ulong addr)

{

    int i;

#if defined(DEBUG_TLB)

    printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr);

#endif

    /* must reset current TB so that interrupts cannot modify the

       links while we are modifying them */

    env->current_tb = NULL;

    addr &= TARGET_PAGE_MASK;

    i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);

    tlb_flush_entry(&env->tlb_table[0][i], addr);

    tlb_flush_entry(&env->tlb_table[1][i], addr);

#if (NB_MMU_MODES >= 3)

    tlb_flush_entry(&env->tlb_table[2][i], addr);

#if (NB_MMU_MODES == 4)

    tlb_flush_entry(&env->tlb_table[3][i], addr);

#endif

#endif

    tlb_flush_jmp_cache(env, addr);

#ifdef USE_KQEMU

    if (env->kqemu_enabled) {

        kqemu_flush_page(env, addr);

    }

#endif

}


void ff_slice_thread_free(AVCodecContext *avctx)

{

    ThreadContext *c = avctx->thread_opaque;

    int i;

    pthread_mutex_lock(&c->current_job_lock);

    c->done = 1;

    pthread_cond_broadcast(&c->current_job_cond);

    pthread_mutex_unlock(&c->current_job_lock);

    for (i=0; i<avctx->thread_count; i++)

         pthread_join(c->workers[i], NULL);

    pthread_mutex_destroy(&c->current_job_lock);

    pthread_cond_destroy(&c->current_job_cond);

    pthread_cond_destroy(&c->last_job_cond);

    av_free(c->workers);

    av_freep(&avctx->thread_opaque);

}


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;

    while (size > 0) {

        ASSDialog *dialog = ff_ass_split_dialog(avctx->priv_data, ptr, 0, NULL);

        int duration = dialog->end - dialog->start;

        len = ff_ass_add_rect(data, ptr, 0, duration, 1);

        if (len < 0)

            return len;

        ptr  += len;

        size -= len;

    }

    *got_sub_ptr = avpkt->size > 0;

    return avpkt->size;

}


static int init_blk_migration(QEMUFile *f)

{

    BlockDriverState *bs;

    BlkMigDevState *bmds;

    int64_t sectors;

    BdrvNextIterator it;

    int i, num_bs = 0;

    struct {

        BlkMigDevState *bmds;

        BlockDriverState *bs;

    } *bmds_bs;

    Error *local_err = NULL;

    int ret;

    block_mig_state.submitted = 0;

    block_mig_state.read_done = 0;

    block_mig_state.transferred = 0;

    block_mig_state.total_sector_sum = 0;

    block_mig_state.prev_progress = -1;

    block_mig_state.bulk_completed = 0;

    block_mig_state.zero_blocks = migrate_zero_blocks();

    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {

        num_bs++;

    }

    bmds_bs = g_malloc0(num_bs * sizeof(*bmds_bs));

    for (i = 0, bs = bdrv_first(&it); bs; bs = bdrv_next(&it), i++) {

        if (bdrv_is_read_only(bs)) {

            continue;

        }

        sectors = bdrv_nb_sectors(bs);

        if (sectors <= 0) {

            ret = sectors;

            goto out;

        }

        bmds = g_new0(BlkMigDevState, 1);

        bmds->blk = blk_new(BLK_PERM_CONSISTENT_READ, BLK_PERM_ALL);

        bmds->blk_name = g_strdup(bdrv_get_device_name(bs));

        bmds->bulk_completed = 0;

        bmds->total_sectors = sectors;

        bmds->completed_sectors = 0;

        bmds->shared_base = migrate_use_block_incremental();

        assert(i < num_bs);

        bmds_bs[i].bmds = bmds;

        bmds_bs[i].bs = bs;

        block_mig_state.total_sector_sum += sectors;

        if (bmds->shared_base) {

            DPRINTF("Start migration for %s with shared base image\n",

                    bdrv_get_device_name(bs));

        } else {

            DPRINTF("Start full migration for %s\n", bdrv_get_device_name(bs));

        }

        QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry);

    }

    /* Can only insert new BDSes now because doing so while iterating block

     * devices may end up in a deadlock (iterating the new BDSes, too). */

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

        BlkMigDevState *bmds = bmds_bs[i].bmds;

        BlockDriverState *bs = bmds_bs[i].bs;

        if (bmds) {

            ret = blk_insert_bs(bmds->blk, bs, &local_err);

            if (ret < 0) {

                error_report_err(local_err);

                goto out;

            }

            alloc_aio_bitmap(bmds);

            error_setg(&bmds->blocker, "block device is in use by migration");

            bdrv_op_block_all(bs, bmds->blocker);

        }

    }

    ret = 0;

out:

    g_free(bmds_bs);

    return ret;

}


static int find_dirty_height(VncState *vs, int y, int last_x, int x)

{

    int h;

    for (h = 1; h < (vs->serverds.height - y); h++) {

        int tmp_x;

        if (!vnc_get_bit(vs->dirty_row[y + h], last_x))

            break;

        for (tmp_x = last_x; tmp_x < x; tmp_x++)

            vnc_clear_bit(vs->dirty_row[y + h], tmp_x);

    }

    return h;

}


static void test_dispatch_cmd_failure(void)

{

    QDict *req = qdict_new();

    QObject *resp;

    qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));

    resp = qmp_dispatch(QOBJECT(req));

    assert(resp != NULL);

    assert(qdict_haskey(qobject_to_qdict(resp), "error"));

    qobject_decref(resp);

    QDECREF(req);

    /* check that with extra arguments it throws an error */

    req = qdict_new();

    qdict_put(args, "a", qint_from_int(66));

    qdict_put(req, "arguments", args);

    qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));

    resp = qmp_dispatch(QOBJECT(req));

    assert(resp != NULL);

    assert(qdict_haskey(qobject_to_qdict(resp), "error"));

    qobject_decref(resp);

    QDECREF(req);

}


static void add_index_entry(AVStream *st,

                            int64_t pos, int64_t timestamp, int flags)

{

    AVIndexEntry *entries, *ie;

    entries = av_fast_realloc(st->index_entries,

                              &st->index_entries_allocated_size,

                              (st->nb_index_entries + 1) *

                              sizeof(AVIndexEntry));

    if (entries) {

        st->index_entries = entries;

        ie = &entries[st->nb_index_entries++];

        ie->pos = pos;

        ie->timestamp = timestamp;

        ie->flags = flags;

    }

}


static int rv10_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,

                             AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size       = avpkt->size;

    MpegEncContext *s = avctx->priv_data;

    AVFrame *pict = data;

    int i, ret;

    int slice_count;

    const uint8_t *slices_hdr = NULL;

    av_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size);

    /* no supplementary picture */

    if (buf_size == 0) {

        return 0;

    }

    if (!avctx->slice_count) {

        slice_count = (*buf++) + 1;

        buf_size--;

        if (!slice_count || buf_size <= 8 * slice_count) {

            av_log(avctx, AV_LOG_ERROR, "Invalid slice count: %d.\n",

                   slice_count);

            return AVERROR_INVALIDDATA;

        }

        slices_hdr = buf + 4;

        buf       += 8 * slice_count;

        buf_size  -= 8 * slice_count;

    } else

        slice_count = avctx->slice_count;

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

        unsigned offset = get_slice_offset(avctx, slices_hdr, i);

        int size, size2;

        if (offset >= buf_size)

            return AVERROR_INVALIDDATA;

        if (i + 1 == slice_count)

            size = buf_size - offset;

        else

            size = get_slice_offset(avctx, slices_hdr, i + 1) - offset;

        if (i + 2 >= slice_count)

            size2 = buf_size - offset;

        else

            size2 = get_slice_offset(avctx, slices_hdr, i + 2) - offset;

        if (size <= 0 || size2 <= 0 ||

            offset + FFMAX(size, size2) > buf_size)

            return AVERROR_INVALIDDATA;

        if ((ret = rv10_decode_packet(avctx, buf + offset, size, size2)) < 0)

            return ret;

        if (ret > 8 * size)

            i++;

    }

    if (s->current_picture_ptr != NULL && s->mb_y >= s->mb_height) {

        ff_er_frame_end(&s->er);

        ff_MPV_frame_end(s);

        if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {

            if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)

                return ret;

            ff_print_debug_info(s, s->current_picture_ptr);

        } else if (s->last_picture_ptr != NULL) {

            if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)

                return ret;

            ff_print_debug_info(s, s->last_picture_ptr);

        }

        if (s->last_picture_ptr || s->low_delay) {

            *got_frame = 1;

        }

        // so we can detect if frame_end was not called (find some nicer solution...)

        s->current_picture_ptr = NULL;

    }

    return avpkt->size;

}


ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb,

                           AVStream *st, RMStream *rst, int codec_data_size)

{

    unsigned int v;

    int size;

    int64_t codec_pos;

    int ret;

    avpriv_set_pts_info(st, 64, 1, 1000);

    codec_pos = avio_tell(pb);

    v = avio_rb32(pb);

    if (v == MKTAG(0xfd, 'a', 'r', '.')) {

        /* ra type header */

        if (rm_read_audio_stream_info(s, pb, st, rst, 0))

            return -1;

    } else if (v == MKBETAG('L', 'S', 'D', ':')) {

        avio_seek(pb, -4, SEEK_CUR);

        if ((ret = rm_read_extradata(pb, st->codec, codec_data_size)) < 0)

            return ret;

        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

        st->codec->codec_tag  = AV_RL32(st->codec->extradata);

        st->codec->codec_id   = ff_codec_get_id(ff_rm_codec_tags,

                                                st->codec->codec_tag);

    } else {

        int fps;

        if (avio_rl32(pb) != MKTAG('V', 'I', 'D', 'O')) {

        fail1:

            av_log(st->codec, AV_LOG_ERROR, "Unsupported video codec\n");

            goto skip;

        }

        st->codec->codec_tag = avio_rl32(pb);

        st->codec->codec_id  = ff_codec_get_id(ff_rm_codec_tags,

                                               st->codec->codec_tag);

//        av_log(s, AV_LOG_DEBUG, "%X %X\n", st->codec->codec_tag, MKTAG('R', 'V', '2', '0'));

        if (st->codec->codec_id == CODEC_ID_NONE)

            goto fail1;

        st->codec->width  = avio_rb16(pb);

        st->codec->height = avio_rb16(pb);

        avio_skip(pb, 2); // looks like bits per sample

        avio_skip(pb, 4); // always zero?

        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

        st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;

        fps = avio_rb32(pb);

        if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (avio_tell(pb) - codec_pos))) < 0)

            return ret;

        av_reduce(&st->r_frame_rate.den, &st->r_frame_rate.num,

                  0x10000, fps, (1 << 30) - 1);

        st->avg_frame_rate = st->r_frame_rate;

    }

skip:

    /* skip codec info */

    size = avio_tell(pb) - codec_pos;

    avio_skip(pb, codec_data_size - size);

    return 0;

}


static void put_uint64(QEMUFile *f, void *pv, size_t size)

{

    uint64_t *v = pv;

    qemu_put_be64s(f, v);

}


QJSON *qjson_new(void)

{

    QJSON *json = QJSON(object_new(TYPE_QJSON));

    return json;

}


void kqemu_record_dump(void)

{

    PCRecord **pr, *r;

    int i, h;

    FILE *f;

    int64_t total, sum;

    pr = malloc(sizeof(PCRecord *) * nb_pc_records);

    i = 0;

    total = 0;

    for(h = 0; h < PC_REC_HASH_SIZE; h++) {

        for(r = pc_rec_hash[h]; r != NULL; r = r->next) {

            pr[i++] = r;

            total += r->count;

        }

    }

    qsort(pr, nb_pc_records, sizeof(PCRecord *), pc_rec_cmp);

    f = fopen("/tmp/kqemu.stats", "w");

    if (!f) {

        perror("/tmp/kqemu.stats");

        exit(1);

    }

    fprintf(f, "total: %" PRId64 "\n", total);

    sum = 0;

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

        r = pr[i];

        sum += r->count;

        fprintf(f, "%08lx: %" PRId64 " %0.2f%% %0.2f%%\n",

                r->pc,

                r->count,

                (double)r->count / (double)total * 100.0,

                (double)sum / (double)total * 100.0);

    }

    fclose(f);

    free(pr);

    kqemu_record_flush();

}


static void pcnet_receive(void *opaque, const uint8_t *buf, size_t size)

{

    PCNetState *s = opaque;

    int is_padr = 0, is_bcast = 0, is_ladr = 0;

    uint8_t buf1[60];

    int remaining;

    int crc_err = 0;

    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)

        return;

#ifdef PCNET_DEBUG

    printf("pcnet_receive size=%d\n", size);

#endif

    /* if too small buffer, then expand it */

    if (size < MIN_BUF_SIZE) {

        memcpy(buf1, buf, size);

        memset(buf1 + size, 0, MIN_BUF_SIZE - size);

        buf = buf1;

        size = MIN_BUF_SIZE;

    }

    if (CSR_PROM(s)

        || (is_padr=padr_match(s, buf, size))

        || (is_bcast=padr_bcast(s, buf, size))

        || (is_ladr=ladr_match(s, buf, size))) {

        pcnet_rdte_poll(s);

        if (!(CSR_CRST(s) & 0x8000) && s->rdra) {

            struct pcnet_RMD rmd;

            int rcvrc = CSR_RCVRC(s)-1,i;

            target_phys_addr_t nrda;

            for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {

                if (rcvrc <= 1)

                    rcvrc = CSR_RCVRL(s);

                nrda = s->rdra +

                    (CSR_RCVRL(s) - rcvrc) *

                    (BCR_SWSTYLE(s) ? 16 : 8 );

                RMDLOAD(&rmd, nrda);

                if (GET_FIELD(rmd.status, RMDS, OWN)) {

#ifdef PCNET_DEBUG_RMD

                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",

                                rcvrc, CSR_RCVRC(s));

#endif

                    CSR_RCVRC(s) = rcvrc;

                    pcnet_rdte_poll(s);

                    break;

                }

            }

        }

        if (!(CSR_CRST(s) & 0x8000)) {

#ifdef PCNET_DEBUG_RMD

            printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));

#endif

            s->csr[0] |= 0x1000; /* Set MISS flag */

            CSR_MISSC(s)++;

        } else {

            uint8_t *src = s->buffer;

            target_phys_addr_t crda = CSR_CRDA(s);

            struct pcnet_RMD rmd;

            int pktcount = 0;

            if (!s->looptest) {

                memcpy(src, buf, size);

                /* no need to compute the CRC */

                src[size] = 0;

                src[size + 1] = 0;

                src[size + 2] = 0;

                src[size + 3] = 0;

                size += 4;

            } else if (s->looptest == PCNET_LOOPTEST_CRC ||

                       !CSR_DXMTFCS(s) || size < MIN_BUF_SIZE+4) {

                uint32_t fcs = ~0;

                uint8_t *p = src;

                while (p != &src[size])

                    CRC(fcs, *p++);

                *(uint32_t *)p = htonl(fcs);

                size += 4;

            } else {

                uint32_t fcs = ~0;

                uint8_t *p = src;

                while (p != &src[size-4])

                    CRC(fcs, *p++);

                crc_err = (*(uint32_t *)p != htonl(fcs));

            }

#ifdef PCNET_DEBUG_MATCH

            PRINT_PKTHDR(buf);

#endif

            RMDLOAD(&rmd, PHYSADDR(s,crda));

            /*if (!CSR_LAPPEN(s))*/

                SET_FIELD(&rmd.status, RMDS, STP, 1);

#define PCNET_RECV_STORE() do {                                 \

    int count = MIN(4096 - GET_FIELD(rmd.buf_length, RMDL, BCNT),remaining); \

    target_phys_addr_t rbadr = PHYSADDR(s, rmd.rbadr);          \

    s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \

    src += count; remaining -= count;                           \

    SET_FIELD(&rmd.status, RMDS, OWN, 0);                       \

    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \

    pktcount++;                                                 \

} while (0)

            remaining = size;

            PCNET_RECV_STORE();

            if ((remaining > 0) && CSR_NRDA(s)) {

                target_phys_addr_t nrda = CSR_NRDA(s);

#ifdef PCNET_DEBUG_RMD

                PRINT_RMD(&rmd);

#endif

                RMDLOAD(&rmd, PHYSADDR(s,nrda));

                if (GET_FIELD(rmd.status, RMDS, OWN)) {

                    crda = nrda;

                    PCNET_RECV_STORE();

#ifdef PCNET_DEBUG_RMD

                    PRINT_RMD(&rmd);

#endif

                    if ((remaining > 0) && (nrda=CSR_NNRD(s))) {

                        RMDLOAD(&rmd, PHYSADDR(s,nrda));

                        if (GET_FIELD(rmd.status, RMDS, OWN)) {

                            crda = nrda;

                            PCNET_RECV_STORE();

                        }

                    }

                }

            }

#undef PCNET_RECV_STORE

            RMDLOAD(&rmd, PHYSADDR(s,crda));

            if (remaining == 0) {

                SET_FIELD(&rmd.msg_length, RMDM, MCNT, size);

                SET_FIELD(&rmd.status, RMDS, ENP, 1);

                SET_FIELD(&rmd.status, RMDS, PAM, !CSR_PROM(s) && is_padr);

                SET_FIELD(&rmd.status, RMDS, LFAM, !CSR_PROM(s) && is_ladr);

                SET_FIELD(&rmd.status, RMDS, BAM, !CSR_PROM(s) && is_bcast);

                if (crc_err) {

                    SET_FIELD(&rmd.status, RMDS, CRC, 1);

                    SET_FIELD(&rmd.status, RMDS, ERR, 1);

                }

            } else {

                SET_FIELD(&rmd.status, RMDS, OFLO, 1);

                SET_FIELD(&rmd.status, RMDS, BUFF, 1);

                SET_FIELD(&rmd.status, RMDS, ERR, 1);

            }

            RMDSTORE(&rmd, PHYSADDR(s,crda));

            s->csr[0] |= 0x0400;

#ifdef PCNET_DEBUG

            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",

                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);

#endif

#ifdef PCNET_DEBUG_RMD

            PRINT_RMD(&rmd);

#endif

            while (pktcount--) {

                if (CSR_RCVRC(s) <= 1)

                    CSR_RCVRC(s) = CSR_RCVRL(s);

                else

                    CSR_RCVRC(s)--;

            }

            pcnet_rdte_poll(s);

        }

    }

    pcnet_poll(s);

    pcnet_update_irq(s);

}


static void nbd_reply_ready(void *opaque)

{

    NbdClientSession *s = opaque;

    uint64_t i;

    int ret;

    if (s->reply.handle == 0) {

        /* No reply already in flight.  Fetch a header.  It is possible

         * that another thread has done the same thing in parallel, so

         * the socket is not readable anymore.

         */

        ret = nbd_receive_reply(s->sock, &s->reply);

        if (ret == -EAGAIN) {

            return;

        }

        if (ret < 0) {

            s->reply.handle = 0;

            goto fail;

        }

    }

    /* There's no need for a mutex on the receive side, because the

     * handler acts as a synchronization point and ensures that only

     * one coroutine is called until the reply finishes.  */

    i = HANDLE_TO_INDEX(s, s->reply.handle);

    if (i >= MAX_NBD_REQUESTS) {

        goto fail;

    }

    if (s->recv_coroutine[i]) {

        qemu_coroutine_enter(s->recv_coroutine[i], NULL);

        return;

    }

fail:

    nbd_teardown_connection(s);

}


static void ffm_write_data(AVFormatContext *s,

                           const uint8_t *buf, int size,

                           int64_t pts, int header)

{

    FFMContext *ffm = s->priv_data;

    int len;

    if (header && ffm->frame_offset == 0) {

        ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE;

        ffm->pts = pts;

    }

    /* write as many packets as needed */

    while (size > 0) {

        len = ffm->packet_end - ffm->packet_ptr;

        if (len > size)

            len = size;

        memcpy(ffm->packet_ptr, buf, len);

        ffm->packet_ptr += len;

        buf += len;

        size -= len;

        if (ffm->packet_ptr >= ffm->packet_end) {

            /* special case : no pts in packet : we leave the current one */

            if (ffm->pts == 0)

                ffm->pts = pts;

            flush_packet(s);

        }

    }

}


static inline void vmsvga_cursor_define(struct vmsvga_state_s *s,

                struct vmsvga_cursor_definition_s *c)

{

    QEMUCursor *qc;

    int i, pixels;

    qc = cursor_alloc(c->width, c->height);

    qc->hot_x = c->hot_x;

    qc->hot_y = c->hot_y;

    switch (c->bpp) {

    case 1:

        cursor_set_mono(qc, 0xffffff, 0x000000, (void*)c->image,

                        1, (void*)c->mask);

#ifdef DEBUG

        cursor_print_ascii_art(qc, "vmware/mono");

#endif

        break;

    case 32:

        /* fill alpha channel from mask, set color to zero */

        cursor_set_mono(qc, 0x000000, 0x000000, (void*)c->mask,

                        1, (void*)c->mask);

        /* add in rgb values */

        pixels = c->width * c->height;

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

            qc->data[i] |= c->image[i] & 0xffffff;

        }

#ifdef DEBUG

        cursor_print_ascii_art(qc, "vmware/32bit");

#endif

        break;

    default:

        fprintf(stderr, "%s: unhandled bpp %d, using fallback cursor\n",

                __FUNCTION__, c->bpp);

        cursor_put(qc);

        qc = cursor_builtin_left_ptr();

    }

    dpy_cursor_define(s->vga.ds, qc);

    cursor_put(qc);

}


static void FUNCC(pred4x4_horizontal_add)(uint8_t *_pix, const int16_t *_block,

                                          ptrdiff_t stride)

{

    int i;

    pixel *pix = (pixel*)_pix;

    const dctcoef *block = (const dctcoef*)_block;

    stride >>= sizeof(pixel)-1;

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

        pixel v = pix[-1];

        pix[0]= v += block[0];

        pix[1]= v += block[1];

        pix[2]= v += block[2];

        pix[3]= v +  block[3];

        pix+= stride;

        block+= 4;

    }

}


static void set_proc_name(const char *s)

{

#ifdef __linux__

    char name[16];

    if (!s)

        return;

    name[sizeof(name) - 1] = 0;

    strncpy(name, s, sizeof(name));

    /* Could rewrite argv[0] too, but that's a bit more complicated.

       This simple way is enough for `top'. */

    prctl(PR_SET_NAME, name);

#endif

}


int nbd_client_session_co_flush(NbdClientSession *client)

{

    struct nbd_request request;

    struct nbd_reply reply;

    ssize_t ret;

    if (!(client->nbdflags & NBD_FLAG_SEND_FLUSH)) {

        return 0;

    }

    request.type = NBD_CMD_FLUSH;

    if (client->nbdflags & NBD_FLAG_SEND_FUA) {

        request.type |= NBD_CMD_FLAG_FUA;

    }

    request.from = 0;

    request.len = 0;

    nbd_coroutine_start(client, &request);

    ret = nbd_co_send_request(client, &request, NULL, 0);

    if (ret < 0) {

        reply.error = -ret;

    } else {

        nbd_co_receive_reply(client, &request, &reply, NULL, 0);

    }

    nbd_coroutine_end(client, &request);

    return -reply.error;

}


int av_opencl_buffer_read(uint8_t *dst_buf, cl_mem src_cl_buf, size_t buf_size)

{

    cl_int status;

    void *mapped = clEnqueueMapBuffer(gpu_env.command_queue, src_cl_buf,

                                      CL_TRUE,CL_MAP_READ, 0, buf_size,

                                      0, NULL, NULL, &status);

    if (status != CL_SUCCESS) {

        av_log(&openclutils, AV_LOG_ERROR, "Could not map OpenCL buffer: %s\n", opencl_errstr(status));

        return AVERROR_EXTERNAL;

    }

    memcpy(dst_buf, mapped, buf_size);

    status = clEnqueueUnmapMemObject(gpu_env.command_queue, src_cl_buf, mapped, 0, NULL, NULL);

    if (status != CL_SUCCESS) {

        av_log(&openclutils, AV_LOG_ERROR, "Could not unmap OpenCL buffer: %s\n", opencl_errstr(status));

        return AVERROR_EXTERNAL;

    }

    return 0;

}


static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)

{

    AVStream *st;

    MOVStreamContext *sc;

    unsigned int i, entries;

    if (c->fc->nb_streams < 1)

        return 0;

    st = c->fc->streams[c->fc->nb_streams-1];

    sc = st->priv_data;

    avio_r8(pb); /* version */

    avio_rb24(pb); /* flags */

    entries = avio_rb32(pb);

    av_log(c->fc, AV_LOG_TRACE, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);

    if (!entries)

        return 0;

    if (entries >= UINT_MAX / sizeof(*sc->stsc_data))

        return AVERROR_INVALIDDATA;

    sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));

    if (!sc->stsc_data)

        return AVERROR(ENOMEM);

    for (i = 0; i < entries && !pb->eof_reached; i++) {

        sc->stsc_data[i].first = avio_rb32(pb);

        sc->stsc_data[i].count = avio_rb32(pb);

        sc->stsc_data[i].id = avio_rb32(pb);

        if (sc->stsc_data[i].id > sc->stsd_count)

            return AVERROR_INVALIDDATA;

    }

    sc->stsc_count = i;

    if (pb->eof_reached)

        return AVERROR_EOF;

    return 0;

}


static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag,

                        uint32_t size)

{

    AVIOContext *pb = s->pb;

    char key[5]     = { 0 };

    char *value;

    size += (size & 1);

    if (size == UINT_MAX)

        return AVERROR(EINVAL);

    value = av_malloc(size + 1);

    if (!value)

        return AVERROR(ENOMEM);

    avio_read(pb, value, size);

    value[size] = 0;

    AV_WL32(key, tag);

    return av_dict_set(st ? &st->metadata : &s->metadata, key, value,

                       AV_DICT_DONT_STRDUP_VAL);

}


void qemu_file_set_rate_limit(QEMUFile *f, int64_t limit)

{

    f->xfer_limit = limit;

}


static void qobject_input_type_bool(Visitor *v, const char *name, bool *obj,

                                    Error **errp)

{

    QObjectInputVisitor *qiv = to_qiv(v);

    QObject *qobj = qobject_input_get_object(qiv, name, true, errp);

    QBool *qbool;

    if (!qobj) {

        return;

    }

    qbool = qobject_to_qbool(qobj);

    if (!qbool) {

        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",

                   "boolean");

        return;

    }

    *obj = qbool_get_bool(qbool);

}


int kvm_arch_get_registers(CPUState *cs)

{

    S390CPU *cpu = S390_CPU(cs);

    CPUS390XState *env = &cpu->env;

    struct kvm_one_reg reg;

    struct kvm_sregs sregs;

    struct kvm_regs regs;

    int i, r;

    /* get the PSW */

    env->psw.addr = cs->kvm_run->psw_addr;

    env->psw.mask = cs->kvm_run->psw_mask;

    /* the GPRS */

    if (cap_sync_regs && cs->kvm_run->kvm_valid_regs & KVM_SYNC_GPRS) {

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

            env->regs[i] = cs->kvm_run->s.regs.gprs[i];

        }

    } else {

        r = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);

        if (r < 0) {

            return r;

        }

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

            env->regs[i] = regs.gprs[i];

        }

    }

    /* The ACRS and CRS */

    if (cap_sync_regs &&

        cs->kvm_run->kvm_valid_regs & KVM_SYNC_ACRS &&

        cs->kvm_run->kvm_valid_regs & KVM_SYNC_CRS) {

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

            env->aregs[i] = cs->kvm_run->s.regs.acrs[i];

            env->cregs[i] = cs->kvm_run->s.regs.crs[i];

        }

    } else {

        r = kvm_vcpu_ioctl(cs, KVM_GET_SREGS, &sregs);

        if (r < 0) {

            return r;

        }

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

            env->aregs[i] = sregs.acrs[i];

            env->cregs[i] = sregs.crs[i];

        }

    }

    /* The prefix */

    if (cap_sync_regs && cs->kvm_run->kvm_valid_regs & KVM_SYNC_PREFIX) {

        env->psa = cs->kvm_run->s.regs.prefix;

    }

    /* One Regs */

    reg.id = KVM_REG_S390_CPU_TIMER;

    reg.addr = (__u64)&(env->cputm);

    r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);

    if (r < 0) {

        return r;

    }

    reg.id = KVM_REG_S390_CLOCK_COMP;

    reg.addr = (__u64)&(env->ckc);

    r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);

    if (r < 0) {

        return r;

    }

    reg.id = KVM_REG_S390_TODPR;

    reg.addr = (__u64)&(env->todpr);

    r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);

    if (r < 0) {

        return r;

    }

    if (cap_async_pf) {

        reg.id = KVM_REG_S390_PFTOKEN;

        reg.addr = (__u64)&(env->pfault_token);

        r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);

        if (r < 0) {

            return r;

        }

        reg.id = KVM_REG_S390_PFCOMPARE;

        reg.addr = (__u64)&(env->pfault_compare);

        r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);

        if (r < 0) {

            return r;

        }

        reg.id = KVM_REG_S390_PFSELECT;

        reg.addr = (__u64)&(env->pfault_select);

        r = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);

        if (r < 0) {

            return r;

        }

    }

    return 0;

}


int select_watchdog(const char *p)

{

    WatchdogTimerModel *model;

    QemuOpts *opts;

    /* -watchdog ? lists available devices and exits cleanly. */

    if (strcmp(p, "?") == 0) {

        LIST_FOREACH(model, &watchdog_list, entry) {

            fprintf(stderr, "\t%s\t%s\n",

                     model->wdt_name, model->wdt_description);

        }

        return 2;

    }

    LIST_FOREACH(model, &watchdog_list, entry) {

        if (strcasecmp(model->wdt_name, p) == 0) {

            /* add the device */

            opts = qemu_opts_create(&qemu_device_opts, NULL, 0);

            qemu_opt_set(opts, "driver", p);

            return 0;

        }

    }

    fprintf(stderr, "Unknown -watchdog device. Supported devices are:\n");

    LIST_FOREACH(model, &watchdog_list, entry) {

        fprintf(stderr, "\t%s\t%s\n",

                 model->wdt_name, model->wdt_description);

    }

    return 1;

}


static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)

{

    VirtIOBalloon *s = VIRTIO_BALLOON(vdev);

    VirtQueueElement elem;

    MemoryRegionSection section;

    while (virtqueue_pop(vq, &elem)) {

        size_t offset = 0;

        uint32_t pfn;

        while (iov_to_buf(elem.out_sg, elem.out_num, offset, &pfn, 4) == 4) {

            ram_addr_t pa;

            ram_addr_t addr;

            int p = virtio_ldl_p(vdev, &pfn);

            pa = (ram_addr_t) p << VIRTIO_BALLOON_PFN_SHIFT;

            offset += 4;

            /* FIXME: remove get_system_memory(), but how? */

            section = memory_region_find(get_system_memory(), pa, 1);

            if (!int128_nz(section.size) || !memory_region_is_ram(section.mr))

                continue;

            trace_virtio_balloon_handle_output(memory_region_name(section.mr),

                                               pa);

            /* Using memory_region_get_ram_ptr is bending the rules a bit, but

               should be OK because we only want a single page.  */

            addr = section.offset_within_region;

            balloon_page(memory_region_get_ram_ptr(section.mr) + addr,

                         !!(vq == s->dvq));

            memory_region_unref(section.mr);

        }

        virtqueue_push(vq, &elem, offset);

        virtio_notify(vdev, vq);

    }

}


static av_cold int vorbis_decode_init(AVCodecContext *avccontext)

{

    vorbis_context *vc = avccontext->priv_data;

    uint8_t *headers   = avccontext->extradata;

    int headers_len    = avccontext->extradata_size;

    uint8_t *header_start[3];

    int header_len[3];

    GetBitContext *gb = &vc->gb;

    int hdr_type, ret;

    vc->avccontext = avccontext;

    ff_dsputil_init(&vc->dsp, avccontext);

    ff_fmt_convert_init(&vc->fmt_conv, avccontext);

    if (avccontext->request_sample_fmt == AV_SAMPLE_FMT_FLT) {

        avccontext->sample_fmt = AV_SAMPLE_FMT_FLT;

        vc->scale_bias = 1.0f;

    } else {

        avccontext->sample_fmt = AV_SAMPLE_FMT_S16;

        vc->scale_bias = 32768.0f;

    }

    if (!headers_len) {

        av_log(avccontext, AV_LOG_ERROR, "Extradata missing.\n");

        return AVERROR_INVALIDDATA;

    }

    if ((ret = avpriv_split_xiph_headers(headers, headers_len, 30, header_start, header_len)) < 0) {

        av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n");

        return ret;

    }

    init_get_bits(gb, header_start[0], header_len[0]*8);

    hdr_type = get_bits(gb, 8);

    if (hdr_type != 1) {

        av_log(avccontext, AV_LOG_ERROR, "First header is not the id header.\n");

        return AVERROR_INVALIDDATA;

    }

    if ((ret = vorbis_parse_id_hdr(vc))) {

        av_log(avccontext, AV_LOG_ERROR, "Id header corrupt.\n");

        vorbis_free(vc);

        return ret;

    }

    init_get_bits(gb, header_start[2], header_len[2]*8);

    hdr_type = get_bits(gb, 8);

    if (hdr_type != 5) {

        av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n");

        vorbis_free(vc);

        return AVERROR_INVALIDDATA;

    }

    if ((ret = vorbis_parse_setup_hdr(vc))) {

        av_log(avccontext, AV_LOG_ERROR, "Setup header corrupt.\n");

        vorbis_free(vc);

        return ret;

    }

    if (vc->audio_channels > 8)

        avccontext->channel_layout = 0;

    else

        avccontext->channel_layout = ff_vorbis_channel_layouts[vc->audio_channels - 1];

    avccontext->channels    = vc->audio_channels;

    avccontext->sample_rate = vc->audio_samplerate;

    avccontext->frame_size  = FFMIN(vc->blocksize[0], vc->blocksize[1]) >> 2;

    avcodec_get_frame_defaults(&vc->frame);

    avccontext->coded_frame = &vc->frame;

    return 0;

}


static void blk_send(QEMUFile *f, BlkMigBlock * blk)

{

    int len;

    uint64_t flags = BLK_MIG_FLAG_DEVICE_BLOCK;

    if (block_mig_state.zero_blocks &&

        buffer_is_zero(blk->buf, BLOCK_SIZE)) {

        flags |= BLK_MIG_FLAG_ZERO_BLOCK;

    }

    /* sector number and flags */

    qemu_put_be64(f, (blk->sector << BDRV_SECTOR_BITS)

                     | flags);

    /* device name */

    len = strlen(bdrv_get_device_name(blk->bmds->bs));

    qemu_put_byte(f, len);

    qemu_put_buffer(f, (uint8_t *)bdrv_get_device_name(blk->bmds->bs), len);

    /* if a block is zero we need to flush here since the network

     * bandwidth is now a lot higher than the storage device bandwidth.

     * thus if we queue zero blocks we slow down the migration */

    if (flags & BLK_MIG_FLAG_ZERO_BLOCK) {

        qemu_fflush(f);

        return;

    }

    qemu_put_buffer(f, blk->buf, BLOCK_SIZE);

}


int64_t qmp_guest_fsfreeze_freeze(Error **err)

{

    int ret = 0, i = 0;

    FsMountList mounts;

    struct FsMount *mount;

    Error *local_err = NULL;

    int fd;

    slog("guest-fsfreeze called");

    execute_fsfreeze_hook(FSFREEZE_HOOK_FREEZE, &local_err);

    if (error_is_set(&local_err)) {

        error_propagate(err, local_err);

        return -1;

    }

    QTAILQ_INIT(&mounts);

    build_fs_mount_list(&mounts, &local_err);

    if (error_is_set(&local_err)) {

        error_propagate(err, local_err);

        return -1;

    }

    /* cannot risk guest agent blocking itself on a write in this state */

    ga_set_frozen(ga_state);

    QTAILQ_FOREACH(mount, &mounts, next) {

        fd = qemu_open(mount->dirname, O_RDONLY);

        if (fd == -1) {

            error_setg_errno(err, errno, "failed to open %s", mount->dirname);

            goto error;

        }

        /* we try to cull filesytems we know won't work in advance, but other

         * filesytems may not implement fsfreeze for less obvious reasons.

         * these will report EOPNOTSUPP. we simply ignore these when tallying

         * the number of frozen filesystems.

         *

         * any other error means a failure to freeze a filesystem we

         * expect to be freezable, so return an error in those cases

         * and return system to thawed state.

         */

        ret = ioctl(fd, FIFREEZE);

        if (ret == -1) {

            if (errno != EOPNOTSUPP) {

                error_setg_errno(err, errno, "failed to freeze %s",

                                 mount->dirname);

                close(fd);

                goto error;

            }

        } else {

            i++;

        }

        close(fd);

    }

    free_fs_mount_list(&mounts);

    return i;

error:

    free_fs_mount_list(&mounts);

    qmp_guest_fsfreeze_thaw(NULL);

    return 0;

}


int qemu_devtree_setprop_string(void *fdt, const char *node_path,

                                const char *property, const char *string)

{

    int offset;

    offset = fdt_path_offset(fdt, node_path);

    if (offset < 0)

        return offset;

    return fdt_setprop_string(fdt, offset, property, string);

}


static uint32_t calc_optimal_rice_params(RiceContext *rc, int porder,

                                         uint32_t *sums, int n, int pred_order)

{

    int i;

    int k, cnt, part;

    uint32_t all_bits;

    part     = (1 << porder);

    all_bits = 4 * part;

    cnt = (n >> porder) - pred_order;

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

        k = find_optimal_param(sums[i], cnt);

        rc->params[i] = k;

        all_bits += rice_encode_count(sums[i], cnt, k);

        cnt = n >> porder;

    }

    rc->porder = porder;

    return all_bits;

}


static void external_snapshot_commit(BlkActionState *common)

{

    ExternalSnapshotState *state =

                             DO_UPCAST(ExternalSnapshotState, common, common);

    bdrv_set_aio_context(state->new_bs, state->aio_context);

    /* This removes our old bs and adds the new bs */

    bdrv_append(state->new_bs, state->old_bs);

    /* We don't need (or want) to use the transactional

     * bdrv_reopen_multiple() across all the entries at once, because we

     * don't want to abort all of them if one of them fails the reopen */

    bdrv_reopen(state->old_bs, state->old_bs->open_flags & ~BDRV_O_RDWR,

                NULL);

}


int av_image_alloc(uint8_t *pointers[4], int linesizes[4],

                   int w, int h, enum PixelFormat pix_fmt, int align)

{

    int i, ret;

    uint8_t *buf;

    if ((ret = av_image_check_size(w, h, 0, NULL)) < 0)

        return ret;

    if ((ret = av_image_fill_linesizes(linesizes, pix_fmt, w)) < 0)

        return ret;

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

        linesizes[i] = FFALIGN(linesizes[i], align);

    if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, NULL, linesizes)) < 0)

        return ret;

    buf = av_malloc(ret + align);

    if (!buf)

        return AVERROR(ENOMEM);

    if ((ret = av_image_fill_pointers(pointers, pix_fmt, h, buf, linesizes)) < 0) {

        av_free(buf);

        return ret;

    }

    if (av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_PAL)

        ff_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt);

    return ret;

}


static void rc4030_dma_as_update_one(rc4030State *s, int index, uint32_t frame)

{

    if (index < MAX_TL_ENTRIES) {

        memory_region_set_enabled(&s->dma_mrs[index], false);

    }

    if (!frame) {

        return;

    }

    if (index >= MAX_TL_ENTRIES) {

        qemu_log_mask(LOG_UNIMP,

                      "rc4030: trying to use too high "

                      "translation table entry %d (max allowed=%d)",

                      index, MAX_TL_ENTRIES);

        return;

    }

    memory_region_set_alias_offset(&s->dma_mrs[index], frame);

    memory_region_set_enabled(&s->dma_mrs[index], true);

}


static bool virtio_scsi_data_plane_handle_cmd(VirtIODevice *vdev,

                                              VirtQueue *vq)

{

    VirtIOSCSI *s = (VirtIOSCSI *)vdev;

    assert(s->ctx && s->dataplane_started);

    return virtio_scsi_handle_cmd_vq(s, vq);

}


USBDevice *usb_host_device_open(const char *devname)

{

    struct usb_device_info bus_info, dev_info;

    USBDevice *d = NULL;

    USBHostDevice *dev;

    char ctlpath[PATH_MAX + 1];

    char buspath[PATH_MAX + 1];

    int bfd, dfd, bus, address, i;

    int ugendebug = UGEN_DEBUG_LEVEL;

    if (usb_host_find_device(&bus, &address, devname) < 0)

        return NULL;

    snprintf(buspath, PATH_MAX, "/dev/usb%d", bus);

    bfd = open(buspath, O_RDWR);

    if (bfd < 0) {

#ifdef DEBUG

        printf("usb_host_device_open: failed to open usb bus - %s\n",

               strerror(errno));

#endif

        return NULL;

    }

    bus_info.udi_addr = address;

    if (ioctl(bfd, USB_DEVICEINFO, &bus_info) < 0) {

#ifdef DEBUG

        printf("usb_host_device_open: failed to grab bus information - %s\n",

               strerror(errno));

#endif

        return NULL;

    }

#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)

    snprintf(ctlpath, PATH_MAX, "/dev/%s", bus_info.udi_devnames[0]);

#else

    snprintf(ctlpath, PATH_MAX, "/dev/%s.00", bus_info.udi_devnames[0]);

#endif

    dfd  = open(ctlpath, O_RDWR);

    if (dfd < 0) {

        dfd = open(ctlpath, O_RDONLY);

        if (dfd < 0) {

#ifdef DEBUG

            printf("usb_host_device_open: failed to open usb device %s - %s\n",

                   ctlpath, strerror(errno));

#endif

        }

    }

    if (dfd >= 0) {

        if (ioctl(dfd, USB_GET_DEVICEINFO, &dev_info) < 0) {

#ifdef DEBUG

            printf("usb_host_device_open: failed to grab device info - %s\n",

                   strerror(errno));

#endif

            goto fail;

        }

        d = usb_create(NULL /* FIXME */, "usb-host");

        dev = DO_UPCAST(USBHostDevice, dev, d);

        if (dev_info.udi_speed == 1)

            dev->dev.speed = USB_SPEED_LOW - 1;

        else

            dev->dev.speed = USB_SPEED_FULL - 1;

        if (strncmp(dev_info.udi_product, "product", 7) != 0)

            pstrcpy(dev->dev.product_desc, sizeof(dev->dev.product_desc),

                    dev_info.udi_product);

        else

            snprintf(dev->dev.product_desc, sizeof(dev->dev.product_desc),

                     "host:%s", devname);

        pstrcpy(dev->devpath, sizeof(dev->devpath), "/dev/");

        pstrcat(dev->devpath, sizeof(dev->devpath), dev_info.udi_devnames[0]);

        /* Mark the endpoints as not yet open */

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

           dev->ep_fd[i] = -1;

        ioctl(dfd, USB_SETDEBUG, &ugendebug);

        return (USBDevice *)dev;

    }

fail:

    return NULL;

}


static av_cold int twin_decode_init(AVCodecContext *avctx)

{

    int ret;

    TwinContext *tctx = avctx->priv_data;

    int isampf, ibps;

    tctx->avctx       = avctx;

    avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;

    if (!avctx->extradata || avctx->extradata_size < 12) {

        av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n");

        return AVERROR_INVALIDDATA;

    }

    avctx->channels = AV_RB32(avctx->extradata    ) + 1;

    avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000;

    isampf          = AV_RB32(avctx->extradata + 8);

    if (isampf < 8 || isampf > 44) {

        av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate\n");

        return AVERROR_INVALIDDATA;

    }

    switch (isampf) {

    case 44: avctx->sample_rate = 44100;         break;

    case 22: avctx->sample_rate = 22050;         break;

    case 11: avctx->sample_rate = 11025;         break;

    default: avctx->sample_rate = isampf * 1000; break;

    }

    if (avctx->channels <= 0 || avctx->channels > CHANNELS_MAX) {

        av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n",

               avctx->channels);

        return -1;

    }

    avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO :

                                                   AV_CH_LAYOUT_STEREO;

    ibps = avctx->bit_rate / (1000 * avctx->channels);

    if (ibps > 255) {

        av_log(avctx, AV_LOG_ERROR, "unsupported per channel bitrate %dkbps\n", ibps);

        return AVERROR_INVALIDDATA;

    }

    switch ((isampf << 8) +  ibps) {

    case (8 <<8) +  8: tctx->mtab = &mode_08_08; break;

    case (11<<8) +  8: tctx->mtab = &mode_11_08; break;

    case (11<<8) + 10: tctx->mtab = &mode_11_10; break;

    case (16<<8) + 16: tctx->mtab = &mode_16_16; break;

    case (22<<8) + 20: tctx->mtab = &mode_22_20; break;

    case (22<<8) + 24: tctx->mtab = &mode_22_24; break;

    case (22<<8) + 32: tctx->mtab = &mode_22_32; break;

    case (44<<8) + 40: tctx->mtab = &mode_44_40; break;

    case (44<<8) + 48: tctx->mtab = &mode_44_48; break;

    default:

        av_log(avctx, AV_LOG_ERROR, "This version does not support %d kHz - %d kbit/s/ch mode.\n", isampf, isampf);

        return -1;

    }

    ff_dsputil_init(&tctx->dsp, avctx);

    avpriv_float_dsp_init(&tctx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);

    if ((ret = init_mdct_win(tctx))) {

        av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n");

        twin_decode_close(avctx);

        return ret;

    }

    init_bitstream_params(tctx);

    memset_float(tctx->bark_hist[0][0], 0.1, FF_ARRAY_ELEMS(tctx->bark_hist));

    avcodec_get_frame_defaults(&tctx->frame);

    avctx->coded_frame = &tctx->frame;

    return 0;

}


static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)

{

    AVFormatContext *is = ifile->ctx;

    AVFormatContext *os = ofile->ctx;

    int i;

    for (i = 0; i < is->nb_chapters; i++) {

        AVChapter *in_ch = is->chapters[i], *out_ch;

        int64_t ts_off   = av_rescale_q(ofile->start_time - ifile->ts_offset,

                                       AV_TIME_BASE_Q, in_ch->time_base);

        int64_t rt       = (ofile->recording_time == INT64_MAX) ? INT64_MAX :

                           av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);

        if (in_ch->end < ts_off)

            continue;

        if (rt != INT64_MAX && in_ch->start > rt + ts_off)

            break;

        out_ch = av_mallocz(sizeof(AVChapter));

        if (!out_ch)

            return AVERROR(ENOMEM);

        out_ch->id        = in_ch->id;

        out_ch->time_base = in_ch->time_base;

        out_ch->start     = FFMAX(0,  in_ch->start - ts_off);

        out_ch->end       = FFMIN(rt, in_ch->end   - ts_off);

        if (copy_metadata)

            av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);

        os->nb_chapters++;

        os->chapters = av_realloc(os->chapters, sizeof(AVChapter) * os->nb_chapters);

        if (!os->chapters)

            return AVERROR(ENOMEM);

        os->chapters[os->nb_chapters - 1] = out_ch;

    }

    return 0;

}


int trace_record_start(TraceBufferRecord *rec, TraceEventID event, size_t datasize)

{

    unsigned int idx, rec_off, old_idx, new_idx;

    uint32_t rec_len = sizeof(TraceRecord) + datasize;

    uint64_t event_u64 = event;

    uint64_t timestamp_ns = get_clock();

    do {

        old_idx = g_atomic_int_get(&trace_idx);

        smp_rmb();

        new_idx = old_idx + rec_len;

        if (new_idx - writeout_idx > TRACE_BUF_LEN) {

            /* Trace Buffer Full, Event dropped ! */

            g_atomic_int_inc(&dropped_events);

            return -ENOSPC;

        }

    } while (!g_atomic_int_compare_and_exchange(&trace_idx, old_idx, new_idx));

    idx = old_idx % TRACE_BUF_LEN;

    rec_off = idx;

    rec_off = write_to_buffer(rec_off, &event_u64, sizeof(event_u64));

    rec_off = write_to_buffer(rec_off, &timestamp_ns, sizeof(timestamp_ns));

    rec_off = write_to_buffer(rec_off, &rec_len, sizeof(rec_len));

    rec_off = write_to_buffer(rec_off, &trace_pid, sizeof(trace_pid));

    rec->tbuf_idx = idx;

    rec->rec_off  = (idx + sizeof(TraceRecord)) % TRACE_BUF_LEN;

    return 0;

}


static float64 roundAndPackFloat64( flag zSign, int16 zExp, uint64_t zSig STATUS_PARAM)

{

    int8 roundingMode;

    flag roundNearestEven;

    int16 roundIncrement, roundBits;

    flag isTiny;

    roundingMode = STATUS(float_rounding_mode);

    roundNearestEven = ( roundingMode == float_round_nearest_even );

    roundIncrement = 0x200;

    if ( ! roundNearestEven ) {

        if ( roundingMode == float_round_to_zero ) {

            roundIncrement = 0;

        }

        else {

            roundIncrement = 0x3FF;

            if ( zSign ) {

                if ( roundingMode == float_round_up ) roundIncrement = 0;

            }

            else {

                if ( roundingMode == float_round_down ) roundIncrement = 0;

            }

        }

    }

    roundBits = zSig & 0x3FF;

    if ( 0x7FD <= (uint16_t) zExp ) {

        if (    ( 0x7FD < zExp )

             || (    ( zExp == 0x7FD )

                  && ( (int64_t) ( zSig + roundIncrement ) < 0 ) )

           ) {

            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);

            return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 ));

        }

        if ( zExp < 0 ) {

            if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 );

            isTiny =

                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )

                || ( zExp < -1 )

                || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );

            shift64RightJamming( zSig, - zExp, &zSig );

            zExp = 0;

            roundBits = zSig & 0x3FF;

            if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);

        }

    }

    if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;

    zSig = ( zSig + roundIncrement )>>10;

    zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );

    if ( zSig == 0 ) zExp = 0;

    return packFloat64( zSign, zExp, zSig );

}


static void xen_remap_bucket(MapCacheEntry *entry,

                             hwaddr size,

                             hwaddr address_index)

{

    uint8_t *vaddr_base;

    xen_pfn_t *pfns;

    int *err;

    unsigned int i;

    hwaddr nb_pfn = size >> XC_PAGE_SHIFT;

    trace_xen_remap_bucket(address_index);

    pfns = g_malloc0(nb_pfn * sizeof (xen_pfn_t));

    err = g_malloc0(nb_pfn * sizeof (int));

    if (entry->vaddr_base != NULL) {

        if (munmap(entry->vaddr_base, entry->size) != 0) {

            perror("unmap fails");

            exit(-1);

        }

    }

    g_free(entry->valid_mapping);

    entry->valid_mapping = NULL;

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

        pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;

    }

    vaddr_base = xc_map_foreign_bulk(xen_xc, xen_domid, PROT_READ|PROT_WRITE,

                                     pfns, err, nb_pfn);

    if (vaddr_base == NULL) {

        perror("xc_map_foreign_bulk");

        exit(-1);

    }

    entry->vaddr_base = vaddr_base;

    entry->paddr_index = address_index;

    entry->size = size;

    entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned long) *

            BITS_TO_LONGS(size >> XC_PAGE_SHIFT));

    bitmap_zero(entry->valid_mapping, nb_pfn);

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

        if (!err[i]) {

            bitmap_set(entry->valid_mapping, i, 1);

        }

    }

    g_free(pfns);

    g_free(err);

}


void usb_packet_complete(USBDevice *dev, USBPacket *p)

{

    USBEndpoint *ep = p->ep;

    int ret;

    assert(p->state == USB_PACKET_ASYNC);

    assert(QTAILQ_FIRST(&ep->queue) == p);

    usb_packet_set_state(p, USB_PACKET_COMPLETE);

    QTAILQ_REMOVE(&ep->queue, p, queue);

    dev->port->ops->complete(dev->port, p);

    while (!QTAILQ_EMPTY(&ep->queue)) {

        p = QTAILQ_FIRST(&ep->queue);

        if (p->state == USB_PACKET_ASYNC) {

            break;

        }

        assert(p->state == USB_PACKET_QUEUED);

        ret = usb_process_one(p);

        if (ret == USB_RET_ASYNC) {

            usb_packet_set_state(p, USB_PACKET_ASYNC);

            break;

        }

        p->result = ret;

        usb_packet_set_state(p, USB_PACKET_COMPLETE);

        QTAILQ_REMOVE(&ep->queue, p, queue);

        dev->port->ops->complete(dev->port, p);

    }

}


static void dyn_buf_write(void *opaque, UINT8 *buf, int buf_size)

{

    DynBuffer *d = opaque;

    int new_size, new_allocated_size;

    UINT8 *new_buffer;

    /* reallocate buffer if needed */

    new_size = d->pos + buf_size;

    new_allocated_size = d->allocated_size;

    while (new_size > new_allocated_size) {

        if (!new_allocated_size)

            new_allocated_size = new_size;

        else

            new_allocated_size = (new_allocated_size * 3) / 2;

    }

    if (new_allocated_size > d->allocated_size) {

        new_buffer = av_malloc(new_allocated_size);

        if (!new_buffer)

            return;

        memcpy(new_buffer, d->buffer, d->size);

        av_free(d->buffer);

        d->buffer = new_buffer;

        d->allocated_size = new_allocated_size;

    }

    memcpy(d->buffer + d->pos, buf, buf_size);

    d->pos = new_size;

    if (d->pos > d->size)

        d->size = d->pos;

}


static inline int RENAME(yuv420_rgb24)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,

             int srcSliceH, uint8_t* dst[], int dstStride[]){

    int y, h_size;

    if(c->srcFormat == PIX_FMT_YUV422P){

	srcStride[1] *= 2;

	srcStride[2] *= 2;

    }

    h_size= (c->dstW+7)&~7;

    if(h_size*3 > dstStride[0]) h_size-=8;

    __asm__ __volatile__ ("pxor %mm4, %mm4;" /* zero mm4 */ );

    for (y= 0; y<srcSliceH; y++ ) {

	uint8_t *_image = dst[0] + (y+srcSliceY)*dstStride[0];

	uint8_t *_py = src[0] + y*srcStride[0];

	uint8_t *_pu = src[1] + (y>>1)*srcStride[1];

	uint8_t *_pv = src[2] + (y>>1)*srcStride[2];

	long index= -h_size/2;

	    /* this mmx assembly code deals with SINGLE scan line at a time, it convert 8

	       pixels in each iteration */

	    __asm__ __volatile__ (

	/* load data for start of next scan line */

		     "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */

		     "movd (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */

		     "movq (%5, %0, 2), %%mm6;" /* Load 8  Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */

//		    ".balign 16			\n\t"

		    "1:				\n\t"

YUV2RGB

	/* mm0=B, %%mm2=G, %%mm1=R */

#ifdef HAVE_MMX2

			"movq "MANGLE(M24A)", %%mm4	\n\t"

			"movq "MANGLE(M24C)", %%mm7	\n\t"

			"pshufw $0x50, %%mm0, %%mm5	\n\t" /* B3 B2 B3 B2  B1 B0 B1 B0 */

			"pshufw $0x50, %%mm2, %%mm3	\n\t" /* G3 G2 G3 G2  G1 G0 G1 G0 */

			"pshufw $0x00, %%mm1, %%mm6	\n\t" /* R1 R0 R1 R0  R1 R0 R1 R0 */

			"pand %%mm4, %%mm5		\n\t" /*    B2        B1       B0 */

			"pand %%mm4, %%mm3		\n\t" /*    G2        G1       G0 */

			"pand %%mm7, %%mm6		\n\t" /*       R1        R0       */

			"psllq $8, %%mm3		\n\t" /* G2        G1       G0    */

			"por %%mm5, %%mm6		\n\t"

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

			MOVNTQ" %%mm6, (%1)		\n\t"

			"psrlq $8, %%mm2		\n\t" /* 00 G7 G6 G5  G4 G3 G2 G1 */

			"pshufw $0xA5, %%mm0, %%mm5	\n\t" /* B5 B4 B5 B4  B3 B2 B3 B2 */

			"pshufw $0x55, %%mm2, %%mm3	\n\t" /* G4 G3 G4 G3  G4 G3 G4 G3 */

			"pshufw $0xA5, %%mm1, %%mm6	\n\t" /* R5 R4 R5 R4  R3 R2 R3 R2 */

			"pand "MANGLE(M24B)", %%mm5	\n\t" /* B5       B4        B3    */

			"pand %%mm7, %%mm3		\n\t" /*       G4        G3       */

			"pand %%mm4, %%mm6		\n\t" /*    R4        R3       R2 */

			"por %%mm5, %%mm3		\n\t" /* B5    G4 B4     G3 B3    */

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

			MOVNTQ" %%mm6, 8(%1)		\n\t"

			"pshufw $0xFF, %%mm0, %%mm5	\n\t" /* B7 B6 B7 B6  B7 B6 B6 B7 */

			"pshufw $0xFA, %%mm2, %%mm3	\n\t" /* 00 G7 00 G7  G6 G5 G6 G5 */

			"pshufw $0xFA, %%mm1, %%mm6	\n\t" /* R7 R6 R7 R6  R5 R4 R5 R4 */

			"movd 4 (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */

			"pand %%mm7, %%mm5		\n\t" /*       B7        B6       */

			"pand %%mm4, %%mm3		\n\t" /*    G7        G6       G5 */

			"pand "MANGLE(M24B)", %%mm6	\n\t" /* R7       R6        R5    */

			"movd 4 (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */

\

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

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

			MOVNTQ" %%mm6, 16(%1)		\n\t"

			"movq 8 (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */

			"pxor %%mm4, %%mm4		\n\t"

#else

			"pxor %%mm4, %%mm4		\n\t"

			"movq %%mm0, %%mm5		\n\t" /* B */

			"movq %%mm1, %%mm6		\n\t" /* R */

			"punpcklbw %%mm2, %%mm0		\n\t" /* GBGBGBGB 0 */

			"punpcklbw %%mm4, %%mm1		\n\t" /* 0R0R0R0R 0 */

			"punpckhbw %%mm2, %%mm5		\n\t" /* GBGBGBGB 2 */

			"punpckhbw %%mm4, %%mm6		\n\t" /* 0R0R0R0R 2 */

			"movq %%mm0, %%mm7		\n\t" /* GBGBGBGB 0 */

			"movq %%mm5, %%mm3		\n\t" /* GBGBGBGB 2 */

			"punpcklwd %%mm1, %%mm7		\n\t" /* 0RGB0RGB 0 */

			"punpckhwd %%mm1, %%mm0		\n\t" /* 0RGB0RGB 1 */

			"punpcklwd %%mm6, %%mm5		\n\t" /* 0RGB0RGB 2 */

			"punpckhwd %%mm6, %%mm3		\n\t" /* 0RGB0RGB 3 */

			"movq %%mm7, %%mm2		\n\t" /* 0RGB0RGB 0 */

			"movq %%mm0, %%mm6		\n\t" /* 0RGB0RGB 1 */

			"movq %%mm5, %%mm1		\n\t" /* 0RGB0RGB 2 */

			"movq %%mm3, %%mm4		\n\t" /* 0RGB0RGB 3 */

			"psllq $40, %%mm7		\n\t" /* RGB00000 0 */

			"psllq $40, %%mm0		\n\t" /* RGB00000 1 */

			"psllq $40, %%mm5		\n\t" /* RGB00000 2 */

			"psllq $40, %%mm3		\n\t" /* RGB00000 3 */

			"punpckhdq %%mm2, %%mm7		\n\t" /* 0RGBRGB0 0 */

			"punpckhdq %%mm6, %%mm0		\n\t" /* 0RGBRGB0 1 */

			"punpckhdq %%mm1, %%mm5		\n\t" /* 0RGBRGB0 2 */

			"punpckhdq %%mm4, %%mm3		\n\t" /* 0RGBRGB0 3 */

			"psrlq $8, %%mm7		\n\t" /* 00RGBRGB 0 */

			"movq %%mm0, %%mm6		\n\t" /* 0RGBRGB0 1 */

			"psllq $40, %%mm0		\n\t" /* GB000000 1 */

			"por %%mm0, %%mm7		\n\t" /* GBRGBRGB 0 */

			MOVNTQ" %%mm7, (%1)		\n\t"

			"movd 4 (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */

			"psrlq $24, %%mm6		\n\t" /* 0000RGBR 1 */

			"movq %%mm5, %%mm1		\n\t" /* 0RGBRGB0 2 */

			"psllq $24, %%mm5		\n\t" /* BRGB0000 2 */

			"por %%mm5, %%mm6		\n\t" /* BRGBRGBR 1 */

			MOVNTQ" %%mm6, 8(%1)		\n\t"

			"movq 8 (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */

			"psrlq $40, %%mm1		\n\t" /* 000000RG 2 */

			"psllq $8, %%mm3		\n\t" /* RGBRGB00 3 */

			"por %%mm3, %%mm1		\n\t" /* RGBRGBRG 2 */

			MOVNTQ" %%mm1, 16(%1)		\n\t"

			"movd 4 (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */

			"pxor %%mm4, %%mm4		\n\t"

#endif

		     "add $24, %1			\n\t"

		     "add $4, %0			\n\t"

		     " js 1b				\n\t"

		     : "+r" (index), "+r" (_image)

		     : "r" (_pu - index), "r" (_pv - index), "r"(&c->redDither), "r" (_py - 2*index)

		     );

    }

    __asm__ __volatile__ (EMMS);

    return srcSliceH;

}


static int hex_to_data(uint8_t *data, const char *p)

{

    int c, len, v;

    len = 0;

    v = 1;

    for(;;) {

        skip_spaces(&p);

        if (*p == '\0')

            break;

        c = toupper((unsigned char)*p++);

        if (c >= '0' && c <= '9')

            c = c - '0';

        else if (c >= 'A' && c <= 'F')

            c = c - 'A' + 10;

        else

            break;

        v = (v << 4) | c;

        if (v & 0x100) {

            if (data)

                data[len] = v;

            len++;

            v = 1;

        }

    }

    return len;

}