int ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number)

{

    int time_incr;

    int time_div, time_mod;

    if (s->pict_type == AV_PICTURE_TYPE_I) {

        if (!(s->avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {

            if (s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT)  // HACK, the reference sw is buggy

                mpeg4_encode_visual_object_header(s);

            if (s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || picture_number == 0)  // HACK, the reference sw is buggy

                mpeg4_encode_vol_header(s, 0, 0);

        }

        if (!(s->workaround_bugs & FF_BUG_MS))

            mpeg4_encode_gop_header(s);

    }

    s->partitioned_frame = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B;

    put_bits(&s->pb, 16, 0);                /* vop header */

    put_bits(&s->pb, 16, VOP_STARTCODE);    /* vop header */

    put_bits(&s->pb, 2, s->pict_type - 1);  /* pict type: I = 0 , P = 1 */

    time_div  = FFUDIV(s->time, s->avctx->time_base.den);

    time_mod  = FFUMOD(s->time, s->avctx->time_base.den);

    time_incr = time_div - s->last_time_base;

    av_assert0(time_incr >= 0);

    // This limits the frame duration to max 1 hour

    if (time_incr > 3600) {

        av_log(s->avctx, AV_LOG_ERROR, "time_incr %d too large\n", time_incr);

        return AVERROR(EINVAL);

    }

    while (time_incr--)

        put_bits(&s->pb, 1, 1);

    put_bits(&s->pb, 1, 0);

    put_bits(&s->pb, 1, 1);                             /* marker */

    put_bits(&s->pb, s->time_increment_bits, time_mod); /* time increment */

    put_bits(&s->pb, 1, 1);                             /* marker */

    put_bits(&s->pb, 1, 1);                             /* vop coded */

    if (s->pict_type == AV_PICTURE_TYPE_P) {

        put_bits(&s->pb, 1, s->no_rounding);    /* rounding type */

    }

    put_bits(&s->pb, 3, 0);     /* intra dc VLC threshold */

    if (!s->progressive_sequence) {

        put_bits(&s->pb, 1, s->current_picture_ptr->f->top_field_first);

        put_bits(&s->pb, 1, s->alternate_scan);

    }

    // FIXME sprite stuff

    put_bits(&s->pb, 5, s->qscale);

    if (s->pict_type != AV_PICTURE_TYPE_I)

        put_bits(&s->pb, 3, s->f_code);  /* fcode_for */

    if (s->pict_type == AV_PICTURE_TYPE_B)

        put_bits(&s->pb, 3, s->b_code);  /* fcode_back */

    return 0;

}


static int read_quant_table(RangeCoder *c, int16_t *quant_table, int scale){

    int v;

    int i=0;

    uint8_t state[CONTEXT_SIZE];

    memset(state, 128, sizeof(state));

    for(v=0; i<128 ; v++){

        int len= get_symbol(c, state, 0) + 1;

        if(len + i > 128) return -1;

        while(len--){

            quant_table[i] = scale*v;

            i++;

//printf("%2d ",v);

//if(i%16==0) printf("\n");

        }

    }

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

        quant_table[256-i]= -quant_table[i];

    }

    quant_table[128]= -quant_table[127];

    return 2*v - 1;

}


static int parse_read_intervals(const char *intervals_spec)

{

    int ret, n, i;

    char *p, *spec = av_strdup(intervals_spec);

    if (!spec)

        return AVERROR(ENOMEM);

    /* preparse specification, get number of intervals */

    for (n = 0, p = spec; *p; p++)

        if (*p == ',')

            n++;

    n++;

    read_intervals = av_malloc(n * sizeof(*read_intervals));

    if (!read_intervals) {

        ret = AVERROR(ENOMEM);

        goto end;

    }

    read_intervals_nb = n;

    /* parse intervals */

    p = spec;

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

        char *next = strchr(p, ',');

        if (next)

            *next++ = 0;

        read_intervals[i].id = i;

        ret = parse_read_interval(p, &read_intervals[i]);

        if (ret < 0) {

            av_log(NULL, AV_LOG_ERROR, "Error parsing read interval #%d '%s'\n",

                   i, p);

            goto end;

        }

        av_log(NULL, AV_LOG_VERBOSE, "Parsed log interval ");

        log_read_interval(&read_intervals[i], NULL, AV_LOG_VERBOSE);

        p = next;

        av_assert0(i <= read_intervals_nb);

    }

    av_assert0(i == read_intervals_nb);

end:

    av_free(spec);

    return ret;

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->no_hotplug = 1;

    k->init = piix4_pm_initfn;

    k->config_write = pm_write_config;

    k->vendor_id = PCI_VENDOR_ID_INTEL;

    k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3;

    k->revision = 0x03;

    k->class_id = PCI_CLASS_BRIDGE_OTHER;

    dc->desc = "PM";

    dc->no_user = 1;

    dc->vmsd = &vmstate_acpi;

    dc->props = piix4_pm_properties;

}


static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,

                              target_siginfo_t *info,

                              target_sigset_t *set, CPUARMState *env)

{

	struct rt_sigframe_v1 *frame;

	abi_ulong frame_addr = get_sigframe(ka, env, sizeof(*frame));

	struct target_sigaltstack stack;

	int i;

        abi_ulong info_addr, uc_addr;

	if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0))

            return /* 1 */;

        info_addr = frame_addr + offsetof(struct rt_sigframe_v1, info);

	__put_user(info_addr, &frame->pinfo);

        uc_addr = frame_addr + offsetof(struct rt_sigframe_v1, uc);

	__put_user(uc_addr, &frame->puc);

	copy_siginfo_to_user(&frame->info, info);

	/* Clear all the bits of the ucontext we don't use.  */

	memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));

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

        __put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);

        __put_user(target_sigaltstack_used.ss_size, &stack.ss_size);

        __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);

        memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));

	setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);

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

            if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))

                goto end;

        }

        setup_return(env, ka, &frame->retcode, frame_addr, usig,

                     frame_addr + offsetof(struct rt_sigframe_v1, retcode));

        env->regs[1] = info_addr;

        env->regs[2] = uc_addr;

end:

	unlock_user_struct(frame, frame_addr, 1);

}


static int alac_decode_frame(AVCodecContext *avctx,

                             void *outbuffer, int *outputsize,

                             AVPacket *avpkt)

{

    const uint8_t *inbuffer = avpkt->data;

    int input_buffer_size = avpkt->size;

    ALACContext *alac = avctx->priv_data;

    int channels;

    unsigned int outputsamples;

    int hassize;

    unsigned int readsamplesize;

    int isnotcompressed;

    uint8_t interlacing_shift;

    uint8_t interlacing_leftweight;

    int i, ch;

    /* short-circuit null buffers */

    if (!inbuffer || !input_buffer_size)

        return -1;

    init_get_bits(&alac->gb, inbuffer, input_buffer_size * 8);

    channels = get_bits(&alac->gb, 3) + 1;

    if (channels != avctx->channels) {

        av_log(avctx, AV_LOG_ERROR, "frame header channel count mismatch\n");

        return AVERROR_INVALIDDATA;

    }

    /* 2^result = something to do with output waiting.

     * perhaps matters if we read > 1 frame in a pass?

     */

    skip_bits(&alac->gb, 4);

    skip_bits(&alac->gb, 12); /* unknown, skip 12 bits */

    /* the output sample size is stored soon */

    hassize = get_bits1(&alac->gb);

    alac->extra_bits = get_bits(&alac->gb, 2) << 3;

    /* whether the frame is compressed */

    isnotcompressed = get_bits1(&alac->gb);

    if (hassize) {

        /* now read the number of samples as a 32bit integer */

        outputsamples = get_bits_long(&alac->gb, 32);

        if(outputsamples > alac->setinfo_max_samples_per_frame){

            av_log(avctx, AV_LOG_ERROR, "outputsamples %d > %d\n", outputsamples, alac->setinfo_max_samples_per_frame);

            return -1;

        }

    } else

        outputsamples = alac->setinfo_max_samples_per_frame;

    alac->bytespersample = channels * av_get_bytes_per_sample(avctx->sample_fmt);

    if(outputsamples > *outputsize / alac->bytespersample){

        av_log(avctx, AV_LOG_ERROR, "sample buffer too small\n");

        return -1;

    }

    *outputsize = outputsamples * alac->bytespersample;

    readsamplesize = alac->setinfo_sample_size - alac->extra_bits + channels - 1;

    if (readsamplesize > MIN_CACHE_BITS) {

        av_log(avctx, AV_LOG_ERROR, "readsamplesize too big (%d)\n", readsamplesize);

        return -1;

    }

    if (!isnotcompressed) {

        /* so it is compressed */

        int16_t predictor_coef_table[MAX_CHANNELS][32];

        int predictor_coef_num[MAX_CHANNELS];

        int prediction_type[MAX_CHANNELS];

        int prediction_quantitization[MAX_CHANNELS];

        int ricemodifier[MAX_CHANNELS];

        interlacing_shift = get_bits(&alac->gb, 8);

        interlacing_leftweight = get_bits(&alac->gb, 8);

        for (ch = 0; ch < channels; ch++) {

            prediction_type[ch] = get_bits(&alac->gb, 4);

            prediction_quantitization[ch] = get_bits(&alac->gb, 4);

            ricemodifier[ch] = get_bits(&alac->gb, 3);

            predictor_coef_num[ch] = get_bits(&alac->gb, 5);

            /* read the predictor table */

            for (i = 0; i < predictor_coef_num[ch]; i++)

                predictor_coef_table[ch][i] = (int16_t)get_bits(&alac->gb, 16);

        }

        if (alac->extra_bits) {

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

                for (ch = 0; ch < channels; ch++)

                    alac->extra_bits_buffer[ch][i] = get_bits(&alac->gb, alac->extra_bits);

            }

        }

        for (ch = 0; ch < channels; ch++) {

            bastardized_rice_decompress(alac,

                                        alac->predicterror_buffer[ch],

                                        outputsamples,

                                        readsamplesize,

                                        alac->setinfo_rice_initialhistory,

                                        alac->setinfo_rice_kmodifier,

                                        ricemodifier[ch] * alac->setinfo_rice_historymult / 4,

                                        (1 << alac->setinfo_rice_kmodifier) - 1);

            if (prediction_type[ch] == 0) {

                /* adaptive fir */

                predictor_decompress_fir_adapt(alac->predicterror_buffer[ch],

                                               alac->outputsamples_buffer[ch],

                                               outputsamples,

                                               readsamplesize,

                                               predictor_coef_table[ch],

                                               predictor_coef_num[ch],

                                               prediction_quantitization[ch]);

            } else {

                av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type[ch]);

                /* I think the only other prediction type (or perhaps this is

                 * just a boolean?) runs adaptive fir twice.. like:

                 * predictor_decompress_fir_adapt(predictor_error, tempout, ...)

                 * predictor_decompress_fir_adapt(predictor_error, outputsamples ...)

                 * little strange..

                 */

            }

        }

    } else {

        /* not compressed, easy case */

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

            for (ch = 0; ch < channels; ch++) {

                alac->outputsamples_buffer[ch][i] = get_sbits_long(&alac->gb,

                                                                   alac->setinfo_sample_size);

            }

        }

        alac->extra_bits = 0;

        interlacing_shift = 0;

        interlacing_leftweight = 0;

    }

    if (get_bits(&alac->gb, 3) != 7)

        av_log(avctx, AV_LOG_ERROR, "Error : Wrong End Of Frame\n");

    if (channels == 2 && interlacing_leftweight) {

        decorrelate_stereo(alac->outputsamples_buffer, outputsamples,

                           interlacing_shift, interlacing_leftweight);

    }

    if (alac->extra_bits) {

        append_extra_bits(alac->outputsamples_buffer, alac->extra_bits_buffer,

                          alac->extra_bits, alac->numchannels, outputsamples);

    }

    switch(alac->setinfo_sample_size) {

    case 16:

        if (channels == 2) {

            interleave_stereo_16(alac->outputsamples_buffer, outbuffer,

                                 outputsamples);

        } else {

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

                ((int16_t*)outbuffer)[i] = alac->outputsamples_buffer[0][i];

            }

        }

        break;

    case 24:

        if (channels == 2) {

            interleave_stereo_24(alac->outputsamples_buffer, outbuffer,

                                 outputsamples);

        } else {

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

                ((int32_t *)outbuffer)[i] = alac->outputsamples_buffer[0][i] << 8;

        }

        break;

    }

    if (input_buffer_size * 8 - get_bits_count(&alac->gb) > 8)

        av_log(avctx, AV_LOG_ERROR, "Error : %d bits left\n", input_buffer_size * 8 - get_bits_count(&alac->gb));

    return input_buffer_size;

}


