static void decode_array_0000(APEContext *ctx, GetBitContext *gb,

                              int32_t *out, APERice *rice, int blockstodecode)

{

    int i;

    int ksummax, ksummin;

    rice->ksum = 0;

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

        out[i] = get_rice_ook(&ctx->gb, 10);

        rice->ksum += out[i];

    }

    rice->k = av_log2(rice->ksum / 10) + 1;

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

        out[i] = get_rice_ook(&ctx->gb, rice->k);

        rice->ksum += out[i];

        rice->k = av_log2(rice->ksum / ((i + 1) * 2)) + 1;

    }

    ksummax = 1 << rice->k + 7;

    ksummin = rice->k ? (1 << rice->k + 6) : 0;

    for (; i < blockstodecode; i++) {

        out[i] = get_rice_ook(&ctx->gb, rice->k);

        rice->ksum += out[i] - out[i - 64];

        while (rice->ksum < ksummin) {

            rice->k--;

            ksummin = rice->k ? ksummin >> 1 : 0;

            ksummax >>= 1;

        }

        while (rice->ksum >= ksummax) {

            rice->k++;

            if (rice->k > 24)

            ksummax <<= 1;

            ksummin = ksummin ? ksummin << 1 : 128;

        }

    }

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

        if (out[i] & 1)

            out[i] = (out[i] >> 1) + 1;

        else

            out[i] = -(out[i] >> 1);

    }

}


static void filter_mb_edgeh( H264Context *h, uint8_t *pix, int stride, int16_t bS[4], int qp ) {

    int i, d;

    const int index_a = qp + h->slice_alpha_c0_offset;

    const int alpha = (alpha_table+52)[index_a];

    const int beta  = (beta_table+52)[qp + h->slice_beta_offset];

    const int pix_next  = stride;

    if( bS[0] < 4 ) {

        int8_t tc[4];

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

            tc[i] = bS[i] ? (tc0_table+52)[index_a][bS[i] - 1] : -1;

        h->s.dsp.h264_v_loop_filter_luma(pix, stride, alpha, beta, tc);

    } else {

        h->s.dsp.h264_v_loop_filter_luma_intra(pix, stride, alpha, beta);

    }

}


int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)

{

    struct kvm_msi msi;

    KVMMSIRoute *route;

    if (s->direct_msi) {

        msi.address_lo = (uint32_t)msg.address;

        msi.address_hi = msg.address >> 32;

        msi.data = le32_to_cpu(msg.data);

        msi.flags = 0;

        memset(msi.pad, 0, sizeof(msi.pad));

        return kvm_vm_ioctl(s, KVM_SIGNAL_MSI, &msi);

    }

    route = kvm_lookup_msi_route(s, msg);

    if (!route) {

        int virq;

        virq = kvm_irqchip_get_virq(s);

        if (virq < 0) {

            return virq;

        }

        route = g_malloc(sizeof(KVMMSIRoute));

        route->kroute.gsi = virq;

        route->kroute.type = KVM_IRQ_ROUTING_MSI;

        route->kroute.flags = 0;

        route->kroute.u.msi.address_lo = (uint32_t)msg.address;

        route->kroute.u.msi.address_hi = msg.address >> 32;

        route->kroute.u.msi.data = le32_to_cpu(msg.data);

        kvm_add_routing_entry(s, &route->kroute);

        kvm_irqchip_commit_routes(s);

        QTAILQ_INSERT_TAIL(&s->msi_hashtab[kvm_hash_msi(msg.data)], route,

                           entry);

    }

    assert(route->kroute.type == KVM_IRQ_ROUTING_MSI);

    return kvm_set_irq(s, route->kroute.gsi, 1);

}


void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert)

{

    sd->readonly_cb = readonly;

    sd->inserted_cb = insert;

    qemu_set_irq(readonly, bdrv_is_read_only(sd->bdrv));

    qemu_set_irq(insert, bdrv_is_inserted(sd->bdrv));

}


static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)

{

    MOVStreamContext *sc = st->priv_data;

    int sample, time_sample;

    int i;

    sample = av_index_search_timestamp(st, timestamp, flags);

    av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);

    if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)

        sample = 0;

    if (sample < 0) /* not sure what to do */

        return AVERROR_INVALIDDATA;

    sc->current_sample = sample;

    av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);

    /* adjust ctts index */

    if (sc->ctts_data) {

        time_sample = 0;

        for (i = 0; i < sc->ctts_count; i++) {

            int next = time_sample + sc->ctts_data[i].count;

            if (next > sc->current_sample) {

                sc->ctts_index = i;

                sc->ctts_sample = sc->current_sample - time_sample;

                break;

            }

            time_sample = next;

        }

    }

    /* adjust stsd index */

    time_sample = 0;

    for (i = 0; i < sc->stsc_count; i++) {

        int next = time_sample + mov_get_stsc_samples(sc, i);

        if (next > sc->current_sample) {

            sc->stsc_index = i;

            sc->stsc_sample = sc->current_sample - time_sample;

            break;

        }

        time_sample = next;

    }

    return sample;

}


static int advanced_decode_i_mbs(VC9Context *v)

{

    MpegEncContext *s = &v->s;

    GetBitContext *gb = &v->s.gb;

    int mqdiff, mquant, current_mb = 0, over_flags_mb = 0;

    for (s->mb_y=0; s->mb_y<s->mb_height; s->mb_y++)

    {

        for (s->mb_x=0; s->mb_x<s->mb_width; s->mb_x++)

        {

            if (v->ac_pred_plane.is_raw)

                s->ac_pred = get_bits(gb, 1);

            else

                s->ac_pred = v->ac_pred_plane.data[current_mb];

            if (v->condover == 3 && v->over_flags_plane.is_raw)

                over_flags_mb = get_bits(gb, 1);

            GET_MQUANT();

            /* TODO: lots */

        }

        current_mb++;

    }

    return 0;

}


static int altivec_uyvy_rgb32 (SwsContext *c,

			       unsigned char **in, int *instrides,

			       int srcSliceY,	int srcSliceH,

			       unsigned char **oplanes, int *outstrides)

{

  int w = c->srcW;

  int h = srcSliceH;

  int i,j;

  vector unsigned char uyvy;

  vector signed   short Y,U,V;

  vector signed   short R0,G0,B0,R1,G1,B1;

  vector unsigned char  R,G,B;

  vector unsigned char *out;

  ubyte *img;

  img = in[0];

  out = (vector unsigned char *)(oplanes[0]+srcSliceY*outstrides[0]);

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

    for (j=0;j<w/16;j++) {

      uyvy = vec_ld (0, img);

      U = (vector signed short)

	vec_perm (uyvy, (vector unsigned char)AVV(0), demux_u);

      V = (vector signed short)

	vec_perm (uyvy, (vector unsigned char)AVV(0), demux_v);

      Y = (vector signed short)

	vec_perm (uyvy, (vector unsigned char)AVV(0), demux_y);

      cvtyuvtoRGB (c, Y,U,V,&R0,&G0,&B0);

      uyvy = vec_ld (16, img);

      U = (vector signed short)

	vec_perm (uyvy, (vector unsigned char)AVV(0), demux_u);

      V = (vector signed short)

	vec_perm (uyvy, (vector unsigned char)AVV(0), demux_v);

      Y = (vector signed short)

	vec_perm (uyvy, (vector unsigned char)AVV(0), demux_y);

      cvtyuvtoRGB (c, Y,U,V,&R1,&G1,&B1);

      R  = vec_packclp (R0,R1);

      G  = vec_packclp (G0,G1);

      B  = vec_packclp (B0,B1);

      //      vec_mstbgr24 (R,G,B, out);

      out_rgba (R,G,B,out);

      img += 32;

    }

  }

  return srcSliceH;

}


static void test_primitives(gconstpointer opaque)

{

    TestArgs *args = (TestArgs *) opaque;

    const SerializeOps *ops = args->ops;

    PrimitiveType *pt = args->test_data;

    PrimitiveType *pt_copy = g_malloc0(sizeof(*pt_copy));

    Error *err = NULL;

    void *serialize_data;

    char *double1, *double2;

    pt_copy->type = pt->type;

    ops->serialize(pt, &serialize_data, visit_primitive_type, &err);

    ops->deserialize((void **)&pt_copy, serialize_data, visit_primitive_type, &err);

    g_assert(err == NULL);

    g_assert(pt_copy != NULL);

    if (pt->type == PTYPE_STRING) {

        g_assert_cmpstr(pt->value.string, ==, pt_copy->value.string);

        g_free((char *)pt_copy->value.string);

    } else if (pt->type == PTYPE_NUMBER) {

        /* we serialize with %f for our reference visitors, so rather than fuzzy

         * floating math to test "equality", just compare the formatted values

         */

        double1 = g_malloc0(calc_float_string_storage(pt->value.number));

        double2 = g_malloc0(calc_float_string_storage(pt_copy->value.number));

        g_assert_cmpstr(double1, ==, double2);

        g_free(double1);

        g_free(double2);

    } else if (pt->type == PTYPE_BOOLEAN) {

        g_assert_cmpint(!!pt->value.max, ==, !!pt->value.max);

    } else {

        g_assert_cmpint(pt->value.max, ==, pt_copy->value.max);

    }

    ops->cleanup(serialize_data);

    g_free(args);

    g_free(pt_copy);

}


