static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)

{

    DisasContext *dc = container_of(dcbase, DisasContext, base);

    if (dc->base.tb->cflags & CF_LAST_IO && dc->condjmp) {

        /* FIXME: This can theoretically happen with self-modifying code. */

        cpu_abort(cpu, "IO on conditional branch instruction");

    }

    /* At this stage dc->condjmp will only be set when the skipped

       instruction was a conditional branch or trap, and the PC has

       already been written.  */

    gen_set_condexec(dc);

    if (dc->base.is_jmp == DISAS_BX_EXCRET) {

        /* Exception return branches need some special case code at the

         * end of the TB, which is complex enough that it has to

         * handle the single-step vs not and the condition-failed

         * insn codepath itself.

         */

        gen_bx_excret_final_code(dc);

    } else if (unlikely(is_singlestepping(dc))) {

        /* Unconditional and "condition passed" instruction codepath. */

        switch (dc->base.is_jmp) {

        case DISAS_SWI:

            gen_ss_advance(dc);

            gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),

                          default_exception_el(dc));

            break;

        case DISAS_HVC:

            gen_ss_advance(dc);

            gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);

            break;

        case DISAS_SMC:

            gen_ss_advance(dc);

            gen_exception(EXCP_SMC, syn_aa32_smc(), 3);

            break;

        case DISAS_NEXT:

        case DISAS_TOO_MANY:

        case DISAS_UPDATE:

            gen_set_pc_im(dc, dc->pc);

            /* fall through */

        default:

            /* FIXME: Single stepping a WFI insn will not halt the CPU. */

            gen_singlestep_exception(dc);

            break;

        case DISAS_NORETURN:

            break;

        }

    } else {

        /* While branches must always occur at the end of an IT block,

           there are a few other things that can cause us to terminate

           the TB in the middle of an IT block:

            - Exception generating instructions (bkpt, swi, undefined).

            - Page boundaries.

            - Hardware watchpoints.

           Hardware breakpoints have already been handled and skip this code.

         */

        switch(dc->base.is_jmp) {

        case DISAS_NEXT:

        case DISAS_TOO_MANY:

            gen_goto_tb(dc, 1, dc->pc);

            break;

        case DISAS_JUMP:

            gen_goto_ptr();

            break;

        case DISAS_UPDATE:

            gen_set_pc_im(dc, dc->pc);

            /* fall through */

        default:

            /* indicate that the hash table must be used to find the next TB */

            tcg_gen_exit_tb(0);

            break;

        case DISAS_NORETURN:

            /* nothing more to generate */

            break;

        case DISAS_WFI:

            gen_helper_wfi(cpu_env);

            /* The helper doesn't necessarily throw an exception, but we

             * must go back to the main loop to check for interrupts anyway.

             */

            tcg_gen_exit_tb(0);

            break;

        case DISAS_WFE:

            gen_helper_wfe(cpu_env);

            break;

        case DISAS_YIELD:

            gen_helper_yield(cpu_env);

            break;

        case DISAS_SWI:

            gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),

                          default_exception_el(dc));

            break;

        case DISAS_HVC:

            gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);

            break;

        case DISAS_SMC:

            gen_exception(EXCP_SMC, syn_aa32_smc(), 3);

            break;

        }

    }

    if (dc->condjmp) {

        /* "Condition failed" instruction codepath for the branch/trap insn */

        gen_set_label(dc->condlabel);

        gen_set_condexec(dc);

        if (unlikely(is_singlestepping(dc))) {

            gen_set_pc_im(dc, dc->pc);

            gen_singlestep_exception(dc);

        } else {

            gen_goto_tb(dc, 1, dc->pc);

        }

    }

    /* Functions above can change dc->pc, so re-align db->pc_next */

    dc->base.pc_next = dc->pc;

}


void pcmcia_info(Monitor *mon, const QDict *qdict)

{

    struct pcmcia_socket_entry_s *iter;

    if (!pcmcia_sockets)

        monitor_printf(mon, "No PCMCIA sockets\n");

    for (iter = pcmcia_sockets; iter; iter = iter->next)

        monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,

                       iter->socket->attached ? iter->socket->card_string :

                       "Empty");

}


static void ahci_reg_init(AHCIState *s)

{

    int i;

    s->control_regs.cap = (s->ports - 1) |

                          (AHCI_NUM_COMMAND_SLOTS << 8) |

                          (AHCI_SUPPORTED_SPEED_GEN1 << AHCI_SUPPORTED_SPEED) |

                          HOST_CAP_NCQ | HOST_CAP_AHCI;

    s->control_regs.impl = (1 << s->ports) - 1;

    s->control_regs.version = AHCI_VERSION_1_0;

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

        s->dev[i].port_state = STATE_RUN;

    }

}


static void virtio_crypto_get_config(VirtIODevice *vdev, uint8_t *config)

{

    VirtIOCrypto *c = VIRTIO_CRYPTO(vdev);

    struct virtio_crypto_config crypto_cfg;

    /*

     * Virtio-crypto device conforms to VIRTIO 1.0 which is always LE,

     * so we can use LE accessors directly.

     */

    stl_le_p(&crypto_cfg.status, c->status);

    stl_le_p(&crypto_cfg.max_dataqueues, c->max_queues);

    stl_le_p(&crypto_cfg.crypto_services, c->conf.crypto_services);

    stl_le_p(&crypto_cfg.cipher_algo_l, c->conf.cipher_algo_l);

    stl_le_p(&crypto_cfg.cipher_algo_h, c->conf.cipher_algo_h);

    stl_le_p(&crypto_cfg.hash_algo, c->conf.hash_algo);

    stl_le_p(&crypto_cfg.mac_algo_l, c->conf.mac_algo_l);

    stl_le_p(&crypto_cfg.mac_algo_h, c->conf.mac_algo_h);

    stl_le_p(&crypto_cfg.aead_algo, c->conf.aead_algo);

    stl_le_p(&crypto_cfg.max_cipher_key_len, c->conf.max_cipher_key_len);

    stl_le_p(&crypto_cfg.max_auth_key_len, c->conf.max_auth_key_len);

    stq_le_p(&crypto_cfg.max_size, c->conf.max_size);

    memcpy(config, &crypto_cfg, c->config_size);

}


static int flac_probe(AVProbeData *p)

{

    uint8_t *bufptr = p->buf;

    uint8_t *end    = p->buf + p->buf_size;

    if(bufptr > end-4 || memcmp(bufptr, "fLaC", 4)) return 0;

    else                                            return AVPROBE_SCORE_MAX/2;

}


static int get_qcd(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q,
                   uint8_t *properties)
{
    Jpeg2000QuantStyle tmp;
    int compno, ret;
    if ((ret = get_qcx(s, n, &tmp)) < 0)
        return ret;
    for (compno = 0; compno < s->ncomponents; compno++)
        if (!(properties[compno] & HAD_QCC))
            memcpy(q + compno, &tmp, sizeof(tmp));
    return 0;
}


void slirp_init(int restricted, struct in_addr vnetwork,

                struct in_addr vnetmask, struct in_addr vhost,

                const char *vhostname, const char *tftp_path,

                const char *bootfile, struct in_addr vdhcp_start,

                struct in_addr vnameserver)

{

#ifdef _WIN32

    WSADATA Data;

    WSAStartup(MAKEWORD(2,0), &Data);

    atexit(slirp_cleanup);

#endif

    link_up = 1;

    slirp_restrict = restricted;

    if_init();

    ip_init();

    /* Initialise mbufs *after* setting the MTU */

    m_init();

    /* set default addresses */

    inet_aton("127.0.0.1", &loopback_addr);

    if (get_dns_addr(&dns_addr) < 0) {

        dns_addr = loopback_addr;

        fprintf (stderr, "Warning: No DNS servers found\n");

    }

    vnetwork_addr = vnetwork;

    vnetwork_mask = vnetmask;

    vhost_addr = vhost;

    if (vhostname) {

        pstrcpy(slirp_hostname, sizeof(slirp_hostname), vhostname);

    }

    qemu_free(tftp_prefix);

    tftp_prefix = NULL;

    if (tftp_path) {

        tftp_prefix = qemu_strdup(tftp_path);

    }

    qemu_free(bootp_filename);

    bootp_filename = NULL;

    if (bootfile) {

        bootp_filename = qemu_strdup(bootfile);

    }

    vdhcp_startaddr = vdhcp_start;

    vnameserver_addr = vnameserver;

    getouraddr();

    register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL);

}


void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features)

{

    int i, config_size = 0;

    for (i = 0; feature_sizes[i].flags != 0; i++) {

        if (host_features & feature_sizes[i].flags) {

            config_size = MAX(feature_sizes[i].end, config_size);

        }

    }

    n->config_size = config_size;

}


qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,

                        qemu_irq **irqs, qemu_irq irq_out)

{

    openpic_t *opp;

    uint8_t *pci_conf;

    int i, m;

    /* XXX: for now, only one CPU is supported */

    if (nb_cpus != 1)

        return NULL;

    if (bus) {

        opp = (openpic_t *)pci_register_device(bus, "OpenPIC", sizeof(openpic_t),

                                               -1, NULL, NULL);

        if (opp == NULL)

            return NULL;

        pci_conf = opp->pci_dev.config;

        pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_IBM);

        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_IBM_OPENPIC2);

        pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); // FIXME?

        pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type

        pci_conf[0x3d] = 0x00; // no interrupt pin

        /* Register I/O spaces */

        pci_register_bar((PCIDevice *)opp, 0, 0x40000,

                               PCI_BASE_ADDRESS_SPACE_MEMORY, &openpic_map);

    } else {

        opp = qemu_mallocz(sizeof(openpic_t));

    }

    opp->mem_index = cpu_register_io_memory(openpic_read,

                                            openpic_write, opp);

    //    isu_base &= 0xFFFC0000;

    opp->nb_cpus = nb_cpus;

    opp->max_irq = OPENPIC_MAX_IRQ;

    opp->irq_ipi0 = OPENPIC_IRQ_IPI0;

    opp->irq_tim0 = OPENPIC_IRQ_TIM0;

    /* Set IRQ types */

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

        opp->src[i].type = IRQ_EXTERNAL;

    }

    for (; i < OPENPIC_IRQ_TIM0; i++) {

        opp->src[i].type = IRQ_SPECIAL;

    }

