static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    ZmbvContext * const c = avctx->priv_data;

    int zret = Z_OK; // Zlib return code

    int len = buf_size;

    int hi_ver, lo_ver, ret;

    if (c->pic.data[0])

            avctx->release_buffer(avctx, &c->pic);

    c->pic.reference = 3;

    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;

    if ((ret = avctx->get_buffer(avctx, &c->pic)) < 0) {

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

        return ret;

    }

    /* parse header */

    c->flags = buf[0];

    buf++; len--;

    if (c->flags & ZMBV_KEYFRAME) {

        void *decode_intra = NULL;

        c->decode_intra= NULL;

        hi_ver = buf[0];

        lo_ver = buf[1];

        c->comp = buf[2];

        c->fmt = buf[3];

        c->bw = buf[4];

        c->bh = buf[5];

        buf += 6;

        len -= 6;

        av_log(avctx, AV_LOG_DEBUG,

               "Flags=%X ver=%i.%i comp=%i fmt=%i blk=%ix%i\n",

               c->flags,hi_ver,lo_ver,c->comp,c->fmt,c->bw,c->bh);

        if (hi_ver != 0 || lo_ver != 1) {

            av_log_ask_for_sample(avctx, "Unsupported version %i.%i\n",

                                  hi_ver, lo_ver);

            return AVERROR_PATCHWELCOME;

        }

        if (c->bw == 0 || c->bh == 0) {

            av_log_ask_for_sample(avctx, "Unsupported block size %ix%i\n",

                                  c->bw, c->bh);

            return AVERROR_PATCHWELCOME;

        }

        if (c->comp != 0 && c->comp != 1) {

            av_log_ask_for_sample(avctx, "Unsupported compression type %i\n",

                                  c->comp);

            return AVERROR_PATCHWELCOME;

        }

        switch (c->fmt) {

        case ZMBV_FMT_8BPP:

            c->bpp = 8;

            decode_intra = zmbv_decode_intra;

            c->decode_xor = zmbv_decode_xor_8;

            break;

        case ZMBV_FMT_15BPP:

        case ZMBV_FMT_16BPP:

            c->bpp = 16;

            decode_intra = zmbv_decode_intra;

            c->decode_xor = zmbv_decode_xor_16;

            break;

#ifdef ZMBV_ENABLE_24BPP

        case ZMBV_FMT_24BPP:

            c->bpp = 24;

            decode_intra = zmbv_decode_intra;

            c->decode_xor = zmbv_decode_xor_24;

            break;

#endif //ZMBV_ENABLE_24BPP

        case ZMBV_FMT_32BPP:

            c->bpp = 32;

            decode_intra = zmbv_decode_intra;

            c->decode_xor = zmbv_decode_xor_32;

            break;

        default:

            c->decode_xor = NULL;

            av_log_ask_for_sample(avctx, "Unsupported (for now) format %i\n",

                                  c->fmt);

            return AVERROR_PATCHWELCOME;

        }

        zret = inflateReset(&c->zstream);

        if (zret != Z_OK) {

            av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);

            return -1;

        }

        c->cur  = av_realloc_f(c->cur, avctx->width * avctx->height,  (c->bpp / 8));

        c->prev = av_realloc_f(c->prev, avctx->width * avctx->height,  (c->bpp / 8));

        c->bx = (c->width + c->bw - 1) / c->bw;

        c->by = (c->height+ c->bh - 1) / c->bh;

        if (!c->cur || !c->prev)

            return -1;

        c->decode_intra= decode_intra;

    }

    if (c->decode_intra == NULL) {

        av_log(avctx, AV_LOG_ERROR, "Error! Got no format or no keyframe!\n");

        return AVERROR_INVALIDDATA;

    }

    if (c->comp == 0) { //Uncompressed data

        memcpy(c->decomp_buf, buf, len);

        c->decomp_size = 1;

    } else { // ZLIB-compressed data

        c->zstream.total_in = c->zstream.total_out = 0;

        c->zstream.next_in = (uint8_t*)buf;

        c->zstream.avail_in = len;

        c->zstream.next_out = c->decomp_buf;

        c->zstream.avail_out = c->decomp_size;

        zret = inflate(&c->zstream, Z_SYNC_FLUSH);

        if (zret != Z_OK && zret != Z_STREAM_END) {

            av_log(avctx, AV_LOG_ERROR, "inflate error %d\n", zret);

            return AVERROR_INVALIDDATA;

        }

        c->decomp_len = c->zstream.total_out;

    }

    if (c->flags & ZMBV_KEYFRAME) {

        c->pic.key_frame = 1;

        c->pic.pict_type = AV_PICTURE_TYPE_I;

        c->decode_intra(c);

    } else {

        c->pic.key_frame = 0;

        c->pic.pict_type = AV_PICTURE_TYPE_P;

        if (c->decomp_len)

            c->decode_xor(c);

    }

    /* update frames */

    {

        uint8_t *out, *src;

        int i, j;

        out = c->pic.data[0];

        src = c->cur;

        switch (c->fmt) {

        case ZMBV_FMT_8BPP:

            for (j = 0; j < c->height; j++) {

                for (i = 0; i < c->width; i++) {

                    out[i * 3 + 0] = c->pal[(*src) * 3 + 0];

                    out[i * 3 + 1] = c->pal[(*src) * 3 + 1];

                    out[i * 3 + 2] = c->pal[(*src) * 3 + 2];

                    src++;

                }

                out += c->pic.linesize[0];

            }

            break;

        case ZMBV_FMT_15BPP:

            for (j = 0; j < c->height; j++) {

                for (i = 0; i < c->width; i++) {

                    uint16_t tmp = AV_RL16(src);

                    src += 2;

                    out[i * 3 + 0] = (tmp & 0x7C00) >> 7;

                    out[i * 3 + 1] = (tmp & 0x03E0) >> 2;

                    out[i * 3 + 2] = (tmp & 0x001F) << 3;

                }

                out += c->pic.linesize[0];

            }

            break;

        case ZMBV_FMT_16BPP:

            for (j = 0; j < c->height; j++) {

                for (i = 0; i < c->width; i++) {

                    uint16_t tmp = AV_RL16(src);

                    src += 2;

                    out[i * 3 + 0] = (tmp & 0xF800) >> 8;

                    out[i * 3 + 1] = (tmp & 0x07E0) >> 3;

                    out[i * 3 + 2] = (tmp & 0x001F) << 3;

                }

                out += c->pic.linesize[0];

            }

            break;

#ifdef ZMBV_ENABLE_24BPP

        case ZMBV_FMT_24BPP:

            for (j = 0; j < c->height; j++) {

                memcpy(out, src, c->width * 3);

                src += c->width * 3;

                out += c->pic.linesize[0];

            }

            break;

#endif //ZMBV_ENABLE_24BPP

        case ZMBV_FMT_32BPP:

            for (j = 0; j < c->height; j++) {

                for (i = 0; i < c->width; i++) {

                    uint32_t tmp = AV_RL32(src);

                    src += 4;

                    AV_WB24(out+(i*3), tmp);

                }

                out += c->pic.linesize[0];

            }

            break;

        default:

            av_log(avctx, AV_LOG_ERROR, "Cannot handle format %i\n", c->fmt);

        }

        FFSWAP(uint8_t *, c->cur, c->prev);

    }

    *data_size = sizeof(AVFrame);

    *(AVFrame*)data = c->pic;

    /* always report that the buffer was completely consumed */

    return buf_size;

}


static int idcin_decode_frame(AVCodecContext *avctx,

                              void *data, int *got_frame,

                              AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    IdcinContext *s = avctx->priv_data;

    const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);

    AVFrame *frame = data;

    int ret;

    s->buf = buf;

    s->size = buf_size;

    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)

        return ret;

    if (idcin_decode_vlcs(s, frame))

        return AVERROR_INVALIDDATA;

    if (pal) {

        frame->palette_has_changed = 1;

        memcpy(s->pal, pal, AVPALETTE_SIZE);

    }

    /* make the palette available on the way out */

    memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);

    *got_frame = 1;

    /* report that the buffer was completely consumed */

    return buf_size;

}


static int sunrast_decode_frame(AVCodecContext *avctx, void *data,

                                int *data_size, AVPacket *avpkt) {

    const uint8_t *buf = avpkt->data;

    SUNRASTContext * const s = avctx->priv_data;

    AVFrame *picture = data;

    AVFrame * const p = &s->picture;

    unsigned int w, h, depth, type, maptype, maplength, stride, x, y, len, alen;

    uint8_t *ptr;

    const uint8_t *bufstart = buf;

    if (AV_RB32(buf) != 0x59a66a95) {

        av_log(avctx, AV_LOG_ERROR, "this is not sunras encoded data\n");

        return -1;

    }

    w         = AV_RB32(buf+4);

    h         = AV_RB32(buf+8);

    depth     = AV_RB32(buf+12);

    type      = AV_RB32(buf+20);

    maptype   = AV_RB32(buf+24);

    maplength = AV_RB32(buf+28);

    if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF) {

        av_log(avctx, AV_LOG_ERROR, "unsupported (compression) type\n");

        return -1;

    }

    if (type > RT_FORMAT_IFF) {

        av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n");

        return -1;

    }

    if (maptype & ~1) {

        av_log(avctx, AV_LOG_ERROR, "invalid colormap type\n");

        return -1;

    }

    buf += 32;

    switch (depth) {

        case 1:

            avctx->pix_fmt = PIX_FMT_MONOWHITE;

            break;

        case 8:

            avctx->pix_fmt = PIX_FMT_PAL8;

            break;

        case 24:

            avctx->pix_fmt = (type == RT_FORMAT_RGB) ? PIX_FMT_RGB24 : PIX_FMT_BGR24;

            break;

        default:

            av_log(avctx, AV_LOG_ERROR, "invalid depth\n");

            return -1;

    }

    if (p->data[0])

        avctx->release_buffer(avctx, p);

    if (av_image_check_size(w, h, 0, avctx))

        return -1;

    if (w != avctx->width || h != avctx->height)

        avcodec_set_dimensions(avctx, w, h);

    if (avctx->get_buffer(avctx, p) < 0) {

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

        return -1;

    }

    p->pict_type = AV_PICTURE_TYPE_I;

    if (depth != 8 && maplength) {

        av_log(avctx, AV_LOG_WARNING, "useless colormap found or file is corrupted, trying to recover\n");

    } else if (depth == 8) {

        unsigned int len = maplength / 3;

        if (!maplength) {

            av_log(avctx, AV_LOG_ERROR, "colormap expected\n");

            return -1;

        }

        if (maplength % 3 || maplength > 768) {

            av_log(avctx, AV_LOG_WARNING, "invalid colormap length\n");

            return -1;

        }

        ptr = p->data[1];

        for (x=0; x<len; x++, ptr+=4)

            *(uint32_t *)ptr = (buf[x]<<16) + (buf[len+x]<<8) + buf[len+len+x];

    }

    buf += maplength;

    ptr    = p->data[0];

    stride = p->linesize[0];

    /* scanlines are aligned on 16 bit boundaries */

    len  = (depth * w + 7) >> 3;

    alen = len + (len&1);

    if (type == RT_BYTE_ENCODED) {

        int value, run;

        uint8_t *end = ptr + h*stride;

        x = 0;

        while (ptr != end) {

            run = 1;

            if ((value = *buf++) == 0x80) {

                run = *buf++ + 1;

                if (run != 1)

                    value = *buf++;

            }

            while (run--) {

                if (x < len)

                    ptr[x] = value;

                if (++x >= alen) {

                    x = 0;

                    ptr += stride;

                    if (ptr == end)

                        break;

                }

            }

        }

    } else {

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

            memcpy(ptr, buf, len);

            ptr += stride;

            buf += alen;

        }

    }

    *picture = s->picture;

    *data_size = sizeof(AVFrame);

    return buf - bufstart;

}