static int qcow_write_snapshots(BlockDriverState *bs)

{

    BDRVQcowState *s = bs->opaque;

    QCowSnapshot *sn;

    QCowSnapshotHeader h;

    int i, name_size, id_str_size, snapshots_size;

    uint64_t data64;

    uint32_t data32;

    int64_t offset, snapshots_offset;

    /* compute the size of the snapshots */

    offset = 0;

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

        sn = s->snapshots + i;

        offset = align_offset(offset, 8);

        offset += sizeof(h);

        offset += strlen(sn->id_str);

        offset += strlen(sn->name);

    }

    snapshots_size = offset;

    snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size);

    offset = snapshots_offset;

    if (offset < 0) {

        return offset;

    }

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

        sn = s->snapshots + i;

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

        h.l1_table_offset = cpu_to_be64(sn->l1_table_offset);

        h.l1_size = cpu_to_be32(sn->l1_size);

        h.vm_state_size = cpu_to_be32(sn->vm_state_size);

        h.date_sec = cpu_to_be32(sn->date_sec);

        h.date_nsec = cpu_to_be32(sn->date_nsec);

        h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec);

        id_str_size = strlen(sn->id_str);

        name_size = strlen(sn->name);

        h.id_str_size = cpu_to_be16(id_str_size);

        h.name_size = cpu_to_be16(name_size);

        offset = align_offset(offset, 8);

        if (bdrv_pwrite(bs->file, offset, &h, sizeof(h)) != sizeof(h))

            goto fail;

        offset += sizeof(h);

        if (bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size) != id_str_size)

            goto fail;

        offset += id_str_size;

        if (bdrv_pwrite(bs->file, offset, sn->name, name_size) != name_size)

            goto fail;

        offset += name_size;

    }

    /* update the various header fields */

    data64 = cpu_to_be64(snapshots_offset);

    if (bdrv_pwrite(bs->file, offsetof(QCowHeader, snapshots_offset),

                    &data64, sizeof(data64)) != sizeof(data64))

        goto fail;

    data32 = cpu_to_be32(s->nb_snapshots);

    if (bdrv_pwrite(bs->file, offsetof(QCowHeader, nb_snapshots),

                    &data32, sizeof(data32)) != sizeof(data32))

        goto fail;

    /* free the old snapshot table */

    qcow2_free_clusters(bs, s->snapshots_offset, s->snapshots_size);

    s->snapshots_offset = snapshots_offset;

    s->snapshots_size = snapshots_size;

    return 0;

 fail:

    return -1;

}


void sigaction_invoke(struct sigaction *action,

                      struct qemu_signalfd_siginfo *info)

{

    siginfo_t si = { 0 };

    si.si_signo = info->ssi_signo;

    si.si_errno = info->ssi_errno;

    si.si_code = info->ssi_code;

    /* Convert the minimal set of fields defined by POSIX.

     * Positive si_code values are reserved for kernel-generated

     * signals, where the valid siginfo fields are determined by

     * the signal number.  But according to POSIX, it is unspecified

     * whether SI_USER and SI_QUEUE have values less than or equal to

     * zero.

     */

    if (info->ssi_code == SI_USER || info->ssi_code == SI_QUEUE ||

        info->ssi_code <= 0) {

        /* SIGTERM, etc.  */

        si.si_pid = info->ssi_pid;

        si.si_uid = info->ssi_uid;

    } else if (info->ssi_signo == SIGILL || info->ssi_signo == SIGFPE ||

               info->ssi_signo == SIGSEGV || info->ssi_signo == SIGBUS) {

        si.si_addr = (void *)(uintptr_t)info->ssi_addr;

    } else if (info->ssi_signo == SIGCHLD) {

        si.si_pid = info->ssi_pid;

        si.si_status = info->ssi_status;

        si.si_uid = info->ssi_uid;

    }

    action->sa_sigaction(info->ssi_signo, &si, NULL);

}


static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)

{

    PixdescTestContext *priv = inlink->dst->priv;

    AVFilterLink *outlink    = inlink->dst->outputs[0];

    AVFilterBufferRef *outpicref;

    int i;

    outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE,

                                                outlink->w, outlink->h);

    outpicref = outlink->out_buf;

    avfilter_copy_buffer_ref_props(outpicref, picref);

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

        int h = outlink->h;

        h = i == 1 || i == 2 ? h>>priv->pix_desc->log2_chroma_h : h;

        if (outpicref->data[i]) {

            uint8_t *data = outpicref->data[i] +

                (outpicref->linesize[i] > 0 ? 0 : outpicref->linesize[i] * (h-1));

            memset(data, 0, FFABS(outpicref->linesize[i]) * h);

        }

    }

    /* copy palette */

    if (priv->pix_desc->flags & PIX_FMT_PAL)

        memcpy(outpicref->data[1], outpicref->data[1], 256*4);

    avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0));

}


void av_noreturn exit_program(int ret)

{

    int i, j;

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

        avfilter_graph_free(&filtergraphs[i]->graph);

        for (j = 0; j < filtergraphs[i]->nb_inputs; j++)

            av_freep(&filtergraphs[i]->inputs[j]);

        av_freep(&filtergraphs[i]->inputs);

        for (j = 0; j < filtergraphs[i]->nb_outputs; j++)

            av_freep(&filtergraphs[i]->outputs[j]);

        av_freep(&filtergraphs[i]->outputs);

        av_freep(&filtergraphs[i]);

    }

    av_freep(&filtergraphs);

    /* close files */

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

        AVFormatContext *s = output_files[i]->ctx;

        if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)

            avio_close(s->pb);

        avformat_free_context(s);

        av_dict_free(&output_files[i]->opts);

        av_freep(&output_files[i]);

    }

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

        AVBitStreamFilterContext *bsfc = output_streams[i]->bitstream_filters;

        while (bsfc) {

            AVBitStreamFilterContext *next = bsfc->next;

            av_bitstream_filter_close(bsfc);

            bsfc = next;

        }

        output_streams[i]->bitstream_filters = NULL;

        if (output_streams[i]->output_frame) {

            AVFrame *frame = output_streams[i]->output_frame;

            if (frame->extended_data != frame->data)

                av_freep(&frame->extended_data);

            av_freep(&frame);

        }

        av_freep(&output_streams[i]->filtered_frame);

        av_freep(&output_streams[i]);

    }

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

        avformat_close_input(&input_files[i]->ctx);

        av_freep(&input_files[i]);

    }

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

        av_freep(&input_streams[i]->decoded_frame);

        av_dict_free(&input_streams[i]->opts);

        free_buffer_pool(input_streams[i]);

        av_freep(&input_streams[i]->filters);

        av_freep(&input_streams[i]);

    }

    if (vstats_file)

        fclose(vstats_file);

    av_free(vstats_filename);

    av_freep(&input_streams);

    av_freep(&input_files);

    av_freep(&output_streams);

    av_freep(&output_files);

    uninit_opts();

    av_freep(&audio_buf);

    allocated_audio_buf_size = 0;

    av_freep(&async_buf);

    allocated_async_buf_size = 0;

    avfilter_uninit();

    avformat_network_deinit();

    if (received_sigterm) {

        av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n",

               (int) received_sigterm);

        exit (255);

    }

    exit(ret); /* not all OS-es handle main() return value */

}


static void openrisc_pic_cpu_handler(void *opaque, int irq, int level)

{

    OpenRISCCPU *cpu = (OpenRISCCPU *)opaque;

    CPUState *cs = CPU(cpu);

    uint32_t irq_bit = 1 << irq;

    if (irq > 31 || irq < 0) {

        return;

    }

    if (level) {

        cpu->env.picsr |= irq_bit;

    } else {

        cpu->env.picsr &= ~irq_bit;

    }

    if (cpu->env.picsr & cpu->env.picmr) {

        cpu_interrupt(cs, CPU_INTERRUPT_HARD);

    } else {

        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);

        cpu->env.picsr = 0;

    }

}


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