#if MAX_IPI > 0

    m = OPENPIC_IRQ_IPI0;

#else

    m = OPENPIC_IRQ_DBL0;

#endif

    for (; i < m; i++) {

        opp->src[i].type = IRQ_TIMER;

    }

    for (; i < OPENPIC_MAX_IRQ; i++) {

        opp->src[i].type = IRQ_INTERNAL;

    }

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

        opp->dst[i].irqs = irqs[i];

    opp->irq_out = irq_out;

    opp->need_swap = 1;

    register_savevm("openpic", 0, 2, openpic_save, openpic_load, opp);

    qemu_register_reset(openpic_reset, opp);

    opp->irq_raise = openpic_irq_raise;

    opp->reset = openpic_reset;

    if (pmem_index)

        *pmem_index = opp->mem_index;

    return qemu_allocate_irqs(openpic_set_irq, opp, opp->max_irq);

}


static int decode_fctl_chunk(AVCodecContext *avctx, PNGDecContext *s,

                             uint32_t length)

{

    uint32_t sequence_number;

    if (length != 26)

        return AVERROR_INVALIDDATA;

    if (!(s->state & PNG_IHDR)) {

        av_log(avctx, AV_LOG_ERROR, "fctl before IHDR\n");

        return AVERROR_INVALIDDATA;

    }

    s->last_w = s->cur_w;

    s->last_h = s->cur_h;

    s->last_x_offset = s->x_offset;

    s->last_y_offset = s->y_offset;

    s->last_dispose_op = s->dispose_op;

    sequence_number = bytestream2_get_be32(&s->gb);

    s->cur_w        = bytestream2_get_be32(&s->gb);

    s->cur_h        = bytestream2_get_be32(&s->gb);

    s->x_offset     = bytestream2_get_be32(&s->gb);

    s->y_offset     = bytestream2_get_be32(&s->gb);

    bytestream2_skip(&s->gb, 4); /* delay_num (2), delay_den (2) */

    s->dispose_op   = bytestream2_get_byte(&s->gb);

    s->blend_op     = bytestream2_get_byte(&s->gb);

    bytestream2_skip(&s->gb, 4); /* crc */

    if (sequence_number == 0 &&

        (s->cur_w != s->width ||

         s->cur_h != s->height ||

         s->x_offset != 0 ||

         s->y_offset != 0) ||

        s->cur_w <= 0 || s->cur_h <= 0 ||

        s->x_offset < 0 || s->y_offset < 0 ||

        s->cur_w > s->width - s->x_offset|| s->cur_h > s->height - s->y_offset)

            return AVERROR_INVALIDDATA;

    if (sequence_number == 0 && s->dispose_op == APNG_DISPOSE_OP_PREVIOUS) {

        // No previous frame to revert to for the first frame

        // Spec says to just treat it as a APNG_DISPOSE_OP_BACKGROUND

        s->dispose_op = APNG_DISPOSE_OP_BACKGROUND;

    }

    if (s->dispose_op == APNG_BLEND_OP_OVER && !s->has_trns && (

            avctx->pix_fmt == AV_PIX_FMT_RGB24 ||

            avctx->pix_fmt == AV_PIX_FMT_RGB48BE ||

            avctx->pix_fmt == AV_PIX_FMT_PAL8 ||

            avctx->pix_fmt == AV_PIX_FMT_GRAY8 ||

            avctx->pix_fmt == AV_PIX_FMT_GRAY16BE ||

            avctx->pix_fmt == AV_PIX_FMT_MONOBLACK

        )) {

        // APNG_DISPOSE_OP_OVER is the same as APNG_DISPOSE_OP_SOURCE when there is no alpha channel

        s->dispose_op = APNG_BLEND_OP_SOURCE;

    }

    return 0;

}


int ff_h264_build_ref_list(H264Context *h, H264SliceContext *sl)

{

    int list, index, pic_structure;

    print_short_term(h);

    print_long_term(h);

    h264_initialise_ref_list(h, sl);

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

        int pred = sl->curr_pic_num;

        for (index = 0; index < sl->nb_ref_modifications[list]; index++) {

            unsigned int modification_of_pic_nums_idc = sl->ref_modifications[list][index].op;

            unsigned int                          val = sl->ref_modifications[list][index].val;

            unsigned int pic_id;

            int i;

            H264Picture *ref = NULL;

            switch (modification_of_pic_nums_idc) {

            case 0:

            case 1: {

                const unsigned int abs_diff_pic_num = val + 1;

                int frame_num;

                if (abs_diff_pic_num > sl->max_pic_num) {

                    av_log(h->avctx, AV_LOG_ERROR,

                           "abs_diff_pic_num overflow\n");

                    return AVERROR_INVALIDDATA;

                }

                if (modification_of_pic_nums_idc == 0)

                    pred -= abs_diff_pic_num;

                else

                    pred += abs_diff_pic_num;

                pred &= sl->max_pic_num - 1;

                frame_num = pic_num_extract(h, pred, &pic_structure);

                for (i = h->short_ref_count - 1; i >= 0; i--) {

                    ref = h->short_ref[i];

                    assert(ref->reference);

                    assert(!ref->long_ref);

                    if (ref->frame_num == frame_num &&

                        (ref->reference & pic_structure))

                        break;

                }

                if (i >= 0)

                    ref->pic_id = pred;

                break;

            }

            case 2: {

                int long_idx;

                pic_id = val; // long_term_pic_idx

                long_idx = pic_num_extract(h, pic_id, &pic_structure);

                if (long_idx > 31U) {

                    av_log(h->avctx, AV_LOG_ERROR,

                           "long_term_pic_idx overflow\n");

                    return AVERROR_INVALIDDATA;

                }

                ref = h->long_ref[long_idx];

                assert(!(ref && !ref->reference));

                if (ref && (ref->reference & pic_structure)) {

                    ref->pic_id = pic_id;

                    assert(ref->long_ref);

                    i = 0;

                } else {

                    i = -1;

                }

                break;

            }

            default:

                av_assert1(0);

            }

            if (i < 0) {

                av_log(h->avctx, AV_LOG_ERROR,

                       "reference picture missing during reorder\n");

                memset(&sl->ref_list[list][index], 0, sizeof(sl->ref_list[0][0])); // FIXME

            } else {

                for (i = index; i + 1 < sl->ref_count[list]; i++) {

                    if (sl->ref_list[list][i].parent &&

                        ref->long_ref == sl->ref_list[list][i].parent->long_ref &&

                        ref->pic_id   == sl->ref_list[list][i].pic_id)

                        break;

                }

                for (; i > index; i--) {

                    sl->ref_list[list][i] = sl->ref_list[list][i - 1];

                }

                ref_from_h264pic(&sl->ref_list[list][index], ref);

                if (FIELD_PICTURE(h)) {

                    pic_as_field(&sl->ref_list[list][index], pic_structure);

                }

            }

        }

    }

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

        for (index = 0; index < sl->ref_count[list]; index++) {

            if (   !sl->ref_list[list][index].parent

                || (!FIELD_PICTURE(h) && (sl->ref_list[list][index].reference&3) != 3)) {

                int i;

                av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref[list].poc);

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

                    h->last_pocs[i] = INT_MIN;

                if (h->default_ref[list].parent

                    && !(!FIELD_PICTURE(h) && (h->default_ref[list].reference&3) != 3))

                    sl->ref_list[list][index] = h->default_ref[list];

                else

                    return -1;

            }

            av_assert0(av_buffer_get_ref_count(sl->ref_list[list][index].parent->f->buf[0]) > 0);

        }

    }

    if (FRAME_MBAFF(h))

        h264_fill_mbaff_ref_list(sl);

    return 0;

}


int check_hw_breakpoints(CPUX86State *env, int force_dr6_update)

