static void spr_read_tbu (DisasContext *ctx, int gprn, int sprn)

{

    if (use_icount) {

        gen_io_start();

    }

    gen_helper_load_tbu(cpu_gpr[gprn], cpu_env);

    if (use_icount) {

        gen_io_end();

        gen_stop_exception(ctx);

    }

}


static void nvdimm_build_common_dsm(Aml *dev)

{

    Aml *method, *ifctx, *function, *dsm_mem, *unpatched, *result_size;

    uint8_t byte_list[1];

    method = aml_method(NVDIMM_COMMON_DSM, 4, AML_SERIALIZED);

    function = aml_arg(2);

    dsm_mem = aml_name(NVDIMM_ACPI_MEM_ADDR);

    /*

     * do not support any method if DSM memory address has not been

     * patched.

     */

    unpatched = aml_if(aml_equal(dsm_mem, aml_int(0x0)));

    /*

     * function 0 is called to inquire what functions are supported by

     * OSPM

     */

    ifctx = aml_if(aml_equal(function, aml_int(0)));

    byte_list[0] = 0 /* No function Supported */;

    aml_append(ifctx, aml_return(aml_buffer(1, byte_list)));

    aml_append(unpatched, ifctx);

    /* No function is supported yet. */

    byte_list[0] = 1 /* Not Supported */;

    aml_append(unpatched, aml_return(aml_buffer(1, byte_list)));

    aml_append(method, unpatched);

    /*

     * The HDLE indicates the DSM function is issued from which device,

     * it is not used at this time as no function is supported yet.

     * Currently we make it always be 0 for all the devices and will set

     * the appropriate value once real function is implemented.

     */

    aml_append(method, aml_store(aml_int(0x0), aml_name("HDLE")));

    aml_append(method, aml_store(aml_arg(1), aml_name("REVS")));

    aml_append(method, aml_store(aml_arg(2), aml_name("FUNC")));

    /*

     * tell QEMU about the real address of DSM memory, then QEMU

     * gets the control and fills the result in DSM memory.

     */

    aml_append(method, aml_store(dsm_mem, aml_name("NTFI")));

    result_size = aml_local(1);

    aml_append(method, aml_store(aml_name("RLEN"), result_size));

    aml_append(method, aml_store(aml_shiftleft(result_size, aml_int(3)),

                                 result_size));

    aml_append(method, aml_create_field(aml_name("ODAT"), aml_int(0),

                                        result_size, "OBUF"));

    aml_append(method, aml_concatenate(aml_buffer(0, NULL), aml_name("OBUF"),

                                       aml_arg(6)));

    aml_append(method, aml_return(aml_arg(6)));

    aml_append(dev, method);

}


static gnutls_anon_server_credentials vnc_tls_initialize_anon_cred(void)

{

    gnutls_anon_server_credentials anon_cred;

    int ret;

    if ((ret = gnutls_anon_allocate_server_credentials(&anon_cred)) < 0) {

	VNC_DEBUG("Cannot allocate credentials %s\n", gnutls_strerror(ret));

	return NULL;

    }

    gnutls_anon_set_server_dh_params(anon_cred, dh_params);

    return anon_cred;

}


static int zero_single_l2(BlockDriverState *bs, uint64_t offset,

    unsigned int nb_clusters)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t *l2_table;

    int l2_index;

    int ret;

    int i;

    ret = get_cluster_table(bs, offset, &l2_table, &l2_index);

    if (ret < 0) {

        return ret;

    }

    /* Limit nb_clusters to one L2 table */

    nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);

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

        uint64_t old_offset;

        old_offset = be64_to_cpu(l2_table[l2_index + i]);

        /* Update L2 entries */

        qcow2_cache_entry_mark_dirty(bs, s->l2_table_cache, l2_table);

        if (old_offset & QCOW_OFLAG_COMPRESSED) {

            l2_table[l2_index + i] = cpu_to_be64(QCOW_OFLAG_ZERO);

            qcow2_free_any_clusters(bs, old_offset, 1, QCOW2_DISCARD_REQUEST);

        } else {

            l2_table[l2_index + i] |= cpu_to_be64(QCOW_OFLAG_ZERO);

        }

    }

    ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);

    if (ret < 0) {

        return ret;

    }

    return nb_clusters;

}


static AddressSpace *s390_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)

{

    S390pciState *s = opaque;

    return &s->pbdev[PCI_SLOT(devfn)].as;

}


static void test_info_commands(void)

{

    char *resp, *info, *info_buf, *endp;

    info_buf = info = hmp("help info");

    while (*info) {

        /* Extract the info command, ignore parameters and description */

        g_assert(strncmp(info, "info ", 5) == 0);

        endp = strchr(&info[5], ' ');

        g_assert(endp != NULL);

        *endp = '\0';

        /* Now run the info command */

        if (verbose) {

            fprintf(stderr, "\t%s\n", info);

        }

        resp = hmp(info);

        g_free(resp);

        /* And move forward to the next line */

        info = strchr(endp + 1, '\n');

        if (!info) {

            break;

        }

        info += 1;

    }

    g_free(info_buf);

}


static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)

{

    uint8_t *old_code_ptr = s->code_ptr;

    assert(ret != arg);

#if TCG_TARGET_REG_BITS == 32

    tcg_out_op_t(s, INDEX_op_mov_i32);

#else

    tcg_out_op_t(s, INDEX_op_mov_i64);

#endif

    tcg_out_r(s, ret);

    tcg_out_r(s, arg);

    old_code_ptr[1] = s->code_ptr - old_code_ptr;

}


static int do_token_in(USBDevice *s, USBPacket *p)

{

    int request, value, index;

    int ret = 0;

    assert(p->devep == 0);

    request = (s->setup_buf[0] << 8) | s->setup_buf[1];

    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];

    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];

    switch(s->setup_state) {

    case SETUP_STATE_ACK:

        if (!(s->setup_buf[0] & USB_DIR_IN)) {

            ret = usb_device_handle_control(s, p, request, value, index,

                                            s->setup_len, s->data_buf);

            if (ret == USB_RET_ASYNC) {

                return USB_RET_ASYNC;

            }

            s->setup_state = SETUP_STATE_IDLE;

            if (ret > 0)

                return 0;

            return ret;

        }

        /* return 0 byte */

        return 0;

    case SETUP_STATE_DATA:

        if (s->setup_buf[0] & USB_DIR_IN) {

            int len = s->setup_len - s->setup_index;

            if (len > p->iov.size) {

                len = p->iov.size;

            }

            usb_packet_copy(p, s->data_buf + s->setup_index, len);

            s->setup_index += len;

            if (s->setup_index >= s->setup_len)

                s->setup_state = SETUP_STATE_ACK;

            return len;

        }

        s->setup_state = SETUP_STATE_IDLE;

        return USB_RET_STALL;

    default:

        return USB_RET_STALL;

    }

}


static int coroutine_fn backup_do_cow(BackupBlockJob *job,

                                      int64_t offset, uint64_t bytes,

                                      bool *error_is_read,

                                      bool is_write_notifier)

{

    BlockBackend *blk = job->common.blk;

    CowRequest cow_request;

    struct iovec iov;

    QEMUIOVector bounce_qiov;

    void *bounce_buffer = NULL;

    int ret = 0;

    int64_t start, end; /* bytes */

    int n; /* bytes */

    qemu_co_rwlock_rdlock(&job->flush_rwlock);

    start = QEMU_ALIGN_DOWN(offset, job->cluster_size);

    end = QEMU_ALIGN_UP(bytes + offset, job->cluster_size);

    trace_backup_do_cow_enter(job, start, offset, bytes);

    wait_for_overlapping_requests(job, start, end);

    cow_request_begin(&cow_request, job, start, end);

    for (; start < end; start += job->cluster_size) {

        if (test_bit(start / job->cluster_size, job->done_bitmap)) {

            trace_backup_do_cow_skip(job, start);

            continue; /* already copied */

        }

        trace_backup_do_cow_process(job, start);

        n = MIN(job->cluster_size, job->common.len - start);

        if (!bounce_buffer) {

            bounce_buffer = blk_blockalign(blk, job->cluster_size);

        }

        iov.iov_base = bounce_buffer;

        iov.iov_len = n;

        qemu_iovec_init_external(&bounce_qiov, &iov, 1);

        ret = blk_co_preadv(blk, start, bounce_qiov.size, &bounce_qiov,

                            is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0);

        if (ret < 0) {

            trace_backup_do_cow_read_fail(job, start, ret);

            if (error_is_read) {

                *error_is_read = true;

            }

            goto out;

        }

        if (buffer_is_zero(iov.iov_base, iov.iov_len)) {

            ret = blk_co_pwrite_zeroes(job->target, start,

                                       bounce_qiov.size, BDRV_REQ_MAY_UNMAP);

        } else {

            ret = blk_co_pwritev(job->target, start,

                                 bounce_qiov.size, &bounce_qiov,

                                 job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0);

        }

        if (ret < 0) {

            trace_backup_do_cow_write_fail(job, start, ret);

            if (error_is_read) {

                *error_is_read = false;

            }

            goto out;

        }

        set_bit(start / job->cluster_size, job->done_bitmap);

        /* Publish progress, guest I/O counts as progress too.  Note that the

         * offset field is an opaque progress value, it is not a disk offset.

         */

        job->bytes_read += n;

        job->common.offset += n;

    }

out:

    if (bounce_buffer) {

        qemu_vfree(bounce_buffer);

    }

    cow_request_end(&cow_request);

    trace_backup_do_cow_return(job, offset, bytes, ret);

    qemu_co_rwlock_unlock(&job->flush_rwlock);

    return ret;

}


static int inject_error(BlockDriverState *bs, BlkdebugRule *rule)

{

    BDRVBlkdebugState *s = bs->opaque;

    int error = rule->options.inject.error;

    bool immediately = rule->options.inject.immediately;

    if (rule->options.inject.once) {

        QSIMPLEQ_REMOVE(&s->active_rules, rule, BlkdebugRule, active_next);

        remove_rule(rule);

    }

    if (!immediately) {

        aio_co_schedule(qemu_get_current_aio_context(), qemu_coroutine_self());

        qemu_coroutine_yield();

    }

    return -error;

}


static void pflash_write(pflash_t *pfl, hwaddr offset,

                         uint32_t value, int width, int be)