{

    int ret = 0;

    int length = 0;

    uint64_t original_size;

    if (c->fc->nb_streams >= 1) {

        AVCodecContext *codec = c->fc->streams[c->fc->nb_streams-1]->codec;

        if (codec->codec_id == AV_CODEC_ID_H264)

            return 0;

        if (atom.size == 16) {

            original_size = codec->extradata_size;

            ret = mov_realloc_extradata(codec, atom);

            if (!ret) {

                length =  mov_read_atom_into_extradata(c, pb, atom, codec, codec->extradata + original_size);

                if (length == atom.size) {

                    const uint8_t range_value = codec->extradata[original_size + 19];

                    switch (range_value) {

                    case 1:

                        codec->color_range = AVCOL_RANGE_MPEG;

                        break;

                    case 2:

                        codec->color_range = AVCOL_RANGE_JPEG;

                        break;

                    default:

                        av_log(c, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);

                        break;

                    }

                    av_dlog(c, "color_range: %d\n", codec->color_range);

                } else {

                  /* For some reason the whole atom was not added to the extradata */

                  av_log(c, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");

                }

            } else {

                av_log(c, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");

            }

        } else {

            av_log(c, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);

        }

    }

    return ret;

}


static av_always_inline void filter_level_for_mb(VP8Context *s, VP8Macroblock *mb, VP8FilterStrength *f )

{

    int interior_limit, filter_level;

    if (s->segmentation.enabled) {

        filter_level = s->segmentation.filter_level[s->segment];

        if (!s->segmentation.absolute_vals)

            filter_level += s->filter.level;

    } else

        filter_level = s->filter.level;

    if (s->lf_delta.enabled) {

        filter_level += s->lf_delta.ref[mb->ref_frame];

        filter_level += s->lf_delta.mode[mb->mode];

    }

/* Like av_clip for inputs 0 and max, where max is equal to (2^n-1) */

#define POW2CLIP(x,max) (((x) & ~max) ? (-(x))>>31 & max : (x));

    filter_level = POW2CLIP(filter_level, 63);

    interior_limit = filter_level;

    if (s->filter.sharpness) {

        interior_limit >>= s->filter.sharpness > 4 ? 2 : 1;

        interior_limit = FFMIN(interior_limit, 9 - s->filter.sharpness);

    }

    interior_limit = FFMAX(interior_limit, 1);

    f->filter_level = filter_level;

    f->inner_limit = interior_limit;

    f->inner_filter = !mb->skip || mb->mode == MODE_I4x4 || mb->mode == VP8_MVMODE_SPLIT;

}


void rgb15tobgr16(const uint8_t *src, uint8_t *dst, long src_size)

{

	long i;

	long num_pixels = src_size >> 1;

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

	{

	    unsigned b,g,r;

	    register uint16_t rgb;

	    rgb = src[2*i];

	    r = rgb&0x1F;

	    g = (rgb&0x3E0)>>5;

	    b = (rgb&0x7C00)>>10;

	    dst[2*i] = (b&0x1F) | ((g&0x3F)<<5) | ((r&0x1F)<<11);

	}

}


static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
                            int opc)
{
    int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
#if defined(CONFIG_SOFTMMU)
    uint32_t *label1_ptr, *label2_ptr;
    data_reg = *args++;
    addr_reg = *args++;
    mem_index = *args;
    s_bits = opc & 3;
    arg0 = TCG_REG_O0;
    arg1 = TCG_REG_O1;
    arg2 = TCG_REG_O2;
#if defined(CONFIG_SOFTMMU)
    /* srl addr_reg, x, arg1 */
    tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
                   SHIFT_SRL);
    tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
                   ARITH_AND);
    /* and arg1, x, arg1 */
    tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
    /* add arg1, x, arg1 */
    tcg_out_addi(s, arg1, offsetof(CPUState,
                                   tlb_table[mem_index][0].addr_read));
    /* add env, arg1, arg1 */
    tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
    /* ld [arg1], arg2 */
    tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
              INSN_RS2(TCG_REG_G0));
    /* subcc arg0, arg2, %g0 */
    tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
    /* will become:
       be label1 */
    label1_ptr = (uint32_t *)s->code_ptr;
    tcg_out32(s, 0);
    /* mov (delay slot) */
    tcg_out_mov(s, arg0, addr_reg);
    /* mov */
    tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
    /* XXX: move that code at the end of the TB */
    /* qemu_ld_helper[s_bits](arg0, arg1) */
    tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
                           - (tcg_target_ulong)s->code_ptr) >> 2)
                         & 0x3fffffff));
    /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
       global registers */
    // delay slot
    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
                 TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_ST_OP);
    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
                 TCG_TARGET_CALL_STACK_OFFSET - sizeof(long), HOST_LD_OP);
    /* data_reg = sign_extend(arg0) */
    switch(opc) {
    case 0 | 4:
        /* sll arg0, 24/56, data_reg */
        tcg_out_arithi(s, data_reg, arg0, (int)sizeof(tcg_target_long) * 8 - 8,
                       HOST_SLL_OP);
        /* sra data_reg, 24/56, data_reg */
        tcg_out_arithi(s, data_reg, data_reg,
                       (int)sizeof(tcg_target_long) * 8 - 8, HOST_SRA_OP);
        break;
    case 1 | 4:
        /* sll arg0, 16/48, data_reg */
        tcg_out_arithi(s, data_reg, arg0,
                       (int)sizeof(tcg_target_long) * 8 - 16, HOST_SLL_OP);
        /* sra data_reg, 16/48, data_reg */
        tcg_out_arithi(s, data_reg, data_reg,
                       (int)sizeof(tcg_target_long) * 8 - 16, HOST_SRA_OP);
        break;
    case 2 | 4:
        /* sll arg0, 32, data_reg */
        tcg_out_arithi(s, data_reg, arg0, 32, HOST_SLL_OP);
        /* sra data_reg, 32, data_reg */
        tcg_out_arithi(s, data_reg, data_reg, 32, HOST_SRA_OP);
        break;
    case 0:
    case 1:
    case 2:
    case 3:
    default:
        /* mov */
        tcg_out_mov(s, data_reg, arg0);
        break;
    }
    /* will become:
       ba label2 */
    label2_ptr = (uint32_t *)s->code_ptr;
    tcg_out32(s, 0);
    /* nop (delay slot */
    tcg_out_nop(s);
    /* label1: */
    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
                   INSN_OFF22((unsigned long)s->code_ptr -
                              (unsigned long)label1_ptr));
    /* ld [arg1 + x], arg1 */
    tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
                 offsetof(CPUTLBEntry, addr_read), HOST_LD_OP);
    /* add addr_reg, arg1, arg0 */
    tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
    arg0 = addr_reg;
    switch(opc) {
    case 0:
        /* ldub [arg0], data_reg */
        tcg_out_ldst(s, data_reg, arg0, 0, LDUB);
        break;
    case 0 | 4:
        /* ldsb [arg0], data_reg */
        tcg_out_ldst(s, data_reg, arg0, 0, LDSB);
        break;
    case 1:
#ifdef TARGET_WORDS_BIGENDIAN
        /* lduh [arg0], data_reg */
        tcg_out_ldst(s, data_reg, arg0, 0, LDUH);
        /* lduha [arg0] ASI_PRIMARY_LITTLE, data_reg */
        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUHA, ASI_PRIMARY_LITTLE);
        break;
    case 1 | 4:
#ifdef TARGET_WORDS_BIGENDIAN
        /* ldsh [arg0], data_reg */
        tcg_out_ldst(s, data_reg, arg0, 0, LDSH);
        /* ldsha [arg0] ASI_PRIMARY_LITTLE, data_reg */
        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSHA, ASI_PRIMARY_LITTLE);
        break;
    case 2:
#ifdef TARGET_WORDS_BIGENDIAN
        /* lduw [arg0], data_reg */
        tcg_out_ldst(s, data_reg, arg0, 0, LDUW);
        /* lduwa [arg0] ASI_PRIMARY_LITTLE, data_reg */
        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUWA, ASI_PRIMARY_LITTLE);
        break;
    case 2 | 4:
#ifdef TARGET_WORDS_BIGENDIAN
        /* ldsw [arg0], data_reg */
        tcg_out_ldst(s, data_reg, arg0, 0, LDSW);
        /* ldswa [arg0] ASI_PRIMARY_LITTLE, data_reg */
        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSWA, ASI_PRIMARY_LITTLE);
        break;
    case 3:
#ifdef TARGET_WORDS_BIGENDIAN
        /* ldx [arg0], data_reg */
        tcg_out_ldst(s, data_reg, arg0, 0, LDX);
        /* ldxa [arg0] ASI_PRIMARY_LITTLE, data_reg */
        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDXA, ASI_PRIMARY_LITTLE);
        break;
    default:
        tcg_abort();
    }
#if defined(CONFIG_SOFTMMU)
    /* label2: */
    *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
                   INSN_OFF22((unsigned long)s->code_ptr -
                              (unsigned long)label2_ptr));
}


static int mxf_read_index_table_segment(MXFIndexTableSegment *segment, ByteIOContext *pb, int tag)

{

    switch(tag) {

    case 0x3F05: dprintf(NULL, "EditUnitByteCount %d\n", get_be32(pb)); break;

    case 0x3F06: dprintf(NULL, "IndexSID %d\n", get_be32(pb)); break;

    case 0x3F07: dprintf(NULL, "BodySID %d\n", get_be32(pb)); break;

    case 0x3F0B: dprintf(NULL, "IndexEditRate %d/%d\n", get_be32(pb), get_be32(pb)); break;

    case 0x3F0C: dprintf(NULL, "IndexStartPosition %lld\n", get_be64(pb)); break;

    case 0x3F0D: dprintf(NULL, "IndexDuration %lld\n", get_be64(pb)); break;

    }

    return 0;

}


