static int decode_simple_internal(AVCodecContext *avctx, AVFrame *frame)

{

    AVCodecInternal   *avci = avctx->internal;

    DecodeSimpleContext *ds = &avci->ds;

    AVPacket           *pkt = ds->in_pkt;

    // copy to ensure we do not change pkt

    AVPacket tmp;

    int got_frame, actual_got_frame, did_split;

    int ret;

    if (!pkt->data && !avci->draining) {

        av_packet_unref(pkt);

        ret = ff_decode_get_packet(avctx, pkt);

        if (ret < 0 && ret != AVERROR_EOF)

            return ret;

    }

    // Some codecs (at least wma lossless) will crash when feeding drain packets

    // after EOF was signaled.

    if (avci->draining_done)

        return AVERROR_EOF;

    if (!pkt->data &&

        !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY ||

          avctx->active_thread_type & FF_THREAD_FRAME))

        return AVERROR_EOF;

    tmp = *pkt;

#if FF_API_MERGE_SD

FF_DISABLE_DEPRECATION_WARNINGS

    did_split = av_packet_split_side_data(&tmp);

    if (did_split) {

        ret = extract_packet_props(avctx->internal, &tmp);

        if (ret < 0)

            return ret;

        ret = apply_param_change(avctx, &tmp);

        if (ret < 0)

            return ret;

    }

FF_ENABLE_DEPRECATION_WARNINGS

#endif

    got_frame = 0;

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

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

    } else {

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

        if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) {

            if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_PKT_DTS))

                frame->pkt_dts = pkt->dts;

            if(!avctx->has_b_frames)

                frame->pkt_pos = pkt->pos;

            //FIXME these should be under if(!avctx->has_b_frames)

            /* get_buffer is supposed to set frame parameters */

            if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) {

                if (!frame->sample_aspect_ratio.num)  frame->sample_aspect_ratio = avctx->sample_aspect_ratio;

                if (!frame->width)                    frame->width               = avctx->width;

                if (!frame->height)                   frame->height              = avctx->height;

                if (frame->format == AV_PIX_FMT_NONE) frame->format              = avctx->pix_fmt;

            }

        } else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {

            frame->pkt_dts = pkt->dts;

        }

    }

    emms_c();

    actual_got_frame = got_frame;

    if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) {

        if (frame->flags & AV_FRAME_FLAG_DISCARD)

            got_frame = 0;

        if (got_frame)

            frame->best_effort_timestamp = guess_correct_pts(avctx,

                                                             frame->pts,

                                                             frame->pkt_dts);

    } else if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {

        uint8_t *side;

        int side_size;

        uint32_t discard_padding = 0;

        uint8_t skip_reason = 0;

        uint8_t discard_reason = 0;

        if (ret >= 0 && got_frame) {

            frame->best_effort_timestamp = guess_correct_pts(avctx,

                                                             frame->pts,

                                                             frame->pkt_dts);

            if (frame->format == AV_SAMPLE_FMT_NONE)

                frame->format = avctx->sample_fmt;

            if (!frame->channel_layout)

                frame->channel_layout = avctx->channel_layout;

            if (!frame->channels)

                frame->channels = avctx->channels;

            if (!frame->sample_rate)

                frame->sample_rate = avctx->sample_rate;

        }

        side= av_packet_get_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);

        if(side && side_size>=10) {

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

            discard_padding = AV_RL32(side + 4);

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

                   avctx->internal->skip_samples, (int)discard_padding);

            skip_reason = AV_RL8(side + 8);

            discard_reason = AV_RL8(side + 9);

        }

        if ((frame->flags & AV_FRAME_FLAG_DISCARD) && got_frame &&

            !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) {

            avctx->internal->skip_samples = FFMAX(0, avctx->internal->skip_samples - frame->nb_samples);

            got_frame = 0;

        }

        if (avctx->internal->skip_samples > 0 && got_frame &&

            !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) {

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

                got_frame = 0;

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

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

                       avctx->internal->skip_samples);

            } else {

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

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

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

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

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

                                                   avctx->pkt_timebase);

                    if(frame->pts!=AV_NOPTS_VALUE)

                        frame->pts += diff_ts;

#if FF_API_PKT_PTS

FF_DISABLE_DEPRECATION_WARNINGS

                    if(frame->pkt_pts!=AV_NOPTS_VALUE)

                        frame->pkt_pts += diff_ts;

FF_ENABLE_DEPRECATION_WARNINGS

#endif

                    if(frame->pkt_dts!=AV_NOPTS_VALUE)

                        frame->pkt_dts += diff_ts;

                    if (frame->pkt_duration >= diff_ts)

                        frame->pkt_duration -= diff_ts;

                } else {

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

                }

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

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

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

                avctx->internal->skip_samples = 0;

            }

        }

        if (discard_padding > 0 && discard_padding <= frame->nb_samples && got_frame &&

            !(avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL)) {

            if (discard_padding == frame->nb_samples) {

                got_frame = 0;

            } else {

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

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

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

                                                   avctx->pkt_timebase);

                    frame->pkt_duration = diff_ts;

                } else {

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

                }

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

                       (int)discard_padding, frame->nb_samples);

                frame->nb_samples -= discard_padding;

            }

        }

        if ((avctx->flags2 & AV_CODEC_FLAG2_SKIP_MANUAL) && got_frame) {

            AVFrameSideData *fside = av_frame_new_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES, 10);

            if (fside) {

                AV_WL32(fside->data, avctx->internal->skip_samples);

                AV_WL32(fside->data + 4, discard_padding);

                AV_WL8(fside->data + 8, skip_reason);

                AV_WL8(fside->data + 9, discard_reason);

                avctx->internal->skip_samples = 0;

            }

        }

    }

#if FF_API_MERGE_SD

    if (did_split) {

        av_packet_free_side_data(&tmp);

        if(ret == tmp.size)

            ret = pkt->size;

    }

#endif

    if (avctx->codec->type == AVMEDIA_TYPE_AUDIO &&

        !avci->showed_multi_packet_warning &&

        ret >= 0 && ret != pkt->size && !(avctx->codec->capabilities & AV_CODEC_CAP_SUBFRAMES)) {

        av_log(avctx, AV_LOG_WARNING, "Multiple frames in a packet.\n");

        avci->showed_multi_packet_warning = 1;

    }

    if (!got_frame)

        av_frame_unref(frame);

    if (ret >= 0 && avctx->codec->type == AVMEDIA_TYPE_VIDEO && !(avctx->flags & AV_CODEC_FLAG_TRUNCATED))

        ret = pkt->size;

#if FF_API_AVCTX_TIMEBASE

    if (avctx->framerate.num > 0 && avctx->framerate.den > 0)

        avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1}));

#endif

    /* do not stop draining when actual_got_frame != 0 or ret < 0 */

    /* got_frame == 0 but actual_got_frame != 0 when frame is discarded */

    if (avctx->internal->draining && !actual_got_frame) {

        if (ret < 0) {

            /* prevent infinite loop if a decoder wrongly always return error on draining */

            /* reasonable nb_errors_max = maximum b frames + thread count */

            int nb_errors_max = 20 + (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME ?

                                avctx->thread_count : 1);

            if (avci->nb_draining_errors++ >= nb_errors_max) {

                av_log(avctx, AV_LOG_ERROR, "Too many errors when draining, this is a bug. "

                       "Stop draining and force EOF.\n");

                avci->draining_done = 1;

                ret = AVERROR_BUG;

            }

        } else {

            avci->draining_done = 1;

        }

    }

    avci->compat_decode_consumed += ret;

    if (ret >= pkt->size || ret < 0) {

        av_packet_unref(pkt);

    } else {

        int consumed = ret;

        pkt->data                += consumed;

        pkt->size                -= consumed;

        avci->last_pkt_props->size -= consumed; // See extract_packet_props() comment.

        pkt->pts                  = AV_NOPTS_VALUE;

        pkt->dts                  = AV_NOPTS_VALUE;

        avci->last_pkt_props->pts = AV_NOPTS_VALUE;

        avci->last_pkt_props->dts = AV_NOPTS_VALUE;

    }

    if (got_frame)

        av_assert0(frame->buf[0]);

    return ret < 0 ? ret : 0;

}


static void sd_erase(SDState *sd)

{

    int i, start, end;

    if (!sd->erase_start || !sd->erase_end) {

        sd->card_status |= ERASE_SEQ_ERROR;

        return;

    }

    start = sd->erase_start >>

            (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);

    end = sd->erase_end >>

            (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);

    sd->erase_start = 0;

    sd->erase_end = 0;

    sd->csd[14] |= 0x40;

    for (i = start; i <= end; i ++)

        if (sd->wp_groups[i])

            sd->card_status |= WP_ERASE_SKIP;

}


static void tcg_init_vcpu(void *_env)

{

    CPUState *env = _env;

    /* share a single thread for all cpus with TCG */

    if (!tcg_cpu_thread) {

        env->thread = qemu_mallocz(sizeof(QemuThread));

        env->halt_cond = qemu_mallocz(sizeof(QemuCond));

        qemu_cond_init(env->halt_cond);

        qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);

        while (env->created == 0)

            qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);

        tcg_cpu_thread = env->thread;

        tcg_halt_cond = env->halt_cond;

    } else {

        env->thread = tcg_cpu_thread;

        env->halt_cond = tcg_halt_cond;

    }

}


static int nbd_negotiate_handle_list(NBDClient *client, uint32_t length,

                                     Error **errp)

{

    NBDExport *exp;

    if (length) {

        if (nbd_drop(client->ioc, length, errp) < 0) {

            return -EIO;

        }

        return nbd_negotiate_send_rep_err(client->ioc,

                                          NBD_REP_ERR_INVALID, NBD_OPT_LIST,

                                          errp,

                                          "OPT_LIST should not have length");

    }

    /* For each export, send a NBD_REP_SERVER reply. */

    QTAILQ_FOREACH(exp, &exports, next) {

        if (nbd_negotiate_send_rep_list(client->ioc, exp, errp)) {

            return -EINVAL;

        }

    }

    /* Finish with a NBD_REP_ACK. */

    return nbd_negotiate_send_rep(client->ioc, NBD_REP_ACK, NBD_OPT_LIST, errp);

}


static void init_excp_620 (CPUPPCState *env)