static int do_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,

                               int64_t count, int flags, int64_t *total)

{

    Coroutine *co;

    CoWriteZeroes data = {

        .blk    = blk,

        .offset = offset,

        .count  = count,

        .total  = total,

        .flags  = flags,

        .done   = false,

    };

    if (count >> BDRV_SECTOR_BITS > INT_MAX) {

        return -ERANGE;

    }

    co = qemu_coroutine_create(co_pwrite_zeroes_entry);

    qemu_coroutine_enter(co, &data);

    while (!data.done) {

        aio_poll(blk_get_aio_context(blk), true);

    }

    if (data.ret < 0) {

        return data.ret;

    } else {

        return 1;

    }

}


static void idreg_init(target_phys_addr_t addr)

{

    DeviceState *dev;

    SysBusDevice *s;

    dev = qdev_create(NULL, "macio_idreg");

    qdev_init(dev);

    s = sysbus_from_qdev(dev);

    sysbus_mmio_map(s, 0, addr);

    cpu_physical_memory_write_rom(addr, idreg_data, sizeof(idreg_data));

}


static void fdctrl_start_transfer (fdctrl_t *fdctrl, int direction)

{

    fdrive_t *cur_drv;

    uint8_t kh, kt, ks;

    int did_seek;

    fdctrl->cur_drv = fdctrl->fifo[1] & 1;

    cur_drv = get_cur_drv(fdctrl);

    kt = fdctrl->fifo[2];

    kh = fdctrl->fifo[3];

    ks = fdctrl->fifo[4];

    FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",

                   fdctrl->cur_drv, kh, kt, ks,

                   _fd_sector(kh, kt, ks, cur_drv->last_sect));

    did_seek = 0;

    switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & 0x40)) {

    case 2:

        /* sect too big */

        fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);

        fdctrl->fifo[3] = kt;

        fdctrl->fifo[4] = kh;

        fdctrl->fifo[5] = ks;

        return;

    case 3:

        /* track too big */

        fdctrl_stop_transfer(fdctrl, 0x40, 0x80, 0x00);

        fdctrl->fifo[3] = kt;

        fdctrl->fifo[4] = kh;

        fdctrl->fifo[5] = ks;

        return;

    case 4:

        /* No seek enabled */

        fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);

        fdctrl->fifo[3] = kt;

        fdctrl->fifo[4] = kh;

        fdctrl->fifo[5] = ks;

        return;

    case 1:

        did_seek = 1;

        break;

    default:

        break;

    }

    /* Set the FIFO state */

    fdctrl->data_dir = direction;

    fdctrl->data_pos = 0;

    FD_SET_STATE(fdctrl->data_state, FD_STATE_DATA); /* FIFO ready for data */

    if (fdctrl->fifo[0] & 0x80)

        fdctrl->data_state |= FD_STATE_MULTI;

    else

        fdctrl->data_state &= ~FD_STATE_MULTI;

    if (did_seek)

        fdctrl->data_state |= FD_STATE_SEEK;

    else

        fdctrl->data_state &= ~FD_STATE_SEEK;

    if (fdctrl->fifo[5] == 00) {

        fdctrl->data_len = fdctrl->fifo[8];

    } else {

	int tmp;

        fdctrl->data_len = 128 << fdctrl->fifo[5];

        tmp = (cur_drv->last_sect - ks + 1);

        if (fdctrl->fifo[0] & 0x80)

            tmp += cur_drv->last_sect;

	fdctrl->data_len *= tmp;

    }

    fdctrl->eot = fdctrl->fifo[6];

    if (fdctrl->dma_en) {

        int dma_mode;

        /* DMA transfer are enabled. Check if DMA channel is well programmed */

        dma_mode = DMA_get_channel_mode(fdctrl->dma_chann);

        dma_mode = (dma_mode >> 2) & 3;

        FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",

		       dma_mode, direction,

                       (128 << fdctrl->fifo[5]) *

		       (cur_drv->last_sect - ks + 1), fdctrl->data_len);

        if (((direction == FD_DIR_SCANE || direction == FD_DIR_SCANL ||

              direction == FD_DIR_SCANH) && dma_mode == 0) ||

            (direction == FD_DIR_WRITE && dma_mode == 2) ||

            (direction == FD_DIR_READ && dma_mode == 1)) {

            /* No access is allowed until DMA transfer has completed */

            fdctrl->state |= FD_CTRL_BUSY;

            /* Now, we just have to wait for the DMA controller to

             * recall us...

             */

            DMA_hold_DREQ(fdctrl->dma_chann);

            DMA_schedule(fdctrl->dma_chann);

            return;

        } else {

	    FLOPPY_ERROR("dma_mode=%d direction=%d\n", dma_mode, direction);

        }

    }

    FLOPPY_DPRINTF("start non-DMA transfer\n");

    /* IO based transfer: calculate len */

    fdctrl_raise_irq(fdctrl, 0x00);

    return;

}


int qemu_chr_open_msmouse(QemuOpts *opts, CharDriverState **_chr)

{

    CharDriverState *chr;

    chr = g_malloc0(sizeof(CharDriverState));

    chr->chr_write = msmouse_chr_write;

    chr->chr_close = msmouse_chr_close;

    qemu_add_mouse_event_handler(msmouse_event, chr, 0, "QEMU Microsoft Mouse");

    *_chr = chr;

    return 0;

}


static char *var_read_string(AVIOContext *pb, int size)

{

    int n;

    char *str = av_malloc(size + 1);

    if (!str)

        return NULL;

    n = avio_get_str(pb, size, str, size + 1);

    if (n < size)

        avio_skip(pb, size - n);

    return str;

}


static char *ctime1(char *buf2, int buf_size)

{

    time_t ti;

    char *p;

    ti = time(NULL);

    p = ctime(&ti);

    av_strlcpy(buf2, p, buf_size);

    p = buf2 + strlen(p) - 1;

    if (*p == '\n')

        *p = '\0';

    return buf2;

}


void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],

                       uint16_t (*qmat16)[2][64],

                       const uint16_t *quant_matrix,

                       int bias, int qmin, int qmax, int intra)

{

    FDCTDSPContext *fdsp = &s->fdsp;

    int qscale;

    int shift = 0;

    for (qscale = qmin; qscale <= qmax; qscale++) {

        int i;

        int qscale2;

        if (s->q_scale_type) qscale2 = ff_mpeg2_non_linear_qscale[qscale];

        else                 qscale2 = qscale << 1;

        if (fdsp->fdct == ff_jpeg_fdct_islow_8  ||

#if CONFIG_FAANDCT

            fdsp->fdct == ff_faandct            ||

#endif /* CONFIG_FAANDCT */

            fdsp->fdct == ff_jpeg_fdct_islow_10) {

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

                const int j = s->idsp.idct_permutation[i];

                int64_t den = (int64_t) qscale2 * quant_matrix[j];

                /* 16 <= qscale * quant_matrix[i] <= 7905

                 * Assume x = ff_aanscales[i] * qscale * quant_matrix[i]

                 *             19952 <=              x  <= 249205026

                 * (1 << 36) / 19952 >= (1 << 36) / (x) >= (1 << 36) / 249205026

                 *           3444240 >= (1 << 36) / (x) >= 275 */

                qmat[qscale][i] = (int)((UINT64_C(2) << QMAT_SHIFT) / den);

            }

        } else if (fdsp->fdct == ff_fdct_ifast) {

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

                const int j = s->idsp.idct_permutation[i];

                int64_t den = ff_aanscales[i] * (int64_t) qscale2 * quant_matrix[j];

                /* 16 <= qscale * quant_matrix[i] <= 7905

                 * Assume x = ff_aanscales[i] * qscale * quant_matrix[i]

                 *             19952 <=              x  <= 249205026

                 * (1 << 36) / 19952 >= (1 << 36) / (x) >= (1 << 36) / 249205026

                 *           3444240 >= (1 << 36) / (x) >= 275 */

                qmat[qscale][i] = (int)((UINT64_C(2) << (QMAT_SHIFT + 14)) / den);

            }

        } else {

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

                const int j = s->idsp.idct_permutation[i];

                int64_t den = (int64_t) qscale2 * quant_matrix[j];

                /* We can safely suppose that 16 <= quant_matrix[i] <= 255

                 * Assume x = qscale * quant_matrix[i]

                 * So             16 <=              x  <= 7905

                 * so (1 << 19) / 16 >= (1 << 19) / (x) >= (1 << 19) / 7905

                 * so          32768 >= (1 << 19) / (x) >= 67 */

                qmat[qscale][i] = (int)((UINT64_C(2) << QMAT_SHIFT) / den);

                //qmat  [qscale][i] = (1 << QMAT_SHIFT_MMX) /

                //                    (qscale * quant_matrix[i]);

                qmat16[qscale][0][i] = (2 << QMAT_SHIFT_MMX) / den;

                if (qmat16[qscale][0][i] == 0 ||

                    qmat16[qscale][0][i] == 128 * 256)

                    qmat16[qscale][0][i] = 128 * 256 - 1;

                qmat16[qscale][1][i] =

                    ROUNDED_DIV(bias << (16 - QUANT_BIAS_SHIFT),

                                qmat16[qscale][0][i]);

            }

        }

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

            int64_t max = 8191;

            if (fdsp->fdct == ff_fdct_ifast) {

                max = (8191LL * ff_aanscales[i]) >> 14;

            }

            while (((max * qmat[qscale][i]) >> shift) > INT_MAX) {

                shift++;

            }

        }

    }

    if (shift) {

        av_log(NULL, AV_LOG_INFO,

               "Warning, QMAT_SHIFT is larger than %d, overflows possible\n",

               QMAT_SHIFT - shift);

    }

}


static void __attribute__((constructor)) coroutine_init(void)

{

    if (!g_thread_supported()) {

        g_thread_init(NULL);

    }

    coroutine_cond = g_cond_new();

}


static void loadvm_postcopy_handle_run_bh(void *opaque)

{

    Error *local_err = NULL;

    MigrationIncomingState *mis = opaque;

    /* TODO we should move all of this lot into postcopy_ram.c or a shared code

     * in migration.c

     */

    cpu_synchronize_all_post_init();

    qemu_announce_self();

    /* Make sure all file formats flush their mutable metadata */

    bdrv_invalidate_cache_all(&local_err);

    if (local_err) {

        error_report_err(local_err);

    }

    trace_loadvm_postcopy_handle_run_cpu_sync();

    cpu_synchronize_all_post_init();

    trace_loadvm_postcopy_handle_run_vmstart();

    if (autostart) {

        /* Hold onto your hats, starting the CPU */

        vm_start();

    } else {

        /* leave it paused and let management decide when to start the CPU */

        runstate_set(RUN_STATE_PAUSED);

    }

    qemu_bh_delete(mis->bh);

}