{

    target_ulong dr6;

    int reg, type;

    int hit_enabled = 0;

    dr6 = env->dr[6] & ~0xf;

    for (reg = 0; reg < DR7_MAX_BP; reg++) {

        type = hw_breakpoint_type(env->dr[7], reg);

        if ((type == 0 && env->dr[reg] == env->eip) ||

            ((type & 1) && env->cpu_watchpoint[reg] &&

             (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {

            dr6 |= 1 << reg;

            if (hw_breakpoint_enabled(env->dr[7], reg)) {

                hit_enabled = 1;

            }

        }

    }

    if (hit_enabled || force_dr6_update)

        env->dr[6] = dr6;

    return hit_enabled;

}


void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)

{

    c->frames= frame_offset;

    if (c->ach)

        c->abytes= av_rescale_q(c->frames, c->sys->time_base,

                                (AVRational){8, c->ast[0]->codec->bit_rate});

    c->audio_pkt[0].size = c->audio_pkt[1].size = 0;

    c->audio_pkt[2].size = c->audio_pkt[3].size = 0;

}


static int process_ipmovie_chunk(IPMVEContext *s, ByteIOContext *pb,

    AVPacket *pkt)

{

    unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE];

    int chunk_type;

    int chunk_size;

    unsigned char opcode_preamble[OPCODE_PREAMBLE_SIZE];

    unsigned char opcode_type;

    unsigned char opcode_version;

    int opcode_size;

    unsigned char scratch[1024];

    int i, j;

    int first_color, last_color;

    int audio_flags;

    unsigned char r, g, b;

    /* see if there are any pending packets */

    chunk_type = load_ipmovie_packet(s, pb, pkt);

    if ((chunk_type == CHUNK_VIDEO) && (chunk_type != CHUNK_DONE))

        return chunk_type;

    /* read the next chunk, wherever the file happens to be pointing */

    if (url_feof(pb))

        return CHUNK_EOF;

    if (get_buffer(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) !=

        CHUNK_PREAMBLE_SIZE)

        return CHUNK_BAD;

    chunk_size = AV_RL16(&chunk_preamble[0]);

    chunk_type = AV_RL16(&chunk_preamble[2]);

    debug_ipmovie("chunk type 0x%04X, 0x%04X bytes: ", chunk_type, chunk_size);

    switch (chunk_type) {

    case CHUNK_INIT_AUDIO:

        debug_ipmovie("initialize audio\n");

        break;

    case CHUNK_AUDIO_ONLY:

        debug_ipmovie("audio only\n");

        break;

    case CHUNK_INIT_VIDEO:

        debug_ipmovie("initialize video\n");

        break;

    case CHUNK_VIDEO:

        debug_ipmovie("video (and audio)\n");

        break;

    case CHUNK_SHUTDOWN:

        debug_ipmovie("shutdown\n");

        break;

    case CHUNK_END:

        debug_ipmovie("end\n");

        break;

    default:

        debug_ipmovie("invalid chunk\n");

        chunk_type = CHUNK_BAD;

        break;

    }

    while ((chunk_size > 0) && (chunk_type != CHUNK_BAD)) {

        /* read the next chunk, wherever the file happens to be pointing */

       if (url_feof(pb)) {

            chunk_type = CHUNK_EOF;

            break;

        }

        if (get_buffer(pb, opcode_preamble, CHUNK_PREAMBLE_SIZE) !=

            CHUNK_PREAMBLE_SIZE) {

            chunk_type = CHUNK_BAD;

            break;

        }

        opcode_size = AV_RL16(&opcode_preamble[0]);

        opcode_type = opcode_preamble[2];

        opcode_version = opcode_preamble[3];

        chunk_size -= OPCODE_PREAMBLE_SIZE;

        chunk_size -= opcode_size;

        if (chunk_size < 0) {

            debug_ipmovie("chunk_size countdown just went negative\n");

            chunk_type = CHUNK_BAD;

            break;

        }

        debug_ipmovie("  opcode type %02X, version %d, 0x%04X bytes: ",

            opcode_type, opcode_version, opcode_size);

        switch (opcode_type) {

        case OPCODE_END_OF_STREAM:

            debug_ipmovie("end of stream\n");

            url_fseek(pb, opcode_size, SEEK_CUR);

            break;

        case OPCODE_END_OF_CHUNK:

            debug_ipmovie("end of chunk\n");

            url_fseek(pb, opcode_size, SEEK_CUR);

            break;

        case OPCODE_CREATE_TIMER:

            debug_ipmovie("create timer\n");

            if ((opcode_version > 0) || (opcode_size > 6)) {

                debug_ipmovie("bad create_timer opcode\n");

                chunk_type = CHUNK_BAD;

                break;

            }

            if (get_buffer(pb, scratch, opcode_size) !=

                opcode_size) {

                chunk_type = CHUNK_BAD;

                break;

            }

            s->fps = 1000000.0 / (AV_RL32(&scratch[0]) * AV_RL16(&scratch[4]));

            s->frame_pts_inc = 90000 / s->fps;

            debug_ipmovie("  %.2f frames/second (timer div = %d, subdiv = %d)\n",

                s->fps, AV_RL32(&scratch[0]), AV_RL16(&scratch[4]));

            break;

        case OPCODE_INIT_AUDIO_BUFFERS:

            debug_ipmovie("initialize audio buffers\n");

            if ((opcode_version > 1) || (opcode_size > 10)) {

                debug_ipmovie("bad init_audio_buffers opcode\n");

                chunk_type = CHUNK_BAD;

                break;

            }

            if (get_buffer(pb, scratch, opcode_size) !=

                opcode_size) {

                chunk_type = CHUNK_BAD;

                break;

            }

            s->audio_sample_rate = AV_RL16(&scratch[4]);

            audio_flags = AV_RL16(&scratch[2]);

            /* bit 0 of the flags: 0 = mono, 1 = stereo */

            s->audio_channels = (audio_flags & 1) + 1;

            /* bit 1 of the flags: 0 = 8 bit, 1 = 16 bit */

            s->audio_bits = (((audio_flags >> 1) & 1) + 1) * 8;

            /* bit 2 indicates compressed audio in version 1 opcode */

            if ((opcode_version == 1) && (audio_flags & 0x4))

                s->audio_type = CODEC_ID_INTERPLAY_DPCM;

            else if (s->audio_bits == 16)

                s->audio_type = CODEC_ID_PCM_S16LE;

            else

                s->audio_type = CODEC_ID_PCM_U8;

            debug_ipmovie("audio: %d bits, %d Hz, %s, %s format\n",

                s->audio_bits,

                s->audio_sample_rate,

                (s->audio_channels == 2) ? "stereo" : "mono",

                (s->audio_type == CODEC_ID_INTERPLAY_DPCM) ?

                "Interplay audio" : "PCM");

            break;

        case OPCODE_START_STOP_AUDIO:

            debug_ipmovie("start/stop audio\n");

            url_fseek(pb, opcode_size, SEEK_CUR);

            break;

        case OPCODE_INIT_VIDEO_BUFFERS:

            debug_ipmovie("initialize video buffers\n");

            if ((opcode_version > 2) || (opcode_size > 8)) {

                debug_ipmovie("bad init_video_buffers opcode\n");

                chunk_type = CHUNK_BAD;

                break;

            }

            if (get_buffer(pb, scratch, opcode_size) !=

                opcode_size) {

                chunk_type = CHUNK_BAD;

                break;

            }

            s->video_width = AV_RL16(&scratch[0]) * 8;

            s->video_height = AV_RL16(&scratch[2]) * 8;

            debug_ipmovie("video resolution: %d x %d\n",

                s->video_width, s->video_height);

            break;

        case OPCODE_UNKNOWN_06:

        case OPCODE_UNKNOWN_0E:

        case OPCODE_UNKNOWN_10:

        case OPCODE_UNKNOWN_12:

        case OPCODE_UNKNOWN_13:

        case OPCODE_UNKNOWN_14:

        case OPCODE_UNKNOWN_15:

            debug_ipmovie("unknown (but documented) opcode %02X\n", opcode_type);

            url_fseek(pb, opcode_size, SEEK_CUR);

            break;

        case OPCODE_SEND_BUFFER:

            debug_ipmovie("send buffer\n");

            url_fseek(pb, opcode_size, SEEK_CUR);

            break;

        case OPCODE_AUDIO_FRAME:

            debug_ipmovie("audio frame\n");

            /* log position and move on for now */

            s->audio_chunk_offset = url_ftell(pb);

            s->audio_chunk_size = opcode_size;

            url_fseek(pb, opcode_size, SEEK_CUR);

            break;

        case OPCODE_SILENCE_FRAME:

            debug_ipmovie("silence frame\n");

            url_fseek(pb, opcode_size, SEEK_CUR);

            break;

        case OPCODE_INIT_VIDEO_MODE:

            debug_ipmovie("initialize video mode\n");

            url_fseek(pb, opcode_size, SEEK_CUR);

            break;

        case OPCODE_CREATE_GRADIENT:

            debug_ipmovie("create gradient\n");

            url_fseek(pb, opcode_size, SEEK_CUR);

            break;

        case OPCODE_SET_PALETTE:

            debug_ipmovie("set palette\n");

            /* check for the logical maximum palette size

             * (3 * 256 + 4 bytes) */

            if (opcode_size > 0x304) {

                debug_ipmovie("demux_ipmovie: set_palette opcode too large\n");

                chunk_type = CHUNK_BAD;

                break;

            }

            if (get_buffer(pb, scratch, opcode_size) != opcode_size) {

                chunk_type = CHUNK_BAD;

                break;

            }

            /* load the palette into internal data structure */

            first_color = AV_RL16(&scratch[0]);

            last_color = first_color + AV_RL16(&scratch[2]) - 1;

            /* sanity check (since they are 16 bit values) */

            if ((first_color > 0xFF) || (last_color > 0xFF)) {

                debug_ipmovie("demux_ipmovie: set_palette indices out of range (%d -> %d)\n",

                    first_color, last_color);

                chunk_type = CHUNK_BAD;

                break;

            }

            j = 4;  /* offset of first palette data */

            for (i = first_color; i <= last_color; i++) {

                /* the palette is stored as a 6-bit VGA palette, thus each

                 * component is shifted up to a 8-bit range */

                r = scratch[j++] * 4;

                g = scratch[j++] * 4;

                b = scratch[j++] * 4;

                s->palette_control.palette[i] = (r << 16) | (g << 8) | (b);

            }

            /* indicate a palette change */

            s->palette_control.palette_changed = 1;

            break;

        case OPCODE_SET_PALETTE_COMPRESSED:

            debug_ipmovie("set palette compressed\n");

            url_fseek(pb, opcode_size, SEEK_CUR);

            break;

        case OPCODE_SET_DECODING_MAP:

            debug_ipmovie("set decoding map\n");

            /* log position and move on for now */

            s->decode_map_chunk_offset = url_ftell(pb);

            s->decode_map_chunk_size = opcode_size;

            url_fseek(pb, opcode_size, SEEK_CUR);

            break;

        case OPCODE_VIDEO_DATA:

            debug_ipmovie("set video data\n");

            /* log position and move on for now */

            s->video_chunk_offset = url_ftell(pb);

            s->video_chunk_size = opcode_size;

            url_fseek(pb, opcode_size, SEEK_CUR);

            break;

        default:

            debug_ipmovie("*** unknown opcode type\n");

            chunk_type = CHUNK_BAD;

            break;

        }

    }

    /* make a note of where the stream is sitting */

    s->next_chunk_offset = url_ftell(pb);

    /* dispatch the first of any pending packets */

    if ((chunk_type == CHUNK_VIDEO) || (chunk_type == CHUNK_AUDIO_ONLY))

        chunk_type = load_ipmovie_packet(s, pb, pkt);

    return chunk_type;

}


static int save_xbzrle_page(RAMState *rs, uint8_t **current_data,

                            ram_addr_t current_addr, RAMBlock *block,

                            ram_addr_t offset, bool last_stage)

{

    int encoded_len = 0, bytes_xbzrle;

    uint8_t *prev_cached_page;

    if (!cache_is_cached(XBZRLE.cache, current_addr, rs->bitmap_sync_count)) {

        rs->xbzrle_cache_miss++;

        if (!last_stage) {

            if (cache_insert(XBZRLE.cache, current_addr, *current_data,

                             rs->bitmap_sync_count) == -1) {

                return -1;

            } else {

                /* update *current_data when the page has been

                   inserted into cache */

                *current_data = get_cached_data(XBZRLE.cache, current_addr);

            }

        }

        return -1;

    }

    prev_cached_page = get_cached_data(XBZRLE.cache, current_addr);

    /* save current buffer into memory */

    memcpy(XBZRLE.current_buf, *current_data, TARGET_PAGE_SIZE);

    /* XBZRLE encoding (if there is no overflow) */

    encoded_len = xbzrle_encode_buffer(prev_cached_page, XBZRLE.current_buf,

                                       TARGET_PAGE_SIZE, XBZRLE.encoded_buf,

                                       TARGET_PAGE_SIZE);

    if (encoded_len == 0) {

        trace_save_xbzrle_page_skipping();

        return 0;

    } else if (encoded_len == -1) {

        trace_save_xbzrle_page_overflow();

        rs->xbzrle_overflows++;

        /* update data in the cache */

        if (!last_stage) {

            memcpy(prev_cached_page, *current_data, TARGET_PAGE_SIZE);

            *current_data = prev_cached_page;

        }

        return -1;

    }

    /* we need to update the data in the cache, in order to get the same data */

    if (!last_stage) {

        memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE);

    }

    /* Send XBZRLE based compressed page */

    bytes_xbzrle = save_page_header(rs, block,

                                    offset | RAM_SAVE_FLAG_XBZRLE);

    qemu_put_byte(rs->f, ENCODING_FLAG_XBZRLE);

    qemu_put_be16(rs->f, encoded_len);

    qemu_put_buffer(rs->f, XBZRLE.encoded_buf, encoded_len);

    bytes_xbzrle += encoded_len + 1 + 2;

    rs->xbzrle_pages++;

    rs->xbzrle_bytes += bytes_xbzrle;

    rs->bytes_transferred += bytes_xbzrle;

    return 1;

}