static void nand_command(NANDFlashState *s)

{

    unsigned int offset;

    switch (s->cmd) {

    case NAND_CMD_READ0:

        s->iolen = 0;

        break;

    case NAND_CMD_READID:

        s->ioaddr = s->io;

        s->iolen = 0;

        nand_pushio_byte(s, s->manf_id);

        nand_pushio_byte(s, s->chip_id);

        nand_pushio_byte(s, 'Q'); /* Don't-care byte (often 0xa5) */

        if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {

            /* Page Size, Block Size, Spare Size; bit 6 indicates

             * 8 vs 16 bit width NAND.

             */

            nand_pushio_byte(s, (s->buswidth == 2) ? 0x55 : 0x15);

        } else {

            nand_pushio_byte(s, 0xc0); /* Multi-plane */

        }

        break;

    case NAND_CMD_RANDOMREAD2:

    case NAND_CMD_NOSERIALREAD2:

        if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP))

            break;

        offset = s->addr & ((1 << s->addr_shift) - 1);

        s->blk_load(s, s->addr, offset);

        if (s->gnd)

            s->iolen = (1 << s->page_shift) - offset;

        else

            s->iolen = (1 << s->page_shift) + (1 << s->oob_shift) - offset;

        break;

    case NAND_CMD_RESET:

        nand_reset(&s->busdev.qdev);

        break;

    case NAND_CMD_PAGEPROGRAM1:

        s->ioaddr = s->io;

        s->iolen = 0;

        break;

    case NAND_CMD_PAGEPROGRAM2:

        if (s->wp) {

            s->blk_write(s);

        }

        break;

    case NAND_CMD_BLOCKERASE1:

        break;

    case NAND_CMD_BLOCKERASE2:

        s->addr &= (1ull << s->addrlen * 8) - 1;

        if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)

            s->addr <<= 16;

        else

            s->addr <<= 8;

        if (s->wp) {

            s->blk_erase(s);

        }

        break;

    case NAND_CMD_READSTATUS:

        s->ioaddr = s->io;

        s->iolen = 0;

        nand_pushio_byte(s, s->status);

        break;

    default:

        printf("%s: Unknown NAND command 0x%02x\n", __FUNCTION__, s->cmd);

    }

}


static void readline_hist_add(ReadLineState *rs, const char *cmdline)

{

    char *hist_entry, *new_entry;

    int idx;

    if (cmdline[0] == '\0')

	return;

    new_entry = NULL;

    if (rs->hist_entry != -1) {

	/* We were editing an existing history entry: replace it */

	hist_entry = rs->history[rs->hist_entry];

	idx = rs->hist_entry;

	if (strcmp(hist_entry, cmdline) == 0) {

	    goto same_entry;

	}

    }

    /* Search cmdline in history buffers */

    for (idx = 0; idx < READLINE_MAX_CMDS; idx++) {

	hist_entry = rs->history[idx];

	if (hist_entry == NULL)

	    break;

	if (strcmp(hist_entry, cmdline) == 0) {

	same_entry:

	    new_entry = hist_entry;

	    /* Put this entry at the end of history */

	    memmove(&rs->history[idx], &rs->history[idx + 1],

		    (READLINE_MAX_CMDS - idx + 1) * sizeof(char *));

	    rs->history[READLINE_MAX_CMDS - 1] = NULL;

	    for (; idx < READLINE_MAX_CMDS; idx++) {

		if (rs->history[idx] == NULL)

		    break;

	    }

	    break;

	}

    }

    if (idx == READLINE_MAX_CMDS) {

	/* Need to get one free slot */

	free(rs->history[0]);

	memcpy(rs->history, &rs->history[1],

	       (READLINE_MAX_CMDS - 1) * sizeof(char *));

	rs->history[READLINE_MAX_CMDS - 1] = NULL;

	idx = READLINE_MAX_CMDS - 1;

    }

    if (new_entry == NULL)

	new_entry = strdup(cmdline);

    rs->history[idx] = new_entry;

    rs->hist_entry = -1;

}


static int flush_blks(QEMUFile *f)

{

    BlkMigBlock *blk;

    int ret = 0;

    DPRINTF("%s Enter submitted %d read_done %d transferred %d\n",

            __FUNCTION__, block_mig_state.submitted, block_mig_state.read_done,

            block_mig_state.transferred);

    blk_mig_lock();

    while ((blk = QSIMPLEQ_FIRST(&block_mig_state.blk_list)) != NULL) {

        if (qemu_file_rate_limit(f)) {

            break;

        }

        if (blk->ret < 0) {

            ret = blk->ret;

            break;

        }

        QSIMPLEQ_REMOVE_HEAD(&block_mig_state.blk_list, entry);

        blk_mig_unlock();

        blk_send(f, blk);

        blk_mig_lock();

        g_free(blk->buf);

        g_free(blk);

        block_mig_state.read_done--;

        block_mig_state.transferred++;

        assert(block_mig_state.read_done >= 0);

    }

    blk_mig_unlock();

    DPRINTF("%s Exit submitted %d read_done %d transferred %d\n", __FUNCTION__,

            block_mig_state.submitted, block_mig_state.read_done,

            block_mig_state.transferred);

    return ret;

}


static int bitplane_decoding(BitPlane *bp, VC9Context *v)

{

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

    int imode, x, y, code, use_vertical_tile, tile_w, tile_h;

    uint8_t invert, *planep = bp->data;

    invert = get_bits(gb, 1);

    imode = get_vlc2(gb, vc9_imode_vlc.table, VC9_IMODE_VLC_BITS, 2);

    bp->is_raw = 0;

    switch (imode)

    {

    case IMODE_RAW:

        //Data is actually read in the MB layer (same for all tests == "raw")

        bp->is_raw = 1; //invert ignored

        return invert;

    case IMODE_DIFF2:

    case IMODE_NORM2:

        if ((bp->height*bp->width) & 1) *(++planep) = get_bits(gb, 1);

        for(x=0; x<(bp->height*bp->width)>>1; x++){

            code = get_vlc2(gb, vc9_norm2_vlc.table, VC9_NORM2_VLC_BITS, 2);

            *(++planep) = code&1; //lsb => left

            *(++planep) = (code>>1)&1; //msb => right

            //FIXME width->stride

        }

        break;

    case IMODE_DIFF6:

    case IMODE_NORM6:

        use_vertical_tile=  bp->height%3==0 &&  bp->width%3!=0;

        tile_w= use_vertical_tile ? 2 : 3;

        tile_h= use_vertical_tile ? 3 : 2;

        for(y=  bp->height%tile_h; y< bp->height; y+=tile_h){

            for(x=  bp->width%tile_w; x< bp->width; x+=tile_w){

#if VLC_NORM6_METH0D == 1

                code = get_vlc2(gb, vc9_norm6_vlc.table, VC9_NORM6_VLC_BITS, 2);

                if(code<0){

                    av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");

                    return -1;

                }

#endif

#if VLC_NORM6_METH0D == 2 //Failure

                code = get_vlc2(gb, vc9_norm6_first_vlc.table, VC9_NORM6_FIRST_BITS, 2);

                if (code == 22)

                {

                    code = vc9_norm6_flc_val[get_bits(gb, 5)];

                }

                else if (code == 23)

                {

#  if TRACE

                    code = get_vlc2(gb, vc9_norm6_second_vlc.table, VC9_NORM6_SECOND_BITS, 2);

                    assert(code>-1 && code<22);

                    code = vc9_norm6_second_val[code];

#  else

                    code = vc9_norm6_second_val[get_vlc2(gb, vc9_norm6_second_vlc.table, VC9_NORM6_SECOND_BITS, 2)];

#  endif

                }

#endif //VLC_NORM6_METH0D == 2

                //FIXME following is a pure guess and probably wrong

                //FIXME A bitplane (0 | !0), so could the shifts be avoided ?

                planep[x     + 0*bp->stride]= (code>>0)&1;

                planep[x + 1 + 0*bp->stride]= (code>>1)&1;

                //FIXME Does branch prediction help here?

                if(use_vertical_tile){

                    planep[x + 0 + 1*bp->stride]= (code>>2)&1;

                    planep[x + 1 + 1*bp->stride]= (code>>3)&1;

                    planep[x + 0 + 2*bp->stride]= (code>>4)&1;

                    planep[x + 1 + 2*bp->stride]= (code>>5)&1;

                }else{

                    planep[x + 2 + 0*bp->stride]= (code>>2)&1;

                    planep[x + 0 + 1*bp->stride]= (code>>3)&1;

                    planep[x + 1 + 1*bp->stride]= (code>>4)&1;

                    planep[x + 2 + 1*bp->stride]= (code>>5)&1;

                }

            }

        }

        x=  bp->width % tile_w;

        decode_colskip(bp->data  ,             x, bp->height         , bp->stride, v);

        decode_rowskip(bp->data+x, bp->width - x, bp->height % tile_h, bp->stride, v);

        break;

    case IMODE_ROWSKIP:

        decode_rowskip(bp->data, bp->width, bp->height, bp->stride, v);

        break;

    case IMODE_COLSKIP: //Teh ugly

        decode_colskip(bp->data, bp->width, bp->height, bp->stride, v);

        break;

    default: break;

    }

    /* Applying diff operator */

    if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)

    {

        planep = bp->data;

        planep[0] ^= invert;

        for (x=1; x<bp->width; x++)

            planep[x] ^= planep[x-1];

        for (y=1; y<bp->height; y++)

        {

            planep += bp->stride;

            planep[0] ^= planep[-bp->stride];

            for (x=1; x<bp->width; x++)

            {

                if (planep[x-1] != planep[x-bp->stride]) planep[x] ^= invert;

                else                                     planep[x] ^= planep[x-1];

            }

        }

    }

    else if (invert)

    {

        planep = bp->data;

        for (x=0; x<bp->width*bp->height; x++) planep[x] = !planep[x]; //FIXME stride

    }

    return (imode<<1) + invert;

}


static void sx1_init(MachineState *machine, const int version)

{

    struct omap_mpu_state_s *mpu;

    MemoryRegion *address_space = get_system_memory();

    MemoryRegion *flash = g_new(MemoryRegion, 1);

    MemoryRegion *flash_1 = g_new(MemoryRegion, 1);

    MemoryRegion *cs = g_new(MemoryRegion, 4);

    static uint32_t cs0val = 0x00213090;

    static uint32_t cs1val = 0x00215070;

    static uint32_t cs2val = 0x00001139;

    static uint32_t cs3val = 0x00001139;

    DriveInfo *dinfo;

    int fl_idx;

    uint32_t flash_size = flash0_size;

    int be;

    if (version == 2) {

        flash_size = flash2_size;

    }

    mpu = omap310_mpu_init(address_space, sx1_binfo.ram_size,

                           machine->cpu_model);

    /* External Flash (EMIFS) */

    memory_region_init_ram(flash, NULL, "omap_sx1.flash0-0", flash_size,

                           &error_abort);

    vmstate_register_ram_global(flash);

    memory_region_set_readonly(flash, true);

    memory_region_add_subregion(address_space, OMAP_CS0_BASE, flash);

    memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val,

                          "sx1.cs0", OMAP_CS0_SIZE - flash_size);

    memory_region_add_subregion(address_space,

                                OMAP_CS0_BASE + flash_size, &cs[0]);

    memory_region_init_io(&cs[2], NULL, &static_ops, &cs2val,

                          "sx1.cs2", OMAP_CS2_SIZE);

    memory_region_add_subregion(address_space,

                                OMAP_CS2_BASE, &cs[2]);

    memory_region_init_io(&cs[3], NULL, &static_ops, &cs3val,

                          "sx1.cs3", OMAP_CS3_SIZE);

    memory_region_add_subregion(address_space,

                                OMAP_CS2_BASE, &cs[3]);

    fl_idx = 0;