static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,

                                            int64_t sector_num,

                                            QEMUIOVector *qiov,

                                            int nb_sectors,

                                            BlockDriverCompletionFunc *cb,

                                            void *opaque,

                                            int is_write)

{

    BlockDriverAIOCBSync *acb;

    acb = qemu_aio_get(&bdrv_em_aiocb_info, bs, cb, opaque);

    acb->is_write = is_write;

    acb->qiov = qiov;

    acb->bounce = qemu_blockalign(bs, qiov->size);

    acb->bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_aio_bh_cb, acb);

    if (is_write) {

        qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);

        acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors);

    } else {

        acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors);

    }

    qemu_bh_schedule(acb->bh);

    return &acb->common;

}


static int vnc_display_listen_addr(VncDisplay *vd,

                                   SocketAddress *addr,

                                   const char *name,

                                   QIOChannelSocket ***lsock,

                                   guint **lsock_tag,

                                   size_t *nlsock,

                                   Error **errp)

{

    QIODNSResolver *resolver = qio_dns_resolver_get_instance();

    SocketAddress **rawaddrs = NULL;

    size_t nrawaddrs = 0;

    Error *listenerr = NULL;

    bool listening = false;

    size_t i;

    if (qio_dns_resolver_lookup_sync(resolver, addr, &nrawaddrs,

                                     &rawaddrs, errp) < 0) {

        return -1;

    }

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

        QIOChannelSocket *sioc = qio_channel_socket_new();

        qio_channel_set_name(QIO_CHANNEL(sioc), name);

        if (qio_channel_socket_listen_sync(

                sioc, rawaddrs[i], listenerr == NULL ? &listenerr : NULL) < 0) {

            continue;

        }

        listening = true;

        (*nlsock)++;

        *lsock = g_renew(QIOChannelSocket *, *lsock, *nlsock);

        *lsock_tag = g_renew(guint, *lsock_tag, *nlsock);

        (*lsock)[*nlsock - 1] = sioc;

        (*lsock_tag)[*nlsock - 1] = 0;

    }

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

        qapi_free_SocketAddress(rawaddrs[i]);

    }

    g_free(rawaddrs);

    if (listenerr) {

        if (!listening) {

            error_propagate(errp, listenerr);

            return -1;

        } else {

            error_free(listenerr);

        }

    }

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

        (*lsock_tag)[i] = qio_channel_add_watch(

            QIO_CHANNEL((*lsock)[i]),

            G_IO_IN, vnc_listen_io, vd, NULL);

    }

    return 0;

}


static av_cold int cook_decode_init(AVCodecContext *avctx)

{

    COOKContext *q = avctx->priv_data;

    const uint8_t *edata_ptr = avctx->extradata;

    const uint8_t *edata_ptr_end = edata_ptr + avctx->extradata_size;

    int extradata_size = avctx->extradata_size;

    int s = 0;

    unsigned int channel_mask = 0;

    int samples_per_frame;

    int ret;

    q->avctx = avctx;

    /* Take care of the codec specific extradata. */

    if (extradata_size < 8) {

        av_log(avctx, AV_LOG_ERROR, "Necessary extradata missing!\n");

        return AVERROR_INVALIDDATA;

    }

    av_log(avctx, AV_LOG_DEBUG, "codecdata_length=%d\n", avctx->extradata_size);

    /* Take data from the AVCodecContext (RM container). */

    if (!avctx->channels) {

        av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");

        return AVERROR_INVALIDDATA;

    }

    /* Initialize RNG. */

    av_lfg_init(&q->random_state, 0);

    ff_audiodsp_init(&q->adsp);

    while (edata_ptr < edata_ptr_end) {

        /* 8 for mono, 16 for stereo, ? for multichannel

           Swap to right endianness so we don't need to care later on. */

        if (extradata_size >= 8) {

            q->subpacket[s].cookversion = bytestream_get_be32(&edata_ptr);

            samples_per_frame           = bytestream_get_be16(&edata_ptr);

            q->subpacket[s].subbands = bytestream_get_be16(&edata_ptr);

            extradata_size -= 8;

        }

        if (extradata_size >= 8) {

            bytestream_get_be32(&edata_ptr);    // Unknown unused

            q->subpacket[s].js_subband_start = bytestream_get_be16(&edata_ptr);

            q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr);

            extradata_size -= 8;

        }

        /* Initialize extradata related variables. */

        q->subpacket[s].samples_per_channel = samples_per_frame / avctx->channels;

        q->subpacket[s].bits_per_subpacket = avctx->block_align * 8;

        /* Initialize default data states. */

        q->subpacket[s].log2_numvector_size = 5;

        q->subpacket[s].total_subbands = q->subpacket[s].subbands;

        q->subpacket[s].num_channels = 1;

        /* Initialize version-dependent variables */

        av_log(avctx, AV_LOG_DEBUG, "subpacket[%i].cookversion=%x\n", s,

               q->subpacket[s].cookversion);

        q->subpacket[s].joint_stereo = 0;

        switch (q->subpacket[s].cookversion) {

        case MONO:

            if (avctx->channels != 1) {

                avpriv_request_sample(avctx, "Container channels != 1");

                return AVERROR_PATCHWELCOME;

            }

            av_log(avctx, AV_LOG_DEBUG, "MONO\n");

            break;

        case STEREO:

            if (avctx->channels != 1) {

                q->subpacket[s].bits_per_subpdiv = 1;

                q->subpacket[s].num_channels = 2;

            }

            av_log(avctx, AV_LOG_DEBUG, "STEREO\n");

            break;

        case JOINT_STEREO:

            if (avctx->channels != 2) {

                avpriv_request_sample(avctx, "Container channels != 2");

                return AVERROR_PATCHWELCOME;

            }

            av_log(avctx, AV_LOG_DEBUG, "JOINT_STEREO\n");

            if (avctx->extradata_size >= 16) {

                q->subpacket[s].total_subbands = q->subpacket[s].subbands +

                                                 q->subpacket[s].js_subband_start;

                q->subpacket[s].joint_stereo = 1;

                q->subpacket[s].num_channels = 2;

            }

            if (q->subpacket[s].samples_per_channel > 256) {

                q->subpacket[s].log2_numvector_size = 6;

            }

            if (q->subpacket[s].samples_per_channel > 512) {

                q->subpacket[s].log2_numvector_size = 7;

            }

            break;

        case MC_COOK:

            av_log(avctx, AV_LOG_DEBUG, "MULTI_CHANNEL\n");

            if (extradata_size >= 4)

                channel_mask |= q->subpacket[s].channel_mask = bytestream_get_be32(&edata_ptr);

            if (av_get_channel_layout_nb_channels(q->subpacket[s].channel_mask) > 1) {

                q->subpacket[s].total_subbands = q->subpacket[s].subbands +

                                                 q->subpacket[s].js_subband_start;

                q->subpacket[s].joint_stereo = 1;

                q->subpacket[s].num_channels = 2;

                q->subpacket[s].samples_per_channel = samples_per_frame >> 1;

                if (q->subpacket[s].samples_per_channel > 256) {

                    q->subpacket[s].log2_numvector_size = 6;

                }

                if (q->subpacket[s].samples_per_channel > 512) {

                    q->subpacket[s].log2_numvector_size = 7;

                }

            } else

                q->subpacket[s].samples_per_channel = samples_per_frame;

            break;

        default:

            avpriv_request_sample(avctx, "Cook version %d",

                                  q->subpacket[s].cookversion);

            return AVERROR_PATCHWELCOME;

        }

        if (s > 1 && q->subpacket[s].samples_per_channel != q->samples_per_channel) {

            av_log(avctx, AV_LOG_ERROR, "different number of samples per channel!\n");

            return AVERROR_INVALIDDATA;

        } else

            q->samples_per_channel = q->subpacket[0].samples_per_channel;

        /* Initialize variable relations */

        q->subpacket[s].numvector_size = (1 << q->subpacket[s].log2_numvector_size);

        /* Try to catch some obviously faulty streams, otherwise it might be exploitable */

        if (q->subpacket[s].total_subbands > 53) {

            avpriv_request_sample(avctx, "total_subbands > 53");

            return AVERROR_PATCHWELCOME;

        }

        if ((q->subpacket[s].js_vlc_bits > 6) ||

            (q->subpacket[s].js_vlc_bits < 2 * q->subpacket[s].joint_stereo)) {

            av_log(avctx, AV_LOG_ERROR, "js_vlc_bits = %d, only >= %d and <= 6 allowed!\n",

                   q->subpacket[s].js_vlc_bits, 2 * q->subpacket[s].joint_stereo);

            return AVERROR_INVALIDDATA;

        }

        if (q->subpacket[s].subbands > 50) {

            avpriv_request_sample(avctx, "subbands > 50");

            return AVERROR_PATCHWELCOME;

        }

        q->subpacket[s].gains1.now      = q->subpacket[s].gain_1;

        q->subpacket[s].gains1.previous = q->subpacket[s].gain_2;

        q->subpacket[s].gains2.now      = q->subpacket[s].gain_3;

        q->subpacket[s].gains2.previous = q->subpacket[s].gain_4;

        q->num_subpackets++;

        s++;

        if (s > MAX_SUBPACKETS) {

            avpriv_request_sample(avctx, "subpackets > %d", MAX_SUBPACKETS);

            return AVERROR_PATCHWELCOME;

        }

    }

    /* Generate tables */

    init_pow2table();

    init_gain_table(q);

    init_cplscales_table(q);

    if ((ret = init_cook_vlc_tables(q)))

        return ret;

    if (avctx->block_align >= UINT_MAX / 2)

        return AVERROR(EINVAL);

    /* Pad the databuffer with:

       DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(),

       AV_INPUT_BUFFER_PADDING_SIZE, for the bitstreamreader. */

    q->decoded_bytes_buffer =

        av_mallocz(avctx->block_align

                   + DECODE_BYTES_PAD1(avctx->block_align)

                   + AV_INPUT_BUFFER_PADDING_SIZE);

    if (!q->decoded_bytes_buffer)

        return AVERROR(ENOMEM);

    /* Initialize transform. */

    if ((ret = init_cook_mlt(q)))

        return ret;

    /* Initialize COOK signal arithmetic handling */

    if (1) {

        q->scalar_dequant  = scalar_dequant_float;

        q->decouple        = decouple_float;

        q->imlt_window     = imlt_window_float;

        q->interpolate     = interpolate_float;

        q->saturate_output = saturate_output_float;

    }

    /* Try to catch some obviously faulty streams, otherwise it might be exploitable */

    if (q->samples_per_channel != 256 && q->samples_per_channel != 512 &&

        q->samples_per_channel != 1024) {

        avpriv_request_sample(avctx, "samples_per_channel = %d",

                              q->samples_per_channel);

        return AVERROR_PATCHWELCOME;

    }

    avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;

    if (channel_mask)

        avctx->channel_layout = channel_mask;

    else

        avctx->channel_layout = (avctx->channels == 2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;

#ifdef DEBUG

    dump_cook_context(q);

#endif

    return 0;

}


