static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)

{

    ASFContext *asf   = s->priv_data;

    ASFStream *asf_st = 0;

    for (;;) {

        int ret;

        if (url_feof(pb))

            return AVERROR_EOF;

        if (asf->packet_size_left < FRAME_HEADER_SIZE) {

            int ret = asf->packet_size_left + asf->packet_padsize;

            assert(ret >= 0);

            /* fail safe */

            avio_skip(pb, ret);

            asf->packet_pos = avio_tell(pb);

            if (asf->data_object_size != (uint64_t)-1 &&

                (asf->packet_pos - asf->data_object_offset >= asf->data_object_size))

                return AVERROR_EOF;  /* Do not exceed the size of the data object */

            return 1;

        }

        if (asf->packet_time_start == 0) {

            if (asf_read_frame_header(s, pb) < 0) {

                asf->packet_time_start = asf->packet_segments = 0;

                continue;

            }

            if (asf->stream_index < 0 ||

                s->streams[asf->stream_index]->discard >= AVDISCARD_ALL ||

                (!asf->packet_key_frame &&

                 (s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY || asf->streams[s->streams[asf->stream_index]->id].skip_to_key))) {

                asf->packet_time_start = 0;

                /* unhandled packet (should not happen) */

                avio_skip(pb, asf->packet_frag_size);

                asf->packet_size_left -= asf->packet_frag_size;

                if (asf->stream_index < 0)

                    av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n",

                           asf->packet_frag_size);

                continue;

            }

            asf->asf_st = &asf->streams[s->streams[asf->stream_index]->id];

            asf->asf_st->skip_to_key = 0;

        }

        asf_st = asf->asf_st;

        av_assert0(asf_st);

        if (asf->packet_replic_size == 1) {

            // frag_offset is here used as the beginning timestamp

            asf->packet_frag_timestamp = asf->packet_time_start;

            asf->packet_time_start    += asf->packet_time_delta;

            asf_st->packet_obj_size    = asf->packet_frag_size = avio_r8(pb);

            asf->packet_size_left--;

            asf->packet_multi_size--;

            if (asf->packet_multi_size < asf_st->packet_obj_size) {

                asf->packet_time_start = 0;

                avio_skip(pb, asf->packet_multi_size);

                asf->packet_size_left -= asf->packet_multi_size;

                continue;

            }

            asf->packet_multi_size -= asf_st->packet_obj_size;

        }

        if (asf_st->pkt.size != asf_st->packet_obj_size ||

            // FIXME is this condition sufficient?

            asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) {

            if (asf_st->pkt.data) {

                av_log(s, AV_LOG_INFO,

                       "freeing incomplete packet size %d, new %d\n",

                       asf_st->pkt.size, asf_st->packet_obj_size);

                asf_st->frag_offset = 0;

                av_free_packet(&asf_st->pkt);

            }

            /* new packet */

            av_new_packet(&asf_st->pkt, asf_st->packet_obj_size);

            asf_st->seq              = asf->packet_seq;

            asf_st->pkt.dts          = asf->packet_frag_timestamp - asf->hdr.preroll;

            asf_st->pkt.stream_index = asf->stream_index;

            asf_st->pkt.pos          = asf_st->packet_pos = asf->packet_pos;

            if (asf_st->pkt.data && asf_st->palette_changed) {

                uint8_t *pal;

                pal = av_packet_new_side_data(&asf_st->pkt, AV_PKT_DATA_PALETTE,

                                              AVPALETTE_SIZE);

                if (!pal) {

                    av_log(s, AV_LOG_ERROR, "Cannot append palette to packet\n");

                } else {

                    memcpy(pal, asf_st->palette, AVPALETTE_SIZE);

                    asf_st->palette_changed = 0;

                }

            }

            av_dlog(asf, "new packet: stream:%d key:%d packet_key:%d audio:%d size:%d\n",

                    asf->stream_index, asf->packet_key_frame,

                    asf_st->pkt.flags & AV_PKT_FLAG_KEY,

                    s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO,

                    asf_st->packet_obj_size);

            if (s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO)

                asf->packet_key_frame = 1;

            if (asf->packet_key_frame)

                asf_st->pkt.flags |= AV_PKT_FLAG_KEY;

        }

        /* read data */

        av_dlog(asf, "READ PACKET s:%d  os:%d  o:%d,%d  l:%d   DATA:%p\n",

                s->packet_size, asf_st->pkt.size, asf->packet_frag_offset,

                asf_st->frag_offset, asf->packet_frag_size, asf_st->pkt.data);

        asf->packet_size_left -= asf->packet_frag_size;

        if (asf->packet_size_left < 0)

            continue;

        if (asf->packet_frag_offset >= asf_st->pkt.size ||

            asf->packet_frag_size > asf_st->pkt.size - asf->packet_frag_offset) {

            av_log(s, AV_LOG_ERROR,

                   "packet fragment position invalid %u,%u not in %u\n",

                   asf->packet_frag_offset, asf->packet_frag_size,

                   asf_st->pkt.size);

            continue;

        }

        if (asf->packet_frag_offset != asf_st->frag_offset && !asf_st->pkt_clean) {

            memset(asf_st->pkt.data + asf_st->frag_offset, 0, asf_st->pkt.size - asf_st->frag_offset);

            asf_st->pkt_clean = 1;

        }

        ret = avio_read(pb, asf_st->pkt.data + asf->packet_frag_offset,

                        asf->packet_frag_size);

        if (ret != asf->packet_frag_size) {

            if (ret < 0 || asf->packet_frag_offset + ret == 0)

                return ret < 0 ? ret : AVERROR_EOF;

            if (asf_st->ds_span > 1) {

                // scrambling, we can either drop it completely or fill the remainder

                // TODO: should we fill the whole packet instead of just the current

                // fragment?

                memset(asf_st->pkt.data + asf->packet_frag_offset + ret, 0,

                       asf->packet_frag_size - ret);

                ret = asf->packet_frag_size;

            } else {

                // no scrambling, so we can return partial packets

                av_shrink_packet(&asf_st->pkt, asf->packet_frag_offset + ret);

            }

        }

        if (s->key && s->keylen == 20)

            ff_asfcrypt_dec(s->key, asf_st->pkt.data + asf->packet_frag_offset,

                            ret);

        asf_st->frag_offset += ret;

        /* test if whole packet is read */

        if (asf_st->frag_offset == asf_st->pkt.size) {

            // workaround for macroshit radio DVR-MS files

            if (s->streams[asf->stream_index]->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO &&

                asf_st->pkt.size > 100) {

                int i;

                for (i = 0; i < asf_st->pkt.size && !asf_st->pkt.data[i]; i++)

                    ;

                if (i == asf_st->pkt.size) {

                    av_log(s, AV_LOG_DEBUG, "discarding ms fart\n");

                    asf_st->frag_offset = 0;

                    av_free_packet(&asf_st->pkt);

                    continue;

                }

            }

            /* return packet */

            if (asf_st->ds_span > 1) {

                if (asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span) {

                    av_log(s, AV_LOG_ERROR,

                           "pkt.size != ds_packet_size * ds_span (%d %d %d)\n",

                           asf_st->pkt.size, asf_st->ds_packet_size,

                           asf_st->ds_span);

                } else {

                    /* packet descrambling */

                    AVBufferRef *buf = av_buffer_alloc(asf_st->pkt.size +

                                                       FF_INPUT_BUFFER_PADDING_SIZE);

                    if (buf) {

                        uint8_t *newdata = buf->data;

                        int offset = 0;

                        memset(newdata + asf_st->pkt.size, 0,

                               FF_INPUT_BUFFER_PADDING_SIZE);

                        while (offset < asf_st->pkt.size) {

                            int off = offset / asf_st->ds_chunk_size;

                            int row = off / asf_st->ds_span;

                            int col = off % asf_st->ds_span;

                            int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size;

                            assert(offset + asf_st->ds_chunk_size <= asf_st->pkt.size);

                            assert(idx + 1 <= asf_st->pkt.size / asf_st->ds_chunk_size);

                            memcpy(newdata + offset,

                                   asf_st->pkt.data + idx * asf_st->ds_chunk_size,

                                   asf_st->ds_chunk_size);

                            offset += asf_st->ds_chunk_size;

                        }

                        av_buffer_unref(&asf_st->pkt.buf);

                        asf_st->pkt.buf  = buf;

                        asf_st->pkt.data = buf->data;

                    }

                }

            }

            asf_st->frag_offset         = 0;

            *pkt                        = asf_st->pkt;

#if FF_API_DESTRUCT_PACKET

FF_DISABLE_DEPRECATION_WARNINGS

            asf_st->pkt.destruct        = NULL;

FF_ENABLE_DEPRECATION_WARNINGS

#endif

            asf_st->pkt.buf             = 0;

            asf_st->pkt.size            = 0;

            asf_st->pkt.data            = 0;

            asf_st->pkt.side_data_elems = 0;

            asf_st->pkt.side_data       = NULL;

            break; // packet completed

        }

    }

    return 0;

}


static void rc4030_unrealize(DeviceState *dev, Error **errp)

{

    rc4030State *s = RC4030(dev);

    int i;

    timer_free(s->periodic_timer);

    address_space_destroy(&s->dma_as);

    object_unparent(OBJECT(&s->dma_tt));

    object_unparent(OBJECT(&s->dma_tt_alias));

    object_unparent(OBJECT(&s->dma_mr));

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

        memory_region_del_subregion(&s->dma_mr, &s->dma_mrs[i]);

        object_unparent(OBJECT(&s->dma_mrs[i]));

    }

}


static int flic_decode_frame_8BPP(AVCodecContext *avctx,

                                  void *data, int *data_size,

                                  uint8_t *buf, int buf_size)