#ifdef TARGET_WORDS_BIGENDIAN

    be = 1;

#else

    be = 0;

#endif

    if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {

        if (!pflash_cfi01_register(OMAP_CS0_BASE, NULL,

                                   "omap_sx1.flash0-1", flash_size,

                                   blk_by_legacy_dinfo(dinfo),

                                   sector_size, flash_size / sector_size,

                                   4, 0, 0, 0, 0, be)) {

            fprintf(stderr, "qemu: Error registering flash memory %d.\n",

                           fl_idx);

        }

        fl_idx++;

    }

    if ((version == 1) &&

            (dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {

        memory_region_init_ram(flash_1, NULL, "omap_sx1.flash1-0", flash1_size,

                               &error_abort);

        vmstate_register_ram_global(flash_1);

        memory_region_set_readonly(flash_1, true);

        memory_region_add_subregion(address_space, OMAP_CS1_BASE, flash_1);

        memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,

                              "sx1.cs1", OMAP_CS1_SIZE - flash1_size);

        memory_region_add_subregion(address_space,

                                OMAP_CS1_BASE + flash1_size, &cs[1]);

        if (!pflash_cfi01_register(OMAP_CS1_BASE, NULL,

                                   "omap_sx1.flash1-1", flash1_size,

                                   blk_by_legacy_dinfo(dinfo),

                                   sector_size, flash1_size / sector_size,

                                   4, 0, 0, 0, 0, be)) {

            fprintf(stderr, "qemu: Error registering flash memory %d.\n",

                           fl_idx);

        }

        fl_idx++;

    } else {

        memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,

                              "sx1.cs1", OMAP_CS1_SIZE);

        memory_region_add_subregion(address_space,

                                OMAP_CS1_BASE, &cs[1]);

    }

    if (!machine->kernel_filename && !fl_idx && !qtest_enabled()) {

        fprintf(stderr, "Kernel or Flash image must be specified\n");

        exit(1);

    }

    /* Load the kernel.  */

    sx1_binfo.kernel_filename = machine->kernel_filename;

    sx1_binfo.kernel_cmdline = machine->kernel_cmdline;

    sx1_binfo.initrd_filename = machine->initrd_filename;

    arm_load_kernel(mpu->cpu, &sx1_binfo);

    /* TODO: fix next line */

    //~ qemu_console_resize(ds, 640, 480);

}


static void avc_luma_mid_16w_msa(const uint8_t *src, int32_t src_stride,

                                 uint8_t *dst, int32_t dst_stride,

                                 int32_t height)

{

    uint32_t multiple8_cnt;

    for (multiple8_cnt = 2; multiple8_cnt--;) {

        avc_luma_mid_8w_msa(src, src_stride, dst, dst_stride, height);

        src += 8;

        dst += 8;

    }

}


static int mpeg_decode_mb(MpegEncContext *s, DCTELEM block[12][64])

{

    int i, j, k, cbp, val, mb_type, motion_type;

    const int mb_block_count = 4 + (1 << s->chroma_format);

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

    assert(s->mb_skipped == 0);

    if (s->mb_skip_run-- != 0) {

        if (s->pict_type == AV_PICTURE_TYPE_P) {

            s->mb_skipped = 1;

            s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;

        } else {

            int mb_type;

            if (s->mb_x)

                mb_type = s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1];

            else

                mb_type = s->current_picture.f.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all

            if (IS_INTRA(mb_type))

                return -1;

            s->current_picture.f.mb_type[s->mb_x + s->mb_y*s->mb_stride] =

                mb_type | MB_TYPE_SKIP;

//            assert(s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8));

            if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0)

                s->mb_skipped = 1;

        }

        return 0;

    }

    switch (s->pict_type) {

    default:

    case AV_PICTURE_TYPE_I:

        if (get_bits1(&s->gb) == 0) {

            if (get_bits1(&s->gb) == 0) {

                av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in I Frame at %d %d\n", s->mb_x, s->mb_y);

                return -1;

            }

            mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA;

        } else {

            mb_type = MB_TYPE_INTRA;

        }

        break;

    case AV_PICTURE_TYPE_P:

        mb_type = get_vlc2(&s->gb, mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1);

        if (mb_type < 0) {

            av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y);

            return -1;

        }

        mb_type = ptype2mb_type[mb_type];

        break;

    case AV_PICTURE_TYPE_B:

        mb_type = get_vlc2(&s->gb, mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1);

        if (mb_type < 0) {

            av_log(s->avctx, AV_LOG_ERROR, "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y);

            return -1;

        }

        mb_type = btype2mb_type[mb_type];

        break;

    }

    av_dlog(s->avctx, "mb_type=%x\n", mb_type);

//    motion_type = 0; /* avoid warning */

    if (IS_INTRA(mb_type)) {

        s->dsp.clear_blocks(s->block[0]);

        if (!s->chroma_y_shift) {

            s->dsp.clear_blocks(s->block[6]);

        }

        /* compute DCT type */

        if (s->picture_structure == PICT_FRAME && // FIXME add an interlaced_dct coded var?

            !s->frame_pred_frame_dct) {

            s->interlaced_dct = get_bits1(&s->gb);

        }

        if (IS_QUANT(mb_type))

            s->qscale = get_qscale(s);

        if (s->concealment_motion_vectors) {

            /* just parse them */

            if (s->picture_structure != PICT_FRAME)

                skip_bits1(&s->gb); /* field select */

            s->mv[0][0][0]= s->last_mv[0][0][0]= s->last_mv[0][1][0] =

                mpeg_decode_motion(s, s->mpeg_f_code[0][0], s->last_mv[0][0][0]);

            s->mv[0][0][1]= s->last_mv[0][0][1]= s->last_mv[0][1][1] =

                mpeg_decode_motion(s, s->mpeg_f_code[0][1], s->last_mv[0][0][1]);

            skip_bits1(&s->gb); /* marker */

        } else

            memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */

        s->mb_intra = 1;

        // if 1, we memcpy blocks in xvmcvideo

        if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {

            ff_xvmc_pack_pblocks(s, -1); // inter are always full blocks

            if (s->swap_uv) {

                exchange_uv(s);

            }

        }

        if (s->codec_id == CODEC_ID_MPEG2VIDEO) {

            if (s->flags2 & CODEC_FLAG2_FAST) {

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

                    mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i);

                }

            } else {

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

                    if (mpeg2_decode_block_intra(s, *s->pblocks[i], i) < 0)

                        return -1;

                }

            }

        } else {

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

                if (mpeg1_decode_block_intra(s, *s->pblocks[i], i) < 0)

                    return -1;

            }

        }

    } else {

        if (mb_type & MB_TYPE_ZERO_MV) {

            assert(mb_type & MB_TYPE_CBP);

            s->mv_dir = MV_DIR_FORWARD;

            if (s->picture_structure == PICT_FRAME) {

                if (!s->frame_pred_frame_dct)

                    s->interlaced_dct = get_bits1(&s->gb);

                s->mv_type = MV_TYPE_16X16;

            } else {

                s->mv_type = MV_TYPE_FIELD;

                mb_type |= MB_TYPE_INTERLACED;

                s->field_select[0][0] = s->picture_structure - 1;

            }

            if (IS_QUANT(mb_type))

                s->qscale = get_qscale(s);

            s->last_mv[0][0][0] = 0;

            s->last_mv[0][0][1] = 0;

            s->last_mv[0][1][0] = 0;

            s->last_mv[0][1][1] = 0;

            s->mv[0][0][0] = 0;

            s->mv[0][0][1] = 0;

        } else {

            assert(mb_type & MB_TYPE_L0L1);

            // FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED

            /* get additional motion vector type */

            if (s->frame_pred_frame_dct)

                motion_type = MT_FRAME;

            else {

                motion_type = get_bits(&s->gb, 2);

                if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type))

                    s->interlaced_dct = get_bits1(&s->gb);

            }

            if (IS_QUANT(mb_type))

                s->qscale = get_qscale(s);

            /* motion vectors */

            s->mv_dir = (mb_type >> 13) & 3;

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

            switch (motion_type) {

            case MT_FRAME: /* or MT_16X8 */

                if (s->picture_structure == PICT_FRAME) {

                    mb_type |= MB_TYPE_16x16;

                    s->mv_type = MV_TYPE_16X16;

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

                        if (USES_LIST(mb_type, i)) {

                            /* MT_FRAME */

                            s->mv[i][0][0]= s->last_mv[i][0][0]= s->last_mv[i][1][0] =

                                mpeg_decode_motion(s, s->mpeg_f_code[i][0], s->last_mv[i][0][0]);

                            s->mv[i][0][1]= s->last_mv[i][0][1]= s->last_mv[i][1][1] =

                                mpeg_decode_motion(s, s->mpeg_f_code[i][1], s->last_mv[i][0][1]);

                            /* full_pel: only for MPEG-1 */

                            if (s->full_pel[i]) {

                                s->mv[i][0][0] <<= 1;

                                s->mv[i][0][1] <<= 1;

                            }

                        }

                    }

                } else {

                    mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;

                    s->mv_type = MV_TYPE_16X8;

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

                        if (USES_LIST(mb_type, i)) {

                            /* MT_16X8 */

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

                                s->field_select[i][j] = get_bits1(&s->gb);

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

                                    val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],

                                                             s->last_mv[i][j][k]);

                                    s->last_mv[i][j][k] = val;

                                    s->mv[i][j][k]      = val;

                                }

                            }

                        }

                    }

                }

                break;

            case MT_FIELD:

                if(s->progressive_sequence){

                    av_log(s->avctx, AV_LOG_ERROR, "MT_FIELD in progressive_sequence\n");

                    return -1;

                }

                s->mv_type = MV_TYPE_FIELD;

                if (s->picture_structure == PICT_FRAME) {

                    mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;

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

                        if (USES_LIST(mb_type, i)) {

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

                                s->field_select[i][j] = get_bits1(&s->gb);

                                val = mpeg_decode_motion(s, s->mpeg_f_code[i][0],

                                                         s->last_mv[i][j][0]);

                                s->last_mv[i][j][0] = val;

                                s->mv[i][j][0]      = val;

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

                                val = mpeg_decode_motion(s, s->mpeg_f_code[i][1],

                                                         s->last_mv[i][j][1] >> 1);

                                s->last_mv[i][j][1] = val << 1;

                                s->mv[i][j][1]      = val;

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

                            }

                        }

                    }

                } else {

                    av_assert0(!s->progressive_sequence);

                    mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;

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

                        if (USES_LIST(mb_type, i)) {

                            s->field_select[i][0] = get_bits1(&s->gb);

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

                                val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],

                                                         s->last_mv[i][0][k]);

                                s->last_mv[i][0][k] = val;

                                s->last_mv[i][1][k] = val;

                                s->mv[i][0][k]      = val;

                            }

                        }

                    }

                }

                break;

            case MT_DMV:

                if(s->progressive_sequence){

                    av_log(s->avctx, AV_LOG_ERROR, "MT_DMV in progressive_sequence\n");

                    return -1;

                }

                s->mv_type = MV_TYPE_DMV;

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

                    if (USES_LIST(mb_type, i)) {

                        int dmx, dmy, mx, my, m;

                        const int my_shift = s->picture_structure == PICT_FRAME;

                        mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],

                                                s->last_mv[i][0][0]);

                        s->last_mv[i][0][0] = mx;

                        s->last_mv[i][1][0] = mx;

                        dmx = get_dmv(s);

                        my  = mpeg_decode_motion(s, s->mpeg_f_code[i][1],

                                                 s->last_mv[i][0][1] >> my_shift);

                        dmy = get_dmv(s);

                        s->last_mv[i][0][1] = my << my_shift;

                        s->last_mv[i][1][1] = my << my_shift;

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

                        s->mv[i][0][1] = my;

                        s->mv[i][1][0] = mx; // not used

                        s->mv[i][1][1] = my; // not used

                        if (s->picture_structure == PICT_FRAME) {

                            mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;

                            // m = 1 + 2 * s->top_field_first;

                            m = s->top_field_first ? 1 : 3;

                            /* top -> top pred */

                            s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx;

                            s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1;

                            m = 4 - m;

                            s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx;

                            s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1;

                        } else {

                            mb_type |= MB_TYPE_16x16;

                            s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx;

                            s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy;

                            if (s->picture_structure == PICT_TOP_FIELD)

                                s->mv[i][2][1]--;

                            else

                                s->mv[i][2][1]++;

                        }

                    }

                }

                break;

            default:

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

                return -1;

            }

        }

        s->mb_intra = 0;

        if (HAS_CBP(mb_type)) {

            s->dsp.clear_blocks(s->block[0]);

            cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1);

            if (mb_block_count > 6) {

                 cbp <<= mb_block_count - 6;

                 cbp  |= get_bits(&s->gb, mb_block_count - 6);

                 s->dsp.clear_blocks(s->block[6]);

            }

            if (cbp <= 0) {

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

                return -1;

            }

            //if 1, we memcpy blocks in xvmcvideo

            if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {

                ff_xvmc_pack_pblocks(s, cbp);

                if (s->swap_uv) {

                    exchange_uv(s);

                }

            }

            if (s->codec_id == CODEC_ID_MPEG2VIDEO) {

                if (s->flags2 & CODEC_FLAG2_FAST) {

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

                        if (cbp & 32) {

                            mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i);

                        } else {

                            s->block_last_index[i] = -1;

                        }

                        cbp += cbp;

                    }

                } else {

                    cbp <<= 12-mb_block_count;

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

                        if (cbp & (1 << 11)) {

                            if (mpeg2_decode_block_non_intra(s, *s->pblocks[i], i) < 0)

                                return -1;

                        } else {

                            s->block_last_index[i] = -1;

                        }

                        cbp += cbp;

                    }

                }

            } else {

                if (s->flags2 & CODEC_FLAG2_FAST) {

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

                        if (cbp & 32) {

                            mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i);

                        } else {

                            s->block_last_index[i] = -1;

                        }

                        cbp += cbp;

                    }

                } else {

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

                        if (cbp & 32) {

                            if (mpeg1_decode_block_inter(s, *s->pblocks[i], i) < 0)

                                return -1;

                        } else {

                            s->block_last_index[i] = -1;

                        }

                        cbp += cbp;

                    }

                }

            }

        } else {

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

                s->block_last_index[i] = -1;

        }

    }

    s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type;

    return 0;

}


