static void do_interrupt_protected(int intno, int is_int, int error_code,

                                   unsigned int next_eip)

{

    SegmentCache *dt;

    uint8_t *ptr, *ssp;

    int type, dpl, selector, ss_dpl;

    int has_error_code, new_stack, shift;

    uint32_t e1, e2, offset, ss, esp, ss_e1, ss_e2, push_size;

    uint32_t old_cs, old_ss, old_esp, old_eip;

    dt = &env->idt;

    if (intno * 8 + 7 > dt->limit)

        raise_exception_err(EXCP0D_GPF, intno * 8 + 2);

    ptr = dt->base + intno * 8;

    e1 = ldl(ptr);

    e2 = ldl(ptr + 4);

    /* check gate type */

    type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;

    switch(type) {

    case 5: /* task gate */

        cpu_abort(env, "task gate not supported");

        break;

    case 6: /* 286 interrupt gate */

    case 7: /* 286 trap gate */

    case 14: /* 386 interrupt gate */

    case 15: /* 386 trap gate */

        break;

    default:

        raise_exception_err(EXCP0D_GPF, intno * 8 + 2);

        break;

    }

    dpl = (e2 >> DESC_DPL_SHIFT) & 3;

    /* check privledge if software int */

    if (is_int && dpl < env->cpl)

        raise_exception_err(EXCP0D_GPF, intno * 8 + 2);

    /* check valid bit */

    if (!(e2 & DESC_P_MASK))

        raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2);

    selector = e1 >> 16;

    offset = (e2 & 0xffff0000) | (e1 & 0x0000ffff);

    if ((selector & 0xfffc) == 0)

        raise_exception_err(EXCP0D_GPF, 0);

    if (load_segment(&e1, &e2, selector) != 0)

        raise_exception_err(EXCP0D_GPF, selector & 0xfffc);

    if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK)))

        raise_exception_err(EXCP0D_GPF, selector & 0xfffc);

    dpl = (e2 >> DESC_DPL_SHIFT) & 3;

    if (dpl > env->cpl)

        raise_exception_err(EXCP0D_GPF, selector & 0xfffc);

    if (!(e2 & DESC_P_MASK))

        raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);

    if (!(e2 & DESC_C_MASK) && dpl < env->cpl) {

        /* to inner priviledge */

        get_ss_esp_from_tss(&ss, &esp, dpl);

        if ((ss & 0xfffc) == 0)

            raise_exception_err(EXCP0A_TSS, ss & 0xfffc);

        if ((ss & 3) != dpl)

            raise_exception_err(EXCP0A_TSS, ss & 0xfffc);

        if (load_segment(&ss_e1, &ss_e2, ss) != 0)

            raise_exception_err(EXCP0A_TSS, ss & 0xfffc);

        ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;

        if (ss_dpl != dpl)

            raise_exception_err(EXCP0A_TSS, ss & 0xfffc);

        if (!(ss_e2 & DESC_S_MASK) ||

            (ss_e2 & DESC_CS_MASK) ||

            !(ss_e2 & DESC_W_MASK))

            raise_exception_err(EXCP0A_TSS, ss & 0xfffc);

        if (!(ss_e2 & DESC_P_MASK))

            raise_exception_err(EXCP0A_TSS, ss & 0xfffc);

        new_stack = 1;

    } else if ((e2 & DESC_C_MASK) || dpl == env->cpl) {

        /* to same priviledge */

        new_stack = 0;

    } else {

        raise_exception_err(EXCP0D_GPF, selector & 0xfffc);

        new_stack = 0; /* avoid warning */

    }

    shift = type >> 3;

    has_error_code = 0;

    if (!is_int) {

        switch(intno) {

        case 8:

        case 10:

        case 11:

        case 12:

        case 13:

        case 14:

        case 17:

            has_error_code = 1;

            break;

        }

    }

    push_size = 6 + (new_stack << 2) + (has_error_code << 1);

    if (env->eflags & VM_MASK)

        push_size += 8;

    push_size <<= shift;

    /* XXX: check that enough room is available */

    if (new_stack) {

        old_esp = env->regs[R_ESP];

        old_ss = env->segs[R_SS].selector;

        load_seg(R_SS, ss, env->eip);

    } else {

        old_esp = 0;

        old_ss = 0;

        esp = env->regs[R_ESP];

    }

    if (is_int)

        old_eip = next_eip;

    else

        old_eip = env->eip;

    old_cs = env->segs[R_CS].selector;

    load_seg(R_CS, selector, env->eip);

    env->eip = offset;

    env->regs[R_ESP] = esp - push_size;

    ssp = env->segs[R_SS].base + esp;

    if (shift == 1) {

        int old_eflags;

        if (env->eflags & VM_MASK) {

            ssp -= 4;

            stl(ssp, env->segs[R_GS].selector);

            ssp -= 4;

            stl(ssp, env->segs[R_FS].selector);

            ssp -= 4;

            stl(ssp, env->segs[R_DS].selector);

            ssp -= 4;

            stl(ssp, env->segs[R_ES].selector);

        }

        if (new_stack) {

            ssp -= 4;

            stl(ssp, old_ss);

            ssp -= 4;

            stl(ssp, old_esp);

        }

        ssp -= 4;

        old_eflags = compute_eflags();

        stl(ssp, old_eflags);

        ssp -= 4;

        stl(ssp, old_cs);

        ssp -= 4;

        stl(ssp, old_eip);

        if (has_error_code) {

            ssp -= 4;

            stl(ssp, error_code);

        }

    } else {

        if (new_stack) {

            ssp -= 2;

            stw(ssp, old_ss);

            ssp -= 2;

            stw(ssp, old_esp);

        }

        ssp -= 2;

        stw(ssp, compute_eflags());

        ssp -= 2;

        stw(ssp, old_cs);

        ssp -= 2;

        stw(ssp, old_eip);

        if (has_error_code) {

            ssp -= 2;

            stw(ssp, error_code);

        }

    }

    /* interrupt gate clear IF mask */

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

        env->eflags &= ~IF_MASK;

    }

    env->eflags &= ~(TF_MASK | VM_MASK | RF_MASK | NT_MASK);

}


static inline void gen_evmergehilo(DisasContext *ctx)

{

    if (unlikely(!ctx->spe_enabled)) {

        gen_exception(ctx, POWERPC_EXCP_APU);

        return;

    }

#if defined(TARGET_PPC64)

    TCGv t0 = tcg_temp_new();

    TCGv t1 = tcg_temp_new();

    tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);

    tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);

    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);

    tcg_temp_free(t0);

    tcg_temp_free(t1);

#else

    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);

    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);

#endif

}


void qjson_finish(QJSON *json)

{

    json_end_object(json);

}


static void arm_cache_flush(abi_ulong start, abi_ulong last)

{

    abi_ulong addr, last1;

    if (last < start)

        return;

    addr = start;

    for(;;) {

        last1 = ((addr + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK) - 1;

        if (last1 > last)

            last1 = last;

        tb_invalidate_page_range(addr, last1 + 1);

        if (last1 == last)

            break;

        addr = last1 + 1;

    }

}


Object *object_dynamic_cast(Object *obj, const char *typename)

{

    GSList *i;

    /* Check if typename is a direct ancestor */

    if (object_is_type(obj, typename)) {

        return obj;

    }

    /* Check if obj has an interface of typename */

    for (i = obj->interfaces; i; i = i->next) {

        Interface *iface = i->data;

        if (object_is_type(OBJECT(iface), typename)) {

            return OBJECT(iface);

        }

    }

    /* Check if obj is an interface and its containing object is a direct

     * ancestor of typename */

    if (object_is_type(obj, TYPE_INTERFACE)) {

        Interface *iface = INTERFACE(obj);

        if (object_is_type(iface->obj, typename)) {

            return iface->obj;

        }

    }

    return NULL;

}


void ioinst_handle_rchp(S390CPU *cpu, uint64_t reg1)

{

    int cc;

    uint8_t cssid;

    uint8_t chpid;

    int ret;

    CPUS390XState *env = &cpu->env;

    if (RCHP_REG1_RES(reg1)) {

        program_interrupt(env, PGM_OPERAND, 2);

        return;

    }

    cssid = RCHP_REG1_CSSID(reg1);

    chpid = RCHP_REG1_CHPID(reg1);

    trace_ioinst_chp_id("rchp", cssid, chpid);

    ret = css_do_rchp(cssid, chpid);

    switch (ret) {

    case -ENODEV:

        cc = 3;

        break;

    case -EBUSY:

        cc = 2;

        break;

    case 0:

        cc = 0;

        break;

    default:

        /* Invalid channel subsystem. */

        program_interrupt(env, PGM_OPERAND, 2);

        return;

    }

    setcc(cpu, cc);

}


int s390_cpu_restart(S390CPU *cpu)

{

    if (kvm_enabled()) {

        return kvm_s390_cpu_restart(cpu);

    }

    return -ENOSYS;

}


static int parse_packet_header(WMAVoiceContext *s)

{

    GetBitContext *gb = &s->gb;

    unsigned int res;

    if (get_bits_left(gb) < 11)

        return 1;

    skip_bits(gb, 4);          // packet sequence number

    s->has_residual_lsps = get_bits1(gb);

    do {

        res = get_bits(gb, 6); // number of superframes per packet

                               // (minus first one if there is spillover)

        if (get_bits_left(gb) < 6 * (res == 0x3F) + s->spillover_bitsize)

            return 1;

    } while (res == 0x3F);

    s->spillover_nbits   = get_bits(gb, s->spillover_bitsize);

    return 0;

}


int xenstore_domain_init1(const char *kernel, const char *ramdisk,

                          const char *cmdline)

{

    char *dom, uuid_string[42], vm[256], path[256];

    int i;

    snprintf(uuid_string, sizeof(uuid_string), UUID_FMT,

             qemu_uuid[0], qemu_uuid[1], qemu_uuid[2], qemu_uuid[3],

             qemu_uuid[4], qemu_uuid[5], qemu_uuid[6], qemu_uuid[7],

             qemu_uuid[8], qemu_uuid[9], qemu_uuid[10], qemu_uuid[11],

             qemu_uuid[12], qemu_uuid[13], qemu_uuid[14], qemu_uuid[15]);

    dom = xs_get_domain_path(xenstore, xen_domid);

    snprintf(vm,  sizeof(vm),  "/vm/%s", uuid_string);

    xenstore_domain_mkdir(dom);

    xenstore_write_str(vm, "image/ostype",  "linux");

    if (kernel)

        xenstore_write_str(vm, "image/kernel",  kernel);

    if (ramdisk)

        xenstore_write_str(vm, "image/ramdisk", ramdisk);

    if (cmdline)

        xenstore_write_str(vm, "image/cmdline", cmdline);

    /* name + id */

    xenstore_write_str(vm,  "name",   qemu_name ? qemu_name : "no-name");

    xenstore_write_str(vm,  "uuid",   uuid_string);

    xenstore_write_str(dom, "name",   qemu_name ? qemu_name : "no-name");

    xenstore_write_int(dom, "domid",  xen_domid);

    xenstore_write_str(dom, "vm",     vm);

    /* memory */

    xenstore_write_int(dom, "memory/target", ram_size >> 10);  // kB

    xenstore_write_int(vm, "memory",         ram_size >> 20);  // MB

    xenstore_write_int(vm, "maxmem",         ram_size >> 20);  // MB

    /* cpus */

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

	snprintf(path, sizeof(path), "cpu/%d/availability",i);

	xenstore_write_str(dom, path, "online");

    }

    xenstore_write_int(vm, "vcpu_avail",  smp_cpus);

    xenstore_write_int(vm, "vcpus",       smp_cpus);

    /* vnc password */

    xenstore_write_str(vm, "vncpassword", "" /* FIXME */);

    free(dom);

    return 0;

}


static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,

                            DeviceState *dev, Error **errp)