{

    FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;

    int stream_ptr = 0;

    int stream_ptr_after_color_chunk;

    int pixel_ptr;

    int palette_ptr;

    unsigned char palette_idx1;

    unsigned char palette_idx2;

    unsigned int frame_size;

    int num_chunks;

    unsigned int chunk_size;

    int chunk_type;

    int i, j;

    int color_packets;

    int color_changes;

    int color_shift;

    unsigned char r, g, b;

    int lines;

    int compressed_lines;

    int starting_line;

    signed short line_packets;

    int y_ptr;

    signed char byte_run;

    int pixel_skip;

    int pixel_countdown;

    unsigned char *pixels;

    int pixel_limit;

    s->frame.reference = 1;

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

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

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

        return -1;

    }

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

    pixel_limit = s->avctx->height * s->frame.linesize[0];

    frame_size = LE_32(&buf[stream_ptr]);

    stream_ptr += 6;  /* skip the magic number */

    num_chunks = LE_16(&buf[stream_ptr]);

    stream_ptr += 10;  /* skip padding */

    frame_size -= 16;

    /* iterate through the chunks */

    while ((frame_size > 0) && (num_chunks > 0)) {

        chunk_size = LE_32(&buf[stream_ptr]);

        stream_ptr += 4;

        chunk_type = LE_16(&buf[stream_ptr]);

        stream_ptr += 2;

        switch (chunk_type) {

        case FLI_256_COLOR:

        case FLI_COLOR:

            stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6;

            /* check special case: If this file is from the Magic Carpet

             * game and uses 6-bit colors even though it reports 256-color

             * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during

             * initialization) */

            if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE))

                color_shift = 0;

            else

                color_shift = 2;

            /* set up the palette */

            color_packets = LE_16(&buf[stream_ptr]);

            stream_ptr += 2;

            palette_ptr = 0;

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

                /* first byte is how many colors to skip */

                palette_ptr += buf[stream_ptr++];

                /* next byte indicates how many entries to change */

                color_changes = buf[stream_ptr++];

                /* if there are 0 color changes, there are actually 256 */

                if (color_changes == 0)

                    color_changes = 256;

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

                    unsigned int entry;

                    /* wrap around, for good measure */

                    if ((unsigned)palette_ptr >= 256)

                        palette_ptr = 0;

                    r = buf[stream_ptr++] << color_shift;

                    g = buf[stream_ptr++] << color_shift;

                    b = buf[stream_ptr++] << color_shift;

                    entry = (r << 16) | (g << 8) | b;

                    if (s->palette[palette_ptr] != entry)

                        s->new_palette = 1;

                    s->palette[palette_ptr++] = entry;

                }

            }

            /* color chunks sometimes have weird 16-bit alignment issues;

             * therefore, take the hardline approach and set the stream_ptr

             * to the value calculated w.r.t. the size specified by the color

             * chunk header */

            stream_ptr = stream_ptr_after_color_chunk;

            break;

        case FLI_DELTA:

            y_ptr = 0;

            compressed_lines = LE_16(&buf[stream_ptr]);

            stream_ptr += 2;

            while (compressed_lines > 0) {

                line_packets = LE_16(&buf[stream_ptr]);

                stream_ptr += 2;

                if (line_packets < 0) {

                    line_packets = -line_packets;

                    y_ptr += line_packets * s->frame.linesize[0];

                } else {

                    compressed_lines--;

                    pixel_ptr = y_ptr;

                    pixel_countdown = s->avctx->width;

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

                        /* account for the skip bytes */

                        pixel_skip = buf[stream_ptr++];

                        pixel_ptr += pixel_skip;

                        pixel_countdown -= pixel_skip;

                        byte_run = buf[stream_ptr++];

                        if (byte_run < 0) {

                            byte_run = -byte_run;

                            palette_idx1 = buf[stream_ptr++];

                            palette_idx2 = buf[stream_ptr++];

                            CHECK_PIXEL_PTR(byte_run);

                            for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {

                                pixels[pixel_ptr++] = palette_idx1;

                                pixels[pixel_ptr++] = palette_idx2;

                            }

                        } else {

                            CHECK_PIXEL_PTR(byte_run * 2);

                            for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {

                                palette_idx1 = buf[stream_ptr++];

                                pixels[pixel_ptr++] = palette_idx1;

                            }

                        }

                    }

                    y_ptr += s->frame.linesize[0];

                }

            }

            break;

        case FLI_LC:

            /* line compressed */

            starting_line = LE_16(&buf[stream_ptr]);

            stream_ptr += 2;

            y_ptr = 0;

            y_ptr += starting_line * s->frame.linesize[0];

            compressed_lines = LE_16(&buf[stream_ptr]);

            stream_ptr += 2;

            while (compressed_lines > 0) {

                pixel_ptr = y_ptr;

                pixel_countdown = s->avctx->width;

                line_packets = buf[stream_ptr++];

                if (line_packets > 0) {

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

                        /* account for the skip bytes */

                        pixel_skip = buf[stream_ptr++];

                        pixel_ptr += pixel_skip;

                        pixel_countdown -= pixel_skip;

                        byte_run = buf[stream_ptr++];

                        if (byte_run > 0) {

                            CHECK_PIXEL_PTR(byte_run);

                            for (j = 0; j < byte_run; j++, pixel_countdown--) {

                                palette_idx1 = buf[stream_ptr++];

                                pixels[pixel_ptr++] = palette_idx1;

                            }

                        } else {

                            byte_run = -byte_run;

                            palette_idx1 = buf[stream_ptr++];

                            CHECK_PIXEL_PTR(byte_run);

                            for (j = 0; j < byte_run; j++, pixel_countdown--) {

                                pixels[pixel_ptr++] = palette_idx1;

                            }

                        }

                    }

                }

                y_ptr += s->frame.linesize[0];

                compressed_lines--;

            }

            break;

        case FLI_BLACK:

            /* set the whole frame to color 0 (which is usually black) */

            memset(pixels, 0,

                s->frame.linesize[0] * s->avctx->height);

            break;

        case FLI_BRUN:

            /* Byte run compression: This chunk type only occurs in the first

             * FLI frame and it will update the entire frame. */

            y_ptr = 0;

            for (lines = 0; lines < s->avctx->height; lines++) {

                pixel_ptr = y_ptr;

                /* disregard the line packets; instead, iterate through all

                 * pixels on a row */

                stream_ptr++;

                pixel_countdown = s->avctx->width;

                while (pixel_countdown > 0) {

                    byte_run = buf[stream_ptr++];

                    if (byte_run > 0) {

                        palette_idx1 = buf[stream_ptr++];

                        CHECK_PIXEL_PTR(byte_run);

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

                            pixels[pixel_ptr++] = palette_idx1;

                            pixel_countdown--;

                            if (pixel_countdown < 0)

                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",

                                       pixel_countdown);

                        }

                    } else {  /* copy bytes if byte_run < 0 */

                        byte_run = -byte_run;

                        CHECK_PIXEL_PTR(byte_run);

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

                            palette_idx1 = buf[stream_ptr++];

                            pixels[pixel_ptr++] = palette_idx1;

                            pixel_countdown--;

                            if (pixel_countdown < 0)

                                av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",

                                       pixel_countdown);

                        }

                    }

                }

                y_ptr += s->frame.linesize[0];

            }

            break;

        case FLI_COPY:

            /* copy the chunk (uncompressed frame) */

            if (chunk_size - 6 > s->avctx->width * s->avctx->height) {

                av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \

                       "bigger than image, skipping chunk\n", chunk_size - 6);

                stream_ptr += chunk_size - 6;

            } else {

                for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;

                     y_ptr += s->frame.linesize[0]) {

                    memcpy(&pixels[y_ptr], &buf[stream_ptr],

                        s->avctx->width);

                    stream_ptr += s->avctx->width;

                }

            }

            break;

        case FLI_MINI:

            /* some sort of a thumbnail? disregard this chunk... */

            stream_ptr += chunk_size - 6;

            break;

        default:

            av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);

            break;

        }

        frame_size -= chunk_size;

        num_chunks--;

    }

    /* by the end of the chunk, the stream ptr should equal the frame

     * size (minus 1, possibly); if it doesn't, issue a warning */

    if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))

        av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \

               "and final chunk ptr = %d\n", buf_size, stream_ptr);

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

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

    if (s->new_palette) {

        s->frame.palette_has_changed = 1;

        s->new_palette = 0;

    }

    *data_size=sizeof(AVFrame);

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

    return buf_size;

}


static ExitStatus trans_fop_dew_0e(DisasContext *ctx, uint32_t insn,

                                   const DisasInsn *di)

{

    unsigned rt = extract32(insn, 0, 5);

    unsigned ra = assemble_ra64(insn);

    return do_fop_dew(ctx, rt, ra, di->f_dew);

}


static void check_watchpoint(int offset, int len_mask, int flags)

{

    CPUArchState *env = cpu_single_env;

    target_ulong pc, cs_base;

    TranslationBlock *tb;

    target_ulong vaddr;

    CPUWatchpoint *wp;

    int cpu_flags;

    if (env->watchpoint_hit) {

        /* We re-entered the check after replacing the TB. Now raise

         * the debug interrupt so that is will trigger after the

         * current instruction. */

        cpu_interrupt(env, CPU_INTERRUPT_DEBUG);

        return;

    }

    vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset;

    QTAILQ_FOREACH(wp, &env->watchpoints, entry) {

        if ((vaddr == (wp->vaddr & len_mask) ||

             (vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {

            wp->flags |= BP_WATCHPOINT_HIT;

            if (!env->watchpoint_hit) {

                env->watchpoint_hit = wp;

                tb = tb_find_pc(env->mem_io_pc);

                if (!tb) {

                    cpu_abort(env, "check_watchpoint: could not find TB for "

                              "pc=%p", (void *)env->mem_io_pc);

                }

                cpu_restore_state(tb, env, env->mem_io_pc);

                tb_phys_invalidate(tb, -1);

                if (wp->flags & BP_STOP_BEFORE_ACCESS) {

                    env->exception_index = EXCP_DEBUG;

                    cpu_loop_exit(env);

                } else {

                    cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags);

                    tb_gen_code(env, pc, cs_base, cpu_flags, 1);

                    cpu_resume_from_signal(env, NULL);

                }

            }

        } else {

            wp->flags &= ~BP_WATCHPOINT_HIT;

        }

    }

}


BalloonInfo *qmp_query_balloon(Error **errp)

{

    BalloonInfo *info;

    if (kvm_enabled() && !kvm_has_sync_mmu()) {

        error_set(errp, QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");

        return NULL;

    }

    info = g_malloc0(sizeof(*info));

    if (qemu_balloon_status(info) == 0) {

        error_set(errp, QERR_DEVICE_NOT_ACTIVE, "balloon");

        qapi_free_BalloonInfo(info);

        return NULL;

    }

    return info;

}


static void pc_init1(MemoryRegion *system_memory,

                     MemoryRegion *system_io,

                     ram_addr_t ram_size,

                     const char *boot_device,

                     const char *kernel_filename,

                     const char *kernel_cmdline,

                     const char *initrd_filename,

                     const char *cpu_model,

                     int pci_enabled,

                     int kvmclock_enabled)

{

    int i;

    ram_addr_t below_4g_mem_size, above_4g_mem_size;

    PCIBus *pci_bus;

    ISABus *isa_bus;

    PCII440FXState *i440fx_state;

    int piix3_devfn = -1;

    qemu_irq *cpu_irq;

    qemu_irq *gsi;

    qemu_irq *i8259;

    qemu_irq *smi_irq;

    GSIState *gsi_state;

    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];

    BusState *idebus[MAX_IDE_BUS];

    ISADevice *rtc_state;

    ISADevice *floppy;

    MemoryRegion *ram_memory;

    MemoryRegion *pci_memory;

    MemoryRegion *rom_memory;

    DeviceState *icc_bridge;

    FWCfgState *fw_cfg = NULL;

    if (xen_enabled() && xen_hvm_init() != 0) {

        fprintf(stderr, "xen hardware virtual machine initialisation failed\n");

        exit(1);

    }

    icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE);

    object_property_add_child(qdev_get_machine(), "icc-bridge",

                              OBJECT(icc_bridge), NULL);

    pc_cpus_init(cpu_model, icc_bridge);

    pc_acpi_init("acpi-dsdt.aml");

    if (kvm_enabled() && kvmclock_enabled) {

        kvmclock_create();

    }

    if (ram_size >= 0xe0000000 ) {

        above_4g_mem_size = ram_size - 0xe0000000;

        below_4g_mem_size = 0xe0000000;

    } else {

        above_4g_mem_size = 0;

        below_4g_mem_size = ram_size;

    }

    if (pci_enabled) {

        pci_memory = g_new(MemoryRegion, 1);

        memory_region_init(pci_memory, "pci", INT64_MAX);

        rom_memory = pci_memory;

    } else {

        pci_memory = NULL;

        rom_memory = system_memory;

    }

    /* allocate ram and load rom/bios */

    if (!xen_enabled()) {

        fw_cfg = pc_memory_init(system_memory,

                       kernel_filename, kernel_cmdline, initrd_filename,

                       below_4g_mem_size, above_4g_mem_size,

                       rom_memory, &ram_memory);

    }

    gsi_state = g_malloc0(sizeof(*gsi_state));

    if (kvm_irqchip_in_kernel()) {

        kvm_pc_setup_irq_routing(pci_enabled);

        gsi = qemu_allocate_irqs(kvm_pc_gsi_handler, gsi_state,

                                 GSI_NUM_PINS);

    } else {

        gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);

    }

    if (pci_enabled) {

        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, &isa_bus, gsi,

                              system_memory, system_io, ram_size,

                              below_4g_mem_size,

                              0x100000000ULL - below_4g_mem_size,

                              0x100000000ULL + above_4g_mem_size,

                              (sizeof(hwaddr) == 4

                               ? 0

                               : ((uint64_t)1 << 62)),

                              pci_memory, ram_memory);

    } else {

        pci_bus = NULL;

        i440fx_state = NULL;

        isa_bus = isa_bus_new(NULL, system_io);

        no_hpet = 1;

    }

    isa_bus_irqs(isa_bus, gsi);

    if (kvm_irqchip_in_kernel()) {

        i8259 = kvm_i8259_init(isa_bus);

    } else if (xen_enabled()) {

        i8259 = xen_interrupt_controller_init();

    } else {

        cpu_irq = pc_allocate_cpu_irq();

        i8259 = i8259_init(isa_bus, cpu_irq[0]);

    }

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

        gsi_state->i8259_irq[i] = i8259[i];

    }

    if (pci_enabled) {

        ioapic_init_gsi(gsi_state, "i440fx");

    }

    qdev_init_nofail(icc_bridge);

    pc_register_ferr_irq(gsi[13]);

    pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);

    if (xen_enabled()) {

        pci_create_simple(pci_bus, -1, "xen-platform");

    }

    /* init basic PC hardware */

    pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, xen_enabled());

    pc_nic_init(isa_bus, pci_bus);

    ide_drive_get(hd, MAX_IDE_BUS);

    if (pci_enabled) {

        PCIDevice *dev;

        if (xen_enabled()) {

            dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1);

        } else {

            dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);

        }

        idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");

        idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");

    } else {

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

            ISADevice *dev;

            dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i],

                               ide_irq[i],

                               hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);

            idebus[i] = qdev_get_child_bus(DEVICE(dev), "ide.0");

        }

    }

    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,

                 floppy, idebus[0], idebus[1], rtc_state);

    if (pci_enabled && usb_enabled(false)) {

        pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");

    }

    if (pci_enabled && acpi_enabled) {

        i2c_bus *smbus;

        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt,

                                     x86_env_get_cpu(first_cpu), 1);

        /* TODO: Populate SPD eeprom data.  */

        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,

                              gsi[9], *smi_irq,

                              kvm_enabled(), fw_cfg);

        smbus_eeprom_init(smbus, 8, NULL, 0);

    }

    if (pci_enabled) {

        pc_pci_device_init(pci_bus);

    }

    if (has_pvpanic) {

        pvpanic_init(isa_bus);

    }

}