AVFilterBufferRef *avfilter_get_audio_buffer(AVFilterLink *link, int perms,

                                             enum AVSampleFormat sample_fmt, int size,

                                             int64_t channel_layout, int planar)

{

    AVFilterBufferRef *ret = NULL;

    if (link->dstpad->get_audio_buffer)

        ret = link->dstpad->get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar);

    if (!ret)

        ret = avfilter_default_get_audio_buffer(link, perms, sample_fmt, size, channel_layout, planar);

    if (ret)

        ret->type = AVMEDIA_TYPE_AUDIO;

    return ret;

}


bool qemu_log_in_addr_range(uint64_t addr)

{

    if (debug_regions) {

        int i = 0;

        for (i = 0; i < debug_regions->len; i++) {

            Range *range = &g_array_index(debug_regions, Range, i);

            if (addr >= range->begin && addr <= range->end - 1) {

                return true;

            }

        }

        return false;

    } else {

        return true;

    }

}


static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s)

{

    int64_t rt = qemu_get_clock(rt_clock);

    if (s->rtsr & (1 << 12))

        s->last_swcr += (rt - s->last_sw) / 10;

    s->last_sw = rt;

}


static int net_socket_connect_init(NetClientState *peer,

                                   const char *model,

                                   const char *name,

                                   const char *host_str)

{

    socket_connect_data *c = g_new0(socket_connect_data, 1);

    int fd = -1;

    Error *local_error = NULL;

    c->peer = peer;

    c->model = g_strdup(model);

    c->name = g_strdup(name);

    c->saddr = socket_parse(host_str, &local_error);

    if (c->saddr == NULL) {

        goto err;

    }

    fd = socket_connect(c->saddr, net_socket_connected, c, &local_error);

    if (fd < 0) {

        goto err;

    }

    return 0;

err:

    error_report_err(local_error);

    socket_connect_data_free(c);

    return -1;

}


int css_do_hsch(SubchDev *sch)

{

    SCSW *s = &sch->curr_status.scsw;

    PMCW *p = &sch->curr_status.pmcw;

    int ret;

    if (!(p->flags & (PMCW_FLAGS_MASK_DNV | PMCW_FLAGS_MASK_ENA))) {

        ret = -ENODEV;

        goto out;

    }

    if (((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_STATUS_PEND) ||

        (s->ctrl & (SCSW_STCTL_PRIMARY |

                    SCSW_STCTL_SECONDARY |

                    SCSW_STCTL_ALERT))) {

        ret = -EINPROGRESS;

        goto out;

    }

    if (s->ctrl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {

        ret = -EBUSY;

        goto out;

    }

    /* Trigger the halt function. */

    s->ctrl |= SCSW_FCTL_HALT_FUNC;

    s->ctrl &= ~SCSW_FCTL_START_FUNC;

    if (((s->ctrl & SCSW_CTRL_MASK_ACTL) ==

         (SCSW_ACTL_SUBCH_ACTIVE | SCSW_ACTL_DEVICE_ACTIVE)) &&

        ((s->ctrl & SCSW_CTRL_MASK_STCTL) == SCSW_STCTL_INTERMEDIATE)) {

        s->ctrl &= ~SCSW_STCTL_STATUS_PEND;

    }

    s->ctrl |= SCSW_ACTL_HALT_PEND;

    do_subchannel_work(sch, NULL);

    ret = 0;

out:

    return ret;

}


static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)

{

    for (;;) {

        int i;

        uint8_t rx;

        uint8_t tx = 0;

        for (i = 0; i < num_effective_busses(s); ++i) {

            if (!i || s->snoop_state == SNOOP_STRIPING) {

                if (fifo8_is_empty(&s->tx_fifo)) {

                    s->regs[R_INTR_STATUS] |= IXR_TX_FIFO_UNDERFLOW;

                    xilinx_spips_update_ixr(s);

                    return;

                } else {

                    tx = fifo8_pop(&s->tx_fifo);

                }

            }

            rx = ssi_transfer(s->spi[i], (uint32_t)tx);

            DB_PRINT("tx = %02x rx = %02x\n", tx, rx);

            if (!i || s->snoop_state == SNOOP_STRIPING) {

                if (fifo8_is_full(&s->rx_fifo)) {

                    s->regs[R_INTR_STATUS] |= IXR_RX_FIFO_OVERFLOW;

                    DB_PRINT("rx FIFO overflow");

                } else {

                    fifo8_push(&s->rx_fifo, (uint8_t)rx);

                }

            }

        }

        switch (s->snoop_state) {

        case (SNOOP_CHECKING):

            switch (tx) { /* new instruction code */

            case 0x0b: /* dual/quad output read DOR/QOR */

            case 0x6b:

                s->snoop_state = 4;

                break;

            /* FIXME: these vary between vendor - set to spansion */

            case 0xbb: /* high performance dual read DIOR */

                s->snoop_state = 4;

                break;

            case 0xeb: /* high performance quad read QIOR */

                s->snoop_state = 6;

                break;

            default:

                s->snoop_state = SNOOP_NONE;

            }

            break;

        case (SNOOP_STRIPING):

        case (SNOOP_NONE):

            break;

        default:

            s->snoop_state--;

        }

    }

}


void memory_region_set_skip_dump(MemoryRegion *mr)

{

    mr->skip_dump = true;

}


static int no_init_out (HWVoiceOut *hw, audsettings_t *as)

{

    audio_pcm_init_info (&hw->info, as);

    hw->samples = 1024;

    return 0;

}


static void __attribute__((constructor)) init_cpuid_cache(void)

{

    int max = __get_cpuid_max(0, NULL);

    int a, b, c, d;

    unsigned cache = 0;

    if (max >= 1) {

        __cpuid(1, a, b, c, d);

        if (d & bit_SSE2) {

            cache |= CACHE_SSE2;

        }

#ifdef CONFIG_AVX2_OPT

        if (c & bit_SSE4_1) {

            cache |= CACHE_SSE4;

        }

        /* We must check that AVX is not just available, but usable.  */

        if ((c & bit_OSXSAVE) && (c & bit_AVX)) {

            __asm("xgetbv" : "=a"(a), "=d"(d) : "c"(0));

            if ((a & 6) == 6) {

                cache |= CACHE_AVX1;

                if (max >= 7) {

                    __cpuid_count(7, 0, a, b, c, d);

                    if (b & bit_AVX2) {

                        cache |= CACHE_AVX2;

                    }

                }

            }

        }

#endif

    }

    cpuid_cache = cache;

}


static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,

                            int parse_extradata)