{

#if !defined(CONFIG_USER_ONLY)

    env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;

    env->excp_vectors[POWERPC_EXCP_MCHECK]   = 0x00000200;

    env->excp_vectors[POWERPC_EXCP_DSI]      = 0x00000300;

    env->excp_vectors[POWERPC_EXCP_DSEG]     = 0x00000380;

    env->excp_vectors[POWERPC_EXCP_ISI]      = 0x00000400;

    env->excp_vectors[POWERPC_EXCP_ISEG]     = 0x00000480;

    env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;

    env->excp_vectors[POWERPC_EXCP_ALIGN]    = 0x00000600;

    env->excp_vectors[POWERPC_EXCP_PROGRAM]  = 0x00000700;

    env->excp_vectors[POWERPC_EXCP_FPU]      = 0x00000800;

    env->excp_vectors[POWERPC_EXCP_DECR]     = 0x00000900;

    env->excp_vectors[POWERPC_EXCP_SYSCALL]  = 0x00000C00;

    env->excp_vectors[POWERPC_EXCP_TRACE]    = 0x00000D00;

    env->excp_vectors[POWERPC_EXCP_FPA]      = 0x00000E00;

    env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;

    env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;

    env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;

    env->excp_prefix = 0xFFF00000UL;

    /* Hardware reset vector */

    env->hreset_vector = 0x0000000000000100ULL;

#endif

}


static void json_print_chapter_header(WriterContext *wctx, const char *chapter)

{

    JSONContext *json = wctx->priv;

    char *chapter_esc;

    if (wctx->nb_chapter)

        printf(",");

    json->multiple_entries = !strcmp(chapter, "packets") || !strcmp(chapter, "streams");

    chapter_esc = json_escape_str(chapter);

    printf("\n  \"%s\":%s", chapter_esc ? chapter_esc : "",

           json->multiple_entries ? " [" : " ");

    av_free(chapter_esc);

}


void qemu_macaddr_default_if_unset(MACAddr *macaddr)

{

    static int index = 0;

    static const MACAddr zero = { .a = { 0,0,0,0,0,0 } };

    if (memcmp(macaddr, &zero, sizeof(zero)) != 0)

        return;

    macaddr->a[0] = 0x52;

    macaddr->a[1] = 0x54;

    macaddr->a[2] = 0x00;

    macaddr->a[3] = 0x12;

    macaddr->a[4] = 0x34;

    macaddr->a[5] = 0x56 + index++;

}


static int compute_bit_allocation(AC3EncodeContext *s,

                                  uint8_t bap[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS],

                                  uint8_t encoded_exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS],

                                  uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS],

                                  int frame_bits)

{

    int blk, ch;

    int coarse_snr_offset, fine_snr_offset;

    uint8_t bap1[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];

    int16_t psd[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];

    int16_t mask[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_CRITICAL_BANDS];

    static const int frame_bits_inc[8] = { 0, 0, 2, 2, 2, 4, 2, 4 };

    /* init default parameters */

    s->slow_decay_code = 2;

    s->fast_decay_code = 1;

    s->slow_gain_code  = 1;

    s->db_per_bit_code = 2;

    s->floor_code      = 4;

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

        s->fast_gain_code[ch] = 4;

    /* compute real values */

    s->bit_alloc.slow_decay = ff_ac3_slow_decay_tab[s->slow_decay_code] >> s->bit_alloc.sr_shift;

    s->bit_alloc.fast_decay = ff_ac3_fast_decay_tab[s->fast_decay_code] >> s->bit_alloc.sr_shift;

    s->bit_alloc.slow_gain  = ff_ac3_slow_gain_tab[s->slow_gain_code];

    s->bit_alloc.db_per_bit = ff_ac3_db_per_bit_tab[s->db_per_bit_code];

    s->bit_alloc.floor      = ff_ac3_floor_tab[s->floor_code];

    /* header size */

    frame_bits += 65;

    // if (s->channel_mode == 2)

    //    frame_bits += 2;

    frame_bits += frame_bits_inc[s->channel_mode];

    /* audio blocks */

    for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {

        frame_bits += s->fbw_channels * 2 + 2; /* blksw * c, dithflag * c, dynrnge, cplstre */

        if (s->channel_mode == AC3_CHMODE_STEREO) {

            frame_bits++; /* rematstr */

            if (!blk)

                frame_bits += 4;

        }

        frame_bits += 2 * s->fbw_channels; /* chexpstr[2] * c */

        if (s->lfe_on)

            frame_bits++; /* lfeexpstr */

        for (ch = 0; ch < s->fbw_channels; ch++) {

            if (exp_strategy[blk][ch] != EXP_REUSE)

                frame_bits += 6 + 2; /* chbwcod[6], gainrng[2] */

        }

        frame_bits++; /* baie */

        frame_bits++; /* snr */

        frame_bits += 2; /* delta / skip */

    }

    frame_bits++; /* cplinu for block 0 */

    /* bit alloc info */

    /* sdcycod[2], fdcycod[2], sgaincod[2], dbpbcod[2], floorcod[3] */

    /* csnroffset[6] */

    /* (fsnoffset[4] + fgaincod[4]) * c */

    frame_bits += 2*4 + 3 + 6 + s->channels * (4 + 3);

    /* auxdatae, crcrsv */

    frame_bits += 2;

    /* CRC */

    frame_bits += 16;

    /* calculate psd and masking curve before doing bit allocation */

    bit_alloc_masking(s, encoded_exp, exp_strategy, psd, mask);

    /* now the big work begins : do the bit allocation. Modify the snr

       offset until we can pack everything in the requested frame size */

    coarse_snr_offset = s->coarse_snr_offset;

    while (coarse_snr_offset >= 0 &&

           bit_alloc(s, mask, psd, bap, frame_bits, coarse_snr_offset, 0) < 0)

        coarse_snr_offset -= SNR_INC1;

    if (coarse_snr_offset < 0) {

        av_log(NULL, AV_LOG_ERROR, "Bit allocation failed. Try increasing the bitrate.\n");

        return -1;

    }

    while (coarse_snr_offset + SNR_INC1 <= 63 &&

           bit_alloc(s, mask, psd, bap1, frame_bits,

                     coarse_snr_offset + SNR_INC1, 0) >= 0) {

        coarse_snr_offset += SNR_INC1;

        memcpy(bap, bap1, sizeof(bap1));

    }

    while (coarse_snr_offset + 1 <= 63 &&

           bit_alloc(s, mask, psd, bap1, frame_bits, coarse_snr_offset + 1, 0) >= 0) {

        coarse_snr_offset++;

        memcpy(bap, bap1, sizeof(bap1));

    }

    fine_snr_offset = 0;

    while (fine_snr_offset + SNR_INC1 <= 15 &&

           bit_alloc(s, mask, psd, bap1, frame_bits,

                     coarse_snr_offset, fine_snr_offset + SNR_INC1) >= 0) {

        fine_snr_offset += SNR_INC1;

        memcpy(bap, bap1, sizeof(bap1));

    }

    while (fine_snr_offset + 1 <= 15 &&

           bit_alloc(s, mask, psd, bap1, frame_bits,

                     coarse_snr_offset, fine_snr_offset + 1) >= 0) {

        fine_snr_offset++;

        memcpy(bap, bap1, sizeof(bap1));

    }

    s->coarse_snr_offset = coarse_snr_offset;

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

        s->fine_snr_offset[ch] = fine_snr_offset;

    return 0;

}


static int h264_frame_start(H264Context *h)

{

    H264Picture *pic;

    int i, ret;

    const int pixel_shift = h->pixel_shift;

    ret = initialize_cur_frame(h);

    if (ret < 0)

        return ret;

    pic = h->cur_pic_ptr;

    pic->reference              = h->droppable ? 0 : h->picture_structure;

    pic->f->coded_picture_number = h->coded_picture_number++;

    pic->field_picture          = h->picture_structure != PICT_FRAME;

    pic->frame_num               = h->frame_num;

    /*

     * Zero key_frame here; IDR markings per slice in frame or fields are ORed

     * in later.

     * See decode_nal_units().

     */

    pic->f->key_frame = 0;

    pic->mmco_reset  = 0;

    pic->recovered   = 0;

    if (CONFIG_ERROR_RESILIENCE && h->enable_er)

        ff_er_frame_start(&h->slice_ctx[0].er);

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

        h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * pic->f->linesize[0] * ((scan8[i] - scan8[0]) >> 3);

        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * pic->f->linesize[0] * ((scan8[i] - scan8[0]) >> 3);

    }

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

        h->block_offset[16 + i]      =

        h->block_offset[32 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * pic->f->linesize[1] * ((scan8[i] - scan8[0]) >> 3);

        h->block_offset[48 + 16 + i] =

        h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * pic->f->linesize[1] * ((scan8[i] - scan8[0]) >> 3);

    }

    /* Some macroblocks can be accessed before they're available in case

     * of lost slices, MBAFF or threading. */

    memset(h->slice_table, -1,

           (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));

    /* We mark the current picture as non-reference after allocating it, so

     * that if we break out due to an error it can be released automatically

     * in the next ff_mpv_frame_start().

     */

    h->cur_pic_ptr->reference = 0;

    h->cur_pic_ptr->field_poc[0] = h->cur_pic_ptr->field_poc[1] = INT_MAX;

    h->next_output_pic = NULL;

    assert(h->cur_pic_ptr->long_ref == 0);

    return 0;

}


void acpi_setup(void)

{

    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());

    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);

    AcpiBuildTables tables;

    AcpiBuildState *build_state;

    if (!pcms->fw_cfg) {

        ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n");

        return;

    }

    if (!pcmc->has_acpi_build) {

        ACPI_BUILD_DPRINTF("ACPI build disabled. Bailing out.\n");

        return;

    }

    if (!acpi_enabled) {

        ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n");

        return;

    }

    build_state = g_malloc0(sizeof *build_state);

    acpi_set_pci_info();

    acpi_build_tables_init(&tables);

    acpi_build(&tables, MACHINE(pcms));

    /* Now expose it all to Guest */

    build_state->table_mr = acpi_add_rom_blob(build_state, tables.table_data,

                                               ACPI_BUILD_TABLE_FILE,

                                               ACPI_BUILD_TABLE_MAX_SIZE);

    assert(build_state->table_mr != NULL);

    build_state->linker_mr =

        acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);

    fw_cfg_add_file(pcms->fw_cfg, ACPI_BUILD_TPMLOG_FILE,

                    tables.tcpalog->data, acpi_data_len(tables.tcpalog));

    if (!pcmc->rsdp_in_ram) {

        /*

         * Keep for compatibility with old machine types.

         * Though RSDP is small, its contents isn't immutable, so

         * we'll update it along with the rest of tables on guest access.

         */

        uint32_t rsdp_size = acpi_data_len(tables.rsdp);

        build_state->rsdp = g_memdup(tables.rsdp->data, rsdp_size);

        fw_cfg_add_file_callback(pcms->fw_cfg, ACPI_BUILD_RSDP_FILE,

                                 acpi_build_update, build_state,

                                 build_state->rsdp, rsdp_size);

        build_state->rsdp_mr = NULL;

    } else {

        build_state->rsdp = NULL;

        build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp,

                                                  ACPI_BUILD_RSDP_FILE, 0);

    }

    qemu_register_reset(acpi_build_reset, build_state);

    acpi_build_reset(build_state);

    vmstate_register(NULL, 0, &vmstate_acpi_build, build_state);

    /* Cleanup tables but don't free the memory: we track it

     * in build_state.

     */

    acpi_build_tables_cleanup(&tables, false);

}