static const char *vnc_auth_name(VncDisplay *vd) {

    switch (vd->auth) {

    case VNC_AUTH_INVALID:

        return "invalid";

    case VNC_AUTH_NONE:

        return "none";

    case VNC_AUTH_VNC:

        return "vnc";

    case VNC_AUTH_RA2:

        return "ra2";

    case VNC_AUTH_RA2NE:

        return "ra2ne";

    case VNC_AUTH_TIGHT:

        return "tight";

    case VNC_AUTH_ULTRA:

        return "ultra";

    case VNC_AUTH_TLS:

        return "tls";

    case VNC_AUTH_VENCRYPT:

#ifdef CONFIG_VNC_TLS

        switch (vd->subauth) {

        case VNC_AUTH_VENCRYPT_PLAIN:

            return "vencrypt+plain";

        case VNC_AUTH_VENCRYPT_TLSNONE:

            return "vencrypt+tls+none";

        case VNC_AUTH_VENCRYPT_TLSVNC:

            return "vencrypt+tls+vnc";

        case VNC_AUTH_VENCRYPT_TLSPLAIN:

            return "vencrypt+tls+plain";

        case VNC_AUTH_VENCRYPT_X509NONE:

            return "vencrypt+x509+none";

        case VNC_AUTH_VENCRYPT_X509VNC:

            return "vencrypt+x509+vnc";

        case VNC_AUTH_VENCRYPT_X509PLAIN:

            return "vencrypt+x509+plain";

        case VNC_AUTH_VENCRYPT_TLSSASL:

            return "vencrypt+tls+sasl";

        case VNC_AUTH_VENCRYPT_X509SASL:

            return "vencrypt+x509+sasl";

        default:

            return "vencrypt";

        }

#else

        return "vencrypt";

#endif

    case VNC_AUTH_SASL:

        return "sasl";

    }

    return "unknown";

}


static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)

{

    CPUX86State *env = &cpu->env;

    x86_def_t def1, *def = &def1;

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

    if (cpu_x86_find_by_name(cpu, def, name) < 0) {

        error_setg(errp, "Unable to find CPU definition: %s", name);

        return;

    }

    if (kvm_enabled()) {

        def->features[FEAT_KVM] |= kvm_default_features;

    }

    def->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;

    object_property_set_str(OBJECT(cpu), def->vendor, "vendor", errp);

    object_property_set_int(OBJECT(cpu), def->level, "level", errp);

    object_property_set_int(OBJECT(cpu), def->family, "family", errp);

    object_property_set_int(OBJECT(cpu), def->model, "model", errp);

    object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);

    env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX];

    env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX];

    env->features[FEAT_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX];

    env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_ECX];

    object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);

    env->features[FEAT_KVM] = def->features[FEAT_KVM];

    env->features[FEAT_SVM] = def->features[FEAT_SVM];

    env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];

    env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];

    env->cpuid_xlevel2 = def->xlevel2;

    object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);

}


int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
                const void *buf1, int count1)
{
    BlockDriver *drv = bs->drv;
    if (!drv)
        return -ENOMEDIUM;
    if (!drv->bdrv_pwrite)
        return bdrv_pwrite_em(bs, offset, buf1, count1);
    return drv->bdrv_pwrite(bs, offset, buf1, count1);
}


static void yuv2nv12X_c(SwsContext *c, const int16_t *lumFilter,

                        const int16_t **lumSrc, int lumFilterSize,

                        const int16_t *chrFilter, const int16_t **chrUSrc,

                        const int16_t **chrVSrc, int chrFilterSize,

                        const int16_t **alpSrc, uint8_t *dest, uint8_t *uDest,

                        uint8_t *vDest, uint8_t *aDest,

                        int dstW, int chrDstW)

{

    enum PixelFormat dstFormat = c->dstFormat;

    //FIXME Optimize (just quickly written not optimized..)

    int i;

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

        int val=1<<18;

        int j;

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

            val += lumSrc[j][i] * lumFilter[j];

        dest[i]= av_clip_uint8(val>>19);

    }

    if (!uDest)

        return;

    if (dstFormat == PIX_FMT_NV12)

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

            int u=1<<18;

            int v=1<<18;

            int j;

            for (j=0; j<chrFilterSize; j++) {

                u += chrUSrc[j][i] * chrFilter[j];

                v += chrVSrc[j][i] * chrFilter[j];

            }

            uDest[2*i]= av_clip_uint8(u>>19);

            uDest[2*i+1]= av_clip_uint8(v>>19);

        }

    else

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

            int u=1<<18;

            int v=1<<18;

            int j;

            for (j=0; j<chrFilterSize; j++) {

                u += chrUSrc[j][i] * chrFilter[j];

                v += chrVSrc[j][i] * chrFilter[j];

            }

            uDest[2*i]= av_clip_uint8(v>>19);

            uDest[2*i+1]= av_clip_uint8(u>>19);

        }

}


static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,

                                QEMUIOVector *qiov, CoroutineEntry co_entry,

                                BdrvRequestFlags flags,

                                BlockCompletionFunc *cb, void *opaque)

{

    BlkAioEmAIOCB *acb;

    Coroutine *co;

    bdrv_inc_in_flight(blk_bs(blk));

    acb = blk_aio_get(&blk_aio_em_aiocb_info, blk, cb, opaque);

    acb->rwco = (BlkRwCo) {

        .blk    = blk,

        .offset = offset,

        .qiov   = qiov,

        .flags  = flags,

        .ret    = NOT_DONE,

    };

    acb->bytes = bytes;

    acb->has_returned = false;

    co = qemu_coroutine_create(co_entry, acb);

    qemu_coroutine_enter(co);

    acb->has_returned = true;

    if (acb->rwco.ret != NOT_DONE) {

        aio_bh_schedule_oneshot(blk_get_aio_context(blk),

                                blk_aio_complete_bh, acb);

    }

    return &acb->common;

}


static int rv10_decode_packet(AVCodecContext *avctx,

                             const uint8_t *buf, int buf_size, int buf_size2)

{

    MpegEncContext *s = avctx->priv_data;

    int mb_count, mb_pos, left, start_mb_x;

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

    if(s->codec_id ==CODEC_ID_RV10)

        mb_count = rv10_decode_picture_header(s);

    else

        mb_count = rv20_decode_picture_header(s);

    if (mb_count < 0) {

        av_log(s->avctx, AV_LOG_ERROR, "HEADER ERROR\n");

        return -1;

    }

    if (s->mb_x >= s->mb_width ||

        s->mb_y >= s->mb_height) {

        av_log(s->avctx, AV_LOG_ERROR, "POS ERROR %d %d\n", s->mb_x, s->mb_y);

        return -1;

    }

    mb_pos = s->mb_y * s->mb_width + s->mb_x;

    left = s->mb_width * s->mb_height - mb_pos;

    if (mb_count > left) {

        av_log(s->avctx, AV_LOG_ERROR, "COUNT ERROR\n");

        return -1;

    }

    if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {

        if(s->current_picture_ptr){ //FIXME write parser so we always have complete frames?

            ff_er_frame_end(s);

            ff_MPV_frame_end(s);

            s->mb_x= s->mb_y = s->resync_mb_x = s->resync_mb_y= 0;

        }

        if(ff_MPV_frame_start(s, avctx) < 0)

            return -1;

        ff_er_frame_start(s);

    } else {

        if (s->current_picture_ptr->f.pict_type != s->pict_type) {

            av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");

            return -1;

        }

    }

    av_dlog(avctx, "qscale=%d\n", s->qscale);

    /* default quantization values */

    if(s->codec_id== CODEC_ID_RV10){

        if(s->mb_y==0) s->first_slice_line=1;

    }else{

        s->first_slice_line=1;

        s->resync_mb_x= s->mb_x;

    }

    start_mb_x= s->mb_x;

    s->resync_mb_y= s->mb_y;

    if(s->h263_aic){

        s->y_dc_scale_table=

        s->c_dc_scale_table= ff_aic_dc_scale_table;

    }else{

        s->y_dc_scale_table=

        s->c_dc_scale_table= ff_mpeg1_dc_scale_table;

    }

    if(s->modified_quant)

        s->chroma_qscale_table= ff_h263_chroma_qscale_table;

    ff_set_qscale(s, s->qscale);

    s->rv10_first_dc_coded[0] = 0;

    s->rv10_first_dc_coded[1] = 0;

    s->rv10_first_dc_coded[2] = 0;

    s->block_wrap[0]=

    s->block_wrap[1]=

    s->block_wrap[2]=

    s->block_wrap[3]= s->b8_stride;

    s->block_wrap[4]=

    s->block_wrap[5]= s->mb_stride;

    ff_init_block_index(s);

    /* decode each macroblock */

    for(s->mb_num_left= mb_count; s->mb_num_left>0; s->mb_num_left--) {

        int ret;

        ff_update_block_index(s);

        av_dlog(avctx, "**mb x=%d y=%d\n", s->mb_x, s->mb_y);

        s->mv_dir = MV_DIR_FORWARD;

        s->mv_type = MV_TYPE_16X16;

        ret=ff_h263_decode_mb(s, s->block);

        if (ret != SLICE_ERROR && s->gb.size_in_bits < get_bits_count(&s->gb) && 8*buf_size2 >= get_bits_count(&s->gb)){

            av_log(avctx, AV_LOG_DEBUG, "update size from %d to %d\n", s->gb.size_in_bits, 8*buf_size2);

            s->gb.size_in_bits= 8*buf_size2;

            ret= SLICE_OK;

        }

        if (ret == SLICE_ERROR || s->gb.size_in_bits < get_bits_count(&s->gb)) {

            av_log(s->avctx, AV_LOG_ERROR, "ERROR at MB %d %d\n", s->mb_x, s->mb_y);

            return -1;

        }

        if(s->pict_type != AV_PICTURE_TYPE_B)

            ff_h263_update_motion_val(s);

        ff_MPV_decode_mb(s, s->block);

        if(s->loop_filter)

            ff_h263_loop_filter(s);

        if (++s->mb_x == s->mb_width) {

            s->mb_x = 0;

            s->mb_y++;

            ff_init_block_index(s);

        }

        if(s->mb_x == s->resync_mb_x)

            s->first_slice_line=0;

        if(ret == SLICE_END) break;

    }

    ff_er_add_slice(s, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);

    return s->gb.size_in_bits;

}