{

    MpegEncContext *const s     = &h->s;

    AVCodecContext *const avctx = s->avctx;

    H264Context *hx; ///< thread context

    int buf_index;

    int context_count;

    int next_avc;

    int pass = !(avctx->active_thread_type & FF_THREAD_FRAME);

    int nals_needed = 0; ///< number of NALs that need decoding before the next frame thread starts

    int nal_index;

    int idr_cleared=0;

    int first_slice = 0;

    h->nal_unit_type= 0;

    if(!s->slice_context_count)

         s->slice_context_count= 1;

    h->max_contexts = s->slice_context_count;

    if (!(s->flags2 & CODEC_FLAG2_CHUNKS)) {

        h->current_slice = 0;

        if (!s->first_field)

            s->current_picture_ptr = NULL;

        ff_h264_reset_sei(h);

    }

    if (h->nal_length_size == 4) {

        if (buf_size > 8 && AV_RB32(buf) == 1 && AV_RB32(buf+5) > (unsigned)buf_size) {

            h->is_avc = 0;

        }else if(buf_size > 3 && AV_RB32(buf) > 1 && AV_RB32(buf) <= (unsigned)buf_size)

            h->is_avc = 1;

    }

    for (; pass <= 1; pass++) {

        buf_index     = 0;

        context_count = 0;

        next_avc      = h->is_avc ? 0 : buf_size;

        nal_index     = 0;

        for (;;) {

            int consumed;

            int dst_length;

            int bit_length;

            const uint8_t *ptr;

            int i, nalsize = 0;

            int err;

            if (buf_index >= next_avc) {

                if (buf_index >= buf_size - h->nal_length_size)

                    break;

                nalsize = 0;

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

                    nalsize = (nalsize << 8) | buf[buf_index++];

                if (nalsize <= 0 || nalsize > buf_size - buf_index) {

                    av_log(h->s.avctx, AV_LOG_ERROR,

                           "AVC: nal size %d\n", nalsize);

                    break;

                }

                next_avc = buf_index + nalsize;

            } else {

                // start code prefix search

                for (; buf_index + 3 < next_avc; buf_index++)

                    // This should always succeed in the first iteration.

                    if (buf[buf_index]     == 0 &&

                        buf[buf_index + 1] == 0 &&

                        buf[buf_index + 2] == 1)

                        break;

                if (buf_index + 3 >= buf_size) {

                    buf_index = buf_size;

                    break;

                }

                buf_index += 3;

                if (buf_index >= next_avc)

                    continue;

            }

            hx = h->thread_context[context_count];

            ptr = ff_h264_decode_nal(hx, buf + buf_index, &dst_length,

                                     &consumed, next_avc - buf_index);

            if (ptr == NULL || dst_length < 0) {

                buf_index = -1;

                goto end;

            }

            i = buf_index + consumed;

            if ((s->workaround_bugs & FF_BUG_AUTODETECT) && i + 3 < next_avc &&

                buf[i]     == 0x00 && buf[i + 1] == 0x00 &&

                buf[i + 2] == 0x01 && buf[i + 3] == 0xE0)

                s->workaround_bugs |= FF_BUG_TRUNCATED;

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

                while(dst_length > 0 && ptr[dst_length - 1] == 0)

                    dst_length--;

            bit_length = !dst_length ? 0

                                     : (8 * dst_length -

                                        decode_rbsp_trailing(h, ptr + dst_length - 1));

            if (s->avctx->debug & FF_DEBUG_STARTCODE)

                av_log(h->s.avctx, AV_LOG_DEBUG, "NAL %d/%d at %d/%d length %d pass %d\n", hx->nal_unit_type, hx->nal_ref_idc, buf_index, buf_size, dst_length, pass);

            if (h->is_avc && (nalsize != consumed) && nalsize)

                av_log(h->s.avctx, AV_LOG_DEBUG,

                       "AVC: Consumed only %d bytes instead of %d\n",

                       consumed, nalsize);

            buf_index += consumed;

            nal_index++;

            if (pass == 0) {

                /* packets can sometimes contain multiple PPS/SPS,

                 * e.g. two PAFF field pictures in one packet, or a demuxer

                 * which splits NALs strangely if so, when frame threading we

                 * can't start the next thread until we've read all of them */

                switch (hx->nal_unit_type) {

                case NAL_SPS:

                case NAL_PPS:

                    nals_needed = nal_index;

                    break;

                case NAL_DPA:

                case NAL_IDR_SLICE:

                case NAL_SLICE:

                    init_get_bits(&hx->s.gb, ptr, bit_length);

                    if (!get_ue_golomb(&hx->s.gb) || !first_slice)

                        nals_needed = nal_index;

                    if (!first_slice)

                        first_slice = hx->nal_unit_type;

                }

                continue;

            }

            if (!first_slice)

                switch (hx->nal_unit_type) {

                case NAL_DPA:

                case NAL_IDR_SLICE:

                case NAL_SLICE:

                    first_slice = hx->nal_unit_type;

                }

            // FIXME do not discard SEI id

            if (avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0)

                continue;

again:

            /* Ignore every NAL unit type except PPS and SPS during extradata

             * parsing. Decoding slices is not possible in codec init

             * with frame-mt */

            if (parse_extradata && HAVE_THREADS &&

                (s->avctx->active_thread_type & FF_THREAD_FRAME) &&

                (hx->nal_unit_type != NAL_PPS &&

                 hx->nal_unit_type != NAL_SPS)) {

                av_log(avctx, AV_LOG_INFO, "Ignoring NAL unit %d during "

                       "extradata parsing\n", hx->nal_unit_type);

                hx->nal_unit_type = NAL_FF_IGNORE;

            }

            err = 0;

            if (h->decoding_extradata) {

                switch (hx->nal_unit_type) {

                case NAL_IDR_SLICE:

                case NAL_SLICE:

                case NAL_DPA:

                case NAL_DPB:

                case NAL_DPC:

                case NAL_AUXILIARY_SLICE:

                    av_log(h->s.avctx, AV_LOG_WARNING, "Ignoring NAL %d in global header\n", hx->nal_unit_type);

                    hx->nal_unit_type = NAL_FILLER_DATA;

                }

            }

            switch (hx->nal_unit_type) {

            case NAL_IDR_SLICE:

                if (first_slice != NAL_IDR_SLICE) {

                    av_log(h->s.avctx, AV_LOG_ERROR,

                           "Invalid mix of idr and non-idr slices\n");

                    buf_index = -1;

                    goto end;

                }

                if(!idr_cleared)

                    idr(h); // FIXME ensure we don't lose some frames if there is reordering

                idr_cleared = 1;

            case NAL_SLICE:

                init_get_bits(&hx->s.gb, ptr, bit_length);

                hx->intra_gb_ptr        =

                    hx->inter_gb_ptr    = &hx->s.gb;

                hx->s.data_partitioning = 0;

                if ((err = decode_slice_header(hx, h)))

                    break;

                if (h->sei_recovery_frame_cnt >= 0 && (h->frame_num != h->sei_recovery_frame_cnt || hx->slice_type_nos != AV_PICTURE_TYPE_I))

                    h->valid_recovery_point = 1;

                if (   h->sei_recovery_frame_cnt >= 0

                    && (   h->recovery_frame<0

                        || ((h->recovery_frame - h->frame_num) & ((1 << h->sps.log2_max_frame_num)-1)) > h->sei_recovery_frame_cnt)) {

                    h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) %

                                        (1 << h->sps.log2_max_frame_num);

                    if (!h->valid_recovery_point)

                        h->recovery_frame = h->frame_num;

                }

                s->current_picture_ptr->f.key_frame |=

                        (hx->nal_unit_type == NAL_IDR_SLICE);

                if (h->recovery_frame == h->frame_num) {

                    s->current_picture_ptr->sync |= 1;

                    h->recovery_frame = -1;

                }

                h->sync |= !!s->current_picture_ptr->f.key_frame;

                h->sync |= 3*!!(s->flags2 & CODEC_FLAG2_SHOW_ALL);

                s->current_picture_ptr->sync |= h->sync;

                if (h->current_slice == 1) {

                    if (!(s->flags2 & CODEC_FLAG2_CHUNKS))

                        decode_postinit(h, nal_index >= nals_needed);

                    if (s->avctx->hwaccel &&

                        s->avctx->hwaccel->start_frame(s->avctx, NULL, 0) < 0)

                        return -1;

                    if (CONFIG_H264_VDPAU_DECODER &&

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

                        ff_vdpau_h264_picture_start(s);

                }

                if (hx->redundant_pic_count == 0 &&

                    (avctx->skip_frame < AVDISCARD_NONREF ||

                     hx->nal_ref_idc) &&

                    (avctx->skip_frame < AVDISCARD_BIDIR  ||

                     hx->slice_type_nos != AV_PICTURE_TYPE_B) &&

                    (avctx->skip_frame < AVDISCARD_NONKEY ||

                     hx->slice_type_nos == AV_PICTURE_TYPE_I) &&

                    avctx->skip_frame < AVDISCARD_ALL) {

                    if (avctx->hwaccel) {

                        if (avctx->hwaccel->decode_slice(avctx,

                                                         &buf[buf_index - consumed],

                                                         consumed) < 0)

                            return -1;

                    } else if (CONFIG_H264_VDPAU_DECODER &&

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

                        static const uint8_t start_code[] = {

                            0x00, 0x00, 0x01 };

                        ff_vdpau_add_data_chunk(s, start_code,

                                                sizeof(start_code));

                        ff_vdpau_add_data_chunk(s, &buf[buf_index - consumed],

                                                consumed);

                    } else

                        context_count++;

                }

                break;

            case NAL_DPA:

                init_get_bits(&hx->s.gb, ptr, bit_length);

                hx->intra_gb_ptr =

                hx->inter_gb_ptr = NULL;

                if ((err = decode_slice_header(hx, h)) < 0)

                    break;

                hx->s.data_partitioning = 1;

                break;

            case NAL_DPB:

                init_get_bits(&hx->intra_gb, ptr, bit_length);

                hx->intra_gb_ptr = &hx->intra_gb;

                break;

            case NAL_DPC:

                init_get_bits(&hx->inter_gb, ptr, bit_length);

                hx->inter_gb_ptr = &hx->inter_gb;

                av_log(h->s.avctx, AV_LOG_ERROR, "Partitioned H.264 support is incomplete\n");

                break;

                if (hx->redundant_pic_count == 0 &&

                    hx->intra_gb_ptr &&

                    hx->s.data_partitioning &&

                    s->current_picture_ptr &&

                    s->context_initialized &&

                    (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) &&

                    (avctx->skip_frame < AVDISCARD_BIDIR  ||

                     hx->slice_type_nos != AV_PICTURE_TYPE_B) &&

                    (avctx->skip_frame < AVDISCARD_NONKEY ||

                     hx->slice_type_nos == AV_PICTURE_TYPE_I) &&

                    avctx->skip_frame < AVDISCARD_ALL)

                    context_count++;

                break;

            case NAL_SEI:

                init_get_bits(&s->gb, ptr, bit_length);

                ff_h264_decode_sei(h);

                break;

            case NAL_SPS:

                init_get_bits(&s->gb, ptr, bit_length);

                if (ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? (nalsize != consumed) && nalsize : 1)) {

                    av_log(h->s.avctx, AV_LOG_DEBUG,

                           "SPS decoding failure, trying again with the complete NAL\n");

                    if (h->is_avc)

                        av_assert0(next_avc - buf_index + consumed == nalsize);

                    if ((next_avc - buf_index + consumed - 1) >= INT_MAX/8)

                        break;

                    init_get_bits(&s->gb, &buf[buf_index + 1 - consumed],

                                  8*(next_avc - buf_index + consumed - 1));

                    ff_h264_decode_seq_parameter_set(h);

                }

                break;

            case NAL_PPS:

                init_get_bits(&s->gb, ptr, bit_length);

                ff_h264_decode_picture_parameter_set(h, bit_length);

                break;

            case NAL_AUD:

            case NAL_END_SEQUENCE:

            case NAL_END_STREAM:

            case NAL_FILLER_DATA:

            case NAL_SPS_EXT:

            case NAL_AUXILIARY_SLICE:

                break;

            case NAL_FF_IGNORE:

                break;

            default:

                av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n",

                       hx->nal_unit_type, bit_length);

            }

            if (context_count == h->max_contexts) {

                execute_decode_slices(h, context_count);

                context_count = 0;

            }

            if (err < 0)

                av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header error\n");

            else if (err == 1) {

                /* Slice could not be decoded in parallel mode, copy down

                 * NAL unit stuff to context 0 and restart. Note that

                 * rbsp_buffer is not transferred, but since we no longer

                 * run in parallel mode this should not be an issue. */

                h->nal_unit_type = hx->nal_unit_type;

                h->nal_ref_idc   = hx->nal_ref_idc;

                hx               = h;

                goto again;

            }

        }

    }

    if (context_count)

        execute_decode_slices(h, context_count);

end:

    /* clean up */

    if (s->current_picture_ptr && s->current_picture_ptr->owner2 == s &&

        !s->droppable) {

        ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX,

                                  s->picture_structure == PICT_BOTTOM_FIELD);

    }

    return buf_index;

}


static void gen_exception_return(DisasContext *s, TCGv_i32 pc)

{

    TCGv_i32 tmp;

    store_reg(s, 15, pc);

    tmp = load_cpu_field(spsr);

    gen_set_cpsr(tmp, CPSR_ERET_MASK);

    tcg_temp_free_i32(tmp);

    s->is_jmp = DISAS_JUMP;

}