DECLARE_WEIGHT(sse2)

DECLARE_WEIGHT(ssse3)

/** @{ */

/**

 * Define one qpel function.

 * LOOPSIZE must be already set to the number of pixels processed per

 * iteration in the inner loop of the called functions.

 * COFF(x) must be already defined so as to provide the offset into any

 * array of coeffs used by the called function for the qpel position x.

 */

#define QPEL_FUNC_DECL(OP, SIZE, PH, PV, OPT)                           \

static void OP ## rv40_qpel ##SIZE ##_mc ##PH ##PV ##OPT(uint8_t *dst,  \

                                                         uint8_t *src,  \

                                                         int stride)    \

{                                                                       \

    int i;                                                              \

    if (PH && PV) {                                                     \

        DECLARE_ALIGNED(16, uint8_t, tmp)[SIZE * (SIZE + 5)];           \

        uint8_t *tmpptr = tmp + SIZE * 2;                               \

        src -= stride * 2;                                              \

                                                                        \

        for (i = 0; i < SIZE; i += LOOPSIZE)                            \

            ff_put_rv40_qpel_h ##OPT(tmp + i, SIZE, src + i, stride,    \

                                     SIZE + 5, HCOFF(PH));              \

        for (i = 0; i < SIZE; i += LOOPSIZE)                            \

            ff_ ##OP ##rv40_qpel_v ##OPT(dst + i, stride, tmpptr + i,   \

                                         SIZE, SIZE, VCOFF(PV));        \

    } else if (PV) {                                                    \

        for (i = 0; i < SIZE; i += LOOPSIZE)                            \

            ff_ ##OP ##rv40_qpel_v ## OPT(dst + i, stride, src + i,     \

                                          stride, SIZE, VCOFF(PV));     \

    } else {                                                            \

        for (i = 0; i < SIZE; i += LOOPSIZE)                            \

            ff_ ##OP ##rv40_qpel_h ## OPT(dst + i, stride, src + i,     \

                                          stride, SIZE, HCOFF(PH));     \

    }                                                                   \

};

/** Declare functions for sizes 8 and 16 and given operations

 *  and qpel position. */

#define QPEL_FUNCS_DECL(OP, PH, PV, OPT) \

    QPEL_FUNC_DECL(OP,  8, PH, PV, OPT)  \

    QPEL_FUNC_DECL(OP, 16, PH, PV, OPT)

/** Declare all functions for all sizes and qpel positions */

#define QPEL_MC_DECL(OP, OPT)                                           \

void ff_ ##OP ##rv40_qpel_h ##OPT(uint8_t *dst, ptrdiff_t dstStride,    \

                                  const uint8_t *src,                   \

                                  ptrdiff_t srcStride,                  \

                                  int len, int m);                      \

void ff_ ##OP ##rv40_qpel_v ##OPT(uint8_t *dst, ptrdiff_t dstStride,    \

                                  const uint8_t *src,                   \

                                  ptrdiff_t srcStride,                  \

                                  int len, int m);                      \

QPEL_FUNCS_DECL(OP, 0, 1, OPT)                                          \

QPEL_FUNCS_DECL(OP, 0, 3, OPT)                                          \

QPEL_FUNCS_DECL(OP, 1, 0, OPT)                                          \

QPEL_FUNCS_DECL(OP, 1, 1, OPT)                                          \

QPEL_FUNCS_DECL(OP, 1, 2, OPT)                                          \

QPEL_FUNCS_DECL(OP, 1, 3, OPT)                                          \

QPEL_FUNCS_DECL(OP, 2, 1, OPT)                                          \

QPEL_FUNCS_DECL(OP, 2, 2, OPT)                                          \

QPEL_FUNCS_DECL(OP, 2, 3, OPT)                                          \

QPEL_FUNCS_DECL(OP, 3, 0, OPT)                                          \

QPEL_FUNCS_DECL(OP, 3, 1, OPT)                                          \

QPEL_FUNCS_DECL(OP, 3, 2, OPT)

/** @} */

#define LOOPSIZE  8

#define HCOFF(x)  (32 * (x - 1))

#define VCOFF(x)  (32 * (x - 1))

QPEL_MC_DECL(put_, _ssse3)

QPEL_MC_DECL(avg_, _ssse3)

#undef LOOPSIZE

#undef HCOFF

#undef VCOFF

#define LOOPSIZE  8

#define HCOFF(x)  (64 * (x - 1))

#define VCOFF(x)  (64 * (x - 1))

QPEL_MC_DECL(put_, _sse2)

QPEL_MC_DECL(avg_, _sse2)

#if ARCH_X86_32

#undef LOOPSIZE

#undef HCOFF

#undef VCOFF

#define LOOPSIZE  4

#define HCOFF(x)  (64 * (x - 1))

#define VCOFF(x)  (64 * (x - 1))

QPEL_MC_DECL(put_, _mmx)

#define ff_put_rv40_qpel_h_mmx2  ff_put_rv40_qpel_h_mmx

#define ff_put_rv40_qpel_v_mmx2  ff_put_rv40_qpel_v_mmx

QPEL_MC_DECL(avg_, _mmx2)

#define ff_put_rv40_qpel_h_3dnow  ff_put_rv40_qpel_h_mmx

#define ff_put_rv40_qpel_v_3dnow  ff_put_rv40_qpel_v_mmx

QPEL_MC_DECL(avg_, _3dnow)

#endif

/** @{ */

/** Set one function */

#define QPEL_FUNC_SET(OP, SIZE, PH, PV, OPT)                            \

    c-> OP ## pixels_tab[2 - SIZE / 8][4 * PV + PH] = OP ## rv40_qpel ##SIZE ## _mc ##PH ##PV ##OPT;

/** Set functions put and avg for sizes 8 and 16 and a given qpel position */

#define QPEL_FUNCS_SET(OP, PH, PV, OPT)         \

    QPEL_FUNC_SET(OP,  8, PH, PV, OPT)          \

    QPEL_FUNC_SET(OP, 16, PH, PV, OPT)

/** Set all functions for all sizes and qpel positions */

#define QPEL_MC_SET(OP, OPT)   \

QPEL_FUNCS_SET (OP, 0, 1, OPT) \

QPEL_FUNCS_SET (OP, 0, 3, OPT) \

QPEL_FUNCS_SET (OP, 1, 0, OPT) \

QPEL_FUNCS_SET (OP, 1, 1, OPT) \

QPEL_FUNCS_SET (OP, 1, 2, OPT) \

QPEL_FUNCS_SET (OP, 1, 3, OPT) \

QPEL_FUNCS_SET (OP, 2, 1, OPT) \

QPEL_FUNCS_SET (OP, 2, 2, OPT) \

QPEL_FUNCS_SET (OP, 2, 3, OPT) \

QPEL_FUNCS_SET (OP, 3, 0, OPT) \

QPEL_FUNCS_SET (OP, 3, 1, OPT) \

QPEL_FUNCS_SET (OP, 3, 2, OPT)

/** @} */

#endif /* HAVE_YASM */

void ff_rv40dsp_init_x86(RV34DSPContext *c, DSPContext *dsp)

{

#if HAVE_YASM

    int mm_flags = av_get_cpu_flags();

    if (mm_flags & AV_CPU_FLAG_MMX) {

        c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_mmx;

        c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_mmx;

#if HAVE_INLINE_ASM

        c->put_pixels_tab[0][15] = ff_put_rv40_qpel16_mc33_mmx;

        c->put_pixels_tab[1][15] = ff_put_rv40_qpel8_mc33_mmx;

        c->avg_pixels_tab[0][15] = ff_avg_rv40_qpel16_mc33_mmx;

        c->avg_pixels_tab[1][15] = ff_avg_rv40_qpel8_mc33_mmx;

#endif /* HAVE_INLINE_ASM */

#if ARCH_X86_32

        QPEL_MC_SET(put_, _mmx)

#endif

    }

    if (mm_flags & AV_CPU_FLAG_MMXEXT) {

        c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_mmx2;

        c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_mmx2;

        c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_mmx2;

        c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_mmx2;

        c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_mmx2;

        c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_mmx2;

#if ARCH_X86_32

        QPEL_MC_SET(avg_, _mmx2)

#endif

    } else if (mm_flags & AV_CPU_FLAG_3DNOW) {

        c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_3dnow;

        c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_3dnow;

#if ARCH_X86_32

        QPEL_MC_SET(avg_, _3dnow)

#endif

    }

    if (mm_flags & AV_CPU_FLAG_SSE2) {

        c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_sse2;

        c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_sse2;

        c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_sse2;

        c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_sse2;

        QPEL_MC_SET(put_, _sse2)

        QPEL_MC_SET(avg_, _sse2)

    }

    if (mm_flags & AV_CPU_FLAG_SSSE3) {

        c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_ssse3;

        c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_ssse3;

        c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_ssse3;

        c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_ssse3;

        QPEL_MC_SET(put_, _ssse3)

        QPEL_MC_SET(avg_, _ssse3)

    }

#endif /* HAVE_YASM */

}


static void axidma_write(void *opaque, hwaddr addr,

                         uint64_t value, unsigned size)

{

    XilinxAXIDMA *d = opaque;

    struct Stream *s;

    int sid;

    sid = streamid_from_addr(addr);

    s = &d->streams[sid];

    addr = addr % 0x30;

    addr >>= 2;

    switch (addr) {

        case R_DMACR:

            /* Tailptr mode is always on.  */

            value |= DMACR_TAILPTR_MODE;

            /* Remember our previous reset state.  */

            value |= (s->regs[addr] & DMACR_RESET);

            s->regs[addr] = value;

            if (value & DMACR_RESET) {

                stream_reset(s);

            }

            if ((value & 1) && !stream_resetting(s)) {

                /* Start processing.  */

                s->regs[R_DMASR] &= ~(DMASR_HALTED | DMASR_IDLE);

            }

            stream_reload_complete_cnt(s);

            break;

        case R_DMASR:

            /* Mask away write to clear irq lines.  */

            value &= ~(value & DMASR_IRQ_MASK);

            s->regs[addr] = value;

            break;

        case R_TAILDESC:

            s->regs[addr] = value;

            s->regs[R_DMASR] &= ~DMASR_IDLE; /* Not idle.  */

            if (!sid) {

                stream_process_mem2s(s, d->tx_dev);

            }

            break;

        default:

            D(qemu_log("%s: ch=%d addr=" TARGET_FMT_plx " v=%x\n",

                  __func__, sid, addr * 4, (unsigned)value));

            s->regs[addr] = value;

            break;

    }

    if (sid == 1 && d->notify) {

        d->notify(d->notify_opaque);

        d->notify = NULL;

    }

    stream_update_irq(s);

}