{

    uint8_t *p;

    uint8_t cmd;

    cmd = value;

    DPRINTF("%s: writing offset " TARGET_FMT_plx " value %08x width %d wcycle 0x%x\n",

            __func__, offset, value, width, pfl->wcycle);

    if (!pfl->wcycle) {

        /* Set the device in I/O access mode */

        memory_region_rom_device_set_readable(&pfl->mem, false);

    }

    switch (pfl->wcycle) {

    case 0:

        /* read mode */

        switch (cmd) {

        case 0x00: /* ??? */

            goto reset_flash;

        case 0x10: /* Single Byte Program */

        case 0x40: /* Single Byte Program */

            DPRINTF("%s: Single Byte Program\n", __func__);

            break;

        case 0x20: /* Block erase */

            p = pfl->storage;

            offset &= ~(pfl->sector_len - 1);

            DPRINTF("%s: block erase at " TARGET_FMT_plx " bytes %x\n",

                    __func__, offset, (unsigned)pfl->sector_len);

            if (!pfl->ro) {

                memset(p + offset, 0xff, pfl->sector_len);

                pflash_update(pfl, offset, pfl->sector_len);

            } else {

                pfl->status |= 0x20; /* Block erase error */

            }

            pfl->status |= 0x80; /* Ready! */

            break;

        case 0x50: /* Clear status bits */

            DPRINTF("%s: Clear status bits\n", __func__);

            pfl->status = 0x0;

            goto reset_flash;

        case 0x60: /* Block (un)lock */

            DPRINTF("%s: Block unlock\n", __func__);

            break;

        case 0x70: /* Status Register */

            DPRINTF("%s: Read status register\n", __func__);

            pfl->cmd = cmd;

            return;

        case 0x90: /* Read Device ID */

            DPRINTF("%s: Read Device information\n", __func__);

            pfl->cmd = cmd;

            return;

        case 0x98: /* CFI query */

            DPRINTF("%s: CFI query\n", __func__);

            break;

        case 0xe8: /* Write to buffer */

            DPRINTF("%s: Write to buffer\n", __func__);

            pfl->status |= 0x80; /* Ready! */

            break;

        case 0xf0: /* Probe for AMD flash */

            DPRINTF("%s: Probe for AMD flash\n", __func__);

            goto reset_flash;

        case 0xff: /* Read array mode */

            DPRINTF("%s: Read array mode\n", __func__);

            goto reset_flash;

        default:

            goto error_flash;

        }

        pfl->wcycle++;

        pfl->cmd = cmd;

        break;

    case 1:

        switch (pfl->cmd) {

        case 0x10: /* Single Byte Program */

        case 0x40: /* Single Byte Program */

            DPRINTF("%s: Single Byte Program\n", __func__);

            if (!pfl->ro) {

                pflash_data_write(pfl, offset, value, width, be);

                pflash_update(pfl, offset, width);

            } else {

                pfl->status |= 0x10; /* Programming error */

            }

            pfl->status |= 0x80; /* Ready! */

            pfl->wcycle = 0;

        break;

        case 0x20: /* Block erase */

        case 0x28:

            if (cmd == 0xd0) { /* confirm */

                pfl->wcycle = 0;

                pfl->status |= 0x80;

            } else if (cmd == 0xff) { /* read array mode */

                goto reset_flash;

            } else

                goto error_flash;

            break;

        case 0xe8:

            DPRINTF("%s: block write of %x bytes\n", __func__, value);

            pfl->counter = value;

            pfl->wcycle++;

            break;

        case 0x60:

            if (cmd == 0xd0) {

                pfl->wcycle = 0;

                pfl->status |= 0x80;

            } else if (cmd == 0x01) {

                pfl->wcycle = 0;

                pfl->status |= 0x80;

            } else if (cmd == 0xff) {

                goto reset_flash;

            } else {

                DPRINTF("%s: Unknown (un)locking command\n", __func__);

                goto reset_flash;

            }

            break;

        case 0x98:

            if (cmd == 0xff) {

                goto reset_flash;

            } else {

                DPRINTF("%s: leaving query mode\n", __func__);

            }

            break;

        default:

            goto error_flash;

        }

        break;

    case 2:

        switch (pfl->cmd) {

        case 0xe8: /* Block write */

            if (!pfl->ro) {

                pflash_data_write(pfl, offset, value, width, be);

            } else {

                pfl->status |= 0x10; /* Programming error */

            }

            pfl->status |= 0x80;

            if (!pfl->counter) {

                hwaddr mask = pfl->writeblock_size - 1;

                mask = ~mask;

                DPRINTF("%s: block write finished\n", __func__);

                pfl->wcycle++;

                if (!pfl->ro) {

                    /* Flush the entire write buffer onto backing storage.  */

                    pflash_update(pfl, offset & mask, pfl->writeblock_size);

                } else {

                    pfl->status |= 0x10; /* Programming error */

                }

            }

            pfl->counter--;

            break;

        default:

            goto error_flash;

        }

        break;

    case 3: /* Confirm mode */

        switch (pfl->cmd) {

        case 0xe8: /* Block write */

            if (cmd == 0xd0) {

                pfl->wcycle = 0;

                pfl->status |= 0x80;

            } else {

                DPRINTF("%s: unknown command for \"write block\"\n", __func__);

                PFLASH_BUG("Write block confirm");

                goto reset_flash;

            }

            break;

        default:

            goto error_flash;

        }

        break;

    default:

        /* Should never happen */

        DPRINTF("%s: invalid write state\n",  __func__);

        goto reset_flash;

    }

    return;

 error_flash:

    qemu_log_mask(LOG_UNIMP, "%s: Unimplemented flash cmd sequence "

                  "(offset " TARGET_FMT_plx ", wcycle 0x%x cmd 0x%x value 0x%x)"

                  "\n", __func__, offset, pfl->wcycle, pfl->cmd, value);

 reset_flash:

    memory_region_rom_device_set_readable(&pfl->mem, true);

    pfl->bypass = 0;

    pfl->wcycle = 0;

    pfl->cmd = 0;

}


int kvm_init_vcpu(CPUState *cpu)

{

    KVMState *s = kvm_state;

    long mmap_size;

    int ret;

    DPRINTF("kvm_init_vcpu\n");

    ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)kvm_arch_vcpu_id(cpu));

    if (ret < 0) {

        DPRINTF("kvm_create_vcpu failed\n");

        goto err;

    }

    cpu->kvm_fd = ret;

    cpu->kvm_state = s;

    cpu->kvm_vcpu_dirty = true;

    mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);

    if (mmap_size < 0) {

        ret = mmap_size;

        DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n");

        goto err;

    }

    cpu->kvm_run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED,

                        cpu->kvm_fd, 0);

    if (cpu->kvm_run == MAP_FAILED) {

        ret = -errno;

        DPRINTF("mmap'ing vcpu state failed\n");

        goto err;

    }

    if (s->coalesced_mmio && !s->coalesced_mmio_ring) {

        s->coalesced_mmio_ring =

            (void *)cpu->kvm_run + s->coalesced_mmio * PAGE_SIZE;

    }

    ret = kvm_arch_init_vcpu(cpu);

err:

    return ret;

}


void arm_cpu_do_interrupt(CPUState *cs)
{
    ARMCPU *cpu = ARM_CPU(cs);
    CPUARMState *env = &cpu->env;
    unsigned int new_el = env->exception.target_el;
    assert(!arm_feature(env, ARM_FEATURE_M));
    arm_log_exception(cs->exception_index);
    qemu_log_mask(CPU_LOG_INT, "...from EL%d to EL%d\n", arm_current_el(env),
                  new_el);
    if (qemu_loglevel_mask(CPU_LOG_INT)
        && !excp_is_internal(cs->exception_index)) {
        qemu_log_mask(CPU_LOG_INT, "...with ESR %x/0x%" PRIx32 "\n",
                      env->exception.syndrome >> ARM_EL_EC_SHIFT,
                      env->exception.syndrome);
    }
    if (arm_is_psci_call(cpu, cs->exception_index)) {
        arm_handle_psci_call(cpu);
        qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
        return;
    }
    /* Semihosting semantics depend on the register width of the
     * code that caused the exception, not the target exception level,
     * so must be handled here.
    if (check_for_semihosting(cs)) {
        return;
    }
    assert(!excp_is_internal(cs->exception_index));
    if (arm_el_is_aa64(env, new_el)) {
        arm_cpu_do_interrupt_aarch64(cs);
    } else {
        arm_cpu_do_interrupt_aarch32(cs);
    }
    arm_call_el_change_hook(cpu);
    if (!kvm_enabled()) {
        cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
    }
}


static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)

{

    VirtQueueElement elem;

    if (!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))

        return;

    if (n->async_tx.elem.out_num) {

        virtio_queue_set_notification(n->tx_vq, 0);

        return;

    }

    while (virtqueue_pop(vq, &elem)) {

        ssize_t ret, len = 0;

        unsigned int out_num = elem.out_num;

        struct iovec *out_sg = &elem.out_sg[0];

        unsigned hdr_len;

        /* hdr_len refers to the header received from the guest */

        hdr_len = n->mergeable_rx_bufs ?

            sizeof(struct virtio_net_hdr_mrg_rxbuf) :

            sizeof(struct virtio_net_hdr);

        if (out_num < 1 || out_sg->iov_len != hdr_len) {

            fprintf(stderr, "virtio-net header not in first element\n");

            exit(1);

        }

        /* ignore the header if GSO is not supported */

        if (!n->has_vnet_hdr) {

            out_num--;

            out_sg++;

            len += hdr_len;

        } else if (n->mergeable_rx_bufs) {

            /* tapfd expects a struct virtio_net_hdr */

            hdr_len -= sizeof(struct virtio_net_hdr);

            out_sg->iov_len -= hdr_len;

            len += hdr_len;

        }

        ret = qemu_sendv_packet_async(&n->nic->nc, out_sg, out_num,

                                      virtio_net_tx_complete);

        if (ret == 0) {

            virtio_queue_set_notification(n->tx_vq, 0);

            n->async_tx.elem = elem;

            n->async_tx.len  = len;

            return;

        }

        len += ret;

        virtqueue_push(vq, &elem, len);

        virtio_notify(&n->vdev, vq);

    }

}


static void flush_queued_data(VirtIOSerialPort *port, bool discard)

{

    assert(port || discard);

    do_flush_queued_data(port, port->ovq, &port->vser->vdev, discard);

}


static int hdev_open(BlockDriverState *bs, QDict *options, int flags,

                     Error **errp)

{

    BDRVRawState *s = bs->opaque;

    Error *local_err = NULL;

    int ret;

#if defined(__APPLE__) && defined(__MACH__)

    const char *filename = qdict_get_str(options, "filename");

    char bsd_path[MAXPATHLEN] = "";

    bool error_occurred = false;

    /* If using a real cdrom */

    if (strcmp(filename, "/dev/cdrom") == 0) {

        char *mediaType = NULL;

        kern_return_t ret_val;

        io_iterator_t mediaIterator = 0;

        mediaType = FindEjectableOpticalMedia(&mediaIterator);

        if (mediaType == NULL) {

            error_setg(errp, "Please make sure your CD/DVD is in the optical"

                       " drive");

            error_occurred = true;

            goto hdev_open_Mac_error;

        }

        ret_val = GetBSDPath(mediaIterator, bsd_path, sizeof(bsd_path), flags);

        if (ret_val != KERN_SUCCESS) {

            error_setg(errp, "Could not get BSD path for optical drive");

            error_occurred = true;

            goto hdev_open_Mac_error;

        }

        /* If a real optical drive was not found */

        if (bsd_path[0] == '\0') {

            error_setg(errp, "Failed to obtain bsd path for optical drive");

            error_occurred = true;

            goto hdev_open_Mac_error;

        }

        /* If using a cdrom disc and finding a partition on the disc failed */

        if (strncmp(mediaType, kIOCDMediaClass, 9) == 0 &&

            setup_cdrom(bsd_path, errp) == false) {

            print_unmounting_directions(bsd_path);

            error_occurred = true;

            goto hdev_open_Mac_error;

        }

        qdict_put(options, "filename", qstring_from_str(bsd_path));

hdev_open_Mac_error:

        g_free(mediaType);

        if (mediaIterator) {

            IOObjectRelease(mediaIterator);

        }

        if (error_occurred) {

            return -ENOENT;

        }

    }

#endif /* defined(__APPLE__) && defined(__MACH__) */

    s->type = FTYPE_FILE;

    ret = raw_open_common(bs, options, flags, 0, &local_err);

    if (ret < 0) {

        error_propagate(errp, local_err);

#if defined(__APPLE__) && defined(__MACH__)

        if (*bsd_path) {

            filename = bsd_path;

        }

        /* if a physical device experienced an error while being opened */

        if (strncmp(filename, "/dev/", 5) == 0) {

            print_unmounting_directions(filename);

        }

#endif /* defined(__APPLE__) && defined(__MACH__) */

        return ret;

    }

    /* Since this does ioctl the device must be already opened */

    bs->sg = hdev_is_sg(bs);

    if (flags & BDRV_O_RDWR) {

        ret = check_hdev_writable(s);

        if (ret < 0) {

            raw_close(bs);

            error_setg_errno(errp, -ret, "The device is not writable");

            return ret;

        }

    }

    return ret;

}


int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)

{

    Location loc;

    DriveInfo *dinfo;

    int res = 0, unit;

    loc_push_none(&loc);

    for (unit = 0; unit < bus->info->max_target; unit++) {

        dinfo = drive_get(IF_SCSI, bus->busnr, unit);

        if (dinfo == NULL) {

            continue;

        }

        qemu_opts_loc_restore(dinfo->opts);

        if (!scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false, -1)) {

            res = -1;

            break;

        }

    }

    loc_pop(&loc);

    return res;

}


