static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,

                            PrdtEntry *prdt, int prdt_entries,

                            void(*post_exec)(QPCIDevice *dev, void *ide_base,

                                             uint64_t sector, int nb_sectors))

{

    QPCIDevice *dev;

    void *bmdma_base;

    void *ide_base;

    uintptr_t guest_prdt;

    size_t len;

    bool from_dev;

    uint8_t status;

    int flags;

    dev = get_pci_device(&bmdma_base, &ide_base);

    flags = cmd & ~0xff;

    cmd &= 0xff;

    switch (cmd) {

    case CMD_READ_DMA:

    case CMD_PACKET:

        /* Assuming we only test data reads w/ ATAPI, otherwise we need to know

         * the SCSI command being sent in the packet, too. */

        from_dev = true;

        break;

    case CMD_WRITE_DMA:

        from_dev = false;

        break;

    default:

        g_assert_not_reached();

    }

    if (flags & CMDF_NO_BM) {

        qpci_config_writew(dev, PCI_COMMAND,

                           PCI_COMMAND_IO | PCI_COMMAND_MEMORY);

    }

    /* Select device 0 */

    qpci_io_writeb(dev, ide_base + reg_device, 0 | LBA);

    /* Stop any running transfer, clear any pending interrupt */

    qpci_io_writeb(dev, bmdma_base + bmreg_cmd, 0);

    qpci_io_writeb(dev, bmdma_base + bmreg_status, BM_STS_INTR);

    /* Setup PRDT */

    len = sizeof(*prdt) * prdt_entries;

    guest_prdt = guest_alloc(guest_malloc, len);

    memwrite(guest_prdt, prdt, len);

    qpci_io_writel(dev, bmdma_base + bmreg_prdt, guest_prdt);

    /* ATA DMA command */

    if (cmd == CMD_PACKET) {

        /* Enables ATAPI DMA; otherwise PIO is attempted */

        qpci_io_writeb(dev, ide_base + reg_feature, 0x01);

    } else {

        qpci_io_writeb(dev, ide_base + reg_nsectors, nb_sectors);

        qpci_io_writeb(dev, ide_base + reg_lba_low,    sector & 0xff);

        qpci_io_writeb(dev, ide_base + reg_lba_middle, (sector >> 8) & 0xff);

        qpci_io_writeb(dev, ide_base + reg_lba_high,   (sector >> 16) & 0xff);

    }

    qpci_io_writeb(dev, ide_base + reg_command, cmd);

    if (post_exec) {

        post_exec(dev, ide_base, sector, nb_sectors);

    }

    /* Start DMA transfer */

    qpci_io_writeb(dev, bmdma_base + bmreg_cmd,

                   BM_CMD_START | (from_dev ? BM_CMD_WRITE : 0));

    if (flags & CMDF_ABORT) {

        qpci_io_writeb(dev, bmdma_base + bmreg_cmd, 0);

    }

    /* Wait for the DMA transfer to complete */

    do {

        status = qpci_io_readb(dev, bmdma_base + bmreg_status);

    } while ((status & (BM_STS_ACTIVE | BM_STS_INTR)) == BM_STS_ACTIVE);

    g_assert_cmpint(get_irq(IDE_PRIMARY_IRQ), ==, !!(status & BM_STS_INTR));

    /* Check IDE status code */

    assert_bit_set(qpci_io_readb(dev, ide_base + reg_status), DRDY);

    assert_bit_clear(qpci_io_readb(dev, ide_base + reg_status), BSY | DRQ);

    /* Reading the status register clears the IRQ */

    g_assert(!get_irq(IDE_PRIMARY_IRQ));

    /* Stop DMA transfer if still active */

    if (status & BM_STS_ACTIVE) {

        qpci_io_writeb(dev, bmdma_base + bmreg_cmd, 0);

    }

    free_pci_device(dev);

    return status;

}


static int mxf_read_close(AVFormatContext *s)

{

    MXFContext *mxf = s->priv_data;

    MXFIndexTableSegment *seg;

    int i;

    av_freep(&mxf->packages_refs);

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

        s->streams[i]->priv_data = NULL;

    for (i = 0; i < mxf->metadata_sets_count; i++) {

        switch (mxf->metadata_sets[i]->type) {

        case MultipleDescriptor:

            av_freep(&((MXFDescriptor *)mxf->metadata_sets[i])->sub_descriptors_refs);

            break;

        case Sequence:

            av_freep(&((MXFSequence *)mxf->metadata_sets[i])->structural_components_refs);

            break;

        case SourcePackage:

        case MaterialPackage:

            av_freep(&((MXFPackage *)mxf->metadata_sets[i])->tracks_refs);

            break;

        case IndexTableSegment:

            seg = (MXFIndexTableSegment *)mxf->metadata_sets[i];

            av_freep(&seg->temporal_offset_entries);

            av_freep(&seg->flag_entries);

            av_freep(&seg->stream_offset_entries);

            break;

        default:

            break;

        }

        av_freep(&mxf->metadata_sets[i]);

    }

    av_freep(&mxf->partitions);

    av_freep(&mxf->metadata_sets);

    av_freep(&mxf->aesc);

    av_freep(&mxf->local_tags);

    for (i = 0; i < mxf->nb_index_tables; i++) {

        av_freep(&mxf->index_tables[i].segments);

        av_freep(&mxf->index_tables[i].ptses);

        av_freep(&mxf->index_tables[i].fake_index);

    }

    av_freep(&mxf->index_tables);

    return 0;

}


static int adts_aac_read_packet(AVFormatContext *s, AVPacket *pkt)

{

    int ret, fsize;

    ret = av_get_packet(s->pb, pkt, ADTS_HEADER_SIZE);

    if (ret < 0)

        return ret;

    if (ret < ADTS_HEADER_SIZE) {

        av_packet_unref(pkt);

        return AVERROR(EIO);

    }

    if ((AV_RB16(pkt->data) >> 4) != 0xfff) {

        av_packet_unref(pkt);

        return AVERROR_INVALIDDATA;

    }

    fsize = (AV_RB32(pkt->data + 3) >> 13) & 0x1FFF;

    if (fsize < ADTS_HEADER_SIZE) {

        av_packet_unref(pkt);

        return AVERROR_INVALIDDATA;

    }

    return av_append_packet(s->pb, pkt, fsize - ADTS_HEADER_SIZE);

}


static int bgr24ToYv12Wrapper(SwsContext *c, const uint8_t *src[],

                              int srcStride[], int srcSliceY, int srcSliceH,

                              uint8_t *dst[], int dstStride[])

{

    rgb24toyv12(

        src[0],

        dst[0] +  srcSliceY       * dstStride[0],

        dst[1] + (srcSliceY >> 1) * dstStride[1],

        dst[2] + (srcSliceY >> 1) * dstStride[2],

        c->srcW, srcSliceH,

        dstStride[0], dstStride[1], srcStride[0]);

    if (dst[3])

        fillPlane(dst[3], dstStride[3], c->srcW, srcSliceH, srcSliceY, 255);

    return srcSliceH;

}


void rgb15tobgr32(const uint8_t *src, uint8_t *dst, unsigned int src_size)

{

	const uint16_t *end;

	uint8_t *d = (uint8_t *)dst;

	const uint16_t *s = (const uint16_t *)src;

	end = s + src_size/2;

	while(s < end)

	{

		register uint16_t bgr;

		bgr = *s++;

		*d++ = (bgr&0x7C00)>>7;

		*d++ = (bgr&0x3E0)>>2;

		*d++ = (bgr&0x1F)<<3;

		*d++ = 0;

	}

}


static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)

{

    VP56RangeCoder *c = &s->c;

    int rows, cols;

    ff_vp56_init_range_decoder(&s->c, buf, buf_size);

    s->frames[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c);

    vp56_rac_get(c);

    ff_vp56_init_dequant(s, vp56_rac_gets(c, 6));

    if (s->frames[VP56_FRAME_CURRENT]->key_frame)

    {

        vp56_rac_gets(c, 8);

        if(vp56_rac_gets(c, 5) > 5)

            return AVERROR_INVALIDDATA;

        vp56_rac_gets(c, 2);

        if (vp56_rac_get(c)) {

            av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n");

            return AVERROR_PATCHWELCOME;

        }

        rows = vp56_rac_gets(c, 8);  /* number of stored macroblock rows */

        cols = vp56_rac_gets(c, 8);  /* number of stored macroblock cols */

        if (!rows || !cols) {

            av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n",

                   cols << 4, rows << 4);

            return AVERROR_INVALIDDATA;

        }

        vp56_rac_gets(c, 8);  /* number of displayed macroblock rows */

        vp56_rac_gets(c, 8);  /* number of displayed macroblock cols */

        vp56_rac_gets(c, 2);

        if (!s->macroblocks || /* first frame */

            16*cols != s->avctx->coded_width ||

            16*rows != s->avctx->coded_height) {

            int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);

            if (ret < 0)

                return ret;

            return VP56_SIZE_CHANGE;

        }

    } else if (!s->macroblocks)

        return AVERROR_INVALIDDATA;

    return 0;

}


static inline int coeff_unpack_golomb(GetBitContext *gb, int qfactor, int qoffset)

{

    int coeff = dirac_get_se_golomb(gb);

    const int sign = FFSIGN(coeff);

    if (coeff)

        coeff = sign*((sign * coeff * qfactor + qoffset) >> 2);

    return coeff;

}


int ff_h264_frame_start(H264Context *h)