static uint32_t bmdma_readb(void *opaque, uint32_t addr)

{

    BMDMAState *bm = opaque;

    PCIIDEState *pci_dev = pci_from_bm(bm);

    uint32_t val;

    switch(addr & 3) {

    case 0:

        val = bm->cmd;

        break;

    case 1:

        val = pci_dev->dev.config[MRDMODE];

        break;

    case 2:

        val = bm->status;

        break;

    case 3:

        if (bm->unit == 0) {

            val = pci_dev->dev.config[UDIDETCR0];

        } else {

            val = pci_dev->dev.config[UDIDETCR1];

        }

        break;

    default:

        val = 0xff;

        break;

    }

#ifdef DEBUG_IDE

    printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);

#endif

    return val;

}


query_params_append (struct QueryParams *ps,

               const char *name, const char *value)

{

    if (ps->n >= ps->alloc) {

        ps->p = g_renew(QueryParam, ps->p, ps->alloc * 2);

        ps->alloc *= 2;

    }

    ps->p[ps->n].name = g_strdup(name);

    ps->p[ps->n].value = value ? g_strdup(value) : NULL;

    ps->p[ps->n].ignore = 0;

    ps->n++;

    return 0;

}


static void nbd_parse_filename(const char *filename, QDict *options,

                               Error **errp)

{

    char *file;

    char *export_name;

    const char *host_spec;

    const char *unixpath;

    if (nbd_has_filename_options_conflict(options, errp)) {

        return;

    }

    if (strstr(filename, "://")) {

        int ret = nbd_parse_uri(filename, options);

        if (ret < 0) {

            error_setg(errp, "No valid URL specified");

        }

        return;

    }

    file = g_strdup(filename);

    export_name = strstr(file, EN_OPTSTR);

    if (export_name) {

        if (export_name[strlen(EN_OPTSTR)] == 0) {

            goto out;

        }

        export_name[0] = 0; /* truncate 'file' */

        export_name += strlen(EN_OPTSTR);

        qdict_put(options, "export", qstring_from_str(export_name));

    }

    /* extract the host_spec - fail if it's not nbd:... */

    if (!strstart(file, "nbd:", &host_spec)) {

        error_setg(errp, "File name string for NBD must start with 'nbd:'");

        goto out;

    }

    if (!*host_spec) {

        goto out;

    }

    /* are we a UNIX or TCP socket? */

    if (strstart(host_spec, "unix:", &unixpath)) {

        qdict_put(options, "server.type", qstring_from_str("unix"));

        qdict_put(options, "server.data.path", qstring_from_str(unixpath));

    } else {

        InetSocketAddress *addr = NULL;

        addr = inet_parse(host_spec, errp);

        if (!addr) {

            goto out;

        }

        qdict_put(options, "server.type", qstring_from_str("inet"));

        qdict_put(options, "server.data.host", qstring_from_str(addr->host));

        qdict_put(options, "server.data.port", qstring_from_str(addr->port));

        qapi_free_InetSocketAddress(addr);

    }

out:

    g_free(file);

}


static inline int range_get_symbol(APEContext * ctx,

                                   const uint32_t counts[],

                                   const uint16_t counts_diff[])

{

    int symbol, cf;

    cf = range_decode_culshift(ctx, 16);

    /* figure out the symbol inefficiently; a binary search would be much better */

    for (symbol = 0; counts[symbol + 1] <= cf; symbol++);

    range_decode_update(ctx, counts_diff[symbol], counts[symbol]);


static TCGv new_tmp(void)

{

    TCGv tmp;

    if (num_temps == MAX_TEMPS)

        abort();

    if (GET_TCGV(temps[num_temps]))

      return temps[num_temps++];

    tmp = tcg_temp_new(TCG_TYPE_I32);

    temps[num_temps++] = tmp;

    return tmp;

}


void cpu_mips_store_status(CPUMIPSState *env, target_ulong val)

{

    uint32_t mask = env->CP0_Status_rw_bitmask;

    target_ulong old = env->CP0_Status;

    if (env->insn_flags & ISA_MIPS32R6) {

        bool has_supervisor = extract32(mask, CP0St_KSU, 2) == 0x3;

#if defined(TARGET_MIPS64)

        uint32_t ksux = (1 << CP0St_KX) & val;

        ksux |= (ksux >> 1) & val; /* KX = 0 forces SX to be 0 */

        ksux |= (ksux >> 1) & val; /* SX = 0 forces UX to be 0 */

        val = (val & ~(7 << CP0St_UX)) | ksux;

#endif

        if (has_supervisor && extract32(val, CP0St_KSU, 2) == 0x3) {

            mask &= ~(3 << CP0St_KSU);

        }

        mask &= ~(((1 << CP0St_SR) | (1 << CP0St_NMI)) & val);

    }

    env->CP0_Status = (old & ~mask) | (val & mask);

#if defined(TARGET_MIPS64)

    if ((env->CP0_Status ^ old) & (old & (7 << CP0St_UX))) {

        /* Access to at least one of the 64-bit segments has been disabled */

        cpu_mips_tlb_flush(env);

    }

#endif

    if (env->CP0_Config3 & (1 << CP0C3_MT)) {

        sync_c0_status(env, env, env->current_tc);

    } else {

        compute_hflags(env);

    }

}


static SocketAddress *nbd_config(BDRVNBDState *s, QDict *options, char **export,

                                 Error **errp)

{

    SocketAddress *saddr;

    if (qdict_haskey(options, "path") == qdict_haskey(options, "host")) {

        if (qdict_haskey(options, "path")) {

            error_setg(errp, "path and host may not be used at the same time.");

        } else {

            error_setg(errp, "one of path and host must be specified.");

        }

        return NULL;

    }

    saddr = g_new0(SocketAddress, 1);

    if (qdict_haskey(options, "path")) {

        UnixSocketAddress *q_unix;

        saddr->type = SOCKET_ADDRESS_KIND_UNIX;

        q_unix = saddr->u.q_unix = g_new0(UnixSocketAddress, 1);

        q_unix->path = g_strdup(qdict_get_str(options, "path"));

        qdict_del(options, "path");

    } else {

        InetSocketAddress *inet;

        saddr->type = SOCKET_ADDRESS_KIND_INET;

        inet = saddr->u.inet = g_new0(InetSocketAddress, 1);

        inet->host = g_strdup(qdict_get_str(options, "host"));

        if (!qdict_get_try_str(options, "port")) {

            inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);

        } else {

            inet->port = g_strdup(qdict_get_str(options, "port"));

        }

        qdict_del(options, "host");

        qdict_del(options, "port");

    }

    s->client.is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;

    *export = g_strdup(qdict_get_try_str(options, "export"));

    if (*export) {

        qdict_del(options, "export");

    }

    return saddr;

}


static void gen_jmpcc(DisasContext *s, int cond, int l1)

{

    TCGv tmp;

    /* TODO: Optimize compare/branch pairs rather than always flushing

       flag state to CC_OP_FLAGS.  */

    gen_flush_flags(s);

    switch (cond) {

    case 0: /* T */

        tcg_gen_br(l1);

        break;

    case 1: /* F */

        break;

    case 2: /* HI (!C && !Z) */

        tmp = tcg_temp_new();

        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C | CCF_Z);

        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);

        break;

    case 3: /* LS (C || Z) */

        tmp = tcg_temp_new();

        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C | CCF_Z);

        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);

        break;

    case 4: /* CC (!C) */

        tmp = tcg_temp_new();

        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C);

        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);

        break;

    case 5: /* CS (C) */

        tmp = tcg_temp_new();

        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C);

        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);

        break;

    case 6: /* NE (!Z) */

        tmp = tcg_temp_new();

        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_Z);

        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);

        break;

    case 7: /* EQ (Z) */

        tmp = tcg_temp_new();

        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_Z);

        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);

        break;

    case 8: /* VC (!V) */

        tmp = tcg_temp_new();

        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_V);

        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);

        break;

    case 9: /* VS (V) */

        tmp = tcg_temp_new();

        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_V);

        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);

        break;

    case 10: /* PL (!N) */

        tmp = tcg_temp_new();

        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);

        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);

        break;

    case 11: /* MI (N) */

        tmp = tcg_temp_new();

        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);

        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);

        break;

    case 12: /* GE (!(N ^ V)) */

        tmp = tcg_temp_new();

        assert(CCF_V == (CCF_N >> 2));

        tcg_gen_shri_i32(tmp, QREG_CC_DEST, 2);

        tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);

        tcg_gen_andi_i32(tmp, tmp, CCF_V);

        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);

        break;

    case 13: /* LT (N ^ V) */

        tmp = tcg_temp_new();

        assert(CCF_V == (CCF_N >> 2));

        tcg_gen_shri_i32(tmp, QREG_CC_DEST, 2);

        tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);

        tcg_gen_andi_i32(tmp, tmp, CCF_V);

        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);

        break;

    case 14: /* GT (!(Z || (N ^ V))) */

        tmp = tcg_temp_new();

        assert(CCF_V == (CCF_N >> 2));

        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);

        tcg_gen_shri_i32(tmp, tmp, 2);

        tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);

        tcg_gen_andi_i32(tmp, tmp, CCF_V | CCF_Z);

        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);

        break;

    case 15: /* LE (Z || (N ^ V)) */

        tmp = tcg_temp_new();

        assert(CCF_V == (CCF_N >> 2));

        tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);

        tcg_gen_shri_i32(tmp, tmp, 2);

        tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);

        tcg_gen_andi_i32(tmp, tmp, CCF_V | CCF_Z);

        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);

        break;

    default:

        /* Should ever happen.  */

        abort();

    }

}


static void add_pollfd(AioHandler *node)

{

    if (npfd == nalloc) {

        if (nalloc == 0) {

            pollfds_cleanup_notifier.notify = pollfds_cleanup;

            qemu_thread_atexit_add(&pollfds_cleanup_notifier);

            nalloc = 8;

        } else {

            g_assert(nalloc <= INT_MAX);

            nalloc *= 2;

        }

        pollfds = g_renew(GPollFD, pollfds, nalloc);

        nodes = g_renew(AioHandler *, nodes, nalloc);

    }

    nodes[npfd] = node;

    pollfds[npfd] = (GPollFD) {

        .fd = node->pfd.fd,

        .events = node->pfd.events,

    };

    npfd++;

}


static void check_loopfilter()