static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
                            DeviceState *dev, Error **errp)
{
    int idx;
    CPUState *cs;
    CPUArchId *cpu_slot;
    X86CPUTopoInfo topo;
    X86CPU *cpu = X86_CPU(dev);
    PCMachineState *pcms = PC_MACHINE(hotplug_dev);
    /* if APIC ID is not set, set it based on socket/core/thread properties */
    if (cpu->apic_id == UNASSIGNED_APIC_ID) {
        int max_socket = (max_cpus - 1) / smp_threads / smp_cores;
        if (cpu->socket_id < 0) {
            error_setg(errp, "CPU socket-id is not set");
        } else if (cpu->socket_id > max_socket) {
            error_setg(errp, "Invalid CPU socket-id: %u must be in range 0:%u",
                       cpu->socket_id, max_socket);
        if (cpu->core_id < 0) {
            error_setg(errp, "CPU core-id is not set");
        } else if (cpu->core_id > (smp_cores - 1)) {
            error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u",
                       cpu->core_id, smp_cores - 1);
        if (cpu->thread_id < 0) {
            error_setg(errp, "CPU thread-id is not set");
        } else if (cpu->thread_id > (smp_threads - 1)) {
            error_setg(errp, "Invalid CPU thread-id: %u must be in range 0:%u",
                       cpu->thread_id, smp_threads - 1);
        topo.pkg_id = cpu->socket_id;
        topo.core_id = cpu->core_id;
        topo.smt_id = cpu->thread_id;
        cpu->apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo);
    cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, &idx);
    if (!cpu_slot) {
        MachineState *ms = MACHINE(pcms);
        x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
        error_setg(errp, "Invalid CPU [socket: %u, core: %u, thread: %u] with"
                  " APIC ID %" PRIu32 ", valid index range 0:%d",
                   topo.pkg_id, topo.core_id, topo.smt_id, cpu->apic_id,
                   ms->possible_cpus->len - 1);
    if (cpu_slot->cpu) {
        error_setg(errp, "CPU[%d] with APIC ID %" PRIu32 " exists",
                   idx, cpu->apic_id);
    /* if 'address' properties socket-id/core-id/thread-id are not set, set them
     * so that machine_query_hotpluggable_cpus would show correct values
     */
    /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn()
     * once -smp refactoring is complete and there will be CPU private
     * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */
    x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
    if (cpu->socket_id != -1 && cpu->socket_id != topo.pkg_id) {
        error_setg(errp, "property socket-id: %u doesn't match set apic-id:"
            " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, topo.pkg_id);
    cpu->socket_id = topo.pkg_id;
    if (cpu->core_id != -1 && cpu->core_id != topo.core_id) {
        error_setg(errp, "property core-id: %u doesn't match set apic-id:"
            " 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id, topo.core_id);
    cpu->core_id = topo.core_id;
    if (cpu->thread_id != -1 && cpu->thread_id != topo.smt_id) {
        error_setg(errp, "property thread-id: %u doesn't match set apic-id:"
            " 0x%x (thread-id: %u)", cpu->thread_id, cpu->apic_id, topo.smt_id);
    cpu->thread_id = topo.smt_id;
    cs = CPU(cpu);
    cs->cpu_index = idx;
    numa_cpu_pre_plug(cpu_slot, dev, errp);


void cpu_reset(CPUARMState *env)
{
    uint32_t id;
    id = env->cp15.c0_cpuid;
    memset(env, 0, offsetof(CPUARMState, breakpoints));
    if (id)
        cpu_reset_model_id(env, id);
#if defined (CONFIG_USER_ONLY)
    env->uncached_cpsr = ARM_CPU_MODE_USR;
    env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
#else
    /* SVC mode with interrupts disabled.  */
    env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
    /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
       clear at reset.  */
    if (IS_M(env))
        env->uncached_cpsr &= ~CPSR_I;
    env->vfp.xregs[ARM_VFP_FPEXC] = 0;
    env->cp15.c2_base_mask = 0xffffc000u;
#endif
    env->regs[15] = 0;
    tlb_flush(env, 1);


static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
{
    BlockDriver *drv = bs->drv;
    BdrvTrackedRequest req;
    int ret;
    if (!drv) {
        return -ENOMEDIUM;
    if (bdrv_check_request(bs, sector_num, nb_sectors)) {
        return -EIO;
    /* throttling disk read I/O */
    if (bs->io_limits_enabled) {
        bdrv_io_limits_intercept(bs, false, nb_sectors);
    tracked_request_begin(&req, bs, sector_num, nb_sectors, false);
    ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
    tracked_request_end(&req);
    return ret;


static inline void cris_ftag_i(unsigned int x)

{

	register unsigned int v asm("$r10") = x;

	asm ("ftagi\t[%0]\n" : : "r" (v) );

}


abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,

                     int flags, int fd, abi_ulong offset)

{

    abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len;

    mmap_lock();

#ifdef DEBUG_MMAP

    {

        printf("mmap: start=0x" TARGET_ABI_FMT_lx

               " len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c flags=",

               start, len,

               prot & PROT_READ ? 'r' : '-',

               prot & PROT_WRITE ? 'w' : '-',

               prot & PROT_EXEC ? 'x' : '-');

        if (flags & MAP_FIXED)

            printf("MAP_FIXED ");

        if (flags & MAP_ANONYMOUS)

            printf("MAP_ANON ");

        switch(flags & MAP_TYPE) {

        case MAP_PRIVATE:

            printf("MAP_PRIVATE ");

            break;

        case MAP_SHARED:

            printf("MAP_SHARED ");

            break;

        default:

            printf("[MAP_TYPE=0x%x] ", flags & MAP_TYPE);

            break;

        }

        printf("fd=%d offset=" TARGET_ABI_FMT_lx "\n", fd, offset);

    }

#endif

    if (offset & ~TARGET_PAGE_MASK) {

        errno = EINVAL;

        goto fail;

    }

    len = TARGET_PAGE_ALIGN(len);

    if (len == 0)

        goto the_end;

    real_start = start & qemu_host_page_mask;

    host_offset = offset & qemu_host_page_mask;

    /* If the user is asking for the kernel to find a location, do that

       before we truncate the length for mapping files below.  */

    if (!(flags & MAP_FIXED)) {

        host_len = len + offset - host_offset;

        host_len = HOST_PAGE_ALIGN(host_len);

        start = mmap_find_vma(real_start, host_len);

        if (start == (abi_ulong)-1) {

            errno = ENOMEM;

            goto fail;

        }

    }

    /* When mapping files into a memory area larger than the file, accesses

       to pages beyond the file size will cause a SIGBUS.

       For example, if mmaping a file of 100 bytes on a host with 4K pages

       emulating a target with 8K pages, the target expects to be able to

       access the first 8K. But the host will trap us on any access beyond

       4K.

       When emulating a target with a larger page-size than the hosts, we

       may need to truncate file maps at EOF and add extra anonymous pages

       up to the targets page boundary.  */

    if ((qemu_real_host_page_size < TARGET_PAGE_SIZE)

        && !(flags & MAP_ANONYMOUS)) {

       struct stat sb;

       if (fstat (fd, &sb) == -1)

           goto fail;

       /* Are we trying to create a map beyond EOF?.  */

       if (offset + len > sb.st_size) {

           /* If so, truncate the file map at eof aligned with

              the hosts real pagesize. Additional anonymous maps

              will be created beyond EOF.  */

           len = REAL_HOST_PAGE_ALIGN(sb.st_size - offset);

       }

    }

    if (!(flags & MAP_FIXED)) {

        unsigned long host_start;

        void *p;

        host_len = len + offset - host_offset;

        host_len = HOST_PAGE_ALIGN(host_len);

        /* Note: we prefer to control the mapping address. It is

           especially important if qemu_host_page_size >

           qemu_real_host_page_size */

        p = mmap(g2h(start), host_len, prot,

                 flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0);

        if (p == MAP_FAILED)

            goto fail;

        /* update start so that it points to the file position at 'offset' */

        host_start = (unsigned long)p;

        if (!(flags & MAP_ANONYMOUS)) {

            p = mmap(g2h(start), len, prot,

                     flags | MAP_FIXED, fd, host_offset);

            if (p == MAP_FAILED) {

                munmap(g2h(start), host_len);

                goto fail;

            }

            host_start += offset - host_offset;

        }

        start = h2g(host_start);

    } else {

        if (start & ~TARGET_PAGE_MASK) {

            errno = EINVAL;

            goto fail;

        }

        end = start + len;

        real_end = HOST_PAGE_ALIGN(end);

	/*

	 * Test if requested memory area fits target address space

	 * It can fail only on 64-bit host with 32-bit target.

	 * On any other target/host host mmap() handles this error correctly.

	 */

        if ((unsigned long)start + len - 1 > (abi_ulong) -1) {

            errno = EINVAL;

            goto fail;

        }

        /* worst case: we cannot map the file because the offset is not

           aligned, so we read it */

        if (!(flags & MAP_ANONYMOUS) &&

            (offset & ~qemu_host_page_mask) != (start & ~qemu_host_page_mask)) {

            /* msync() won't work here, so we return an error if write is

               possible while it is a shared mapping */

            if ((flags & MAP_TYPE) == MAP_SHARED &&

                (prot & PROT_WRITE)) {

                errno = EINVAL;

                goto fail;

            }

            retaddr = target_mmap(start, len, prot | PROT_WRITE,

                                  MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,

                                  -1, 0);

            if (retaddr == -1)

                goto fail;

            if (pread(fd, g2h(start), len, offset) == -1)

                goto fail;

            if (!(prot & PROT_WRITE)) {

                ret = target_mprotect(start, len, prot);

                assert(ret == 0);

            }

            goto the_end;

        }

        /* handle the start of the mapping */

        if (start > real_start) {

            if (real_end == real_start + qemu_host_page_size) {

                /* one single host page */

                ret = mmap_frag(real_start, start, end,

                                prot, flags, fd, offset);

                if (ret == -1)

                    goto fail;

                goto the_end1;

            }

            ret = mmap_frag(real_start, start, real_start + qemu_host_page_size,

                            prot, flags, fd, offset);

            if (ret == -1)

                goto fail;

            real_start += qemu_host_page_size;

        }

        /* handle the end of the mapping */

        if (end < real_end) {

            ret = mmap_frag(real_end - qemu_host_page_size,

                            real_end - qemu_host_page_size, end,

                            prot, flags, fd,

                            offset + real_end - qemu_host_page_size - start);

            if (ret == -1)

                goto fail;

            real_end -= qemu_host_page_size;

        }

        /* map the middle (easier) */

        if (real_start < real_end) {

            void *p;

            unsigned long offset1;

            if (flags & MAP_ANONYMOUS)

                offset1 = 0;

            else

                offset1 = offset + real_start - start;

            p = mmap(g2h(real_start), real_end - real_start,

                     prot, flags, fd, offset1);

            if (p == MAP_FAILED)

                goto fail;

        }

    }

 the_end1:

    page_set_flags(start, start + len, prot | PAGE_VALID);

 the_end:

#ifdef DEBUG_MMAP

    printf("ret=0x" TARGET_ABI_FMT_lx "\n", start);

    page_dump(stdout);

    printf("\n");

#endif

    tb_invalidate_phys_range(start, start + len);

    mmap_unlock();

    return start;

fail:

    mmap_unlock();

    return -1;

}


int kvm_arch_insert_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp)

{

    return -EINVAL;

}


static bool remove_objects(BDRVSheepdogState *s)

{

    int fd, i = 0, nr_objs = 0;

    Error *local_err = NULL;

    int ret = 0;

    bool result = true;

    SheepdogInode *inode = &s->inode;

    fd = connect_to_sdog(s, &local_err);

    if (fd < 0) {

        error_report_err(local_err);

        return false;

    }

    nr_objs = count_data_objs(inode);

    while (i < nr_objs) {

        int start_idx, nr_filled_idx;

        while (i < nr_objs && !inode->data_vdi_id[i]) {

            i++;

        }

        start_idx = i;

        nr_filled_idx = 0;

        while (i < nr_objs && nr_filled_idx < NR_BATCHED_DISCARD) {

            if (inode->data_vdi_id[i]) {

                inode->data_vdi_id[i] = 0;

                nr_filled_idx++;

            }

            i++;

        }

        ret = write_object(fd, s->bs,

                           (char *)&inode->data_vdi_id[start_idx],

                           vid_to_vdi_oid(s->inode.vdi_id), inode->nr_copies,

                           (i - start_idx) * sizeof(uint32_t),

                           offsetof(struct SheepdogInode,

                                    data_vdi_id[start_idx]),

                           false, s->cache_flags);

        if (ret < 0) {

            error_report("failed to discard snapshot inode.");

            result = false;

            goto out;

        }

    }

out:

    closesocket(fd);

    return result;

}


static int vfio_populate_device(VFIODevice *vbasedev)

{

    VFIOINTp *intp, *tmp;

    int i, ret = -1;

    VFIOPlatformDevice *vdev =

        container_of(vbasedev, VFIOPlatformDevice, vbasedev);

    if (!(vbasedev->flags & VFIO_DEVICE_FLAGS_PLATFORM)) {

        error_report("vfio: Um, this isn't a platform device");

        return ret;

    }

    vdev->regions = g_new0(VFIORegion *, vbasedev->num_regions);

    for (i = 0; i < vbasedev->num_regions; i++) {

        struct vfio_region_info reg_info = { .argsz = sizeof(reg_info) };

        VFIORegion *ptr;

        vdev->regions[i] = g_malloc0(sizeof(VFIORegion));

        ptr = vdev->regions[i];

        reg_info.index = i;

        ret = ioctl(vbasedev->fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info);

        if (ret) {

            error_report("vfio: Error getting region %d info: %m", i);

            goto reg_error;

        }

        ptr->flags = reg_info.flags;

        ptr->size = reg_info.size;

        ptr->fd_offset = reg_info.offset;

        ptr->nr = i;

        ptr->vbasedev = vbasedev;

        trace_vfio_platform_populate_regions(ptr->nr,

                            (unsigned long)ptr->flags,

                            (unsigned long)ptr->size,

                            ptr->vbasedev->fd,

                            (unsigned long)ptr->fd_offset);

    }

    vdev->mmap_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,

                                    vfio_intp_mmap_enable, vdev);

    QSIMPLEQ_INIT(&vdev->pending_intp_queue);

    for (i = 0; i < vbasedev->num_irqs; i++) {

        struct vfio_irq_info irq = { .argsz = sizeof(irq) };

        irq.index = i;

        ret = ioctl(vbasedev->fd, VFIO_DEVICE_GET_IRQ_INFO, &irq);

        if (ret) {

            error_printf("vfio: error getting device %s irq info",

                         vbasedev->name);

            goto irq_err;

        } else {

            trace_vfio_platform_populate_interrupts(irq.index,

                                                    irq.count,

                                                    irq.flags);

            intp = vfio_init_intp(vbasedev, irq);

            if (!intp) {

                error_report("vfio: Error installing IRQ %d up", i);

                goto irq_err;

            }

        }

    }

    return 0;

irq_err:

    timer_del(vdev->mmap_timer);

    QLIST_FOREACH_SAFE(intp, &vdev->intp_list, next, tmp) {

        QLIST_REMOVE(intp, next);

        g_free(intp);

    }

reg_error:

    for (i = 0; i < vbasedev->num_regions; i++) {

        g_free(vdev->regions[i]);

    }

    g_free(vdev->regions);

    return ret;

}


static int execute_decode_slices(H264Context *h, int context_count)

{

    MpegEncContext *const s     = &h->s;

    AVCodecContext *const avctx = s->avctx;

    H264Context *hx;

    int i;

    if (s->avctx->hwaccel ||

        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)

        return 0;

    if (context_count == 1) {

        return decode_slice(avctx, &h);

    } else {

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

            hx                    = h->thread_context[i];

            hx->s.err_recognition = avctx->err_recognition;

            hx->s.error_count     = 0;

            hx->x264_build        = h->x264_build;

        }

        avctx->execute(avctx, decode_slice, h->thread_context,

                       NULL, context_count, sizeof(void *));

        /* pull back stuff from slices to master context */

        hx                   = h->thread_context[context_count - 1];

        s->mb_x              = hx->s.mb_x;

        s->mb_y              = hx->s.mb_y;

        s->droppable         = hx->s.droppable;

        s->picture_structure = hx->s.picture_structure;

        for (i = 1; i < context_count; i++)

            h->s.error_count += h->thread_context[i]->s.error_count;

    }

    return 0;

}


void pcmcia_socket_register(PCMCIASocket *socket)

{

    struct pcmcia_socket_entry_s *entry;

    entry = g_malloc(sizeof(struct pcmcia_socket_entry_s));

    entry->socket = socket;

    entry->next = pcmcia_sockets;

    pcmcia_sockets = entry;

}


static void encode_subband(SnowContext *s, SubBand *b, DWTELEM *src, DWTELEM *parent, int stride, int orientation){

//    encode_subband_qtree(s, b, src, parent, stride, orientation);

//    encode_subband_z0run(s, b, src, parent, stride, orientation);

    encode_subband_c0run(s, b, src, parent, stride, orientation);

//    encode_subband_dzr(s, b, src, parent, stride, orientation);

}


static void handle_s_without_atn(ESPState *s)

{

    uint8_t buf[32];

    int len;

    if (s->dma && !s->dma_enabled) {

        s->dma_cb = handle_s_without_atn;

        return;

    }

    len = get_cmd(s, buf);

    if (len) {

        do_busid_cmd(s, buf, 0);

    }

}


static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,

                              uint32_t node, Error **errp)

{

    Error *local_err = NULL;

    sPAPRMachineState *ms = SPAPR_MACHINE(hotplug_dev);

    PCDIMMDevice *dimm = PC_DIMM(dev);

    PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);

    MemoryRegion *mr = ddc->get_memory_region(dimm);

    uint64_t align = memory_region_get_alignment(mr);

    uint64_t size = memory_region_size(mr);

    uint64_t addr;

    if (size % SPAPR_MEMORY_BLOCK_SIZE) {

        error_setg(&local_err, "Hotplugged memory size must be a multiple of "

                      "%lld MB", SPAPR_MEMORY_BLOCK_SIZE/M_BYTE);

        goto out;

    }

    pc_dimm_memory_plug(dev, &ms->hotplug_memory, mr, align, &local_err);

    if (local_err) {

        goto out;

    }

    addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err);

    if (local_err) {

        pc_dimm_memory_unplug(dev, &ms->hotplug_memory, mr);

        goto out;

    }

    spapr_add_lmbs(dev, addr, size, node, &error_abort);

out:

    error_propagate(errp, local_err);

}


static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,

                                 const AVFrame *pict, int *got_packet)

{

    A64Context *c = avctx->priv_data;

    AVFrame *const p = (AVFrame *) & c->picture;

    int frame;

    int x, y;

    int b_height;

    int b_width;

    int req_size, ret;

    uint8_t *buf;

    int *charmap     = c->mc_charmap;

    uint8_t *colram  = c->mc_colram;

    uint8_t *charset = c->mc_charset;

    int *meta        = c->mc_meta_charset;

    int *best_cb     = c->mc_best_cb;

    int charset_size = 0x800 * (INTERLACED + 1);

    int colram_size  = 0x100 * c->mc_use_5col;

    int screen_size;

    if(CROP_SCREENS) {

        b_height = FFMIN(avctx->height,C64YRES) >> 3;

        b_width  = FFMIN(avctx->width ,C64XRES) >> 3;

        screen_size = b_width * b_height;

    } else {

        b_height = C64YRES >> 3;

        b_width  = C64XRES >> 3;

        screen_size = 0x400;

    }

    /* no data, means end encoding asap */

    if (!pict) {

        /* all done, end encoding */

        if (!c->mc_lifetime) return 0;

        /* no more frames in queue, prepare to flush remaining frames */

        if (!c->mc_frame_counter) {

            c->mc_lifetime = 0;

        }

        /* still frames in queue so limit lifetime to remaining frames */

        else c->mc_lifetime = c->mc_frame_counter;

    /* still new data available */

    } else {

        /* fill up mc_meta_charset with data until lifetime exceeds */

        if (c->mc_frame_counter < c->mc_lifetime) {

            *p = *pict;

            p->pict_type = AV_PICTURE_TYPE_I;

            p->key_frame = 1;

            to_meta_with_crop(avctx, p, meta + 32000 * c->mc_frame_counter);

            c->mc_frame_counter++;

            if (c->next_pts == AV_NOPTS_VALUE)

                c->next_pts = pict->pts;

            /* lifetime is not reached so wait for next frame first */

            return 0;

        }

    }

    /* lifetime reached so now convert X frames at once */

    if (c->mc_frame_counter == c->mc_lifetime) {

        req_size = 0;

        /* any frames to encode? */

        if (c->mc_lifetime) {

            req_size = charset_size + c->mc_lifetime*(screen_size + colram_size);

            if ((ret = ff_alloc_packet(pkt, req_size)) < 0) {

                av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", req_size);

                return ret;

            }

            buf = pkt->data;

            /* calc optimal new charset + charmaps */

            ff_init_elbg(meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx);

            ff_do_elbg  (meta, 32, 1000 * c->mc_lifetime, best_cb, CHARSET_CHARS, 50, charmap, &c->randctx);

            /* create colorram map and a c64 readable charset */

            render_charset(avctx, charset, colram);

            /* copy charset to buf */

            memcpy(buf, charset, charset_size);

            /* advance pointers */

            buf      += charset_size;

            charset  += charset_size;

        }

        /* write x frames to buf */

        for (frame = 0; frame < c->mc_lifetime; frame++) {

            /* copy charmap to buf. buf is uchar*, charmap is int*, so no memcpy here, sorry */

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

                for (x = 0; x < b_width; x++) {

                    buf[y * b_width + x] = charmap[y * b_width + x];

                }

            }

            /* advance pointers */

            buf += screen_size;

            req_size += screen_size;

            /* compress and copy colram to buf */

            if (c->mc_use_5col) {

                a64_compress_colram(buf, charmap, colram);

                /* advance pointers */

                buf += colram_size;

                req_size += colram_size;

            }

            /* advance to next charmap */

            charmap += 1000;

        }

        AV_WB32(avctx->extradata + 4,  c->mc_frame_counter);

        AV_WB32(avctx->extradata + 8,  charset_size);

        AV_WB32(avctx->extradata + 12, screen_size + colram_size);

        /* reset counter */

        c->mc_frame_counter = 0;

        pkt->pts = pkt->dts = c->next_pts;

        c->next_pts         = AV_NOPTS_VALUE;

        pkt->size   = req_size;

        pkt->flags |= AV_PKT_FLAG_KEY;

        *got_packet = !!req_size;

    }

    return 0;

}


static av_always_inline void MPV_motion_internal(MpegEncContext *s,

                              uint8_t *dest_y, uint8_t *dest_cb,

                              uint8_t *dest_cr, int dir,

                              uint8_t **ref_picture,

                              op_pixels_func (*pix_op)[4],

                              qpel_mc_func (*qpix_op)[16], int is_mpeg12)

{

    int dxy, mx, my, src_x, src_y, motion_x, motion_y;

    int mb_x, mb_y, i;

    uint8_t *ptr, *dest;

    mb_x = s->mb_x;

    mb_y = s->mb_y;

    prefetch_motion(s, ref_picture, dir);

    if(!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B){

        LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]);

        Picture *cur_frame = &s->current_picture;

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

        const int mot_stride= s->b8_stride;

        const int mot_xy= mb_x*2 + mb_y*2*mot_stride;

        av_assert2(!s->mb_skipped);

        AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy    ]);

        AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]);

        AV_COPY32(mv_cache[2][1], cur_frame->motion_val[0][mot_xy + mot_stride    ]);

        AV_COPY32(mv_cache[2][2], cur_frame->motion_val[0][mot_xy + mot_stride + 1]);

        AV_COPY32(mv_cache[3][1], cur_frame->motion_val[0][mot_xy + mot_stride    ]);

        AV_COPY32(mv_cache[3][2], cur_frame->motion_val[0][mot_xy + mot_stride + 1]);

        if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) {

            AV_COPY32(mv_cache[0][1], mv_cache[1][1]);

            AV_COPY32(mv_cache[0][2], mv_cache[1][2]);

        }else{

            AV_COPY32(mv_cache[0][1], cur_frame->motion_val[0][mot_xy - mot_stride    ]);

            AV_COPY32(mv_cache[0][2], cur_frame->motion_val[0][mot_xy - mot_stride + 1]);

        }

        if (mb_x == 0 || IS_INTRA(cur_frame->mb_type[xy - 1])) {

            AV_COPY32(mv_cache[1][0], mv_cache[1][1]);

            AV_COPY32(mv_cache[2][0], mv_cache[2][1]);

        }else{

            AV_COPY32(mv_cache[1][0], cur_frame->motion_val[0][mot_xy - 1]);

            AV_COPY32(mv_cache[2][0], cur_frame->motion_val[0][mot_xy - 1 + mot_stride]);

        }

        if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->mb_type[xy + 1])) {

            AV_COPY32(mv_cache[1][3], mv_cache[1][2]);

            AV_COPY32(mv_cache[2][3], mv_cache[2][2]);

        }else{

            AV_COPY32(mv_cache[1][3], cur_frame->motion_val[0][mot_xy + 2]);

            AV_COPY32(mv_cache[2][3], cur_frame->motion_val[0][mot_xy + 2 + mot_stride]);

        }

        mx = 0;

        my = 0;

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

            const int x= (i&1)+1;

            const int y= (i>>1)+1;

            int16_t mv[5][2]= {

                {mv_cache[y][x  ][0], mv_cache[y][x  ][1]},

                {mv_cache[y-1][x][0], mv_cache[y-1][x][1]},

                {mv_cache[y][x-1][0], mv_cache[y][x-1][1]},

                {mv_cache[y][x+1][0], mv_cache[y][x+1][1]},

                {mv_cache[y+1][x][0], mv_cache[y+1][x][1]}};

            //FIXME cleanup

            obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,

                        ref_picture[0],

                        mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,

                        pix_op[1],

                        mv);

            mx += mv[0][0];

            my += mv[0][1];

        }

        if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY))

            chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);

        return;

    }

    switch(s->mv_type) {

    case MV_TYPE_16X16:

        if(s->mcsel){

            if(s->real_sprite_warping_points==1){

                gmc1_motion(s, dest_y, dest_cb, dest_cr,

                            ref_picture);

            }else{

                gmc_motion(s, dest_y, dest_cb, dest_cr,

                            ref_picture);

            }

        }else if(!is_mpeg12 && s->quarter_sample){

            qpel_motion(s, dest_y, dest_cb, dest_cr,

                        0, 0, 0,

                        ref_picture, pix_op, qpix_op,

                        s->mv[dir][0][0], s->mv[dir][0][1], 16);

        } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) &&

                   s->mspel && s->codec_id == AV_CODEC_ID_WMV2) {

            ff_mspel_motion(s, dest_y, dest_cb, dest_cr,

                        ref_picture, pix_op,

                        s->mv[dir][0][0], s->mv[dir][0][1], 16);

        }else

        {

            mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,

                        ref_picture, pix_op,

                        s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y);

        }

        break;

    case MV_TYPE_8X8:

    if (!is_mpeg12) {

        mx = 0;

        my = 0;

        if(s->quarter_sample){

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

                motion_x = s->mv[dir][i][0];

                motion_y = s->mv[dir][i][1];

                dxy = ((motion_y & 3) << 2) | (motion_x & 3);

                src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;

                src_y = mb_y * 16 + (motion_y >> 2) + (i >>1) * 8;

                /* WARNING: do no forget half pels */

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

                if (src_x == s->width)

                    dxy &= ~3;

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

                if (src_y == s->height)

                    dxy &= ~12;

                ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);

                if(s->flags&CODEC_FLAG_EMU_EDGE){

                    if(   (unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x&3) - 8, 0)

                       || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y&3) - 8, 0)){

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

                                            s->linesize, 9, 9,

                                            src_x, src_y,

                                            s->h_edge_pos, s->v_edge_pos);

                        ptr= s->edge_emu_buffer;

                    }

                }

                dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;

                qpix_op[1][dxy](dest, ptr, s->linesize);

                mx += s->mv[dir][i][0]/2;

                my += s->mv[dir][i][1]/2;

            }

        }else{

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

                hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,

                            ref_picture[0],

                            mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >>1) * 8,

                            pix_op[1],

                            s->mv[dir][i][0], s->mv[dir][i][1]);

                mx += s->mv[dir][i][0];

                my += s->mv[dir][i][1];

            }

        }

        if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY))

            chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my);

    }

        break;

    case MV_TYPE_FIELD:

        if (s->picture_structure == PICT_FRAME) {

            if(!is_mpeg12 && s->quarter_sample){

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

                    qpel_motion(s, dest_y, dest_cb, dest_cr,

                                1, i, s->field_select[dir][i],

                                ref_picture, pix_op, qpix_op,

                                s->mv[dir][i][0], s->mv[dir][i][1], 8);

                }

            }else{

                /* top field */

                mpeg_motion_field(s, dest_y, dest_cb, dest_cr,

                                  0, s->field_select[dir][0],

                                  ref_picture, pix_op,

                                  s->mv[dir][0][0], s->mv[dir][0][1], 8, mb_y);

                /* bottom field */

                mpeg_motion_field(s, dest_y, dest_cb, dest_cr,

                                  1, s->field_select[dir][1],

                                  ref_picture, pix_op,

                                  s->mv[dir][1][0], s->mv[dir][1][1], 8, mb_y);

            }

        } else {

            if(s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field){

                ref_picture = s->current_picture_ptr->f.data;

            }

            mpeg_motion(s, dest_y, dest_cb, dest_cr,

                        s->field_select[dir][0],

                        ref_picture, pix_op,

                        s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y>>1);

        }

        break;

    case MV_TYPE_16X8:

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

            uint8_t ** ref2picture;

            if(s->picture_structure == s->field_select[dir][i] + 1

               || s->pict_type == AV_PICTURE_TYPE_B || s->first_field){

                ref2picture= ref_picture;

            }else{

                ref2picture = s->current_picture_ptr->f.data;

            }

            mpeg_motion(s, dest_y, dest_cb, dest_cr,

                        s->field_select[dir][i],

                        ref2picture, pix_op,

                        s->mv[dir][i][0], s->mv[dir][i][1] + 16*i, 8, mb_y>>1);

            dest_y += 16*s->linesize;

            dest_cb+= (16>>s->chroma_y_shift)*s->uvlinesize;

            dest_cr+= (16>>s->chroma_y_shift)*s->uvlinesize;

        }

        break;

    case MV_TYPE_DMV:

        if(s->picture_structure == PICT_FRAME){

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

                int j;

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

                    mpeg_motion_field(s, dest_y, dest_cb, dest_cr,

                                      j, j^i, ref_picture, pix_op,

                                      s->mv[dir][2*i + j][0],

                                      s->mv[dir][2*i + j][1], 8, mb_y);

                }

                pix_op = s->hdsp.avg_pixels_tab;

            }

        }else{

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

                mpeg_motion(s, dest_y, dest_cb, dest_cr,

                            s->picture_structure != i+1,

                            ref_picture, pix_op,

                            s->mv[dir][2*i][0],s->mv[dir][2*i][1],16, mb_y>>1);

                // after put we make avg of the same block

                pix_op=s->hdsp.avg_pixels_tab;

                //opposite parity is always in the same frame if this is second field

                if(!s->first_field){

                    ref_picture = s->current_picture_ptr->f.data;

                }

            }

        }

    break;

    default: av_assert2(0);

    }

}