static void test_visitor_out_alternate(TestOutputVisitorData *data,

                                       const void *unused)

{

    QObject *arg;

    UserDefAlternate *tmp;

    QDict *qdict;

    tmp = g_new0(UserDefAlternate, 1);

    tmp->type = QTYPE_QINT;

    tmp->u.i = 42;

    visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);

    arg = visitor_get(data);

    g_assert(qobject_type(arg) == QTYPE_QINT);

    g_assert_cmpint(qint_get_int(qobject_to_qint(arg)), ==, 42);

    qapi_free_UserDefAlternate(tmp);

    visitor_reset(data);

    tmp = g_new0(UserDefAlternate, 1);

    tmp->type = QTYPE_QSTRING;

    tmp->u.s = g_strdup("hello");

    visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);

    arg = visitor_get(data);

    g_assert(qobject_type(arg) == QTYPE_QSTRING);

    g_assert_cmpstr(qstring_get_str(qobject_to_qstring(arg)), ==, "hello");

    qapi_free_UserDefAlternate(tmp);

    visitor_reset(data);

    tmp = g_new0(UserDefAlternate, 1);

    tmp->type = QTYPE_QDICT;

    tmp->u.udfu.integer = 1;

    tmp->u.udfu.string = g_strdup("str");

    tmp->u.udfu.enum1 = ENUM_ONE_VALUE1;

    tmp->u.udfu.u.value1.boolean = true;

    visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort);

    arg = visitor_get(data);

    g_assert_cmpint(qobject_type(arg), ==, QTYPE_QDICT);

    qdict = qobject_to_qdict(arg);

    g_assert_cmpint(qdict_size(qdict), ==, 4);

    g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 1);

    g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "str");

    g_assert_cmpstr(qdict_get_str(qdict, "enum1"), ==, "value1");

    g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, true);

    qapi_free_UserDefAlternate(tmp);

}


static int qcow2_discard_refcount_block(BlockDriverState *bs,

                                        uint64_t discard_block_offs)

{

    BDRVQcow2State *s = bs->opaque;

    uint64_t refblock_offs = get_refblock_offset(s, discard_block_offs);

    uint64_t cluster_index = discard_block_offs >> s->cluster_bits;

    uint32_t block_index = cluster_index & (s->refcount_block_size - 1);

    void *refblock;

    int ret;

    assert(discard_block_offs != 0);

    ret = qcow2_cache_get(bs, s->refcount_block_cache, refblock_offs,

                          &refblock);

    if (ret < 0) {

        return ret;

    }

    if (s->get_refcount(refblock, block_index) != 1) {

        qcow2_signal_corruption(bs, true, -1, -1, "Invalid refcount:"

                                " refblock offset %#" PRIx64

                                ", reftable index %u"

                                ", block offset %#" PRIx64

                                ", refcount %#" PRIx64,

                                refblock_offs,

                                offset_to_reftable_index(s, discard_block_offs),

                                discard_block_offs,

                                s->get_refcount(refblock, block_index));

        qcow2_cache_put(bs, s->refcount_block_cache, &refblock);

        return -EINVAL;

    }

    s->set_refcount(refblock, block_index, 0);

    qcow2_cache_entry_mark_dirty(bs, s->refcount_block_cache, refblock);

    qcow2_cache_put(bs, s->refcount_block_cache, &refblock);

    if (cluster_index < s->free_cluster_index) {

        s->free_cluster_index = cluster_index;

    }

    refblock = qcow2_cache_is_table_offset(bs, s->refcount_block_cache,

                                           discard_block_offs);

    if (refblock) {

        /* discard refblock from the cache if refblock is cached */

        qcow2_cache_discard(bs, s->refcount_block_cache, refblock);

    }

    update_refcount_discard(bs, discard_block_offs, s->cluster_size);

    return 0;

}


static void test_qemu_strtoul_full_correct(void)

{

    const char *str = "123";

    unsigned long res = 999;

    int err;

    err = qemu_strtoul(str, NULL, 0, &res);

    g_assert_cmpint(err, ==, 0);

    g_assert_cmpint(res, ==, 123);

}


int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt,

                          const char *filename, void *logctx,

                          unsigned int offset, unsigned int max_probe_size)

{

    AVProbeData pd = { filename ? filename : "" };

    uint8_t *buf = NULL;

    uint8_t *mime_type;

    int ret = 0, probe_size, buf_offset = 0;

    int score = 0;

    if (!max_probe_size)

        max_probe_size = PROBE_BUF_MAX;

    else if (max_probe_size < PROBE_BUF_MIN) {

        av_log(logctx, AV_LOG_ERROR,

               "Specified probe size value %u cannot be < %u\n", max_probe_size, PROBE_BUF_MIN);

        return AVERROR(EINVAL);

    }

    if (offset >= max_probe_size)

        return AVERROR(EINVAL);

#ifdef FF_API_PROBE_MIME

    if (pb->av_class)

        av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &pd.mime_type);

#endif

#if !FF_API_PROBE_MIME

    if (!*fmt && pb->av_class && av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type) >= 0 && mime_type) {

        if (!av_strcasecmp(mime_type, "audio/aacp")) {

            *fmt = av_find_input_format("aac");

        }

        av_freep(&mime_type);

    }

#endif

    for (probe_size = PROBE_BUF_MIN; probe_size <= max_probe_size && !*fmt;

         probe_size = FFMIN(probe_size << 1,

                            FFMAX(max_probe_size, probe_size + 1))) {

        score = probe_size < max_probe_size ? AVPROBE_SCORE_RETRY : 0;

        /* Read probe data. */

        if ((ret = av_reallocp(&buf, probe_size + AVPROBE_PADDING_SIZE)) < 0)

            goto fail;

        if ((ret = avio_read(pb, buf + buf_offset,

                             probe_size - buf_offset)) < 0) {

            /* Fail if error was not end of file, otherwise, lower score. */

            if (ret != AVERROR_EOF)

                goto fail;

            score = 0;

            ret   = 0;          /* error was end of file, nothing read */

        }

        buf_offset += ret;

        if (buf_offset < offset)

            continue;

        pd.buf_size = buf_offset - offset;

        pd.buf = &buf[offset];

        memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE);

        /* Guess file format. */

        *fmt = av_probe_input_format2(&pd, 1, &score);

        if (*fmt) {

            /* This can only be true in the last iteration. */

            if (score <= AVPROBE_SCORE_RETRY) {

                av_log(logctx, AV_LOG_WARNING,

                       "Format %s detected only with low score of %d, "

                       "misdetection possible!\n", (*fmt)->name, score);

            } else

                av_log(logctx, AV_LOG_DEBUG,

                       "Format %s probed with size=%d and score=%d\n",

                       (*fmt)->name, probe_size, score);

#if 0

            FILE *f = fopen("probestat.tmp", "ab");

            fprintf(f, "probe_size:%d format:%s score:%d filename:%s\n", probe_size, (*fmt)->name, score, filename);

            fclose(f);

#endif

        }

    }

    if (!*fmt)

        ret = AVERROR_INVALIDDATA;

fail:

    /* Rewind. Reuse probe buffer to avoid seeking. */

    if (ret >= 0)

        ret = ffio_rewind_with_probe_data(pb, &buf, buf_offset);

#ifdef FF_API_PROBE_MIME

    av_free(pd.mime_type);

#endif

    return ret < 0 ? ret : score;

}


static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,

                             int Al, const uint8_t *mb_bitmask,

                             const AVFrame *reference)