{

    int idx;

    int node_id;

    CPUState *cs;

    CPUArchId *cpu_slot;

    X86CPUTopoInfo topo;

    X86CPU *cpu = X86_CPU(dev);

    PCMachineState *pcms = PC_MACHINE(hotplug_dev);

    /* if APIC ID is not set, set it based on socket/core/thread properties */

    if (cpu->apic_id == UNASSIGNED_APIC_ID) {

        int max_socket = (max_cpus - 1) / smp_threads / smp_cores;

        if (cpu->socket_id < 0) {

            error_setg(errp, "CPU socket-id is not set");

            return;

        } else if (cpu->socket_id > max_socket) {

            error_setg(errp, "Invalid CPU socket-id: %u must be in range 0:%u",

                       cpu->socket_id, max_socket);

            return;

        }

        if (cpu->core_id < 0) {

            error_setg(errp, "CPU core-id is not set");

            return;

        } else if (cpu->core_id > (smp_cores - 1)) {

            error_setg(errp, "Invalid CPU core-id: %u must be in range 0:%u",

                       cpu->core_id, smp_cores - 1);

            return;

        }

        if (cpu->thread_id < 0) {

            error_setg(errp, "CPU thread-id is not set");

            return;

        } else if (cpu->thread_id > (smp_threads - 1)) {

            error_setg(errp, "Invalid CPU thread-id: %u must be in range 0:%u",

                       cpu->thread_id, smp_threads - 1);

            return;

        }

        topo.pkg_id = cpu->socket_id;

        topo.core_id = cpu->core_id;

        topo.smt_id = cpu->thread_id;

        cpu->apic_id = apicid_from_topo_ids(smp_cores, smp_threads, &topo);

    }

    cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, &idx);

    if (!cpu_slot) {

        MachineState *ms = MACHINE(pcms);

        x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);

        error_setg(errp, "Invalid CPU [socket: %u, core: %u, thread: %u] with"

                  " APIC ID %" PRIu32 ", valid index range 0:%d",

                   topo.pkg_id, topo.core_id, topo.smt_id, cpu->apic_id,

                   ms->possible_cpus->len - 1);

        return;

    }

    if (cpu_slot->cpu) {

        error_setg(errp, "CPU[%d] with APIC ID %" PRIu32 " exists",

                   idx, cpu->apic_id);

        return;

    }

    /* if 'address' properties socket-id/core-id/thread-id are not set, set them

     * so that machine_query_hotpluggable_cpus would show correct values

     */

    /* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn()

     * once -smp refactoring is complete and there will be CPU private

     * CPUState::nr_cores and CPUState::nr_threads fields instead of globals */

    x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);

    if (cpu->socket_id != -1 && cpu->socket_id != topo.pkg_id) {

        error_setg(errp, "property socket-id: %u doesn't match set apic-id:"

            " 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, topo.pkg_id);

        return;

    }

    cpu->socket_id = topo.pkg_id;

    if (cpu->core_id != -1 && cpu->core_id != topo.core_id) {

        error_setg(errp, "property core-id: %u doesn't match set apic-id:"

            " 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id, topo.core_id);

        return;

    }

    cpu->core_id = topo.core_id;

    if (cpu->thread_id != -1 && cpu->thread_id != topo.smt_id) {

        error_setg(errp, "property thread-id: %u doesn't match set apic-id:"

            " 0x%x (thread-id: %u)", cpu->thread_id, cpu->apic_id, topo.smt_id);

        return;

    }

    cpu->thread_id = topo.smt_id;

    cs = CPU(cpu);

    cs->cpu_index = idx;

    node_id = cpu_slot->props.node_id;

    if (!cpu_slot->props.has_node_id) {

        /* by default CPUState::numa_node was 0 if it's not set via CLI

         * keep it this way for now but in future we probably should

         * refuse to start up with incomplete numa mapping */

        node_id = 0;

    }

    if (cs->numa_node == CPU_UNSET_NUMA_NODE_ID) {

        cs->numa_node = node_id;

    } else if (cs->numa_node != node_id) {

            error_setg(errp, "node-id %d must match numa node specified"

                "with -numa option for cpu-index %d",

                cs->numa_node, cs->cpu_index);

            return;

    }

}


void monitor_readline(const char *prompt, int is_password,

                      char *buf, int buf_size)

{

    int i;

    if (is_password) {

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

            if (monitor_hd[i] && monitor_hd[i]->focus == 0)

                qemu_chr_send_event(monitor_hd[i], CHR_EVENT_FOCUS);

    }

    readline_start(prompt, is_password, monitor_readline_cb, NULL);

    monitor_readline_buf = buf;

    monitor_readline_buf_size = buf_size;

    monitor_readline_started = 1;

    while (monitor_readline_started) {

        main_loop_wait(10);

    }

}


static void decode_422_bitstream(HYuvContext *s, int count)

{

    int i;

    count /= 2;

    if (count >= (get_bits_left(&s->gb)) / (31 * 4)) {

        for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {

            READ_2PIX(s->temp[0][2 * i    ], s->temp[1][i], 1);

            READ_2PIX(s->temp[0][2 * i + 1], s->temp[2][i], 2);

        }

        for (; i < count; i++)

            s->temp[0][2 * i    ] = s->temp[1][i] =

            s->temp[0][2 * i + 1] = s->temp[2][i] = 128;

    } else {

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

            READ_2PIX(s->temp[0][2 * i    ], s->temp[1][i], 1);

            READ_2PIX(s->temp[0][2 * i + 1], s->temp[2][i], 2);

        }

    }

}


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

{

    OSSVoiceOut *oss = (OSSVoiceOut *) hw;

    struct oss_params req, obt;

    int endianness;

    int err;

    int fd;

    audfmt_e effective_fmt;

    audsettings_t obt_as;

    oss->fd = -1;

    req.fmt = aud_to_ossfmt (as->fmt);

    req.freq = as->freq;

    req.nchannels = as->nchannels;

    req.fragsize = conf.fragsize;

    req.nfrags = conf.nfrags;

    if (oss_open (0, &req, &obt, &fd)) {

        return -1;

    }

    err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);

    if (err) {

        oss_anal_close (&fd);

        return -1;

    }

    obt_as.freq = obt.freq;

    obt_as.nchannels = obt.nchannels;

    obt_as.fmt = effective_fmt;

    obt_as.endianness = endianness;

    audio_pcm_init_info (&hw->info, &obt_as);

    oss->nfrags = obt.nfrags;

    oss->fragsize = obt.fragsize;

    if (obt.nfrags * obt.fragsize & hw->info.align) {

        dolog ("warning: Misaligned DAC buffer, size %d, alignment %d\n",

               obt.nfrags * obt.fragsize, hw->info.align + 1);

    }

    hw->samples = (obt.nfrags * obt.fragsize) >> hw->info.shift;

    oss->mmapped = 0;

    if (conf.try_mmap) {

        oss->pcm_buf = mmap (

            0,

            hw->samples << hw->info.shift,

            PROT_READ | PROT_WRITE,

            MAP_SHARED,

            fd,

            0

            );

        if (oss->pcm_buf == MAP_FAILED) {

            oss_logerr (errno, "Failed to map %d bytes of DAC\n",

                        hw->samples << hw->info.shift);

        } else {

            int err;

            int trig = 0;

            if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {

                oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");

            }

            else {

                trig = PCM_ENABLE_OUTPUT;

                if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {

                    oss_logerr (

                        errno,

                        "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"

                        );

                }

                else {

                    oss->mmapped = 1;

                }

            }

            if (!oss->mmapped) {

                err = munmap (oss->pcm_buf, hw->samples << hw->info.shift);

                if (err) {

                    oss_logerr (errno, "Failed to unmap buffer %p size %d\n",

                                oss->pcm_buf, hw->samples << hw->info.shift);

                }

            }

        }

    }

    if (!oss->mmapped) {

        oss->pcm_buf = audio_calloc (

            AUDIO_FUNC,

            hw->samples,

            1 << hw->info.shift

            );

        if (!oss->pcm_buf) {

            dolog (

                "Could not allocate DAC buffer (%d samples, each %d bytes)\n",

                hw->samples,

                1 << hw->info.shift

                );

            oss_anal_close (&fd);

            return -1;

        }

    }

    oss->fd = fd;

    return 0;

}


void msi_notify(PCIDevice *dev, unsigned int vector)

{

    uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));

    bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;

    unsigned int nr_vectors = msi_nr_vectors(flags);

    MSIMessage msg;

    assert(vector < nr_vectors);

    if (msi_is_masked(dev, vector)) {

        assert(flags & PCI_MSI_FLAGS_MASKBIT);

        pci_long_test_and_set_mask(

            dev->config + msi_pending_off(dev, msi64bit), 1U << vector);

        MSI_DEV_PRINTF(dev, "pending vector 0x%x\n", vector);

        return;

    }

    msg = msi_get_message(dev, vector);

    MSI_DEV_PRINTF(dev,

                   "notify vector 0x%x"

                   " address: 0x%"PRIx64" data: 0x%"PRIx32"\n",

                   vector, msg.address, msg.data);

    stl_le_phys(&address_space_memory, msg.address, msg.data);

}


int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs,

                            int sock, const char *export, Error **errp)

{

    int ret;

    /* NBD handshake */

    logout("session init %s\n", export);

    qemu_set_block(sock);

    ret = nbd_receive_negotiate(sock, export,

                                &client->nbdflags, &client->size,

                                &client->blocksize, errp);

    if (ret < 0) {

        logout("Failed to negotiate with the NBD server\n");

        closesocket(sock);

        return ret;

    }

    qemu_co_mutex_init(&client->send_mutex);

    qemu_co_mutex_init(&client->free_sema);

    client->bs = bs;

    client->sock = sock;

    /* Now that we're connected, set the socket to be non-blocking and

     * kick the reply mechanism.  */

    qemu_set_nonblock(sock);

    nbd_client_session_attach_aio_context(client, bdrv_get_aio_context(bs));

    logout("Established connection with NBD server\n");

    return 0;

}


static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value)

{

    QStackEntry *e = g_malloc0(sizeof(*e));

    assert(qov->root);

    assert(value);

    e->value = value;

    if (qobject_type(e->value) == QTYPE_QLIST) {

        e->is_list_head = true;

    }

    QTAILQ_INSERT_HEAD(&qov->stack, e, node);

}


static bool enforce_config_section(void)

{

    MachineState *machine = MACHINE(qdev_get_machine());

    return machine->enforce_config_section;

}


MSA_ST_DF(DF_BYTE,   b, helper_ret_stb_mmu, oi, GETRA())

MSA_ST_DF(DF_HALF,   h, helper_ret_stw_mmu, oi, GETRA())

MSA_ST_DF(DF_WORD,   w, helper_ret_stl_mmu, oi, GETRA())

MSA_ST_DF(DF_DOUBLE, d, helper_ret_stq_mmu, oi, GETRA())

#else

MSA_ST_DF(DF_BYTE,   b, cpu_stb_data)

MSA_ST_DF(DF_HALF,   h, cpu_stw_data)

MSA_ST_DF(DF_WORD,   w, cpu_stl_data)

MSA_ST_DF(DF_DOUBLE, d, cpu_stq_data)

#endif

void helper_cache(CPUMIPSState *env, target_ulong addr, uint32_t op)

{

#ifndef CONFIG_USER_ONLY

    target_ulong index = addr & 0x1fffffff;

    if (op == 9) {

        /* Index Store Tag */

        memory_region_dispatch_write(env->itc_tag, index, env->CP0_TagLo,

                                     8, MEMTXATTRS_UNSPECIFIED);

    } else if (op == 5) {

        /* Index Load Tag */

        memory_region_dispatch_read(env->itc_tag, index, &env->CP0_TagLo,

                                    8, MEMTXATTRS_UNSPECIFIED);

    }

#endif

}


void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,

                            qxl_async_io async)

{

    if (async != QXL_SYNC) {

#if SPICE_INTERFACE_QXL_MINOR >= 1

        spice_qxl_add_memslot_async(&ssd->qxl, memslot, 0);

#else

        abort();

#endif

    } else {

        ssd->worker->add_memslot(ssd->worker, memslot);

    }

}