{

    LOCAL_ALIGNED_32(uint8_t, base0, [32 + 16 * 16 * 2]);

    LOCAL_ALIGNED_32(uint8_t, base1, [32 + 16 * 16 * 2]);

    VP9DSPContext dsp;

    int dir, wd, wd2, bit_depth;

    static const char *const dir_name[2] = { "h", "v" };

    int E[2] = { 20, 28 }, I[2] = { 10, 16 }, H[2] = { 7, 11 }, F[2] = { 1, 1 };

    declare_func(void, uint8_t *dst, ptrdiff_t stride, int E, int I, int H);

    for (bit_depth = 8; bit_depth <= 12; bit_depth += 2) {

        ff_vp9dsp_init(&dsp, bit_depth, 0);

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

            uint8_t *buf0, *buf1;

            int midoff = (dir ? 8 * 8 : 8) * SIZEOF_PIXEL;

            int midoff_aligned = (dir ? 8 * 8 : 16) * SIZEOF_PIXEL;

            buf0 = base0 + midoff_aligned;

            buf1 = base1 + midoff_aligned;

            for (wd = 0; wd < 3; wd++) {

                // 4/8/16wd_8px

                if (check_func(dsp.loop_filter_8[wd][dir],

                               "vp9_loop_filter_%s_%d_8_%dbpp",

                               dir_name[dir], 4 << wd, bit_depth)) {

                    randomize_buffers(0, 0, 8);

                    memcpy(buf1 - midoff, buf0 - midoff,

                           16 * 8 * SIZEOF_PIXEL);

                    call_ref(buf0, 16 * SIZEOF_PIXEL >> dir, E[0], I[0], H[0]);

                    call_new(buf1, 16 * SIZEOF_PIXEL >> dir, E[0], I[0], H[0]);

                    if (memcmp(buf0 - midoff, buf1 - midoff, 16 * 8 * SIZEOF_PIXEL))

                        fail();

                    bench_new(buf1, 16 * SIZEOF_PIXEL >> dir, E[0], I[0], H[0]);

                }

            }

            midoff = (dir ? 16 * 8 : 8) * SIZEOF_PIXEL;

            midoff_aligned = (dir ? 16 * 8 : 16) * SIZEOF_PIXEL;

            // 16wd_16px loopfilter

            if (check_func(dsp.loop_filter_16[dir],

                           "vp9_loop_filter_%s_16_16_%dbpp",

                           dir_name[dir], bit_depth)) {

                randomize_buffers(0, 0, 16);

                randomize_buffers(0, 8, 16);

                memcpy(buf1 - midoff, buf0 - midoff, 16 * 16 * SIZEOF_PIXEL);

                call_ref(buf0, 16 * SIZEOF_PIXEL, E[0], I[0], H[0]);

                call_new(buf1, 16 * SIZEOF_PIXEL, E[0], I[0], H[0]);

                if (memcmp(buf0 - midoff, buf1 - midoff, 16 * 16 * SIZEOF_PIXEL))

                    fail();

                bench_new(buf1, 16 * SIZEOF_PIXEL, E[0], I[0], H[0]);

            }

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

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

                    // mix2 loopfilter

                    if (check_func(dsp.loop_filter_mix2[wd][wd2][dir],

                                   "vp9_loop_filter_mix2_%s_%d%d_16_%dbpp",

                                   dir_name[dir], 4 << wd, 4 << wd2, bit_depth)) {

                        randomize_buffers(0, 0, 16);

                        randomize_buffers(1, 8, 16);

                        memcpy(buf1 - midoff, buf0 - midoff, 16 * 16 * SIZEOF_PIXEL);

#define M(a) ((a[1] << 8) | a[0])

                        call_ref(buf0, 16 * SIZEOF_PIXEL, M(E), M(I), M(H));

                        call_new(buf1, 16 * SIZEOF_PIXEL, M(E), M(I), M(H));

                        if (memcmp(buf0 - midoff, buf1 - midoff, 16 * 16 * SIZEOF_PIXEL))

                            fail();

                        bench_new(buf1, 16 * SIZEOF_PIXEL, M(E), M(I), M(H));

#undef M

                    }

                }

            }

        }

    }

    report("loopfilter");

}


static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,

                                   const char *filename, int flags,

                                   const AVIOInterruptCB *int_cb)