{

    int i, mb_x, mb_y;

    uint8_t *data[MAX_COMPONENTS];

    const uint8_t *reference_data[MAX_COMPONENTS];

    int linesize[MAX_COMPONENTS];

    GetBitContext mb_bitmask_gb;

    if (mb_bitmask)

        init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height);

    if (s->flipped && s->avctx->flags & CODEC_FLAG_EMU_EDGE) {

        av_log(s->avctx, AV_LOG_ERROR,

               "Can not flip image with CODEC_FLAG_EMU_EDGE set!\n");

        s->flipped = 0;

    }

    if (s->flipped && s->avctx->lowres) {

        av_log(s->avctx, AV_LOG_ERROR, "Can not flip image with lowres\n");

        s->flipped = 0;

    }

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

        int c   = s->comp_index[i];

        data[c] = s->picture_ptr->data[c];

        reference_data[c] = reference ? reference->data[c] : NULL;

        linesize[c] = s->linesize[c];

        s->coefs_finished[c] |= 1;

        if (s->flipped) {

            // picture should be flipped upside-down for this codec

            int offset = (linesize[c] * (s->v_scount[i] *

                         (8 * s->mb_height - ((s->height / s->v_max) & 7)) - 1));

            data[c]           += offset;

            reference_data[c] += offset;

            linesize[c]       *= -1;

        }

    }

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

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

            const int copy_mb = mb_bitmask && !get_bits1(&mb_bitmask_gb);

            if (s->restart_interval && !s->restart_count)

                s->restart_count = s->restart_interval;

            if (get_bits_left(&s->gb) < 0) {

                av_log(s->avctx, AV_LOG_ERROR, "overread %d\n",

                       -get_bits_left(&s->gb));

                return -1;

            }

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

                uint8_t *ptr;

                int n, h, v, x, y, c, j;

                int block_offset;

                n = s->nb_blocks[i];

                c = s->comp_index[i];

                h = s->h_scount[i];

                v = s->v_scount[i];

                x = 0;

                y = 0;

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

                    block_offset = ((linesize[c] * (v * mb_y + y) * 8) +

                                    (h * mb_x + x) * 8);

                    if (s->interlaced && s->bottom_field)

                        block_offset += linesize[c] >> 1;

                    ptr = data[c] + block_offset;

                    if (!s->progressive) {

                        if (copy_mb)

                            copy_block8(ptr, reference_data[c] + block_offset,

                                        linesize[c], linesize[c], 8);

                        else {

                            s->dsp.clear_block(s->block);

                            if (decode_block(s, s->block, i,

                                             s->dc_index[i], s->ac_index[i],

                                             s->quant_matrixes[s->quant_index[c]]) < 0) {

                                av_log(s->avctx, AV_LOG_ERROR,

                                       "error y=%d x=%d\n", mb_y, mb_x);

                                return -1;

                            }

                            s->dsp.idct_put(ptr, linesize[c], s->block);

                        }

                    } else {

                        int block_idx  = s->block_stride[c] * (v * mb_y + y) +

                                         (h * mb_x + x);

                        DCTELEM *block = s->blocks[c][block_idx];

                        if (Ah)

                            block[0] += get_bits1(&s->gb) *

                                        s->quant_matrixes[s->quant_index[c]][0] << Al;

                        else if (decode_dc_progressive(s, block, i, s->dc_index[i],

                                                       s->quant_matrixes[s->quant_index[c]],

                                                       Al) < 0) {

                            av_log(s->avctx, AV_LOG_ERROR,

                                   "error y=%d x=%d\n", mb_y, mb_x);

                            return -1;

                        }

                    }

                    // av_log(s->avctx, AV_LOG_DEBUG, "mb: %d %d processed\n",

                    //        mb_y, mb_x);

                    // av_log(NULL, AV_LOG_DEBUG, "%d %d %d %d %d %d %d %d \n",

                    //        mb_x, mb_y, x, y, c, s->bottom_field,

                    //        (v * mb_y + y) * 8, (h * mb_x + x) * 8);

                    if (++x == h) {

                        x = 0;

                        y++;

                    }

                }

            }

            if (s->restart_interval) {

                s->restart_count--;

                if(s->restart_count == 0 && s->avctx->codec_id == CODEC_ID_THP){

                    align_get_bits(&s->gb);

                    for (i = 0; i < nb_components; i++) /* reset dc */

                        s->last_dc[i] = 1024;

                }

                i = 8 + ((-get_bits_count(&s->gb)) & 7);

                /* skip RSTn */

                if (show_bits(&s->gb, i) == (1 << i) - 1) {

                    int pos = get_bits_count(&s->gb);

                    align_get_bits(&s->gb);

                    while (get_bits_left(&s->gb) >= 8 && show_bits(&s->gb, 8) == 0xFF)

                        skip_bits(&s->gb, 8);

                    if (get_bits_left(&s->gb) >= 8 && (get_bits(&s->gb, 8) & 0xF8) == 0xD0) {

                        for (i = 0; i < nb_components; i++) /* reset dc */

                            s->last_dc[i] = 1024;

                    } else

                        skip_bits_long(&s->gb, pos - get_bits_count(&s->gb));

                }

            }

        }

    }

    return 0;

}


static void arm_cpu_register_types(void)

{

    int i;

    type_register_static(&arm_cpu_type_info);

    for (i = 0; i < ARRAY_SIZE(arm_cpus); i++) {

        cpu_register(&arm_cpus[i]);

    }

}


static void gpio_write(void *opaque, target_phys_addr_t addr, uint64_t value,

                       unsigned size)

{

    struct gpio_state_t *s = opaque;

    D(printf("%s %x=%x\n", __func__, addr, (unsigned)value));

    addr >>= 2;

    switch (addr)

    {

        case RW_PA_DOUT:

            /* Decode nand pins.  */

            s->nand->ale = !!(value & (1 << 6));

            s->nand->cle = !!(value & (1 << 5));

            s->nand->ce  = !!(value & (1 << 4));

            s->regs[addr] = value;

            break;

        case RW_PD_DOUT:

            /* Temp sensor clk.  */

            if ((s->regs[addr] ^ value) & 2)

                tempsensor_clkedge(&s->tempsensor, !!(value & 2),

                                   !!(value & 16));

            s->regs[addr] = value;

            break;

        default:

            s->regs[addr] = value;

            break;

    }

}


static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)

{

    XilinxAXIEnet *s = qemu_get_nic_opaque(nc);

    static const unsigned char sa_bcast[6] = {0xff, 0xff, 0xff,

                                              0xff, 0xff, 0xff};

    static const unsigned char sa_ipmcast[3] = {0x01, 0x00, 0x52};

    uint32_t app[6] = {0};

    int promisc = s->fmi & (1 << 31);

    int unicast, broadcast, multicast, ip_multicast = 0;

    uint32_t csum32;

    uint16_t csum16;

    int i;

    DENET(qemu_log("%s: %zd bytes\n", __func__, size));

    unicast = ~buf[0] & 0x1;

    broadcast = memcmp(buf, sa_bcast, 6) == 0;

    multicast = !unicast && !broadcast;

    if (multicast && (memcmp(sa_ipmcast, buf, sizeof sa_ipmcast) == 0)) {

        ip_multicast = 1;

    }

    /* Jumbo or vlan sizes ?  */

    if (!(s->rcw[1] & RCW1_JUM)) {

        if (size > 1518 && size <= 1522 && !(s->rcw[1] & RCW1_VLAN)) {

            return size;

        }

    }

    /* Basic Address filters.  If you want to use the extended filters

       you'll generally have to place the ethernet mac into promiscuous mode

       to avoid the basic filtering from dropping most frames.  */

    if (!promisc) {

        if (unicast) {

            if (!enet_match_addr(buf, s->uaw[0], s->uaw[1])) {

                return size;

            }

        } else {

            if (broadcast) {

                /* Broadcast.  */

                if (s->regs[R_RAF] & RAF_BCAST_REJ) {

                    return size;

                }

            } else {

                int drop = 1;

                /* Multicast.  */

                if (s->regs[R_RAF] & RAF_MCAST_REJ) {

                    return size;

                }

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

                    if (enet_match_addr(buf, s->maddr[i][0], s->maddr[i][1])) {

                        drop = 0;

                        break;

                    }

                }

                if (drop) {

                    return size;

                }

            }

        }

    }

    /* Extended mcast filtering enabled?  */

    if (axienet_newfunc_enabled(s) && axienet_extmcf_enabled(s)) {

        if (unicast) {

            if (!enet_match_addr(buf, s->ext_uaw[0], s->ext_uaw[1])) {

                return size;

            }

        } else {

            if (broadcast) {

                /* Broadcast. ???  */

                if (s->regs[R_RAF] & RAF_BCAST_REJ) {

                    return size;

                }

            } else {

                int idx, bit;

                /* Multicast.  */

                if (!memcmp(buf, sa_ipmcast, 3)) {

                    return size;

                }

                idx  = (buf[4] & 0x7f) << 8;

                idx |= buf[5];

                bit = 1 << (idx & 0x1f);

                idx >>= 5;

                if (!(s->ext_mtable[idx] & bit)) {

                    return size;

                }

            }

        }

    }

    if (size < 12) {

        s->regs[R_IS] |= IS_RX_REJECT;

        enet_update_irq(s);

        return -1;

    }

    if (size > (s->c_rxmem - 4)) {

        size = s->c_rxmem - 4;

    }

    memcpy(s->rxmem, buf, size);

    memset(s->rxmem + size, 0, 4); /* Clear the FCS.  */

    if (s->rcw[1] & RCW1_FCS) {

        size += 4; /* fcs is inband.  */

    }

    app[0] = 5 << 28;

    csum32 = net_checksum_add(size - 14, (uint8_t *)s->rxmem + 14);

    /* Fold it once.  */

    csum32 = (csum32 & 0xffff) + (csum32 >> 16);

    /* And twice to get rid of possible carries.  */

    csum16 = (csum32 & 0xffff) + (csum32 >> 16);

    app[3] = csum16;

    app[4] = size & 0xffff;

    s->stats.rx_bytes += size;

    s->stats.rx++;

    if (multicast) {

        s->stats.rx_mcast++;

        app[2] |= 1 | (ip_multicast << 1);

    } else if (broadcast) {

        s->stats.rx_bcast++;

        app[2] |= 1 << 3;

    }

    /* Good frame.  */

    app[2] |= 1 << 6;

    s->rxsize = size;

    s->rxpos = 0;

    s->rxapp = g_memdup(app, sizeof(app));

    axienet_eth_rx_notify(s);

    enet_update_irq(s);

    return size;

}


static int get_physical_address_code(CPUState *env,

                                     target_phys_addr_t *physical, int *prot,

                                     target_ulong address, int mmu_idx)

{

    unsigned int i;

    uint64_t context;

    int is_user = (mmu_idx == MMU_USER_IDX ||

                   mmu_idx == MMU_USER_SECONDARY_IDX);

    if ((env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0) {

        /* IMMU disabled */

        *physical = ultrasparc_truncate_physical(address);

        *prot = PAGE_EXEC;

        return 0;

    }

    if (env->tl == 0) {

        /* PRIMARY context */

        context = env->dmmu.mmu_primary_context & 0x1fff;

    } else {

        /* NUCLEUS context */

        context = 0;

    }

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

        // ctx match, vaddr match, valid?

        if (ultrasparc_tag_match(&env->itlb[i],

                                 address, context, physical)) {

            // access ok?

            if ((env->itlb[i].tte & 0x4) && is_user) {

                if (env->immu.sfsr) /* Fault status register */

                    env->immu.sfsr = 2; /* overflow (not read before

                                             another fault) */

                env->immu.sfsr |= (is_user << 3) | 1;

                env->exception_index = TT_TFAULT;

#ifdef DEBUG_MMU

                printf("TFAULT at 0x%" PRIx64 "\n", address);

#endif

                return 1;

            }

            *prot = PAGE_EXEC;

            TTE_SET_USED(env->itlb[i].tte);

            return 0;

        }

    }

#ifdef DEBUG_MMU

    printf("TMISS at 0x%" PRIx64 "\n", address);

#endif

    /* Context is stored in DMMU (dmmuregs[1]) also for IMMU */

    env->immu.tag_access = (address & ~0x1fffULL) | context;

    env->exception_index = TT_TMISS;

    return 1;

}


static inline void RENAME(yuv2packedX)(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,

				    int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,

			    uint8_t *dest, long dstW, long dstY)