static void spapr_cpu_core_register(const SPAPRCoreInfo *info)

{

    TypeInfo type_info = {

        .parent = TYPE_SPAPR_CPU_CORE,

        .instance_size = sizeof(sPAPRCPUCore),

        .instance_init = info->initfn,

    };

    type_info.name = g_strdup_printf("%s-" TYPE_SPAPR_CPU_CORE, info->name);

    type_register(&type_info);

    g_free((void *)type_info.name);

}


static int aer915_init(I2CSlave *i2c)

{

    /* Nothing to do.  */

    return 0;

}


static void define_debug_regs(ARMCPU *cpu)

{

    /* Define v7 and v8 architectural debug registers.

     * These are just dummy implementations for now.

     */

    int i;

    define_arm_cp_regs(cpu, debug_cp_reginfo);

    if (arm_feature(&cpu->env, ARM_FEATURE_LPAE)) {

        define_arm_cp_regs(cpu, debug_lpae_cp_reginfo);

    }

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

        ARMCPRegInfo dbgregs[] = {

            { .name = "DBGBVR", .state = ARM_CP_STATE_BOTH,

              .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 4,

              .access = PL1_RW,

              .fieldoffset = offsetof(CPUARMState, cp15.dbgbvr[i]) },

            { .name = "DBGBCR", .state = ARM_CP_STATE_BOTH,

              .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 5,

              .access = PL1_RW,

              .fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]) },

            { .name = "DBGWVR", .state = ARM_CP_STATE_BOTH,

              .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 6,

              .access = PL1_RW,

              .fieldoffset = offsetof(CPUARMState, cp15.dbgwvr[i]) },

            { .name = "DBGWCR", .state = ARM_CP_STATE_BOTH,

              .cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = i, .opc2 = 7,

              .access = PL1_RW,

              .fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]) },

               REGINFO_SENTINEL

        };

        define_arm_cp_regs(cpu, dbgregs);

    }

}


static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)

{

    /* XXX: TODO */

    return 0;

}


static inline void gen_efsneg(DisasContext *ctx)

{

    if (unlikely(!ctx->spe_enabled)) {

        gen_exception(ctx, POWERPC_EXCP_APU);

        return;

    }

    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);

}


VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)

{

    VirtIOBlockReq *req = g_new(VirtIOBlockReq, 1);

    req->dev = s;

    req->qiov.size = 0;

    req->in_len = 0;

    req->next = NULL;

    req->mr_next = NULL;

    return req;

}


static void uhci_reset(void *opaque)

{

    UHCIState *s = opaque;

    uint8_t *pci_conf;

    int i;

    UHCIPort *port;

    DPRINTF("uhci: full reset\n");

    pci_conf = s->dev.config;

    pci_conf[0x6a] = 0x01; /* usb clock */

    pci_conf[0x6b] = 0x00;

    s->cmd = 0;

    s->status = 0;

    s->status2 = 0;

    s->intr = 0;

    s->fl_base_addr = 0;

    s->sof_timing = 64;

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

        port = &s->ports[i];

        port->ctrl = 0x0080;

        if (port->port.dev) {

            usb_attach(&port->port, port->port.dev);

        }

    }

    uhci_async_cancel_all(s);

}


static int parse_block_size_shift(BDRVSheepdogState *s, QemuOpts *opt)

{

    struct SheepdogInode *inode = &s->inode;

    uint64_t object_size;

    int obj_order;

    object_size = qemu_opt_get_size_del(opt, BLOCK_OPT_OBJECT_SIZE, 0);

    if (object_size) {

        if ((object_size - 1) & object_size) {    /* not a power of 2? */

            return -EINVAL;

        }

        obj_order = ffs(object_size) - 1;

        if (obj_order < 20 || obj_order > 31) {

            return -EINVAL;

        }

        inode->block_size_shift = (uint8_t)obj_order;

    }

    return 0;

}


static uint64_t mmio_ide_read(void *opaque, target_phys_addr_t addr,

                              unsigned size)

{

    MMIOState *s = opaque;

    addr >>= s->shift;

    if (addr & 7)

        return ide_ioport_read(&s->bus, addr);

    else

        return ide_data_readw(&s->bus, 0);

}


static void dbdma_write(void *opaque, target_phys_addr_t addr,

                        uint64_t value, unsigned size)

{

    int channel = addr >> DBDMA_CHANNEL_SHIFT;

    DBDMAState *s = opaque;

    DBDMA_channel *ch = &s->channels[channel];

    int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2;

    DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08x\n", addr, value);

    DBDMA_DPRINTF("channel 0x%x reg 0x%x\n",

                  (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg);

    /* cmdptr cannot be modified if channel is RUN or ACTIVE */

    if (reg == DBDMA_CMDPTR_LO &&

        (ch->regs[DBDMA_STATUS] & (RUN | ACTIVE)))

	return;

    ch->regs[reg] = value;

    switch(reg) {

    case DBDMA_CONTROL:

        dbdma_control_write(ch);

        break;

    case DBDMA_CMDPTR_LO:

        /* 16-byte aligned */

        ch->regs[DBDMA_CMDPTR_LO] &= ~0xf;

        dbdma_cmdptr_load(ch);

        break;

    case DBDMA_STATUS:

    case DBDMA_INTR_SEL:

    case DBDMA_BRANCH_SEL:

    case DBDMA_WAIT_SEL:

        /* nothing to do */

        break;

    case DBDMA_XFER_MODE:

    case DBDMA_CMDPTR_HI:

    case DBDMA_DATA2PTR_HI:

    case DBDMA_DATA2PTR_LO:

    case DBDMA_ADDRESS_HI:

    case DBDMA_BRANCH_ADDR_HI:

    case DBDMA_RES1:

    case DBDMA_RES2:

    case DBDMA_RES3:

    case DBDMA_RES4:

        /* unused */

        break;

    }

}


static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)

{

    VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n);

    VFIOContainer *container = giommu->container;

    hwaddr iova = iotlb->iova + giommu->iommu_offset;

    MemoryRegion *mr;

    hwaddr xlat;

    hwaddr len = iotlb->addr_mask + 1;

    void *vaddr;

    int ret;

    trace_vfio_iommu_map_notify(iotlb->perm == IOMMU_NONE ? "UNMAP" : "MAP",

                                iova, iova + iotlb->addr_mask);

    if (iotlb->target_as != &address_space_memory) {

        error_report("Wrong target AS \"%s\", only system memory is allowed",

                     iotlb->target_as->name ? iotlb->target_as->name : "none");

        return;

    }

    /*

     * The IOMMU TLB entry we have just covers translation through

     * this IOMMU to its immediate target.  We need to translate

     * it the rest of the way through to memory.

     */

    rcu_read_lock();

    mr = address_space_translate(&address_space_memory,

                                 iotlb->translated_addr,

                                 &xlat, &len, iotlb->perm & IOMMU_WO);

    if (!memory_region_is_ram(mr)) {

        error_report("iommu map to non memory area %"HWADDR_PRIx"",

                     xlat);

        goto out;

    }

    /*

     * Translation truncates length to the IOMMU page size,

     * check that it did not truncate too much.

     */

    if (len & iotlb->addr_mask) {

        error_report("iommu has granularity incompatible with target AS");

        goto out;

    }

    if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {

        vaddr = memory_region_get_ram_ptr(mr) + xlat;

        ret = vfio_dma_map(container, iova,

                           iotlb->addr_mask + 1, vaddr,

                           !(iotlb->perm & IOMMU_WO) || mr->readonly);

        if (ret) {

            error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", "

                         "0x%"HWADDR_PRIx", %p) = %d (%m)",

                         container, iova,

                         iotlb->addr_mask + 1, vaddr, ret);

        }

    } else {

        ret = vfio_dma_unmap(container, iova, iotlb->addr_mask + 1);

        if (ret) {

            error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", "

                         "0x%"HWADDR_PRIx") = %d (%m)",

                         container, iova,

                         iotlb->addr_mask + 1, ret);

        }

    }

out:

    rcu_read_unlock();

}


static void flush_packet(AVFormatContext *ctx, int stream_index, int last_pkt)

{

    MpegMuxContext *s = ctx->priv_data;

    StreamInfo *stream = ctx->streams[stream_index]->priv_data;

    uint8_t *buf_ptr;

    int size, payload_size, startcode, id, len, stuffing_size, i, header_len;

    int64_t timestamp;

    uint8_t buffer[128];

    int last = last_pkt ? 4 : 0;

    id = stream->id;

    timestamp = stream->start_pts;

#if 0

    printf("packet ID=%2x PTS=%0.3f\n",

           id, timestamp / 90000.0);

#endif

    buf_ptr = buffer;

    if (((s->packet_number % s->pack_header_freq) == 0)) {

        /* output pack and systems header if needed */

        size = put_pack_header(ctx, buf_ptr, timestamp);

        buf_ptr += size;

        if ((s->packet_number % s->system_header_freq) == 0) {

            size = put_system_header(ctx, buf_ptr);

            buf_ptr += size;

        }

    }

    size = buf_ptr - buffer;

    put_buffer(&ctx->pb, buffer, size);

    /* packet header */

    if (s->is_mpeg2) {

        header_len = 8;

    } else {

        header_len = 5;

    }

    payload_size = s->packet_size - (size + 6 + header_len + last);

    if (id < 0xc0) {

        startcode = PRIVATE_STREAM_1;

        payload_size -= 4;

    } else {

        startcode = 0x100 + id;

    }

    stuffing_size = payload_size - stream->buffer_ptr;

    if (stuffing_size < 0)

        stuffing_size = 0;

    put_be32(&ctx->pb, startcode);

    put_be16(&ctx->pb, payload_size + header_len);

    /* stuffing */

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

        put_byte(&ctx->pb, 0xff);

    if (s->is_mpeg2) {

        put_byte(&ctx->pb, 0x80); /* mpeg2 id */

        put_byte(&ctx->pb, 0x80); /* flags */

        put_byte(&ctx->pb, 0x05); /* header len (only pts is included) */

    }

    put_byte(&ctx->pb,

             (0x02 << 4) |

             (((timestamp >> 30) & 0x07) << 1) |

             1);

    put_be16(&ctx->pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1));

    put_be16(&ctx->pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1));

    if (startcode == PRIVATE_STREAM_1) {

        put_byte(&ctx->pb, id);

        if (id >= 0x80 && id <= 0xbf) {

            /* XXX: need to check AC3 spec */

            put_byte(&ctx->pb, 1);

            put_byte(&ctx->pb, 0);

            put_byte(&ctx->pb, 2);

        }

    }

    if (last_pkt) {

        put_be32(&ctx->pb, ISO_11172_END_CODE);

    }

    /* output data */

    put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size);

    put_flush_packet(&ctx->pb);

    /* preserve remaining data */

    len = stream->buffer_ptr - payload_size;

    if (len < 0)

        len = 0;

    memmove(stream->buffer, stream->buffer + stream->buffer_ptr - len, len);

    stream->buffer_ptr = len;

    s->packet_number++;

    stream->packet_number++;

    stream->start_pts = -1;

}


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