void object_property_add_link(Object *obj, const char *name,

                              const char *type, Object **child,

                              void (*check)(Object *, const char *,

                                            Object *, Error **),

                              ObjectPropertyLinkFlags flags,

                              Error **errp)

{

    Error *local_err = NULL;

    LinkProperty *prop = g_malloc(sizeof(*prop));

    gchar *full_type;

    prop->child = child;

    prop->check = check;

    prop->flags = flags;

    full_type = g_strdup_printf("link<%s>", type);

    object_property_add(obj, name, full_type,

                        object_get_link_property,

                        check ? object_set_link_property : NULL,

                        object_release_link_property,

                        prop,

                        &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        g_free(prop);

    }

    g_free(full_type);

}


void ioinst_handle_csch(S390CPU *cpu, uint64_t reg1)

{

    int cssid, ssid, schid, m;

    SubchDev *sch;

    int ret = -ENODEV;

    int cc;

    if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {

        program_interrupt(&cpu->env, PGM_OPERAND, 2);

        return;

    }

    trace_ioinst_sch_id("csch", cssid, ssid, schid);

    sch = css_find_subch(m, cssid, ssid, schid);

    if (sch && css_subch_visible(sch)) {

        ret = css_do_csch(sch);

    }

    if (ret == -ENODEV) {

        cc = 3;

    } else {

        cc = 0;

    }

    setcc(cpu, cc);

}


static void curl_multi_read(BDRVCURLState *s)

{

    int msgs_in_queue;

    /* Try to find done transfers, so we can free the easy

     * handle again. */

    do {

        CURLMsg *msg;

        msg = curl_multi_info_read(s->multi, &msgs_in_queue);

        if (!msg)

            break;

        if (msg->msg == CURLMSG_NONE)

            break;

        switch (msg->msg) {

            case CURLMSG_DONE:

            {

                CURLState *state = NULL;

                curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE,

                                  (char **)&state);

                /* ACBs for successful messages get completed in curl_read_cb */

                if (msg->data.result != CURLE_OK) {

                    int i;

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

                        CURLAIOCB *acb = state->acb[i];

                        if (acb == NULL) {

                            continue;

                        }

                        acb->common.cb(acb->common.opaque, -EIO);

                        qemu_aio_release(acb);

                        state->acb[i] = NULL;

                    }

                }

                curl_clean_state(state);

                break;

            }

            default:

                msgs_in_queue = 0;

                break;

        }

    } while(msgs_in_queue);

}


static void init_blk_migration(Monitor *mon, QEMUFile *f)

{

    BlkMigDevState *bmds;

    BlockDriverState *bs;

    int64_t sectors;

    block_mig_state.submitted = 0;

    block_mig_state.read_done = 0;

    block_mig_state.transferred = 0;

    block_mig_state.total_sector_sum = 0;

    block_mig_state.prev_progress = -1;

    block_mig_state.bulk_completed = 0;

    block_mig_state.total_time = 0;

    block_mig_state.reads = 0;

    for (bs = bdrv_first; bs != NULL; bs = bs->next) {

        if (bs->type == BDRV_TYPE_HD) {

            sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;

            if (sectors == 0) {

                continue;

            }

            bmds = qemu_mallocz(sizeof(BlkMigDevState));

            bmds->bs = bs;

            bmds->bulk_completed = 0;

            bmds->total_sectors = sectors;

            bmds->completed_sectors = 0;

            bmds->shared_base = block_mig_state.shared_base;

            block_mig_state.total_sector_sum += sectors;

            if (bmds->shared_base) {

                monitor_printf(mon, "Start migration for %s with shared base "

                                    "image\n",

                               bs->device_name);

            } else {

                monitor_printf(mon, "Start full migration for %s\n",

                               bs->device_name);

            }

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

        }

    }

}


static void init_proc_970MP (CPUPPCState *env)

{

    gen_spr_ne_601(env);

    gen_spr_7xx(env);

    /* Time base */

    gen_tbl(env);

    /* Hardware implementation registers */

    /* XXX : not implemented */

    spr_register(env, SPR_HID0, "HID0",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_clear,

                 0x60000000);

    /* XXX : not implemented */

    spr_register(env, SPR_HID1, "HID1",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    /* XXX : not implemented */

    spr_register(env, SPR_970_HID5, "HID5",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 POWERPC970_HID5_INIT);

    /* XXX : not implemented */

    /* Memory management */

    /* XXX: not correct */

    gen_low_BATs(env);

    spr_register(env, SPR_HIOR, "SPR_HIOR",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_hior, &spr_write_hior,

                 0x00000000);

    /* Logical partitionning */

    spr_register_kvm(env, SPR_LPCR, "LPCR",

                     SPR_NOACCESS, SPR_NOACCESS,

                     &spr_read_generic, &spr_write_generic,

                     KVM_REG_PPC_LPCR, 0x00000000);

#if !defined(CONFIG_USER_ONLY)

    env->slb_nr = 32;

#endif

    init_excp_970(env);

    env->dcache_line_size = 128;

    env->icache_line_size = 128;

    /* Allocate hardware IRQ controller */

    ppc970_irq_init(env);

    /* Can't find information on what this should be on reset.  This

     * value is the one used by 74xx processors. */

    vscr_init(env, 0x00010000);

}


static void platform_mmio_write(ReadWriteHandler *handler, pcibus_t addr,

                                uint32_t val, int len)

{

    DPRINTF("Warning: attempted write of 0x%x to physical "

            "address 0x" TARGET_FMT_plx " in xen platform mmio space\n",

            val, addr);

}


int pci_piix3_xen_ide_unplug(DeviceState *dev)

{

    PCIIDEState *pci_ide;

    DriveInfo *di;

    int i;

    IDEDevice *idedev;

    pci_ide = PCI_IDE(dev);

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

        di = drive_get_by_index(IF_IDE, i);

        if (di != NULL && !di->media_cd) {

            BlockBackend *blk = blk_by_legacy_dinfo(di);

            DeviceState *ds = blk_get_attached_dev(blk);

            blk_drain(blk);

            blk_flush(blk);

            if (ds) {

                blk_detach_dev(blk, ds);

            }

            pci_ide->bus[di->bus].ifs[di->unit].blk = NULL;

            if (!(i % 2)) {

                idedev = pci_ide->bus[di->bus].master;

            } else {

                idedev = pci_ide->bus[di->bus].slave;

            }

            idedev->conf.blk = NULL;

            monitor_remove_blk(blk);

            blk_unref(blk);

        }

    }

    qdev_reset_all(DEVICE(dev));

    return 0;

}


static void shift_history(DCAEncContext *c, const int32_t *input)

{

    int k, ch;

    for (k = 0; k < 512; k++)

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

            const int chi = c->channel_order_tab[ch];

            c->history[k][ch] = input[k * c->channels + chi];

        }

}


static void init_vlcs()

{

    static int done = 0;

    if (!done) {

        done = 1;

        init_vlc(&dc_lum_vlc, DC_VLC_BITS, 12,

                 vlc_dc_lum_bits, 1, 1,

                 vlc_dc_lum_code, 2, 2);

        init_vlc(&dc_chroma_vlc,  DC_VLC_BITS, 12,

                 vlc_dc_chroma_bits, 1, 1,

                 vlc_dc_chroma_code, 2, 2);

        init_vlc(&mv_vlc, MV_VLC_BITS, 17,

                 &mbMotionVectorTable[0][1], 2, 1,

                 &mbMotionVectorTable[0][0], 2, 1);

        init_vlc(&mbincr_vlc, MBINCR_VLC_BITS, 36,

                 &mbAddrIncrTable[0][1], 2, 1,

                 &mbAddrIncrTable[0][0], 2, 1);

        init_vlc(&mb_pat_vlc, MB_PAT_VLC_BITS, 63,

                 &mbPatTable[0][1], 2, 1,

                 &mbPatTable[0][0], 2, 1);

        init_vlc(&mb_ptype_vlc, MB_PTYPE_VLC_BITS, 7,

                 &table_mb_ptype[0][1], 2, 1,

                 &table_mb_ptype[0][0], 2, 1);

        init_vlc(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11,

                 &table_mb_btype[0][1], 2, 1,

                 &table_mb_btype[0][0], 2, 1);

        init_rl(&rl_mpeg1);

        init_rl(&rl_mpeg2);

        init_2d_vlc_rl(&rl_mpeg1);

        init_2d_vlc_rl(&rl_mpeg2);

    }

}


static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type,

                           uint8_t *src, uint8_t *last, int size, int bpp)

{

    int i, p, r, g, b, a;

    switch (filter_type) {

    case PNG_FILTER_VALUE_NONE:

        memcpy(dst, src, size);

        break;

    case PNG_FILTER_VALUE_SUB:

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

            dst[i] = src[i];

        if (bpp == 4) {

            p = *(int *)dst;

            for (; i < size; i += bpp) {

                unsigned s = *(int *)(src + i);

                p = ((s & 0x7f7f7f7f) + (p & 0x7f7f7f7f)) ^ ((s ^ p) & 0x80808080);

                *(int *)(dst + i) = p;

            }

        } else {

#define OP_SUB(x, s, l) ((x) + (s))

            UNROLL_FILTER(OP_SUB);

        }

        break;

    case PNG_FILTER_VALUE_UP:

        dsp->add_bytes_l2(dst, src, last, size);

        break;

    case PNG_FILTER_VALUE_AVG:

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

            p      = (last[i] >> 1);

            dst[i] = p + src[i];

        }

#define OP_AVG(x, s, l) (((((x) + (l)) >> 1) + (s)) & 0xff)

        UNROLL_FILTER(OP_AVG);

        break;

    case PNG_FILTER_VALUE_PAETH:

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

            p      = last[i];

            dst[i] = p + src[i];

        }

        if (bpp > 2 && size > 4) {

            /* would write off the end of the array if we let it process

             * the last pixel with bpp=3 */

            int w = bpp == 4 ? size : size - 3;

            dsp->add_paeth_prediction(dst + i, src + i, last + i, w - i, bpp);

            i = w;

        }

        ff_add_png_paeth_prediction(dst + i, src + i, last + i, size - i, bpp);

        break;

    }

}


av_cold int ff_mpv_common_init(MpegEncContext *s)

{

    int i;

    int nb_slices = (HAVE_THREADS &&

                     s->avctx->active_thread_type & FF_THREAD_SLICE) ?

                    s->avctx->thread_count : 1;

    if (s->encoding && s->avctx->slices)

        nb_slices = s->avctx->slices;

    if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence)

        s->mb_height = (s->height + 31) / 32 * 2;

    else

        s->mb_height = (s->height + 15) / 16;

    if (s->avctx->pix_fmt == AV_PIX_FMT_NONE) {

        av_log(s->avctx, AV_LOG_ERROR,

               "decoding to AV_PIX_FMT_NONE is not supported.\n");

        return -1;

    }

    if (nb_slices > MAX_THREADS || (nb_slices > s->mb_height && s->mb_height)) {

        int max_slices;

        if (s->mb_height)

            max_slices = FFMIN(MAX_THREADS, s->mb_height);

        else

            max_slices = MAX_THREADS;

        av_log(s->avctx, AV_LOG_WARNING, "too many threads/slices (%d),"

               " reducing to %d\n", nb_slices, max_slices);

        nb_slices = max_slices;

    }

    if ((s->width || s->height) &&

        av_image_check_size(s->width, s->height, 0, s->avctx))

        return -1;

    dct_init(s);

    /* set chroma shifts */

    avcodec_get_chroma_sub_sample(s->avctx->pix_fmt,

                                  &s->chroma_x_shift,

                                  &s->chroma_y_shift);

    FF_ALLOCZ_OR_GOTO(s->avctx, s->picture,

                      MAX_PICTURE_COUNT * sizeof(Picture), fail);

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

        s->picture[i].f = av_frame_alloc();

        if (!s->picture[i].f)

            goto fail;

    }

    memset(&s->next_picture, 0, sizeof(s->next_picture));

    memset(&s->last_picture, 0, sizeof(s->last_picture));

    memset(&s->current_picture, 0, sizeof(s->current_picture));

    memset(&s->new_picture, 0, sizeof(s->new_picture));

    s->next_picture.f = av_frame_alloc();

    if (!s->next_picture.f)

        goto fail;

    s->last_picture.f = av_frame_alloc();

    if (!s->last_picture.f)

        goto fail;

    s->current_picture.f = av_frame_alloc();

    if (!s->current_picture.f)

        goto fail;

    s->new_picture.f = av_frame_alloc();

    if (!s->new_picture.f)

        goto fail;

        if (init_context_frame(s))

            goto fail;

        s->parse_context.state = -1;

        s->context_initialized = 1;

        memset(s->thread_context, 0, sizeof(s->thread_context));

        s->thread_context[0]   = s;