void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value)

{

    LOG_MMU("%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__,

            srnum, value, env->sr[srnum]);

#if defined(TARGET_PPC64)

    if (env->mmu_model & POWERPC_MMU_64) {

        uint64_t rb = 0, rs = 0;

        /* ESID = srnum */

        rb |= ((uint32_t)srnum & 0xf) << 28;

        /* Set the valid bit */

        rb |= 1 << 27;

        /* Index = ESID */

        rb |= (uint32_t)srnum;

        /* VSID = VSID */

        rs |= (value & 0xfffffff) << 12;

        /* flags = flags */

        rs |= ((value >> 27) & 0xf) << 9;

        ppc_store_slb(env, rb, rs);

    } else

#endif

    if (env->sr[srnum] != value) {

        env->sr[srnum] = value;

/* Invalidating 256MB of virtual memory in 4kB pages is way longer than

   flusing the whole TLB. */

#if !defined(FLUSH_ALL_TLBS) && 0

        {

            target_ulong page, end;

            /* Invalidate 256 MB of virtual memory */

            page = (16 << 20) * srnum;

            end = page + (16 << 20);

            for (; page != end; page += TARGET_PAGE_SIZE)

                tlb_flush_page(env, page);

        }

#else

        tlb_flush(env, 1);

#endif

    }

}