static int link_filter_inouts(AVFilterContext *filt_ctx,

                              AVFilterInOut **curr_inputs,

                              AVFilterInOut **open_inputs, AVClass *log_ctx)

{

    int pad = filt_ctx->input_count, ret;

    while (pad--) {

        AVFilterInOut *p = *curr_inputs;

        if (!p) {

            av_log(log_ctx, AV_LOG_ERROR,

                   "Not enough inputs specified for the \"%s\" filter.\n",

                   filt_ctx->filter->name);

            return AVERROR(EINVAL);

        }

        *curr_inputs = (*curr_inputs)->next;

        if (p->filter) {

            if ((ret = link_filter(p->filter, p->pad_idx, filt_ctx, pad, log_ctx)) < 0)

                return ret;

            av_free(p->name);

            av_free(p);

        } else {

            p->filter = filt_ctx;

            p->pad_idx = pad;

            insert_inout(open_inputs, p);

        }

    }

    if (*curr_inputs) {

        av_log(log_ctx, AV_LOG_ERROR,

               "Too many inputs specified for the \"%s\" filter.\n",

               filt_ctx->filter->name);

        return AVERROR(EINVAL);

    }

    pad = filt_ctx->output_count;

    while (pad--) {

        AVFilterInOut *currlinkn = av_mallocz(sizeof(AVFilterInOut));

        currlinkn->filter  = filt_ctx;

        currlinkn->pad_idx = pad;

        insert_inout(curr_inputs, currlinkn);

    }

    return 0;

}


static void x86_cpu_common_class_init(ObjectClass *oc, void *data)

{

    X86CPUClass *xcc = X86_CPU_CLASS(oc);

    CPUClass *cc = CPU_CLASS(oc);

    DeviceClass *dc = DEVICE_CLASS(oc);

    xcc->parent_realize = dc->realize;

    dc->realize = x86_cpu_realizefn;

    dc->bus_type = TYPE_ICC_BUS;

    dc->props = x86_cpu_properties;

    xcc->parent_reset = cc->reset;

    cc->reset = x86_cpu_reset;

    cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;

    cc->class_by_name = x86_cpu_class_by_name;

    cc->parse_features = x86_cpu_parse_featurestr;

    cc->has_work = x86_cpu_has_work;

    cc->do_interrupt = x86_cpu_do_interrupt;

    cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;

    cc->dump_state = x86_cpu_dump_state;

    cc->set_pc = x86_cpu_set_pc;

    cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;

    cc->gdb_read_register = x86_cpu_gdb_read_register;

    cc->gdb_write_register = x86_cpu_gdb_write_register;

    cc->get_arch_id = x86_cpu_get_arch_id;

    cc->get_paging_enabled = x86_cpu_get_paging_enabled;

#ifdef CONFIG_USER_ONLY

    cc->handle_mmu_fault = x86_cpu_handle_mmu_fault;

#else

    cc->get_memory_mapping = x86_cpu_get_memory_mapping;

    cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;

    cc->write_elf64_note = x86_cpu_write_elf64_note;

    cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;

    cc->write_elf32_note = x86_cpu_write_elf32_note;

    cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;

    cc->vmsd = &vmstate_x86_cpu;

#endif

    cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;

#ifndef CONFIG_USER_ONLY

    cc->debug_excp_handler = breakpoint_handler;

#endif

    cc->cpu_exec_enter = x86_cpu_exec_enter;

    cc->cpu_exec_exit = x86_cpu_exec_exit;

}


static int qpa_init_in (HWVoiceIn *hw, audsettings_t *as)

{

    int error;

    static pa_sample_spec ss;

    audsettings_t obt_as = *as;

    PAVoiceIn *pa = (PAVoiceIn *) hw;

    ss.format = audfmt_to_pa (as->fmt, as->endianness);

    ss.channels = as->nchannels;

    ss.rate = as->freq;

    obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);

    pa->s = pa_simple_new (

        conf.server,

        "qemu",

        PA_STREAM_RECORD,

        conf.source,

        "pcm.capture",

        &ss,

        NULL,                   /* channel map */

        NULL,                   /* buffering attributes */

        &error

        );

    if (!pa->s) {

        qpa_logerr (error, "pa_simple_new for capture failed\n");

        goto fail1;

    }

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

    hw->samples = conf.samples;

    pa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);

    if (!pa->pcm_buf) {

        dolog ("Could not allocate buffer (%d bytes)\n",

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

        goto fail2;

    }

    if (audio_pt_init (&pa->pt, qpa_thread_in, hw, AUDIO_CAP, AUDIO_FUNC)) {

        goto fail3;

    }

    return 0;

 fail3:

    free (pa->pcm_buf);

    pa->pcm_buf = NULL;

 fail2:

    pa_simple_free (pa->s);

    pa->s = NULL;

 fail1:

    return -1;

}


uint32_t helper_compute_fprf (uint64_t arg, uint32_t set_fprf)

{

    CPU_DoubleU farg;

    int isneg;

    int ret;

    farg.ll = arg;

    isneg = float64_is_neg(farg.d);

    if (unlikely(float64_is_nan(farg.d))) {

        if (float64_is_signaling_nan(farg.d)) {

            /* Signaling NaN: flags are undefined */

            ret = 0x00;

        } else {

            /* Quiet NaN */

            ret = 0x11;

        }

    } else if (unlikely(float64_is_infinity(farg.d))) {

        /* +/- infinity */

        if (isneg)

            ret = 0x09;

        else

            ret = 0x05;

    } else {

        if (float64_is_zero(farg.d)) {

            /* +/- zero */

            if (isneg)

                ret = 0x12;

            else

                ret = 0x02;

        } else {

            if (isden(farg.d)) {

                /* Denormalized numbers */

                ret = 0x10;

            } else {

                /* Normalized numbers */

                ret = 0x00;

            }

            if (isneg) {

                ret |= 0x08;

            } else {

                ret |= 0x04;

            }

        }

    }

    if (set_fprf) {

        /* We update FPSCR_FPRF */

        env->fpscr &= ~(0x1F << FPSCR_FPRF);

        env->fpscr |= ret << FPSCR_FPRF;

    }

    /* We just need fpcc to update Rc1 */

    return ret & 0xF;

}


void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)

{

    VGACommonState *s = opaque;

    int index;

    /* check port range access depending on color/monochrome mode */

    if (vga_ioport_invalid(s, addr)) {

        return;

    }

#ifdef DEBUG_VGA

    printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);

#endif

    switch(addr) {

    case VGA_ATT_W:

        if (s->ar_flip_flop == 0) {

            val &= 0x3f;

            s->ar_index = val;

        } else {

            index = s->ar_index & 0x1f;

            switch(index) {

            case VGA_ATC_PALETTE0 ... VGA_ATC_PALETTEF:

                s->ar[index] = val & 0x3f;

                break;

            case VGA_ATC_MODE:

                s->ar[index] = val & ~0x10;

                break;

            case VGA_ATC_OVERSCAN:

                s->ar[index] = val;

                break;

            case VGA_ATC_PLANE_ENABLE:

                s->ar[index] = val & ~0xc0;

                break;

            case VGA_ATC_PEL:

                s->ar[index] = val & ~0xf0;

                break;

            case VGA_ATC_COLOR_PAGE:

                s->ar[index] = val & ~0xf0;

                break;

            default:

                break;

            }

        }

        s->ar_flip_flop ^= 1;

        break;

    case VGA_MIS_W:

        s->msr = val & ~0x10;

        s->update_retrace_info(s);

        break;

    case VGA_SEQ_I:

        s->sr_index = val & 7;

        break;

    case VGA_SEQ_D:

#ifdef DEBUG_VGA_REG

        printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);

#endif

        s->sr[s->sr_index] = val & sr_mask[s->sr_index];

        if (s->sr_index == VGA_SEQ_CLOCK_MODE) {

            s->update_retrace_info(s);

        }

        vga_update_memory_access(s);

        break;

    case VGA_PEL_IR:

        s->dac_read_index = val;

        s->dac_sub_index = 0;

        s->dac_state = 3;

        break;

    case VGA_PEL_IW:

        s->dac_write_index = val;

        s->dac_sub_index = 0;

        s->dac_state = 0;

        break;

    case VGA_PEL_D:

        s->dac_cache[s->dac_sub_index] = val;

        if (++s->dac_sub_index == 3) {

            memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);

            s->dac_sub_index = 0;

            s->dac_write_index++;

        }

        break;

    case VGA_GFX_I:

        s->gr_index = val & 0x0f;

        break;

    case VGA_GFX_D:

#ifdef DEBUG_VGA_REG

        printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);

#endif

        s->gr[s->gr_index] = val & gr_mask[s->gr_index];

        vga_update_memory_access(s);

        break;

    case VGA_CRT_IM:

    case VGA_CRT_IC:

        s->cr_index = val;

        break;

    case VGA_CRT_DM:

    case VGA_CRT_DC:

#ifdef DEBUG_VGA_REG

        printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);

#endif

        /* handle CR0-7 protection */

        if (s->cr[VGA_CRTC_V_SYNC_END] & VGA_CR11_LOCK_CR0_CR7) {

            if (s->cr_index <= VGA_CRTC_OVERFLOW) {

                /* can always write bit 4 of CR7 */

                if (s->cr_index == VGA_CRTC_OVERFLOW) {

                    s->cr[VGA_CRTC_OVERFLOW] =

                        (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) | (val & 0x10);

                }

                return;

            } else if ((vga_cga_hacks & VGA_CGA_HACK_FONT_HEIGHT) &&

                       !(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {

                /* extra CGA compatibility hacks (not in standard VGA) */

                if (s->cr_index == VGA_CRTC_MAX_SCAN &&

                    val == 7 &&

                    (s->cr[VGA_CRTC_MAX_SCAN] & 0xf) == 0xf) {

                    return;

                } else if (s->cr_index == VGA_CRTC_CURSOR_START &&

                           val == 6 &&

                           (s->cr[VGA_CRTC_MAX_SCAN] & 0xf) == 0xf) {

                    val = 0xd;

                } else if (s->cr_index == VGA_CRTC_CURSOR_END &&

                           val == 7 &&

                           (s->cr[VGA_CRTC_MAX_SCAN] & 0xf) == 0xf) {

                    val = 0xe;

                }

            }

        }

        s->cr[s->cr_index] = val;

        switch(s->cr_index) {

        case VGA_CRTC_H_TOTAL:

        case VGA_CRTC_H_SYNC_START:

        case VGA_CRTC_H_SYNC_END:

        case VGA_CRTC_V_TOTAL:

        case VGA_CRTC_OVERFLOW:

        case VGA_CRTC_V_SYNC_END:

        case VGA_CRTC_MODE:

            s->update_retrace_info(s);

            break;

        }

        break;

    case VGA_IS1_RM:

    case VGA_IS1_RC:

        s->fcr = val & 0x10;

        break;

    }

}


static int usbnet_can_receive(NetClientState *nc)

{

    USBNetState *s = qemu_get_nic_opaque(nc);

    if (!s->dev.config) {

        return 0;

    }

    if (is_rndis(s) && s->rndis_state != RNDIS_DATA_INITIALIZED) {

        return 1;

    }

    return !s->in_len;

}


static void dhcp_decode(const uint8_t *buf, int size,

                        int *pmsg_type)

{

    const uint8_t *p, *p_end;

    int len, tag;

    *pmsg_type = 0;

    p = buf;

    p_end = buf + size;

    if (size < 5)

        return;

    if (memcmp(p, rfc1533_cookie, 4) != 0)

        return;

    p += 4;

    while (p < p_end) {

        tag = p[0];

        if (tag == RFC1533_PAD) {

            p++;

        } else if (tag == RFC1533_END) {

            break;

        } else {

            p++;

            if (p >= p_end)

                break;

            len = *p++;

            dprintf("dhcp: tag=0x%02x len=%d\n", tag, len);

            switch(tag) {

            case RFC2132_MSG_TYPE:

                if (len >= 1)

                    *pmsg_type = p[0];

                break;

            default:

                break;

            }

            p += len;

        }

    }

}