{

    Picture *pic;

    int i, ret;

    const int pixel_shift = h->pixel_shift;

    int c[4] = {

        1<<(h->sps.bit_depth_luma-1),

        1<<(h->sps.bit_depth_chroma-1),

        1<<(h->sps.bit_depth_chroma-1),

        -1

    };

    if (!ff_thread_can_start_frame(h->avctx)) {

        av_log(h->avctx, AV_LOG_ERROR, "Attempt to start a frame outside SETUP state\n");

        return -1;

    }

    release_unused_pictures(h, 1);

    h->cur_pic_ptr = NULL;

    i = find_unused_picture(h);

    if (i < 0) {

        av_log(h->avctx, AV_LOG_ERROR, "no frame buffer available\n");

        return i;

    }

    pic = &h->DPB[i];

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

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

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

    /*

     * 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->sync        = 0;

    pic->mmco_reset  = 0;

    if ((ret = alloc_picture(h, pic)) < 0)

        return ret;

    if(!h->sync && !h->avctx->hwaccel)

        avpriv_color_frame(&pic->f, c);

    h->cur_pic_ptr = pic;

    h->cur_pic     = *h->cur_pic_ptr;

    h->cur_pic.f.extended_data = h->cur_pic.f.data;

    ff_er_frame_start(&h->er);

    assert(h->linesize && h->uvlinesize);

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

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

        h->block_offset[48 + i]      = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->linesize * ((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 * h->uvlinesize * ((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 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3);

    }

    /* can't be in alloc_tables because linesize isn't known there.

     * FIXME: redo bipred weight to not require extra buffer? */

    for (i = 0; i < h->slice_context_count; i++)

        if (h->thread_context[i]) {

            ret = alloc_scratch_buffers(h->thread_context[i], h->linesize);

            if (ret < 0)

                return ret;

        }

    /* 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));

    // s->decode = (h->flags & CODEC_FLAG_PSNR) || !s->encoding ||

    //             h->cur_pic.f.reference /* || h->contains_intra */ || 1;

    /* 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().

     * SVQ3 as well as most other codecs have only last/next/current and thus

     * get released even with set reference, besides SVQ3 and others do not

     * mark frames as reference later "naturally". */

    if (h->avctx->codec_id != AV_CODEC_ID_SVQ3)

        h->cur_pic_ptr->f.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;

}


static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)

{

    gen_set_cpsr(cpsr, CPSR_ERET_MASK);

    tcg_temp_free_i32(cpsr);

    store_reg(s, 15, pc);

    s->is_jmp = DISAS_UPDATE;

}


static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)

{

    const char *rn = "invalid";

    if (sel != 0)

        check_insn(ctx, ISA_MIPS32);

    switch (reg) {

    case 0:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));

            rn = "Index";

            break;

        case 1:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_helper_mfc0_mvpcontrol(arg, cpu_env);

            rn = "MVPControl";

            break;

        case 2:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_helper_mfc0_mvpconf0(arg, cpu_env);

            rn = "MVPConf0";

            break;

        case 3:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_helper_mfc0_mvpconf1(arg, cpu_env);

            rn = "MVPConf1";

            break;

        case 4:

            CP0_CHECK(ctx->vp);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));

            rn = "VPControl";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 1:

        switch (sel) {

        case 0:

            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));

            gen_helper_mfc0_random(arg, cpu_env);

            rn = "Random";

            break;

        case 1:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));

            rn = "VPEControl";

            break;

        case 2:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));

            rn = "VPEConf0";

            break;

        case 3:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));

            rn = "VPEConf1";

            break;

        case 4:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));

            rn = "YQMask";

            break;

        case 5:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));

            rn = "VPESchedule";

            break;

        case 6:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));

            rn = "VPEScheFBack";

            break;

        case 7:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));

            rn = "VPEOpt";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 2:

        switch (sel) {

        case 0:

            {

                TCGv_i64 tmp = tcg_temp_new_i64();

                tcg_gen_ld_i64(tmp, cpu_env,

                               offsetof(CPUMIPSState, CP0_EntryLo0));

#if defined(TARGET_MIPS64)

                if (ctx->rxi) {

                    /* Move RI/XI fields to bits 31:30 */

                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);

                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);

                }

#endif

                gen_move_low32(arg, tmp);

                tcg_temp_free_i64(tmp);

            }

            rn = "EntryLo0";

            break;

        case 1:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_helper_mfc0_tcstatus(arg, cpu_env);

            rn = "TCStatus";

            break;

        case 2:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_helper_mfc0_tcbind(arg, cpu_env);

            rn = "TCBind";

            break;

        case 3:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_helper_mfc0_tcrestart(arg, cpu_env);

            rn = "TCRestart";

            break;

        case 4:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_helper_mfc0_tchalt(arg, cpu_env);

            rn = "TCHalt";

            break;

        case 5:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_helper_mfc0_tccontext(arg, cpu_env);

            rn = "TCContext";

            break;

        case 6:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_helper_mfc0_tcschedule(arg, cpu_env);

            rn = "TCSchedule";

            break;

        case 7:

            CP0_CHECK(ctx->insn_flags & ASE_MT);

            gen_helper_mfc0_tcschefback(arg, cpu_env);

            rn = "TCScheFBack";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 3:

        switch (sel) {

        case 0:

            {

                TCGv_i64 tmp = tcg_temp_new_i64();

                tcg_gen_ld_i64(tmp, cpu_env,

                               offsetof(CPUMIPSState, CP0_EntryLo1));

#if defined(TARGET_MIPS64)

                if (ctx->rxi) {

                    /* Move RI/XI fields to bits 31:30 */

                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);

                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);

                }

#endif

                gen_move_low32(arg, tmp);

                tcg_temp_free_i64(tmp);

            }

            rn = "EntryLo1";

            break;

        case 1:

            CP0_CHECK(ctx->vp);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));

            rn = "GlobalNumber";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 4:

        switch (sel) {

        case 0:

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "Context";

            break;

        case 1:

//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */

            rn = "ContextConfig";

            goto cp0_unimplemented;

        case 2:

            CP0_CHECK(ctx->ulri);

            tcg_gen_ld_tl(arg, cpu_env,

                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "UserLocal";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 5:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));

            rn = "PageMask";

            break;

        case 1:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));

            rn = "PageGrain";

            break;

        case 2:

            CP0_CHECK(ctx->sc);

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "SegCtl0";

            break;

        case 3:

            CP0_CHECK(ctx->sc);

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "SegCtl1";

            break;

        case 4:

            CP0_CHECK(ctx->sc);

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "SegCtl2";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 6:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));

            rn = "Wired";

            break;

        case 1:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));

            rn = "SRSConf0";

            break;

        case 2:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));

            rn = "SRSConf1";

            break;

        case 3:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));

            rn = "SRSConf2";

            break;

        case 4:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));

            rn = "SRSConf3";

            break;

        case 5:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));

            rn = "SRSConf4";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 7:

        switch (sel) {

        case 0:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));

            rn = "HWREna";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 8:

        switch (sel) {

        case 0:

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "BadVAddr";

            break;

        case 1:

            CP0_CHECK(ctx->bi);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));

            rn = "BadInstr";

            break;

        case 2:

            CP0_CHECK(ctx->bp);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));

            rn = "BadInstrP";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 9:

        switch (sel) {

        case 0:

            /* Mark as an IO operation because we read the time.  */

            if (ctx->tb->cflags & CF_USE_ICOUNT) {

                gen_io_start();

	    }

            gen_helper_mfc0_count(arg, cpu_env);

            if (ctx->tb->cflags & CF_USE_ICOUNT) {

                gen_io_end();

            }

            /* Break the TB to be able to take timer interrupts immediately

               after reading count. BS_STOP isn't sufficient, we need to ensure

               we break completely out of translated code.  */

            gen_save_pc(ctx->pc + 4);

            ctx->bstate = BS_EXCP;

            rn = "Count";

            break;

        /* 6,7 are implementation dependent */

        default:

            goto cp0_unimplemented;

        }

        break;

    case 10:

        switch (sel) {

        case 0:

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "EntryHi";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 11:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));

            rn = "Compare";

            break;

        /* 6,7 are implementation dependent */

        default:

            goto cp0_unimplemented;

        }

        break;

    case 12:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));

            rn = "Status";

            break;

        case 1:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));

            rn = "IntCtl";

            break;

        case 2:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));

            rn = "SRSCtl";

            break;

        case 3:

            check_insn(ctx, ISA_MIPS32R2);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));

            rn = "SRSMap";

            break;

        default:

            goto cp0_unimplemented;

       }

        break;

    case 13:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));

            rn = "Cause";

            break;

        default:

            goto cp0_unimplemented;

       }

        break;

    case 14:

        switch (sel) {

        case 0:

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "EPC";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 15:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));

            rn = "PRid";

            break;

        case 1:

            check_insn(ctx, ISA_MIPS32R2);

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "EBase";

            break;

        case 3:

            check_insn(ctx, ISA_MIPS32R2);

            CP0_CHECK(ctx->cmgcr);

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "CMGCRBase";

            break;

        default:

            goto cp0_unimplemented;

       }

        break;

    case 16:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));

            rn = "Config";

            break;

        case 1:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));

            rn = "Config1";

            break;

        case 2:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));

            rn = "Config2";

            break;

        case 3:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));

            rn = "Config3";

            break;

        case 4:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));

            rn = "Config4";

            break;

        case 5:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));

            rn = "Config5";

            break;

        /* 6,7 are implementation dependent */

        case 6:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));

            rn = "Config6";

            break;

        case 7:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));

            rn = "Config7";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 17:

        switch (sel) {

        case 0:

            gen_helper_mfc0_lladdr(arg, cpu_env);

            rn = "LLAddr";

            break;

        case 1:

            CP0_CHECK(ctx->mrp);

            gen_helper_mfc0_maar(arg, cpu_env);

            rn = "MAAR";

            break;

        case 2:

            CP0_CHECK(ctx->mrp);

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));

            rn = "MAARI";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 18:

        switch (sel) {

        case 0 ... 7:

            gen_helper_1e0i(mfc0_watchlo, arg, sel);

            rn = "WatchLo";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 19:

        switch (sel) {

        case 0 ...7:

            gen_helper_1e0i(mfc0_watchhi, arg, sel);

            rn = "WatchHi";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 20:

        switch (sel) {

        case 0:

#if defined(TARGET_MIPS64)

            check_insn(ctx, ISA_MIPS3);

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "XContext";

            break;

#endif

        default:

            goto cp0_unimplemented;

        }

        break;

    case 21:

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

        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));

            rn = "Framemask";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 22:

        tcg_gen_movi_tl(arg, 0); /* unimplemented */

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

        break;

    case 23:

        switch (sel) {

        case 0:

            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */

            rn = "Debug";

            break;

        case 1:

//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */

            rn = "TraceControl";

            goto cp0_unimplemented;

        case 2:

//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */

            rn = "TraceControl2";

            goto cp0_unimplemented;

        case 3:

//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */

            rn = "UserTraceData";

            goto cp0_unimplemented;

        case 4:

//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */

            rn = "TraceBPC";

            goto cp0_unimplemented;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 24:

        switch (sel) {

        case 0:

            /* EJTAG support */

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "DEPC";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 25:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));

            rn = "Performance0";

            break;

        case 1:

//            gen_helper_mfc0_performance1(arg);

            rn = "Performance1";

            goto cp0_unimplemented;

        case 2:

//            gen_helper_mfc0_performance2(arg);

            rn = "Performance2";

            goto cp0_unimplemented;

        case 3:

//            gen_helper_mfc0_performance3(arg);

            rn = "Performance3";

            goto cp0_unimplemented;

        case 4:

//            gen_helper_mfc0_performance4(arg);

            rn = "Performance4";

            goto cp0_unimplemented;

        case 5:

//            gen_helper_mfc0_performance5(arg);

            rn = "Performance5";

            goto cp0_unimplemented;

        case 6:

//            gen_helper_mfc0_performance6(arg);

            rn = "Performance6";

            goto cp0_unimplemented;

        case 7:

//            gen_helper_mfc0_performance7(arg);

            rn = "Performance7";

            goto cp0_unimplemented;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 26:

        switch (sel) {

        case 0:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));

            rn = "ErrCtl";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 27:

        switch (sel) {

        case 0 ... 3:

            tcg_gen_movi_tl(arg, 0); /* unimplemented */

            rn = "CacheErr";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 28:

        switch (sel) {

        case 0:

        case 2:

        case 4:

        case 6:

            {

                TCGv_i64 tmp = tcg_temp_new_i64();

                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));

                gen_move_low32(arg, tmp);

                tcg_temp_free_i64(tmp);

            }

            rn = "TagLo";

            break;

        case 1:

        case 3:

        case 5:

        case 7:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));

            rn = "DataLo";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 29:

        switch (sel) {

        case 0:

        case 2:

        case 4:

        case 6:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));

            rn = "TagHi";

            break;

        case 1:

        case 3:

        case 5:

        case 7:

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));

            rn = "DataHi";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 30:

        switch (sel) {

        case 0:

            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "ErrorEPC";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    case 31:

        switch (sel) {

        case 0:

            /* EJTAG support */

            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));

            rn = "DESAVE";

            break;

        case 2 ... 7:

            CP0_CHECK(ctx->kscrexist & (1 << sel));

            tcg_gen_ld_tl(arg, cpu_env,

                          offsetof(CPUMIPSState, CP0_KScratch[sel-2]));

            tcg_gen_ext32s_tl(arg, arg);

            rn = "KScratch";

            break;

        default:

            goto cp0_unimplemented;

        }

        break;

    default:

       goto cp0_unimplemented;

    }

    trace_mips_translate_c0("mfc0", rn, reg, sel);

    return;

cp0_unimplemented:

    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);

    gen_mfc0_unimplemented(ctx, arg);

}


static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)

{

    const char *p;

    int ch, reg_size, type;

    char buf[4096];

    uint8_t mem_buf[4096];

    uint32_t *registers;

    target_ulong addr, len;

#ifdef DEBUG_GDB

    printf("command='%s'\n", line_buf);

#endif

    p = line_buf;

    ch = *p++;

    switch(ch) {

    case '?':

        /* TODO: Make this return the correct value for user-mode.  */

        snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);

        put_packet(s, buf);

        /* Remove all the breakpoints when this query is issued,

         * because gdb is doing and initial connect and the state

         * should be cleaned up.

         */

    case 'c':

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

            addr = strtoull(p, (char **)&p, 16);

#if defined(TARGET_I386)

            env->eip = addr;

#elif defined (TARGET_PPC)

            env->nip = addr;

#elif defined (TARGET_SPARC)

            env->pc = addr;

            env->npc = addr + 4;

#elif defined (TARGET_ARM)

            env->regs[15] = addr;

#elif defined (TARGET_SH4)

            env->pc = addr;

#elif defined (TARGET_MIPS)

            env->PC[env->current_tc] = addr;

#elif defined (TARGET_CRIS)

            env->pc = addr;

#endif

        }

	return RS_IDLE;

    case 's':

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

            addr = strtoull(p, (char **)&p, 16);

#if defined(TARGET_I386)

            env->eip = addr;

#elif defined (TARGET_PPC)

            env->nip = addr;

#elif defined (TARGET_SPARC)

            env->pc = addr;

            env->npc = addr + 4;

#elif defined (TARGET_ARM)

            env->regs[15] = addr;

#elif defined (TARGET_SH4)

            env->pc = addr;

#elif defined (TARGET_MIPS)

            env->PC[env->current_tc] = addr;

#elif defined (TARGET_CRIS)

            env->pc = addr;

#endif

        }

        cpu_single_step(env, sstep_flags);

	return RS_IDLE;

    case 'F':

        {

            target_ulong ret;

            target_ulong err;

            ret = strtoull(p, (char **)&p, 16);

            if (*p == ',') {

                p++;

                err = strtoull(p, (char **)&p, 16);

            } else {

                err = 0;

            }

            if (*p == ',')

                p++;

            type = *p;

            if (gdb_current_syscall_cb)

                gdb_current_syscall_cb(s->env, ret, err);

            if (type == 'C') {

                put_packet(s, "T02");

            } else {

            }

        }

    case 'g':

        reg_size = cpu_gdb_read_registers(env, mem_buf);

        memtohex(buf, mem_buf, reg_size);

        put_packet(s, buf);

    case 'G':

        registers = (void *)mem_buf;

        len = strlen(p) / 2;

        hextomem((uint8_t *)registers, p, len);

        cpu_gdb_write_registers(env, mem_buf, len);

    case 'm':

        addr = strtoull(p, (char **)&p, 16);

        if (*p == ',')

            p++;

        len = strtoull(p, NULL, 16);

        if (cpu_memory_rw_debug(env, addr, mem_buf, len, 0) != 0) {

            put_packet (s, "E14");

        } else {

            memtohex(buf, mem_buf, len);

            put_packet(s, buf);

        }

    case 'M':

        addr = strtoull(p, (char **)&p, 16);

        if (*p == ',')

            p++;

        len = strtoull(p, (char **)&p, 16);

        if (*p == ':')

            p++;

        hextomem(mem_buf, p, len);

        if (cpu_memory_rw_debug(env, addr, mem_buf, len, 1) != 0)

            put_packet(s, "E14");

        else

    case 'Z':

        type = strtoul(p, (char **)&p, 16);

        if (*p == ',')

            p++;

        addr = strtoull(p, (char **)&p, 16);

        if (*p == ',')

            p++;

        len = strtoull(p, (char **)&p, 16);

        if (type == 0 || type == 1) {

            if (cpu_breakpoint_insert(env, addr) < 0)

                goto breakpoint_error;

#ifndef CONFIG_USER_ONLY

        } else if (type == 2) {

            if (cpu_watchpoint_insert(env, addr) < 0)

                goto breakpoint_error;

#endif

        } else {

        breakpoint_error:

            put_packet(s, "E22");

        }

    case 'z':

        type = strtoul(p, (char **)&p, 16);

        if (*p == ',')

            p++;

        addr = strtoull(p, (char **)&p, 16);

        if (*p == ',')

            p++;

        len = strtoull(p, (char **)&p, 16);

        if (type == 0 || type == 1) {

            cpu_breakpoint_remove(env, addr);

#ifndef CONFIG_USER_ONLY

        } else if (type == 2) {

            cpu_watchpoint_remove(env, addr);

#endif

        } else {

            goto breakpoint_error;

        }

    case 'q':

    case 'Q':

        /* parse any 'q' packets here */

        if (!strcmp(p,"qemu.sstepbits")) {

            /* Query Breakpoint bit definitions */

            sprintf(buf,"ENABLE=%x,NOIRQ=%x,NOTIMER=%x",

                    SSTEP_ENABLE,

                    SSTEP_NOIRQ,

                    SSTEP_NOTIMER);

            put_packet(s, buf);

        } else if (strncmp(p,"qemu.sstep",10) == 0) {

            /* Display or change the sstep_flags */

            p += 10;

            if (*p != '=') {

                /* Display current setting */

                sprintf(buf,"0x%x", sstep_flags);

                put_packet(s, buf);

            }

            p++;

            type = strtoul(p, (char **)&p, 16);

            sstep_flags = type;

        }

#ifdef CONFIG_LINUX_USER

        else if (strncmp(p, "Offsets", 7) == 0) {

            TaskState *ts = env->opaque;

            sprintf(buf,

                    "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx

                    ";Bss=" TARGET_ABI_FMT_lx,

                    ts->info->code_offset,

                    ts->info->data_offset,

                    ts->info->data_offset);

            put_packet(s, buf);

        }

#endif

        /* Fall through.  */

    default:

        /* put empty packet */

        buf[0] = '\0';

        put_packet(s, buf);

    }

    return RS_IDLE;

}


static void decode_ac_filter(WmallDecodeCtx *s)

{

    int i;

    s->acfilter_order = get_bits(&s->gb, 4) + 1;

    s->acfilter_scaling = get_bits(&s->gb, 4);

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

	s->acfilter_coeffs[i] = get_bits(&s->gb, s->acfilter_scaling) + 1;

    }

}


static void check_loopfilter(void)

{

    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" };

    static const int E[2] = { 20, 28 }, I[2] = { 10, 16 };

    static const int 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++) {

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

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

            uint8_t *buf0 = base0 + midoff_aligned;

            uint8_t *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;

            buf0 = base0 + midoff_aligned;

            buf1 = base1 + midoff_aligned;

            // 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");

}