int ff_h264_decode_mb_cabac(H264Context *h) {

    MpegEncContext * const s = &h->s;

    int mb_xy;

    int mb_type, partition_count, cbp = 0;

    int dct8x8_allowed= h->pps.transform_8x8_mode;

    int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;

    const int pixel_shift = h->pixel_shift;

    mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;

    tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);

    if( h->slice_type_nos != AV_PICTURE_TYPE_I ) {

        int skip;

        /* a skipped mb needs the aff flag from the following mb */

        if( FRAME_MBAFF && (s->mb_y&1)==1 && h->prev_mb_skipped )

            skip = h->next_mb_skipped;

        else

            skip = decode_cabac_mb_skip( h, s->mb_x, s->mb_y );

        /* read skip flags */

        if( skip ) {

            if( FRAME_MBAFF && (s->mb_y&1)==0 ){

                s->current_picture.f.mb_type[mb_xy] = MB_TYPE_SKIP;

                h->next_mb_skipped = decode_cabac_mb_skip( h, s->mb_x, s->mb_y+1 );

                if(!h->next_mb_skipped)

                    h->mb_mbaff = h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);

            }

            decode_mb_skip(h);

            h->cbp_table[mb_xy] = 0;

            h->chroma_pred_mode_table[mb_xy] = 0;

            h->last_qscale_diff = 0;

            return 0;

        }

    }

    if(FRAME_MBAFF){

        if( (s->mb_y&1) == 0 )

            h->mb_mbaff =

            h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);

    }

    h->prev_mb_skipped = 0;

    fill_decode_neighbors(h, -(MB_FIELD));

    if( h->slice_type_nos == AV_PICTURE_TYPE_B ) {

        int ctx = 0;

        assert(h->slice_type_nos == AV_PICTURE_TYPE_B);

        if( !IS_DIRECT( h->left_type[LTOP]-1 ) )

            ctx++;

        if( !IS_DIRECT( h->top_type-1 ) )

            ctx++;

        if( !get_cabac_noinline( &h->cabac, &h->cabac_state[27+ctx] ) ){

            mb_type= 0; /* B_Direct_16x16 */

        }else if( !get_cabac_noinline( &h->cabac, &h->cabac_state[27+3] ) ) {

            mb_type= 1 + get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ); /* B_L[01]_16x16 */

        }else{

            int bits;

            bits = get_cabac_noinline( &h->cabac, &h->cabac_state[27+4] ) << 3;

            bits+= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ) << 2;

            bits+= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ) << 1;

            bits+= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] );

            if( bits < 8 ){

                mb_type= bits + 3; /* B_Bi_16x16 through B_L1_L0_16x8 */

            }else if( bits == 13 ){

                mb_type= decode_cabac_intra_mb_type(h, 32, 0);

                goto decode_intra_mb;

            }else if( bits == 14 ){

                mb_type= 11; /* B_L1_L0_8x16 */

            }else if( bits == 15 ){

                mb_type= 22; /* B_8x8 */

            }else{

                bits= ( bits<<1 ) + get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] );

                mb_type= bits - 4; /* B_L0_Bi_* through B_Bi_Bi_* */

            }

        }

            partition_count= b_mb_type_info[mb_type].partition_count;

            mb_type=         b_mb_type_info[mb_type].type;

    } else if( h->slice_type_nos == AV_PICTURE_TYPE_P ) {

        if( get_cabac_noinline( &h->cabac, &h->cabac_state[14] ) == 0 ) {

            /* P-type */

            if( get_cabac_noinline( &h->cabac, &h->cabac_state[15] ) == 0 ) {

                /* P_L0_D16x16, P_8x8 */

                mb_type= 3 * get_cabac_noinline( &h->cabac, &h->cabac_state[16] );

            } else {

                /* P_L0_D8x16, P_L0_D16x8 */

                mb_type= 2 - get_cabac_noinline( &h->cabac, &h->cabac_state[17] );

            }

            partition_count= p_mb_type_info[mb_type].partition_count;

            mb_type=         p_mb_type_info[mb_type].type;

        } else {

            mb_type= decode_cabac_intra_mb_type(h, 17, 0);

            goto decode_intra_mb;

        }

    } else {

        mb_type= decode_cabac_intra_mb_type(h, 3, 1);

        if(h->slice_type == AV_PICTURE_TYPE_SI && mb_type)

            mb_type--;

        assert(h->slice_type_nos == AV_PICTURE_TYPE_I);

decode_intra_mb:

        partition_count = 0;

        cbp= i_mb_type_info[mb_type].cbp;

        h->intra16x16_pred_mode= i_mb_type_info[mb_type].pred_mode;

        mb_type= i_mb_type_info[mb_type].type;

    }

    if(MB_FIELD)

        mb_type |= MB_TYPE_INTERLACED;

    h->slice_table[ mb_xy ]= h->slice_num;

    if(IS_INTRA_PCM(mb_type)) {

        static const uint16_t mb_sizes[4] = {256,384,512,768};

        const int mb_size = mb_sizes[h->sps.chroma_format_idc]*h->sps.bit_depth_luma >> 3;

        const uint8_t *ptr;

        // We assume these blocks are very rare so we do not optimize it.

        // FIXME The two following lines get the bitstream position in the cabac

        // decode, I think it should be done by a function in cabac.h (or cabac.c).

        ptr= h->cabac.bytestream;

        if(h->cabac.low&0x1) ptr--;

        if(CABAC_BITS==16){

            if(h->cabac.low&0x1FF) ptr--;

        }

        // The pixels are stored in the same order as levels in h->mb array.

        memcpy(h->mb, ptr, mb_size); ptr+=mb_size;

        ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr);

        // All blocks are present

        h->cbp_table[mb_xy] = 0xf7ef;

        h->chroma_pred_mode_table[mb_xy] = 0;

        // In deblocking, the quantizer is 0

        s->current_picture.f.qscale_table[mb_xy] = 0;

        // All coeffs are present

        memset(h->non_zero_count[mb_xy], 16, 48);

        s->current_picture.f.mb_type[mb_xy] = mb_type;

        h->last_qscale_diff = 0;

        return 0;

    }

    if(MB_MBAFF){

        h->ref_count[0] <<= 1;

        h->ref_count[1] <<= 1;

    }

    fill_decode_caches(h, mb_type);

    if( IS_INTRA( mb_type ) ) {

        int i, pred_mode;

        if( IS_INTRA4x4( mb_type ) ) {

            if( dct8x8_allowed && get_cabac_noinline( &h->cabac, &h->cabac_state[399 + h->neighbor_transform_size] ) ) {

                mb_type |= MB_TYPE_8x8DCT;

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

                    int pred = pred_intra_mode( h, i );

                    int mode = decode_cabac_mb_intra4x4_pred_mode( h, pred );

                    fill_rectangle( &h->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1 );

                }

            } else {

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

                    int pred = pred_intra_mode( h, i );

                    h->intra4x4_pred_mode_cache[ scan8[i] ] = decode_cabac_mb_intra4x4_pred_mode( h, pred );

                //av_log( s->avctx, AV_LOG_ERROR, "i4x4 pred=%d mode=%d\n", pred, h->intra4x4_pred_mode_cache[ scan8[i] ] );

                }

            }

            write_back_intra_pred_mode(h);

            if( ff_h264_check_intra4x4_pred_mode(h) < 0 ) return -1;

        } else {

            h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode( h, h->intra16x16_pred_mode, 0 );

            if( h->intra16x16_pred_mode < 0 ) return -1;

        }

        if(decode_chroma){

            h->chroma_pred_mode_table[mb_xy] =

            pred_mode                        = decode_cabac_mb_chroma_pre_mode( h );

            pred_mode= ff_h264_check_intra_pred_mode( h, pred_mode, 1 );

            if( pred_mode < 0 ) return -1;

            h->chroma_pred_mode= pred_mode;

        } else {

            h->chroma_pred_mode= DC_128_PRED8x8;

        }

    } else if( partition_count == 4 ) {

        int i, j, sub_partition_count[4], list, ref[2][4];

        if( h->slice_type_nos == AV_PICTURE_TYPE_B ) {

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

                h->sub_mb_type[i] = decode_cabac_b_mb_sub_type( h );

                sub_partition_count[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;

                h->sub_mb_type[i]=      b_sub_mb_type_info[ h->sub_mb_type[i] ].type;

            }

            if( IS_DIRECT(h->sub_mb_type[0] | h->sub_mb_type[1] |

                          h->sub_mb_type[2] | h->sub_mb_type[3]) ) {

                ff_h264_pred_direct_motion(h, &mb_type);

                h->ref_cache[0][scan8[4]] =

                h->ref_cache[1][scan8[4]] =

                h->ref_cache[0][scan8[12]] =

                h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;

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

                        fill_rectangle( &h->direct_cache[scan8[4*i]], 2, 2, 8, (h->sub_mb_type[i]>>1)&0xFF, 1 );

            }

        } else {

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

                h->sub_mb_type[i] = decode_cabac_p_mb_sub_type( h );

                sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;

                h->sub_mb_type[i]=      p_sub_mb_type_info[ h->sub_mb_type[i] ].type;

            }

        }

        for( list = 0; list < h->list_count; list++ ) {

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

                    if(IS_DIRECT(h->sub_mb_type[i])) continue;

                    if(IS_DIR(h->sub_mb_type[i], 0, list)){

                        if( h->ref_count[list] > 1 ){

                            ref[list][i] = decode_cabac_mb_ref( h, list, 4*i );

                            if(ref[list][i] >= (unsigned)h->ref_count[list]){

                                av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], h->ref_count[list]);

                            }

                        }else

                            ref[list][i] = 0;

                    } else {

                        ref[list][i] = -1;

                    }

                                                       h->ref_cache[list][ scan8[4*i]+1 ]=

                    h->ref_cache[list][ scan8[4*i]+8 ]=h->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i];

                }

        }

        if(dct8x8_allowed)

            dct8x8_allowed = get_dct8x8_allowed(h);

        for(list=0; list<h->list_count; list++){

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

                h->ref_cache[list][ scan8[4*i]   ]=h->ref_cache[list][ scan8[4*i]+1 ];

                if(IS_DIRECT(h->sub_mb_type[i])){

                    fill_rectangle(h->mvd_cache[list][scan8[4*i]], 2, 2, 8, 0, 2);

                    continue;

                }

                if(IS_DIR(h->sub_mb_type[i], 0, list) && !IS_DIRECT(h->sub_mb_type[i])){

                    const int sub_mb_type= h->sub_mb_type[i];

                    const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;

                    for(j=0; j<sub_partition_count[i]; j++){

                        int mpx, mpy;

                        int mx, my;

                        const int index= 4*i + block_width*j;

                        int16_t (* mv_cache)[2]= &h->mv_cache[list][ scan8[index] ];

                        uint8_t (* mvd_cache)[2]= &h->mvd_cache[list][ scan8[index] ];

                        pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my);

                        DECODE_CABAC_MB_MVD( h, list, index)

                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                        if(IS_SUB_8X8(sub_mb_type)){

                            mv_cache[ 1 ][0]=

                            mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;

                            mv_cache[ 1 ][1]=

                            mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;

                            mvd_cache[ 1 ][0]=

                            mvd_cache[ 8 ][0]= mvd_cache[ 9 ][0]= mpx;

                            mvd_cache[ 1 ][1]=

                            mvd_cache[ 8 ][1]= mvd_cache[ 9 ][1]= mpy;

                        }else if(IS_SUB_8X4(sub_mb_type)){

                            mv_cache[ 1 ][0]= mx;

                            mv_cache[ 1 ][1]= my;

                            mvd_cache[ 1 ][0]=  mpx;

                            mvd_cache[ 1 ][1]= mpy;

                        }else if(IS_SUB_4X8(sub_mb_type)){

                            mv_cache[ 8 ][0]= mx;

                            mv_cache[ 8 ][1]= my;

                            mvd_cache[ 8 ][0]= mpx;

                            mvd_cache[ 8 ][1]= mpy;

                        }

                        mv_cache[ 0 ][0]= mx;

                        mv_cache[ 0 ][1]= my;

                        mvd_cache[ 0 ][0]= mpx;

                        mvd_cache[ 0 ][1]= mpy;

                    }

                }else{

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

                    fill_rectangle(h->mvd_cache[list][ scan8[4*i] ], 2, 2, 8, 0, 2);

                }

            }

        }

    } else if( IS_DIRECT(mb_type) ) {

        ff_h264_pred_direct_motion(h, &mb_type);

        fill_rectangle(h->mvd_cache[0][scan8[0]], 4, 4, 8, 0, 2);

        fill_rectangle(h->mvd_cache[1][scan8[0]], 4, 4, 8, 0, 2);

        dct8x8_allowed &= h->sps.direct_8x8_inference_flag;

    } else {

        int list, i;

        if(IS_16X16(mb_type)){

            for(list=0; list<h->list_count; list++){

                if(IS_DIR(mb_type, 0, list)){

                    int ref;

                    if(h->ref_count[list] > 1){

                        ref= decode_cabac_mb_ref(h, list, 0);

                        if(ref >= (unsigned)h->ref_count[list]){

                            av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, h->ref_count[list]);

                        }

                    }else

                        ref=0;

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

                }

            }

            for(list=0; list<h->list_count; list++){

                if(IS_DIR(mb_type, 0, list)){

                    int mx,my,mpx,mpy;

                    pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my);

                    DECODE_CABAC_MB_MVD( h, list, 0)

                    tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                    fill_rectangle(h->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack8to16(mpx,mpy), 2);

                    fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);

                }

            }

        }

        else if(IS_16X8(mb_type)){

            for(list=0; list<h->list_count; list++){

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

                        if(IS_DIR(mb_type, i, list)){

                            int ref;

                            if(h->ref_count[list] > 1){

                                ref= decode_cabac_mb_ref( h, list, 8*i );

                                if(ref >= (unsigned)h->ref_count[list]){

                                    av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, h->ref_count[list]);

                                }

                            }else

                                ref=0;

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

                        }else

                            fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, (LIST_NOT_USED&0xFF), 1);

                    }

            }

            for(list=0; list<h->list_count; list++){

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

                    if(IS_DIR(mb_type, i, list)){

                        int mx,my,mpx,mpy;

                        pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my);

                        DECODE_CABAC_MB_MVD( h, list, 8*i)

                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                        fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack8to16(mpx,mpy), 2);

                        fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4);

                    }else{

                        fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 2);

                        fill_rectangle(h-> mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4);

                    }

                }

            }

        }else{

            assert(IS_8X16(mb_type));

            for(list=0; list<h->list_count; list++){

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

                        if(IS_DIR(mb_type, i, list)){ //FIXME optimize

                            int ref;

                            if(h->ref_count[list] > 1){

                                ref= decode_cabac_mb_ref( h, list, 4*i );

                                if(ref >= (unsigned)h->ref_count[list]){

                                    av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, h->ref_count[list]);

                                }

                            }else

                                ref=0;

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

                        }else

                            fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, (LIST_NOT_USED&0xFF), 1);

                    }

            }

            for(list=0; list<h->list_count; list++){

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

                    if(IS_DIR(mb_type, i, list)){

                        int mx,my,mpx,mpy;

                        pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);

                        DECODE_CABAC_MB_MVD( h, list, 4*i)

                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                        fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack8to16(mpx,mpy), 2);

                        fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4);

                    }else{

                        fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 2);

                        fill_rectangle(h-> mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4);

                    }

                }

            }

        }

    }

   if( IS_INTER( mb_type ) ) {

        h->chroma_pred_mode_table[mb_xy] = 0;

        write_back_motion( h, mb_type );

   }

    if( !IS_INTRA16x16( mb_type ) ) {

        cbp  = decode_cabac_mb_cbp_luma( h );

        if(decode_chroma)

            cbp |= decode_cabac_mb_cbp_chroma( h ) << 4;

    }

    h->cbp_table[mb_xy] = h->cbp = cbp;

    if( dct8x8_allowed && (cbp&15) && !IS_INTRA( mb_type ) ) {

        mb_type |= MB_TYPE_8x8DCT * get_cabac_noinline( &h->cabac, &h->cabac_state[399 + h->neighbor_transform_size] );

    }

    /* It would be better to do this in fill_decode_caches, but we don't know

     * the transform mode of the current macroblock there. */

    if (CHROMA444 && IS_8x8DCT(mb_type)){

        int i;

        uint8_t *nnz_cache = h->non_zero_count_cache;

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

            if (h->left_type[LEFT(i)] && !IS_8x8DCT(h->left_type[LEFT(i)])){

                nnz_cache[3+8* 1 + 2*8*i]=

                nnz_cache[3+8* 2 + 2*8*i]=

                nnz_cache[3+8* 6 + 2*8*i]=

                nnz_cache[3+8* 7 + 2*8*i]=

                nnz_cache[3+8*11 + 2*8*i]=

                nnz_cache[3+8*12 + 2*8*i]= IS_INTRA(mb_type) ? 64 : 0;

            }

        }

        if (h->top_type && !IS_8x8DCT(h->top_type)){

            uint32_t top_empty = CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040;

            AV_WN32A(&nnz_cache[4+8* 0], top_empty);

            AV_WN32A(&nnz_cache[4+8* 5], top_empty);

            AV_WN32A(&nnz_cache[4+8*10], top_empty);

        }

    }

    s->current_picture.f.mb_type[mb_xy] = mb_type;

    if( cbp || IS_INTRA16x16( mb_type ) ) {

        const uint8_t *scan, *scan8x8;

        const uint32_t *qmul;

        if(IS_INTERLACED(mb_type)){

            scan8x8= s->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;

            scan= s->qscale ? h->field_scan : h->field_scan_q0;

        }else{

            scan8x8= s->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;

            scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;

        }

        // decode_cabac_mb_dqp

        if(get_cabac_noinline( &h->cabac, &h->cabac_state[60 + (h->last_qscale_diff != 0)])){

            int val = 1;

            int ctx= 2;

            const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);

            while( get_cabac_noinline( &h->cabac, &h->cabac_state[60 + ctx] ) ) {

                ctx= 3;

                val++;

                if(val > 2*max_qp){ //prevent infinite loop

                    av_log(h->s.avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", s->mb_x, s->mb_y);

                }

            }

            if( val&0x01 )

                val=   (val + 1)>>1 ;

            else

                val= -((val + 1)>>1);

            h->last_qscale_diff = val;

            s->qscale += val;

            if(((unsigned)s->qscale) > max_qp){

                if(s->qscale<0) s->qscale+= max_qp+1;

                else            s->qscale-= max_qp+1;

            }

            h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);

            h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);

        }else

            h->last_qscale_diff=0;

        decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 0);

        if(CHROMA444){

            decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 1);

            decode_cabac_luma_residual(h, scan, scan8x8, pixel_shift, mb_type, cbp, 2);

        } else if (CHROMA422) {

            if( cbp&0x30 ){

                int c;

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

                    //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-DC\n",c );

                    decode_cabac_residual_dc_422(h, h->mb + ((256 + 16*16*c) << pixel_shift), 3,

                                                 CHROMA_DC_BLOCK_INDEX + c,

                                                 chroma422_dc_scan, 8);

                }

            }

            if( cbp&0x20 ) {

                int c, i, i8x8;

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

                    DCTELEM *mb = h->mb + (16*(16 + 16*c) << pixel_shift);

                    qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[c]];

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

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

                            const int index = 16 + 16 * c + 8*i8x8 + i;

                            //av_log(s->avctx, AV_LOG_ERROR, "INTRA C%d-AC %d\n",c, index - 16);

                            decode_cabac_residual_nondc(h, mb, 4, index, scan + 1, qmul, 15);

                            mb += 16<<pixel_shift;

                        }

                    }

                }

            } else {

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

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

            }

        } else /* yuv420 */ {

            if( cbp&0x30 ){

                int c;

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

                    //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-DC\n",c );

                    decode_cabac_residual_dc(h, h->mb + ((256 + 16*16*c) << pixel_shift), 3, CHROMA_DC_BLOCK_INDEX+c, chroma_dc_scan, 4);

                }

            }

            if( cbp&0x20 ) {

                int c, i;

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

                    qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[c]];

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

                        const int index = 16 + 16 * c + i;

                        //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-AC %d\n",c, index - 16 );

                        decode_cabac_residual_nondc(h, h->mb + (16*index << pixel_shift), 4, index, scan + 1, qmul, 15);

                    }

                }

            } else {

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

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

            }

        }

    } else {

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

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

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

        h->last_qscale_diff = 0;

    }

    s->current_picture.f.qscale_table[mb_xy] = s->qscale;

    write_back_non_zero_count(h);

    if(MB_MBAFF){

        h->ref_count[0] >>= 1;

        h->ref_count[1] >>= 1;

    }

    return 0;

}