static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,

                           struct iovec *iov, int niov, bool create,

                           enum AIOCBState aiocb_type)

{

    int nr_copies = s->inode.nr_copies;

    SheepdogObjReq hdr;

    unsigned int wlen = 0;

    int ret;

    uint64_t oid = aio_req->oid;

    unsigned int datalen = aio_req->data_len;

    uint64_t offset = aio_req->offset;

    uint8_t flags = aio_req->flags;

    uint64_t old_oid = aio_req->base_oid;

    if (!nr_copies) {

        error_report("bug");

    }

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

    switch (aiocb_type) {

    case AIOCB_FLUSH_CACHE:

        hdr.opcode = SD_OP_FLUSH_VDI;

        break;

    case AIOCB_READ_UDATA:

        hdr.opcode = SD_OP_READ_OBJ;

        hdr.flags = flags;

        break;

    case AIOCB_WRITE_UDATA:

        if (create) {

            hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;

        } else {

            hdr.opcode = SD_OP_WRITE_OBJ;

        }

        wlen = datalen;

        hdr.flags = SD_FLAG_CMD_WRITE | flags;

        break;

    case AIOCB_DISCARD_OBJ:

        hdr.opcode = SD_OP_DISCARD_OBJ;

        break;

    }

    if (s->cache_flags) {

        hdr.flags |= s->cache_flags;

    }

    hdr.oid = oid;

    hdr.cow_oid = old_oid;

    hdr.copies = s->inode.nr_copies;

    hdr.data_length = datalen;

    hdr.offset = offset;

    hdr.id = aio_req->id;

    qemu_co_mutex_lock(&s->lock);

    s->co_send = qemu_coroutine_self();

    aio_set_fd_handler(s->aio_context, s->fd,

                       co_read_response, co_write_request, s);

    socket_set_cork(s->fd, 1);

    /* send a header */

    ret = qemu_co_send(s->fd, &hdr, sizeof(hdr));

    if (ret != sizeof(hdr)) {

        error_report("failed to send a req, %s", strerror(errno));

        goto out;

    }

    if (wlen) {

        ret = qemu_co_sendv(s->fd, iov, niov, aio_req->iov_offset, wlen);

        if (ret != wlen) {

            error_report("failed to send a data, %s", strerror(errno));

        }

    }

out:

    socket_set_cork(s->fd, 0);

    aio_set_fd_handler(s->aio_context, s->fd, co_read_response, NULL, s);

    s->co_send = NULL;

    qemu_co_mutex_unlock(&s->lock);

}


static void init_proc_750gx (CPUPPCState *env)

{

    gen_spr_ne_601(env);

    gen_spr_7xx(env);

    /* XXX : not implemented (XXX: different from 750fx) */

    spr_register(env, SPR_L2CR, "L2CR",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, NULL,

                 0x00000000);

    /* Time base */

    gen_tbl(env);

    /* Thermal management */

    gen_spr_thrm(env);

    /* XXX : not implemented */

    spr_register(env, SPR_750_THRM4, "THRM4",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    /* Hardware implementation registers */

    /* XXX : not implemented (XXX: different from 750fx) */

    spr_register(env, SPR_HID0, "HID0",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    /* XXX : not implemented */

    spr_register(env, SPR_HID1, "HID1",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    /* XXX : not implemented (XXX: different from 750fx) */

    spr_register(env, SPR_750FX_HID2, "HID2",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    /* Memory management */

    gen_low_BATs(env);

    /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */

    gen_high_BATs(env);

    init_excp_7x0(env);

    env->dcache_line_size = 32;

    env->icache_line_size = 32;

    /* Allocate hardware IRQ controller */

    ppc6xx_irq_init(env);

}


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

                      Error **errp)

{

    BDRVCloopState *s = bs->opaque;

    uint32_t offsets_size, max_compressed_block_size = 1, i;

    int ret;

    bs->read_only = 1;

    /* read header */

    ret = bdrv_pread(bs->file, 128, &s->block_size, 4);

    if (ret < 0) {

        return ret;

    }

    s->block_size = be32_to_cpu(s->block_size);

    if (s->block_size % 512) {

        error_setg(errp, "block_size %u must be a multiple of 512",

                   s->block_size);

        return -EINVAL;

    }

    if (s->block_size == 0) {

        error_setg(errp, "block_size cannot be zero");

        return -EINVAL;

    }

    /* cloop's create_compressed_fs.c warns about block sizes beyond 256 KB but

     * we can accept more.  Prevent ridiculous values like 4 GB - 1 since we

     * need a buffer this big.

     */

    if (s->block_size > MAX_BLOCK_SIZE) {

        error_setg(errp, "block_size %u must be %u MB or less",

                   s->block_size,

                   MAX_BLOCK_SIZE / (1024 * 1024));

        return -EINVAL;

    }

    ret = bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4);

    if (ret < 0) {

        return ret;

    }

    s->n_blocks = be32_to_cpu(s->n_blocks);

    /* read offsets */

    if (s->n_blocks > UINT32_MAX / sizeof(uint64_t)) {

        /* Prevent integer overflow */

        error_setg(errp, "n_blocks %u must be %zu or less",

                   s->n_blocks,

                   UINT32_MAX / sizeof(uint64_t));

        return -EINVAL;

    }

    offsets_size = s->n_blocks * sizeof(uint64_t);

    if (offsets_size > 512 * 1024 * 1024) {

        /* Prevent ridiculous offsets_size which causes memory allocation to

         * fail or overflows bdrv_pread() size.  In practice the 512 MB

         * offsets[] limit supports 16 TB images at 256 KB block size.

         */

        error_setg(errp, "image requires too many offsets, "

                   "try increasing block size");

        return -EINVAL;

    }

    s->offsets = g_malloc(offsets_size);

    ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);

    if (ret < 0) {

        goto fail;

    }

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

        s->offsets[i] = be64_to_cpu(s->offsets[i]);

        if (i > 0) {

            uint32_t size = s->offsets[i] - s->offsets[i - 1];

            if (size > max_compressed_block_size) {

                max_compressed_block_size = size;

            }

        }

    }

    /* initialize zlib engine */

    s->compressed_block = g_malloc(max_compressed_block_size + 1);

    s->uncompressed_block = g_malloc(s->block_size);

    if (inflateInit(&s->zstream) != Z_OK) {

        ret = -EINVAL;

        goto fail;

    }

    s->current_block = s->n_blocks;

    s->sectors_per_block = s->block_size/512;

    bs->total_sectors = s->n_blocks * s->sectors_per_block;

    qemu_co_mutex_init(&s->lock);

    return 0;

fail:

    g_free(s->offsets);

    g_free(s->compressed_block);

    g_free(s->uncompressed_block);

    return ret;

}


static void spapr_tce_table_class_init(ObjectClass *klass, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->vmsd = &vmstate_spapr_tce_table;

    dc->init = spapr_tce_table_realize;

    dc->reset = spapr_tce_reset;

    QLIST_INIT(&spapr_tce_tables);

    /* hcall-tce */

    spapr_register_hypercall(H_PUT_TCE, h_put_tce);

}


static void gmc1_motion(MpegEncContext *s,

                        uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,

                        uint8_t **ref_picture)