{

	long dummy=0;

	switch(c->dstFormat)

	{

#ifdef HAVE_MMX

	case IMGFMT_BGR32:

		{

			asm volatile(

				YSCALEYUV2RGBX

				WRITEBGR32(%4, %5, %%REGa)

			:: "r" (&c->redDither),

			   "m" (dummy), "m" (dummy), "m" (dummy),

			   "r" (dest), "m" (dstW)

			: "%"REG_a, "%"REG_d, "%"REG_S

			);

		}

		break;

	case IMGFMT_BGR24:

		{

			asm volatile(

				YSCALEYUV2RGBX

				"lea (%%"REG_a", %%"REG_a", 2), %%"REG_b"\n\t" //FIXME optimize

				"add %4, %%"REG_b"			\n\t"

				WRITEBGR24(%%REGb, %5, %%REGa)

			:: "r" (&c->redDither),

			   "m" (dummy), "m" (dummy), "m" (dummy),

			   "r" (dest), "m" (dstW)

			: "%"REG_a, "%"REG_b, "%"REG_d, "%"REG_S //FIXME ebx

			);

		}

		break;

	case IMGFMT_BGR15:

		{

			asm volatile(

				YSCALEYUV2RGBX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

				"paddusb "MANGLE(b5Dither)", %%mm2\n\t"

				"paddusb "MANGLE(g5Dither)", %%mm4\n\t"

				"paddusb "MANGLE(r5Dither)", %%mm5\n\t"

#endif

				WRITEBGR15(%4, %5, %%REGa)

			:: "r" (&c->redDither),

			   "m" (dummy), "m" (dummy), "m" (dummy),

			   "r" (dest), "m" (dstW)

			: "%"REG_a, "%"REG_d, "%"REG_S

			);

		}

		break;

	case IMGFMT_BGR16:

		{

			asm volatile(

				YSCALEYUV2RGBX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

				"paddusb "MANGLE(b5Dither)", %%mm2\n\t"

				"paddusb "MANGLE(g6Dither)", %%mm4\n\t"

				"paddusb "MANGLE(r5Dither)", %%mm5\n\t"

#endif

				WRITEBGR16(%4, %5, %%REGa)

			:: "r" (&c->redDither),

			   "m" (dummy), "m" (dummy), "m" (dummy),

			   "r" (dest), "m" (dstW)

			: "%"REG_a, "%"REG_d, "%"REG_S

			);

		}

		break;

	case IMGFMT_YUY2:

		{

			asm volatile(

				YSCALEYUV2PACKEDX

		/* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

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

				"psraw $3, %%mm4		\n\t"

				"psraw $3, %%mm1		\n\t"

				"psraw $3, %%mm7		\n\t"

				WRITEYUY2(%4, %5, %%REGa)

			:: "r" (&c->redDither),

			   "m" (dummy), "m" (dummy), "m" (dummy),

			   "r" (dest), "m" (dstW)

			: "%"REG_a, "%"REG_d, "%"REG_S

			);

		}

		break;

#endif

	default:

#ifdef HAVE_ALTIVEC

		/* The following list of supported dstFormat values should

		   match what's found in the body of altivec_yuv2packedX() */

		if(c->dstFormat==IMGFMT_ABGR  || c->dstFormat==IMGFMT_BGRA  ||

		   c->dstFormat==IMGFMT_BGR24 || c->dstFormat==IMGFMT_RGB24 ||

		   c->dstFormat==IMGFMT_RGBA  || c->dstFormat==IMGFMT_ARGB)

			altivec_yuv2packedX (c, lumFilter, lumSrc, lumFilterSize,

				    chrFilter, chrSrc, chrFilterSize,

				    dest, dstW, dstY);

		else

#endif

			yuv2packedXinC(c, lumFilter, lumSrc, lumFilterSize,

				    chrFilter, chrSrc, chrFilterSize,

				    dest, dstW, dstY);

		break;

	}

}


static inline void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst,

                                        int dstWidth, const uint8_t *src, int srcW,

                                        int xInc)

{

    int32_t *filterPos = c->hLumFilterPos;

    int16_t *filter    = c->hLumFilter;

    void    *mmx2FilterCode= c->lumMmx2FilterCode;

    int i;

#if defined(PIC)

    DECLARE_ALIGNED(8, uint64_t, ebxsave);

#endif

    __asm__ volatile(

#if defined(PIC)

        "mov               %%"REG_b", %5        \n\t"

#endif

        "pxor                  %%mm7, %%mm7     \n\t"

        "mov                      %0, %%"REG_c" \n\t"

        "mov                      %1, %%"REG_D" \n\t"

        "mov                      %2, %%"REG_d" \n\t"

        "mov                      %3, %%"REG_b" \n\t"

        "xor               %%"REG_a", %%"REG_a" \n\t" // i

        PREFETCH"        (%%"REG_c")            \n\t"

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

        PREFETCH"      64(%%"REG_c")            \n\t"

#if ARCH_X86_64

#define CALL_MMX2_FILTER_CODE \

        "movl            (%%"REG_b"), %%esi     \n\t"\

        "call                    *%4            \n\t"\

        "movl (%%"REG_b", %%"REG_a"), %%esi     \n\t"\

        "add               %%"REG_S", %%"REG_c" \n\t"\

        "add               %%"REG_a", %%"REG_D" \n\t"\

        "xor               %%"REG_a", %%"REG_a" \n\t"\

#else

#define CALL_MMX2_FILTER_CODE \

        "movl (%%"REG_b"), %%esi        \n\t"\

        "call         *%4                       \n\t"\

        "addl (%%"REG_b", %%"REG_a"), %%"REG_c" \n\t"\

        "add               %%"REG_a", %%"REG_D" \n\t"\

        "xor               %%"REG_a", %%"REG_a" \n\t"\

#endif /* ARCH_X86_64 */

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

#if defined(PIC)

        "mov                      %5, %%"REG_b" \n\t"

#endif

        :: "m" (src), "m" (dst), "m" (filter), "m" (filterPos),

           "m" (mmx2FilterCode)

#if defined(PIC)

          ,"m" (ebxsave)

#endif

        : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D

#if !defined(PIC)

         ,"%"REG_b

#endif

    );

    for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)

        dst[i] = src[srcW-1]*128;

}


int avfilter_parse_graph(AVFilterGraph *graph, const char *filters,

                         AVFilterInOut *openLinks, AVClass *log_ctx)

{

    int index = 0;

    char chr = 0;

    int pad = 0;

    AVFilterInOut *currInputs = NULL;

    do {

        AVFilterContext *filter;

        filters += consume_whitespace(filters);

        pad = parse_inputs(&filters, &currInputs, &openLinks, log_ctx);

        if(pad < 0)

            goto fail;

        if(!(filter = parse_filter(&filters, graph, index, log_ctx)))

            goto fail;

        if(filter->input_count == 1 && !currInputs && !index) {

            // First input can be ommitted if it is "[in]"

            const char *tmp = "[in]";

            pad = parse_inputs(&tmp, &currInputs, &openLinks, log_ctx);

            if(pad < 0)

                goto fail;

        }

        if(link_filter_inouts(filter, &currInputs, &openLinks, log_ctx) < 0)

            goto fail;

        pad = parse_outputs(&filters, &currInputs, &openLinks, log_ctx);

        if(pad < 0)

            goto fail;

        filters += consume_whitespace(filters);

        chr = *filters++;

        if(chr == ';' && currInputs) {

            av_log(log_ctx, AV_LOG_ERROR,

                   "Could not find a output to link when parsing \"%s\"\n",

                   filters - 1);

            goto fail;

        }

        index++;

    } while(chr == ',' || chr == ';');

    if(openLinks && !strcmp(openLinks->name, "out") && currInputs) {

        // Last output can be ommitted if it is "[out]"

        const char *tmp = "[out]";

        if(parse_outputs(&tmp, &currInputs, &openLinks, log_ctx) < 0)

            goto fail;

    }

    return 0;

 fail:

    avfilter_destroy_graph(graph);

    free_inout(openLinks);

    free_inout(currInputs);

    return -1;

}


static av_cold int qtrle_encode_init(AVCodecContext *avctx)

{

    QtrleEncContext *s = avctx->priv_data;

    if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) {

        return -1;

    }

    s->avctx=avctx;

    switch (avctx->pix_fmt) {

    case AV_PIX_FMT_RGB555BE:

        s->pixel_size = 2;

        break;

    case AV_PIX_FMT_RGB24:

        s->pixel_size = 3;

        break;

    case AV_PIX_FMT_ARGB:

        s->pixel_size = 4;

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "Unsupported colorspace.\n");

        break;

    }

    avctx->bits_per_coded_sample = s->pixel_size*8;

    s->rlecode_table = av_mallocz(s->avctx->width);

    s->skip_table    = av_mallocz(s->avctx->width);

    s->length_table  = av_mallocz((s->avctx->width + 1)*sizeof(int));

    if (!s->skip_table || !s->length_table || !s->rlecode_table) {

        av_log(avctx, AV_LOG_ERROR, "Error allocating memory.\n");

        return -1;

    }

    if (avpicture_alloc(&s->previous_frame, avctx->pix_fmt, avctx->width, avctx->height) < 0) {

        av_log(avctx, AV_LOG_ERROR, "Error allocating picture\n");

        return -1;

    }

    s->max_buf_size = s->avctx->width*s->avctx->height*s->pixel_size*2 /* image base material */

                      + 15                                           /* header + footer */

                      + s->avctx->height*2                           /* skip code+rle end */

                      + s->avctx->width/MAX_RLE_BULK + 1             /* rle codes */;

    avctx->coded_frame = av_frame_alloc();

    if (!avctx->coded_frame) {

        qtrle_encode_end(avctx);

        return AVERROR(ENOMEM);

    }

    return 0;

}


static inline void check_for_slice(AVSContext *h) {

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

    int align;

    if(h->mbx)

        return;

    align = (-get_bits_count(gb)) & 7;

    if((show_bits_long(gb,24+align) & 0xFFFFFF) == 0x000001) {

        skip_bits_long(gb,24+align);

        h->stc = get_bits(gb,8);

        decode_slice_header(h,gb);

    }

}


ISADevice *isa_create_simple(const char *name)

{

    ISADevice *dev;

    dev = isa_create(name);

    if (qdev_init(&dev->qdev) != 0) {

        return NULL;

    }

    return dev;

}


envlist_create(void)

{

	envlist_t *envlist;

	if ((envlist = malloc(sizeof (*envlist))) == NULL)

		return (NULL);

	LIST_INIT(&envlist->el_entries);

	envlist->el_count = 0;

	return (envlist);

}


void qemu_fopen_ops_buffered(MigrationState *migration_state)

{

    QEMUFileBuffered *s;

    s = g_malloc0(sizeof(*s));

    s->migration_state = migration_state;

    s->xfer_limit = migration_state->bandwidth_limit / 10;

    s->migration_state->complete = false;

    s->file = qemu_fopen_ops(s, &buffered_file_ops);

    migration_state->file = s->file;

    qemu_thread_create(&s->thread, buffered_file_thread, s,

                       QEMU_THREAD_DETACHED);

}


static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length)

{

    int rc = -EINVAL;

    char name[256];

    /* Client sends:

        [20 ..  xx]   export name (length bytes)

     */

    TRACE("Checking length");

    if (length > 255) {

        LOG("Bad length received");

        goto fail;

    }

    if (nbd_negotiate_read(client->ioc, name, length) != length) {

        LOG("read failed");

        goto fail;

    }

    name[length] = '\0';

    TRACE("Client requested export '%s'", name);

    client->exp = nbd_export_find(name);

    if (!client->exp) {

        LOG("export not found");

        goto fail;

    }

    QTAILQ_INSERT_TAIL(&client->exp->clients, client, next);

    nbd_export_get(client->exp);

    rc = 0;

fail:

    return rc;

}


void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc){

    if(bsfc->filter->close)

        bsfc->filter->close(bsfc);

    av_freep(&bsfc->priv_data);

    av_parser_close(bsfc->parser);

    av_free(bsfc);

}


static void mov_text_cleanup_ftab(MovTextContext *m)

{

    int i;

    for(i = 0; i < m->count_f; i++) {

        av_freep(&m->ftab[i]->font);

        av_freep(&m->ftab[i]);

    }

    av_freep(&m->ftab);

}


static inline bool extended_addresses_enabled(CPUARMState *env)

{

    return arm_feature(env, ARM_FEATURE_LPAE)

        && (env->cp15.c2_control & (1 << 31));

}


static int fill_filter_caches(const H264Context *h, H264SliceContext *sl, int mb_type)