{

    URLContext *uc;

    int err;

#if CONFIG_NETWORK

    if (up->flags & URL_PROTOCOL_FLAG_NETWORK && !ff_network_init())

        return AVERROR(EIO);

#endif

    if ((flags & AVIO_FLAG_READ) && !up->url_read) {

        av_log(NULL, AV_LOG_ERROR,

               "Impossible to open the '%s' protocol for reading\n", up->name);

        return AVERROR(EIO);

    if ((flags & AVIO_FLAG_WRITE) && !up->url_write) {

        av_log(NULL, AV_LOG_ERROR,

               "Impossible to open the '%s' protocol for writing\n", up->name);

        return AVERROR(EIO);

    uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);

    if (!uc) {

    uc->av_class = &ffurl_context_class;

    uc->filename = (char *) &uc[1];

    strcpy(uc->filename, filename);

    uc->prot = up;

    uc->flags = flags;

    uc->is_streamed = 0; /* default = not streamed */

    uc->max_packet_size = 0; /* default: stream file */

    if (up->priv_data_size) {

        uc->priv_data = av_mallocz(up->priv_data_size);

        if (up->priv_data_class) {

            int proto_len= strlen(up->name);

            char *start = strchr(uc->filename, ',');

            *(const AVClass**)uc->priv_data = up->priv_data_class;

            av_opt_set_defaults(uc->priv_data);

            if(!strncmp(up->name, uc->filename, proto_len) && uc->filename + proto_len == start){

                int ret= 0;

                char *p= start;

                char sep= *++p;

                char *key, *val;

                p++;

                while(ret >= 0 && (key= strchr(p, sep)) && p<key && (val = strchr(key+1, sep))){

                    *val= *key= 0;

                    ret= av_opt_set(uc->priv_data, p, key+1, 0);

                    if (ret == AVERROR_OPTION_NOT_FOUND)

                        av_log(uc, AV_LOG_ERROR, "Key '%s' not found.\n", p);

                    *val= *key= sep;

                    p= val+1;

                if(ret<0 || p!=key){

                    av_log(uc, AV_LOG_ERROR, "Error parsing options string %s\n", start);

                    av_freep(&uc->priv_data);

                    av_freep(&uc);

                    err = AVERROR(EINVAL);

                memmove(start, key+1, strlen(key));

    if (int_cb)

        uc->interrupt_callback = *int_cb;

    *puc = uc;

    return 0;

 fail:

    *puc = NULL;

    if (uc)

        av_freep(&uc->priv_data);

    av_freep(&uc);

#if CONFIG_NETWORK

    if (up->flags & URL_PROTOCOL_FLAG_NETWORK)

        ff_network_close();

#endif

    return err;


static int flashsv_decode_frame(AVCodecContext *avctx,

                                    void *data, int *data_size,

                                    AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    FlashSVContext *s = avctx->priv_data;

    int h_blocks, v_blocks, h_part, v_part, i, j;

    GetBitContext gb;

    /* no supplementary picture */

    if (buf_size == 0)

        return 0;

    init_get_bits(&gb, buf, buf_size * 8);

    /* start to parse the bitstream */

    s->block_width = 16* (get_bits(&gb, 4)+1);

    s->image_width =     get_bits(&gb,12);

    s->block_height= 16* (get_bits(&gb, 4)+1);

    s->image_height=     get_bits(&gb,12);

    /* calculate amount of blocks and the size of the border blocks */

    h_blocks = s->image_width / s->block_width;

    h_part = s->image_width % s->block_width;

    v_blocks = s->image_height / s->block_height;

    v_part = s->image_height % s->block_height;

    /* the block size could change between frames, make sure the buffer

     * is large enough, if not, get a larger one */

    if(s->block_size < s->block_width*s->block_height) {

        if (s->tmpblock != NULL)

            av_free(s->tmpblock);

        if ((s->tmpblock = av_malloc(3*s->block_width*s->block_height)) == NULL) {

            av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");

        }

    }

    s->block_size = s->block_width*s->block_height;

    /* init the image size once */

    if((avctx->width==0) && (avctx->height==0)){

        avctx->width = s->image_width;

        avctx->height = s->image_height;

    }

    /* check for changes of image width and image height */

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

        av_log(avctx, AV_LOG_ERROR, "Frame width or height differs from first frames!\n");

        av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d  vs  ch = %d, cv = %d\n",avctx->height,

        avctx->width,s->image_height,s->image_width);

    }

    av_log(avctx, AV_LOG_DEBUG, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",

        s->image_width, s->image_height, s->block_width, s->block_height,

        h_blocks, v_blocks, h_part, v_part);

    s->frame.reference = 1;

    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;

    if(avctx->reget_buffer(avctx, &s->frame) < 0){

      av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");

    }

    /* loop over all block columns */

    for (j = 0; j < v_blocks + (v_part?1:0); j++)

    {

        int hp = j*s->block_height; // horiz position in frame

        int hs = (j<v_blocks)?s->block_height:v_part; // size of block

        /* loop over all block rows */

        for (i = 0; i < h_blocks + (h_part?1:0); i++)

        {

            int wp = i*s->block_width; // vert position in frame

            int ws = (i<h_blocks)?s->block_width:h_part; // size of block

            /* get the size of the compressed zlib chunk */

            int size = get_bits(&gb, 16);

            if (8 * size > get_bits_left(&gb)) {

                avctx->release_buffer(avctx, &s->frame);

                s->frame.data[0] = NULL;

            }

            if (size == 0) {

                /* no change, don't do anything */

            } else {

                /* decompress block */

                int ret = inflateReset(&(s->zstream));

                if (ret != Z_OK)

                {

                    av_log(avctx, AV_LOG_ERROR, "error in decompression (reset) of block %dx%d\n", i, j);

                    /* return -1; */

                }

                s->zstream.next_in = buf+(get_bits_count(&gb)/8);

                s->zstream.avail_in = size;

                s->zstream.next_out = s->tmpblock;

                s->zstream.avail_out = s->block_size*3;

                ret = inflate(&(s->zstream), Z_FINISH);

                if (ret == Z_DATA_ERROR)

                {

                    av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");

                    inflateSync(&(s->zstream));

                    ret = inflate(&(s->zstream), Z_FINISH);

                }

                if ((ret != Z_OK) && (ret != Z_STREAM_END))

                {

                    av_log(avctx, AV_LOG_ERROR, "error in decompression of block %dx%d: %d\n", i, j, ret);

                    /* return -1; */

                }

                copy_region(s->tmpblock, s->frame.data[0], s->image_height-(hp+hs+1), wp, hs, ws, s->frame.linesize[0]);

                skip_bits_long(&gb, 8*size);   /* skip the consumed bits */

            }

        }

    }

    *data_size = sizeof(AVFrame);

    *(AVFrame*)data = s->frame;

    if ((get_bits_count(&gb)/8) != buf_size)

        av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",

            buf_size, (get_bits_count(&gb)/8));

    /* report that the buffer was completely consumed */

    return buf_size;

}


static void xenfb_handle_events(struct XenFB *xenfb)

{

    uint32_t prod, cons;

    struct xenfb_page *page = xenfb->c.page;

    prod = page->out_prod;

    if (prod == page->out_cons)

	return;

    xen_rmb();		/* ensure we see ring contents up to prod */

    for (cons = page->out_cons; cons != prod; cons++) {

	union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);

	int x, y, w, h;

	switch (event->type) {

	case XENFB_TYPE_UPDATE:

	    if (xenfb->up_count == UP_QUEUE)

		xenfb->up_fullscreen = 1;

	    if (xenfb->up_fullscreen)

		break;

	    x = MAX(event->update.x, 0);

	    y = MAX(event->update.y, 0);

	    w = MIN(event->update.width, xenfb->width - x);

	    h = MIN(event->update.height, xenfb->height - y);

	    if (w < 0 || h < 0) {

                xen_be_printf(&xenfb->c.xendev, 1, "bogus update ignored\n");

		break;

	    }

	    if (x != event->update.x ||

                y != event->update.y ||

		w != event->update.width ||

		h != event->update.height) {

                xen_be_printf(&xenfb->c.xendev, 1, "bogus update clipped\n");

	    }

	    if (w == xenfb->width && h > xenfb->height / 2) {

		/* scroll detector: updated more than 50% of the lines,

		 * don't bother keeping track of the rectangles then */

		xenfb->up_fullscreen = 1;

	    } else {

		xenfb->up_rects[xenfb->up_count].x = x;

		xenfb->up_rects[xenfb->up_count].y = y;

		xenfb->up_rects[xenfb->up_count].w = w;

		xenfb->up_rects[xenfb->up_count].h = h;

		xenfb->up_count++;

	    }

	    break;

#ifdef XENFB_TYPE_RESIZE

	case XENFB_TYPE_RESIZE:

	    if (xenfb_configure_fb(xenfb, xenfb->fb_len,

				   event->resize.width,

				   event->resize.height,

				   event->resize.depth,

				   xenfb->fb_len,

				   event->resize.offset,

				   event->resize.stride) < 0)

		break;

	    xenfb_invalidate(xenfb);

	    break;

#endif

	}

    }

    xen_mb();		/* ensure we're done with ring contents */

    page->out_cons = cons;

}


static int find_video_stream_info(AVFormatContext *fmt_ctx, int decode)
{
    int ret = 0;
    int i, done = 0;
    AVPacket pkt;
    av_init_packet(&pkt);
    while (!done) {
        AVCodecContext *codec_ctx = NULL;
        AVStream *st;
        if ((ret = av_read_frame(fmt_ctx, &pkt)) < 0) {
            av_log(fmt_ctx, AV_LOG_ERROR, "Failed to read frame\n");
            goto end;
        st = fmt_ctx->streams[pkt.stream_index];
        codec_ctx = st->codec;
        /* Writing to AVStream.codec_info_nb_frames must not be done by
         * user applications. It is done here for testing purposing as
         * find_video_stream_info tries to mimic avformat_find_stream_info
         * which writes to this field.
         * */
        if (codec_ctx->codec_type != AVMEDIA_TYPE_VIDEO ||
            st->codec_info_nb_frames++ > 0) {
            av_packet_unref(&pkt);
            continue;
        ret = try_decode_video_frame(codec_ctx, &pkt, decode);
        if (ret < 0) {
            av_log(fmt_ctx, AV_LOG_ERROR, "Failed to decode video frame\n");
            goto end;
        av_packet_unref(&pkt);
        /* check if all video streams have demuxed a packet */
        done = 1;
            st = fmt_ctx->streams[i];
            codec_ctx = st->codec;
            if (codec_ctx->codec_type != AVMEDIA_TYPE_VIDEO)
                continue;
            done &= st->codec_info_nb_frames > 0;
end:
    av_packet_unref(&pkt);
    return ret < 0;


static int vdpau_mpeg4_start_frame(AVCodecContext *avctx,

                                   const uint8_t *buffer, uint32_t size)

{

    Mpeg4DecContext *ctx = avctx->priv_data;

    MpegEncContext * const s = &ctx->m;

    Picture *pic             = s->current_picture_ptr;

    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;

    VdpPictureInfoMPEG4Part2 *info = &pic_ctx->info.mpeg4;

    VdpVideoSurface ref;

    int i;

    /* fill VdpPictureInfoMPEG4Part2 struct */

    info->forward_reference  = VDP_INVALID_HANDLE;

    info->backward_reference = VDP_INVALID_HANDLE;

    info->vop_coding_type    = 0;

    switch (s->pict_type) {

    case AV_PICTURE_TYPE_B:

        ref = ff_vdpau_get_surface_id(&s->next_picture.f);

        assert(ref != VDP_INVALID_HANDLE);

        info->backward_reference = ref;

        info->vop_coding_type    = 2;

        /* fall-through */

    case AV_PICTURE_TYPE_P:

        ref = ff_vdpau_get_surface_id(&s->last_picture.f);

        assert(ref != VDP_INVALID_HANDLE);

        info->forward_reference  = ref;

    }

    info->trd[0]                            = s->pp_time;

    info->trb[0]                            = s->pb_time;

    info->trd[1]                            = s->pp_field_time >> 1;

    info->trb[1]                            = s->pb_field_time >> 1;

    info->vop_time_increment_resolution     = s->avctx->time_base.den;

    info->vop_fcode_forward                 = s->f_code;

    info->vop_fcode_backward                = s->b_code;

    info->resync_marker_disable             = !ctx->resync_marker;

    info->interlaced                        = !s->progressive_sequence;

    info->quant_type                        = s->mpeg_quant;

    info->quarter_sample                    = s->quarter_sample;

    info->short_video_header                = avctx->codec->id == AV_CODEC_ID_H263;

    info->rounding_control                  = s->no_rounding;

    info->alternate_vertical_scan_flag      = s->alternate_scan;

    info->top_field_first                   = s->top_field_first;

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

        info->intra_quantizer_matrix[i]     = s->intra_matrix[i];

        info->non_intra_quantizer_matrix[i] = s->inter_matrix[i];

    }

    ff_vdpau_common_start_frame(pic_ctx, buffer, size);

    return ff_vdpau_add_buffer(pic_ctx, buffer, size);

}


static void calculate_geometry(int64_t total_sectors, uint16_t* cyls,

    uint8_t* heads, uint8_t* secs_per_cyl)

{

    uint32_t cyls_times_heads;

    if (total_sectors > 65535 * 16 * 255)

        total_sectors = 65535 * 16 * 255;

    if (total_sectors > 65535 * 16 * 63) {

        *secs_per_cyl = 255;

        *heads = 16;

        cyls_times_heads = total_sectors / *secs_per_cyl;

    } else {

        *secs_per_cyl = 17;

        cyls_times_heads = total_sectors / *secs_per_cyl;

        *heads = (cyls_times_heads + 1023) / 1024;

        if (*heads < 4)

            *heads = 4;

        if (cyls_times_heads >= (*heads * 1024) || *heads > 16) {

            *secs_per_cyl = 31;

            *heads = 16;

            cyls_times_heads = total_sectors / *secs_per_cyl;

        }

        if (cyls_times_heads >= (*heads * 1024)) {

            *secs_per_cyl = 63;

            *heads = 16;

            cyls_times_heads = total_sectors / *secs_per_cyl;

        }

    }

    // Note: Rounding up deviates from the Virtual PC behaviour

    // However, we need this to avoid truncating images in qemu-img convert

    *cyls = (cyls_times_heads + *heads - 1) / *heads;

}


static void h264_v_loop_filter_chroma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0)

{

    h264_loop_filter_chroma_c(pix, stride, 1, alpha, beta, tc0);

}


static int within_hwc_y_range(SM501State *state, int y, int crt)

{

    int hwc_y = get_hwc_y(state, crt);

    return (hwc_y <= y && y < hwc_y + SM501_HWC_HEIGHT);

}


static inline void gen_evmwumi(DisasContext *ctx)

{

    TCGv_i64 t0, t1;

    if (unlikely(!ctx->spe_enabled)) {

        gen_exception(ctx, POWERPC_EXCP_APU);

        return;

    }

    t0 = tcg_temp_new_i64();

    t1 = tcg_temp_new_i64();

    /* t0 := rA; t1 := rB */

#if defined(TARGET_PPC64)

    tcg_gen_ext32u_tl(t0, cpu_gpr[rA(ctx->opcode)]);

    tcg_gen_ext32u_tl(t1, cpu_gpr[rB(ctx->opcode)]);

#else

    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);

    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);

#endif

    tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */

    gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */

    tcg_temp_free_i64(t0);

    tcg_temp_free_i64(t1);

}


static int nvdec_vp9_end_frame(AVCodecContext *avctx)

{

    NVDECContext *ctx = avctx->internal->hwaccel_priv_data;

    int ret = ff_nvdec_end_frame(avctx);

    ctx->bitstream = NULL;

    return ret;

}


SwsVector *sws_allocVec(int length)

{

    SwsVector *vec = av_malloc(sizeof(SwsVector));

    if (!vec)

        return NULL;

    vec->length = length;

    vec->coeff  = av_malloc(sizeof(double) * length);

    if (!vec->coeff)

        av_freep(&vec);

    return vec;

}


static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,

                           uint64_t off, uint32_t max_count)

{

    ssize_t err;

    size_t offset = 7;

    int read_count;

    int64_t xattr_len;

    V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);

    VirtQueueElement *elem = &v->elems[pdu->idx];

    xattr_len = fidp->fs.xattr.len;

    read_count = xattr_len - off;

    if (read_count > max_count) {

        read_count = max_count;

    } else if (read_count < 0) {

        /*

         * read beyond XATTR value

         */

        read_count = 0;

    }

    err = pdu_marshal(pdu, offset, "d", read_count);

    if (err < 0) {

        return err;

    }

    offset += err;

    err = v9fs_pack(elem->in_sg, elem->in_num, offset,

                    ((char *)fidp->fs.xattr.value) + off,

                    read_count);

    if (err < 0) {

        return err;

    }

    offset += err;

    return offset;

}


static void virtio_blk_dma_restart_cb(void *opaque, int running, int reason)

{

    VirtIOBlock *s = opaque;

    VirtIOBlockReq *req = s->rq;

    if (!running)

        return;

    s->rq = NULL;

    while (req) {

        virtio_blk_handle_write(req);

        req = req->next;

    }

}


static void pic_ioport_write(void *opaque, target_phys_addr_t addr64,

                             uint64_t val64, unsigned size)

{

    PICCommonState *s = opaque;

    uint32_t addr = addr64;

    uint32_t val = val64;

    int priority, cmd, irq;

    DPRINTF("write: addr=0x%02x val=0x%02x\n", addr, val);

    if (addr == 0) {

        if (val & 0x10) {

            pic_init_reset(s);

            s->init_state = 1;

            s->init4 = val & 1;

            s->single_mode = val & 2;

            if (val & 0x08) {

                hw_error("level sensitive irq not supported");

            }

        } else if (val & 0x08) {

            if (val & 0x04) {

                s->poll = 1;

            }

            if (val & 0x02) {

                s->read_reg_select = val & 1;

            }

            if (val & 0x40) {

                s->special_mask = (val >> 5) & 1;

            }

        } else {

            cmd = val >> 5;

            switch (cmd) {

            case 0:

            case 4:

                s->rotate_on_auto_eoi = cmd >> 2;

                break;

            case 1: /* end of interrupt */

            case 5:

                priority = get_priority(s, s->isr);

                if (priority != 8) {

                    irq = (priority + s->priority_add) & 7;

                    s->isr &= ~(1 << irq);

                    if (cmd == 5) {

                        s->priority_add = (irq + 1) & 7;

                    }

                    pic_update_irq(s);

                }

                break;

            case 3:

                irq = val & 7;

                s->isr &= ~(1 << irq);

                pic_update_irq(s);

                break;

            case 6:

                s->priority_add = (val + 1) & 7;

                pic_update_irq(s);

                break;

            case 7:

                irq = val & 7;

                s->isr &= ~(1 << irq);

                s->priority_add = (irq + 1) & 7;

                pic_update_irq(s);

                break;

            default:

                /* no operation */

                break;

            }

        }

    } else {

        switch (s->init_state) {

        case 0:

            /* normal mode */

            s->imr = val;

            pic_update_irq(s);

            break;

        case 1:

            s->irq_base = val & 0xf8;

            s->init_state = s->single_mode ? (s->init4 ? 3 : 0) : 2;

            break;

        case 2:

            if (s->init4) {

                s->init_state = 3;

            } else {

                s->init_state = 0;

            }

            break;

        case 3:

            s->special_fully_nested_mode = (val >> 4) & 1;

            s->auto_eoi = (val >> 1) & 1;

            s->init_state = 0;

            break;

        }

    }

}


void ff_af_queue_log_state(AudioFrameQueue *afq)

{

    AudioFrame *f;

    av_log(afq->avctx, AV_LOG_DEBUG, "remaining delay   = %d\n",

           afq->remaining_delay);

    av_log(afq->avctx, AV_LOG_DEBUG, "remaining samples = %d\n",

           afq->remaining_samples);

    av_log(afq->avctx, AV_LOG_DEBUG, "frames:\n");

    f = afq->frame_queue;

    while (f) {

        av_log(afq->avctx, AV_LOG_DEBUG, "  [ pts=%9"PRId64" duration=%d ]\n",

               f->pts, f->duration);

        f = f->next;

    }

}


static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
                            int cmd, abi_long arg)
{
    void *argptr;
    struct dm_ioctl *host_dm;
    abi_long guest_data;
    uint32_t guest_data_size;
    int target_size;
    const argtype *arg_type = ie->arg_type;
    abi_long ret;
    void *big_buf = NULL;
    char *host_data;
    arg_type++;
    target_size = thunk_type_size(arg_type, 0);
    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
    unlock_user(argptr, arg, 0);
    /* buf_temp is too small, so fetch things into a bigger buffer */
    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
    memcpy(big_buf, buf_temp, target_size);
    buf_temp = big_buf;
    host_dm = big_buf;
    guest_data = arg + host_dm->data_start;
    if ((guest_data - arg) < 0) {
        ret = -EINVAL;
    guest_data_size = host_dm->data_size - host_dm->data_start;
    host_data = (char*)host_dm + host_dm->data_start;
    argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
    switch (ie->host_cmd) {
    case DM_REMOVE_ALL:
    case DM_LIST_DEVICES:
    case DM_DEV_CREATE:
    case DM_DEV_REMOVE:
    case DM_DEV_SUSPEND:
    case DM_DEV_STATUS:
    case DM_DEV_WAIT:
    case DM_TABLE_STATUS:
    case DM_TABLE_CLEAR:
    case DM_TABLE_DEPS:
    case DM_LIST_VERSIONS:
        /* no input data */
        break;
    case DM_DEV_RENAME:
    case DM_DEV_SET_GEOMETRY:
        /* data contains only strings */
        memcpy(host_data, argptr, guest_data_size);
        break;
    case DM_TARGET_MSG:
        memcpy(host_data, argptr, guest_data_size);
        *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
        break;
    case DM_TABLE_LOAD:
    {
        void *gspec = argptr;
        void *cur_data = host_data;
        const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
        int spec_size = thunk_type_size(arg_type, 0);
        int i;
        for (i = 0; i < host_dm->target_count; i++) {
            struct dm_target_spec *spec = cur_data;
            uint32_t next;
            int slen;
            thunk_convert(spec, gspec, arg_type, THUNK_HOST);
            slen = strlen((char*)gspec + spec_size) + 1;
            next = spec->next;
            spec->next = sizeof(*spec) + slen;
            strcpy((char*)&spec[1], gspec + spec_size);
            gspec += next;
            cur_data += spec->next;
        break;
    default:
        ret = -TARGET_EINVAL;
        unlock_user(argptr, guest_data, 0);
    unlock_user(argptr, guest_data, 0);
    ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
    if (!is_error(ret)) {
        guest_data = arg + host_dm->data_start;
        guest_data_size = host_dm->data_size - host_dm->data_start;
        argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
        switch (ie->host_cmd) {
        case DM_REMOVE_ALL:
        case DM_DEV_CREATE:
        case DM_DEV_REMOVE:
        case DM_DEV_RENAME:
        case DM_DEV_SUSPEND:
        case DM_DEV_STATUS:
        case DM_TABLE_LOAD:
        case DM_TABLE_CLEAR:
        case DM_TARGET_MSG:
        case DM_DEV_SET_GEOMETRY:
            /* no return data */
            break;
        case DM_LIST_DEVICES:
        {
            struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
            uint32_t remaining_data = guest_data_size;
            void *cur_data = argptr;
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
            int nl_size = 12; /* can't use thunk_size due to alignment */
            while (1) {
                uint32_t next = nl->next;
                if (next) {
                    nl->next = nl_size + (strlen(nl->name) + 1);
                if (remaining_data < nl->next) {
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
                    break;
                thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
                strcpy(cur_data + nl_size, nl->name);
                cur_data += nl->next;
                remaining_data -= nl->next;
                if (!next) {
                    break;
                nl = (void*)nl + next;
            break;
        case DM_DEV_WAIT:
        case DM_TABLE_STATUS:
        {
            struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
            void *cur_data = argptr;
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
            int spec_size = thunk_type_size(arg_type, 0);
            int i;
            for (i = 0; i < host_dm->target_count; i++) {
                uint32_t next = spec->next;
                int slen = strlen((char*)&spec[1]) + 1;
                spec->next = (cur_data - argptr) + spec_size + slen;
                if (guest_data_size < spec->next) {
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
                    break;
                thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
                strcpy(cur_data + spec_size, (char*)&spec[1]);
                cur_data = argptr + spec->next;
                spec = (void*)host_dm + host_dm->data_start + next;
            break;
        case DM_TABLE_DEPS:
        {
            void *hdata = (void*)host_dm + host_dm->data_start;
            int count = *(uint32_t*)hdata;
            uint64_t *hdev = hdata + 8;
            uint64_t *gdev = argptr + 8;
            int i;
            *(uint32_t*)argptr = tswap32(count);
            for (i = 0; i < count; i++) {
                *gdev = tswap64(*hdev);
                gdev++;
                hdev++;
            break;
        case DM_LIST_VERSIONS:
        {
            struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
            uint32_t remaining_data = guest_data_size;
            void *cur_data = argptr;
            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
            int vers_size = thunk_type_size(arg_type, 0);
            while (1) {
                uint32_t next = vers->next;
                if (next) {
                    vers->next = vers_size + (strlen(vers->name) + 1);
                if (remaining_data < vers->next) {
                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
                    break;
                thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
                strcpy(cur_data + vers_size, vers->name);
                cur_data += vers->next;
                remaining_data -= vers->next;
                if (!next) {
                    break;
                vers = (void*)vers + next;
            break;
        default:
            unlock_user(argptr, guest_data, 0);
            ret = -TARGET_EINVAL;
        unlock_user(argptr, guest_data, guest_data_size);
        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
        thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
        unlock_user(argptr, arg, target_size);
out:
    g_free(big_buf);
    return ret;


static void arm1026_initfn(Object *obj)

{

    ARMCPU *cpu = ARM_CPU(obj);

    cpu->dtb_compatible = "arm,arm1026";

    set_feature(&cpu->env, ARM_FEATURE_V5);

    set_feature(&cpu->env, ARM_FEATURE_VFP);

    set_feature(&cpu->env, ARM_FEATURE_AUXCR);

    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);

    set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);

    cpu->midr = 0x4106a262;

    cpu->reset_fpsid = 0x410110a0;

    cpu->ctr = 0x1dd20d2;

    cpu->reset_sctlr = 0x00090078;

    cpu->reset_auxcr = 1;

    {

        /* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */

        ARMCPRegInfo ifar = {

            .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,

            .access = PL1_RW,

            .fieldoffset = offsetof(CPUARMState, cp15.ifar_ns),

            .resetvalue = 0

        };

        define_one_arm_cp_reg(cpu, &ifar);

    }

}


static void opt_frame_pad_bottom(const char *arg)

{

    frame_padbottom = atoi(arg);

    if (frame_padbottom < 0) {

        fprintf(stderr, "Incorrect bottom pad size\n");

        av_exit(1);

    }

}


static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,

                                      unsigned int size)

{

    MemHotplugState *mem_st = opaque;

    MemStatus *mdev;

    ACPIOSTInfo *info;

    DeviceState *dev = NULL;

    HotplugHandler *hotplug_ctrl = NULL;

    Error *local_err = NULL;

    if (!mem_st->dev_count) {

        return;

    }

    if (addr) {

        if (mem_st->selector >= mem_st->dev_count) {

            trace_mhp_acpi_invalid_slot_selected(mem_st->selector);

            return;

        }

    }

    switch (addr) {

    case 0x0: /* DIMM slot selector */

        mem_st->selector = data;

        trace_mhp_acpi_write_slot(mem_st->selector);

        break;

    case 0x4: /* _OST event  */

        mdev = &mem_st->devs[mem_st->selector];

        if (data == 1) {

            /* TODO: handle device insert OST event */

        } else if (data == 3) {

            /* TODO: handle device remove OST event */

        }

        mdev->ost_event = data;

        trace_mhp_acpi_write_ost_ev(mem_st->selector, mdev->ost_event);

        break;

    case 0x8: /* _OST status */

        mdev = &mem_st->devs[mem_st->selector];

        mdev->ost_status = data;

        trace_mhp_acpi_write_ost_status(mem_st->selector, mdev->ost_status);

        /* TODO: implement memory removal on guest signal */

        info = acpi_memory_device_status(mem_st->selector, mdev);

        qapi_event_send_acpi_device_ost(info, &error_abort);

        qapi_free_ACPIOSTInfo(info);

        break;

    case 0x14: /* set is_* fields  */

        mdev = &mem_st->devs[mem_st->selector];

        if (data & 2) { /* clear insert event */

            mdev->is_inserting  = false;

            trace_mhp_acpi_clear_insert_evt(mem_st->selector);

        } else if (data & 4) {

            mdev->is_removing = false;

            trace_mhp_acpi_clear_remove_evt(mem_st->selector);

        } else if (data & 8) {

            if (!mdev->is_enabled) {

                trace_mhp_acpi_ejecting_invalid_slot(mem_st->selector);

                break;

            }

            dev = DEVICE(mdev->dimm);

            hotplug_ctrl = qdev_get_hotplug_handler(dev);

            /* call pc-dimm unplug cb */

            hotplug_handler_unplug(hotplug_ctrl, dev, &local_err);

            if (local_err) {

                trace_mhp_acpi_pc_dimm_delete_failed(mem_st->selector);

                qapi_event_send_mem_unplug_error(dev->id,

                                                 error_get_pretty(local_err),

                                                 &error_abort);

                break;

            }

            trace_mhp_acpi_pc_dimm_deleted(mem_st->selector);

        }

        break;

    default:

        break;

    }

}


long do_rt_sigreturn(CPUState *env)

{

    fprintf(stderr, "do_rt_sigreturn: not implemented\n");

    return -TARGET_ENOSYS;

}


void vga_hw_screen_dump(const char *filename)

{

    TextConsole *previous_active_console;

    previous_active_console = active_console;

    active_console = consoles[0];

    /* There is currently no way of specifying which screen we want to dump,

       so always dump the first one.  */

    if (consoles[0] && consoles[0]->hw_screen_dump)

        consoles[0]->hw_screen_dump(consoles[0]->hw, filename);

    active_console = previous_active_console;

}


static int net_socket_udp_init(NetClientState *peer,

                                 const char *model,

                                 const char *name,

                                 const char *rhost,

                                 const char *lhost)

{

    NetSocketState *s;

    int fd, ret;

    struct sockaddr_in laddr, raddr;

    if (parse_host_port(&laddr, lhost) < 0) {

        return -1;

    }

    if (parse_host_port(&raddr, rhost) < 0) {

        return -1;

    }

    fd = qemu_socket(PF_INET, SOCK_DGRAM, 0);

    if (fd < 0) {

        perror("socket(PF_INET, SOCK_DGRAM)");

        return -1;

    }

    ret = socket_set_fast_reuse(fd);

    if (ret < 0) {

        closesocket(fd);

        return -1;

    }

    ret = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));

    if (ret < 0) {

        perror("bind");

        closesocket(fd);

        return -1;

    }

    qemu_set_nonblock(fd);

    s = net_socket_fd_init(peer, model, name, fd, 0);

    if (!s) {

        return -1;

    }

    s->dgram_dst = raddr;

    snprintf(s->nc.info_str, sizeof(s->nc.info_str),

             "socket: udp=%s:%d",

             inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port));

    return 0;

}


static void audio_init (PCIBus *pci_bus)

{

    struct soundhw *c;

    int audio_enabled = 0;

    for (c = soundhw; !audio_enabled && c->name; ++c) {

        audio_enabled = c->enabled;

    }

    if (audio_enabled) {

        AudioState *s;

        s = AUD_init ();

        if (s) {

            for (c = soundhw; c->name; ++c) {

                if (c->enabled)

                    c->init.init_pci (pci_bus, s);

            }

        }

    }

}


static int query_codec(enum CodecID id, int std_compliance)

{

    CodecMime *cm= ff_id3v2_mime_tags;

    while(cm->id != CODEC_ID_NONE) {

        if(id == cm->id)

            return MKTAG('A', 'P', 'I', 'C');

        cm++;

    }

    return -1;

}


DECLARE_LOOP_FILTER(mmxext)

DECLARE_LOOP_FILTER(sse2)

DECLARE_LOOP_FILTER(ssse3)

DECLARE_LOOP_FILTER(sse4)

#endif

#define VP8_LUMA_MC_FUNC(IDX, SIZE, OPT) \

    c->put_vp8_epel_pixels_tab[IDX][0][2] = ff_put_vp8_epel ## SIZE ## _h6_ ## OPT; \

    c->put_vp8_epel_pixels_tab[IDX][2][0] = ff_put_vp8_epel ## SIZE ## _v6_ ## OPT; \

    c->put_vp8_epel_pixels_tab[IDX][2][2] = ff_put_vp8_epel ## SIZE ## _h6v6_ ## OPT

#define VP8_MC_FUNC(IDX, SIZE, OPT) \

    c->put_vp8_epel_pixels_tab[IDX][0][1] = ff_put_vp8_epel ## SIZE ## _h4_ ## OPT; \

    c->put_vp8_epel_pixels_tab[IDX][1][0] = ff_put_vp8_epel ## SIZE ## _v4_ ## OPT; \

    c->put_vp8_epel_pixels_tab[IDX][1][1] = ff_put_vp8_epel ## SIZE ## _h4v4_ ## OPT; \

    c->put_vp8_epel_pixels_tab[IDX][1][2] = ff_put_vp8_epel ## SIZE ## _h6v4_ ## OPT; \

    c->put_vp8_epel_pixels_tab[IDX][2][1] = ff_put_vp8_epel ## SIZE ## _h4v6_ ## OPT; \

    VP8_LUMA_MC_FUNC(IDX, SIZE, OPT)

#define VP8_BILINEAR_MC_FUNC(IDX, SIZE, OPT) \

    c->put_vp8_bilinear_pixels_tab[IDX][0][1] = ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][0][2] = ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][1][0] = ff_put_vp8_bilinear ## SIZE ## _v_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][1][1] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][1][2] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][2][0] = ff_put_vp8_bilinear ## SIZE ## _v_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][2][1] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][2][2] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT

av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)

{

    mm_flags = mm_support();

#if HAVE_YASM

    if (mm_flags & FF_MM_MMX) {

        c->vp8_idct_dc_add    = ff_vp8_idct_dc_add_mmx;

        c->vp8_idct_dc_add4y  = ff_vp8_idct_dc_add4y_mmx;

        c->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmx;

        c->vp8_idct_add       = ff_vp8_idct_add_mmx;

        c->vp8_luma_dc_wht    = ff_vp8_luma_dc_wht_mmx;

        c->put_vp8_epel_pixels_tab[0][0][0]     =

        c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_mmx;

        c->put_vp8_epel_pixels_tab[1][0][0]     =

        c->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_mmx;

        c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmx;

        c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmx;

        c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_mmx;

        c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_mmx;

        c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmx;

        c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmx;

        c->vp8_v_loop_filter16y       = ff_vp8_v_loop_filter16y_mbedge_mmx;

        c->vp8_h_loop_filter16y       = ff_vp8_h_loop_filter16y_mbedge_mmx;

        c->vp8_v_loop_filter8uv       = ff_vp8_v_loop_filter8uv_mbedge_mmx;

        c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_mmx;

    }

    /* note that 4-tap width=16 functions are missing because w=16

     * is only used for luma, and luma is always a copy or sixtap. */

    if (mm_flags & FF_MM_MMX2) {

        VP8_LUMA_MC_FUNC(0, 16, mmxext);

        VP8_MC_FUNC(1, 8, mmxext);

        VP8_MC_FUNC(2, 4, mmxext);

        VP8_BILINEAR_MC_FUNC(0, 16, mmxext);

        VP8_BILINEAR_MC_FUNC(1, 8, mmxext);

        VP8_BILINEAR_MC_FUNC(2, 4, mmxext);

        c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmxext;

        c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmxext;

        c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_mmxext;

        c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_mmxext;

        c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmxext;

        c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmxext;

        c->vp8_v_loop_filter16y       = ff_vp8_v_loop_filter16y_mbedge_mmxext;

        c->vp8_h_loop_filter16y       = ff_vp8_h_loop_filter16y_mbedge_mmxext;

        c->vp8_v_loop_filter8uv       = ff_vp8_v_loop_filter8uv_mbedge_mmxext;

        c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_mmxext;

    }

    if (mm_flags & FF_MM_SSE) {

        c->vp8_idct_add                         = ff_vp8_idct_add_sse;

        c->put_vp8_epel_pixels_tab[0][0][0]     =

        c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_sse;

    }

    if (mm_flags & (FF_MM_SSE2|FF_MM_SSE2SLOW)) {

        VP8_LUMA_MC_FUNC(0, 16, sse2);

        VP8_MC_FUNC(1, 8, sse2);

        VP8_BILINEAR_MC_FUNC(0, 16, sse2);

        VP8_BILINEAR_MC_FUNC(1, 8, sse2);

        c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_sse2;

        c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse2;

        c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_sse2;

        c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_sse2;

        c->vp8_v_loop_filter16y       = ff_vp8_v_loop_filter16y_mbedge_sse2;

        c->vp8_v_loop_filter8uv       = ff_vp8_v_loop_filter8uv_mbedge_sse2;

    }

    if (mm_flags & FF_MM_SSE2) {

        c->vp8_idct_dc_add4y          = ff_vp8_idct_dc_add4y_sse2;

        c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_sse2;

        c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_sse2;

        c->vp8_h_loop_filter16y       = ff_vp8_h_loop_filter16y_mbedge_sse2;

        c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_sse2;

    }

    if (mm_flags & FF_MM_SSSE3) {

        VP8_LUMA_MC_FUNC(0, 16, ssse3);

        VP8_MC_FUNC(1, 8, ssse3);

        VP8_MC_FUNC(2, 4, ssse3);

        VP8_BILINEAR_MC_FUNC(0, 16, ssse3);

        VP8_BILINEAR_MC_FUNC(1, 8, ssse3);

        VP8_BILINEAR_MC_FUNC(2, 4, ssse3);

        c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_ssse3;

        c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_ssse3;

        c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_ssse3;

        c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_ssse3;

        c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_ssse3;

        c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_ssse3;

        c->vp8_v_loop_filter16y       = ff_vp8_v_loop_filter16y_mbedge_ssse3;

        c->vp8_h_loop_filter16y       = ff_vp8_h_loop_filter16y_mbedge_ssse3;

        c->vp8_v_loop_filter8uv       = ff_vp8_v_loop_filter8uv_mbedge_ssse3;

        c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_ssse3;

    }

    if (mm_flags & FF_MM_SSE4) {

        c->vp8_idct_dc_add                  = ff_vp8_idct_dc_add_sse4;

        c->vp8_h_loop_filter16y       = ff_vp8_h_loop_filter16y_mbedge_sse4;

        c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_sse4;

    }

#endif

}