{

    AVPacket *pkt = &is->audio_pkt;

    int n, len1, data_size;

    double pts;

    for(;;) {

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

        while (is->audio_pkt_size > 0) {

            len1 = avcodec_decode_audio(&is->audio_st->codec,

                                        (int16_t *)audio_buf, &data_size,

                                        is->audio_pkt_data, is->audio_pkt_size);

            if (len1 < 0) {

                /* if error, we skip the frame */

                is->audio_pkt_size = 0;

                break;

            }

            is->audio_pkt_data += len1;

            is->audio_pkt_size -= len1;

            if (data_size <= 0)

                continue;

            /* if no pts, then compute it */

            pts = is->audio_clock;

            *pts_ptr = pts;

            n = 2 * is->audio_st->codec.channels;

printf("%f %d %d %d\n", is->audio_clock, is->audio_st->codec.channels, data_size, is->audio_st->codec.sample_rate);

            is->audio_clock += (double)data_size /

                (double)(n * is->audio_st->codec.sample_rate);

#if defined(DEBUG_SYNC)

            {

                static double last_clock;

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

                       is->audio_clock - last_clock,

                       is->audio_clock, pts);

                last_clock = is->audio_clock;

            }

#endif

            return data_size;

        }

        /* free the current packet */

        if (pkt->data)

            av_free_packet(pkt);

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

            return -1;

        }

        /* read next packet */

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

            return -1;

        is->audio_pkt_data = pkt->data;

        is->audio_pkt_size = pkt->size;

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

        if (pkt->pts != AV_NOPTS_VALUE) {

            is->audio_clock = (double)pkt->pts / AV_TIME_BASE;

        }

    }

}


static int rtp_write_header(AVFormatContext *s1)

{

    RTPDemuxContext *s = s1->priv_data;

    int payload_type, max_packet_size, n;

    AVStream *st;

    if (s1->nb_streams != 1)

        return -1;

    st = s1->streams[0];

    payload_type = rtp_get_payload_type(st->codec);

    if (payload_type < 0)

        payload_type = RTP_PT_PRIVATE; /* private payload type */

    s->payload_type = payload_type;

    s->base_timestamp = random();

    s->timestamp = s->base_timestamp;

    s->ssrc = random();

    s->first_packet = 1;

    max_packet_size = url_fget_max_packet_size(&s1->pb);

    if (max_packet_size <= 12)

        return AVERROR_IO;

    s->max_payload_size = max_packet_size - 12;

    switch(st->codec->codec_id) {

    case CODEC_ID_MP2:

    case CODEC_ID_MP3:

        s->buf_ptr = s->buf + 4;

        s->cur_timestamp = 0;

        break;

    case CODEC_ID_MPEG1VIDEO:

        s->cur_timestamp = 0;

        break;

    case CODEC_ID_MPEG2TS:

        n = s->max_payload_size / TS_PACKET_SIZE;

        if (n < 1)

            n = 1;

        s->max_payload_size = n * TS_PACKET_SIZE;

        s->buf_ptr = s->buf;

        break;

    default:

        s->buf_ptr = s->buf;

        break;

    }

    return 0;

}


int ff_v4l2_context_dequeue_packet(V4L2Context* ctx, AVPacket* pkt)

{

    V4L2Buffer* avbuf = NULL;

    /* if we are draining, we are no longer inputing data, therefore enable a

     * timeout so we can dequeue and flag the last valid buffer.

     *

     * blocks until:

     *  1. encoded packet available

     *  2. an input buffer ready to be dequeued

     */

    avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1);

    if (!avbuf) {

        if (ctx->done)

            return AVERROR_EOF;

        return AVERROR(EAGAIN);

    }

    return ff_v4l2_buffer_buf_to_avpkt(pkt, avbuf);

}


static SlirpState *slirp_lookup(Monitor *mon, const char *vlan,

                                const char *stack)

{

    VLANClientState *vc;

    if (vlan) {

        vc = qemu_find_vlan_client_by_name(mon, strtol(vlan, NULL, 0), stack);

        if (!vc) {

            return NULL;

        }

        if (strcmp(vc->model, "user")) {

            monitor_printf(mon, "invalid device specified\n");

            return NULL;

        }

        return vc->opaque;

    } else {

        if (TAILQ_EMPTY(&slirp_stacks)) {

            monitor_printf(mon, "user mode network stack not in use\n");

            return NULL;

        }

        return TAILQ_FIRST(&slirp_stacks);

    }

}


static void usb_host_speed_compat(USBHostDevice *s)

{

    USBDevice *udev = USB_DEVICE(s);

    struct libusb_config_descriptor *conf;

    const struct libusb_interface_descriptor *intf;

    const struct libusb_endpoint_descriptor *endp;

#ifdef HAVE_STREAMS

    struct libusb_ss_endpoint_companion_descriptor *endp_ss_comp;

#endif

    bool compat_high = true;

    bool compat_full = true;

    uint8_t type;

    int rc, c, i, a, e;

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

        rc = libusb_get_config_descriptor(s->dev, c, &conf);

        if (rc != 0) {

            break;

        }

        for (i = 0; i < conf->bNumInterfaces; i++) {

            for (a = 0; a < conf->interface[i].num_altsetting; a++) {

                intf = &conf->interface[i].altsetting[a];

                for (e = 0; e < intf->bNumEndpoints; e++) {

                    endp = &intf->endpoint[e];

                    type = endp->bmAttributes & 0x3;

                    switch (type) {

                    case 0x01: /* ISO */

                        compat_full = false;

                        compat_high = false;

                        break;

                    case 0x02: /* BULK */

#ifdef HAVE_STREAMS

                        rc = libusb_get_ss_endpoint_companion_descriptor

                            (ctx, endp, &endp_ss_comp);

                        if (rc == LIBUSB_SUCCESS) {

                            libusb_free_ss_endpoint_companion_descriptor

                                (endp_ss_comp);

                            compat_full = false;

                            compat_high = false;

                        }

#endif

                        break;

                    case 0x03: /* INTERRUPT */

                        if (endp->wMaxPacketSize > 64) {

                            compat_full = false;

                        }

                        if (endp->wMaxPacketSize > 1024) {

                            compat_high = false;

                        }

                        break;

                    }

                }

            }

        }

        libusb_free_config_descriptor(conf);

    }

    udev->speedmask = (1 << udev->speed);

    if (udev->speed == USB_SPEED_SUPER && compat_high) {

        udev->speedmask |= USB_SPEED_MASK_HIGH;

    }

    if (udev->speed == USB_SPEED_SUPER && compat_full) {

        udev->speedmask |= USB_SPEED_MASK_FULL;

    }

    if (udev->speed == USB_SPEED_HIGH && compat_full) {

        udev->speedmask |= USB_SPEED_MASK_FULL;

    }

}


static void find_best_tables(MpegEncContext * s)

{

    int i;

    int best       =-1, best_size       =9999999;

    int chroma_best=-1, best_chroma_size=9999999;

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

        int level;

        int chroma_size=0;

        int size=0;

        if(i>0){// ;)

            size++;

            chroma_size++;

        }

        for(level=0; level<=MAX_LEVEL; level++){

            int run;

            for(run=0; run<=MAX_RUN; run++){

                int last;

                const int last_size= size + chroma_size;

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

                    int inter_count       = s->ac_stats[0][0][level][run][last] + s->ac_stats[0][1][level][run][last];

                    int intra_luma_count  = s->ac_stats[1][0][level][run][last];

                    int intra_chroma_count= s->ac_stats[1][1][level][run][last];

                    if(s->pict_type==AV_PICTURE_TYPE_I){

                        size       += intra_luma_count  *rl_length[i  ][level][run][last];

                        chroma_size+= intra_chroma_count*rl_length[i+3][level][run][last];

                    }else{

                        size+=        intra_luma_count  *rl_length[i  ][level][run][last]

                                     +intra_chroma_count*rl_length[i+3][level][run][last]

                                     +inter_count       *rl_length[i+3][level][run][last];

                    }

                }

                if(last_size == size+chroma_size) break;

            }

        }

        if(size<best_size){

            best_size= size;

            best= i;

        }

        if(chroma_size<best_chroma_size){

            best_chroma_size= chroma_size;

            chroma_best= i;

        }

    }

//    printf("type:%d, best:%d, qp:%d, var:%d, mcvar:%d, size:%d //\n",

//           s->pict_type, best, s->qscale, s->mb_var_sum, s->mc_mb_var_sum, best_size);

    if(s->pict_type==AV_PICTURE_TYPE_P) chroma_best= best;

    memset(s->ac_stats, 0, sizeof(int)*(MAX_LEVEL+1)*(MAX_RUN+1)*2*2*2);

    s->rl_table_index       =        best;

    s->rl_chroma_table_index= chroma_best;

    if(s->pict_type != s->last_non_b_pict_type){

        s->rl_table_index= 2;

        if(s->pict_type==AV_PICTURE_TYPE_I)

            s->rl_chroma_table_index= 1;

        else

            s->rl_chroma_table_index= 2;

    }

}


static always_inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)

{

    if (unlikely(ctx->mem_idx)) {

        TCGv_i32 t0;

        tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);

        t0 = tcg_temp_new_i32();

        tcg_gen_trunc_tl_i32(t0, arg1);

        tcg_gen_bswap_i32(t0, t0);

        tcg_gen_ext_i32_tl(arg1, t0);

        tcg_temp_free_i32(t0);

    } else

        tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);

}


static inline void gen_ins(DisasContext *s, TCGMemOp ot)

{

    if (use_icount)

        gen_io_start();

    gen_string_movl_A0_EDI(s);

    /* Note: we must do this dummy write first to be restartable in

       case of page fault. */

    tcg_gen_movi_tl(cpu_T[0], 0);

    gen_op_st_v(s, ot, cpu_T[0], cpu_A0);

    tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[R_EDX]);

    tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);

    gen_helper_in_func(ot, cpu_T[0], cpu_tmp2_i32);

    gen_op_st_v(s, ot, cpu_T[0], cpu_A0);

    gen_op_movl_T0_Dshift(ot);

    gen_op_add_reg_T0(s->aflag, R_EDI);

    if (use_icount)

        gen_io_end();

}


void qmp_block_stream(const char *device,

                      bool has_base, const char *base,

                      bool has_backing_file, const char *backing_file,

                      bool has_speed, int64_t speed,

                      bool has_on_error, BlockdevOnError on_error,

                      Error **errp)

{

    BlockDriverState *bs;

    BlockDriverState *base_bs = NULL;

    Error *local_err = NULL;

    const char *base_name = NULL;

    if (!has_on_error) {

        on_error = BLOCKDEV_ON_ERROR_REPORT;

    }

    bs = bdrv_find(device);

    if (!bs) {

        error_set(errp, QERR_DEVICE_NOT_FOUND, device);

        return;

    }

    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_STREAM, errp)) {

        return;

    }

    if (has_base) {

        base_bs = bdrv_find_backing_image(bs, base);

        if (base_bs == NULL) {

            error_set(errp, QERR_BASE_NOT_FOUND, base);

            return;

        }

        base_name = base;

    }

    /* if we are streaming the entire chain, the result will have no backing

     * file, and specifying one is therefore an error */

    if (base_bs == NULL && has_backing_file) {

        error_setg(errp, "backing file specified, but streaming the "

                         "entire chain");

        return;

    }

    /* backing_file string overrides base bs filename */

    base_name = has_backing_file ? backing_file : base_name;

    stream_start(bs, base_bs, base_name, has_speed ? speed : 0,

                 on_error, block_job_cb, bs, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        return;

    }

    trace_qmp_block_stream(bs, bs->job);

}


static uint16_t md_common_read(PCMCIACardState *card, uint32_t at)

{

    MicroDriveState *s = MICRODRIVE(card);

    IDEState *ifs;

    uint16_t ret;

    at -= s->io_base;

    switch (s->opt & OPT_MODE) {

    case OPT_MODE_MMAP:

        if ((at & ~0x3ff) == 0x400) {

            at = 0;

        }

        break;

    case OPT_MODE_IOMAP16:

        at &= 0xf;

        break;

    case OPT_MODE_IOMAP1:

        if ((at & ~0xf) == 0x3f0) {

            at -= 0x3e8;

        } else if ((at & ~0xf) == 0x1f0) {

            at -= 0x1f0;

        }

        break;

    case OPT_MODE_IOMAP2:

        if ((at & ~0xf) == 0x370) {

            at -= 0x368;

        } else if ((at & ~0xf) == 0x170) {

            at -= 0x170;

        }

    }

    switch (at) {

    case 0x0:	/* Even RD Data */

    case 0x8:

        return ide_data_readw(&s->bus, 0);

        /* TODO: 8-bit accesses */

        if (s->cycle) {

            ret = s->io >> 8;

        } else {

            s->io = ide_data_readw(&s->bus, 0);

            ret = s->io & 0xff;

        }

        s->cycle = !s->cycle;

        return ret;

    case 0x9:	/* Odd RD Data */

        return s->io >> 8;

    case 0xd:	/* Error */

        return ide_ioport_read(&s->bus, 0x1);

    case 0xe:	/* Alternate Status */

        ifs = idebus_active_if(&s->bus);

        if (ifs->bs) {

            return ifs->status;

        } else {

            return 0;

        }

    case 0xf:	/* Device Address */

        ifs = idebus_active_if(&s->bus);

        return 0xc2 | ((~ifs->select << 2) & 0x3c);

    default:

        return ide_ioport_read(&s->bus, at);

    }

    return 0;

}