static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)

{

    XHCITRB *trb_setup, *trb_status;

    uint8_t bmRequestType;

    trb_setup = &xfer->trbs[0];

    trb_status = &xfer->trbs[xfer->trb_count-1];

    trace_usb_xhci_xfer_start(xfer, xfer->epctx->slotid,

                              xfer->epctx->epid, xfer->streamid);

    /* at most one Event Data TRB allowed after STATUS */

    if (TRB_TYPE(*trb_status) == TR_EVDATA && xfer->trb_count > 2) {

        trb_status--;

    }

    /* do some sanity checks */

    if (TRB_TYPE(*trb_setup) != TR_SETUP) {

        DPRINTF("xhci: ep0 first TD not SETUP: %d\n",

                TRB_TYPE(*trb_setup));

        return -1;

    }

    if (TRB_TYPE(*trb_status) != TR_STATUS) {

        DPRINTF("xhci: ep0 last TD not STATUS: %d\n",

                TRB_TYPE(*trb_status));

        return -1;

    }

    if (!(trb_setup->control & TRB_TR_IDT)) {

        DPRINTF("xhci: Setup TRB doesn't have IDT set\n");

        return -1;

    }

    if ((trb_setup->status & 0x1ffff) != 8) {

        DPRINTF("xhci: Setup TRB has bad length (%d)\n",

                (trb_setup->status & 0x1ffff));

        return -1;

    }

    bmRequestType = trb_setup->parameter;

    xfer->in_xfer = bmRequestType & USB_DIR_IN;

    xfer->iso_xfer = false;

    xfer->timed_xfer = false;

    if (xhci_setup_packet(xfer) < 0) {

        return -1;

    }

    xfer->packet.parameter = trb_setup->parameter;

    usb_handle_packet(xfer->packet.ep->dev, &xfer->packet);

    xhci_try_complete_packet(xfer);

    if (!xfer->running_async && !xfer->running_retry) {

        xhci_kick_epctx(xfer->epctx, 0);

    }

    return 0;

}


void qemu_free_timer(QEMUTimer *ts)

{

    g_free(ts);

}


static av_cold int dvdsub_close(AVCodecContext *avctx)

{

    DVDSubContext *ctx = avctx->priv_data;

    av_freep(&ctx->buf);

    ctx->buf_size = 0;

    return 0;

}


static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)

{

    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);

    int start_track, format, msf, toclen;

    uint64_t nb_sectors;

    msf = req->cmd.buf[1] & 2;

    format = req->cmd.buf[2] & 0xf;

    start_track = req->cmd.buf[6];

    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);

    DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);

    nb_sectors /= s->qdev.blocksize / 512;

    switch (format) {

    case 0:

        toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);

        break;

    case 1:

        /* multi session : only a single session defined */

        toclen = 12;

        memset(outbuf, 0, 12);

        outbuf[1] = 0x0a;

        outbuf[2] = 0x01;

        outbuf[3] = 0x01;

        break;

    case 2:

        toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);

        break;

    default:

        return -1;

    }

    return toclen;

}


void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)

{

    Error *local_err = NULL;

    int ret;

    if (!bs->drv)  {

        return;

    }

    if (!(bs->open_flags & BDRV_O_INACTIVE)) {

        return;

    }

    bs->open_flags &= ~BDRV_O_INACTIVE;

    if (bs->drv->bdrv_invalidate_cache) {

        bs->drv->bdrv_invalidate_cache(bs, &local_err);

    } else if (bs->file) {

        bdrv_invalidate_cache(bs->file->bs, &local_err);

    }

    if (local_err) {

        bs->open_flags |= BDRV_O_INACTIVE;

        error_propagate(errp, local_err);

        return;

    }

    ret = refresh_total_sectors(bs, bs->total_sectors);

    if (ret < 0) {

        bs->open_flags |= BDRV_O_INACTIVE;

        error_setg_errno(errp, -ret, "Could not refresh total sector count");

        return;

    }

}


static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)

{

    UHCIState *s = DO_UPCAST(UHCIState, dev, dev);

    uint8_t *pci_conf = s->dev.config;

    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);

    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_UHCI);

    /* USB misc control 1/2 */

    pci_set_long(pci_conf + 0x40,0x00001000);

    /* PM capability */

    pci_set_long(pci_conf + 0x80,0x00020001);

    /* USB legacy support  */

    pci_set_long(pci_conf + 0xc0,0x00002000);

    return usb_uhci_common_initfn(s);

}


static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)

{

    int rd = (insn >> 0) & 0xf;

    TCGv tmp;

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

        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {

            return 1;

        } else {

            tmp = iwmmxt_load_creg(rd);

        }

    } else {

        tmp = new_tmp();

        iwmmxt_load_reg(cpu_V0, rd);

        tcg_gen_trunc_i64_i32(tmp, cpu_V0);

    }

    tcg_gen_andi_i32(tmp, tmp, mask);

    tcg_gen_mov_i32(dest, tmp);

    dead_tmp(tmp);

    return 0;

}


static void vfio_vga_probe_nvidia_3d0_quirk(VFIOPCIDevice *vdev)

{

    VFIOQuirk *quirk;

    VFIONvidia3d0Quirk *data;

    if (!vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID) ||

        !vdev->bars[1].region.size) {

        return;

    }

    quirk = g_malloc0(sizeof(*quirk));

    quirk->data = data = g_malloc0(sizeof(*data));

    quirk->mem = g_malloc0(sizeof(MemoryRegion) * 2);

    quirk->nr_mem = 2;

    data->vdev = vdev;

    memory_region_init_io(&quirk->mem[0], OBJECT(vdev), &vfio_nvidia_3d4_quirk,

                          data, "vfio-nvidia-3d4-quirk", 2);

    memory_region_add_subregion(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].mem,

                                0x14 /* 0x3c0 + 0x14 */, &quirk->mem[0]);

    memory_region_init_io(&quirk->mem[1], OBJECT(vdev), &vfio_nvidia_3d0_quirk,

                          data, "vfio-nvidia-3d0-quirk", 2);

    memory_region_add_subregion(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].mem,

                                0x10 /* 0x3c0 + 0x10 */, &quirk->mem[1]);

    QLIST_INSERT_HEAD(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].quirks,

                      quirk, next);

    trace_vfio_quirk_nvidia_3d0_probe(vdev->vbasedev.name);

}


static int cookie_string(AVDictionary *dict, char **cookies)

{

    AVDictionaryEntry *e = NULL;

    int len = 1;

    // determine how much memory is needed for the cookies string

    while (e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))

        len += strlen(e->key) + strlen(e->value) + 1;

    // reallocate the cookies

    e = NULL;

    if (*cookies) av_free(*cookies);

    *cookies = av_malloc(len);

    if (!cookies) return AVERROR(ENOMEM);

    *cookies[0] = '\0';

    // write out the cookies

    while (e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))

        av_strlcatf(*cookies, len, "%s%s\n", e->key, e->value);

    return 0;

}


static int get_physical_address (CPUMIPSState *env, hwaddr *physical,

                                int *prot, target_ulong real_address,

                                int rw, int access_type)

{

    /* User mode can only access useg/xuseg */

    int user_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM;

    int supervisor_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_SM;

    int kernel_mode = !user_mode && !supervisor_mode;

#if defined(TARGET_MIPS64)

    int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;

    int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;

    int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;

#endif

    int ret = TLBRET_MATCH;

    /* effective address (modified for KVM T&E kernel segments) */

    target_ulong address = real_address;

#define USEG_LIMIT      0x7FFFFFFFUL

#define KSEG0_BASE      0x80000000UL

#define KSEG1_BASE      0xA0000000UL

#define KSEG2_BASE      0xC0000000UL

#define KSEG3_BASE      0xE0000000UL

#define KVM_KSEG0_BASE  0x40000000UL

#define KVM_KSEG2_BASE  0x60000000UL

    if (kvm_enabled()) {

        /* KVM T&E adds guest kernel segments in useg */

        if (real_address >= KVM_KSEG0_BASE) {

            if (real_address < KVM_KSEG2_BASE) {

                /* kseg0 */

                address += KSEG0_BASE - KVM_KSEG0_BASE;

            } else if (real_address <= USEG_LIMIT) {

                /* kseg2/3 */

                address += KSEG2_BASE - KVM_KSEG2_BASE;

            }

        }

    }

    if (address <= USEG_LIMIT) {

        /* useg */

        if (env->CP0_Status & (1 << CP0St_ERL)) {

            *physical = address & 0xFFFFFFFF;

            *prot = PAGE_READ | PAGE_WRITE;

        } else {

            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);

        }

#if defined(TARGET_MIPS64)

    } else if (address < 0x4000000000000000ULL) {

        /* xuseg */

        if (UX && address <= (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {

            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);

        } else {

            ret = TLBRET_BADADDR;

        }

    } else if (address < 0x8000000000000000ULL) {

        /* xsseg */

        if ((supervisor_mode || kernel_mode) &&

            SX && address <= (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {

            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);

        } else {

            ret = TLBRET_BADADDR;

        }

    } else if (address < 0xC000000000000000ULL) {

        /* xkphys */

        if (kernel_mode && KX &&

            (address & 0x07FFFFFFFFFFFFFFULL) <= env->PAMask) {

            *physical = address & env->PAMask;

            *prot = PAGE_READ | PAGE_WRITE;

        } else {

            ret = TLBRET_BADADDR;

        }

    } else if (address < 0xFFFFFFFF80000000ULL) {

        /* xkseg */

        if (kernel_mode && KX &&

            address <= (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {

            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);

        } else {

            ret = TLBRET_BADADDR;

        }

#endif

    } else if (address < (int32_t)KSEG1_BASE) {

        /* kseg0 */

        if (kernel_mode) {

            *physical = address - (int32_t)KSEG0_BASE;

            *prot = PAGE_READ | PAGE_WRITE;

        } else {

            ret = TLBRET_BADADDR;

        }

    } else if (address < (int32_t)KSEG2_BASE) {

        /* kseg1 */

        if (kernel_mode) {

            *physical = address - (int32_t)KSEG1_BASE;

            *prot = PAGE_READ | PAGE_WRITE;

        } else {

            ret = TLBRET_BADADDR;

        }

    } else if (address < (int32_t)KSEG3_BASE) {

        /* sseg (kseg2) */

        if (supervisor_mode || kernel_mode) {

            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);

        } else {

            ret = TLBRET_BADADDR;

        }

    } else {

        /* kseg3 */

        /* XXX: debug segment is not emulated */

        if (kernel_mode) {

            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);

        } else {

            ret = TLBRET_BADADDR;

        }

    }

    return ret;

}


static int get_htab_fd(sPAPRMachineState *spapr)

{

    if (spapr->htab_fd >= 0) {

        return spapr->htab_fd;

    }

    spapr->htab_fd = kvmppc_get_htab_fd(false);

    if (spapr->htab_fd < 0) {

        error_report("Unable to open fd for reading hash table from KVM: %s",

                     strerror(errno));

    }

    return spapr->htab_fd;

}


static void qobject_input_start_list(Visitor *v, const char *name,

                                     GenericList **list, size_t size,

                                     Error **errp)

{

    QObjectInputVisitor *qiv = to_qiv(v);

    QObject *qobj = qobject_input_get_object(qiv, name, true, errp);

    const QListEntry *entry;

    if (list) {

        *list = NULL;

    }

    if (!qobj) {

        return;

    }

    if (qobject_type(qobj) != QTYPE_QLIST) {

        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",

                   "list");

        return;

    }

    entry = qobject_input_push(qiv, qobj, list);

    if (entry && list) {

        *list = g_malloc0(size);

    }

}


static void test_qga_file_write_read(gconstpointer fix)