static void dump_qobject(fprintf_function func_fprintf, void *f,

                         int comp_indent, QObject *obj)

{

    switch (qobject_type(obj)) {

        case QTYPE_QINT: {

            QInt *value = qobject_to_qint(obj);

            func_fprintf(f, "%" PRId64, qint_get_int(value));

            break;

        }

        case QTYPE_QSTRING: {

            QString *value = qobject_to_qstring(obj);

            func_fprintf(f, "%s", qstring_get_str(value));

            break;

        }

        case QTYPE_QDICT: {

            QDict *value = qobject_to_qdict(obj);

            dump_qdict(func_fprintf, f, comp_indent, value);

            break;

        }

        case QTYPE_QLIST: {

            QList *value = qobject_to_qlist(obj);

            dump_qlist(func_fprintf, f, comp_indent, value);

            break;

        }

        case QTYPE_QFLOAT: {

            QFloat *value = qobject_to_qfloat(obj);

            func_fprintf(f, "%g", qfloat_get_double(value));

            break;

        }

        case QTYPE_QBOOL: {

            QBool *value = qobject_to_qbool(obj);

            func_fprintf(f, "%s", qbool_get_int(value) ? "true" : "false");

            break;

        }

        case QTYPE_QERROR: {

            QString *value = qerror_human((QError *)obj);

            func_fprintf(f, "%s", qstring_get_str(value));

            break;

        }

        case QTYPE_NONE:

            break;

        case QTYPE_MAX:

        default:

            abort();

    }

}


int sws_getColorspaceDetails(SwsContext *c, int **inv_table, int *srcRange, int **table, int *dstRange, int *brightness, int *contrast, int *saturation)

{

    if (isYUV(c->dstFormat) || isGray(c->dstFormat)) return -1;

    *inv_table = c->srcColorspaceTable;

    *table     = c->dstColorspaceTable;

    *srcRange  = c->srcRange;

    *dstRange  = c->dstRange;

    *brightness= c->brightness;

    *contrast  = c->contrast;

    *saturation= c->saturation;

    return 0;

}


static int mjpeg_decode_frame(AVCodecContext *avctx,

                              void *data, int *data_size,

                              UINT8 *buf, int buf_size)

{

    MJpegDecodeContext *s = avctx->priv_data;

    UINT8 *buf_end, *buf_ptr;

    int i, start_code;

    AVPicture *picture = data;

    *data_size = 0;

    /* no supplementary picture */

    if (buf_size == 0)

        return 0;

    buf_ptr = buf;

    buf_end = buf + buf_size;

    while (buf_ptr < buf_end) {

        /* find start next marker */

        start_code = find_marker(&buf_ptr, buf_end);

	{

	    /* EOF */

            if (start_code < 0) {

		goto the_end;

            } else {

                dprintf("marker=%x avail_size_in_buf=%d\n", start_code, buf_end - buf_ptr);

		if ((buf_end - buf_ptr) > s->buffer_size)

		{

		    av_free(s->buffer);

		    s->buffer_size = buf_end-buf_ptr;

		    s->buffer = av_malloc(s->buffer_size);

		    dprintf("buffer too small, expanding to %d bytes\n",

			s->buffer_size);

		}

		/* unescape buffer of SOS */

		if (start_code == SOS)

		{

		    UINT8 *src = buf_ptr;

		    UINT8 *dst = s->buffer;

		    while (src<buf_end)

		    {

			UINT8 x = *(src++);

			*(dst++) = x;

			if (x == 0xff)

			{

			    while(*src == 0xff) src++;

			    x = *(src++);

			    if (x >= 0xd0 && x <= 0xd7)

				*(dst++) = x;

			    else if (x)

				break;

			}

		    }

		    init_get_bits(&s->gb, s->buffer, dst - s->buffer);

		    dprintf("escaping removed %d bytes\n",

			(buf_end - buf_ptr) - (dst - s->buffer));

		}

		else

		    init_get_bits(&s->gb, buf_ptr, buf_end - buf_ptr);

		s->start_code = start_code;

		/* process markers */

		if (start_code >= 0xd0 && start_code <= 0xd7) {

		    dprintf("restart marker: %d\n", start_code&0x0f);

		} else if (s->first_picture) {

		    /* APP fields */

		    if (start_code >= 0xe0 && start_code <= 0xef)

			mjpeg_decode_app(s);

		    /* Comment */

		    else if (start_code == COM)

			mjpeg_decode_com(s);

		}

                switch(start_code) {

                case SOI:

		    s->restart_interval = 0;

                    /* nothing to do on SOI */

                    break;

                case DQT:

                    mjpeg_decode_dqt(s);

                    break;

                case DHT:

                    mjpeg_decode_dht(s);

                    break;

                case SOF0:

                    if (mjpeg_decode_sof0(s) < 0)

			return -1;

                    break;

		case EOI:

eoi_parser:

		    {

                        if (s->interlaced) {

                            s->bottom_field ^= 1;

                            /* if not bottom field, do not output image yet */

                            if (s->bottom_field)

                                goto not_the_end;

                        }

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

                            picture->data[i] = s->current_picture[i];

			    picture->linesize[i] = (s->interlaced) ?

				s->linesize[i] >> 1 : s->linesize[i];

                        }

                        *data_size = sizeof(AVPicture);

                        avctx->height = s->height;

                        if (s->interlaced)

                            avctx->height *= 2;

                        avctx->width = s->width;

                        /* XXX: not complete test ! */

                        switch((s->h_count[0] << 4) | s->v_count[0]) {

                        case 0x11:

                            avctx->pix_fmt = PIX_FMT_YUV444P;

                            break;

                        case 0x21:

                            avctx->pix_fmt = PIX_FMT_YUV422P;

                            break;

                        default:

                        case 0x22:

                            avctx->pix_fmt = PIX_FMT_YUV420P;

                            break;

                        }

                        /* dummy quality */

                        /* XXX: infer it with matrix */

//                    	avctx->quality = 3;

                        goto the_end;

                    }

		    break;

                case SOS:

                    mjpeg_decode_sos(s);

		    /* buggy avid puts EOI every 10-20th frame */

		    /* if restart period is over process EOI */

		    if ((s->buggy_avid && !s->interlaced) || s->restart_interval)

			goto eoi_parser;

                    break;

		case DRI:

		    mjpeg_decode_dri(s);

		    break;

		case SOF1:

		case SOF2:

		case SOF3:

		case SOF5:

		case SOF6:

		case SOF7:

		case SOF9:

		case SOF10:

		case SOF11:

		case SOF13:

		case SOF14:

		case SOF15:

		case JPG:

		    printf("mjpeg: unsupported coding type (%x)\n", start_code);

		    break;

//		default:

//		    printf("mjpeg: unsupported marker (%x)\n", start_code);

//		    break;

                }

not_the_end:

		/* eof process start code */

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

		dprintf("marker parser used %d bytes (%d bits)\n",

		    (get_bits_count(&s->gb)+7)/8, get_bits_count(&s->gb));

            }

        }

    }