//     if (s->width && s->height) {

        if (nb_slices > 1) {

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

                if (i) {

                    s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext));

                    if (!s->thread_context[i])

                        goto fail;

                }

                if (init_duplicate_context(s->thread_context[i]) < 0)

                    goto fail;

                    s->thread_context[i]->start_mb_y =

                        (s->mb_height * (i) + nb_slices / 2) / nb_slices;

                    s->thread_context[i]->end_mb_y   =

                        (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;

            }

        } else {

            if (init_duplicate_context(s) < 0)

                goto fail;

            s->start_mb_y = 0;

            s->end_mb_y   = s->mb_height;

        }

        s->slice_context_count = nb_slices;

//     }

    return 0;

 fail:

    ff_mpv_common_end(s);

    return -1;

}


int ff_socket(int af, int type, int proto)

{

    int fd;

#ifdef SOCK_CLOEXEC

    fd = socket(af, type | SOCK_CLOEXEC, proto);

    if (fd == -1 && errno == EINVAL)

#endif

    {

        fd = socket(af, type, proto);

#if HAVE_FCNTL

        if (fd != -1)

            fcntl(fd, F_SETFD, FD_CLOEXEC);

#endif

    }

    return fd;

}


static int nuv_header(AVFormatContext *s)

{

    NUVContext *ctx = s->priv_data;

    AVIOContext *pb = s->pb;

    char id_string[12];

    double aspect, fps;

    int is_mythtv, width, height, v_packs, a_packs;

    AVStream *vst = NULL, *ast = NULL;

    avio_read(pb, id_string, 12);

    is_mythtv = !memcmp(id_string, "MythTVVideo", 12);

    avio_skip(pb, 5);       // version string

    avio_skip(pb, 3);       // padding

    width  = avio_rl32(pb);

    height = avio_rl32(pb);

    avio_rl32(pb);          // unused, "desiredwidth"

    avio_rl32(pb);          // unused, "desiredheight"

    avio_r8(pb);            // 'P' == progressive, 'I' == interlaced

    avio_skip(pb, 3);       // padding

    aspect = av_int2double(avio_rl64(pb));

    if (aspect > 0.9999 && aspect < 1.0001)

        aspect = 4.0 / 3.0;

    fps = av_int2double(avio_rl64(pb));

    // number of packets per stream type, -1 means unknown, e.g. streaming

    v_packs = avio_rl32(pb);

    a_packs = avio_rl32(pb);

    avio_rl32(pb); // text

    avio_rl32(pb); // keyframe distance (?)

    if (v_packs) {

        vst = avformat_new_stream(s, NULL);

        if (!vst)

            return AVERROR(ENOMEM);

        ctx->v_id = vst->index;

        vst->codec->codec_type            = AVMEDIA_TYPE_VIDEO;

        vst->codec->codec_id              = AV_CODEC_ID_NUV;

        vst->codec->width                 = width;

        vst->codec->height                = height;

        vst->codec->bits_per_coded_sample = 10;

        vst->sample_aspect_ratio          = av_d2q(aspect * height / width,

                                                   10000);

#if FF_API_R_FRAME_RATE

        vst->r_frame_rate =

#endif

        vst->avg_frame_rate = av_d2q(fps, 60000);

        avpriv_set_pts_info(vst, 32, 1, 1000);

    } else

        ctx->v_id = -1;

    if (a_packs) {

        ast = avformat_new_stream(s, NULL);

        if (!ast)

            return AVERROR(ENOMEM);

        ctx->a_id = ast->index;

        ast->codec->codec_type            = AVMEDIA_TYPE_AUDIO;

        ast->codec->codec_id              = AV_CODEC_ID_PCM_S16LE;

        ast->codec->channels              = 2;

        ast->codec->channel_layout        = AV_CH_LAYOUT_STEREO;

        ast->codec->sample_rate           = 44100;

        ast->codec->bit_rate              = 2 * 2 * 44100 * 8;

        ast->codec->block_align           = 2 * 2;

        ast->codec->bits_per_coded_sample = 16;

        avpriv_set_pts_info(ast, 32, 1, 1000);

    } else

        ctx->a_id = -1;

    get_codec_data(pb, vst, ast, is_mythtv);

    ctx->rtjpg_video = vst && vst->codec->codec_id == AV_CODEC_ID_NUV;

    return 0;

}


static int qcow2_update_ext_header(BlockDriverState *bs,

    const char *backing_file, const char *backing_fmt)

{

    size_t backing_file_len = 0;

    size_t backing_fmt_len = 0;

    BDRVQcowState *s = bs->opaque;

    QCowExtension ext_backing_fmt = {0, 0};

    int ret;

    /* Backing file format doesn't make sense without a backing file */

    if (backing_fmt && !backing_file) {

        return -EINVAL;

    }

    /* Prepare the backing file format extension if needed */

    if (backing_fmt) {

        ext_backing_fmt.len = cpu_to_be32(strlen(backing_fmt));

        ext_backing_fmt.magic = cpu_to_be32(QCOW_EXT_MAGIC_BACKING_FORMAT);

        backing_fmt_len = ((sizeof(ext_backing_fmt)

            + strlen(backing_fmt) + 7) & ~7);

    }

    /* Check if we can fit the new header into the first cluster */

    if (backing_file) {

        backing_file_len = strlen(backing_file);

    }

    size_t header_size = sizeof(QCowHeader) + backing_file_len

        + backing_fmt_len;

    if (header_size > s->cluster_size) {

        return -ENOSPC;

    }

    /* Rewrite backing file name and qcow2 extensions */

    size_t ext_size = header_size - sizeof(QCowHeader);

    uint8_t buf[ext_size];

    size_t offset = 0;

    size_t backing_file_offset = 0;

    if (backing_file) {

        if (backing_fmt) {

            int padding = backing_fmt_len -

                (sizeof(ext_backing_fmt) + strlen(backing_fmt));

            memcpy(buf + offset, &ext_backing_fmt, sizeof(ext_backing_fmt));

            offset += sizeof(ext_backing_fmt);

            memcpy(buf + offset, backing_fmt, strlen(backing_fmt));

            offset += strlen(backing_fmt);

            memset(buf + offset, 0, padding);

            offset += padding;

        }

        memcpy(buf + offset, backing_file, backing_file_len);

        backing_file_offset = sizeof(QCowHeader) + offset;

    }

    ret = bdrv_pwrite(bs->file, sizeof(QCowHeader), buf, ext_size);

    if (ret < 0) {

        goto fail;

    }

    /* Update header fields */

    uint64_t be_backing_file_offset = cpu_to_be64(backing_file_offset);

    uint32_t be_backing_file_size = cpu_to_be32(backing_file_len);

    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, backing_file_offset),

        &be_backing_file_offset, sizeof(uint64_t));

    if (ret < 0) {

        goto fail;

    }

    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, backing_file_size),

        &be_backing_file_size, sizeof(uint32_t));

    if (ret < 0) {

        goto fail;

    }

    ret = 0;

fail:

    return ret;

}


static int img_dd(int argc, char **argv)

{

    int ret = 0;

    char *arg = NULL;

    char *tmp;

    BlockDriver *drv = NULL, *proto_drv = NULL;

    BlockBackend *blk1 = NULL, *blk2 = NULL;

    QemuOpts *opts = NULL;

    QemuOptsList *create_opts = NULL;

    Error *local_err = NULL;

    bool image_opts = false;

    int c, i;

    const char *out_fmt = "raw";

    const char *fmt = NULL;

    int64_t size = 0;

    int64_t block_count = 0, out_pos, in_pos;

    struct DdInfo dd = {

        .flags = 0,

        .count = 0,

    };

    struct DdIo in = {

        .bsz = 512, /* Block size is by default 512 bytes */

        .filename = NULL,

        .buf = NULL,

        .offset = 0

    };

    struct DdIo out = {

        .bsz = 512,

        .filename = NULL,

        .buf = NULL,

        .offset = 0

    };

    const struct DdOpts options[] = {

        { "bs", img_dd_bs, C_BS },

        { "count", img_dd_count, C_COUNT },

        { "if", img_dd_if, C_IF },

        { "of", img_dd_of, C_OF },

        { "skip", img_dd_skip, C_SKIP },

        { NULL, NULL, 0 }

    };

    const struct option long_options[] = {

        { "help", no_argument, 0, 'h'},

        { "image-opts", no_argument, 0, OPTION_IMAGE_OPTS},

        { 0, 0, 0, 0 }

    };

    while ((c = getopt_long(argc, argv, "hf:O:", long_options, NULL))) {

        if (c == EOF) {

            break;

        }

        switch (c) {

        case 'O':

            out_fmt = optarg;

            break;

        case 'f':

            fmt = optarg;

            break;

        case '?':

            error_report("Try 'qemu-img --help' for more information.");

            ret = -1;

            goto out;

        case 'h':

            help();

            break;

        case OPTION_IMAGE_OPTS:

            image_opts = true;

            break;

        }

    }

    for (i = optind; i < argc; i++) {

        int j;

        arg = g_strdup(argv[i]);

        tmp = strchr(arg, '=');

        if (tmp == NULL) {

            error_report("unrecognized operand %s", arg);

            ret = -1;

            goto out;

        }

        *tmp++ = '\0';

        for (j = 0; options[j].name != NULL; j++) {

            if (!strcmp(arg, options[j].name)) {

                break;

            }

        }

        if (options[j].name == NULL) {

            error_report("unrecognized operand %s", arg);

            ret = -1;

            goto out;

        }

        if (options[j].f(tmp, &in, &out, &dd) != 0) {

            ret = -1;

            goto out;

        }

        dd.flags |= options[j].flag;

        g_free(arg);

        arg = NULL;

    }

    if (!(dd.flags & C_IF && dd.flags & C_OF)) {

        error_report("Must specify both input and output files");

        ret = -1;

        goto out;

    }

    blk1 = img_open(image_opts, in.filename, fmt, 0, false, false);

    if (!blk1) {

        ret = -1;

        goto out;

    }

    drv = bdrv_find_format(out_fmt);

    if (!drv) {

        error_report("Unknown file format");

        ret = -1;

        goto out;

    }

    proto_drv = bdrv_find_protocol(out.filename, true, &local_err);

    if (!proto_drv) {

        error_report_err(local_err);

        ret = -1;

        goto out;

    }

    if (!drv->create_opts) {

        error_report("Format driver '%s' does not support image creation",

                     drv->format_name);

        ret = -1;

        goto out;

    }

    if (!proto_drv->create_opts) {

        error_report("Protocol driver '%s' does not support image creation",

                     proto_drv->format_name);

        ret = -1;

        goto out;

    }

    create_opts = qemu_opts_append(create_opts, drv->create_opts);

    create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);

    opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);

    size = blk_getlength(blk1);

    if (size < 0) {

        error_report("Failed to get size for '%s'", in.filename);

        ret = -1;

        goto out;

    }

    if (dd.flags & C_COUNT && dd.count <= INT64_MAX / in.bsz &&

        dd.count * in.bsz < size) {

        size = dd.count * in.bsz;

    }

    /* Overflow means the specified offset is beyond input image's size */

    if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||

                              size < in.bsz * in.offset)) {

        qemu_opt_set_number(opts, BLOCK_OPT_SIZE, 0, &error_abort);

    } else {

        qemu_opt_set_number(opts, BLOCK_OPT_SIZE,

                            size - in.bsz * in.offset, &error_abort);

    }

    ret = bdrv_create(drv, out.filename, opts, &local_err);

    if (ret < 0) {

        error_reportf_err(local_err,

                          "%s: error while creating output image: ",

                          out.filename);

        ret = -1;

        goto out;

    }

    blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR,

                    false, false);

    if (!blk2) {

        ret = -1;

        goto out;

    }

    if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||

                              size < in.offset * in.bsz)) {

        /* We give a warning if the skip option is bigger than the input

         * size and create an empty output disk image (i.e. like dd(1)).

         */

        error_report("%s: cannot skip to specified offset", in.filename);

        in_pos = size;

    } else {

        in_pos = in.offset * in.bsz;

    }

    in.buf = g_new(uint8_t, in.bsz);

    for (out_pos = 0; in_pos < size; block_count++) {

        int in_ret, out_ret;

        if (in_pos + in.bsz > size) {

            in_ret = blk_pread(blk1, in_pos, in.buf, size - in_pos);

        } else {

            in_ret = blk_pread(blk1, in_pos, in.buf, in.bsz);

        }

        if (in_ret < 0) {

            error_report("error while reading from input image file: %s",

                         strerror(-in_ret));

            ret = -1;

            goto out;

        }

        in_pos += in_ret;

        out_ret = blk_pwrite(blk2, out_pos, in.buf, in_ret, 0);

        if (out_ret < 0) {

            error_report("error while writing to output image file: %s",

                         strerror(-out_ret));

            ret = -1;

            goto out;

        }

        out_pos += out_ret;

    }