static inline void RENAME(rgb32to15)(const uint8_t *src, uint8_t *dst, unsigned src_size)

{

	const uint8_t *s = src;

	const uint8_t *end;

#ifdef HAVE_MMX

	const uint8_t *mm_end;

#endif

	uint16_t *d = (uint16_t *)dst;

	end = s + src_size;

#ifdef HAVE_MMX

	mm_end = end - 15;

#if 1 //is faster only if multiplies are reasonable fast (FIXME figure out on which cpus this is faster, on Athlon its slightly faster)

	asm volatile(

		"movq %3, %%mm5			\n\t"

		"movq %4, %%mm6			\n\t"

		"movq %5, %%mm7			\n\t"

		".balign 16			\n\t"

		"1:				\n\t"

		PREFETCH" 32(%1)		\n\t"

		"movd	(%1), %%mm0		\n\t"

		"movd	4(%1), %%mm3		\n\t"

		"punpckldq 8(%1), %%mm0		\n\t"

		"punpckldq 12(%1), %%mm3	\n\t"

		"movq %%mm0, %%mm1		\n\t"

		"movq %%mm3, %%mm4		\n\t"

		"pand %%mm6, %%mm0		\n\t"

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

		"pmaddwd %%mm7, %%mm0		\n\t"

		"pmaddwd %%mm7, %%mm3		\n\t"

		"pand %%mm5, %%mm1		\n\t"

		"pand %%mm5, %%mm4		\n\t"

		"por %%mm1, %%mm0		\n\t"

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

		"psrld $6, %%mm0		\n\t"

		"pslld $10, %%mm3		\n\t"

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

		MOVNTQ"	%%mm0, (%0)		\n\t"

		"add $16, %1			\n\t"

		"add $8, %0			\n\t"

		"cmp %2, %1			\n\t"

		" jb 1b				\n\t"

		: "+r" (d), "+r"(s)

		: "r" (mm_end), "m" (mask3215g), "m" (mask3216br), "m" (mul3215)

	);

#else

	__asm __volatile(PREFETCH"	%0"::"m"(*src):"memory");

	__asm __volatile(

	    "movq	%0, %%mm7\n\t"

	    "movq	%1, %%mm6\n\t"

	    ::"m"(red_15mask),"m"(green_15mask));

	while(s < mm_end)

	{

	    __asm __volatile(

		PREFETCH" 32%1\n\t"

		"movd	%1, %%mm0\n\t"

		"movd	4%1, %%mm3\n\t"

		"punpckldq 8%1, %%mm0\n\t"

		"punpckldq 12%1, %%mm3\n\t"

		"movq	%%mm0, %%mm1\n\t"

		"movq	%%mm0, %%mm2\n\t"

		"movq	%%mm3, %%mm4\n\t"

		"movq	%%mm3, %%mm5\n\t"

		"psrlq	$3, %%mm0\n\t"

		"psrlq	$3, %%mm3\n\t"

		"pand	%2, %%mm0\n\t"

		"pand	%2, %%mm3\n\t"

		"psrlq	$6, %%mm1\n\t"

		"psrlq	$6, %%mm4\n\t"

		"pand	%%mm6, %%mm1\n\t"

		"pand	%%mm6, %%mm4\n\t"

		"psrlq	$9, %%mm2\n\t"

		"psrlq	$9, %%mm5\n\t"

		"pand	%%mm7, %%mm2\n\t"

		"pand	%%mm7, %%mm5\n\t"

		"por	%%mm1, %%mm0\n\t"

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

		"por	%%mm2, %%mm0\n\t"

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

		"psllq	$16, %%mm3\n\t"

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

		MOVNTQ"	%%mm0, %0\n\t"

		:"=m"(*d):"m"(*s),"m"(blue_15mask):"memory");

		d += 4;

		s += 16;

	}

#endif

	__asm __volatile(SFENCE:::"memory");

	__asm __volatile(EMMS:::"memory");

#endif

	while(s < end)

	{

		// FIXME on bigendian

		const int src= *s; s += 4;

		*d++ = ((src&0xFF)>>3) + ((src&0xF800)>>6) + ((src&0xF80000)>>9);

	}

}