av_cold void ff_dsputil_init_x86(DSPContext *c, AVCodecContext *avctx)

{

    int cpu_flags = av_get_cpu_flags();

#if HAVE_7REGS && HAVE_INLINE_ASM

    if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_CMOV)

        c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_cmov;

#endif

    if (X86_MMX(cpu_flags)) {

#if HAVE_INLINE_ASM

        const int idct_algo = avctx->idct_algo;

        if (avctx->lowres == 0 && avctx->bits_per_raw_sample <= 8) {

            if (idct_algo == FF_IDCT_AUTO || idct_algo == FF_IDCT_SIMPLEMMX) {

                c->idct_put              = ff_simple_idct_put_mmx;

                c->idct_add              = ff_simple_idct_add_mmx;

                c->idct                  = ff_simple_idct_mmx;

                c->idct_permutation_type = FF_SIMPLE_IDCT_PERM;

            } else if (idct_algo == FF_IDCT_XVIDMMX) {

                if (cpu_flags & AV_CPU_FLAG_SSE2) {

                    c->idct_put              = ff_idct_xvid_sse2_put;

                    c->idct_add              = ff_idct_xvid_sse2_add;

                    c->idct                  = ff_idct_xvid_sse2;

                    c->idct_permutation_type = FF_SSE2_IDCT_PERM;

                } else if (cpu_flags & AV_CPU_FLAG_MMXEXT) {

                    c->idct_put              = ff_idct_xvid_mmxext_put;

                    c->idct_add              = ff_idct_xvid_mmxext_add;

                    c->idct                  = ff_idct_xvid_mmxext;

                } else {

                    c->idct_put              = ff_idct_xvid_mmx_put;

                    c->idct_add              = ff_idct_xvid_mmx_add;

                    c->idct                  = ff_idct_xvid_mmx;

                }

            }

        }

#endif /* HAVE_INLINE_ASM */

        dsputil_init_mmx(c, avctx, cpu_flags);

    }

    if (X86_MMXEXT(cpu_flags))

        dsputil_init_mmxext(c, avctx, cpu_flags);

    if (X86_SSE(cpu_flags))

        dsputil_init_sse(c, avctx, cpu_flags);

    if (X86_SSE2(cpu_flags))

        dsputil_init_sse2(c, avctx, cpu_flags);

    if (EXTERNAL_SSSE3(cpu_flags))

        dsputil_init_ssse3(c, avctx, cpu_flags);

    if (EXTERNAL_SSE4(cpu_flags))

        dsputil_init_sse4(c, avctx, cpu_flags);

    if (CONFIG_ENCODERS)

        ff_dsputilenc_init_mmx(c, avctx);

}


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

                                       SingleChannelElement *sce,

                                       const float lambda)

{

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

    int i, j;

    int idx;

    TrellisPath paths[TRELLIS_STAGES][TRELLIS_STATES];

    int bandaddr[TRELLIS_STAGES];

    int minq;

    float mincost;

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

    int q0, q1, qcnt = 0;

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

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

        if (t > 0.0f) {

            q0f = FFMIN(q0f, t);

            q1f = FFMAX(q1f, t);

            qnrgf += t*t;

            qcnt++;

        }

    }

    if (!qcnt) {

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

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

        return;

    }

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

    q0 = coef2minsf(q0f);

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

    q1 = coef2maxsf(q1f);

    if (q1 - q0 > 60) {

        int q0low  = q0;

        int q1high = q1;

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

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

        q1 = qnrg + 30;

        q0 = qnrg - 30;

        if (q0 < q0low) {

            q1 += q0low - q0;

            q0  = q0low;

        } else if (q1 > q1high) {

            q0 -= q1 - q1high;

            q1  = q1high;

        }

    }

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

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

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

    }

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

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

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

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

        }

    }

    idx = 1;

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

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

        start = w*128;

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

            const float *coefs = &sce->coeffs[start];

            float qmin, qmax;

            int nz = 0;

            bandaddr[idx] = w * 16 + g;

            qmin = INT_MAX;

            qmax = 0.0f;

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

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

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

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

                    continue;

                }

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

                nz = 1;

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

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

                    if (t > 0.0f)

                        qmin = FFMIN(qmin, t);

                    qmax = FFMAX(qmax, t);

                }

            }

            if (nz) {

                int minscale, maxscale;

                float minrd = INFINITY;

                float maxval;

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

                minscale = coef2minsf(qmin);

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

                maxscale = coef2maxsf(qmax);

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

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

                maxval = find_max_val(sce->ics.group_len[w], sce->ics.swb_sizes[g], s->scoefs+start);

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

                    float dist = 0;

                    int cb = find_min_book(maxval, sce->sf_idx[w*16+g]);

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

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

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

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

                    }

                    minrd = FFMIN(minrd, dist);

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

                        float cost;

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

                               + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];

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

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

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

                        }

                    }

                }

            } else {

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

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

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

                }

            }

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

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

            idx++;

        }

    }

    idx--;

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

    minq    = 0;

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

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

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

            minq = i;

        }

    }

    while (idx) {

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

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

        idx--;

    }

    //set the same quantizers inside window groups

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

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

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

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

}


QDict *qdict_get_qdict(const QDict *qdict, const char *key)

{

    return qobject_to_qdict(qdict_get_obj(qdict, key, QTYPE_QDICT));

}


static int guess_ni_flag(AVFormatContext *s){

    int i;

    int64_t last_start=0;

    int64_t first_end= INT64_MAX;

    int64_t oldpos= avio_tell(s->pb);

    int *idx;

    int64_t min_pos, pos;

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

        AVStream *st = s->streams[i];

        int n= st->nb_index_entries;

        unsigned int size;

        if(n <= 0)

            continue;

        if(n >= 2){

            int64_t pos= st->index_entries[0].pos;

            avio_seek(s->pb, pos + 4, SEEK_SET);

            size= avio_rl32(s->pb);

            if(pos + size > st->index_entries[1].pos)

                last_start= INT64_MAX;

        }

        if(st->index_entries[0].pos > last_start)

            last_start= st->index_entries[0].pos;

        if(st->index_entries[n-1].pos < first_end)

            first_end= st->index_entries[n-1].pos;

    }

    avio_seek(s->pb, oldpos, SEEK_SET);

    if (last_start > first_end)

        return 1;

    idx= av_mallocz(sizeof(*idx) * s->nb_streams);

    for (min_pos=pos=0; min_pos!=INT64_MAX; pos= min_pos+1) {

        int64_t max_dts = INT64_MIN/2, min_dts= INT64_MAX/2;

        min_pos = INT64_MAX;

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

            AVStream *st = s->streams[i];

            int n= st->nb_index_entries;

            while (idx[i]<n && st->index_entries[idx[i]].pos < pos)

                idx[i]++;

            if (idx[i] < n) {

                min_dts = FFMIN(min_dts, av_rescale_q(st->index_entries[idx[i]].timestamp, st->time_base, AV_TIME_BASE_Q));

                min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos);

            }

            if (idx[i])

                max_dts = FFMAX(max_dts, av_rescale_q(st->index_entries[idx[i]-1].timestamp, st->time_base, AV_TIME_BASE_Q));

        }

        if(max_dts - min_dts > 2*AV_TIME_BASE) {

            av_free(idx);

            return 1;

        }

    }

    av_free(idx);

    return 0;

}


static int nut_write_trailer(AVFormatContext *s)

{

    NUTContext *nut = s->priv_data;

    AVIOContext *bc = s->pb, *dyn_bc;

    int i, ret;

    while (nut->header_count < 3)

        write_headers(s, bc);

    ret = avio_open_dyn_buf(&dyn_bc);

    if (ret >= 0 && nut->sp_count) {

        av_assert1(nut->write_index);

        write_index(nut, dyn_bc);

        put_packet(nut, bc, dyn_bc, 1, INDEX_STARTCODE);

    }

    ff_nut_free_sp(nut);

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

        av_freep(&nut->stream[i].keyframe_pts);

    av_freep(&nut->stream);

    av_freep(&nut->chapter);

    av_freep(&nut->time_base);

    return 0;

}


static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,

                            ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)

{

    ARMCPU *cpu = ARM_CPU(cs);

    CPUARMState *env = &cpu->env;

    MemTxAttrs attrs = {};

    AddressSpace *as;

    attrs.secure = is_secure;

    as = arm_addressspace(cs, attrs);

    addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fi);

    if (fi->s1ptw) {

        return 0;

    }

    if (regime_translation_big_endian(env, mmu_idx)) {

        return address_space_ldl_be(as, addr, attrs, NULL);

    } else {

        return address_space_ldl_le(as, addr, attrs, NULL);

    }

}


void aio_context_acquire(AioContext *ctx)

{

    qemu_rec_mutex_lock(&ctx->lock);

}


static void qjson_finalizefn(Object *obj)

{

    QJSON *json = QJSON(obj);

    qobject_decref(QOBJECT(json->str));

}


static void cchip_write(void *opaque, hwaddr addr,

                        uint64_t v32, unsigned size)