out:

    g_free(arg);

    qemu_opts_del(opts);

    qemu_opts_free(create_opts);

    blk_unref(blk1);

    blk_unref(blk2);

    g_free(in.filename);

    g_free(out.filename);

    g_free(in.buf);

    g_free(out.buf);

    if (ret) {

        return 1;

    }

    return 0;

}


static int imx_eth_can_receive(NetClientState *nc)

{

    IMXFECState *s = IMX_FEC(qemu_get_nic_opaque(nc));

    FEC_PRINTF("\n");

    return s->regs[ENET_RDAR] ? 1 : 0;

}


static int dfa_probe(AVProbeData *p)
{
    if (p->buf_size < 4 || AV_RL32(p->buf) != MKTAG('D', 'F', 'I', 'A'))
        return 0;
    return AVPROBE_SCORE_MAX;
}


static void ohci_sof(OHCIState *ohci)

{

    ohci->sof_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);

    timer_mod(ohci->eof_timer, ohci->sof_time + usb_frame_time);

    ohci_set_interrupt(ohci, OHCI_INTR_SF);

}


static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,

                                   bool isread)

{

    /* Performance monitor registers user accessibility is controlled

     * by PMUSERENR.

     */

    if (arm_current_el(env) == 0 && !env->cp15.c9_pmuserenr) {

        return CP_ACCESS_TRAP;

    }

    return CP_ACCESS_OK;

}


static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,

                            target_ulong opcode, target_ulong *args)

{

    CPUPPCState *env = &cpu->env;

    target_ulong flags = args[0];

    target_ulong pte_index = args[1];

    target_ulong pteh = args[2];

    target_ulong ptel = args[3];

    unsigned apshift, spshift;

    target_ulong raddr;

    target_ulong index;

    uint64_t token;

    apshift = ppc_hash64_hpte_page_shift_noslb(cpu, pteh, ptel, &spshift);

    if (!apshift) {

        /* Bad page size encoding */

        return H_PARAMETER;

    }

    raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << apshift) - 1);

    if (is_ram_address(spapr, raddr)) {

        /* Regular RAM - should have WIMG=0010 */

        if ((ptel & HPTE64_R_WIMG) != HPTE64_R_M) {

            return H_PARAMETER;

        }

    } else {

        /* Looks like an IO address */

        /* FIXME: What WIMG combinations could be sensible for IO?

         * For now we allow WIMG=010x, but are there others? */

        /* FIXME: Should we check against registered IO addresses? */

        if ((ptel & (HPTE64_R_W | HPTE64_R_I | HPTE64_R_M)) != HPTE64_R_I) {

            return H_PARAMETER;

        }

    }

    pteh &= ~0x60ULL;

    if (!valid_pte_index(env, pte_index)) {

        return H_PARAMETER;

    }

    index = 0;

    if (likely((flags & H_EXACT) == 0)) {

        pte_index &= ~7ULL;

        token = ppc_hash64_start_access(cpu, pte_index);

        for (; index < 8; index++) {

            if (!(ppc_hash64_load_hpte0(cpu, token, index) & HPTE64_V_VALID)) {

                break;

            }

        }

        ppc_hash64_stop_access(token);

        if (index == 8) {

            return H_PTEG_FULL;

        }

    } else {

        token = ppc_hash64_start_access(cpu, pte_index);

        if (ppc_hash64_load_hpte0(cpu, token, 0) & HPTE64_V_VALID) {

            ppc_hash64_stop_access(token);

            return H_PTEG_FULL;

        }

        ppc_hash64_stop_access(token);

    }

    ppc_hash64_store_hpte(cpu, pte_index + index,

                          pteh | HPTE64_V_HPTE_DIRTY, ptel);

    args[0] = pte_index + index;

    return H_SUCCESS;

}


static void init_excp_602 (CPUPPCState *env)

{

#if !defined(CONFIG_USER_ONLY)

    env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;

    env->excp_vectors[POWERPC_EXCP_MCHECK]   = 0x00000200;

    env->excp_vectors[POWERPC_EXCP_DSI]      = 0x00000300;

    env->excp_vectors[POWERPC_EXCP_ISI]      = 0x00000400;

    env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;

    env->excp_vectors[POWERPC_EXCP_ALIGN]    = 0x00000600;

    env->excp_vectors[POWERPC_EXCP_PROGRAM]  = 0x00000700;

    env->excp_vectors[POWERPC_EXCP_FPU]      = 0x00000800;

    env->excp_vectors[POWERPC_EXCP_DECR]     = 0x00000900;

    env->excp_vectors[POWERPC_EXCP_SYSCALL]  = 0x00000C00;

    env->excp_vectors[POWERPC_EXCP_TRACE]    = 0x00000D00;

    env->excp_vectors[POWERPC_EXCP_FPA]      = 0x00000E00;

    env->excp_vectors[POWERPC_EXCP_IFTLB]    = 0x00001000;

    env->excp_vectors[POWERPC_EXCP_DLTLB]    = 0x00001100;

    env->excp_vectors[POWERPC_EXCP_DSTLB]    = 0x00001200;

    env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;

    env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;

    env->excp_vectors[POWERPC_EXCP_WDT]      = 0x00001500;

    env->excp_vectors[POWERPC_EXCP_EMUL]     = 0x00001600;

    env->excp_prefix = 0xFFF00000UL;

    /* Hardware reset vector */

    env->hreset_vector = 0xFFFFFFFCUL;

#endif

}


static void unplug_nic(PCIBus *b, PCIDevice *d)

{

    if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==

            PCI_CLASS_NETWORK_ETHERNET) {

        qdev_unplug(&(d->qdev), NULL);

    }

}


static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,

                                    int is_write, sigset_t *old_set,

                                    void *puc)

{

    TranslationBlock *tb;

    int ret;

    if (cpu_single_env) {

        env = cpu_single_env; /* XXX: find a correct solution for multithread */

    }

#if defined(DEBUG_SIGNAL)

    qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",

                pc, address, is_write, *(unsigned long *)old_set);

#endif

    /* XXX: locking issue */

    if (is_write && page_unprotect(h2g(address), pc, puc)) {

        return 1;

    }

    /* see if it is an MMU fault */

    ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX);

    if (ret < 0) {

        return 0; /* not an MMU fault */

    }

    if (ret == 0) {

        return 1; /* the MMU fault was handled without causing real CPU fault */

    }

    /* now we have a real cpu fault */

    tb = tb_find_pc(pc);

    if (tb) {

        /* the PC is inside the translated code. It means that we have

           a virtual CPU fault */

        cpu_restore_state(tb, env, pc);

    }

    /* we restore the process signal mask as the sigreturn should

       do it (XXX: use sigsetjmp) */

    sigprocmask(SIG_SETMASK, old_set, NULL);

    exception_action(env);

    /* never comes here */

    return 1;

}


static char *qemu_rbd_parse_clientname(const char *conf, char *clientname)

{

    const char *p = conf;

    while (*p) {

        int len;

        const char *end = strchr(p, ':');

        if (end) {

            len = end - p;

        } else {

            len = strlen(p);

        }

        if (strncmp(p, "id=", 3) == 0) {

            len -= 3;

            strncpy(clientname, p + 3, len);

            clientname[len] = '\0';

            return clientname;

        }

        if (end == NULL) {

            break;

        }

        p = end + 1;

    }

    return NULL;

}


int float64_le_quiet( float64 a, float64 b STATUS_PARAM )

{

    flag aSign, bSign;

    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )

         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )

       ) {

        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {

            float_raise( float_flag_invalid STATUS_VAR);

        }

        return 0;

    }

    aSign = extractFloat64Sign( a );

    bSign = extractFloat64Sign( b );

    if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );

    return ( a == b ) || ( aSign ^ ( a < b ) );

}


void ppc_hash64_unmap_hptes(PowerPCCPU *cpu, const ppc_hash_pte64_t *hptes,

                            hwaddr ptex, int n)

{

    if (cpu->env.external_htab == MMU_HASH64_KVM_MANAGED_HPT) {

        g_free((void *)hptes);

    } else if (!cpu->env.external_htab) {

        address_space_unmap(CPU(cpu)->as, (void *)hptes, n * HASH_PTE_SIZE_64,

                            false, n * HASH_PTE_SIZE_64);

    }

}


static void tcg_reg_sync(TCGContext *s, TCGReg reg, TCGRegSet allocated_regs)

{

    TCGTemp *ts = s->reg_to_temp[reg];

    assert(ts->val_type == TEMP_VAL_REG);

    if (!ts->mem_coherent && !ts->fixed_reg) {

        if (!ts->mem_allocated) {

            temp_allocate_frame(s, temp_idx(s, ts));

        } else if (ts->indirect_reg) {

            tcg_regset_set_reg(allocated_regs, ts->reg);

            temp_load(s, ts->mem_base,

                      tcg_target_available_regs[TCG_TYPE_PTR],

                      allocated_regs);

        }

        tcg_out_st(s, ts->type, reg, ts->mem_base->reg, ts->mem_offset);

    }

    ts->mem_coherent = 1;

}


static QOSState *pci_test_start(int socket)

{

    const char *cmd = "-netdev socket,fd=%d,id=hs0 -device "

                      "virtio-net-pci,netdev=hs0";

    return qtest_pc_boot(cmd, socket);

}