the_end:

    dprintf("mjpeg decode frame unused %d bytes\n", buf_end - buf_ptr);

//    return buf_end - buf_ptr;

    return buf_ptr - buf;

}


static int draw_text(AVFilterContext *ctx, AVFrame *frame,

                     int width, int height)

{

    DrawTextContext *s = ctx->priv;

    AVFilterLink *inlink = ctx->inputs[0];

    uint32_t code = 0, prev_code = 0;

    int x = 0, y = 0, i = 0, ret;

    int max_text_line_w = 0, len;

    int box_w, box_h;

    char *text;

    uint8_t *p;

    int y_min = 32000, y_max = -32000;

    int x_min = 32000, x_max = -32000;

    FT_Vector delta;

    Glyph *glyph = NULL, *prev_glyph = NULL;

    Glyph dummy = { 0 };

    time_t now = time(0);

    struct tm ltime;

    AVBPrint *bp = &s->expanded_text;

    FFDrawColor fontcolor;

    FFDrawColor shadowcolor;

    FFDrawColor bordercolor;

    FFDrawColor boxcolor;

    av_bprint_clear(bp);

    if(s->basetime != AV_NOPTS_VALUE)

        now= frame->pts*av_q2d(ctx->inputs[0]->time_base) + s->basetime/1000000;

    switch (s->exp_mode) {

    case EXP_NONE:

        av_bprintf(bp, "%s", s->text);

        break;

    case EXP_NORMAL:

        if ((ret = expand_text(ctx, s->text, &s->expanded_text)) < 0)

            return ret;

        break;

    case EXP_STRFTIME:

        localtime_r(&now, &ltime);

        av_bprint_strftime(bp, s->text, &ltime);

        break;

    }

    if (s->tc_opt_string) {

        char tcbuf[AV_TIMECODE_STR_SIZE];

        av_timecode_make_string(&s->tc, tcbuf, inlink->frame_count);

        av_bprint_clear(bp);

        av_bprintf(bp, "%s%s", s->text, tcbuf);

    }

    if (!av_bprint_is_complete(bp))

        return AVERROR(ENOMEM);

    text = s->expanded_text.str;

    if ((len = s->expanded_text.len) > s->nb_positions) {

        if (!(s->positions =

              av_realloc(s->positions, len*sizeof(*s->positions))))

            return AVERROR(ENOMEM);

        s->nb_positions = len;

    }

    if (s->fontcolor_expr[0]) {

        /* If expression is set, evaluate and replace the static value */

        av_bprint_clear(&s->expanded_fontcolor);

        if ((ret = expand_text(ctx, s->fontcolor_expr, &s->expanded_fontcolor)) < 0)

            return ret;

        if (!av_bprint_is_complete(&s->expanded_fontcolor))

            return AVERROR(ENOMEM);

        av_log(s, AV_LOG_DEBUG, "Evaluated fontcolor is '%s'\n", s->expanded_fontcolor.str);

        ret = av_parse_color(s->fontcolor.rgba, s->expanded_fontcolor.str, -1, s);

        if (ret)

            return ret;

        ff_draw_color(&s->dc, &s->fontcolor, s->fontcolor.rgba);

    }

    x = 0;

    y = 0;

    /* load and cache glyphs */

    for (i = 0, p = text; *p; i++) {

        GET_UTF8(code, *p++, continue;);

        /* get glyph */

        dummy.code = code;

        glyph = av_tree_find(s->glyphs, &dummy, glyph_cmp, NULL);

        if (!glyph) {

            load_glyph(ctx, &glyph, code);

        }

        y_min = FFMIN(glyph->bbox.yMin, y_min);

        y_max = FFMAX(glyph->bbox.yMax, y_max);

        x_min = FFMIN(glyph->bbox.xMin, x_min);

        x_max = FFMAX(glyph->bbox.xMax, x_max);

    }

    s->max_glyph_h = y_max - y_min;

    s->max_glyph_w = x_max - x_min;

    /* compute and save position for each glyph */

    glyph = NULL;

    for (i = 0, p = text; *p; i++) {

        GET_UTF8(code, *p++, continue;);

        /* skip the \n in the sequence \r\n */

        if (prev_code == '\r' && code == '\n')

            continue;

        prev_code = code;

        if (is_newline(code)) {

            max_text_line_w = FFMAX(max_text_line_w, x);

            y += s->max_glyph_h;

            x = 0;

            continue;

        }

        /* get glyph */

        prev_glyph = glyph;

        dummy.code = code;

        glyph = av_tree_find(s->glyphs, &dummy, glyph_cmp, NULL);

        /* kerning */

        if (s->use_kerning && prev_glyph && glyph->code) {

            FT_Get_Kerning(s->face, prev_glyph->code, glyph->code,

                           ft_kerning_default, &delta);

            x += delta.x >> 6;

        }

        /* save position */

        s->positions[i].x = x + glyph->bitmap_left;

        s->positions[i].y = y - glyph->bitmap_top + y_max;

        if (code == '\t') x  = (x / s->tabsize + 1)*s->tabsize;

        else              x += glyph->advance;

    }

    max_text_line_w = FFMAX(x, max_text_line_w);

    s->var_values[VAR_TW] = s->var_values[VAR_TEXT_W] = max_text_line_w;

    s->var_values[VAR_TH] = s->var_values[VAR_TEXT_H] = y + s->max_glyph_h;

    s->var_values[VAR_MAX_GLYPH_W] = s->max_glyph_w;

    s->var_values[VAR_MAX_GLYPH_H] = s->max_glyph_h;

    s->var_values[VAR_MAX_GLYPH_A] = s->var_values[VAR_ASCENT ] = y_max;

    s->var_values[VAR_MAX_GLYPH_D] = s->var_values[VAR_DESCENT] = y_min;

    s->var_values[VAR_LINE_H] = s->var_values[VAR_LH] = s->max_glyph_h;

    s->x = s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, &s->prng);

    s->y = s->var_values[VAR_Y] = av_expr_eval(s->y_pexpr, s->var_values, &s->prng);

    s->x = s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, &s->prng);

    update_alpha(s);

    update_color_with_alpha(s, &fontcolor  , s->fontcolor  );

    update_color_with_alpha(s, &shadowcolor, s->shadowcolor);

    update_color_with_alpha(s, &bordercolor, s->bordercolor);

    update_color_with_alpha(s, &boxcolor   , s->boxcolor   );

    box_w = FFMIN(width - 1 , max_text_line_w);

    box_h = FFMIN(height - 1, y + s->max_glyph_h);

    /* draw box */

    if (s->draw_box)

        ff_blend_rectangle(&s->dc, &boxcolor,

                           frame->data, frame->linesize, width, height,

                           s->x - s->boxborderw, s->y - s->boxborderw,

                           box_w + s->boxborderw * 2, box_h + s->boxborderw * 2);

    if (s->shadowx || s->shadowy) {

        if ((ret = draw_glyphs(s, frame, width, height,

                               &shadowcolor, s->shadowx, s->shadowy, 0)) < 0)

            return ret;

    }

    if (s->borderw) {

        if ((ret = draw_glyphs(s, frame, width, height,

                               &bordercolor, 0, 0, s->borderw)) < 0)

            return ret;

    }

    if ((ret = draw_glyphs(s, frame, width, height,

                           &fontcolor, 0, 0, 0)) < 0)

        return ret;

    return 0;

}


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

                             int srcStride[], int srcSliceY, int srcSliceH,

                             uint8_t *dst[], int dstStride[])