{

    uint8_t *ptr;

    int src_x, src_y, motion_x, motion_y;

    ptrdiff_t offset, linesize, uvlinesize;

    int emu = 0;

    motion_x   = s->sprite_offset[0][0];

    motion_y   = s->sprite_offset[0][1];

    src_x      = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy + 1));

    src_y      = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy + 1));

    motion_x <<= (3 - s->sprite_warping_accuracy);

    motion_y <<= (3 - s->sprite_warping_accuracy);

    src_x      = av_clip(src_x, -16, s->width);

    if (src_x == s->width)

        motion_x = 0;

    src_y = av_clip(src_y, -16, s->height);

    if (src_y == s->height)

        motion_y = 0;

    linesize   = s->linesize;

    uvlinesize = s->uvlinesize;

    ptr = ref_picture[0] + src_y * linesize + src_x;

    if ((unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) ||

        (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)) {

        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,

                                 linesize, linesize,

                                 17, 17,

                                 src_x, src_y,

                                 s->h_edge_pos, s->v_edge_pos);

        ptr = s->sc.edge_emu_buffer;

    }

    if ((motion_x | motion_y) & 7) {

        s->mdsp.gmc1(dest_y, ptr, linesize, 16,

                     motion_x & 15, motion_y & 15, 128 - s->no_rounding);

        s->mdsp.gmc1(dest_y + 8, ptr + 8, linesize, 16,

                     motion_x & 15, motion_y & 15, 128 - s->no_rounding);

    } else {

        int dxy;

        dxy = ((motion_x >> 3) & 1) | ((motion_y >> 2) & 2);

        if (s->no_rounding) {

            s->hdsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);

        } else {

            s->hdsp.put_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);

        }

    }

    if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)

        return;

    motion_x   = s->sprite_offset[1][0];

    motion_y   = s->sprite_offset[1][1];

    src_x      = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy + 1));

    src_y      = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy + 1));

    motion_x <<= (3 - s->sprite_warping_accuracy);

    motion_y <<= (3 - s->sprite_warping_accuracy);

    src_x      = av_clip(src_x, -8, s->width >> 1);

    if (src_x == s->width >> 1)

        motion_x = 0;

    src_y = av_clip(src_y, -8, s->height >> 1);

    if (src_y == s->height >> 1)

        motion_y = 0;

    offset = (src_y * uvlinesize) + src_x;

    ptr    = ref_picture[1] + offset;

    if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - 9, 0) ||

        (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - 9, 0)) {

        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,

                                 uvlinesize, uvlinesize,

                                 9, 9,

                                 src_x, src_y,

                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);

        ptr = s->sc.edge_emu_buffer;

        emu = 1;

    }

    s->mdsp.gmc1(dest_cb, ptr, uvlinesize, 8,

                 motion_x & 15, motion_y & 15, 128 - s->no_rounding);

    ptr = ref_picture[2] + offset;

    if (emu) {

        s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,

                                 uvlinesize, uvlinesize,

                                 9, 9,

                                 src_x, src_y,

                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);

        ptr = s->sc.edge_emu_buffer;

    }

    s->mdsp.gmc1(dest_cr, ptr, uvlinesize, 8,

                 motion_x & 15, motion_y & 15, 128 - s->no_rounding);

}


static void gxf_write_padding(ByteIOContext *pb, offset_t to_pad)

{

    while (to_pad--) {

        put_byte(pb, 0);

    }

}


static int aea_read_header(AVFormatContext *s)

{

    AVStream *st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    /* Parse the amount of channels and skip to pos 2048(0x800) */

    avio_skip(s->pb, 264);

    st->codec->channels = avio_r8(s->pb);

    avio_skip(s->pb, 1783);

    st->codec->codec_type     = AVMEDIA_TYPE_AUDIO;

    st->codec->codec_id       = AV_CODEC_ID_ATRAC1;

    st->codec->sample_rate    = 44100;

    st->codec->bit_rate       = 292000;

    if (st->codec->channels != 1 && st->codec->channels != 2) {

        av_log(s,AV_LOG_ERROR,"Channels %d not supported!\n",st->codec->channels);

        return -1;

    }

    st->codec->channel_layout = (st->codec->channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;

    st->codec->block_align = AT1_SU_SIZE * st->codec->channels;

    return 0;

}


static void spr_write_ibatl (void *opaque, int sprn)

{

    DisasContext *ctx = opaque;

    gen_op_store_ibatl((sprn - SPR_IBAT0L) / 2);

    RET_STOP(ctx);

}


static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit)

{

    gen_update_cc_op(s);

    /* If several instructions disable interrupts, only the first does it.  */

    if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {

        gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);

    } else {

        gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);

    }

    if (s->tb->flags & HF_RF_MASK) {

        gen_helper_reset_rf(cpu_env);

    }

    if (s->singlestep_enabled) {

        gen_helper_debug(cpu_env);

    } else if (s->tf) {

        gen_helper_single_step(cpu_env);

    } else {

        tcg_gen_exit_tb(0);

    }

    s->is_jmp = DISAS_TB_JUMP;

}


void tb_invalidate_page_range(target_ulong start, target_ulong end)

{

    /* XXX: cannot enable it yet because it yields to MMU exception

       where NIP != read address on PowerPC */

#if 0

    target_ulong phys_addr;

    phys_addr = get_phys_addr_code(env, start);

    tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0);

#endif

}


static bool kvmppc_is_pr(KVMState *ks)

{

    /* Assume KVM-PR if the GET_PVINFO capability is available */

    return kvm_check_extension(ks, KVM_CAP_PPC_GET_PVINFO) != 0;

}


void aio_set_fd_handler(AioContext *ctx,

                        int fd,

                        IOHandler *io_read,

                        IOHandler *io_write,

                        AioFlushHandler *io_flush,

                        void *opaque)

{

    AioHandler *node;

    node = find_aio_handler(ctx, fd);

    /* Are we deleting the fd handler? */

    if (!io_read && !io_write) {

        if (node) {

            /* If the lock is held, just mark the node as deleted */

            if (ctx->walking_handlers)

                node->deleted = 1;

            else {

                /* Otherwise, delete it for real.  We can't just mark it as

                 * deleted because deleted nodes are only cleaned up after

                 * releasing the walking_handlers lock.

                 */

                QLIST_REMOVE(node, node);

                g_free(node);

            }

        }

    } else {

        if (node == NULL) {

            /* Alloc and insert if it's not already there */

            node = g_malloc0(sizeof(AioHandler));

            node->fd = fd;

            QLIST_INSERT_HEAD(&ctx->aio_handlers, node, node);

        }

        /* Update handler with latest information */

        node->io_read = io_read;

        node->io_write = io_write;

        node->io_flush = io_flush;

        node->opaque = opaque;

    }

}


static uint64_t gic_do_cpu_read(void *opaque, target_phys_addr_t addr,

                                unsigned size)

{

    GICState **backref = (GICState **)opaque;

    GICState *s = *backref;

    int id = (backref - s->backref);

    return gic_cpu_read(s, id, addr);

}


void bdrv_io_unplug(BlockDriverState *bs)

{

    BlockDriver *drv = bs->drv;

    if (drv && drv->bdrv_io_unplug) {

        drv->bdrv_io_unplug(bs);

    } else if (bs->file) {

        bdrv_io_unplug(bs->file->bs);

    }

}


static void ehci_advance_async_state(EHCIState *ehci)

{

    const int async = 1;

    switch(ehci_get_state(ehci, async)) {

    case EST_INACTIVE:

        if (!ehci_async_enabled(ehci)) {

            break;

        }

        ehci_set_state(ehci, async, EST_ACTIVE);

        // No break, fall through to ACTIVE

    case EST_ACTIVE:

        if (!ehci_async_enabled(ehci)) {

            ehci_queues_rip_all(ehci, async);

            ehci_set_state(ehci, async, EST_INACTIVE);

            break;

        }

        /* make sure guest has acknowledged the doorbell interrupt */

        /* TO-DO: is this really needed? */

        if (ehci->usbsts & USBSTS_IAA) {

            DPRINTF("IAA status bit still set.\n");

            break;

        }

        /* check that address register has been set */

        if (ehci->asynclistaddr == 0) {

            break;

        }

        ehci_set_state(ehci, async, EST_WAITLISTHEAD);

        ehci_advance_state(ehci, async);

        /* If the doorbell is set, the guest wants to make a change to the

         * schedule. The host controller needs to release cached data.

         * (section 4.8.2)

         */

        if (ehci->usbcmd & USBCMD_IAAD) {

            /* Remove all unseen qhs from the async qhs queue */

            ehci_queues_rip_unused(ehci, async, 1);

            DPRINTF("ASYNC: doorbell request acknowledged\n");

            ehci->usbcmd &= ~USBCMD_IAAD;

            ehci_set_interrupt(ehci, USBSTS_IAA);

        }

        break;

    default:

        /* this should only be due to a developer mistake */

        fprintf(stderr, "ehci: Bad asynchronous state %d. "

                "Resetting to active\n", ehci->astate);

        assert(0);

    }

}


static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap)