static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)

{

    MSDState *s = (MSDState *)dev;

    uint32_t tag;

    struct usb_msd_cbw cbw;

    uint8_t devep = p->ep->nr;

    switch (p->pid) {

    case USB_TOKEN_OUT:

        if (devep != 2)

            goto fail;

        switch (s->mode) {

        case USB_MSDM_CBW:

            if (p->iov.size != 31) {

                fprintf(stderr, "usb-msd: Bad CBW size");

                goto fail;

            }

            usb_packet_copy(p, &cbw, 31);

            if (le32_to_cpu(cbw.sig) != 0x43425355) {

                fprintf(stderr, "usb-msd: Bad signature %08x\n",

                        le32_to_cpu(cbw.sig));

                goto fail;

            }

            DPRINTF("Command on LUN %d\n", cbw.lun);

            if (cbw.lun != 0) {

                fprintf(stderr, "usb-msd: Bad LUN %d\n", cbw.lun);

                goto fail;

            }

            tag = le32_to_cpu(cbw.tag);

            s->data_len = le32_to_cpu(cbw.data_len);

            if (s->data_len == 0) {

                s->mode = USB_MSDM_CSW;

            } else if (cbw.flags & 0x80) {

                s->mode = USB_MSDM_DATAIN;

            } else {

                s->mode = USB_MSDM_DATAOUT;

            }

            DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",

                    tag, cbw.flags, cbw.cmd_len, s->data_len);

            assert(le32_to_cpu(s->csw.residue) == 0);

            s->scsi_len = 0;

            s->req = scsi_req_new(s->scsi_dev, tag, 0, cbw.cmd, NULL);

#ifdef DEBUG_MSD

            scsi_req_print(s->req);

#endif

            scsi_req_enqueue(s->req);

            if (s->req && s->req->cmd.xfer != SCSI_XFER_NONE) {

                scsi_req_continue(s->req);

            }

            break;

        case USB_MSDM_DATAOUT:

            DPRINTF("Data out %zd/%d\n", p->iov.size, s->data_len);

            if (p->iov.size > s->data_len) {

                goto fail;

            }

            if (s->scsi_len) {

                usb_msd_copy_data(s, p);

            }

            if (le32_to_cpu(s->csw.residue)) {

                int len = p->iov.size - p->actual_length;

                if (len) {

                    usb_packet_skip(p, len);

                    s->data_len -= len;

                    if (s->data_len == 0) {

                        s->mode = USB_MSDM_CSW;

                    }

                }

            }

            if (p->actual_length < p->iov.size) {

                DPRINTF("Deferring packet %p [wait data-out]\n", p);

                s->packet = p;

                p->status = USB_RET_ASYNC;

            }

            break;

        default:

            DPRINTF("Unexpected write (len %zd)\n", p->iov.size);

            goto fail;

        }

        break;

    case USB_TOKEN_IN:

        if (devep != 1)

            goto fail;

        switch (s->mode) {

        case USB_MSDM_DATAOUT:

            if (s->data_len != 0 || p->iov.size < 13) {

                goto fail;

            }

            /* Waiting for SCSI write to complete.  */

            s->packet = p;

            p->status = USB_RET_ASYNC;

            break;

        case USB_MSDM_CSW:

            if (p->iov.size < 13) {

                goto fail;

            }

            if (s->req) {

                /* still in flight */

                DPRINTF("Deferring packet %p [wait status]\n", p);

                s->packet = p;

                p->status = USB_RET_ASYNC;

            } else {

                usb_msd_send_status(s, p);

                s->mode = USB_MSDM_CBW;

            }

            break;

        case USB_MSDM_DATAIN:

            DPRINTF("Data in %zd/%d, scsi_len %d\n",

                    p->iov.size, s->data_len, s->scsi_len);

            if (s->scsi_len) {

                usb_msd_copy_data(s, p);

            }

            if (le32_to_cpu(s->csw.residue)) {

                int len = p->iov.size - p->actual_length;

                if (len) {

                    usb_packet_skip(p, len);

                    s->data_len -= len;

                    if (s->data_len == 0) {

                        s->mode = USB_MSDM_CSW;

                    }

                }

            }

            if (p->actual_length < p->iov.size) {

                DPRINTF("Deferring packet %p [wait data-in]\n", p);

                s->packet = p;

                p->status = USB_RET_ASYNC;

            }

            break;

        default:

            DPRINTF("Unexpected read (len %zd)\n", p->iov.size);

            goto fail;

        }

        break;

    default:

        DPRINTF("Bad token\n");

    fail:

        p->status = USB_RET_STALL;

        break;

    }

}


void optimize_flags_init(void)

{

    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");

    cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0,

                                       offsetof(CPUX86State, cc_op), "cc_op");

    cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_src),

                                    "cc_src");

    cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUX86State, cc_dst),

                                    "cc_dst");

#ifdef TARGET_X86_64

    cpu_regs[R_EAX] = tcg_global_mem_new_i64(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_EAX]), "rax");

    cpu_regs[R_ECX] = tcg_global_mem_new_i64(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_ECX]), "rcx");

    cpu_regs[R_EDX] = tcg_global_mem_new_i64(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_EDX]), "rdx");

    cpu_regs[R_EBX] = tcg_global_mem_new_i64(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_EBX]), "rbx");

    cpu_regs[R_ESP] = tcg_global_mem_new_i64(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_ESP]), "rsp");

    cpu_regs[R_EBP] = tcg_global_mem_new_i64(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_EBP]), "rbp");

    cpu_regs[R_ESI] = tcg_global_mem_new_i64(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_ESI]), "rsi");

    cpu_regs[R_EDI] = tcg_global_mem_new_i64(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_EDI]), "rdi");

    cpu_regs[8] = tcg_global_mem_new_i64(TCG_AREG0,

                                         offsetof(CPUX86State, regs[8]), "r8");

    cpu_regs[9] = tcg_global_mem_new_i64(TCG_AREG0,

                                          offsetof(CPUX86State, regs[9]), "r9");

    cpu_regs[10] = tcg_global_mem_new_i64(TCG_AREG0,

                                          offsetof(CPUX86State, regs[10]), "r10");

    cpu_regs[11] = tcg_global_mem_new_i64(TCG_AREG0,

                                          offsetof(CPUX86State, regs[11]), "r11");

    cpu_regs[12] = tcg_global_mem_new_i64(TCG_AREG0,

                                          offsetof(CPUX86State, regs[12]), "r12");

    cpu_regs[13] = tcg_global_mem_new_i64(TCG_AREG0,

                                          offsetof(CPUX86State, regs[13]), "r13");

    cpu_regs[14] = tcg_global_mem_new_i64(TCG_AREG0,

                                          offsetof(CPUX86State, regs[14]), "r14");

    cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0,

                                          offsetof(CPUX86State, regs[15]), "r15");

#else

    cpu_regs[R_EAX] = tcg_global_mem_new_i32(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_EAX]), "eax");

    cpu_regs[R_ECX] = tcg_global_mem_new_i32(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_ECX]), "ecx");

    cpu_regs[R_EDX] = tcg_global_mem_new_i32(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_EDX]), "edx");

    cpu_regs[R_EBX] = tcg_global_mem_new_i32(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_EBX]), "ebx");

    cpu_regs[R_ESP] = tcg_global_mem_new_i32(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_ESP]), "esp");

    cpu_regs[R_EBP] = tcg_global_mem_new_i32(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_EBP]), "ebp");

    cpu_regs[R_ESI] = tcg_global_mem_new_i32(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_ESI]), "esi");

    cpu_regs[R_EDI] = tcg_global_mem_new_i32(TCG_AREG0,

                                             offsetof(CPUX86State, regs[R_EDI]), "edi");

#endif

    /* register helpers */

#define GEN_HELPER 2

#include "helper.h"

}


static size_t handle_aiocb_rw(struct qemu_paiocb *aiocb)

{

    size_t nbytes;

    char *buf;

    if (!(aiocb->aio_type & QEMU_AIO_MISALIGNED)) {

        /*

         * If there is just a single buffer, and it is properly aligned

         * we can just use plain pread/pwrite without any problems.

         */

        if (aiocb->aio_niov == 1)

             return handle_aiocb_rw_linear(aiocb, aiocb->aio_iov->iov_base);

        /*

         * We have more than one iovec, and all are properly aligned.

         *

         * Try preadv/pwritev first and fall back to linearizing the

         * buffer if it's not supported.

         */

	if (preadv_present) {

            nbytes = handle_aiocb_rw_vector(aiocb);

            if (nbytes == aiocb->aio_nbytes)

	        return nbytes;

            if (nbytes < 0 && nbytes != -ENOSYS)

                return nbytes;

            preadv_present = 0;

        }

        /*

         * XXX(hch): short read/write.  no easy way to handle the reminder

         * using these interfaces.  For now retry using plain

         * pread/pwrite?

         */

    }

    /*

     * Ok, we have to do it the hard way, copy all segments into

     * a single aligned buffer.

     */

    buf = qemu_memalign(512, aiocb->aio_nbytes);

    if (aiocb->aio_type & QEMU_AIO_WRITE) {

        char *p = buf;

        int i;

        for (i = 0; i < aiocb->aio_niov; ++i) {

            memcpy(p, aiocb->aio_iov[i].iov_base, aiocb->aio_iov[i].iov_len);

            p += aiocb->aio_iov[i].iov_len;

        }

    }

    nbytes = handle_aiocb_rw_linear(aiocb, buf);

    if (!(aiocb->aio_type & QEMU_AIO_WRITE)) {

        char *p = buf;

        size_t count = aiocb->aio_nbytes, copy;

        int i;

        for (i = 0; i < aiocb->aio_niov && count; ++i) {

            copy = count;

            if (copy > aiocb->aio_iov[i].iov_len)

                copy = aiocb->aio_iov[i].iov_len;

            memcpy(aiocb->aio_iov[i].iov_base, p, copy);

            p     += copy;

            count -= copy;

        }

    }

    qemu_vfree(buf);

    return nbytes;

}


static int coroutine_fn bdrv_co_do_copy_on_readv(BlockDriverState *bs,

        int64_t offset, unsigned int bytes, QEMUIOVector *qiov)