{

    const TestFixture *fixture = fix;

    const unsigned char helloworld[] = "Hello World!\n";

    const char *b64;

    gchar *cmd, *enc;

    QDict *ret, *val;

    int64_t id, eof;

    gsize count;

    /* open */

    ret = qmp_fd(fixture->fd, "{'execute': 'guest-file-open',"

                 " 'arguments': { 'path': 'foo', 'mode': 'w+' } }");

    g_assert_nonnull(ret);

    qmp_assert_no_error(ret);

    id = qdict_get_int(ret, "return");

    QDECREF(ret);

    enc = g_base64_encode(helloworld, sizeof(helloworld));

    /* write */

    cmd = g_strdup_printf("{'execute': 'guest-file-write',"

                          " 'arguments': { 'handle': %" PRId64 ","

                          " 'buf-b64': '%s' } }", id, enc);

    ret = qmp_fd(fixture->fd, cmd);

    g_assert_nonnull(ret);

    qmp_assert_no_error(ret);

    val = qdict_get_qdict(ret, "return");

    count = qdict_get_int(val, "count");

    eof = qdict_get_bool(val, "eof");

    g_assert_cmpint(count, ==, sizeof(helloworld));

    g_assert_cmpint(eof, ==, 0);

    QDECREF(ret);

    g_free(cmd);

    /* read (check implicit flush) */

    cmd = g_strdup_printf("{'execute': 'guest-file-read',"

                          " 'arguments': { 'handle': %" PRId64 "} }",

                          id);

    ret = qmp_fd(fixture->fd, cmd);

    val = qdict_get_qdict(ret, "return");

    count = qdict_get_int(val, "count");

    eof = qdict_get_bool(val, "eof");

    b64 = qdict_get_str(val, "buf-b64");

    g_assert_cmpint(count, ==, 0);

    g_assert(eof);

    g_assert_cmpstr(b64, ==, "");

    QDECREF(ret);

    g_free(cmd);

    /* seek to 0 */

    cmd = g_strdup_printf("{'execute': 'guest-file-seek',"

                          " 'arguments': { 'handle': %" PRId64 ", "

                          " 'offset': %d, 'whence': %d } }",

                          id, 0, SEEK_SET);

    ret = qmp_fd(fixture->fd, cmd);

    qmp_assert_no_error(ret);

    val = qdict_get_qdict(ret, "return");

    count = qdict_get_int(val, "position");

    eof = qdict_get_bool(val, "eof");

    g_assert_cmpint(count, ==, 0);

    g_assert(!eof);

    QDECREF(ret);

    g_free(cmd);

    /* read */

    cmd = g_strdup_printf("{'execute': 'guest-file-read',"

                          " 'arguments': { 'handle': %" PRId64 "} }",

                          id);

    ret = qmp_fd(fixture->fd, cmd);

    val = qdict_get_qdict(ret, "return");

    count = qdict_get_int(val, "count");

    eof = qdict_get_bool(val, "eof");

    b64 = qdict_get_str(val, "buf-b64");

    g_assert_cmpint(count, ==, sizeof(helloworld));

    g_assert(eof);

    g_assert_cmpstr(b64, ==, enc);

    QDECREF(ret);

    g_free(cmd);

    g_free(enc);

    /* close */

    cmd = g_strdup_printf("{'execute': 'guest-file-close',"

                          " 'arguments': {'handle': %" PRId64 "} }",

                          id);

    ret = qmp_fd(fixture->fd, cmd);

    QDECREF(ret);

    g_free(cmd);

}


static void test_visitor_out_native_list_uint16(TestOutputVisitorData *data,

                                                const void *unused)

{

    test_native_list(data, unused, USER_DEF_NATIVE_LIST_UNION_KIND_U16);

}


static int xen_9pfs_connect(struct XenDevice *xendev)

{

    int i;

    Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);

    V9fsState *s = &xen_9pdev->state;

    QemuOpts *fsdev;

    if (xenstore_read_fe_int(&xen_9pdev->xendev, "num-rings",

                             &xen_9pdev->num_rings) == -1 ||

        xen_9pdev->num_rings > MAX_RINGS || xen_9pdev->num_rings < 1) {

        return -1;

    }

    xen_9pdev->rings = g_malloc0(xen_9pdev->num_rings * sizeof(Xen9pfsRing));

    for (i = 0; i < xen_9pdev->num_rings; i++) {

        char *str;

        int ring_order;

        xen_9pdev->rings[i].priv = xen_9pdev;

        xen_9pdev->rings[i].evtchn = -1;

        xen_9pdev->rings[i].local_port = -1;

        str = g_strdup_printf("ring-ref%u", i);

        if (xenstore_read_fe_int(&xen_9pdev->xendev, str,

                                 &xen_9pdev->rings[i].ref) == -1) {

            g_free(str);

            goto out;

        }

        g_free(str);

        str = g_strdup_printf("event-channel-%u", i);

        if (xenstore_read_fe_int(&xen_9pdev->xendev, str,

                                 &xen_9pdev->rings[i].evtchn) == -1) {

            g_free(str);

            goto out;

        }

        g_free(str);

        xen_9pdev->rings[i].intf =  xengnttab_map_grant_ref(

                xen_9pdev->xendev.gnttabdev,

                xen_9pdev->xendev.dom,

                xen_9pdev->rings[i].ref,

                PROT_READ | PROT_WRITE);

        if (!xen_9pdev->rings[i].intf) {

            goto out;

        }

        ring_order = xen_9pdev->rings[i].intf->ring_order;

        if (ring_order > MAX_RING_ORDER) {

            goto out;

        }

        xen_9pdev->rings[i].ring_order = ring_order;

        xen_9pdev->rings[i].data = xengnttab_map_domain_grant_refs(

                xen_9pdev->xendev.gnttabdev,

                (1 << ring_order),

                xen_9pdev->xendev.dom,

                xen_9pdev->rings[i].intf->ref,

                PROT_READ | PROT_WRITE);

        if (!xen_9pdev->rings[i].data) {

            goto out;

        }

        xen_9pdev->rings[i].ring.in = xen_9pdev->rings[i].data;

        xen_9pdev->rings[i].ring.out = xen_9pdev->rings[i].data +

                                       XEN_FLEX_RING_SIZE(ring_order);

        xen_9pdev->rings[i].bh = qemu_bh_new(xen_9pfs_bh, &xen_9pdev->rings[i]);

        xen_9pdev->rings[i].out_cons = 0;

        xen_9pdev->rings[i].out_size = 0;

        xen_9pdev->rings[i].inprogress = false;

        xen_9pdev->rings[i].evtchndev = xenevtchn_open(NULL, 0);

        if (xen_9pdev->rings[i].evtchndev == NULL) {

            goto out;

        }

        fcntl(xenevtchn_fd(xen_9pdev->rings[i].evtchndev), F_SETFD, FD_CLOEXEC);

        xen_9pdev->rings[i].local_port = xenevtchn_bind_interdomain

                                            (xen_9pdev->rings[i].evtchndev,

                                             xendev->dom,

                                             xen_9pdev->rings[i].evtchn);

        if (xen_9pdev->rings[i].local_port == -1) {

            xen_pv_printf(xendev, 0,

                          "xenevtchn_bind_interdomain failed port=%d\n",

                          xen_9pdev->rings[i].evtchn);

            goto out;

        }

        xen_pv_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);

        qemu_set_fd_handler(xenevtchn_fd(xen_9pdev->rings[i].evtchndev),

                xen_9pfs_evtchn_event, NULL, &xen_9pdev->rings[i]);

    }

    xen_9pdev->security_model = xenstore_read_be_str(xendev, "security_model");

    xen_9pdev->path = xenstore_read_be_str(xendev, "path");

    xen_9pdev->id = s->fsconf.fsdev_id =

        g_strdup_printf("xen9p%d", xendev->dev);

    xen_9pdev->tag = s->fsconf.tag = xenstore_read_fe_str(xendev, "tag");

    v9fs_register_transport(s, &xen_9p_transport);

    fsdev = qemu_opts_create(qemu_find_opts("fsdev"),

            s->fsconf.tag,

            1, NULL);

    qemu_opt_set(fsdev, "fsdriver", "local", NULL);

    qemu_opt_set(fsdev, "path", xen_9pdev->path, NULL);

    qemu_opt_set(fsdev, "security_model", xen_9pdev->security_model, NULL);

    qemu_opts_set_id(fsdev, s->fsconf.fsdev_id);

    qemu_fsdev_add(fsdev);

    v9fs_device_realize_common(s, NULL);

    return 0;

out:

    xen_9pfs_free(xendev);

    return -1;

}


static void tcg_opt_gen_mov(TCGContext *s, TCGOp *op, TCGArg *args,

                            TCGArg dst, TCGArg src)

{

    if (temps_are_copies(dst, src)) {

        tcg_op_remove(s, op);

        return;

    }

    if (temp_is_const(src)) {

        tcg_opt_gen_movi(s, op, args, dst, temps[src].val);

        return;

    }

    TCGOpcode new_op = op_to_mov(op->opc);

    tcg_target_ulong mask;

    op->opc = new_op;

    reset_temp(dst);

    mask = temps[src].mask;

    if (TCG_TARGET_REG_BITS > 32 && new_op == INDEX_op_mov_i32) {

        /* High bits of the destination are now garbage.  */

        mask |= ~0xffffffffull;

    }

    temps[dst].mask = mask;

    assert(!temp_is_const(src));

    if (s->temps[src].type == s->temps[dst].type) {

        temps[dst].next_copy = temps[src].next_copy;

        temps[dst].prev_copy = src;

        temps[temps[dst].next_copy].prev_copy = dst;

        temps[src].next_copy = dst;

        temps[dst].is_const = false;

    }

    args[0] = dst;

    args[1] = src;

}


av_cold void ff_dsputil_init_vis(DSPContext *c, AVCodecContext *avctx)

{

  /* VIS-specific optimizations */

  int accel = vis_level ();

  const int high_bit_depth = avctx->bits_per_raw_sample > 8;

  if (accel & ACCEL_SPARC_VIS) {

      if (avctx->bits_per_raw_sample <= 8 &&

          avctx->idct_algo == FF_IDCT_SIMPLEVIS) {

          c->idct_put = ff_simple_idct_put_vis;

          c->idct_add = ff_simple_idct_add_vis;

          c->idct     = ff_simple_idct_vis;

          c->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;

      }

      if (!high_bit_depth) {

      c->put_pixels_tab[0][0] = MC_put_o_16_vis;

      c->put_pixels_tab[0][1] = MC_put_x_16_vis;

      c->put_pixels_tab[0][2] = MC_put_y_16_vis;

      c->put_pixels_tab[0][3] = MC_put_xy_16_vis;

      c->put_pixels_tab[1][0] = MC_put_o_8_vis;

      c->put_pixels_tab[1][1] = MC_put_x_8_vis;

      c->put_pixels_tab[1][2] = MC_put_y_8_vis;

      c->put_pixels_tab[1][3] = MC_put_xy_8_vis;

      c->avg_pixels_tab[0][0] = MC_avg_o_16_vis;

      c->avg_pixels_tab[0][1] = MC_avg_x_16_vis;

      c->avg_pixels_tab[0][2] = MC_avg_y_16_vis;

      c->avg_pixels_tab[0][3] = MC_avg_xy_16_vis;

      c->avg_pixels_tab[1][0] = MC_avg_o_8_vis;

      c->avg_pixels_tab[1][1] = MC_avg_x_8_vis;

      c->avg_pixels_tab[1][2] = MC_avg_y_8_vis;

      c->avg_pixels_tab[1][3] = MC_avg_xy_8_vis;

      c->put_no_rnd_pixels_tab[0][0] = MC_put_no_round_o_16_vis;

      c->put_no_rnd_pixels_tab[0][1] = MC_put_no_round_x_16_vis;

      c->put_no_rnd_pixels_tab[0][2] = MC_put_no_round_y_16_vis;

      c->put_no_rnd_pixels_tab[0][3] = MC_put_no_round_xy_16_vis;

      c->put_no_rnd_pixels_tab[1][0] = MC_put_no_round_o_8_vis;

      c->put_no_rnd_pixels_tab[1][1] = MC_put_no_round_x_8_vis;

      c->put_no_rnd_pixels_tab[1][2] = MC_put_no_round_y_8_vis;

      c->put_no_rnd_pixels_tab[1][3] = MC_put_no_round_xy_8_vis;

      c->avg_no_rnd_pixels_tab[0] = MC_avg_no_round_o_16_vis;

      c->avg_no_rnd_pixels_tab[1] = MC_avg_no_round_x_16_vis;

      c->avg_no_rnd_pixels_tab[2] = MC_avg_no_round_y_16_vis;

      c->avg_no_rnd_pixels_tab[3] = MC_avg_no_round_xy_16_vis;

      }

  }

}