{

    const int mb_xy = sl->mb_xy;

    int top_xy, left_xy[LEFT_MBS];

    int top_type, left_type[LEFT_MBS];

    uint8_t *nnz;

    uint8_t *nnz_cache;

    top_xy = mb_xy - (h->mb_stride << MB_FIELD(sl));

    /* Wow, what a mess, why didn't they simplify the interlacing & intra

     * stuff, I can't imagine that these complex rules are worth it. */

    left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1;

    if (FRAME_MBAFF(h)) {

        const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.mb_type[mb_xy - 1]);

        const int curr_mb_field_flag = IS_INTERLACED(mb_type);

        if (sl->mb_y & 1) {

            if (left_mb_field_flag != curr_mb_field_flag)

                left_xy[LTOP] -= h->mb_stride;

        } else {

            if (curr_mb_field_flag)

                top_xy += h->mb_stride &

                          (((h->cur_pic.mb_type[top_xy] >> 7) & 1) - 1);

            if (left_mb_field_flag != curr_mb_field_flag)

                left_xy[LBOT] += h->mb_stride;

        }

    }

    sl->top_mb_xy        = top_xy;

    sl->left_mb_xy[LTOP] = left_xy[LTOP];

    sl->left_mb_xy[LBOT] = left_xy[LBOT];

    {

        /* For sufficiently low qp, filtering wouldn't do anything.

         * This is a conservative estimate: could also check beta_offset

         * and more accurate chroma_qp. */

        int qp_thresh = sl->qp_thresh; // FIXME strictly we should store qp_thresh for each mb of a slice

        int qp        = h->cur_pic.qscale_table[mb_xy];

        if (qp <= qp_thresh &&

            (left_xy[LTOP] < 0 ||

             ((qp + h->cur_pic.qscale_table[left_xy[LTOP]] + 1) >> 1) <= qp_thresh) &&

            (top_xy < 0 ||

             ((qp + h->cur_pic.qscale_table[top_xy] + 1) >> 1) <= qp_thresh)) {

            if (!FRAME_MBAFF(h))

                return 1;

            if ((left_xy[LTOP] < 0 ||

                 ((qp + h->cur_pic.qscale_table[left_xy[LBOT]] + 1) >> 1) <= qp_thresh) &&

                (top_xy < h->mb_stride ||

                 ((qp + h->cur_pic.qscale_table[top_xy - h->mb_stride] + 1) >> 1) <= qp_thresh))

                return 1;

        }

    }

    top_type        = h->cur_pic.mb_type[top_xy];

    left_type[LTOP] = h->cur_pic.mb_type[left_xy[LTOP]];

    left_type[LBOT] = h->cur_pic.mb_type[left_xy[LBOT]];

    if (sl->deblocking_filter == 2) {

        if (h->slice_table[top_xy] != sl->slice_num)

            top_type = 0;

        if (h->slice_table[left_xy[LBOT]] != sl->slice_num)

            left_type[LTOP] = left_type[LBOT] = 0;

    } else {

        if (h->slice_table[top_xy] == 0xFFFF)

            top_type = 0;

        if (h->slice_table[left_xy[LBOT]] == 0xFFFF)

            left_type[LTOP] = left_type[LBOT] = 0;

    }

    sl->top_type        = top_type;

    sl->left_type[LTOP] = left_type[LTOP];

    sl->left_type[LBOT] = left_type[LBOT];

    if (IS_INTRA(mb_type))

        return 0;

    fill_filter_caches_inter(h, sl, mb_type, top_xy, left_xy,

                             top_type, left_type, mb_xy, 0);

    if (sl->list_count == 2)

        fill_filter_caches_inter(h, sl, mb_type, top_xy, left_xy,

                                 top_type, left_type, mb_xy, 1);

    nnz       = h->non_zero_count[mb_xy];

    nnz_cache = sl->non_zero_count_cache;

    AV_COPY32(&nnz_cache[4 + 8 * 1], &nnz[0]);

    AV_COPY32(&nnz_cache[4 + 8 * 2], &nnz[4]);

    AV_COPY32(&nnz_cache[4 + 8 * 3], &nnz[8]);

    AV_COPY32(&nnz_cache[4 + 8 * 4], &nnz[12]);

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

    if (top_type) {

        nnz = h->non_zero_count[top_xy];

        AV_COPY32(&nnz_cache[4 + 8 * 0], &nnz[3 * 4]);

    }

    if (left_type[LTOP]) {

        nnz = h->non_zero_count[left_xy[LTOP]];

        nnz_cache[3 + 8 * 1] = nnz[3 + 0 * 4];

        nnz_cache[3 + 8 * 2] = nnz[3 + 1 * 4];

        nnz_cache[3 + 8 * 3] = nnz[3 + 2 * 4];

        nnz_cache[3 + 8 * 4] = nnz[3 + 3 * 4];

    }

    /* CAVLC 8x8dct requires NNZ values for residual decoding that differ

     * from what the loop filter needs */

    if (!CABAC(h) && h->pps.transform_8x8_mode) {

        if (IS_8x8DCT(top_type)) {

            nnz_cache[4 + 8 * 0] =

            nnz_cache[5 + 8 * 0] = (h->cbp_table[top_xy] & 0x4000) >> 12;

            nnz_cache[6 + 8 * 0] =

            nnz_cache[7 + 8 * 0] = (h->cbp_table[top_xy] & 0x8000) >> 12;

        }

        if (IS_8x8DCT(left_type[LTOP])) {

            nnz_cache[3 + 8 * 1] =

            nnz_cache[3 + 8 * 2] = (h->cbp_table[left_xy[LTOP]] & 0x2000) >> 12; // FIXME check MBAFF

        }

        if (IS_8x8DCT(left_type[LBOT])) {

            nnz_cache[3 + 8 * 3] =

            nnz_cache[3 + 8 * 4] = (h->cbp_table[left_xy[LBOT]] & 0x8000) >> 12; // FIXME check MBAFF

        }

        if (IS_8x8DCT(mb_type)) {

            nnz_cache[scan8[0]] =

            nnz_cache[scan8[1]] =

            nnz_cache[scan8[2]] =

            nnz_cache[scan8[3]] = (sl->cbp & 0x1000) >> 12;

            nnz_cache[scan8[0 + 4]] =

            nnz_cache[scan8[1 + 4]] =

            nnz_cache[scan8[2 + 4]] =

            nnz_cache[scan8[3 + 4]] = (sl->cbp & 0x2000) >> 12;

            nnz_cache[scan8[0 + 8]] =

            nnz_cache[scan8[1 + 8]] =

            nnz_cache[scan8[2 + 8]] =

            nnz_cache[scan8[3 + 8]] = (sl->cbp & 0x4000) >> 12;

            nnz_cache[scan8[0 + 12]] =

            nnz_cache[scan8[1 + 12]] =

            nnz_cache[scan8[2 + 12]] =

            nnz_cache[scan8[3 + 12]] = (sl->cbp & 0x8000) >> 12;

        }

    }

    return 0;

}


uint64_t migrate_max_downtime(void)

{

    return max_downtime;

}


static int h264_parse(AVCodecParserContext *s,

                      AVCodecContext *avctx,

                      const uint8_t **poutbuf, int *poutbuf_size,

                      const uint8_t *buf, int buf_size)

{

    H264ParseContext *p = s->priv_data;

    ParseContext *pc = &p->pc;

    int next;

    if (!p->got_first) {

        p->got_first = 1;

        if (avctx->extradata_size) {

            ff_h264_decode_extradata(avctx->extradata, avctx->extradata_size,

                                     &p->ps, &p->is_avc, &p->nal_length_size,

                                     avctx->err_recognition, avctx);

        }

    }

    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {

        next = buf_size;

    } else {

        next = h264_find_frame_end(p, buf, buf_size, avctx);

        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {

            *poutbuf      = NULL;

            *poutbuf_size = 0;

            return buf_size;

        }

        if (next < 0 && next != END_NOT_FOUND) {

            av_assert1(pc->last_index + next >= 0);

            h264_find_frame_end(p, &pc->buffer[pc->last_index + next], -next, avctx); // update state

        }

    }

    parse_nal_units(s, avctx, buf, buf_size);

    if (avctx->framerate.num)

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

    if (p->sei.picture_timing.cpb_removal_delay >= 0) {

        s->dts_sync_point    = p->sei.buffering_period.present;

        s->dts_ref_dts_delta = p->sei.picture_timing.cpb_removal_delay;

        s->pts_dts_delta     = p->sei.picture_timing.dpb_output_delay;

    } else {

        s->dts_sync_point    = INT_MIN;

        s->dts_ref_dts_delta = INT_MIN;

        s->pts_dts_delta     = INT_MIN;

    }

    if (s->flags & PARSER_FLAG_ONCE) {

        s->flags &= PARSER_FLAG_COMPLETE_FRAMES;

    }

    if (s->dts_sync_point >= 0) {

        int64_t den = avctx->time_base.den * avctx->pkt_timebase.num;

        if (den > 0) {

            int64_t num = avctx->time_base.num * avctx->pkt_timebase.den;

            if (s->dts != AV_NOPTS_VALUE) {

                // got DTS from the stream, update reference timestamp

                p->reference_dts = s->dts - av_rescale(s->dts_ref_dts_delta, num, den);

            } else if (p->reference_dts != AV_NOPTS_VALUE) {

                // compute DTS based on reference timestamp

                s->dts = p->reference_dts + av_rescale(s->dts_ref_dts_delta, num, den);

            }

            if (p->reference_dts != AV_NOPTS_VALUE && s->pts == AV_NOPTS_VALUE)

                s->pts = s->dts + av_rescale(s->pts_dts_delta, num, den);

            if (s->dts_sync_point > 0)

                p->reference_dts = s->dts; // new reference

        }

    }

    *poutbuf      = buf;

    *poutbuf_size = buf_size;

    return next;

}


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

{

    FLVContext *flv = s->priv_data;

    int ret, i, type, size, flags;

    int stream_type=-1;

    int64_t next, pos;

    int64_t dts, pts = AV_NOPTS_VALUE;

    AVStream *st = NULL;

 for(;;avio_skip(s->pb, 4)){ /* pkt size is repeated at end. skip it */

    pos = avio_tell(s->pb);

    type = avio_r8(s->pb);

    size = avio_rb24(s->pb);

    dts = avio_rb24(s->pb);

    dts |= avio_r8(s->pb) << 24;

    av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts);

    if (url_feof(s->pb))

        return AVERROR_EOF;

    avio_skip(s->pb, 3); /* stream id, always 0 */

    flags = 0;

    if(size == 0)

        continue;

    next= size + avio_tell(s->pb);

    if (type == FLV_TAG_TYPE_AUDIO) {

        stream_type=FLV_STREAM_TYPE_AUDIO;

        flags = avio_r8(s->pb);

        size--;

    } else if (type == FLV_TAG_TYPE_VIDEO) {

        stream_type=FLV_STREAM_TYPE_VIDEO;

        flags = avio_r8(s->pb);

        size--;

        if ((flags & 0xf0) == 0x50) /* video info / command frame */

            goto skip;

    } else if (type == FLV_TAG_TYPE_META) {

        if (size > 13+1+4 && dts == 0) { // Header-type metadata stuff

            flv_read_metabody(s, next);

            goto skip;

        } else if (dts != 0) { // Script-data "special" metadata frames - don't skip

            stream_type=FLV_STREAM_TYPE_DATA;

        } else {

            goto skip;

        }

    } else {

        av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);

    skip:

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

        continue;

    }

    /* skip empty data packets */

    if (!size)

        continue;

    /* now find stream */

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

        st = s->streams[i];

        if (st->id == stream_type)

            break;

    }

    if(i == s->nb_streams){

        av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n");

        st= create_stream(s, stream_type);

        s->ctx_flags &= ~AVFMTCTX_NOHEADER;

    }

    av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard);

    if(  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO)))

       ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO)))

       || st->discard >= AVDISCARD_ALL

       ){

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

        continue;

    }

    if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY)

        av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);

    break;

 }

    // if not streamed and no duration from metadata then seek to end to find the duration from the timestamps

    if(s->pb->seekable && (!s->duration || s->duration==AV_NOPTS_VALUE)){

        int size;

        const int64_t pos= avio_tell(s->pb);

        const int64_t fsize= avio_size(s->pb);

        avio_seek(s->pb, fsize-4, SEEK_SET);

        size= avio_rb32(s->pb);

        avio_seek(s->pb, fsize-3-size, SEEK_SET);

        if(size == avio_rb24(s->pb) + 11){

            uint32_t ts = avio_rb24(s->pb);

            ts |= avio_r8(s->pb) << 24;

            s->duration = ts * (int64_t)AV_TIME_BASE / 1000;

        }

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

    }

    if(stream_type == FLV_STREAM_TYPE_AUDIO){

        if(!st->codec->channels || !st->codec->sample_rate || !st->codec->bits_per_coded_sample) {

            st->codec->channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;

            st->codec->sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3);

            st->codec->bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;

        }

        if(!st->codec->codec_id){

            flv_set_audio_codec(s, st, flags & FLV_AUDIO_CODECID_MASK);

        }

    } else if(stream_type == FLV_STREAM_TYPE_VIDEO) {

        size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK);

    }

    if (st->codec->codec_id == CODEC_ID_AAC ||

        st->codec->codec_id == CODEC_ID_H264 ||

        st->codec->codec_id == CODEC_ID_MPEG4) {

        int type = avio_r8(s->pb);

        size--;

        if (st->codec->codec_id == CODEC_ID_H264 || st->codec->codec_id == CODEC_ID_MPEG4) {

            int32_t cts = (avio_rb24(s->pb)+0xff800000)^0xff800000; // sign extension

            pts = dts + cts;

            if (cts < 0) { // dts are wrong

                flv->wrong_dts = 1;

                av_log(s, AV_LOG_WARNING, "negative cts, previous timestamps might be wrong\n");

            }

            if (flv->wrong_dts)

                dts = AV_NOPTS_VALUE;

        }

        if (type == 0) {

            if ((ret = flv_get_extradata(s, st, size)) < 0)

                return ret;

            if (st->codec->codec_id == CODEC_ID_AAC) {

                MPEG4AudioConfig cfg;

                ff_mpeg4audio_get_config(&cfg, st->codec->extradata,

                                         st->codec->extradata_size);

                st->codec->channels = cfg.channels;

                if (cfg.ext_sample_rate)

                    st->codec->sample_rate = cfg.ext_sample_rate;

                else

                    st->codec->sample_rate = cfg.sample_rate;

                av_dlog(s, "mp4a config channels %d sample rate %d\n",

                        st->codec->channels, st->codec->sample_rate);

            }

            ret = AVERROR(EAGAIN);

            goto leave;

        }

    }

    /* skip empty data packets */

    if (!size) {

        ret = AVERROR(EAGAIN);

        goto leave;

    }

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

    if (ret < 0) {

        return AVERROR(EIO);

    }

    /* note: we need to modify the packet size here to handle the last

       packet */

    pkt->size = ret;

    pkt->dts = dts;

    pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;

    pkt->stream_index = st->index;

    if (    stream_type == FLV_STREAM_TYPE_AUDIO ||

            ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) ||

            stream_type == FLV_STREAM_TYPE_DATA)

        pkt->flags |= AV_PKT_FLAG_KEY;