{

    const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);

    const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);

    int plane, i, j;

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

        int length = (plane == 0 || plane == 3) ? c->srcW  : -((-c->srcW  ) >> c->chrDstHSubSample);

        int y =      (plane == 0 || plane == 3) ? srcSliceY: -((-srcSliceY) >> c->chrDstVSubSample);

        int height = (plane == 0 || plane == 3) ? srcSliceH: -((-srcSliceH) >> c->chrDstVSubSample);

        const uint8_t *srcPtr = src[plane];

        uint8_t *dstPtr = dst[plane] + dstStride[plane] * y;

        if (!dst[plane])

            continue;

        // ignore palette for GRAY8

        if (plane == 1 && !dst[2]) continue;

        if (!src[plane] || (plane == 1 && !src[2])) {

            int val = (plane == 3) ? 255 : 128;

            if (is16BPS(c->dstFormat))

                length *= 2;

            if (is9_OR_10BPS(c->dstFormat)) {

                fill_plane9or10(dst[plane], dstStride[plane],

                                length, height, y, val,

                                desc_dst->comp[plane].depth_minus1 + 1,

                                isBE(c->dstFormat));

            } else

                fillPlane(dst[plane], dstStride[plane], length, height, y,

                          val);

        } else {

            if (is9_OR_10BPS(c->srcFormat)) {

                const int src_depth = desc_src->comp[plane].depth_minus1 + 1;

                const int dst_depth = desc_dst->comp[plane].depth_minus1 + 1;

                const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;

                if (is16BPS(c->dstFormat)) {

                    uint16_t *dstPtr2 = (uint16_t *) dstPtr;

#define COPY9_OR_10TO16(rfunc, wfunc) \

                    for (i = 0; i < height; i++) { \

                        for (j = 0; j < length; j++) { \

                            int srcpx = rfunc(&srcPtr2[j]); \

                            wfunc(&dstPtr2[j], (srcpx << (16 - src_depth)) | (srcpx >> (2 * src_depth - 16))); \

                        } \

                        dstPtr2 += dstStride[plane] / 2; \

                        srcPtr2 += srcStride[plane] / 2; \

                    }

                    if (isBE(c->dstFormat)) {

                        if (isBE(c->srcFormat)) {

                            COPY9_OR_10TO16(AV_RB16, AV_WB16);

                        } else {

                            COPY9_OR_10TO16(AV_RL16, AV_WB16);

                        }

                    } else {

                        if (isBE(c->srcFormat)) {

                            COPY9_OR_10TO16(AV_RB16, AV_WL16);

                        } else {

                            COPY9_OR_10TO16(AV_RL16, AV_WL16);

                        }

                    }

                } else if (is9_OR_10BPS(c->dstFormat)) {

                    uint16_t *dstPtr2 = (uint16_t *) dstPtr;

#define COPY9_OR_10TO9_OR_10(loop) \

                    for (i = 0; i < height; i++) { \

                        for (j = 0; j < length; j++) { \

                            loop; \

                        } \

                        dstPtr2 += dstStride[plane] / 2; \

                        srcPtr2 += srcStride[plane] / 2; \

                    }

#define COPY9_OR_10TO9_OR_10_2(rfunc, wfunc) \

                    if (dst_depth > src_depth) { \

                        COPY9_OR_10TO9_OR_10(int srcpx = rfunc(&srcPtr2[j]); \

                            wfunc(&dstPtr2[j], (srcpx << 1) | (srcpx >> 9))); \

                    } else if (dst_depth < src_depth) { \

                        DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \

                                    srcPtr2, srcStride[plane] / 2, rfunc, \

                                    dither_8x8_1, 1, clip9); \

                    } else { \

                        COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]))); \

                    }

                    if (isBE(c->dstFormat)) {

                        if (isBE(c->srcFormat)) {

                            COPY9_OR_10TO9_OR_10_2(AV_RB16, AV_WB16);

                        } else {

                            COPY9_OR_10TO9_OR_10_2(AV_RL16, AV_WB16);

                        }

                    } else {

                        if (isBE(c->srcFormat)) {

                            COPY9_OR_10TO9_OR_10_2(AV_RB16, AV_WL16);

                        } else {

                            COPY9_OR_10TO9_OR_10_2(AV_RL16, AV_WL16);

                        }

                    }

                } else {

#define W8(a, b) { *(a) = (b); }

#define COPY9_OR_10TO8(rfunc) \

                    if (src_depth == 9) { \

                        DITHER_COPY(dstPtr,  dstStride[plane],   W8, \

                                    srcPtr2, srcStride[plane] / 2, rfunc, \

                                    dither_8x8_1, 1, av_clip_uint8); \

                    } else { \

                        DITHER_COPY(dstPtr,  dstStride[plane],   W8, \

                                    srcPtr2, srcStride[plane] / 2, rfunc, \

                                    dither_8x8_3, 2, av_clip_uint8); \

                    }

                    if (isBE(c->srcFormat)) {

                        COPY9_OR_10TO8(AV_RB16);

                    } else {

                        COPY9_OR_10TO8(AV_RL16);

                    }

                }

            } else if (is9_OR_10BPS(c->dstFormat)) {

                const int dst_depth = desc_dst->comp[plane].depth_minus1 + 1;

                uint16_t *dstPtr2 = (uint16_t *) dstPtr;

                if (is16BPS(c->srcFormat)) {

                    const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;

#define COPY16TO9_OR_10(rfunc, wfunc) \

                    if (dst_depth == 9) { \

                        DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \

                                    srcPtr2, srcStride[plane] / 2, rfunc, \

                                    ff_dither_8x8_128, 7, clip9); \

                    } else { \

                        DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \

                                    srcPtr2, srcStride[plane] / 2, rfunc, \

                                    dither_8x8_64, 6, clip10); \

                    }

                    if (isBE(c->dstFormat)) {

                        if (isBE(c->srcFormat)) {

                            COPY16TO9_OR_10(AV_RB16, AV_WB16);

                        } else {

                            COPY16TO9_OR_10(AV_RL16, AV_WB16);

                        }

                    } else {

                        if (isBE(c->srcFormat)) {

                            COPY16TO9_OR_10(AV_RB16, AV_WL16);

                        } else {

                            COPY16TO9_OR_10(AV_RL16, AV_WL16);

                        }

                    }

                } else /* 8bit */ {

#define COPY8TO9_OR_10(wfunc) \

                    for (i = 0; i < height; i++) { \

                        for (j = 0; j < length; j++) { \

                            const int srcpx = srcPtr[j]; \

                            wfunc(&dstPtr2[j], (srcpx << (dst_depth - 8)) | (srcpx >> (16 - dst_depth))); \

                        } \

                        dstPtr2 += dstStride[plane] / 2; \

                        srcPtr  += srcStride[plane]; \

                    }

                    if (isBE(c->dstFormat)) {

                        COPY8TO9_OR_10(AV_WB16);

                    } else {

                        COPY8TO9_OR_10(AV_WL16);

                    }

                }

            } else if (is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {

                const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;

#define COPY16TO8(rfunc) \

                    DITHER_COPY(dstPtr,  dstStride[plane],   W8, \

                                srcPtr2, srcStride[plane] / 2, rfunc, \

                                dither_8x8_256, 8, av_clip_uint8);

                if (isBE(c->srcFormat)) {

                    COPY16TO8(AV_RB16);

                } else {

                    COPY16TO8(AV_RL16);

                }

            } else if (!is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) {

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

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

                        dstPtr[ j << 1     ] = srcPtr[j];

                        dstPtr[(j << 1) + 1] = srcPtr[j];

                    }

                    srcPtr += srcStride[plane];

                    dstPtr += dstStride[plane];

                }

            } else if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat) &&

                      isBE(c->srcFormat) != isBE(c->dstFormat)) {

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

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

                        ((uint16_t *) dstPtr)[j] = av_bswap16(((const uint16_t *) srcPtr)[j]);

                    srcPtr += srcStride[plane];

                    dstPtr += dstStride[plane];

                }

            } else if (dstStride[plane] == srcStride[plane] &&

                       srcStride[plane] > 0 && srcStride[plane] == length) {

                memcpy(dst[plane] + dstStride[plane] * y, src[plane],

                       height * dstStride[plane]);

            } else {

                if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat))

                    length *= 2;

                else if (!desc_src->comp[0].depth_minus1)

                    length >>= 3; // monowhite/black

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

                    memcpy(dstPtr, srcPtr, length);

                    srcPtr += srcStride[plane];

                    dstPtr += dstStride[plane];

                }

            }

        }

    }

    return srcSliceH;

}


static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)

{

    AcpiPciHpState *s = opaque;

    uint32_t val = 0;

    int bsel = s->hotplug_select;

    if (bsel < 0 || bsel > ACPI_PCIHP_MAX_HOTPLUG_BUS) {

        return 0;

    }

    switch (addr) {

    case PCI_UP_BASE:

        val = s->acpi_pcihp_pci_status[bsel].up;

        if (!s->legacy_piix) {

            s->acpi_pcihp_pci_status[bsel].up = 0;

        }

        ACPI_PCIHP_DPRINTF("pci_up_read %" PRIu32 "\n", val);

        break;

    case PCI_DOWN_BASE:

        val = s->acpi_pcihp_pci_status[bsel].down;

        ACPI_PCIHP_DPRINTF("pci_down_read %" PRIu32 "\n", val);

        break;

    case PCI_EJ_BASE:

        /* No feature defined yet */

        ACPI_PCIHP_DPRINTF("pci_features_read %" PRIu32 "\n", val);

        break;

    case PCI_RMV_BASE:

        val = s->acpi_pcihp_pci_status[bsel].hotplug_enable;

        ACPI_PCIHP_DPRINTF("pci_rmv_read %" PRIu32 "\n", val);

        break;

    case PCI_SEL_BASE:

        val = s->hotplug_select;

        ACPI_PCIHP_DPRINTF("pci_sel_read %" PRIu32 "\n", val);

    default:

        break;

    }

    return val;

}


static void free_field_queue(PullupField *head, PullupField **last)

{

    PullupField *f = head;

    while (f) {

        av_free(f->diffs);

        av_free(f->combs);

        av_free(f->vars);

        if (f == *last) {

            av_freep(last);

            break;

        }

        f = f->next;

        av_freep(&f->prev);

    };

}


static void notify_guest_bh(void *opaque)

{

    VirtIOBlockDataPlane *s = opaque;

    unsigned nvqs = s->conf->num_queues;

    unsigned long bitmap[BITS_TO_LONGS(nvqs)];

    unsigned j;

    memcpy(bitmap, s->batch_notify_vqs, sizeof(bitmap));

    memset(s->batch_notify_vqs, 0, sizeof(bitmap));

    for (j = 0; j < nvqs; j += BITS_PER_LONG) {

        unsigned long bits = bitmap[j];

        while (bits != 0) {

            unsigned i = j + ctzl(bits);

            VirtQueue *vq = virtio_get_queue(s->vdev, i);

            if (virtio_should_notify(s->vdev, vq)) {

                event_notifier_set(virtio_queue_get_guest_notifier(vq));

            }

            bits &= bits - 1; /* clear right-most bit */

        }

    }

}


static char *doubles2str(double *dp, int count, const char *sep)