{

    AVIOContext *pb = s->pb;

    RPLContext *rpl = s->priv_data;

    AVStream *vst = NULL, *ast = NULL;

    int total_audio_size;

    int error = 0;

    uint32_t i;

    int32_t audio_format, chunk_catalog_offset, number_of_chunks;

    AVRational fps;

    char line[RPL_LINE_LENGTH];

    // The header for RPL/ARMovie files is 21 lines of text

    // containing the various header fields.  The fields are always

    // in the same order, and other text besides the first

    // number usually isn't important.

    // (The spec says that there exists some significance

    // for the text in a few cases; samples needed.)

    error |= read_line(pb, line, sizeof(line));      // ARMovie

    error |= read_line(pb, line, sizeof(line));      // movie name

    av_dict_set(&s->metadata, "title"    , line, 0);

    error |= read_line(pb, line, sizeof(line));      // date/copyright

    av_dict_set(&s->metadata, "copyright", line, 0);

    error |= read_line(pb, line, sizeof(line));      // author and other

    av_dict_set(&s->metadata, "author"   , line, 0);

    // video headers

    vst = avformat_new_stream(s, NULL);

    if (!vst)

        return AVERROR(ENOMEM);

    vst->codec->codec_type      = AVMEDIA_TYPE_VIDEO;

    vst->codec->codec_tag       = read_line_and_int(pb, &error);  // video format

    vst->codec->width           = read_line_and_int(pb, &error);  // video width

    vst->codec->height          = read_line_and_int(pb, &error);  // video height

    vst->codec->bits_per_coded_sample = read_line_and_int(pb, &error);  // video bits per sample

    error |= read_line(pb, line, sizeof(line));                   // video frames per second

    fps = read_fps(line, &error);

    avpriv_set_pts_info(vst, 32, fps.den, fps.num);

    // Figure out the video codec

    switch (vst->codec->codec_tag) {

#if 0

        case 122:

            vst->codec->codec_id = CODEC_ID_ESCAPE122;

            break;

#endif

        case 124:

            vst->codec->codec_id = CODEC_ID_ESCAPE124;

            // The header is wrong here, at least sometimes

            vst->codec->bits_per_coded_sample = 16;

            break;

        case 130:

            vst->codec->codec_id = CODEC_ID_ESCAPE130;

            break;

        default:

            av_log(s, AV_LOG_WARNING,

                   "RPL video format %i not supported yet!\n",

                   vst->codec->codec_tag);

            vst->codec->codec_id = CODEC_ID_NONE;

    }

    // Audio headers

    // ARMovie supports multiple audio tracks; I don't have any

    // samples, though. This code will ignore additional tracks.

    audio_format = read_line_and_int(pb, &error);  // audio format ID

    if (audio_format) {

        ast = avformat_new_stream(s, NULL);

        if (!ast)

            return AVERROR(ENOMEM);

        ast->codec->codec_type      = AVMEDIA_TYPE_AUDIO;

        ast->codec->codec_tag       = audio_format;

        ast->codec->sample_rate     = read_line_and_int(pb, &error);  // audio bitrate

        ast->codec->channels        = read_line_and_int(pb, &error);  // number of audio channels

        ast->codec->bits_per_coded_sample = read_line_and_int(pb, &error);  // audio bits per sample

        // At least one sample uses 0 for ADPCM, which is really 4 bits

        // per sample.

        if (ast->codec->bits_per_coded_sample == 0)

            ast->codec->bits_per_coded_sample = 4;

        ast->codec->bit_rate = ast->codec->sample_rate *

                               ast->codec->bits_per_coded_sample *

                               ast->codec->channels;

        ast->codec->codec_id = CODEC_ID_NONE;

        switch (audio_format) {

            case 1:

                if (ast->codec->bits_per_coded_sample == 16) {

                    // 16-bit audio is always signed

                    ast->codec->codec_id = CODEC_ID_PCM_S16LE;

                    break;

                }

                // There are some other formats listed as legal per the spec;

                // samples needed.

                break;

            case 101:

                if (ast->codec->bits_per_coded_sample == 8) {

                    // The samples with this kind of audio that I have

                    // are all unsigned.

                    ast->codec->codec_id = CODEC_ID_PCM_U8;

                    break;

                } else if (ast->codec->bits_per_coded_sample == 4) {

                    ast->codec->codec_id = CODEC_ID_ADPCM_IMA_EA_SEAD;

                    break;

                }

                break;

        }

        if (ast->codec->codec_id == CODEC_ID_NONE) {

            av_log(s, AV_LOG_WARNING,

                   "RPL audio format %i not supported yet!\n",

                   audio_format);

        }

        avpriv_set_pts_info(ast, 32, 1, ast->codec->bit_rate);

    } else {

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

            error |= read_line(pb, line, sizeof(line));

    }

    rpl->frames_per_chunk = read_line_and_int(pb, &error);  // video frames per chunk

    if (rpl->frames_per_chunk > 1 && vst->codec->codec_tag != 124)

        av_log(s, AV_LOG_WARNING,

               "Don't know how to split frames for video format %i. "

               "Video stream will be broken!\n", vst->codec->codec_tag);

    number_of_chunks = read_line_and_int(pb, &error);  // number of chunks in the file

    // The number in the header is actually the index of the last chunk.

    number_of_chunks++;

    error |= read_line(pb, line, sizeof(line));  // "even" chunk size in bytes

    error |= read_line(pb, line, sizeof(line));  // "odd" chunk size in bytes

    chunk_catalog_offset =                       // offset of the "chunk catalog"

        read_line_and_int(pb, &error);           //   (file index)

    error |= read_line(pb, line, sizeof(line));  // offset to "helpful" sprite

    error |= read_line(pb, line, sizeof(line));  // size of "helpful" sprite

    error |= read_line(pb, line, sizeof(line));  // offset to key frame list

    // Read the index

    avio_seek(pb, chunk_catalog_offset, SEEK_SET);

    total_audio_size = 0;

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

        int64_t offset, video_size, audio_size;

        error |= read_line(pb, line, sizeof(line));

        if (3 != sscanf(line, "%"PRId64" , %"PRId64" ; %"PRId64,

                        &offset, &video_size, &audio_size))

            error = -1;

        av_add_index_entry(vst, offset, i * rpl->frames_per_chunk,

                           video_size, rpl->frames_per_chunk, 0);

        if (ast)

            av_add_index_entry(ast, offset + video_size, total_audio_size,

                               audio_size, audio_size * 8, 0);

        total_audio_size += audio_size * 8;

    }

    if (error) return AVERROR(EIO);

    return 0;

}


static QDict *monitor_parse_arguments(Monitor *mon,

                                      const char **endp,

                                      const mon_cmd_t *cmd)