void vp8_mc(VP8Context *s, int luma,

            uint8_t *dst, uint8_t *src, const VP56mv *mv,

            int x_off, int y_off, int block_w, int block_h,

            int width, int height, int linesize,

            vp8_mc_func mc_func[3][3])

{

    if (AV_RN32A(mv)) {

        static const uint8_t idx[3][8] = {

            { 0, 1, 2, 1, 2, 1, 2, 1 }, // nr. of left extra pixels,

                                        // also function pointer index

            { 0, 3, 5, 3, 5, 3, 5, 3 }, // nr. of extra pixels required

            { 0, 2, 3, 2, 3, 2, 3, 2 }, // nr. of right extra pixels

        };

        int mx = (mv->x << luma)&7, mx_idx = idx[0][mx];

        int my = (mv->y << luma)&7, my_idx = idx[0][my];

        x_off += mv->x >> (3 - luma);

        y_off += mv->y >> (3 - luma);

        // edge emulation

        src += y_off * linesize + x_off;

        if (x_off < mx_idx || x_off >= width  - block_w - idx[2][mx] ||

            y_off < my_idx || y_off >= height - block_h - idx[2][my]) {

            s->dsp.emulated_edge_mc(s->edge_emu_buffer, src - my_idx * linesize - mx_idx, linesize,

                                block_w + idx[1][mx], block_h + idx[1][my],

                                x_off - mx_idx, y_off - my_idx, width, height);

            src = s->edge_emu_buffer + mx_idx + linesize * my_idx;

        }

        mc_func[my_idx][mx_idx](dst, linesize, src, linesize, block_h, mx, my);

    } else

        mc_func[0][0](dst, linesize, src + y_off * linesize + x_off, linesize, block_h, 0, 0);

}


static int parse_uint16(DeviceState *dev, Property *prop, const char *str)

{

    uint16_t *ptr = qdev_get_prop_ptr(dev, prop);

    const char *fmt;

    /* accept both hex and decimal */

    fmt = strncasecmp(str, "0x",2) == 0 ? "%" PRIx16 : "%" PRIu16;

    if (sscanf(str, fmt, ptr) != 1)

        return -EINVAL;

    return 0;

}


DECLARE_LOOP_FILTER(mmxext)

DECLARE_LOOP_FILTER(sse2)

DECLARE_LOOP_FILTER(ssse3)

DECLARE_LOOP_FILTER(sse4)

#endif /* HAVE_YASM */

#define VP8_LUMA_MC_FUNC(IDX, SIZE, OPT) \

    c->put_vp8_epel_pixels_tab[IDX][0][2] = ff_put_vp8_epel ## SIZE ## _h6_ ## OPT; \

    c->put_vp8_epel_pixels_tab[IDX][2][0] = ff_put_vp8_epel ## SIZE ## _v6_ ## OPT; \

    c->put_vp8_epel_pixels_tab[IDX][2][2] = ff_put_vp8_epel ## SIZE ## _h6v6_ ## OPT

#define VP8_MC_FUNC(IDX, SIZE, OPT) \

    c->put_vp8_epel_pixels_tab[IDX][0][1] = ff_put_vp8_epel ## SIZE ## _h4_ ## OPT; \

    c->put_vp8_epel_pixels_tab[IDX][1][0] = ff_put_vp8_epel ## SIZE ## _v4_ ## OPT; \

    c->put_vp8_epel_pixels_tab[IDX][1][1] = ff_put_vp8_epel ## SIZE ## _h4v4_ ## OPT; \

    c->put_vp8_epel_pixels_tab[IDX][1][2] = ff_put_vp8_epel ## SIZE ## _h6v4_ ## OPT; \

    c->put_vp8_epel_pixels_tab[IDX][2][1] = ff_put_vp8_epel ## SIZE ## _h4v6_ ## OPT; \

    VP8_LUMA_MC_FUNC(IDX, SIZE, OPT)

#define VP8_BILINEAR_MC_FUNC(IDX, SIZE, OPT) \

    c->put_vp8_bilinear_pixels_tab[IDX][0][1] = ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][0][2] = ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][1][0] = ff_put_vp8_bilinear ## SIZE ## _v_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][1][1] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][1][2] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][2][0] = ff_put_vp8_bilinear ## SIZE ## _v_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][2][1] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \

    c->put_vp8_bilinear_pixels_tab[IDX][2][2] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT

av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c)