{

    int i;

    char *ap, *ap0;

    int component_len = 15 + strlen(sep);

    if (!sep) sep = ", ";

    ap = av_malloc(component_len * count);

    if (!ap)

        return NULL;

    ap0   = ap;

    ap[0] = '\0';

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

        unsigned l = snprintf(ap, component_len, "%f%s", dp[i], sep);

        if(l >= component_len)

            return NULL;

        ap += l;

    }

    ap0[strlen(ap0) - strlen(sep)] = '\0';

    return ap0;

}


static uint32_t arm_v7m_load_vector(ARMCPU *cpu)

{

    CPUState *cs = CPU(cpu);

    CPUARMState *env = &cpu->env;

    MemTxResult result;

    hwaddr vec = env->v7m.vecbase + env->v7m.exception * 4;

    uint32_t addr;

    addr = address_space_ldl(cs->as, vec,

                             MEMTXATTRS_UNSPECIFIED, &result);

    if (result != MEMTX_OK) {

        /* Architecturally this should cause a HardFault setting HSFR.VECTTBL,

         * which would then be immediately followed by our failing to load

         * the entry vector for that HardFault, which is a Lockup case.

         * Since we don't model Lockup, we just report this guest error

         * via cpu_abort().

         */

        cpu_abort(cs, "Failed to read from exception vector table "

                  "entry %08x\n", (unsigned)vec);

    }

    return addr;

}


static void htab_save_first_pass(QEMUFile *f, sPAPREnvironment *spapr,

                                 int64_t max_ns)

{

    int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64;

    int index = spapr->htab_save_index;

    int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);

    assert(spapr->htab_first_pass);

    do {

        int chunkstart;

        /* Consume invalid HPTEs */

        while ((index < htabslots)

               && !HPTE_VALID(HPTE(spapr->htab, index))) {

            index++;

            CLEAN_HPTE(HPTE(spapr->htab, index));

        }

        /* Consume valid HPTEs */

        chunkstart = index;

        while ((index < htabslots)

               && HPTE_VALID(HPTE(spapr->htab, index))) {

            index++;

            CLEAN_HPTE(HPTE(spapr->htab, index));

        }

        if (index > chunkstart) {

            int n_valid = index - chunkstart;

            qemu_put_be32(f, chunkstart);

            qemu_put_be16(f, n_valid);

            qemu_put_be16(f, 0);

            qemu_put_buffer(f, HPTE(spapr->htab, chunkstart),

                            HASH_PTE_SIZE_64 * n_valid);

            if ((qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) {

                break;

            }

        }

    } while ((index < htabslots) && !qemu_file_rate_limit(f));

    if (index >= htabslots) {

        assert(index == htabslots);

        index = 0;

        spapr->htab_first_pass = false;

    }

    spapr->htab_save_index = index;

}


build_dsdt(GArray *table_data, BIOSLinker *linker,

           AcpiPmInfo *pm, AcpiMiscInfo *misc,

           Range *pci_hole, Range *pci_hole64, MachineState *machine)