leave:

    avio_skip(s->pb, 4);

    return ret;

}


static void fill_note(struct memelfnote *note, const char *name, int type,

                      unsigned int sz, void *data)

{

    unsigned int namesz;

    namesz = strlen(name) + 1;

    note->name = name;

    note->namesz = namesz;

    note->namesz_rounded = roundup(namesz, sizeof (int32_t));

    note->type = type;

    note->datasz = roundup(sz, sizeof (int32_t));;

    note->data = data;

    /*

     * We calculate rounded up note size here as specified by

     * ELF document.

     */

    note->notesz = sizeof (struct elf_note) +

        note->namesz_rounded + note->datasz;

}


int bdrv_snapshot_goto(BlockDriverState *bs,

                       const char *snapshot_id)

{

    BlockDriver *drv = bs->drv;

    int ret, open_ret;

    if (!drv)

        return -ENOMEDIUM;

    if (drv->bdrv_snapshot_goto)

        return drv->bdrv_snapshot_goto(bs, snapshot_id);

    if (bs->file) {

        drv->bdrv_close(bs);

        ret = bdrv_snapshot_goto(bs->file, snapshot_id);

        open_ret = drv->bdrv_open(bs, NULL, bs->open_flags);

        if (open_ret < 0) {

            bdrv_delete(bs->file);

            bs->drv = NULL;

            return open_ret;

        }

        return ret;

    }

    return -ENOTSUP;

}


static int MPA_encode_init(AVCodecContext *avctx)

{

    MpegAudioContext *s = avctx->priv_data;

    int freq = avctx->sample_rate;

    int bitrate = avctx->bit_rate;

    int channels = avctx->channels;

    int i, v, table;

    float a;

    if (channels > 2)

        return -1;

    bitrate = bitrate / 1000;

    s->nb_channels = channels;

    s->freq = freq;

    s->bit_rate = bitrate * 1000;

    avctx->frame_size = MPA_FRAME_SIZE;

    /* encoding freq */

    s->lsf = 0;

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

        if (mpa_freq_tab[i] == freq)

            break;

        if ((mpa_freq_tab[i] / 2) == freq) {

            s->lsf = 1;

            break;

        }

    }

    if (i == 3){

        av_log(avctx, AV_LOG_ERROR, "Sampling rate %d is not allowed in mp2\n", freq);

        return -1;

    }

    s->freq_index = i;

    /* encoding bitrate & frequency */

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

        if (mpa_bitrate_tab[s->lsf][1][i] == bitrate)

            break;

    }

    if (i == 15){

        av_log(avctx, AV_LOG_ERROR, "bitrate %d is not allowed in mp2\n", bitrate);

        return -1;

    }

    s->bitrate_index = i;

    /* compute total header size & pad bit */

    a = (float)(bitrate * 1000 * MPA_FRAME_SIZE) / (freq * 8.0);

    s->frame_size = ((int)a) * 8;

    /* frame fractional size to compute padding */

    s->frame_frac = 0;

    s->frame_frac_incr = (int)((a - floor(a)) * 65536.0);

    /* select the right allocation table */

    table = l2_select_table(bitrate, s->nb_channels, freq, s->lsf);

    /* number of used subbands */

    s->sblimit = sblimit_table[table];

    s->alloc_table = alloc_tables[table];

#ifdef DEBUG

    av_log(avctx, AV_LOG_DEBUG, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n",

           bitrate, freq, s->frame_size, table, s->frame_frac_incr);

#endif

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

        s->samples_offset[i] = 0;

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

        int v;

        v = mpa_enwindow[i];

#if WFRAC_BITS != 16

        v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS);

#endif

        filter_bank[i] = v;

        if ((i & 63) != 0)

            v = -v;

        if (i != 0)

            filter_bank[512 - i] = v;

    }

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

        v = (int)(pow(2.0, (3 - i) / 3.0) * (1 << 20));

        if (v <= 0)

            v = 1;

        scale_factor_table[i] = v;

#ifdef USE_FLOATS

        scale_factor_inv_table[i] = pow(2.0, -(3 - i) / 3.0) / (float)(1 << 20);

#else

#define P 15

        scale_factor_shift[i] = 21 - P - (i / 3);

        scale_factor_mult[i] = (1 << P) * pow(2.0, (i % 3) / 3.0);

#endif

    }

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

        v = i - 64;

        if (v <= -3)

            v = 0;

        else if (v < 0)

            v = 1;

        else if (v == 0)

            v = 2;

        else if (v < 3)

            v = 3;

        else

            v = 4;

        scale_diff_table[i] = v;

    }

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

        v = quant_bits[i];

        if (v < 0)

            v = -v;

        else

            v = v * 3;

        total_quant_bits[i] = 12 * v;

    }

    avctx->coded_frame= avcodec_alloc_frame();

    avctx->coded_frame->key_frame= 1;

    return 0;

}


static void lsi_execute_script(LSIState *s)