{

#if HAVE_YASM

    int cpu_flags = av_get_cpu_flags();

    if (EXTERNAL_MMX(cpu_flags)) {

        c->vp8_idct_dc_add    = ff_vp8_idct_dc_add_mmx;

        c->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmx;

#if ARCH_X86_32

        c->vp8_idct_dc_add4y  = ff_vp8_idct_dc_add4y_mmx;

        c->vp8_idct_add       = ff_vp8_idct_add_mmx;

        c->vp8_luma_dc_wht    = ff_vp8_luma_dc_wht_mmx;

        c->put_vp8_epel_pixels_tab[0][0][0]     =

        c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_mmx;

#endif

        c->put_vp8_epel_pixels_tab[1][0][0]     =

        c->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_mmx;

#if ARCH_X86_32

        c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmx;

        c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmx;

        c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_mmx;

        c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_mmx;

        c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmx;

        c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmx;

        c->vp8_v_loop_filter16y       = ff_vp8_v_loop_filter16y_mbedge_mmx;

        c->vp8_h_loop_filter16y       = ff_vp8_h_loop_filter16y_mbedge_mmx;

        c->vp8_v_loop_filter8uv       = ff_vp8_v_loop_filter8uv_mbedge_mmx;

        c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_mmx;

#endif

    }

    /* note that 4-tap width=16 functions are missing because w=16

     * is only used for luma, and luma is always a copy or sixtap. */

    if (EXTERNAL_MMXEXT(cpu_flags)) {

        VP8_MC_FUNC(2, 4, mmxext);

        VP8_BILINEAR_MC_FUNC(2, 4, mmxext);

#if ARCH_X86_32

        VP8_LUMA_MC_FUNC(0, 16, mmxext);

        VP8_MC_FUNC(1, 8, mmxext);

        VP8_BILINEAR_MC_FUNC(0, 16, mmxext);

        VP8_BILINEAR_MC_FUNC(1,  8, mmxext);

        c->vp8_v_loop_filter_simple   = ff_vp8_v_loop_filter_simple_mmxext;

        c->vp8_h_loop_filter_simple   = ff_vp8_h_loop_filter_simple_mmxext;

        c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_mmxext;

        c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_mmxext;

        c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmxext;

        c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmxext;

        c->vp8_v_loop_filter16y       = ff_vp8_v_loop_filter16y_mbedge_mmxext;

        c->vp8_h_loop_filter16y       = ff_vp8_h_loop_filter16y_mbedge_mmxext;

        c->vp8_v_loop_filter8uv       = ff_vp8_v_loop_filter8uv_mbedge_mmxext;

        c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_mmxext;

#endif

    }

    if (EXTERNAL_SSE(cpu_flags)) {

        c->vp8_idct_add                         = ff_vp8_idct_add_sse;

        c->vp8_luma_dc_wht                      = ff_vp8_luma_dc_wht_sse;

        c->put_vp8_epel_pixels_tab[0][0][0]     =

        c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_sse;

    }

    if (EXTERNAL_SSE2(cpu_flags) && (cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {

        VP8_LUMA_MC_FUNC(0, 16, sse2);

        VP8_MC_FUNC(1, 8, sse2);

        VP8_BILINEAR_MC_FUNC(0, 16, sse2);

        VP8_BILINEAR_MC_FUNC(1, 8, sse2);

        c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_sse2;

        c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_sse2;

        c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_sse2;

        c->vp8_v_loop_filter16y       = ff_vp8_v_loop_filter16y_mbedge_sse2;

        c->vp8_v_loop_filter8uv       = ff_vp8_v_loop_filter8uv_mbedge_sse2;

    }

    if (EXTERNAL_SSE2(cpu_flags)) {

        c->vp8_idct_dc_add4y          = ff_vp8_idct_dc_add4y_sse2;

        c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse2;

        c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_sse2;

        c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_sse2;

        c->vp8_h_loop_filter16y       = ff_vp8_h_loop_filter16y_mbedge_sse2;

        c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_sse2;

    }

    if (EXTERNAL_SSSE3(cpu_flags)) {

        VP8_LUMA_MC_FUNC(0, 16, ssse3);

        VP8_MC_FUNC(1, 8, ssse3);

        VP8_MC_FUNC(2, 4, ssse3);

        VP8_BILINEAR_MC_FUNC(0, 16, ssse3);

        VP8_BILINEAR_MC_FUNC(1, 8, ssse3);

        VP8_BILINEAR_MC_FUNC(2, 4, ssse3);

        c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_ssse3;

        c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_ssse3;

        c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_ssse3;

        c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_ssse3;

        c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_ssse3;

        c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_ssse3;

        c->vp8_v_loop_filter16y       = ff_vp8_v_loop_filter16y_mbedge_ssse3;

        c->vp8_h_loop_filter16y       = ff_vp8_h_loop_filter16y_mbedge_ssse3;

        c->vp8_v_loop_filter8uv       = ff_vp8_v_loop_filter8uv_mbedge_ssse3;

        c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_ssse3;

    }

    if (EXTERNAL_SSE4(cpu_flags)) {

        c->vp8_idct_dc_add                  = ff_vp8_idct_dc_add_sse4;

        c->vp8_h_loop_filter_simple   = ff_vp8_h_loop_filter_simple_sse4;

        c->vp8_h_loop_filter16y       = ff_vp8_h_loop_filter16y_mbedge_sse4;

        c->vp8_h_loop_filter8uv       = ff_vp8_h_loop_filter8uv_mbedge_sse4;

    }

#endif /* HAVE_YASM */

}


static int get_bat (CPUState *env, mmu_ctx_t *ctx,

                    target_ulong virtual, int rw, int type)

{

    target_ulong *BATlt, *BATut, *BATu, *BATl;

    target_ulong base, BEPIl, BEPIu, bl;

    int i;

    int ret = -1;

#if defined (DEBUG_BATS)

    if (loglevel != 0) {

        fprintf(logfile, "%s: %cBAT v 0x" ADDRX "\n", __func__,

                type == ACCESS_CODE ? 'I' : 'D', virtual);

    }

#endif

    switch (type) {

    case ACCESS_CODE:

        BATlt = env->IBAT[1];

        BATut = env->IBAT[0];

        break;

    default:

        BATlt = env->DBAT[1];

        BATut = env->DBAT[0];

        break;

    }

#if defined (DEBUG_BATS)

    if (loglevel != 0) {

        fprintf(logfile, "%s...: %cBAT v 0x" ADDRX "\n", __func__,

                type == ACCESS_CODE ? 'I' : 'D', virtual);

    }

#endif

    base = virtual & 0xFFFC0000;

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

        BATu = &BATut[i];

        BATl = &BATlt[i];

        BEPIu = *BATu & 0xF0000000;

        BEPIl = *BATu & 0x0FFE0000;

        bl = (*BATu & 0x00001FFC) << 15;

#if defined (DEBUG_BATS)

        if (loglevel != 0) {

            fprintf(logfile, "%s: %cBAT%d v 0x" ADDRX " BATu 0x" ADDRX

                    " BATl 0x" ADDRX "\n",

                    __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,

                    *BATu, *BATl);

        }

#endif

        if ((virtual & 0xF0000000) == BEPIu &&

            ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {

            /* BAT matches */

            if ((msr_pr == 0 && (*BATu & 0x00000002)) ||

                (msr_pr == 1 && (*BATu & 0x00000001))) {

                /* Get physical address */

                ctx->raddr = (*BATl & 0xF0000000) |

                    ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |

                    (virtual & 0x0001F000);

                if (*BATl & 0x00000001)

                    ctx->prot = PAGE_READ;

                if (*BATl & 0x00000002)

                    ctx->prot = PAGE_WRITE | PAGE_READ;

#if defined (DEBUG_BATS)

                if (loglevel != 0) {

                    fprintf(logfile, "BAT %d match: r 0x" PADDRX

                            " prot=%c%c\n",

                            i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',

                            ctx->prot & PAGE_WRITE ? 'W' : '-');

                }

#endif

                ret = 0;

                break;

            }

        }

    }

    if (ret < 0) {

#if defined (DEBUG_BATS)

        if (loglevel != 0) {

            fprintf(logfile, "no BAT match for 0x" ADDRX ":\n", virtual);

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

                BATu = &BATut[i];

                BATl = &BATlt[i];

                BEPIu = *BATu & 0xF0000000;

                BEPIl = *BATu & 0x0FFE0000;

                bl = (*BATu & 0x00001FFC) << 15;

                fprintf(logfile, "%s: %cBAT%d v 0x" ADDRX " BATu 0x" ADDRX

                        " BATl 0x" ADDRX " \n\t"

                        "0x" ADDRX " 0x" ADDRX " 0x" ADDRX "\n",

                        __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,

                        *BATu, *BATl, BEPIu, BEPIl, bl);

            }

        }

#endif

    }

    /* No hit */

    return ret;

}


static void *migration_thread(void *opaque)

{

    MigrationState *s = opaque;

    /* Used by the bandwidth calcs, updated later */

    int64_t initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);

    int64_t setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST);

    int64_t initial_bytes = 0;

    int64_t max_size = 0;

    int64_t start_time = initial_time;

    int64_t end_time;

    bool old_vm_running = false;

    bool entered_postcopy = false;

    /* The active state we expect to be in; ACTIVE or POSTCOPY_ACTIVE */

    enum MigrationStatus current_active_state = MIGRATION_STATUS_ACTIVE;

    rcu_register_thread();

    qemu_savevm_state_header(s->to_dst_file);

    if (migrate_postcopy_ram()) {

        /* Now tell the dest that it should open its end so it can reply */

        qemu_savevm_send_open_return_path(s->to_dst_file);

        /* And do a ping that will make stuff easier to debug */

        qemu_savevm_send_ping(s->to_dst_file, 1);

        /*

         * Tell the destination that we *might* want to do postcopy later;

         * if the other end can't do postcopy it should fail now, nice and

         * early.

         */

        qemu_savevm_send_postcopy_advise(s->to_dst_file);

    }

    qemu_savevm_state_begin(s->to_dst_file, &s->params);

    s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;

    current_active_state = MIGRATION_STATUS_ACTIVE;

    migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,

                      MIGRATION_STATUS_ACTIVE);

    trace_migration_thread_setup_complete();

    while (s->state == MIGRATION_STATUS_ACTIVE ||

           s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {

        int64_t current_time;

        uint64_t pending_size;

        if (!qemu_file_rate_limit(s->to_dst_file)) {

            uint64_t pend_post, pend_nonpost;

            qemu_savevm_state_pending(s->to_dst_file, max_size, &pend_nonpost,

                                      &pend_post);

            pending_size = pend_nonpost + pend_post;

            trace_migrate_pending(pending_size, max_size,

                                  pend_post, pend_nonpost);

            if (pending_size && pending_size >= max_size) {

                /* Still a significant amount to transfer */

                if (migrate_postcopy_ram() &&

                    s->state != MIGRATION_STATUS_POSTCOPY_ACTIVE &&

                    pend_nonpost <= max_size &&

                    atomic_read(&s->start_postcopy)) {

                    if (!postcopy_start(s, &old_vm_running)) {

                        current_active_state = MIGRATION_STATUS_POSTCOPY_ACTIVE;

                        entered_postcopy = true;

                    }

                    continue;

                }

                /* Just another iteration step */

                qemu_savevm_state_iterate(s->to_dst_file, entered_postcopy);

            } else {

                trace_migration_thread_low_pending(pending_size);

                migration_completion(s, current_active_state,

                                     &old_vm_running, &start_time);

                break;

            }

        }

        if (qemu_file_get_error(s->to_dst_file)) {

            migrate_set_state(&s->state, current_active_state,

                              MIGRATION_STATUS_FAILED);

            trace_migration_thread_file_err();

            break;

        }

        current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);

        if (current_time >= initial_time + BUFFER_DELAY) {

            uint64_t transferred_bytes = qemu_ftell(s->to_dst_file) -

                                         initial_bytes;

            uint64_t time_spent = current_time - initial_time;

            double bandwidth = (double)transferred_bytes / time_spent;

            max_size = bandwidth * migrate_max_downtime() / 1000000;

            s->mbps = (((double) transferred_bytes * 8.0) /

                    ((double) time_spent / 1000.0)) / 1000.0 / 1000.0;

            trace_migrate_transferred(transferred_bytes, time_spent,

                                      bandwidth, max_size);

            /* if we haven't sent anything, we don't want to recalculate

               10000 is a small enough number for our purposes */

            if (s->dirty_bytes_rate && transferred_bytes > 10000) {

                s->expected_downtime = s->dirty_bytes_rate / bandwidth;

            }

            qemu_file_reset_rate_limit(s->to_dst_file);

            initial_time = current_time;

            initial_bytes = qemu_ftell(s->to_dst_file);

        }

        if (qemu_file_rate_limit(s->to_dst_file)) {

            /* usleep expects microseconds */

            g_usleep((initial_time + BUFFER_DELAY - current_time)*1000);

        }

    }

    trace_migration_thread_after_loop();

    /* If we enabled cpu throttling for auto-converge, turn it off. */

    cpu_throttle_stop();

    end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);

    qemu_mutex_lock_iothread();

    qemu_savevm_state_cleanup();

    if (s->state == MIGRATION_STATUS_COMPLETED) {

        uint64_t transferred_bytes = qemu_ftell(s->to_dst_file);

        s->total_time = end_time - s->total_time;

        if (!entered_postcopy) {

            s->downtime = end_time - start_time;

        }

        if (s->total_time) {

            s->mbps = (((double) transferred_bytes * 8.0) /

                       ((double) s->total_time)) / 1000;

        }

        runstate_set(RUN_STATE_POSTMIGRATE);

    } else {

        if (old_vm_running && !entered_postcopy) {

            vm_start();

        } else {

            if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {

                runstate_set(RUN_STATE_POSTMIGRATE);

            }

        }

    }

    qemu_bh_schedule(s->cleanup_bh);

    qemu_mutex_unlock_iothread();

    rcu_unregister_thread();

    return NULL;

}


void replay_input_event(QemuConsole *src, InputEvent *evt)

{

    if (replay_mode == REPLAY_MODE_PLAY) {

        /* Nothing */

    } else if (replay_mode == REPLAY_MODE_RECORD) {

        replay_add_input_event(qapi_clone_InputEvent(evt));

    } else {

        qemu_input_event_send_impl(src, evt);

    }

}


static inline unsigned int get_uint(ShortenContext *s, int k)

{

    if (s->version != 0)

        k = get_ur_golomb_shorten(&s->gb, ULONGSIZE);

    return get_ur_golomb_shorten(&s->gb, k);

}


static void scale_coefs (

    int32_t *dst,

    const int32_t *src,

    int dynrng,

    int len)

{

    int i, shift, round;

    int16_t mul;

    int temp, temp1, temp2, temp3, temp4, temp5, temp6, temp7;

    mul = (dynrng & 0x1f) + 0x20;

    shift = 4 - ((dynrng << 23) >> 28);

    if (shift > 0 ) {

      round = 1 << (shift-1);

      for (i=0; i<len; i+=8) {

          temp = src[i] * mul;

          temp1 = src[i+1] * mul;

          temp = temp + round;

          temp2 = src[i+2] * mul;

          temp1 = temp1 + round;

          dst[i] = temp >> shift;

          temp3 = src[i+3] * mul;

          temp2 = temp2 + round;

          dst[i+1] = temp1 >> shift;

          temp4 = src[i + 4] * mul;

          temp3 = temp3 + round;

          dst[i+2] = temp2 >> shift;

          temp5 = src[i+5] * mul;

          temp4 = temp4 + round;

          dst[i+3] = temp3 >> shift;

          temp6 = src[i+6] * mul;

          dst[i+4] = temp4 >> shift;

          temp5 = temp5 + round;

          temp7 = src[i+7] * mul;

          temp6 = temp6 + round;

          dst[i+5] = temp5 >> shift;

          temp7 = temp7 + round;

          dst[i+6] = temp6 >> shift;

          dst[i+7] = temp7 >> shift;

      }

    } else {

      shift = -shift;

      for (i=0; i<len; i+=8) {

          temp = src[i] * mul;

          temp1 = src[i+1] * mul;

          temp2 = src[i+2] * mul;

          dst[i] = temp << shift;

          temp3 = src[i+3] * mul;

          dst[i+1] = temp1 << shift;

          temp4 = src[i + 4] * mul;

          dst[i+2] = temp2 << shift;

          temp5 = src[i+5] * mul;

          dst[i+3] = temp3 << shift;

          temp6 = src[i+6] * mul;

          dst[i+4] = temp4 << shift;

          temp7 = src[i+7] * mul;

          dst[i+5] = temp5 << shift;

          dst[i+6] = temp6 << shift;

          dst[i+7] = temp7 << shift;

      }

    }

}


static int handle_parse_opts(QemuOpts *opts, FsDriverEntry *fse, Error **errp)
{
    const char *sec_model = qemu_opt_get(opts, "security_model");
    const char *path = qemu_opt_get(opts, "path");
    if (sec_model) {
        error_report("Invalid argument security_model specified with handle fsdriver");
        return -1;
    }
    if (!path) {
        error_report("fsdev: No path specified");
        return -1;
    }
    fse->path = g_strdup(path);
    return 0;
}


void vnc_sasl_client_cleanup(VncState *vs)

{

    if (vs->sasl.conn) {

        vs->sasl.runSSF = vs->sasl.waitWriteSSF = vs->sasl.wantSSF = 0;

        vs->sasl.encodedLength = vs->sasl.encodedOffset = 0;

        vs->sasl.encoded = NULL;

        g_free(vs->sasl.username);

        free(vs->sasl.mechlist);

        vs->sasl.username = vs->sasl.mechlist = NULL;

        sasl_dispose(&vs->sasl.conn);

        vs->sasl.conn = NULL;

    }

}


static int integratorcm_init(SysBusDevice *dev)

{

    IntegratorCMState *s = INTEGRATOR_CM(dev);

    s->cm_osc = 0x01000048;

    /* ??? What should the high bits of this value be?  */

    s->cm_auxosc = 0x0007feff;

    s->cm_sdram = 0x00011122;

    if (s->memsz >= 256) {

        integrator_spd[31] = 64;

        s->cm_sdram |= 0x10;

    } else if (s->memsz >= 128) {

        integrator_spd[31] = 32;

        s->cm_sdram |= 0x0c;

    } else if (s->memsz >= 64) {

        integrator_spd[31] = 16;

        s->cm_sdram |= 0x08;

    } else if (s->memsz >= 32) {

        integrator_spd[31] = 4;

        s->cm_sdram |= 0x04;

    } else {

        integrator_spd[31] = 2;

    }

    memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);

    s->cm_init = 0x00000112;

    s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,

                                   1000);

    memory_region_init_ram(&s->flash, OBJECT(s), "integrator.flash", 0x100000,

                           &error_abort);

    vmstate_register_ram_global(&s->flash);

    memory_region_init_io(&s->iomem, OBJECT(s), &integratorcm_ops, s,

                          "integratorcm", 0x00800000);

    sysbus_init_mmio(dev, &s->iomem);

    integratorcm_do_remap(s);

    /* ??? Save/restore.  */

    return 0;

}