{

    /* Perform I/O through a temporary buffer so that users who scribble over

     * their read buffer while the operation is in progress do not end up

     * modifying the image file.  This is critical for zero-copy guest I/O

     * where anything might happen inside guest memory.

     */

    void *bounce_buffer;

    BlockDriver *drv = bs->drv;

    struct iovec iov;

    QEMUIOVector bounce_qiov;

    int64_t cluster_offset;

    unsigned int cluster_bytes;

    size_t skip_bytes;

    int ret;

    /* Cover entire cluster so no additional backing file I/O is required when

     * allocating cluster in the image file.

     */

    bdrv_round_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes);

    trace_bdrv_co_do_copy_on_readv(bs, offset, bytes,

                                   cluster_offset, cluster_bytes);

    iov.iov_len = cluster_bytes;

    iov.iov_base = bounce_buffer = qemu_try_blockalign(bs, iov.iov_len);

    if (bounce_buffer == NULL) {

        ret = -ENOMEM;

        goto err;

    }

    qemu_iovec_init_external(&bounce_qiov, &iov, 1);

    ret = bdrv_driver_preadv(bs, cluster_offset, cluster_bytes,

                             &bounce_qiov, 0);

    if (ret < 0) {

        goto err;

    }

    if (drv->bdrv_co_pwrite_zeroes &&

        buffer_is_zero(bounce_buffer, iov.iov_len)) {

        /* FIXME: Should we (perhaps conditionally) be setting

         * BDRV_REQ_MAY_UNMAP, if it will allow for a sparser copy

         * that still correctly reads as zero? */

        ret = bdrv_co_do_pwrite_zeroes(bs, cluster_offset, cluster_bytes, 0);

    } else {

        /* This does not change the data on the disk, it is not necessary

         * to flush even in cache=writethrough mode.

         */

        ret = bdrv_driver_pwritev(bs, cluster_offset, cluster_bytes,

                                  &bounce_qiov, 0);

    }

    if (ret < 0) {

        /* It might be okay to ignore write errors for guest requests.  If this

         * is a deliberate copy-on-read then we don't want to ignore the error.

         * Simply report it in all cases.

         */

        goto err;

    }

    skip_bytes = offset - cluster_offset;

    qemu_iovec_from_buf(qiov, 0, bounce_buffer + skip_bytes, bytes);

err:

    qemu_vfree(bounce_buffer);

    return ret;

}


static int sector_limits_lun2qemu(int64_t sector, IscsiLun *iscsilun)

{

    int limit = MIN(sector_lun2qemu(sector, iscsilun), INT_MAX / 2 + 1);

    return limit < BDRV_REQUEST_MAX_SECTORS ? limit : 0;

}


static ssize_t test_block_init_func(QCryptoBlock *block,

                                    size_t headerlen,

                                    Error **errp,

                                    void *opaque)

{

    Buffer *header = opaque;

    g_assert_cmpint(header->capacity, ==, 0);

    buffer_reserve(header, headerlen);

    return headerlen;

}


e1000_mmio_write(void *opaque, hwaddr addr, uint64_t val,

                 unsigned size)

{

    E1000State *s = opaque;

    unsigned int index = (addr & 0x1ffff) >> 2;

    if (index < NWRITEOPS && macreg_writeops[index]) {

        macreg_writeops[index](s, index, val);

    } else if (index < NREADOPS && macreg_readops[index]) {

        DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04"PRIx64"\n", index<<2, val);

    } else {

        DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08"PRIx64"\n",

               index<<2, val);

    }

}


void vnc_hextile_set_pixel_conversion(VncState *vs, int generic)

{

    if (!generic) {

        switch (vs->ds->surface->pf.bits_per_pixel) {

            case 8:

                vs->send_hextile_tile = send_hextile_tile_8;

                break;

            case 16:

                vs->send_hextile_tile = send_hextile_tile_16;

                break;

            case 32:

                vs->send_hextile_tile = send_hextile_tile_32;

                break;

        }

    } else {

        switch (vs->ds->surface->pf.bits_per_pixel) {

            case 8:

                vs->send_hextile_tile = send_hextile_tile_generic_8;

                break;

            case 16:

                vs->send_hextile_tile = send_hextile_tile_generic_16;

                break;

            case 32:

                vs->send_hextile_tile = send_hextile_tile_generic_32;

                break;

        }

    }

}


static void qemu_rbd_aio_event_reader(void *opaque)

{

    BDRVRBDState *s = opaque;

    ssize_t ret;

    do {

        char *p = (char *)&s->event_rcb;

        /* now read the rcb pointer that was sent from a non qemu thread */

        if ((ret = read(s->fds[RBD_FD_READ], p + s->event_reader_pos,

                        sizeof(s->event_rcb) - s->event_reader_pos)) > 0) {

            if (ret > 0) {

                s->event_reader_pos += ret;

                if (s->event_reader_pos == sizeof(s->event_rcb)) {

                    s->event_reader_pos = 0;

                    qemu_rbd_complete_aio(s->event_rcb);

                    s->qemu_aio_count--;

                }

            }

        }

    } while (ret < 0 && errno == EINTR);

}


static coroutine_fn int send_co_req(int sockfd, SheepdogReq *hdr, void *data,

                                    unsigned int *wlen)

{

    int ret;

    ret = qemu_co_send(sockfd, hdr, sizeof(*hdr));

    if (ret < sizeof(*hdr)) {

        error_report("failed to send a req, %s", strerror(errno));

        return ret;

    }

    ret = qemu_co_send(sockfd, data, *wlen);

    if (ret < *wlen) {

        error_report("failed to send a req, %s", strerror(errno));

    }

    return ret;

}


static inline void start_exclusive(void)

{

    CPUState *other;

    pthread_mutex_lock(&exclusive_lock);

    exclusive_idle();

    pending_cpus = 1;

    /* Make all other cpus stop executing.  */

    for (other = first_cpu; other; other = other->next_cpu) {

        if (other->running) {

            pending_cpus++;

            cpu_interrupt(other, CPU_INTERRUPT_EXIT);

        }

    }

    if (pending_cpus > 1) {

        pthread_cond_wait(&exclusive_cond, &exclusive_lock);

    }

}


matroska_parse_cluster (MatroskaDemuxContext *matroska)

{

    int res = 0;

    uint32_t id;

    uint64_t cluster_time = 0;

    uint8_t *data;

    int64_t pos;

    int size;

    av_log(matroska->ctx, AV_LOG_DEBUG,

           "parsing cluster at %"PRId64"\n", url_ftell(&matroska->ctx->pb));

    while (res == 0) {

        if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {

            res = AVERROR_IO;

            break;

        } else if (matroska->level_up) {

            matroska->level_up--;

            break;

        }

        switch (id) {

            /* cluster timecode */

            case MATROSKA_ID_CLUSTERTIMECODE: {

                uint64_t num;

                if ((res = ebml_read_uint(matroska, &id, &num)) < 0)

                    break;

                cluster_time = num;

                break;

            }

                /* a group of blocks inside a cluster */

            case MATROSKA_ID_BLOCKGROUP:

                if ((res = ebml_read_master(matroska, &id)) < 0)

                    break;

                res = matroska_parse_blockgroup(matroska, cluster_time);

                break;

            case MATROSKA_ID_SIMPLEBLOCK:

                pos = url_ftell(&matroska->ctx->pb);

                res = ebml_read_binary(matroska, &id, &data, &size);

                if (res == 0)

                    res = matroska_parse_block(matroska, data, size, pos,

                                               cluster_time, -1, NULL, NULL);

                break;

            default:

                av_log(matroska->ctx, AV_LOG_INFO,

                       "Unknown entry 0x%x in cluster data\n", id);

                /* fall-through */

            case EBML_ID_VOID:

                res = ebml_read_skip(matroska);

                break;

        }

        if (matroska->level_up) {

            matroska->level_up--;

            break;

        }

    }

    return res;

}


static inline void gen_evsel(DisasContext *ctx)

{

    int l1 = gen_new_label();

    int l2 = gen_new_label();

    int l3 = gen_new_label();

    int l4 = gen_new_label();

    TCGv_i32 t0 = tcg_temp_local_new_i32();

    tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);

    tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);

    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);

    tcg_gen_br(l2);

    gen_set_label(l1);

    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);

    gen_set_label(l2);

    tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);

    tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);

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

    tcg_gen_br(l4);

    gen_set_label(l3);

    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);

    gen_set_label(l4);

    tcg_temp_free_i32(t0);

}


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

{

    CPUState *cs = CPU(dev);

    X86CPU *cpu = X86_CPU(dev);

    X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);

    CPUX86State *env = &cpu->env;

    Error *local_err = NULL;

    static bool ht_warned;

    if (xcc->kvm_required && !kvm_enabled()) {

        char *name = x86_cpu_class_get_model_name(xcc);

        error_setg(&local_err, "CPU model '%s' requires KVM", name);

        g_free(name);

        goto out;

    }

    if (cpu->apic_id == UNASSIGNED_APIC_ID) {

        error_setg(errp, "apic-id property was not initialized properly");

        return;

    }

    x86_cpu_load_features(cpu, &local_err);

    if (local_err) {

        goto out;

    }

    if (x86_cpu_filter_features(cpu) &&

        (cpu->check_cpuid || cpu->enforce_cpuid)) {

        x86_cpu_report_filtered_features(cpu);

        if (cpu->enforce_cpuid) {

            error_setg(&local_err,

                       kvm_enabled() ?

                           "Host doesn't support requested features" :

                           "TCG doesn't support requested features");

            goto out;

        }

    }

    /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on

     * CPUID[1].EDX.

     */

    if (IS_AMD_CPU(env)) {

        env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;

        env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]

           & CPUID_EXT2_AMD_ALIASES);

    }

    /* For 64bit systems think about the number of physical bits to present.

     * ideally this should be the same as the host; anything other than matching

     * the host can cause incorrect guest behaviour.

     * QEMU used to pick the magic value of 40 bits that corresponds to

     * consumer AMD devices but nothing else.

     */

    if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {

        if (kvm_enabled()) {

            uint32_t host_phys_bits = x86_host_phys_bits();

            static bool warned;

            if (cpu->host_phys_bits) {

                /* The user asked for us to use the host physical bits */

                cpu->phys_bits = host_phys_bits;

            }

            /* Print a warning if the user set it to a value that's not the

             * host value.

             */

            if (cpu->phys_bits != host_phys_bits && cpu->phys_bits != 0 &&

                !warned) {

                error_report("Warning: Host physical bits (%u)"

                                 " does not match phys-bits property (%u)",

                                 host_phys_bits, cpu->phys_bits);

                warned = true;

            }

            if (cpu->phys_bits &&

                (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||

                cpu->phys_bits < 32)) {

                error_setg(errp, "phys-bits should be between 32 and %u "

                                 " (but is %u)",

                                 TARGET_PHYS_ADDR_SPACE_BITS, cpu->phys_bits);

                return;

            }

        } else {

            if (cpu->phys_bits && cpu->phys_bits != TCG_PHYS_ADDR_BITS) {

                error_setg(errp, "TCG only supports phys-bits=%u",

                                  TCG_PHYS_ADDR_BITS);

                return;

            }

        }

        /* 0 means it was not explicitly set by the user (or by machine

         * compat_props or by the host code above). In this case, the default

         * is the value used by TCG (40).

         */

        if (cpu->phys_bits == 0) {

            cpu->phys_bits = TCG_PHYS_ADDR_BITS;

        }

    } else {

        /* For 32 bit systems don't use the user set value, but keep

         * phys_bits consistent with what we tell the guest.

         */

        if (cpu->phys_bits != 0) {

            error_setg(errp, "phys-bits is not user-configurable in 32 bit");

            return;

        }

        if (env->features[FEAT_1_EDX] & CPUID_PSE36) {

            cpu->phys_bits = 36;

        } else {

            cpu->phys_bits = 32;

        }

    }

    cpu_exec_init(cs, &error_abort);

    if (tcg_enabled()) {

        tcg_x86_init();

    }

#ifndef CONFIG_USER_ONLY

    qemu_register_reset(x86_cpu_machine_reset_cb, cpu);

    if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {

        x86_cpu_apic_create(cpu, &local_err);

        if (local_err != NULL) {

            goto out;

        }

    }

#endif

    mce_init(cpu);

#ifndef CONFIG_USER_ONLY

    if (tcg_enabled()) {

        AddressSpace *newas = g_new(AddressSpace, 1);

        cpu->cpu_as_mem = g_new(MemoryRegion, 1);

        cpu->cpu_as_root = g_new(MemoryRegion, 1);

        /* Outer container... */

        memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);

        memory_region_set_enabled(cpu->cpu_as_root, true);

        /* ... with two regions inside: normal system memory with low

         * priority, and...

         */

        memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",

                                 get_system_memory(), 0, ~0ull);

        memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);

        memory_region_set_enabled(cpu->cpu_as_mem, true);

        address_space_init(newas, cpu->cpu_as_root, "CPU");

        cs->num_ases = 1;

        cpu_address_space_init(cs, newas, 0);

        /* ... SMRAM with higher priority, linked from /machine/smram.  */

        cpu->machine_done.notify = x86_cpu_machine_done;

        qemu_add_machine_init_done_notifier(&cpu->machine_done);

    }