{

    uint32_t insn;

    uint32_t addr, addr_high;

    int opcode;

    int insn_processed = 0;

    s->istat1 |= LSI_ISTAT1_SRUN;

again:

    insn_processed++;

    insn = read_dword(s, s->dsp);

    addr = read_dword(s, s->dsp + 4);

    addr_high = 0;

    DPRINTF("SCRIPTS dsp=%08x opcode %08x arg %08x\n", s->dsp, insn, addr);

    s->dsps = addr;

    s->dcmd = insn >> 24;

    s->dsp += 8;

    switch (insn >> 30) {

    case 0: /* Block move.  */

        if (s->sist1 & LSI_SIST1_STO) {

            DPRINTF("Delayed select timeout\n");

            lsi_stop_script(s);

            break;

        }

        s->dbc = insn & 0xffffff;

        s->rbc = s->dbc;

        if (insn & (1 << 29)) {

            /* Indirect addressing.  */

            addr = read_dword(s, addr);

        } else if (insn & (1 << 28)) {

            uint32_t buf[2];

            int32_t offset;

            /* Table indirect addressing.  */

            offset = sxt24(addr);

            cpu_physical_memory_read(s->dsa + offset, (uint8_t *)buf, 8);

            /* byte count is stored in bits 0:23 only */

            s->dbc = cpu_to_le32(buf[0]) & 0xffffff;

            s->rbc = s->dbc;

            addr = cpu_to_le32(buf[1]);

            /* 40-bit DMA, upper addr bits [39:32] stored in first DWORD of

             * table, bits [31:24] */

            if (lsi_dma_40bit(s))

                addr_high = cpu_to_le32(buf[0]) >> 24;

        }

        if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {

            DPRINTF("Wrong phase got %d expected %d\n",

                    s->sstat1 & PHASE_MASK, (insn >> 24) & 7);

            lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);

            break;

        }

        s->dnad = addr;

        s->dnad64 = addr_high;

        /* ??? Set ESA.  */

        s->ia = s->dsp - 8;

        switch (s->sstat1 & 0x7) {

        case PHASE_DO:

            s->waiting = 2;

            lsi_do_dma(s, 1);

            if (s->waiting)

                s->waiting = 3;

            break;

        case PHASE_DI:

            s->waiting = 2;

            s->current_dma_len = s->dbc;

            lsi_do_dma(s, 0);

            if (s->waiting)

                s->waiting = 3;

            break;

        case PHASE_CMD:

            lsi_do_command(s);

            break;

        case PHASE_ST:

            lsi_do_status(s);

            break;

        case PHASE_MO:

            lsi_do_msgout(s);

            break;

        case PHASE_MI:

            lsi_do_msgin(s);

            break;

        default:

            BADF("Unimplemented phase %d\n", s->sstat1 & PHASE_MASK);

            exit(1);

        }

        s->dfifo = s->dbc & 0xff;

        s->ctest5 = (s->ctest5 & 0xfc) | ((s->dbc >> 8) & 3);

        s->sbc = s->dbc;

        s->rbc -= s->dbc;

        s->ua = addr + s->dbc;

        break;

    case 1: /* IO or Read/Write instruction.  */

        opcode = (insn >> 27) & 7;

        if (opcode < 5) {

            uint32_t id;

            if (insn & (1 << 25)) {

                id = read_dword(s, s->dsa + sxt24(insn));

            } else {

                id = addr;

            }

            id = (id >> 16) & 0xf;

            if (insn & (1 << 26)) {

                addr = s->dsp + sxt24(addr);

            }

            s->dnad = addr;

            switch (opcode) {

            case 0: /* Select */

                s->sdid = id;

                if (s->current_dma_len && (s->ssid & 0xf) == id) {

                    DPRINTF("Already reselected by target %d\n", id);

                    break;

                }

                s->sstat0 |= LSI_SSTAT0_WOA;

                s->scntl1 &= ~LSI_SCNTL1_IARB;

                if (id >= LSI_MAX_DEVS || !s->scsi_dev[id]) {

                    DPRINTF("Selected absent target %d\n", id);

                    lsi_script_scsi_interrupt(s, 0, LSI_SIST1_STO);

                    lsi_disconnect(s);

                    break;

                }

                DPRINTF("Selected target %d%s\n",

                        id, insn & (1 << 3) ? " ATN" : "");

                /* ??? Linux drivers compain when this is set.  Maybe

                   it only applies in low-level mode (unimplemented).

                lsi_script_scsi_interrupt(s, LSI_SIST0_CMP, 0); */

                s->current_dev = s->scsi_dev[id];

                s->current_tag = id << 8;

                s->scntl1 |= LSI_SCNTL1_CON;

                if (insn & (1 << 3)) {

                    s->socl |= LSI_SOCL_ATN;

                }

                lsi_set_phase(s, PHASE_MO);

                break;

            case 1: /* Disconnect */

                DPRINTF("Wait Disconect\n");

                s->scntl1 &= ~LSI_SCNTL1_CON;

                break;

            case 2: /* Wait Reselect */

                lsi_wait_reselect(s);

                break;

            case 3: /* Set */

                DPRINTF("Set%s%s%s%s\n",

                        insn & (1 << 3) ? " ATN" : "",

                        insn & (1 << 6) ? " ACK" : "",

                        insn & (1 << 9) ? " TM" : "",

                        insn & (1 << 10) ? " CC" : "");

                if (insn & (1 << 3)) {

                    s->socl |= LSI_SOCL_ATN;

                    lsi_set_phase(s, PHASE_MO);

                }

                if (insn & (1 << 9)) {

                    BADF("Target mode not implemented\n");

                    exit(1);

                }

                if (insn & (1 << 10))

                    s->carry = 1;

                break;

            case 4: /* Clear */

                DPRINTF("Clear%s%s%s%s\n",

                        insn & (1 << 3) ? " ATN" : "",

                        insn & (1 << 6) ? " ACK" : "",

                        insn & (1 << 9) ? " TM" : "",

                        insn & (1 << 10) ? " CC" : "");

                if (insn & (1 << 3)) {

                    s->socl &= ~LSI_SOCL_ATN;

                }

                if (insn & (1 << 10))

                    s->carry = 0;

                break;

            }

        } else {

            uint8_t op0;

            uint8_t op1;

            uint8_t data8;

            int reg;

            int operator;

#ifdef DEBUG_LSI

            static const char *opcode_names[3] =

                {"Write", "Read", "Read-Modify-Write"};

            static const char *operator_names[8] =

                {"MOV", "SHL", "OR", "XOR", "AND", "SHR", "ADD", "ADC"};

#endif

            reg = ((insn >> 16) & 0x7f) | (insn & 0x80);

            data8 = (insn >> 8) & 0xff;

            opcode = (insn >> 27) & 7;

            operator = (insn >> 24) & 7;

            DPRINTF("%s reg 0x%x %s data8=0x%02x sfbr=0x%02x%s\n",

                    opcode_names[opcode - 5], reg,

                    operator_names[operator], data8, s->sfbr,

                    (insn & (1 << 23)) ? " SFBR" : "");

            op0 = op1 = 0;

            switch (opcode) {

            case 5: /* From SFBR */

                op0 = s->sfbr;

                op1 = data8;

                break;

            case 6: /* To SFBR */

                if (operator)

                    op0 = lsi_reg_readb(s, reg);

                op1 = data8;

                break;

            case 7: /* Read-modify-write */

                if (operator)

                    op0 = lsi_reg_readb(s, reg);

                if (insn & (1 << 23)) {

                    op1 = s->sfbr;

                } else {

                    op1 = data8;

                }

                break;

            }

            switch (operator) {

            case 0: /* move */

                op0 = op1;

                break;

            case 1: /* Shift left */

                op1 = op0 >> 7;

                op0 = (op0 << 1) | s->carry;

                s->carry = op1;

                break;

            case 2: /* OR */

                op0 |= op1;

                break;

            case 3: /* XOR */

                op0 ^= op1;

                break;

            case 4: /* AND */

                op0 &= op1;

                break;

            case 5: /* SHR */

                op1 = op0 & 1;

                op0 = (op0 >> 1) | (s->carry << 7);

                s->carry = op1;

                break;

            case 6: /* ADD */

                op0 += op1;

                s->carry = op0 < op1;

                break;

            case 7: /* ADC */

                op0 += op1 + s->carry;

                if (s->carry)

                    s->carry = op0 <= op1;

                else

                    s->carry = op0 < op1;

                break;

            }

            switch (opcode) {

            case 5: /* From SFBR */

            case 7: /* Read-modify-write */

                lsi_reg_writeb(s, reg, op0);

                break;

            case 6: /* To SFBR */

                s->sfbr = op0;

                break;

            }

        }

        break;

    case 2: /* Transfer Control.  */

        {

            int cond;

            int jmp;

            if ((insn & 0x002e0000) == 0) {

                DPRINTF("NOP\n");

                break;

            }

            if (s->sist1 & LSI_SIST1_STO) {

                DPRINTF("Delayed select timeout\n");

                lsi_stop_script(s);

                break;

            }

            cond = jmp = (insn & (1 << 19)) != 0;

            if (cond == jmp && (insn & (1 << 21))) {

                DPRINTF("Compare carry %d\n", s->carry == jmp);

                cond = s->carry != 0;

            }

            if (cond == jmp && (insn & (1 << 17))) {

                DPRINTF("Compare phase %d %c= %d\n",

                        (s->sstat1 & PHASE_MASK),

                        jmp ? '=' : '!',

                        ((insn >> 24) & 7));

                cond = (s->sstat1 & PHASE_MASK) == ((insn >> 24) & 7);

            }

            if (cond == jmp && (insn & (1 << 18))) {

                uint8_t mask;

                mask = (~insn >> 8) & 0xff;

                DPRINTF("Compare data 0x%x & 0x%x %c= 0x%x\n",

                        s->sfbr, mask, jmp ? '=' : '!', insn & mask);

                cond = (s->sfbr & mask) == (insn & mask);

            }

            if (cond == jmp) {

                if (insn & (1 << 23)) {

                    /* Relative address.  */

                    addr = s->dsp + sxt24(addr);

                }

                switch ((insn >> 27) & 7) {

                case 0: /* Jump */

                    DPRINTF("Jump to 0x%08x\n", addr);

                    s->dsp = addr;

                    break;

                case 1: /* Call */

                    DPRINTF("Call 0x%08x\n", addr);

                    s->temp = s->dsp;

                    s->dsp = addr;

                    break;

                case 2: /* Return */

                    DPRINTF("Return to 0x%08x\n", s->temp);

                    s->dsp = s->temp;

                    break;

                case 3: /* Interrupt */

                    DPRINTF("Interrupt 0x%08x\n", s->dsps);

                    if ((insn & (1 << 20)) != 0) {

                        s->istat0 |= LSI_ISTAT0_INTF;

                        lsi_update_irq(s);

                    } else {

                        lsi_script_dma_interrupt(s, LSI_DSTAT_SIR);

                    }

                    break;

                default:

                    DPRINTF("Illegal transfer control\n");

                    lsi_script_dma_interrupt(s, LSI_DSTAT_IID);

                    break;

                }

            } else {

                DPRINTF("Control condition failed\n");

            }

        }

        break;

    case 3:

        if ((insn & (1 << 29)) == 0) {

            /* Memory move.  */

            uint32_t dest;

            /* ??? The docs imply the destination address is loaded into

               the TEMP register.  However the Linux drivers rely on

               the value being presrved.  */

            dest = read_dword(s, s->dsp);

            s->dsp += 4;

            lsi_memcpy(s, dest, addr, insn & 0xffffff);

        } else {

            uint8_t data[7];

            int reg;

            int n;

            int i;

            if (insn & (1 << 28)) {

                addr = s->dsa + sxt24(addr);

            }

            n = (insn & 7);

            reg = (insn >> 16) & 0xff;

            if (insn & (1 << 24)) {

                cpu_physical_memory_read(addr, data, n);

                DPRINTF("Load reg 0x%x size %d addr 0x%08x = %08x\n", reg, n,

                        addr, *(int *)data);

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

                    lsi_reg_writeb(s, reg + i, data[i]);

                }

            } else {

                DPRINTF("Store reg 0x%x size %d addr 0x%08x\n", reg, n, addr);

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

                    data[i] = lsi_reg_readb(s, reg + i);

                }

                cpu_physical_memory_write(addr, data, n);

            }

        }

    }

    if (insn_processed > 10000 && !s->waiting) {

        /* Some windows drivers make the device spin waiting for a memory

           location to change.  If we have been executed a lot of code then

           assume this is the case and force an unexpected device disconnect.

           This is apparently sufficient to beat the drivers into submission.

         */

        if (!(s->sien0 & LSI_SIST0_UDC))

            fprintf(stderr, "inf. loop with UDC masked\n");

        lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);

        lsi_disconnect(s);

    } else if (s->istat1 & LSI_ISTAT1_SRUN && !s->waiting) {

        if (s->dcntl & LSI_DCNTL_SSM) {

            lsi_script_dma_interrupt(s, LSI_DSTAT_SSI);

        } else {

            goto again;

        }

    }

    DPRINTF("SCRIPTS execution stopped\n");

}


static void kqemu_update_cpuid(CPUState *env)

{

    int critical_features_mask, features, ext_features, ext_features_mask;

    uint32_t eax, ebx, ecx, edx;

    /* the following features are kept identical on the host and

       target cpus because they are important for user code. Strictly

       speaking, only SSE really matters because the OS must support

       it if the user code uses it. */

    critical_features_mask =

        CPUID_CMOV | CPUID_CX8 |

        CPUID_FXSR | CPUID_MMX | CPUID_SSE |

        CPUID_SSE2 | CPUID_SEP;

    ext_features_mask = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR;

    if (!is_cpuid_supported()) {

        features = 0;

        ext_features = 0;

    } else {

        cpuid(1, eax, ebx, ecx, edx);

        features = edx;

        ext_features = ecx;

    }

#ifdef __x86_64__

    /* NOTE: on x86_64 CPUs, SYSENTER is not supported in

       compatibility mode, so in order to have the best performances

       it is better not to use it */

    features &= ~CPUID_SEP;

#endif

    env->cpuid_features = (env->cpuid_features & ~critical_features_mask) |

        (features & critical_features_mask);

    env->cpuid_ext_features = (env->cpuid_ext_features & ~ext_features_mask) |

        (ext_features & ext_features_mask);

    /* XXX: we could update more of the target CPUID state so that the

       non accelerated code sees exactly the same CPU features as the

       accelerated code */

}


static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList **listp,

                                           size_t size)

{

    GenericList *list = *listp;

    QapiDeallocVisitor *qov = to_qov(v);

    StackEntry *e = QTAILQ_FIRST(&qov->stack);

    if (e && e->is_list_head) {

        e->is_list_head = false;

        return list;

    }

    if (list) {

        list = list->next;

        g_free(*listp);

        return list;

    }

    return NULL;

}


static void qbool_destroy_obj(QObject *obj)

{

    assert(obj != NULL);

    g_free(qobject_to_qbool(obj));

}


static void frame_thread_free(AVCodecContext *avctx, int thread_count)

{

    FrameThreadContext *fctx = avctx->thread_opaque;

    AVCodec *codec = avctx->codec;

    int i;

    park_frame_worker_threads(fctx, thread_count);

    if (fctx->prev_thread)

        update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0);

    fctx->die = 1;

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

        PerThreadContext *p = &fctx->threads[i];

        pthread_mutex_lock(&p->mutex);

        pthread_cond_signal(&p->input_cond);

        pthread_mutex_unlock(&p->mutex);

        pthread_join(p->thread, NULL);

        if (codec->close)

            codec->close(p->avctx);

        avctx->codec = NULL;

        release_delayed_buffers(p);

    }

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

        PerThreadContext *p = &fctx->threads[i];

        avcodec_default_free_buffers(p->avctx);

        pthread_mutex_destroy(&p->mutex);

        pthread_mutex_destroy(&p->progress_mutex);

        pthread_cond_destroy(&p->input_cond);

        pthread_cond_destroy(&p->progress_cond);

        pthread_cond_destroy(&p->output_cond);

        av_freep(&p->avpkt.data);

        if (i)

            av_freep(&p->avctx->priv_data);

        av_freep(&p->avctx);

    }

    av_freep(&fctx->threads);

    pthread_mutex_destroy(&fctx->buffer_mutex);

    av_freep(&avctx->thread_opaque);

}


static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)

{

    QemuOpt *opt;

    TAILQ_FOREACH(opt, &opts->head, next) {

        if (strcmp(opt->name, name) != 0)

            continue;

        return opt;

    }

    return NULL;

}


uint64_t helper_cmptun (uint64_t a, uint64_t b)

{

    float64 fa, fb;

    fa = t_to_float64(a);

    fb = t_to_float64(b);

    if (float64_is_quiet_nan(fa) || float64_is_quiet_nan(fb))

        return 0x4000000000000000ULL;

    else

        return 0;

}