{

    TyphoonState *s = opaque;

    uint64_t val, oldval, newval;

    if (addr & 4) {

        val = v32 << 32 | s->latch_tmp;

        addr ^= 4;

    } else {

        s->latch_tmp = v32;

        return;

    }

    switch (addr) {

    case 0x0000:

        /* CSC: Cchip System Configuration Register.  */

        /* All sorts of data here; nothing relevant RW.  */

        break;

    case 0x0040:

        /* MTR: Memory Timing Register.  */

        /* All sorts of stuff related to real DRAM.  */

        break;

    case 0x0080:

        /* MISC: Miscellaneous Register.  */

        newval = oldval = s->cchip.misc;

        newval &= ~(val & 0x10000ff0);     /* W1C fields */

        if (val & 0x100000) {

            newval &= ~0xff0000ull;        /* ACL clears ABT and ABW */

        } else {

            newval |= val & 0x00f00000;    /* ABT field is W1S */

            if ((newval & 0xf0000) == 0) {

                newval |= val & 0xf0000;   /* ABW field is W1S iff zero */

            }

        }

        newval |= (val & 0xf000) >> 4;     /* IPREQ field sets IPINTR.  */

        newval &= ~0xf0000000000ull;       /* WO and RW fields */

        newval |= val & 0xf0000000000ull;

        s->cchip.misc = newval;

        /* Pass on changes to IPI and ITI state.  */

        if ((newval ^ oldval) & 0xff0) {

            int i;

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

                AlphaCPU *cpu = s->cchip.cpu[i];

                if (cpu != NULL) {

                    CPUState *cs = CPU(cpu);

                    /* IPI can be either cleared or set by the write.  */

                    if (newval & (1 << (i + 8))) {

                        cpu_interrupt(cs, CPU_INTERRUPT_SMP);

                    } else {

                        cpu_reset_interrupt(cs, CPU_INTERRUPT_SMP);

                    }

                    /* ITI can only be cleared by the write.  */

                    if ((newval & (1 << (i + 4))) == 0) {

                        cpu_reset_interrupt(cs, CPU_INTERRUPT_TIMER);

                    }

                }

            }

        }

        break;

    case 0x00c0:

        /* MPD: Memory Presence Detect Register.  */

        break;

    case 0x0100: /* AAR0 */

    case 0x0140: /* AAR1 */

    case 0x0180: /* AAR2 */

    case 0x01c0: /* AAR3 */

        /* AAR: Array Address Register.  */

        /* All sorts of information about DRAM.  */

        break;

    case 0x0200: /* DIM0 */

        /* DIM: Device Interrupt Mask Register, CPU0.  */

        s->cchip.dim[0] = val;

        cpu_irq_change(s->cchip.cpu[0], val & s->cchip.drir);

        break;

    case 0x0240: /* DIM1 */

        /* DIM: Device Interrupt Mask Register, CPU1.  */

        s->cchip.dim[0] = val;

        cpu_irq_change(s->cchip.cpu[1], val & s->cchip.drir);

        break;

    case 0x0280: /* DIR0 (RO) */

    case 0x02c0: /* DIR1 (RO) */

    case 0x0300: /* DRIR (RO) */

        break;

    case 0x0340:

        /* PRBEN: Probe Enable Register.  */

        break;

    case 0x0380: /* IIC0 */

        s->cchip.iic[0] = val & 0xffffff;

        break;

    case 0x03c0: /* IIC1 */

        s->cchip.iic[1] = val & 0xffffff;

        break;

    case 0x0400: /* MPR0 */

    case 0x0440: /* MPR1 */

    case 0x0480: /* MPR2 */

    case 0x04c0: /* MPR3 */

        /* MPR: Memory Programming Register.  */

        break;

    case 0x0580:

        /* TTR: TIGbus Timing Register.  */

        /* All sorts of stuff related to interrupt delivery timings.  */

        break;

    case 0x05c0:

        /* TDR: TIGbug Device Timing Register.  */

        break;

    case 0x0600:

        /* DIM2: Device Interrupt Mask Register, CPU2.  */

        s->cchip.dim[2] = val;

        cpu_irq_change(s->cchip.cpu[2], val & s->cchip.drir);

        break;

    case 0x0640:

        /* DIM3: Device Interrupt Mask Register, CPU3.  */

        s->cchip.dim[3] = val;

        cpu_irq_change(s->cchip.cpu[3], val & s->cchip.drir);

        break;

    case 0x0680: /* DIR2 (RO) */

    case 0x06c0: /* DIR3 (RO) */

        break;

    case 0x0700: /* IIC2 */

        s->cchip.iic[2] = val & 0xffffff;

        break;

    case 0x0740: /* IIC3 */

        s->cchip.iic[3] = val & 0xffffff;

        break;

    case 0x0780:

        /* PWR: Power Management Control.   */

        break;

    case 0x0c00: /* CMONCTLA */

    case 0x0c40: /* CMONCTLB */

    case 0x0c80: /* CMONCNT01 */

    case 0x0cc0: /* CMONCNT23 */

        break;

    default:

        cpu_unassigned_access(current_cpu, addr, true, false, 0, size);

        return;

    }

}


static void visitor_output_setup(TestOutputVisitorData *data,

                                 const void *unused)

{

    data->qov = qmp_output_visitor_new();

    g_assert(data->qov != NULL);

    data->ov = qmp_output_get_visitor(data->qov);

    g_assert(data->ov != NULL);

}


static void group_exponents(AC3EncodeContext *s)

{

    int blk, ch, i;

    int group_size, nb_groups, bit_count;

    uint8_t *p;

    int delta0, delta1, delta2;

    int exp0, exp1;

    bit_count = 0;

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

        AC3Block *block = &s->blocks[blk];

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

            if (s->exp_strategy[ch][blk] == EXP_REUSE)

                continue;

            group_size = s->exp_strategy[ch][blk] + (s->exp_strategy[ch][blk] == EXP_D45);

            nb_groups = exponent_group_tab[s->exp_strategy[ch][blk]-1][s->nb_coefs[ch]];

            bit_count += 4 + (nb_groups * 7);

            p = block->exp[ch];

            /* DC exponent */

            exp1 = *p++;

            block->grouped_exp[ch][0] = exp1;

            /* remaining exponents are delta encoded */

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

                /* merge three delta in one code */

                exp0   = exp1;

                exp1   = p[0];

                p     += group_size;

                delta0 = exp1 - exp0 + 2;

                exp0   = exp1;

                exp1   = p[0];

                p     += group_size;

                delta1 = exp1 - exp0 + 2;

                exp0   = exp1;

                exp1   = p[0];

                p     += group_size;

                delta2 = exp1 - exp0 + 2;

                block->grouped_exp[ch][i] = ((delta0 * 5 + delta1) * 5) + delta2;

            }

        }

    }

    s->exponent_bits = bit_count;

}


void sd_write_data(SDState *sd, uint8_t value)

{

    int i;

    if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable)

        return;

    if (sd->state != sd_receivingdata_state) {

        fprintf(stderr, "sd_write_data: not in Receiving-Data state\n");

        return;

    }

    if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))

        return;

    switch (sd->current_cmd) {

    case 24:	/* CMD24:  WRITE_SINGLE_BLOCK */

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sd->blk_len) {

            /* TODO: Check CRC before committing */

            sd->state = sd_programming_state;

            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);

            sd->blk_written ++;

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

            /* Bzzzzzzztt .... Operation complete.  */

            sd->state = sd_transfer_state;

        }

        break;

    case 25:	/* CMD25:  WRITE_MULTIPLE_BLOCK */

        if (sd->data_offset == 0) {

            /* Start of the block - let's check the address is valid */

            if (sd->data_start + sd->blk_len > sd->size) {

                sd->card_status |= ADDRESS_ERROR;

                break;

            }

            if (sd_wp_addr(sd, sd->data_start)) {

                sd->card_status |= WP_VIOLATION;

                break;

            }

        }

        sd->data[sd->data_offset++] = value;

        if (sd->data_offset >= sd->blk_len) {

            /* TODO: Check CRC before committing */

            sd->state = sd_programming_state;

            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);

            sd->blk_written++;

            sd->data_start += sd->blk_len;

            sd->data_offset = 0;

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

            /* Bzzzzzzztt .... Operation complete.  */

            sd->state = sd_receivingdata_state;

        }

        break;

    case 26:	/* CMD26:  PROGRAM_CID */

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sizeof(sd->cid)) {

            /* TODO: Check CRC before committing */

            sd->state = sd_programming_state;

            for (i = 0; i < sizeof(sd->cid); i ++)

                if ((sd->cid[i] | 0x00) != sd->data[i])

                    sd->card_status |= CID_CSD_OVERWRITE;

            if (!(sd->card_status & CID_CSD_OVERWRITE))

                for (i = 0; i < sizeof(sd->cid); i ++) {

                    sd->cid[i] |= 0x00;

                    sd->cid[i] &= sd->data[i];

                }

            /* Bzzzzzzztt .... Operation complete.  */

            sd->state = sd_transfer_state;

        }

        break;

    case 27:	/* CMD27:  PROGRAM_CSD */

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sizeof(sd->csd)) {

            /* TODO: Check CRC before committing */

            sd->state = sd_programming_state;

            for (i = 0; i < sizeof(sd->csd); i ++)

                if ((sd->csd[i] | sd_csd_rw_mask[i]) !=

                    (sd->data[i] | sd_csd_rw_mask[i]))

                    sd->card_status |= CID_CSD_OVERWRITE;

            /* Copy flag (OTP) & Permanent write protect */

            if (sd->csd[14] & ~sd->data[14] & 0x60)

                sd->card_status |= CID_CSD_OVERWRITE;

            if (!(sd->card_status & CID_CSD_OVERWRITE))

                for (i = 0; i < sizeof(sd->csd); i ++) {

                    sd->csd[i] |= sd_csd_rw_mask[i];

                    sd->csd[i] &= sd->data[i];

                }

            /* Bzzzzzzztt .... Operation complete.  */

            sd->state = sd_transfer_state;

        }

        break;

    case 42:	/* CMD42:  LOCK_UNLOCK */

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sd->blk_len) {

            /* TODO: Check CRC before committing */

            sd->state = sd_programming_state;

            sd_lock_command(sd);

            /* Bzzzzzzztt .... Operation complete.  */

            sd->state = sd_transfer_state;

        }

        break;

    case 56:	/* CMD56:  GEN_CMD */

        sd->data[sd->data_offset ++] = value;

        if (sd->data_offset >= sd->blk_len) {

            APP_WRITE_BLOCK(sd->data_start, sd->data_offset);

            sd->state = sd_transfer_state;

        }

        break;

    default:

        fprintf(stderr, "sd_write_data: unknown command\n");

        break;

    }

}


int event_notifier_get_fd(EventNotifier *e)

{

    return e->fd;

}


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