{

    CrsRangeEntry *entry;

    Aml *dsdt, *sb_scope, *scope, *dev, *method, *field, *pkg, *crs;

    CrsRangeSet crs_range_set;

    PCMachineState *pcms = PC_MACHINE(machine);

    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);

    uint32_t nr_mem = machine->ram_slots;

    int root_bus_limit = 0xFF;

    PCIBus *bus = NULL;

    int i;

    dsdt = init_aml_allocator();

    /* Reserve space for header */

    acpi_data_push(dsdt->buf, sizeof(AcpiTableHeader));

    build_dbg_aml(dsdt);

    if (misc->is_piix4) {

        sb_scope = aml_scope("_SB");

        dev = aml_device("PCI0");

        aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));

        aml_append(dev, aml_name_decl("_ADR", aml_int(0)));

        aml_append(dev, aml_name_decl("_UID", aml_int(1)));

        aml_append(sb_scope, dev);

        aml_append(dsdt, sb_scope);

        build_hpet_aml(dsdt);

        build_piix4_pm(dsdt);

        build_piix4_isa_bridge(dsdt);

        build_isa_devices_aml(dsdt);

        build_piix4_pci_hotplug(dsdt);

        build_piix4_pci0_int(dsdt);

    } else {

        sb_scope = aml_scope("_SB");

        dev = aml_device("PCI0");

        aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));

        aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));

        aml_append(dev, aml_name_decl("_ADR", aml_int(0)));

        aml_append(dev, aml_name_decl("_UID", aml_int(1)));

        aml_append(dev, build_q35_osc_method());

        aml_append(sb_scope, dev);

        aml_append(dsdt, sb_scope);

        build_hpet_aml(dsdt);

        build_q35_isa_bridge(dsdt);

        build_isa_devices_aml(dsdt);

        build_q35_pci0_int(dsdt);

    }

    if (pcmc->legacy_cpu_hotplug) {

        build_legacy_cpu_hotplug_aml(dsdt, machine, pm->cpu_hp_io_base);

    } else {

        CPUHotplugFeatures opts = {

            .apci_1_compatible = true, .has_legacy_cphp = true

        };

        build_cpus_aml(dsdt, machine, opts, pm->cpu_hp_io_base,

                       "\\_SB.PCI0", "\\_GPE._E02");

    }

    build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0", "\\_GPE._E03");

    scope =  aml_scope("_GPE");

    {

        aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006")));

        if (misc->is_piix4) {

            method = aml_method("_E01", 0, AML_NOTSERIALIZED);

            aml_append(method,

                aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF));

            aml_append(method, aml_call0("\\_SB.PCI0.PCNT"));

            aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK")));

            aml_append(scope, method);

        }

        if (pcms->acpi_nvdimm_state.is_enabled) {

            method = aml_method("_E04", 0, AML_NOTSERIALIZED);

            aml_append(method, aml_notify(aml_name("\\_SB.NVDR"),

                                          aml_int(0x80)));

            aml_append(scope, method);

        }

    }

    aml_append(dsdt, scope);

    crs_range_set_init(&crs_range_set);

    bus = PC_MACHINE(machine)->bus;

    if (bus) {

        QLIST_FOREACH(bus, &bus->child, sibling) {

            uint8_t bus_num = pci_bus_num(bus);

            uint8_t numa_node = pci_bus_numa_node(bus);

            /* look only for expander root buses */

            if (!pci_bus_is_root(bus)) {

                continue;

            }

            if (bus_num < root_bus_limit) {

                root_bus_limit = bus_num - 1;

            }

            scope = aml_scope("\\_SB");

            dev = aml_device("PC%.02X", bus_num);

            aml_append(dev, aml_name_decl("_UID", aml_int(bus_num)));

            aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));

            aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num)));

            if (pci_bus_is_express(bus)) {

                aml_append(dev, build_q35_osc_method());

            }

            if (numa_node != NUMA_NODE_UNASSIGNED) {

                aml_append(dev, aml_name_decl("_PXM", aml_int(numa_node)));

            }

            aml_append(dev, build_prt(false));

            crs = build_crs(PCI_HOST_BRIDGE(BUS(bus)->parent), &crs_range_set);

            aml_append(dev, aml_name_decl("_CRS", crs));

            aml_append(scope, dev);

            aml_append(dsdt, scope);

        }

    }

    scope = aml_scope("\\_SB.PCI0");

    /* build PCI0._CRS */

    crs = aml_resource_template();

    aml_append(crs,

        aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,

                            0x0000, 0x0, root_bus_limit,

                            0x0000, root_bus_limit + 1));

    aml_append(crs, aml_io(AML_DECODE16, 0x0CF8, 0x0CF8, 0x01, 0x08));

    aml_append(crs,

        aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED,

                    AML_POS_DECODE, AML_ENTIRE_RANGE,

                    0x0000, 0x0000, 0x0CF7, 0x0000, 0x0CF8));

    crs_replace_with_free_ranges(crs_range_set.io_ranges, 0x0D00, 0xFFFF);

    for (i = 0; i < crs_range_set.io_ranges->len; i++) {

        entry = g_ptr_array_index(crs_range_set.io_ranges, i);

        aml_append(crs,

            aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED,

                        AML_POS_DECODE, AML_ENTIRE_RANGE,

                        0x0000, entry->base, entry->limit,

                        0x0000, entry->limit - entry->base + 1));

    }

    aml_append(crs,

        aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,

                         AML_CACHEABLE, AML_READ_WRITE,

                         0, 0x000A0000, 0x000BFFFF, 0, 0x00020000));

    crs_replace_with_free_ranges(crs_range_set.mem_ranges,

                                 range_lob(pci_hole),

                                 range_upb(pci_hole));

    for (i = 0; i < crs_range_set.mem_ranges->len; i++) {

        entry = g_ptr_array_index(crs_range_set.mem_ranges, i);

        aml_append(crs,

            aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,

                             AML_NON_CACHEABLE, AML_READ_WRITE,

                             0, entry->base, entry->limit,

                             0, entry->limit - entry->base + 1));

    }

    if (!range_is_empty(pci_hole64)) {

        crs_replace_with_free_ranges(crs_range_set.mem_64bit_ranges,

                                     range_lob(pci_hole64),

                                     range_upb(pci_hole64));

        for (i = 0; i < crs_range_set.mem_64bit_ranges->len; i++) {

            entry = g_ptr_array_index(crs_range_set.mem_64bit_ranges, i);

            aml_append(crs,

                       aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED,

                                        AML_MAX_FIXED,

                                        AML_CACHEABLE, AML_READ_WRITE,

                                        0, entry->base, entry->limit,

                                        0, entry->limit - entry->base + 1));

        }

    }

    if (misc->tpm_version != TPM_VERSION_UNSPEC) {

        aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE,

                   TPM_TIS_ADDR_SIZE, AML_READ_WRITE));

    }

    aml_append(scope, aml_name_decl("_CRS", crs));

    /* reserve GPE0 block resources */

    dev = aml_device("GPE0");

    aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));

    aml_append(dev, aml_name_decl("_UID", aml_string("GPE0 resources")));

    /* device present, functioning, decoding, not shown in UI */

    aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));

    crs = aml_resource_template();

    aml_append(crs,

        aml_io(AML_DECODE16, pm->gpe0_blk, pm->gpe0_blk, 1, pm->gpe0_blk_len)

    );

    aml_append(dev, aml_name_decl("_CRS", crs));

    aml_append(scope, dev);

    crs_range_set_free(&crs_range_set);

    /* reserve PCIHP resources */

    if (pm->pcihp_io_len) {

        dev = aml_device("PHPR");

        aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));

        aml_append(dev,

            aml_name_decl("_UID", aml_string("PCI Hotplug resources")));

        /* device present, functioning, decoding, not shown in UI */

        aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));

        crs = aml_resource_template();

        aml_append(crs,

            aml_io(AML_DECODE16, pm->pcihp_io_base, pm->pcihp_io_base, 1,

                   pm->pcihp_io_len)

        );

        aml_append(dev, aml_name_decl("_CRS", crs));

        aml_append(scope, dev);

    }

    aml_append(dsdt, scope);

    /*  create S3_ / S4_ / S5_ packages if necessary */

    scope = aml_scope("\\");

    if (!pm->s3_disabled) {

        pkg = aml_package(4);

        aml_append(pkg, aml_int(1)); /* PM1a_CNT.SLP_TYP */

        aml_append(pkg, aml_int(1)); /* PM1b_CNT.SLP_TYP, FIXME: not impl. */

        aml_append(pkg, aml_int(0)); /* reserved */

        aml_append(pkg, aml_int(0)); /* reserved */

        aml_append(scope, aml_name_decl("_S3", pkg));

    }

    if (!pm->s4_disabled) {

        pkg = aml_package(4);

        aml_append(pkg, aml_int(pm->s4_val)); /* PM1a_CNT.SLP_TYP */

        /* PM1b_CNT.SLP_TYP, FIXME: not impl. */

        aml_append(pkg, aml_int(pm->s4_val));

        aml_append(pkg, aml_int(0)); /* reserved */

        aml_append(pkg, aml_int(0)); /* reserved */

        aml_append(scope, aml_name_decl("_S4", pkg));

    }

    pkg = aml_package(4);

    aml_append(pkg, aml_int(0)); /* PM1a_CNT.SLP_TYP */

    aml_append(pkg, aml_int(0)); /* PM1b_CNT.SLP_TYP not impl. */

    aml_append(pkg, aml_int(0)); /* reserved */

    aml_append(pkg, aml_int(0)); /* reserved */

    aml_append(scope, aml_name_decl("_S5", pkg));

    aml_append(dsdt, scope);

    /* create fw_cfg node, unconditionally */

    {

        /* when using port i/o, the 8-bit data register *always* overlaps

         * with half of the 16-bit control register. Hence, the total size

         * of the i/o region used is FW_CFG_CTL_SIZE; when using DMA, the

         * DMA control register is located at FW_CFG_DMA_IO_BASE + 4 */

        uint8_t io_size = object_property_get_bool(OBJECT(pcms->fw_cfg),

                                                   "dma_enabled", NULL) ?

                          ROUND_UP(FW_CFG_CTL_SIZE, 4) + sizeof(dma_addr_t) :

                          FW_CFG_CTL_SIZE;

        scope = aml_scope("\\_SB.PCI0");

        dev = aml_device("FWCF");

        aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));

        /* device present, functioning, decoding, not shown in UI */

        aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));

        crs = aml_resource_template();

        aml_append(crs,

            aml_io(AML_DECODE16, FW_CFG_IO_BASE, FW_CFG_IO_BASE, 0x01, io_size)

        );

        aml_append(dev, aml_name_decl("_CRS", crs));

        aml_append(scope, dev);

        aml_append(dsdt, scope);

    }

    if (misc->applesmc_io_base) {

        scope = aml_scope("\\_SB.PCI0.ISA");

        dev = aml_device("SMC");

        aml_append(dev, aml_name_decl("_HID", aml_eisaid("APP0001")));

        /* device present, functioning, decoding, not shown in UI */

        aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));

        crs = aml_resource_template();

        aml_append(crs,

            aml_io(AML_DECODE16, misc->applesmc_io_base, misc->applesmc_io_base,

                   0x01, APPLESMC_MAX_DATA_LENGTH)

        );

        aml_append(crs, aml_irq_no_flags(6));

        aml_append(dev, aml_name_decl("_CRS", crs));

        aml_append(scope, dev);

        aml_append(dsdt, scope);

    }

    if (misc->pvpanic_port) {

        scope = aml_scope("\\_SB.PCI0.ISA");

        dev = aml_device("PEVT");

        aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0001")));

        crs = aml_resource_template();

        aml_append(crs,

            aml_io(AML_DECODE16, misc->pvpanic_port, misc->pvpanic_port, 1, 1)

        );

        aml_append(dev, aml_name_decl("_CRS", crs));

        aml_append(dev, aml_operation_region("PEOR", AML_SYSTEM_IO,

                                              aml_int(misc->pvpanic_port), 1));

        field = aml_field("PEOR", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);

        aml_append(field, aml_named_field("PEPT", 8));

        aml_append(dev, field);

        /* device present, functioning, decoding, shown in UI */

        aml_append(dev, aml_name_decl("_STA", aml_int(0xF)));

        method = aml_method("RDPT", 0, AML_NOTSERIALIZED);

        aml_append(method, aml_store(aml_name("PEPT"), aml_local(0)));

        aml_append(method, aml_return(aml_local(0)));

        aml_append(dev, method);

        method = aml_method("WRPT", 1, AML_NOTSERIALIZED);

        aml_append(method, aml_store(aml_arg(0), aml_name("PEPT")));

        aml_append(dev, method);

        aml_append(scope, dev);

        aml_append(dsdt, scope);

    }

    sb_scope = aml_scope("\\_SB");

    {

        Object *pci_host;

        PCIBus *bus = NULL;

        pci_host = acpi_get_i386_pci_host();

        if (pci_host) {

            bus = PCI_HOST_BRIDGE(pci_host)->bus;

        }

        if (bus) {

            Aml *scope = aml_scope("PCI0");

            /* Scan all PCI buses. Generate tables to support hotplug. */

            build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en);

            if (misc->tpm_version != TPM_VERSION_UNSPEC) {

                dev = aml_device("ISA.TPM");

                aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0C31")));

                aml_append(dev, aml_name_decl("_STA", aml_int(0xF)));

                crs = aml_resource_template();

                aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE,

                           TPM_TIS_ADDR_SIZE, AML_READ_WRITE));

                /*

                    FIXME: TPM_TIS_IRQ=5 conflicts with PNP0C0F irqs,

                    Rewrite to take IRQ from TPM device model and

                    fix default IRQ value there to use some unused IRQ

                 */

                /* aml_append(crs, aml_irq_no_flags(TPM_TIS_IRQ)); */

                aml_append(dev, aml_name_decl("_CRS", crs));

                aml_append(scope, dev);

            }

            aml_append(sb_scope, scope);

        }

    }

    aml_append(dsdt, sb_scope);

    /* copy AML table into ACPI tables blob and patch header there */

    g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);

    build_header(linker, table_data,

        (void *)(table_data->data + table_data->len - dsdt->buf->len),

        "DSDT", dsdt->buf->len, 1, NULL, NULL);

    free_aml_allocator();

}


int64_t cpu_get_clock(void)

{

    int64_t ti;

    if (!timers_state.cpu_ticks_enabled) {

        return timers_state.cpu_clock_offset;

    } else {

        ti = get_clock();

        return ti + timers_state.cpu_clock_offset;

    }

}


static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, int16_t *block, int n)

{

    int level, dc, diff, j, run;

    int component;

    RLTable *rl;

    uint8_t * scantable = s->intra_scantable.permutated;

    const uint16_t *quant_matrix;

    const int qscale = s->qscale;

    /* DC coefficient */

    if (n < 4) {

        quant_matrix = s->intra_matrix;

        component = 0;

    } else {

        quant_matrix = s->chroma_intra_matrix;

        component = (n & 1) + 1;

    }

    diff = decode_dc(&s->gb, component);

    if (diff >= 0xffff)

        return -1;

    dc = s->last_dc[component];

    dc += diff;

    s->last_dc[component] = dc;

    block[0] = dc << (3 - s->intra_dc_precision);

    if (s->intra_vlc_format)

        rl = &ff_rl_mpeg2;

    else

        rl = &ff_rl_mpeg1;

    {

        OPEN_READER(re, &s->gb);

        /* now quantify & encode AC coefficients */

        for (;;) {

            UPDATE_CACHE(re, &s->gb);

            GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);

            if (level == 127) {

                break;

            } else if (level != 0) {

                scantable += run;

                j = *scantable;

                level = (level * qscale * quant_matrix[j]) >> 4;

                level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);

                LAST_SKIP_BITS(re, &s->gb, 1);

            } else {

                /* escape */

                run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6);

                UPDATE_CACHE(re, &s->gb);

                level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12);

                scantable += run;

                j = *scantable;

                if (level < 0) {

                    level = (-level * qscale * quant_matrix[j]) >> 4;

                    level = -level;

                } else {

                    level = (level * qscale * quant_matrix[j]) >> 4;

                }

            }

            block[j] = level;

        }

        CLOSE_READER(re, &s->gb);

    }

    s->block_last_index[n] = scantable - s->intra_scantable.permutated;

    return 0;

}