#endif

    qemu_init_vcpu(cs);

    /* Only Intel CPUs support hyperthreading. Even though QEMU fixes this

     * issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX

     * based on inputs (sockets,cores,threads), it is still better to gives

     * users a warning.

     *

     * NOTE: the following code has to follow qemu_init_vcpu(). Otherwise

     * cs->nr_threads hasn't be populated yet and the checking is incorrect.

     */

    if (!IS_INTEL_CPU(env) && cs->nr_threads > 1 && !ht_warned) {

        error_report("AMD CPU doesn't support hyperthreading. Please configure"

                     " -smp options properly.");

        ht_warned = true;

    }

    x86_cpu_apic_realize(cpu, &local_err);

    if (local_err != NULL) {

        goto out;

    }

    cpu_reset(cs);

    xcc->parent_realize(dev, &local_err);

out:

    if (local_err != NULL) {

        error_propagate(errp, local_err);

        return;

    }

}


static int http_proxy_open(URLContext *h, const char *uri, int flags)

{

    HTTPContext *s = h->priv_data;

    char hostname[1024], hoststr[1024];

    char auth[1024], pathbuf[1024], *path;

    char line[1024], lower_url[100];

    int port, ret = 0;

    HTTPAuthType cur_auth_type;

    char *authstr;

    h->is_streamed = 1;

    av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,

                 pathbuf, sizeof(pathbuf), uri);

    ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);

    path = pathbuf;

    if (*path == '/')

        path++;

    ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port,

                NULL);

redo:

    ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE,

                     &h->interrupt_callback, NULL);

    if (ret < 0)

        return ret;

    authstr = ff_http_auth_create_response(&s->proxy_auth_state, auth,

                                           path, "CONNECT");

    snprintf(s->buffer, sizeof(s->buffer),

             "CONNECT %s HTTP/1.1\r\n"

             "Host: %s\r\n"

             "Connection: close\r\n"

             "%s%s"

             "\r\n",

             path,

             hoststr,

             authstr ? "Proxy-" : "", authstr ? authstr : "");

    av_freep(&authstr);

    if ((ret = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0)

        goto fail;

    s->buf_ptr = s->buffer;

    s->buf_end = s->buffer;

    s->line_count = 0;

    s->filesize = -1;

    cur_auth_type = s->proxy_auth_state.auth_type;

    for (;;) {

        int new_loc;

        // Note: This uses buffering, potentially reading more than the

        // HTTP header. If tunneling a protocol where the server starts

        // the conversation, we might buffer part of that here, too.

        // Reading that requires using the proper ffurl_read() function

        // on this URLContext, not using the fd directly (as the tls

        // protocol does). This shouldn't be an issue for tls though,

        // since the client starts the conversation there, so there

        // is no extra data that we might buffer up here.

        if (http_get_line(s, line, sizeof(line)) < 0) {

            ret = AVERROR(EIO);

            goto fail;

        }

        av_dlog(h, "header='%s'\n", line);

        ret = process_line(h, line, s->line_count, &new_loc);

        if (ret < 0)

            goto fail;

        if (ret == 0)

            break;

        s->line_count++;

    }

    if (s->http_code == 407 && cur_auth_type == HTTP_AUTH_NONE &&

        s->proxy_auth_state.auth_type != HTTP_AUTH_NONE) {

        ffurl_close(s->hd);

        s->hd = NULL;

        goto redo;

    }

    if (s->http_code < 400)

        return 0;

    ret = AVERROR(EIO);

fail:

    http_proxy_close(h);

    return ret;

}


void rtp_parse_close(RTPDemuxContext *s)

{

    // TODO: fold this into the protocol specific data fields.

    if (!strcmp(ff_rtp_enc_name(s->payload_type), "MP2T")) {

        ff_mpegts_parse_close(s->ts);

    }

    av_free(s);

}


static long gethugepagesize(const char *path, Error **errp)

{

    struct statfs fs;

    int ret;

    do {

        ret = statfs(path, &fs);

    } while (ret != 0 && errno == EINTR);

    if (ret != 0) {

        error_setg_errno(errp, errno, "failed to get page size of file %s",

                         path);

        return 0;

    }

    return fs.f_bsize;

}


void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,

                         void (*func)(QPCIDevice *dev, int devfn, void *data),

                         void *data)

{

    int slot;

    for (slot = 0; slot < 32; slot++) {

        int fn;

        for (fn = 0; fn < 8; fn++) {

            QPCIDevice *dev;

            dev = qpci_device_find(bus, QPCI_DEVFN(slot, fn));

            if (!dev) {

                continue;

            }

            if (vendor_id != -1 &&

                qpci_config_readw(dev, PCI_VENDOR_ID) != vendor_id) {

                continue;

            }

            if (device_id != -1 &&

                qpci_config_readw(dev, PCI_DEVICE_ID) != device_id) {

                continue;

            }

            func(dev, QPCI_DEVFN(slot, fn), data);

        }

    }

}


static int vc1_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            const uint8_t *buf, int buf_size)

{

    VC1Context *v = avctx->priv_data;

    MpegEncContext *s = &v->s;

    AVFrame *pict = data;

    uint8_t *buf2 = NULL;

    /* no supplementary picture */

    if (buf_size == 0) {

        /* special case for last picture */

        if (s->low_delay==0 && s->next_picture_ptr) {

            *pict= *(AVFrame*)s->next_picture_ptr;

            s->next_picture_ptr= NULL;

            *data_size = sizeof(AVFrame);

        }

        return 0;

    }

    /* We need to set current_picture_ptr before reading the header,

     * otherwise we cannot store anything in there. */

    if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){

        int i= ff_find_unused_picture(s, 0);

        s->current_picture_ptr= &s->picture[i];

    }

    //for advanced profile we may need to parse and unescape data

    if (avctx->codec_id == CODEC_ID_VC1) {

        int buf_size2 = 0;

        buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);

        if(IS_MARKER(AV_RB32(buf))){ /* frame starts with marker and needs to be parsed */

            const uint8_t *start, *end, *next;

            int size;

            next = buf;

            for(start = buf, end = buf + buf_size; next < end; start = next){

                next = find_next_marker(start + 4, end);

                size = next - start - 4;

                if(size <= 0) continue;

                switch(AV_RB32(start)){

                case VC1_CODE_FRAME:

                    buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);

                    break;

                case VC1_CODE_ENTRYPOINT: /* it should be before frame data */

                    buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);

                    init_get_bits(&s->gb, buf2, buf_size2*8);

                    decode_entry_point(avctx, &s->gb);

                    break;

                case VC1_CODE_SLICE:

                    av_log(avctx, AV_LOG_ERROR, "Sliced decoding is not implemented (yet)\n");

                    return -1;

                }

            }

        }else if(v->interlace && ((buf[0] & 0xC0) == 0xC0)){ /* WVC1 interlaced stores both fields divided by marker */

            const uint8_t *divider;

            divider = find_next_marker(buf, buf + buf_size);

            if((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD){

                av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n");

                return -1;

            }

            buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2);

            // TODO

            av_free(buf2);return -1;

        }else{

            buf_size2 = vc1_unescape_buffer(buf, buf_size, buf2);

        }

        init_get_bits(&s->gb, buf2, buf_size2*8);

    } else

        init_get_bits(&s->gb, buf, buf_size*8);

    // do parse frame header

    if(v->profile < PROFILE_ADVANCED) {

        if(vc1_parse_frame_header(v, &s->gb) == -1) {

            return -1;

        }

    } else {

        if(vc1_parse_frame_header_adv(v, &s->gb) == -1) {

            return -1;

        }

    }

    if(s->pict_type != FF_I_TYPE && !v->res_rtm_flag){

        return -1;

    }

    // for hurry_up==5

    s->current_picture.pict_type= s->pict_type;

    s->current_picture.key_frame= s->pict_type == FF_I_TYPE;

    /* skip B-frames if we don't have reference frames */

    if(s->last_picture_ptr==NULL && (s->pict_type==FF_B_TYPE || s->dropable)){

        return -1;//buf_size;

    }

    /* skip b frames if we are in a hurry */

    if(avctx->hurry_up && s->pict_type==FF_B_TYPE) return -1;//buf_size;

    if(   (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==FF_B_TYPE)

       || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=FF_I_TYPE)

       ||  avctx->skip_frame >= AVDISCARD_ALL) {

        return buf_size;

    }

    /* skip everything if we are in a hurry>=5 */

    if(avctx->hurry_up>=5) {

        return -1;//buf_size;

    }

    if(s->next_p_frame_damaged){

        if(s->pict_type==FF_B_TYPE)

            return buf_size;

        else

            s->next_p_frame_damaged=0;

    }

    if(MPV_frame_start(s, avctx) < 0) {

        return -1;

    }

    s->me.qpel_put= s->dsp.put_qpel_pixels_tab;

    s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;

    ff_er_frame_start(s);

    v->bits = buf_size * 8;

    vc1_decode_blocks(v);

//av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), buf_size*8);

//  if(get_bits_count(&s->gb) > buf_size * 8)

//      return -1;

    ff_er_frame_end(s);

    MPV_frame_end(s);

assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);

assert(s->current_picture.pict_type == s->pict_type);

    if (s->pict_type == FF_B_TYPE || s->low_delay) {

        *pict= *(AVFrame*)s->current_picture_ptr;

    } else if (s->last_picture_ptr != NULL) {

        *pict= *(AVFrame*)s->last_picture_ptr;

    }

    if(s->last_picture_ptr || s->low_delay){

        *data_size = sizeof(AVFrame);

        ff_print_debug_info(s, pict);

    }

    /* Return the Picture timestamp as the frame number */

    /* we subtract 1 because it is added on utils.c     */

    avctx->frame_number = s->picture_number - 1;

    return buf_size;

}


static int configuration_post_load(void *opaque, int version_id)

{

    SaveState *state = opaque;

    const char *current_name = MACHINE_GET_CLASS(current_machine)->name;

    if (strncmp(state->name, current_name, state->len) != 0) {

        error_report("Machine type received is '%s' and local is '%s'",

                     state->name, current_name);

        return -EINVAL;

    }

    return 0;

}


static inline void vmsvga_copy_rect(struct vmsvga_state_s *s,

                int x0, int y0, int x1, int y1, int w, int h)

{

    DisplaySurface *surface = qemu_console_surface(s->vga.con);

    uint8_t *vram = s->vga.vram_ptr;

    int bypl = surface_stride(surface);

    int bypp = surface_bytes_per_pixel(surface);

    int width = bypp * w;

    int line = h;

    uint8_t *ptr[2];

    if (y1 > y0) {

        ptr[0] = vram + bypp * x0 + bypl * (y0 + h - 1);

        ptr[1] = vram + bypp * x1 + bypl * (y1 + h - 1);

        for (; line > 0; line --, ptr[0] -= bypl, ptr[1] -= bypl) {

            memmove(ptr[1], ptr[0], width);

        }

    } else {

        ptr[0] = vram + bypp * x0 + bypl * y0;

        ptr[1] = vram + bypp * x1 + bypl * y1;

        for (; line > 0; line --, ptr[0] += bypl, ptr[1] += bypl) {

            memmove(ptr[1], ptr[0], width);

        }

    }

    vmsvga_update_rect_delayed(s, x1, y1, w, h);

}


static inline int decode_mb(MDECContext *a, DCTELEM block[6][64]){

    int i;

    const int block_index[6]= {5,4,0,1,2,3};

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

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

        if( mdec_decode_block_intra(a, block[ block_index[i] ], block_index[i]) < 0)

            return -1;

    }

    return 0;

}


static int vnc_start_vencrypt_handshake(VncState *vs)