{

    const char *typestr;

    char *key;

    int c;

    const char *p = *endp;

    char buf[1024];

    QDict *qdict = qdict_new();

    /* parse the parameters */

    typestr = cmd->args_type;

    for(;;) {

        typestr = key_get_info(typestr, &key);

        if (!typestr)

            break;

        c = *typestr;

        typestr++;

        switch(c) {

        case 'F':

        case 'B':

        case 's':

            {

                int ret;

                while (qemu_isspace(*p))

                    p++;

                if (*typestr == '?') {

                    typestr++;

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

                        /* no optional string: NULL argument */

                        break;

                    }

                }

                ret = get_str(buf, sizeof(buf), &p);

                if (ret < 0) {

                    switch(c) {

                    case 'F':

                        monitor_printf(mon, "%s: filename expected\n",

                                       cmd->name);

                        break;

                    case 'B':

                        monitor_printf(mon, "%s: block device name expected\n",

                                       cmd->name);

                        break;

                    default:

                        monitor_printf(mon, "%s: string expected\n", cmd->name);

                        break;

                    }

                    goto fail;

                }

                qdict_put(qdict, key, qstring_from_str(buf));

            }

            break;

        case 'O':

            {

                QemuOptsList *opts_list;

                QemuOpts *opts;

                opts_list = qemu_find_opts(key);

                if (!opts_list || opts_list->desc->name) {

                    goto bad_type;

                }

                while (qemu_isspace(*p)) {

                    p++;

                }

                if (!*p)

                    break;

                if (get_str(buf, sizeof(buf), &p) < 0) {

                    goto fail;

                }

                opts = qemu_opts_parse_noisily(opts_list, buf, true);

                if (!opts) {

                    goto fail;

                }

                qemu_opts_to_qdict(opts, qdict);

                qemu_opts_del(opts);

            }

            break;

        case '/':

            {

                int count, format, size;

                while (qemu_isspace(*p))

                    p++;

                if (*p == '/') {

                    /* format found */

                    p++;

                    count = 1;

                    if (qemu_isdigit(*p)) {

                        count = 0;

                        while (qemu_isdigit(*p)) {

                            count = count * 10 + (*p - '0');

                            p++;

                        }

                    }

                    size = -1;

                    format = -1;

                    for(;;) {

                        switch(*p) {

                        case 'o':

                        case 'd':

                        case 'u':

                        case 'x':

                        case 'i':

                        case 'c':

                            format = *p++;

                            break;

                        case 'b':

                            size = 1;

                            p++;

                            break;

                        case 'h':

                            size = 2;

                            p++;

                            break;

                        case 'w':

                            size = 4;

                            p++;

                            break;

                        case 'g':

                        case 'L':

                            size = 8;

                            p++;

                            break;

                        default:

                            goto next;

                        }

                    }

                next:

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

                        monitor_printf(mon, "invalid char in format: '%c'\n",

                                       *p);

                        goto fail;

                    }

                    if (format < 0)

                        format = default_fmt_format;

                    if (format != 'i') {

                        /* for 'i', not specifying a size gives -1 as size */

                        if (size < 0)

                            size = default_fmt_size;

                        default_fmt_size = size;

                    }

                    default_fmt_format = format;

                } else {

                    count = 1;

                    format = default_fmt_format;

                    if (format != 'i') {

                        size = default_fmt_size;

                    } else {

                        size = -1;

                    }

                }

                qdict_put(qdict, "count", qint_from_int(count));

                qdict_put(qdict, "format", qint_from_int(format));

                qdict_put(qdict, "size", qint_from_int(size));

            }

            break;

        case 'i':

        case 'l':

        case 'M':

            {

                int64_t val;

                while (qemu_isspace(*p))

                    p++;

                if (*typestr == '?' || *typestr == '.') {

                    if (*typestr == '?') {

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

                            typestr++;

                            break;

                        }

                    } else {

                        if (*p == '.') {

                            p++;

                            while (qemu_isspace(*p))

                                p++;

                        } else {

                            typestr++;

                            break;

                        }

                    }

                    typestr++;

                }

                if (get_expr(mon, &val, &p))

                    goto fail;

                /* Check if 'i' is greater than 32-bit */

                if ((c == 'i') && ((val >> 32) & 0xffffffff)) {

                    monitor_printf(mon, "\'%s\' has failed: ", cmd->name);

                    monitor_printf(mon, "integer is for 32-bit values\n");

                    goto fail;

                } else if (c == 'M') {

                    if (val < 0) {

                        monitor_printf(mon, "enter a positive value\n");

                        goto fail;

                    }

                    val <<= 20;

                }

                qdict_put(qdict, key, qint_from_int(val));

            }

            break;

        case 'o':

            {

                int64_t val;

                char *end;

                while (qemu_isspace(*p)) {

                    p++;

                }

                if (*typestr == '?') {

                    typestr++;

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

                        break;

                    }

                }

                val = qemu_strtosz_MiB(p, &end);

                if (val < 0) {

                    monitor_printf(mon, "invalid size\n");

                    goto fail;

                }

                qdict_put(qdict, key, qint_from_int(val));

                p = end;

            }

            break;

        case 'T':

            {

                double val;

                while (qemu_isspace(*p))

                    p++;

                if (*typestr == '?') {

                    typestr++;

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

                        break;

                    }

                }

                if (get_double(mon, &val, &p) < 0) {

                    goto fail;

                }

                if (p[0] && p[1] == 's') {

                    switch (*p) {

                    case 'm':

                        val /= 1e3; p += 2; break;

                    case 'u':

                        val /= 1e6; p += 2; break;

                    case 'n':

                        val /= 1e9; p += 2; break;

                    }

                }

                if (*p && !qemu_isspace(*p)) {

                    monitor_printf(mon, "Unknown unit suffix\n");

                    goto fail;

                }

                qdict_put(qdict, key, qfloat_from_double(val));

            }

            break;

        case 'b':

            {

                const char *beg;

                bool val;

                while (qemu_isspace(*p)) {

                    p++;

                }

                beg = p;

                while (qemu_isgraph(*p)) {

                    p++;

                }

                if (p - beg == 2 && !memcmp(beg, "on", p - beg)) {

                    val = true;

                } else if (p - beg == 3 && !memcmp(beg, "off", p - beg)) {

                    val = false;

                } else {

                    monitor_printf(mon, "Expected 'on' or 'off'\n");

                    goto fail;

                }

                qdict_put(qdict, key, qbool_from_bool(val));

            }

            break;

        case '-':

            {

                const char *tmp = p;

                int skip_key = 0;

                /* option */

                c = *typestr++;

                if (c == '\0')

                    goto bad_type;

                while (qemu_isspace(*p))

                    p++;

                if (*p == '-') {

                    p++;

                    if(c != *p) {

                        if(!is_valid_option(p, typestr)) {

                            monitor_printf(mon, "%s: unsupported option -%c\n",

                                           cmd->name, *p);

                            goto fail;

                        } else {

                            skip_key = 1;

                        }

                    }

                    if(skip_key) {

                        p = tmp;

                    } else {

                        /* has option */

                        p++;

                        qdict_put(qdict, key, qbool_from_bool(true));

                    }

                }

            }

            break;

        case 'S':

            {

                /* package all remaining string */

                int len;

                while (qemu_isspace(*p)) {

                    p++;

                }

                if (*typestr == '?') {

                    typestr++;

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

                        /* no remaining string: NULL argument */

                        break;

                    }

                }

                len = strlen(p);

                if (len <= 0) {

                    monitor_printf(mon, "%s: string expected\n",

                                   cmd->name);

                    goto fail;

                }

                qdict_put(qdict, key, qstring_from_str(p));

                p += len;

            }

            break;

        default:

        bad_type:

            monitor_printf(mon, "%s: unknown type '%c'\n", cmd->name, c);

            goto fail;

        }

        g_free(key);

        key = NULL;

    }

    /* check that all arguments were parsed */

    while (qemu_isspace(*p))

        p++;

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

        monitor_printf(mon, "%s: extraneous characters at the end of line\n",

                       cmd->name);

        goto fail;

    }

    return qdict;

fail:

    QDECREF(qdict);

    g_free(key);

    return NULL;

}


static void visitor_input_teardown(TestInputVisitorData *data,

                                   const void *unused)

{

    qobject_decref(data->obj);

    data->obj = NULL;

    if (data->qiv) {

        visit_free(data->qiv);

        data->qiv = NULL;

    }

}


MigrationState *migrate_get_current(void)

{

    static bool once;

    static MigrationState current_migration = {

        .state = MIGRATION_STATUS_NONE,

        .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE,

        .mbps = -1,

        .parameters = {

            .compress_level = DEFAULT_MIGRATE_COMPRESS_LEVEL,

            .compress_threads = DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT,

            .decompress_threads = DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT,

            .cpu_throttle_initial = DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL,

            .cpu_throttle_increment = DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT,

            .max_bandwidth = MAX_THROTTLE,

            .downtime_limit = DEFAULT_MIGRATE_SET_DOWNTIME,

            .x_checkpoint_delay = DEFAULT_MIGRATE_X_CHECKPOINT_DELAY,

        },

    };

    if (!once) {

        current_migration.parameters.tls_creds = g_strdup("");

        current_migration.parameters.tls_hostname = g_strdup("");

        once = true;

    }

    return &current_migration;

}


static int coroutine_fn qed_aio_read_data(void *opaque, int ret,

                                          uint64_t offset, size_t len)

{

    QEDAIOCB *acb = opaque;

    BDRVQEDState *s = acb_to_s(acb);

    BlockDriverState *bs = acb->bs;

    /* Adjust offset into cluster */

    offset += qed_offset_into_cluster(s, acb->cur_pos);

    trace_qed_aio_read_data(s, acb, ret, offset, len);

    qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);

    /* Handle zero cluster and backing file reads */

    if (ret == QED_CLUSTER_ZERO) {

        qemu_iovec_memset(&acb->cur_qiov, 0, 0, acb->cur_qiov.size);

        return 0;

    } else if (ret != QED_CLUSTER_FOUND) {

        return qed_read_backing_file(s, acb->cur_pos, &acb->cur_qiov,

                                     &acb->backing_qiov);

    }

    BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);

    ret = bdrv_co_preadv(bs->file, offset, acb->cur_qiov.size,

                         &acb->cur_qiov, 0);

    if (ret < 0) {

        return ret;

    }

    return 0;

}


static void portio_list_add_1(PortioList *piolist,

                              const MemoryRegionPortio *pio_init,

                              unsigned count, unsigned start,

                              unsigned off_low, unsigned off_high)

{

    MemoryRegionPortio *pio;

    MemoryRegionOps *ops;

    MemoryRegion *region, *alias;

    unsigned i;

    /* Copy the sub-list and null-terminate it.  */

    pio = g_new(MemoryRegionPortio, count + 1);

    memcpy(pio, pio_init, sizeof(MemoryRegionPortio) * count);

    memset(pio + count, 0, sizeof(MemoryRegionPortio));

    /* Adjust the offsets to all be zero-based for the region.  */

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

        pio[i].offset -= off_low;

    }

    ops = g_new0(MemoryRegionOps, 1);

    ops->old_portio = pio;

    region = g_new(MemoryRegion, 1);

    alias = g_new(MemoryRegion, 1);

    /*

     * Use an alias so that the callback is called with an absolute address,

     * rather than an offset relative to to start + off_low.

     */

    memory_region_init_io(region, ops, piolist->opaque, piolist->name,

                          INT64_MAX);

    memory_region_init_alias(alias, piolist->name,

                             region, start + off_low, off_high - off_low);

    memory_region_add_subregion(piolist->address_space,

                                start + off_low, alias);

    piolist->regions[piolist->nr] = region;

    piolist->aliases[piolist->nr] = alias;

    ++piolist->nr;

}


static int bochs_read(BlockDriverState *bs, int64_t sector_num,

                    uint8_t *buf, int nb_sectors)

{

    int ret;

    while (nb_sectors > 0) {

        int64_t block_offset = seek_to_sector(bs, sector_num);

        if (block_offset >= 0) {

            ret = bdrv_pread(bs->file, block_offset, buf, 512);

            if (ret != 512) {

                return -1;

            }

        } else

            memset(buf, 0, 512);

        nb_sectors--;

        sector_num++;

        buf += 512;

    }

    return 0;

}


static void visit_nested_struct_list(Visitor *v, void **native, Error **errp)

{

    visit_type_UserDefNestedList(v, (UserDefNestedList **)native, NULL, errp);

}