static void unterminated_array_comma(void)

{

    QObject *obj = qobject_from_json("[32,", NULL);

    g_assert(obj == NULL);

}


static int svq1_decode_frame_header(GetBitContext *bitbuf, MpegEncContext *s)

{

    int frame_size_code;

    skip_bits(bitbuf, 8); /* temporal_reference */

    /* frame type */

    s->pict_type = get_bits(bitbuf, 2) + 1;

    if (s->pict_type == 4)

        return AVERROR_INVALIDDATA;

    if (s->pict_type == AV_PICTURE_TYPE_I) {

        /* unknown fields */

        if (s->f_code == 0x50 || s->f_code == 0x60) {

            int csum = get_bits(bitbuf, 16);

            csum = ff_svq1_packet_checksum(bitbuf->buffer,

                                           bitbuf->size_in_bits >> 3,

                                           csum);

            av_dlog(s->avctx, "%s checksum (%02x) for packet data\n",

                    (csum == 0) ? "correct" : "incorrect", csum);

        }

        if ((s->f_code ^ 0x10) >= 0x50) {

            uint8_t msg[256];

            svq1_parse_string(bitbuf, msg);

            av_log(s->avctx, AV_LOG_ERROR,

                   "embedded message: \"%s\"\n", (char *)msg);

        }

        skip_bits(bitbuf, 2);

        skip_bits(bitbuf, 2);

        skip_bits1(bitbuf);

        /* load frame size */

        frame_size_code = get_bits(bitbuf, 3);

        if (frame_size_code == 7) {

            /* load width, height (12 bits each) */

            s->width  = get_bits(bitbuf, 12);

            s->height = get_bits(bitbuf, 12);

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

                return AVERROR_INVALIDDATA;

        } else {

            /* get width, height from table */

            s->width  = ff_svq1_frame_size_table[frame_size_code].width;

            s->height = ff_svq1_frame_size_table[frame_size_code].height;

        }

    }

    /* unknown fields */

    if (get_bits1(bitbuf) == 1) {

        skip_bits1(bitbuf);    /* use packet checksum if (1) */

        skip_bits1(bitbuf);    /* component checksums after image data if (1) */

        if (get_bits(bitbuf, 2) != 0)

            return AVERROR_INVALIDDATA;

    }

    if (get_bits1(bitbuf) == 1) {

        skip_bits1(bitbuf);

        skip_bits(bitbuf, 4);

        skip_bits1(bitbuf);

        skip_bits(bitbuf, 2);

        while (get_bits1(bitbuf) == 1)

            skip_bits(bitbuf, 8);

    }

    return 0;

}


void prepare_grab(void)

{

    fprintf(stderr, "Must supply at least one input file\n");

    exit(1);

}


static int compare_codec_desc(const void *a, const void *b)

{

    const AVCodecDescriptor * const *da = a;

    const AVCodecDescriptor * const *db = b;

    return (*da)->type != (*db)->type ? (*da)->type - (*db)->type :

           strcmp((*da)->name, (*db)->name);

}


static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,

                           struct iovec *iov, int niov, int create,

                           enum AIOCBState aiocb_type)

{

    int nr_copies = s->inode.nr_copies;

    SheepdogObjReq hdr;

    unsigned int wlen;

    int ret;

    uint64_t oid = aio_req->oid;

    unsigned int datalen = aio_req->data_len;

    uint64_t offset = aio_req->offset;

    uint8_t flags = aio_req->flags;

    uint64_t old_oid = aio_req->base_oid;

    if (!nr_copies) {

        error_report("bug");

    }

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

    if (aiocb_type == AIOCB_READ_UDATA) {

        wlen = 0;

        hdr.opcode = SD_OP_READ_OBJ;

        hdr.flags = flags;

    } else if (create) {

        wlen = datalen;

        hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;

        hdr.flags = SD_FLAG_CMD_WRITE | flags;

    } else {

        wlen = datalen;

        hdr.opcode = SD_OP_WRITE_OBJ;

        hdr.flags = SD_FLAG_CMD_WRITE | flags;

    }

    hdr.oid = oid;

    hdr.cow_oid = old_oid;

    hdr.copies = s->inode.nr_copies;

    hdr.data_length = datalen;

    hdr.offset = offset;

    hdr.id = aio_req->id;

    qemu_co_mutex_lock(&s->lock);

    s->co_send = qemu_coroutine_self();

    qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request,

                            aio_flush_request, NULL, s);

    set_cork(s->fd, 1);

    /* send a header */

    ret = do_write(s->fd, &hdr, sizeof(hdr));

    if (ret) {

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

        return -EIO;

    }

    if (wlen) {

        ret = do_writev(s->fd, iov, wlen, aio_req->iov_offset);

        if (ret) {

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

            return -EIO;

        }

    }

    set_cork(s->fd, 0);

    qemu_aio_set_fd_handler(s->fd, co_read_response, NULL,

                            aio_flush_request, NULL, s);

    return 0;

}


static void ehci_writeback_async_complete_packet(EHCIPacket *p)
{
    EHCIQueue *q = p->queue;
    int state;
    state = ehci_get_state(q->ehci, q->async);
    ehci_state_executing(q);
    ehci_state_writeback(q); /* Frees the packet! */
    if (!(q->qh.token & QTD_TOKEN_HALT)) {
        ehci_state_advqueue(q);
    ehci_set_state(q->ehci, q->async, state);


static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,

                           int base, int16_t offset)

{

    const char *opn = "ldst_pair";

    TCGv t0, t1;

    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {

        generate_exception(ctx, EXCP_RI);

        return;

    }

    t0 = tcg_temp_new();

    t1 = tcg_temp_new();

    gen_base_offset_addr(ctx, t0, base, offset);

    switch (opc) {

    case LWP:

        save_cpu_state(ctx, 0);

        op_ld_lw(t1, t0, ctx);

        gen_store_gpr(t1, rd);

        tcg_gen_movi_tl(t1, 4);

        gen_op_addr_add(ctx, t0, t0, t1);

        op_ld_lw(t1, t0, ctx);

        gen_store_gpr(t1, rd+1);

        opn = "lwp";

        break;

    case SWP:

        save_cpu_state(ctx, 0);

        gen_load_gpr(t1, rd);

        op_st_sw(t1, t0, ctx);

        tcg_gen_movi_tl(t1, 4);

        gen_op_addr_add(ctx, t0, t0, t1);

        gen_load_gpr(t1, rd+1);

        op_st_sw(t1, t0, ctx);

        opn = "swp";

        break;

#ifdef TARGET_MIPS64

    case LDP:

        save_cpu_state(ctx, 0);

        op_ld_ld(t1, t0, ctx);

        gen_store_gpr(t1, rd);

        tcg_gen_movi_tl(t1, 8);

        gen_op_addr_add(ctx, t0, t0, t1);

        op_ld_ld(t1, t0, ctx);

        gen_store_gpr(t1, rd+1);

        opn = "ldp";

        break;

    case SDP:

        save_cpu_state(ctx, 0);

        gen_load_gpr(t1, rd);

        op_st_sd(t1, t0, ctx);

        tcg_gen_movi_tl(t1, 8);

        gen_op_addr_add(ctx, t0, t0, t1);

        gen_load_gpr(t1, rd+1);

        op_st_sd(t1, t0, ctx);

        opn = "sdp";

        break;

#endif

    }

    (void)opn; /* avoid a compiler warning */

    MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);

    tcg_temp_free(t0);

    tcg_temp_free(t1);

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    DIAG288Class *diag288 = DIAG288_CLASS(klass);

    dc->realize = wdt_diag288_realize;

    dc->unrealize = wdt_diag288_unrealize;

    dc->reset = wdt_diag288_reset;

    set_bit(DEVICE_CATEGORY_MISC, dc->categories);

    dc->vmsd = &vmstate_diag288;

    diag288->handle_timer = wdt_diag288_handle_timer;

}


int ff_estimate_motion_b(MpegEncContext * s,

                       int mb_x, int mb_y, int16_t (*mv_table)[2], uint8_t *ref_picture, int f_code)

{

    int mx, my, range, dmin;

    int xmin, ymin, xmax, ymax;

    int rel_xmin, rel_ymin, rel_xmax, rel_ymax;

    int pred_x=0, pred_y=0;

    int P[6][2];

    const int shift= 1+s->quarter_sample;

    const int mot_stride = s->mb_width + 2;

    const int mot_xy = (mb_y + 1)*mot_stride + mb_x + 1;

    get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, f_code);

    switch(s->me_method) {

    case ME_ZERO:

    default:

	no_motion_search(s, &mx, &my);

        dmin = 0;

        break;

    case ME_FULL:

	dmin = full_motion_search(s, &mx, &my, range, xmin, ymin, xmax, ymax, ref_picture);

        break;

    case ME_LOG:

	dmin = log_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax, ref_picture);

        break;

    case ME_PHODS:

	dmin = phods_motion_search(s, &mx, &my, range / 2, xmin, ymin, xmax, ymax, ref_picture);

        break;

    case ME_X1:

    case ME_EPZS:

       {

            rel_xmin= xmin - mb_x*16;

            rel_xmax= xmax - mb_x*16;

            rel_ymin= ymin - mb_y*16;

            rel_ymax= ymax - mb_y*16;

            P[0][0] = mv_table[mot_xy    ][0];

            P[0][1] = mv_table[mot_xy    ][1];

            P[1][0] = mv_table[mot_xy - 1][0];

            P[1][1] = mv_table[mot_xy - 1][1];

            if(P[1][0] > (rel_xmax<<shift)) P[1][0]= (rel_xmax<<shift);

            /* special case for first line */

            if ((mb_y == 0 || s->first_slice_line || s->first_gob_line)) {

                P[4][0] = P[1][0];

                P[4][1] = P[1][1];

            } else {

                P[2][0] = mv_table[mot_xy - mot_stride             ][0];

                P[2][1] = mv_table[mot_xy - mot_stride             ][1];

                P[3][0] = mv_table[mot_xy - mot_stride + 1         ][0];

                P[3][1] = mv_table[mot_xy - mot_stride + 1         ][1];

                if(P[2][1] > (rel_ymax<<shift)) P[2][1]= (rel_ymax<<shift);

                if(P[3][0] < (rel_xmin<<shift)) P[3][0]= (rel_xmin<<shift);

                if(P[3][1] > (rel_ymax<<shift)) P[3][1]= (rel_ymax<<shift);

                P[4][0]= mid_pred(P[1][0], P[2][0], P[3][0]);

                P[4][1]= mid_pred(P[1][1], P[2][1], P[3][1]);

            }

            pred_x= P[1][0];

            pred_y= P[1][1];

        }

        dmin = epzs_motion_search(s, &mx, &my, P, pred_x, pred_y, rel_xmin, rel_ymin, rel_xmax, rel_ymax, ref_picture);

        mx+= mb_x*16;

        my+= mb_y*16;

        break;

    }

    /* intra / predictive decision */

//    xx = mb_x * 16;

//    yy = mb_y * 16;

//    pix = s->new_picture[0] + (yy * s->linesize) + xx;

    /* At this point (mx,my) are full-pell and the absolute displacement */

//    ppix = ref_picture + (my * s->linesize) + mx;

    dmin= halfpel_motion_search(s, &mx, &my, dmin, xmin, ymin, xmax, ymax, pred_x, pred_y, ref_picture);

//    s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;

    mv_table[mot_xy][0]= mx;

    mv_table[mot_xy][1]= my;

    return dmin;

}