{

    OptsVisitor *ov = to_ov(v);

    const QemuOpt *opt;

    int64_t val;

    opt = lookup_scalar(ov, name, errp);

    if (!opt) {

        return;

    }

    val = qemu_strtosz(opt->str ? opt->str : "", NULL);

    if (val < 0) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,

                   "a size value representible as a non-negative int64");

        return;

    }

    *obj = val;

    processed(ov, name);

}


static void handle_mousemotion(SDL_Event *ev)

{

    int max_x, max_y;

    struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);

    if (qemu_input_is_absolute() || absolute_enabled) {

        int scr_w, scr_h;

        SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h);

        max_x = scr_w - 1;

        max_y = scr_h - 1;

        if (gui_grab && (ev->motion.x == 0 || ev->motion.y == 0 ||

                         ev->motion.x == max_x || ev->motion.y == max_y)) {

            sdl_grab_end(scon);

        }

        if (!gui_grab &&

            (ev->motion.x > 0 && ev->motion.x < max_x &&

             ev->motion.y > 0 && ev->motion.y < max_y)) {

            sdl_grab_start(scon);

        }

    }

    if (gui_grab || qemu_input_is_absolute() || absolute_enabled) {

        sdl_send_mouse_event(scon, ev->motion.xrel, ev->motion.yrel,

                             ev->motion.x, ev->motion.y, ev->motion.state);

    }

}


static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,

                                       uint64_t flags)

{

    Error *local_err = NULL, **errp = &local_err;

    QEMUFileRDMA *rfile = opaque;

    RDMAContext *rdma = rfile->rdma;

    RDMAControlHeader head = { .len = 0, .repeat = 1 };

    int ret = 0;

    CHECK_ERROR_STATE();

    qemu_fflush(f);

    ret = qemu_rdma_drain_cq(f, rdma);

    if (ret < 0) {

        goto err;

    }

    if (flags == RAM_CONTROL_SETUP) {

        RDMAControlHeader resp = {.type = RDMA_CONTROL_RAM_BLOCKS_RESULT };

        RDMALocalBlocks *local = &rdma->local_ram_blocks;

        int reg_result_idx, i, j, nb_remote_blocks;

        head.type = RDMA_CONTROL_RAM_BLOCKS_REQUEST;

        DPRINTF("Sending registration setup for ram blocks...\n");

        /*

         * Make sure that we parallelize the pinning on both sides.

         * For very large guests, doing this serially takes a really

         * long time, so we have to 'interleave' the pinning locally

         * with the control messages by performing the pinning on this

         * side before we receive the control response from the other

         * side that the pinning has completed.

         */

        ret = qemu_rdma_exchange_send(rdma, &head, NULL, &resp,

                    &reg_result_idx, rdma->pin_all ?

                    qemu_rdma_reg_whole_ram_blocks : NULL);

        if (ret < 0) {

            ERROR(errp, "receiving remote info!");

            return ret;

        }

        qemu_rdma_move_header(rdma, reg_result_idx, &resp);

        memcpy(rdma->block,

            rdma->wr_data[reg_result_idx].control_curr, resp.len);

        nb_remote_blocks = resp.len / sizeof(RDMARemoteBlock);

        /*

         * The protocol uses two different sets of rkeys (mutually exclusive):

         * 1. One key to represent the virtual address of the entire ram block.

         *    (dynamic chunk registration disabled - pin everything with one rkey.)

         * 2. One to represent individual chunks within a ram block.

         *    (dynamic chunk registration enabled - pin individual chunks.)

         *

         * Once the capability is successfully negotiated, the destination transmits

         * the keys to use (or sends them later) including the virtual addresses

         * and then propagates the remote ram block descriptions to his local copy.

         */

        if (local->nb_blocks != nb_remote_blocks) {

            ERROR(errp, "ram blocks mismatch #1! "

                        "Your QEMU command line parameters are probably "

                        "not identical on both the source and destination.");

            return -EINVAL;

        }

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

            network_to_remote_block(&rdma->block[i]);

            /* search local ram blocks */

            for (j = 0; j < local->nb_blocks; j++) {

                if (rdma->block[i].offset != local->block[j].offset) {

                    continue;

                }

                if (rdma->block[i].length != local->block[j].length) {

                    ERROR(errp, "ram blocks mismatch #2! "

                        "Your QEMU command line parameters are probably "

                        "not identical on both the source and destination.");

                    return -EINVAL;

                }

                local->block[j].remote_host_addr =

                        rdma->block[i].remote_host_addr;

                local->block[j].remote_rkey = rdma->block[i].remote_rkey;

                break;

            }

            if (j >= local->nb_blocks) {

                ERROR(errp, "ram blocks mismatch #3! "

                        "Your QEMU command line parameters are probably "

                        "not identical on both the source and destination.");

                return -EINVAL;

            }

        }

    }

    DDDPRINTF("Sending registration finish %" PRIu64 "...\n", flags);

    head.type = RDMA_CONTROL_REGISTER_FINISHED;

    ret = qemu_rdma_exchange_send(rdma, &head, NULL, NULL, NULL, NULL);

    if (ret < 0) {

        goto err;

    }

    return 0;

err:

    rdma->error_state = ret;

    return ret;

}


static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)

{

    PCIXenPlatformState *s = opaque;

    addr &= 0xff;

    val  &= 0xff;

    switch (addr) {

    case 0: /* Platform flags */

        platform_fixed_ioport_writeb(opaque, XEN_PLATFORM_IOPORT, val);

        break;

    case 8:

        log_writeb(s, val);

        break;

    default:

        break;

    }

}


static uint32_t nabm_readb (void *opaque, uint32_t addr)

{

    PCIAC97LinkState *d = opaque;

    AC97LinkState *s = &d->ac97;

    AC97BusMasterRegs *r = NULL;

    uint32_t index = addr - s->base[1];

    uint32_t val = ~0U;

    switch (index) {

    case CAS:

        dolog ("CAS %d\n", s->cas);

        val = s->cas;

        s->cas = 1;

        break;

    case PI_CIV:

    case PO_CIV:

    case MC_CIV:

        r = &s->bm_regs[GET_BM (index)];

        val = r->civ;

        dolog ("CIV[%d] -> %#x\n", GET_BM (index), val);

        break;

    case PI_LVI:

    case PO_LVI:

    case MC_LVI:

        r = &s->bm_regs[GET_BM (index)];

        val = r->lvi;

        dolog ("LVI[%d] -> %#x\n", GET_BM (index), val);

        break;

    case PI_PIV:

    case PO_PIV:

    case MC_PIV:

        r = &s->bm_regs[GET_BM (index)];

        val = r->piv;

        dolog ("PIV[%d] -> %#x\n", GET_BM (index), val);

        break;

    case PI_CR:

    case PO_CR:

    case MC_CR:

        r = &s->bm_regs[GET_BM (index)];

        val = r->cr;

        dolog ("CR[%d] -> %#x\n", GET_BM (index), val);

        break;

    case PI_SR:

    case PO_SR:

    case MC_SR:

        r = &s->bm_regs[GET_BM (index)];

        val = r->sr & 0xff;

        dolog ("SRb[%d] -> %#x\n", GET_BM (index), val);

        break;

    default:

        dolog ("U nabm readb %#x -> %#x\n", addr, val);

        break;

    }

    return val;

}


static int ac3_encode_frame(AVCodecContext *avctx,

                            unsigned char *frame, int buf_size, void *data)

{

    AC3EncodeContext *s = avctx->priv_data;

    const int16_t *samples = data;

    int16_t planar_samples[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE+AC3_FRAME_SIZE];

    int32_t mdct_coef[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];

    uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];

    uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS];

    uint8_t encoded_exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];

    uint8_t num_exp_groups[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS];

    uint8_t grouped_exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_EXP_GROUPS];

    uint8_t bap[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];

    int8_t exp_shift[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS];

    uint16_t qmant[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];

    int frame_bits;

    if (s->bit_alloc.sr_code == 1)

        adjust_frame_size(s);

    deinterleave_input_samples(s, samples, planar_samples);

    apply_mdct(s, planar_samples, exp_shift, mdct_coef);

    frame_bits = process_exponents(s, mdct_coef, exp_shift, exp, exp_strategy,

                                   encoded_exp, num_exp_groups, grouped_exp);

    compute_bit_allocation(s, bap, encoded_exp, exp_strategy, frame_bits);

    quantize_mantissas(s, mdct_coef, exp_shift, encoded_exp, bap, qmant);

    output_frame(s, frame, exp_strategy, num_exp_groups, grouped_exp, bap, qmant);

    return s->frame_size;

}


void cpu_physical_memory_write_rom(target_phys_addr_t addr,

                                   const uint8_t *buf, int len)

{

    AddressSpaceDispatch *d = address_space_memory.dispatch;

    int l;

    uint8_t *ptr;

    target_phys_addr_t page;

    MemoryRegionSection *section;

    while (len > 0) {

        page = addr & TARGET_PAGE_MASK;

        l = (page + TARGET_PAGE_SIZE) - addr;

        if (l > len)

            l = len;

        section = phys_page_find(d, page >> TARGET_PAGE_BITS);

        if (!(memory_region_is_ram(section->mr) ||

              memory_region_is_romd(section->mr))) {

            /* do nothing */

        } else {

            unsigned long addr1;

            addr1 = memory_region_get_ram_addr(section->mr)

                + memory_region_section_addr(section, addr);

            /* ROM/RAM case */

            ptr = qemu_get_ram_ptr(addr1);

            memcpy(ptr, buf, l);

            invalidate_and_set_dirty(addr1, l);

            qemu_put_ram_ptr(ptr);

        }

        len -= l;

        buf += l;

        addr += l;

    }

}


av_cold int ff_lpc_init(LPCContext *s, int blocksize, int max_order,

                        enum FFLPCType lpc_type)

{

    s->blocksize = blocksize;

    s->max_order = max_order;

    s->lpc_type  = lpc_type;