{

    int ret;

    if ((ret = gnutls_handshake(vs->tls.session)) < 0) {

       if (!gnutls_error_is_fatal(ret)) {

           VNC_DEBUG("Handshake interrupted (blocking)\n");

           if (!gnutls_record_get_direction(vs->tls.session))

               qemu_set_fd_handler(vs->csock, vnc_tls_handshake_io, NULL, vs);

           else

               qemu_set_fd_handler(vs->csock, NULL, vnc_tls_handshake_io, vs);

           return 0;

       }

       VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));

       vnc_client_error(vs);

       return -1;

    }

    if (vs->vd->tls.x509verify) {

        if (vnc_tls_validate_certificate(vs) < 0) {

            VNC_DEBUG("Client verification failed\n");

            vnc_client_error(vs);

            return -1;

        } else {

            VNC_DEBUG("Client verification passed\n");

        }

    }

    VNC_DEBUG("Handshake done, switching to TLS data mode\n");

    qemu_set_fd_handler(vs->csock, vnc_client_read, vnc_client_write, vs);

    start_auth_vencrypt_subauth(vs);

    return 0;

}


static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)

{

    VirtIOBlockReq *req = g_slice_new(VirtIOBlockReq);

    req->dev = s;

    req->qiov.size = 0;

    req->next = NULL;

    req->elem = g_slice_new(VirtQueueElement);

    return req;

}


static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize)

{

    SCPRContext *s = avctx->priv_data;

    GetByteContext *gb = &s->gb;

    int cx = 0, cx1 = 0, k = 0, clr = 0;

    int run, r, g, b, off, y = 0, x = 0, z, ret;

    unsigned backstep = linesize - avctx->width;

    const int cxshift = s->cxshift;

    unsigned lx, ly, ptype;

    reinit_tables(s);

    bytestream2_skip(gb, 2);

    init_rangecoder(&s->rc, gb);

    while (k < avctx->width + 1) {

        ret = decode_unit(s, &s->pixel_model[0][cx + cx1], 400, &r);

        if (ret < 0)

            return ret;

        cx1 = (cx << 6) & 0xFC0;

        cx = r >> cxshift;

        ret = decode_unit(s, &s->pixel_model[1][cx + cx1], 400, &g);

        if (ret < 0)

            return ret;

        cx1 = (cx << 6) & 0xFC0;

        cx = g >> cxshift;

        ret = decode_unit(s, &s->pixel_model[2][cx + cx1], 400, &b);

        if (ret < 0)

            return ret;

        cx1 = (cx << 6) & 0xFC0;

        cx = b >> cxshift;

        ret = decode_value(s, s->run_model[0], 256, 400, &run);

        if (ret < 0)

            return ret;

        clr = (b << 16) + (g << 8) + r;

        k += run;

        while (run-- > 0) {

            if (y >= avctx->height)

                return AVERROR_INVALIDDATA;

            dst[y * linesize + x] = clr;

            lx = x;

            ly = y;

            x++;

            if (x >= avctx->width) {

                x = 0;

                y++;

            }

        }

    }

    off = -linesize - 1;

    ptype = 0;

    while (x < avctx->width && y < avctx->height) {

        ret = decode_value(s, s->op_model[ptype], 6, 1000, &ptype);

        if (ret < 0)

            return ret;

        if (ptype == 0) {

            ret = decode_unit(s, &s->pixel_model[0][cx + cx1], 400, &r);

            if (ret < 0)

                return ret;

            cx1 = (cx << 6) & 0xFC0;

            cx = r >> cxshift;

            ret = decode_unit(s, &s->pixel_model[1][cx + cx1], 400, &g);

            if (ret < 0)

                return ret;

            cx1 = (cx << 6) & 0xFC0;

            cx = g >> cxshift;

            ret = decode_unit(s, &s->pixel_model[2][cx + cx1], 400, &b);

            if (ret < 0)

                return ret;

            clr = (b << 16) + (g << 8) + r;

        }

        if (ptype > 5)

            return AVERROR_INVALIDDATA;

        ret = decode_value(s, s->run_model[ptype], 256, 400, &run);

        if (ret < 0)

            return ret;

        switch (ptype) {

        case 0:

            while (run-- > 0) {

                if (y >= avctx->height)

                    return AVERROR_INVALIDDATA;

                dst[y * linesize + x] = clr;

                lx = x;

                ly = y;

                x++;

                if (x >= avctx->width) {

                    x = 0;

                    y++;

                }

            }

            break;

        case 1:

            while (run-- > 0) {

                if (y >= avctx->height)

                    return AVERROR_INVALIDDATA;

                dst[y * linesize + x] = dst[ly * linesize + lx];

                lx = x;

                ly = y;

                x++;

                if (x >= avctx->width) {

                    x = 0;

                    y++;

                }

            }

            clr = dst[ly * linesize + lx];

            break;

        case 2:

            while (run-- > 0) {

                if (y < 1 || y >= avctx->height)

                    return AVERROR_INVALIDDATA;

                clr = dst[y * linesize + x + off + 1];

                dst[y * linesize + x] = clr;

                lx = x;

                ly = y;

                x++;

                if (x >= avctx->width) {

                    x = 0;

                    y++;

                }

            }

            break;

        case 4:

            while (run-- > 0) {

                uint8_t *odst = (uint8_t *)dst;

                if (y < 1 || y >= avctx->height ||

                    (y == 1 && x == 0))

                    return AVERROR_INVALIDDATA;

                if (x == 0) {

                    z = backstep;

                } else {

                    z = 0;

                }

                r = odst[(ly * linesize + lx) * 4] +

                    odst[((y * linesize + x) + off - z) * 4 + 4] -

                    odst[((y * linesize + x) + off - z) * 4];

                g = odst[(ly * linesize + lx) * 4 + 1] +

                    odst[((y * linesize + x) + off - z) * 4 + 5] -

                    odst[((y * linesize + x) + off - z) * 4 + 1];

                b = odst[(ly * linesize + lx) * 4 + 2] +

                    odst[((y * linesize + x) + off - z) * 4 + 6] -

                    odst[((y * linesize + x) + off - z) * 4 + 2];

                clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF);

                dst[y * linesize + x] = clr;

                lx = x;

                ly = y;

                x++;

                if (x >= avctx->width) {

                    x = 0;

                    y++;

                }

            }

            break;

        case 5:

            while (run-- > 0) {

                if (y < 1 || y >= avctx->height ||

                    (y == 1 && x == 0))

                    return AVERROR_INVALIDDATA;

                if (x == 0) {

                    z = backstep;

                } else {

                    z = 0;

                }

                clr = dst[y * linesize + x + off - z];

                dst[y * linesize + x] = clr;

                lx = x;

                ly = y;

                x++;

                if (x >= avctx->width) {

                    x = 0;

                    y++;

                }

            }

            break;

        }

        if (avctx->bits_per_coded_sample == 16) {

            cx1 = (clr & 0x3F00) >> 2;

            cx = (clr & 0xFFFFFF) >> 16;

        } else {

            cx1 = (clr & 0xFC00) >> 4;

            cx = (clr & 0xFFFFFF) >> 18;

        }

    }

    return 0;

}


static int scale_vector(int16_t *vector, int length)

{

    int bits, max = 0;

    int64_t scale;

    int i;

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

        max = FFMAX(max, FFABS(vector[i]));

    max   = FFMIN(max, 0x7FFF);

    bits  = normalize_bits(max, 15);

    scale = (bits == 15) ? 0x7FFF : (1 << bits);

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

        vector[i] = av_clipl_int32(vector[i] * scale << 1) >> 4;

    return bits - 3;

}


static int fileTest(uint8_t *ref[4], int refStride[4], int w, int h, FILE *fp,

                    enum AVPixelFormat srcFormat_in,

                    enum AVPixelFormat dstFormat_in)

{

    char buf[256];

    while (fgets(buf, sizeof(buf), fp)) {

        struct Results r;

        enum AVPixelFormat srcFormat;

        char srcStr[12];

        int srcW, srcH;

        enum AVPixelFormat dstFormat;

        char dstStr[12];

        int dstW, dstH;

        int flags;

        int ret;

        ret = sscanf(buf,

                     " %12s %dx%d -> %12s %dx%d flags=%d CRC=%x"

                     " SSD=%"SCNu64 ", %"SCNu64 ", %"SCNu64 ", %"SCNu64 "\n",

                     srcStr, &srcW, &srcH, dstStr, &dstW, &dstH,

                     &flags, &r.crc, &r.ssdY, &r.ssdU, &r.ssdV, &r.ssdA);

        if (ret != 12) {

            srcStr[0] = dstStr[0] = 0;

            ret       = sscanf(buf, "%12s -> %12s\n", srcStr, dstStr);

        }

        srcFormat = av_get_pix_fmt(srcStr);

        dstFormat = av_get_pix_fmt(dstStr);

        if (srcFormat == AV_PIX_FMT_NONE || dstFormat == AV_PIX_FMT_NONE ||

            srcW > 8192U || srcH > 8192U || dstW > 8192U || dstH > 8192U) {

            fprintf(stderr, "malformed input file\n");

            return -1;

        }

        if ((srcFormat_in != AV_PIX_FMT_NONE && srcFormat_in != srcFormat) ||

            (dstFormat_in != AV_PIX_FMT_NONE && dstFormat_in != dstFormat))

            continue;

        if (ret != 12) {

            printf("%s", buf);

            continue;

        }

        doTest(ref, refStride, w, h,

               srcFormat, dstFormat,

               srcW, srcH, dstW, dstH, flags,

               &r);

    }

    return 0;

}


static int lut2_config_output(AVFilterLink *outlink)

{

    AVFilterContext *ctx = outlink->src;

    LUT2Context *s = ctx->priv;

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

    AVFilterLink *srcy = ctx->inputs[1];

    FFFrameSyncIn *in;

    int ret;

    if (srcx->format != srcy->format) {

        av_log(ctx, AV_LOG_ERROR, "inputs must be of same pixel format\n");

        return AVERROR(EINVAL);

    }

    if (srcx->w                       != srcy->w ||

        srcx->h                       != srcy->h ||

        srcx->sample_aspect_ratio.num != srcy->sample_aspect_ratio.num ||

        srcx->sample_aspect_ratio.den != srcy->sample_aspect_ratio.den) {

        av_log(ctx, AV_LOG_ERROR, "First input link %s parameters "

               "(size %dx%d, SAR %d:%d) do not match the corresponding "

               "second input link %s parameters (%dx%d, SAR %d:%d)\n",

               ctx->input_pads[0].name, srcx->w, srcx->h,

               srcx->sample_aspect_ratio.num,

               srcx->sample_aspect_ratio.den,

               ctx->input_pads[1].name,

               srcy->w, srcy->h,

               srcy->sample_aspect_ratio.num,

               srcy->sample_aspect_ratio.den);

        return AVERROR(EINVAL);

    }

    outlink->w = srcx->w;

    outlink->h = srcx->h;

    outlink->time_base = srcx->time_base;

    outlink->sample_aspect_ratio = srcx->sample_aspect_ratio;

    outlink->frame_rate = srcx->frame_rate;

    if ((ret = ff_framesync2_init(&s->fs, ctx, 2)) < 0)

        return ret;

    in = s->fs.in;

    in[0].time_base = srcx->time_base;

    in[1].time_base = srcy->time_base;

    in[0].sync   = 1;

    in[0].before = EXT_STOP;

    in[0].after  = EXT_INFINITY;

    in[1].sync   = 1;

    in[1].before = EXT_STOP;

    in[1].after  = EXT_INFINITY;

    s->fs.opaque   = s;

    s->fs.on_event = process_frame;

    if ((ret = config_output(outlink)) < 0)

        return ret;

    return ff_framesync2_configure(&s->fs);

}


void do_subfe (void)

{

    T0 = T1 + ~T0 + xer_ca;

    if (likely(T0 >= T1 && (xer_ca == 0 || T0 != T1))) {

        xer_ca = 0;

    } else {

        xer_ca = 1;

    }

}