    if (lpc_type == FF_LPC_TYPE_LEVINSON) {

        s->windowed_samples = av_mallocz((blocksize + max_order + 2) *

                                         sizeof(*s->windowed_samples));

        if (!s->windowed_samples)

            return AVERROR(ENOMEM);

    } else {

        s->windowed_samples = NULL;

    }

    s->lpc_apply_welch_window = lpc_apply_welch_window_c;

    s->lpc_compute_autocorr   = lpc_compute_autocorr_c;

    if (HAVE_MMX)

        ff_lpc_init_x86(s);

    return 0;

}


static int audio_decode_frame(VideoState *is, double *pts_ptr)

{

    AVPacket *pkt_temp = &is->audio_pkt_temp;

    AVPacket *pkt = &is->audio_pkt;

    AVCodecContext *dec = is->audio_st->codec;

    int len1, len2, data_size, resampled_data_size;

    int64_t dec_channel_layout;

    int got_frame;

    double pts;

    int new_packet = 0;

    int flush_complete = 0;

    int wanted_nb_samples;

    for (;;) {

        /* NOTE: the audio packet can contain several frames */

        while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {

            if (!is->frame) {

                if (!(is->frame = avcodec_alloc_frame()))

                    return AVERROR(ENOMEM);

            } else

                avcodec_get_frame_defaults(is->frame);

            if (is->paused)

                return -1;

            if (flush_complete)

                break;

            new_packet = 0;

            len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);

            if (len1 < 0) {

                /* if error, we skip the frame */

                pkt_temp->size = 0;

                break;

            }

            pkt_temp->data += len1;

            pkt_temp->size -= len1;

            if (!got_frame) {

                /* stop sending empty packets if the decoder is finished */

                if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)

                    flush_complete = 1;

                continue;

            }

            data_size = av_samples_get_buffer_size(NULL, dec->channels,

                                                   is->frame->nb_samples,

                                                   dec->sample_fmt, 1);

            dec_channel_layout = (dec->channel_layout && dec->channels == av_get_channel_layout_nb_channels(dec->channel_layout)) ? dec->channel_layout : av_get_default_channel_layout(dec->channels);

            wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);

            if (dec->sample_fmt != is->audio_src.fmt ||

                dec_channel_layout != is->audio_src.channel_layout ||

                dec->sample_rate != is->audio_src.freq ||

                (wanted_nb_samples != is->frame->nb_samples && !is->swr_ctx)) {

                if (is->swr_ctx)

                    swr_free(&is->swr_ctx);

                is->swr_ctx = swr_alloc_set_opts(NULL,

                                                 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,

                                                 dec_channel_layout,           dec->sample_fmt,   dec->sample_rate,

                                                 0, NULL);

                if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {

                    fprintf(stderr, "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",

                        dec->sample_rate,

                        av_get_sample_fmt_name(dec->sample_fmt),

                        dec->channels,

                        is->audio_tgt.freq,

                        av_get_sample_fmt_name(is->audio_tgt.fmt),

                        is->audio_tgt.channels);

                    break;

                }

                is->audio_src.channel_layout = dec_channel_layout;

                is->audio_src.channels = dec->channels;

                is->audio_src.freq = dec->sample_rate;

                is->audio_src.fmt = dec->sample_fmt;

            }

            resampled_data_size = data_size;

            if (is->swr_ctx) {

                const uint8_t *in[] = { is->frame->data[0] };

                uint8_t *out[] = {is->audio_buf2};

                if (wanted_nb_samples != is->frame->nb_samples) {

                    if (swr_set_compensation(is->swr_ctx, (wanted_nb_samples - is->frame->nb_samples) * is->audio_tgt.freq / dec->sample_rate,

                                                wanted_nb_samples * is->audio_tgt.freq / dec->sample_rate) < 0) {

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

                        break;

                    }

                }

                len2 = swr_convert(is->swr_ctx, out, sizeof(is->audio_buf2) / is->audio_tgt.channels / av_get_bytes_per_sample(is->audio_tgt.fmt),

                                                in, is->frame->nb_samples);

                if (len2 < 0) {

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

                    break;

                }

                if (len2 == sizeof(is->audio_buf2) / is->audio_tgt.channels / av_get_bytes_per_sample(is->audio_tgt.fmt)) {

                    fprintf(stderr, "warning: audio buffer is probably too small\n");

                    swr_init(is->swr_ctx);

                }

                is->audio_buf = is->audio_buf2;

                resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);

            } else {

                is->audio_buf = is->frame->data[0];

            }

            /* if no pts, then compute it */

            pts = is->audio_clock;

            *pts_ptr = pts;

            is->audio_clock += (double)data_size /

                (dec->channels * dec->sample_rate * av_get_bytes_per_sample(dec->sample_fmt));

#ifdef DEBUG

            {

                static double last_clock;

                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",

                       is->audio_clock - last_clock,

                       is->audio_clock, pts);

                last_clock = is->audio_clock;

            }

#endif

            return resampled_data_size;

        }

        /* free the current packet */

        if (pkt->data)

            av_free_packet(pkt);

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

        if (is->paused || is->audioq.abort_request) {

            return -1;

        }

        /* read next packet */

        if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0)

            return -1;

        if (pkt->data == flush_pkt.data) {

            avcodec_flush_buffers(dec);

            flush_complete = 0;

        }

        *pkt_temp = *pkt;

        /* if update the audio clock with the pts */

        if (pkt->pts != AV_NOPTS_VALUE) {

            is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;

        }

    }

}


void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)

{

    int i;

	int data;

	OPLSAMPLE *buf = buffer;

	UINT32 amsCnt  = OPL->amsCnt;

	UINT32 vibCnt  = OPL->vibCnt;

	UINT8 rythm = OPL->rythm&0x20;

	OPL_CH *CH,*R_CH;

	if( (void *)OPL != cur_chip ){

		cur_chip = (void *)OPL;

		/* channel pointers */

		S_CH = OPL->P_CH;

		E_CH = &S_CH[9];

		/* rythm slot */

		SLOT7_1 = &S_CH[7].SLOT[SLOT1];

		SLOT7_2 = &S_CH[7].SLOT[SLOT2];

		SLOT8_1 = &S_CH[8].SLOT[SLOT1];

		SLOT8_2 = &S_CH[8].SLOT[SLOT2];

		/* LFO state */

		amsIncr = OPL->amsIncr;

		vibIncr = OPL->vibIncr;

		ams_table = OPL->ams_table;

		vib_table = OPL->vib_table;

	}

	R_CH = rythm ? &S_CH[6] : E_CH;

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

	{

		/*            channel A         channel B         channel C      */

		/* LFO */

		ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];

		vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];

		outd[0] = 0;

		/* FM part */

		for(CH=S_CH ; CH < R_CH ; CH++)

			OPL_CALC_CH(CH);

		/* Rythn part */

		if(rythm)

			OPL_CALC_RH(S_CH);

		/* limit check */

		data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );

		/* store to sound buffer */

		buf[i] = data >> OPL_OUTSB;

	}

	OPL->amsCnt = amsCnt;

	OPL->vibCnt = vibCnt;

#ifdef OPL_OUTPUT_LOG

	if(opl_dbg_fp)

	{

		for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)

			if( opl_dbg_opl[opl_dbg_chip] == OPL) break;

		fprintf(opl_dbg_fp,"%c%c%c",0x20+opl_dbg_chip,length&0xff,length/256);

	}

#endif

}


static void omap_tipb_bridge_write(void *opaque, target_phys_addr_t addr,

                                   uint64_t value, unsigned size)

{

    struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;

    if (size < 2) {

        return omap_badwidth_write16(opaque, addr, value);

    }

    switch (addr) {

    case 0x00:	/* TIPB_CNTL */

        s->control = value & 0xffff;

        break;

    case 0x04:	/* TIPB_BUS_ALLOC */

        s->alloc = value & 0x003f;

        break;

    case 0x08:	/* MPU_TIPB_CNTL */

        s->buffer = value & 0x0003;

        break;

    case 0x0c:	/* ENHANCED_TIPB_CNTL */

        s->width_intr = !(value & 2);

        s->enh_control = value & 0x000f;

        break;

    case 0x10:	/* ADDRESS_DBG */

    case 0x14:	/* DATA_DEBUG_LOW */

    case 0x18:	/* DATA_DEBUG_HIGH */

    case 0x1c:	/* DEBUG_CNTR_SIG */

        OMAP_RO_REG(addr);

        break;

    default:

        OMAP_BAD_REG(addr);

    }

}


PCIDevice *pci_register_device(PCIBus *bus, const char *name,

                               int instance_size, int devfn,

                               PCIConfigReadFunc *config_read,

                               PCIConfigWriteFunc *config_write)

{

    PCIDevice *pci_dev;

    pci_dev = qemu_mallocz(instance_size);

    pci_dev = do_pci_register_device(pci_dev, bus, name, devfn,

                                     config_read, config_write);

    return pci_dev;

}


int64 float64_to_int64_round_to_zero( float64 a STATUS_PARAM )

{

    flag aSign;

    int16 aExp, shiftCount;

    bits64 aSig;

    int64 z;

    aSig = extractFloat64Frac( a );

    aExp = extractFloat64Exp( a );

    aSign = extractFloat64Sign( a );

    if ( aExp ) aSig |= LIT64( 0x0010000000000000 );

    shiftCount = aExp - 0x433;

    if ( 0 <= shiftCount ) {

        if ( 0x43E <= aExp ) {

            if ( a != LIT64( 0xC3E0000000000000 ) ) {

                float_raise( float_flag_invalid STATUS_VAR);

                if (    ! aSign

                     || (    ( aExp == 0x7FF )

                          && ( aSig != LIT64( 0x0010000000000000 ) ) )

                   ) {

                    return LIT64( 0x7FFFFFFFFFFFFFFF );

                }

            }

            return (sbits64) LIT64( 0x8000000000000000 );

        }

        z = aSig<<shiftCount;

    }

    else {

        if ( aExp < 0x3FE ) {

            if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;

            return 0;

        }

        z = aSig>>( - shiftCount );

        if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) {

            STATUS(float_exception_flags) |= float_flag_inexact;

        }

    }

    if ( aSign ) z = - z;

    return z;

}


static void icount_warp_rt(void)

{

    unsigned seq;

    int64_t warp_start;

    /* The icount_warp_timer is rescheduled soon after vm_clock_warp_start

     * changes from -1 to another value, so the race here is okay.

     */

    do {

        seq = seqlock_read_begin(&timers_state.vm_clock_seqlock);

        warp_start = vm_clock_warp_start;

    } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, seq));

    if (warp_start == -1) {

        return;

    }

    seqlock_write_begin(&timers_state.vm_clock_seqlock);

    if (runstate_is_running()) {

        int64_t clock = REPLAY_CLOCK(REPLAY_CLOCK_VIRTUAL_RT,

                                     cpu_get_clock_locked());

        int64_t warp_delta;

        warp_delta = clock - vm_clock_warp_start;

        if (use_icount == 2) {

            /*

             * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too

             * far ahead of real time.

             */

            int64_t cur_icount = cpu_get_icount_locked();

            int64_t delta = clock - cur_icount;

            warp_delta = MIN(warp_delta, delta);

        }

        timers_state.qemu_icount_bias += warp_delta;

    }

    vm_clock_warp_start = -1;

    seqlock_write_end(&timers_state.vm_clock_seqlock);

    if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {

        qemu_clock_notify(QEMU_CLOCK_VIRTUAL);

    }

}


void bdrv_aio_cancel(BlockAIOCB *acb)

{

    qemu_aio_ref(acb);

    bdrv_aio_cancel_async(acb);

    while (acb->refcnt > 1) {

        if (acb->aiocb_info->get_aio_context) {

            aio_poll(acb->aiocb_info->get_aio_context(acb), true);

        } else if (acb->bs) {

            aio_poll(bdrv_get_aio_context(acb->bs), true);

        } else {

            abort();

        }

    }

    qemu_aio_unref(acb);

}


static void vnc_listen_read(void *opaque, bool websocket)

{

    VncDisplay *vs = opaque;

    struct sockaddr_in addr;

    socklen_t addrlen = sizeof(addr);

    int csock;

    /* Catch-up */

    graphic_hw_update(vs->dcl.con);

#ifdef CONFIG_VNC_WS

    if (websocket) {

        csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);

    } else

#endif /* CONFIG_VNC_WS */

    {

        csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);

    }

    if (csock != -1) {

        socket_set_nodelay(csock);

        vnc_connect(vs, csock, false, websocket);

    }

}


static void gen_sraq(DisasContext *ctx)

{

    int l1 = gen_new_label();

    int l2 = gen_new_label();

    TCGv t0 = tcg_temp_new();

    TCGv t1 = tcg_temp_local_new();

    TCGv t2 = tcg_temp_local_new();

    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);

    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);

    tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);

    tcg_gen_subfi_tl(t2, 32, t2);

    tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);

    tcg_gen_or_tl(t0, t0, t2);

    gen_store_spr(SPR_MQ, t0);

    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);

    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);

    tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);

    tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);

    gen_set_label(l1);

    tcg_temp_free(t0);

    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);

    tcg_gen_movi_tl(cpu_ca, 0);

    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);

    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);

    tcg_gen_movi_tl(cpu_ca, 1);

    gen_set_label(l2);

    tcg_temp_free(t1);

    tcg_temp_free(t2);

    if (unlikely(Rc(ctx->opcode) != 0))

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

}


static void reverse_dc_prediction(Vp3DecodeContext *s,

                                  int first_fragment,

                                  int fragment_width,

                                  int fragment_height)

{

#define PUL 8

#define PU 4

#define PUR 2

#define PL 1

    int x, y;

    int i = first_fragment;

    int predicted_dc;

    /* DC values for the left, up-left, up, and up-right fragments */

    int vl, vul, vu, vur;

    /* indexes for the left, up-left, up, and up-right fragments */

    int l, ul, u, ur;

    /*

     * The 6 fields mean:

     *   0: up-left multiplier

     *   1: up multiplier

     *   2: up-right multiplier

     *   3: left multiplier

     */

    static const int predictor_transform[16][4] = {

        {  0,  0,  0,  0},

        {  0,  0,  0,128},        // PL

        {  0,  0,128,  0},        // PUR

        {  0,  0, 53, 75},        // PUR|PL

        {  0,128,  0,  0},        // PU

        {  0, 64,  0, 64},        // PU|PL

        {  0,128,  0,  0},        // PU|PUR

        {  0,  0, 53, 75},        // PU|PUR|PL

        {128,  0,  0,  0},        // PUL

        {  0,  0,  0,128},        // PUL|PL

        { 64,  0, 64,  0},        // PUL|PUR

        {  0,  0, 53, 75},        // PUL|PUR|PL

        {  0,128,  0,  0},        // PUL|PU

       {-104,116,  0,116},        // PUL|PU|PL

        { 24, 80, 24,  0},        // PUL|PU|PUR

       {-104,116,  0,116}         // PUL|PU|PUR|PL

    };

    /* This table shows which types of blocks can use other blocks for

     * prediction. For example, INTRA is the only mode in this table to

     * have a frame number of 0. That means INTRA blocks can only predict

     * from other INTRA blocks. There are 2 golden frame coding types;

     * blocks encoding in these modes can only predict from other blocks

     * that were encoded with these 1 of these 2 modes. */

    static const unsigned char compatible_frame[8] = {

        1,    /* MODE_INTER_NO_MV */

        0,    /* MODE_INTRA */

        1,    /* MODE_INTER_PLUS_MV */

        1,    /* MODE_INTER_LAST_MV */

        1,    /* MODE_INTER_PRIOR_MV */

        2,    /* MODE_USING_GOLDEN */

        2,    /* MODE_GOLDEN_MV */

        1     /* MODE_INTER_FOUR_MV */

    };

    int current_frame_type;

    /* there is a last DC predictor for each of the 3 frame types */

    short last_dc[3];

    int transform = 0;

    vul = vu = vur = vl = 0;

    last_dc[0] = last_dc[1] = last_dc[2] = 0;

    /* for each fragment row... */

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

        /* for each fragment in a row... */

        for (x = 0; x < fragment_width; x++, i++) {

            /* reverse prediction if this block was coded */

            if (s->all_fragments[i].coding_method != MODE_COPY) {

                current_frame_type =

                    compatible_frame[s->all_fragments[i].coding_method];

                transform= 0;

                if(x){

                    l= i-1;

                    vl = DC_COEFF(l);

                    if(FRAME_CODED(l) && COMPATIBLE_FRAME(l))

                        transform |= PL;

                }

                if(y){

                    u= i-fragment_width;

                    vu = DC_COEFF(u);

                    if(FRAME_CODED(u) && COMPATIBLE_FRAME(u))

                        transform |= PU;

                    if(x){

                        ul= i-fragment_width-1;

                        vul = DC_COEFF(ul);

                        if(FRAME_CODED(ul) && COMPATIBLE_FRAME(ul))

                            transform |= PUL;

                    }

                    if(x + 1 < fragment_width){

                        ur= i-fragment_width+1;

                        vur = DC_COEFF(ur);

                        if(FRAME_CODED(ur) && COMPATIBLE_FRAME(ur))

                            transform |= PUR;

                    }

                }

                if (transform == 0) {

                    /* if there were no fragments to predict from, use last

                     * DC saved */

                    predicted_dc = last_dc[current_frame_type];

                } else {

                    /* apply the appropriate predictor transform */

                    predicted_dc =

                        (predictor_transform[transform][0] * vul) +

                        (predictor_transform[transform][1] * vu) +

                        (predictor_transform[transform][2] * vur) +

                        (predictor_transform[transform][3] * vl);

                    predicted_dc /= 128;

                    /* check for outranging on the [ul u l] and

                     * [ul u ur l] predictors */

                    if ((transform == 13) || (transform == 15)) {

                        if (FFABS(predicted_dc - vu) > 128)

                            predicted_dc = vu;

                        else if (FFABS(predicted_dc - vl) > 128)

                            predicted_dc = vl;

                        else if (FFABS(predicted_dc - vul) > 128)

                            predicted_dc = vul;

                    }

                }

                /* at long last, apply the predictor */

                if(s->coeffs[i].index){

                    *s->next_coeff= s->coeffs[i];

                    s->coeffs[i].index=0;

                    s->coeffs[i].coeff=0;

                    s->coeffs[i].next= s->next_coeff++;

                }

                s->coeffs[i].coeff += predicted_dc;

                /* save the DC */

                last_dc[current_frame_type] = DC_COEFF(i);

                if(DC_COEFF(i) && !(s->coeff_counts[i]&127)){

                    s->coeff_counts[i]= 129;

//                    s->all_fragments[i].next_coeff= s->next_coeff;

                    s->coeffs[i].next= s->next_coeff;

                    (s->next_coeff++)->next=NULL;

                }

            }

        }

    }

}


static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)

{

    void **lp, **p;

    p = (void **)l1_phys_map;

#if TARGET_PHYS_ADDR_SPACE_BITS > 32

#if TARGET_PHYS_ADDR_SPACE_BITS > (32 + L1_BITS)

#error unsupported TARGET_PHYS_ADDR_SPACE_BITS

#endif

    lp = p + ((index >> (L1_BITS + L2_BITS)) & (L1_SIZE - 1));

    p = *lp;

    if (!p) {

        /* allocate if not found */

        if (!alloc)

            return NULL;

        p = qemu_vmalloc(sizeof(void *) * L1_SIZE);

        memset(p, 0, sizeof(void *) * L1_SIZE);

        *lp = p;

    }

#endif

    lp = p + ((index >> L2_BITS) & (L1_SIZE - 1));

    p = *lp;

    if (!p) {

        /* allocate if not found */

        if (!alloc)

            return NULL;

        p = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);

        memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE);

        *lp = p;

    }

    return ((PhysPageDesc *)p) + (index & (L2_SIZE - 1));

}