static void stellaris_enet_receive(void *opaque, const uint8_t *buf, size_t size)

{

    stellaris_enet_state *s = (stellaris_enet_state *)opaque;

    int n;

    uint8_t *p;

    uint32_t crc;

    if ((s->rctl & SE_RCTL_RXEN) == 0)

        return;

    if (s->np >= 31) {

        DPRINTF("Packet dropped\n");

        return;

    }

    DPRINTF("Received packet len=%d\n", size);

    n = s->next_packet + s->np;

    if (n >= 31)

        n -= 31;

    s->np++;

    s->rx[n].len = size + 6;

    p = s->rx[n].data;

    *(p++) = (size + 6);

    *(p++) = (size + 6) >> 8;

    memcpy (p, buf, size);

    p += size;

    crc = crc32(~0, buf, size);

    *(p++) = crc;

    *(p++) = crc >> 8;

    *(p++) = crc >> 16;

    *(p++) = crc >> 24;

    /* Clear the remaining bytes in the last word.  */

    if ((size & 3) != 2) {

        memset(p, 0, (6 - size) & 3);

    }

    s->ris |= SE_INT_RX;

    stellaris_enet_update(s);

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->init = virtio_blk_init_pci;

    k->exit = virtio_blk_exit_pci;

    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;

    k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;

    k->revision = VIRTIO_PCI_ABI_VERSION;

    k->class_id = PCI_CLASS_STORAGE_SCSI;

    dc->alias = "virtio-blk";

    dc->reset = virtio_pci_reset;

    dc->props = virtio_blk_properties;

}


static void qxl_dirty_surfaces(PCIQXLDevice *qxl)

{

    uintptr_t vram_start;

    int i;

    if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) {

        return;

    }

    /* dirty the primary surface */

    qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,

                  qxl->shadow_rom.surface0_area_size);

    vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);

    /* dirty the off-screen surfaces */

    for (i = 0; i < qxl->ssd.num_surfaces; i++) {

        QXLSurfaceCmd *cmd;

        intptr_t surface_offset;

        int surface_size;

        if (qxl->guest_surfaces.cmds[i] == 0) {

            continue;

        }

        cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i],

                            MEMSLOT_GROUP_GUEST);

        assert(cmd);

        assert(cmd->type == QXL_SURFACE_CMD_CREATE);

        surface_offset = (intptr_t)qxl_phys2virt(qxl,

                                                 cmd->u.surface_create.data,

                                                 MEMSLOT_GROUP_GUEST);

        assert(surface_offset);

        surface_offset -= vram_start;

        surface_size = cmd->u.surface_create.height *

                       abs(cmd->u.surface_create.stride);

        trace_qxl_surfaces_dirty(qxl->id, i, (int)surface_offset, surface_size);

        qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);

    }

}


static void xics_reset(DeviceState *d)

{

    XICSState *icp = XICS(d);

    int i;

    for (i = 0; i < icp->nr_servers; i++) {

        device_reset(DEVICE(&icp->ss[i]));

    }

    device_reset(DEVICE(icp->ics));

}


void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,

                      int fdt_start_offset, bool coldplug, Error **errp)

{

    trace_spapr_drc_attach(spapr_drc_index(drc));

    if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {

        error_setg(errp, "an attached device is still awaiting release");

        return;

    }

    if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_PCI) {

        g_assert(drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE);

    }

    g_assert(fdt || coldplug);

    drc->dr_indicator = SPAPR_DR_INDICATOR_ACTIVE;

    drc->dev = d;

    drc->fdt = fdt;

    drc->fdt_start_offset = fdt_start_offset;

    drc->configured = coldplug;

    /* 'logical' DR resources such as memory/cpus are in some cases treated

     * as a pool of resources from which the guest is free to choose from

     * based on only a count. for resources that can be assigned in this

     * fashion, we must assume the resource is signalled immediately

     * since a single hotplug request might make an arbitrary number of

     * such attached resources available to the guest, as opposed to

     * 'physical' DR resources such as PCI where each device/resource is

     * signalled individually.

     */

    drc->signalled = (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI)

                     ? true : coldplug;

    if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) {

        drc->awaiting_allocation = true;

    }

    object_property_add_link(OBJECT(drc), "device",

                             object_get_typename(OBJECT(drc->dev)),

                             (Object **)(&drc->dev),

                             NULL, 0, NULL);

}


static void openpic_src_write(void *opaque, hwaddr addr, uint64_t val,

                              unsigned len)

{

    OpenPICState *opp = opaque;

    int idx;

    DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n",

            __func__, addr, val);

    if (addr & 0xF) {

        return;

    }

    addr = addr & 0xFFF0;

    idx = addr >> 5;

    if (addr & 0x10) {

        /* EXDE / IFEDE / IEEDE */

        write_IRQreg_idr(opp, idx, val);

    } else {

        /* EXVP / IFEVP / IEEVP */

        write_IRQreg_ivpr(opp, idx, val);

    }

}


static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)

{

    gen_set_condexec(s);

    gen_set_pc_im(s, s->pc - offset);

    gen_exception_internal(excp);

    s->is_jmp = DISAS_JUMP;

}


static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)

{

    TCGv tmp;

    switch (op1) {

#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)

    case 0:

        tmp = tcg_temp_new(TCG_TYPE_PTR);

        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));

        PAS_OP(s)

        break;

    case 4:

        tmp = tcg_temp_new(TCG_TYPE_PTR);

        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));

        PAS_OP(u)

        break;

#undef gen_pas_helper

#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)

    case 1:

        PAS_OP(q);

        break;

    case 2:

        PAS_OP(sh);

        break;

    case 5:

        PAS_OP(uq);

        break;

    case 6:

        PAS_OP(uh);

        break;

#undef gen_pas_helper

    }

}


static void test_io_rw_interface(enum AddrMode lba48, enum IOMode dma,

                                 unsigned bufsize, uint64_t sector)

{

    AHCIQState *ahci;

    ahci = ahci_boot_and_enable();

    ahci_test_io_rw_simple(ahci, bufsize, sector,

                           io_cmds[dma][lba48][IO_READ],

                           io_cmds[dma][lba48][IO_WRITE]);

    ahci_shutdown(ahci);

}


static void aio_write_done(void *opaque, int ret)

{

    struct aio_ctx *ctx = opaque;

    struct timeval t2;

    gettimeofday(&t2, NULL);

    if (ret < 0) {

        printf("aio_write failed: %s\n", strerror(-ret));

        goto out;

    }

    if (ctx->qflag) {

        goto out;

    }

    /* Finally, report back -- -C gives a parsable format */

    t2 = tsub(t2, ctx->t1);

    print_report("wrote", &t2, ctx->offset, ctx->qiov.size,

                 ctx->qiov.size, 1, ctx->Cflag);

out:

    qemu_io_free(ctx->buf);

    free(ctx);

}


uint64_t helper_fres (uint64_t arg)

{

    CPU_DoubleU fone, farg;

    float32 f32;

    fone.ll = 0x3FF0000000000000ULL; /* 1.0 */

    farg.ll = arg;

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

        /* sNaN reciprocal */

        farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);

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

        /* Zero reciprocal */

        farg.ll = float_zero_divide_excp(fone.d, farg.d);

    } else {

        farg.d = float64_div(fone.d, farg.d, &env->fp_status);

        f32 = float64_to_float32(farg.d, &env->fp_status);

        farg.d = float32_to_float64(f32, &env->fp_status);

    }

    return farg.ll;

}


static uint64_t uart_read(void *opaque, target_phys_addr_t addr,

                          unsigned size)

{

    LM32UartState *s = opaque;

    uint32_t r = 0;

    addr >>= 2;

    switch (addr) {

    case R_RXTX:

        r = s->regs[R_RXTX];

        s->regs[R_LSR] &= ~LSR_DR;

        uart_update_irq(s);

        break;

    case R_IIR:

    case R_LSR:

    case R_MSR:

        r = s->regs[addr];

        break;

    case R_IER:

    case R_LCR:

    case R_MCR:

    case R_DIV:

        error_report("lm32_uart: read access to write only register 0x"

                TARGET_FMT_plx, addr << 2);

        break;

    default:

        error_report("lm32_uart: read access to unknown register 0x"

                TARGET_FMT_plx, addr << 2);

        break;

    }

    trace_lm32_uart_memory_read(addr << 2, r);

    return r;

}


static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)

{

    uint32_t insn, imm, shift, offset;

    uint32_t rd, rn, rm, rs;

    TCGv_i32 tmp;

    TCGv_i32 tmp2;

    TCGv_i32 tmp3;

    TCGv_i32 addr;

    TCGv_i64 tmp64;

    int op;

    int shiftop;

    int conds;

    int logic_cc;

    if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)

          || arm_dc_feature(s, ARM_FEATURE_M))) {

        /* Thumb-1 cores may need to treat bl and blx as a pair of

           16-bit instructions to get correct prefetch abort behavior.  */

        insn = insn_hw1;

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

            ARCH(5);

            /* Second half of blx.  */

            offset = ((insn & 0x7ff) << 1);

            tmp = load_reg(s, 14);

            tcg_gen_addi_i32(tmp, tmp, offset);

            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);

            tmp2 = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp2, s->pc | 1);

            store_reg(s, 14, tmp2);

            gen_bx(s, tmp);

            return 0;

        }

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

            /* Second half of bl.  */

            offset = ((insn & 0x7ff) << 1) | 1;

            tmp = load_reg(s, 14);

            tcg_gen_addi_i32(tmp, tmp, offset);

            tmp2 = tcg_temp_new_i32();

            tcg_gen_movi_i32(tmp2, s->pc | 1);

            store_reg(s, 14, tmp2);

            gen_bx(s, tmp);

            return 0;

        }

        if ((s->pc & ~TARGET_PAGE_MASK) == 0) {

            /* Instruction spans a page boundary.  Implement it as two

               16-bit instructions in case the second half causes an

               prefetch abort.  */

            offset = ((int32_t)insn << 21) >> 9;

            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);

            return 0;

        }

        /* Fall through to 32-bit decode.  */

    }

    insn = arm_lduw_code(env, s->pc, s->bswap_code);

    s->pc += 2;

    insn |= (uint32_t)insn_hw1 << 16;

    if ((insn & 0xf800e800) != 0xf000e800) {

        ARCH(6T2);

    }

    rn = (insn >> 16) & 0xf;

    rs = (insn >> 12) & 0xf;

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

    rm = insn & 0xf;

    switch ((insn >> 25) & 0xf) {

    case 0: case 1: case 2: case 3:

        /* 16-bit instructions.  Should never happen.  */

        abort();

    case 4:

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

            /* Other load/store, table branch.  */

            if (insn & 0x01200000) {

                /* Load/store doubleword.  */

                if (rn == 15) {

                    addr = tcg_temp_new_i32();

                    tcg_gen_movi_i32(addr, s->pc & ~3);

                } else {

                    addr = load_reg(s, rn);

                }

                offset = (insn & 0xff) * 4;

                if ((insn & (1 << 23)) == 0)

                    offset = -offset;

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

                    tcg_gen_addi_i32(addr, addr, offset);

                    offset = 0;

                }

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

                    /* ldrd */

                    tmp = tcg_temp_new_i32();

                    gen_aa32_ld32u(tmp, addr, get_mem_index(s));

                    store_reg(s, rs, tmp);

                    tcg_gen_addi_i32(addr, addr, 4);

                    tmp = tcg_temp_new_i32();

                    gen_aa32_ld32u(tmp, addr, get_mem_index(s));

                    store_reg(s, rd, tmp);

                } else {

                    /* strd */

                    tmp = load_reg(s, rs);

                    gen_aa32_st32(tmp, addr, get_mem_index(s));

                    tcg_temp_free_i32(tmp);

                    tcg_gen_addi_i32(addr, addr, 4);

                    tmp = load_reg(s, rd);

                    gen_aa32_st32(tmp, addr, get_mem_index(s));

                    tcg_temp_free_i32(tmp);

                }

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

                    /* Base writeback.  */

                    if (rn == 15)

                        goto illegal_op;

                    tcg_gen_addi_i32(addr, addr, offset - 4);

                    store_reg(s, rn, addr);

                } else {

                    tcg_temp_free_i32(addr);

                }

            } else if ((insn & (1 << 23)) == 0) {

                /* Load/store exclusive word.  */

                addr = tcg_temp_local_new_i32();

                load_reg_var(s, addr, rn);

                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);

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

                    gen_load_exclusive(s, rs, 15, addr, 2);

                } else {

                    gen_store_exclusive(s, rd, rs, 15, addr, 2);

                }

                tcg_temp_free_i32(addr);

            } else if ((insn & (7 << 5)) == 0) {

                /* Table Branch.  */

                if (rn == 15) {

                    addr = tcg_temp_new_i32();

                    tcg_gen_movi_i32(addr, s->pc);

                } else {

                    addr = load_reg(s, rn);

                }

                tmp = load_reg(s, rm);

                tcg_gen_add_i32(addr, addr, tmp);

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

                    /* tbh */

                    tcg_gen_add_i32(addr, addr, tmp);

                    tcg_temp_free_i32(tmp);

                    tmp = tcg_temp_new_i32();

                    gen_aa32_ld16u(tmp, addr, get_mem_index(s));

                } else { /* tbb */

                    tcg_temp_free_i32(tmp);

                    tmp = tcg_temp_new_i32();

                    gen_aa32_ld8u(tmp, addr, get_mem_index(s));

                }

                tcg_temp_free_i32(addr);

                tcg_gen_shli_i32(tmp, tmp, 1);

                tcg_gen_addi_i32(tmp, tmp, s->pc);

                store_reg(s, 15, tmp);

            } else {

                int op2 = (insn >> 6) & 0x3;

                op = (insn >> 4) & 0x3;

                switch (op2) {

                case 0:

                    goto illegal_op;

                case 1:

                    /* Load/store exclusive byte/halfword/doubleword */

                    if (op == 2) {

                        goto illegal_op;

                    }

                    ARCH(7);

                    break;

                case 2:

                    /* Load-acquire/store-release */

                    if (op == 3) {

                        goto illegal_op;

                    }

                    /* Fall through */

                case 3:

                    /* Load-acquire/store-release exclusive */

                    ARCH(8);

                    break;

                }

                addr = tcg_temp_local_new_i32();

                load_reg_var(s, addr, rn);

                if (!(op2 & 1)) {

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

                        tmp = tcg_temp_new_i32();

                        switch (op) {

                        case 0: /* ldab */

                            gen_aa32_ld8u(tmp, addr, get_mem_index(s));

                            break;

                        case 1: /* ldah */

                            gen_aa32_ld16u(tmp, addr, get_mem_index(s));

                            break;

                        case 2: /* lda */

                            gen_aa32_ld32u(tmp, addr, get_mem_index(s));

                            break;

                        default:

                            abort();

                        }

                        store_reg(s, rs, tmp);

                    } else {

                        tmp = load_reg(s, rs);

                        switch (op) {

                        case 0: /* stlb */

                            gen_aa32_st8(tmp, addr, get_mem_index(s));

                            break;

                        case 1: /* stlh */

                            gen_aa32_st16(tmp, addr, get_mem_index(s));

                            break;

                        case 2: /* stl */

                            gen_aa32_st32(tmp, addr, get_mem_index(s));

                            break;

                        default:

                            abort();

                        }

                        tcg_temp_free_i32(tmp);

                    }

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

                    gen_load_exclusive(s, rs, rd, addr, op);

                } else {

                    gen_store_exclusive(s, rm, rs, rd, addr, op);

                }

                tcg_temp_free_i32(addr);

            }

        } else {

            /* Load/store multiple, RFE, SRS.  */

            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {

                /* RFE, SRS: not available in user mode or on M profile */

                if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {

                    goto illegal_op;

                }

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

                    /* rfe */

                    addr = load_reg(s, rn);

                    if ((insn & (1 << 24)) == 0)

                        tcg_gen_addi_i32(addr, addr, -8);

                    /* Load PC into tmp and CPSR into tmp2.  */

                    tmp = tcg_temp_new_i32();

                    gen_aa32_ld32u(tmp, addr, get_mem_index(s));

                    tcg_gen_addi_i32(addr, addr, 4);

                    tmp2 = tcg_temp_new_i32();

                    gen_aa32_ld32u(tmp2, addr, get_mem_index(s));

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

                        /* Base writeback.  */

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

                            tcg_gen_addi_i32(addr, addr, 4);

                        } else {

                            tcg_gen_addi_i32(addr, addr, -4);

                        }

                        store_reg(s, rn, addr);

                    } else {

                        tcg_temp_free_i32(addr);

                    }

                    gen_rfe(s, tmp, tmp2);

                } else {

                    /* srs */

                    gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,

                            insn & (1 << 21));

                }

            } else {

                int i, loaded_base = 0;

                TCGv_i32 loaded_var;

                /* Load/store multiple.  */

                addr = load_reg(s, rn);

                offset = 0;

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

                    if (insn & (1 << i))

                        offset += 4;

                }

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

                    tcg_gen_addi_i32(addr, addr, -offset);

                }

                TCGV_UNUSED_I32(loaded_var);

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

                    if ((insn & (1 << i)) == 0)

                        continue;

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

                        /* Load.  */

                        tmp = tcg_temp_new_i32();

                        gen_aa32_ld32u(tmp, addr, get_mem_index(s));

                        if (i == 15) {

                            gen_bx(s, tmp);

                        } else if (i == rn) {

                            loaded_var = tmp;

                            loaded_base = 1;

                        } else {

                            store_reg(s, i, tmp);

                        }

                    } else {

                        /* Store.  */

                        tmp = load_reg(s, i);

                        gen_aa32_st32(tmp, addr, get_mem_index(s));

                        tcg_temp_free_i32(tmp);

                    }

                    tcg_gen_addi_i32(addr, addr, 4);

                }

                if (loaded_base) {

                    store_reg(s, rn, loaded_var);

                }

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

                    /* Base register writeback.  */

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

                        tcg_gen_addi_i32(addr, addr, -offset);

                    }

                    /* Fault if writeback register is in register list.  */

                    if (insn & (1 << rn))

                        goto illegal_op;

                    store_reg(s, rn, addr);

                } else {

                    tcg_temp_free_i32(addr);

                }

            }

        }

        break;

    case 5:

        op = (insn >> 21) & 0xf;

        if (op == 6) {

            if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {

                goto illegal_op;

            }

            /* Halfword pack.  */

            tmp = load_reg(s, rn);

            tmp2 = load_reg(s, rm);

            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);

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

                /* pkhtb */

                if (shift == 0)

                    shift = 31;

                tcg_gen_sari_i32(tmp2, tmp2, shift);

                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);

                tcg_gen_ext16u_i32(tmp2, tmp2);

            } else {

                /* pkhbt */

                if (shift)

                    tcg_gen_shli_i32(tmp2, tmp2, shift);

                tcg_gen_ext16u_i32(tmp, tmp);

                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);

            }

            tcg_gen_or_i32(tmp, tmp, tmp2);

            tcg_temp_free_i32(tmp2);

            store_reg(s, rd, tmp);

        } else {

            /* Data processing register constant shift.  */

            if (rn == 15) {

                tmp = tcg_temp_new_i32();

                tcg_gen_movi_i32(tmp, 0);

            } else {

                tmp = load_reg(s, rn);

            }

            tmp2 = load_reg(s, rm);

            shiftop = (insn >> 4) & 3;

            shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);

            conds = (insn & (1 << 20)) != 0;

            logic_cc = (conds && thumb2_logic_op(op));

            gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);

            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))

                goto illegal_op;

            tcg_temp_free_i32(tmp2);

            if (rd != 15) {

                store_reg(s, rd, tmp);

            } else {

                tcg_temp_free_i32(tmp);

            }

        }

        break;

    case 13: /* Misc data processing.  */

        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);

        if (op < 4 && (insn & 0xf000) != 0xf000)

            goto illegal_op;

        switch (op) {

        case 0: /* Register controlled shift.  */

            tmp = load_reg(s, rn);

            tmp2 = load_reg(s, rm);

            if ((insn & 0x70) != 0)

                goto illegal_op;

            op = (insn >> 21) & 3;

            logic_cc = (insn & (1 << 20)) != 0;

            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);

            if (logic_cc)

                gen_logic_CC(tmp);

            store_reg_bx(s, rd, tmp);

            break;

        case 1: /* Sign/zero extend.  */

            op = (insn >> 20) & 7;

            switch (op) {

            case 0: /* SXTAH, SXTH */

            case 1: /* UXTAH, UXTH */

            case 4: /* SXTAB, SXTB */

            case 5: /* UXTAB, UXTB */

                break;

            case 2: /* SXTAB16, SXTB16 */

            case 3: /* UXTAB16, UXTB16 */

                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {

                    goto illegal_op;

                }

                break;

            default:

                goto illegal_op;

            }

            if (rn != 15) {

                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {

                    goto illegal_op;

                }

            }

            tmp = load_reg(s, rm);

            shift = (insn >> 4) & 3;

            /* ??? In many cases it's not necessary to do a

               rotate, a shift is sufficient.  */

            if (shift != 0)

                tcg_gen_rotri_i32(tmp, tmp, shift * 8);

            op = (insn >> 20) & 7;

            switch (op) {

            case 0: gen_sxth(tmp);   break;

            case 1: gen_uxth(tmp);   break;

            case 2: gen_sxtb16(tmp); break;

            case 3: gen_uxtb16(tmp); break;

            case 4: gen_sxtb(tmp);   break;

            case 5: gen_uxtb(tmp);   break;

            default:

                g_assert_not_reached();

            }

            if (rn != 15) {

                tmp2 = load_reg(s, rn);

                if ((op >> 1) == 1) {

                    gen_add16(tmp, tmp2);

                } else {

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                    tcg_temp_free_i32(tmp2);

                }

            }

            store_reg(s, rd, tmp);

            break;

        case 2: /* SIMD add/subtract.  */

            if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {

                goto illegal_op;

            }

            op = (insn >> 20) & 7;

            shift = (insn >> 4) & 7;

            if ((op & 3) == 3 || (shift & 3) == 3)

                goto illegal_op;

            tmp = load_reg(s, rn);

            tmp2 = load_reg(s, rm);

            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);

            tcg_temp_free_i32(tmp2);

            store_reg(s, rd, tmp);

            break;

        case 3: /* Other data processing.  */

            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);

            if (op < 4) {

                /* Saturating add/subtract.  */

                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {

                    goto illegal_op;

                }

                tmp = load_reg(s, rn);

                tmp2 = load_reg(s, rm);

                if (op & 1)

                    gen_helper_double_saturate(tmp, cpu_env, tmp);

                if (op & 2)

                    gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);

                else

                    gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);

                tcg_temp_free_i32(tmp2);

            } else {

                switch (op) {

                case 0x0a: /* rbit */

                case 0x08: /* rev */

                case 0x09: /* rev16 */

                case 0x0b: /* revsh */

                case 0x18: /* clz */

                    break;

                case 0x10: /* sel */

                    if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {

                        goto illegal_op;

                    }

                    break;

                case 0x20: /* crc32/crc32c */

                case 0x21:

                case 0x22:

                case 0x28:

                case 0x29:

                case 0x2a:

                    if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {

                        goto illegal_op;

                    }

                    break;

                default:

                    goto illegal_op;

                }

                tmp = load_reg(s, rn);

                switch (op) {

                case 0x0a: /* rbit */

                    gen_helper_rbit(tmp, tmp);

                    break;

                case 0x08: /* rev */

                    tcg_gen_bswap32_i32(tmp, tmp);

                    break;

                case 0x09: /* rev16 */

                    gen_rev16(tmp);

                    break;

                case 0x0b: /* revsh */

                    gen_revsh(tmp);

                    break;

                case 0x10: /* sel */

                    tmp2 = load_reg(s, rm);

                    tmp3 = tcg_temp_new_i32();

                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));

                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);

                    tcg_temp_free_i32(tmp3);

                    tcg_temp_free_i32(tmp2);

                    break;

                case 0x18: /* clz */

                    gen_helper_clz(tmp, tmp);

                    break;

                case 0x20:

                case 0x21:

                case 0x22:

                case 0x28:

                case 0x29:

                case 0x2a:

                {

                    /* crc32/crc32c */

                    uint32_t sz = op & 0x3;

                    uint32_t c = op & 0x8;

                    tmp2 = load_reg(s, rm);

                    if (sz == 0) {

                        tcg_gen_andi_i32(tmp2, tmp2, 0xff);

                    } else if (sz == 1) {

                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff);

                    }

                    tmp3 = tcg_const_i32(1 << sz);

                    if (c) {

                        gen_helper_crc32c(tmp, tmp, tmp2, tmp3);

                    } else {

                        gen_helper_crc32(tmp, tmp, tmp2, tmp3);

                    }

                    tcg_temp_free_i32(tmp2);

                    tcg_temp_free_i32(tmp3);

                    break;

                }

                default:

                    g_assert_not_reached();

                }

            }

            store_reg(s, rd, tmp);

            break;

        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */

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

            case 0: /* 32 x 32 -> 32 */

            case 7: /* Unsigned sum of absolute differences.  */

                break;

            case 1: /* 16 x 16 -> 32 */

            case 2: /* Dual multiply add.  */

            case 3: /* 32 * 16 -> 32msb */

            case 4: /* Dual multiply subtract.  */

            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */

                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {

                    goto illegal_op;

                }

                break;

            }

            op = (insn >> 4) & 0xf;

            tmp = load_reg(s, rn);

            tmp2 = load_reg(s, rm);

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

            case 0: /* 32 x 32 -> 32 */

                tcg_gen_mul_i32(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp2);

                if (rs != 15) {

                    tmp2 = load_reg(s, rs);

                    if (op)

                        tcg_gen_sub_i32(tmp, tmp2, tmp);

                    else

                        tcg_gen_add_i32(tmp, tmp, tmp2);

                    tcg_temp_free_i32(tmp2);

                }

                break;

            case 1: /* 16 x 16 -> 32 */

                gen_mulxy(tmp, tmp2, op & 2, op & 1);

                tcg_temp_free_i32(tmp2);

                if (rs != 15) {

                    tmp2 = load_reg(s, rs);

                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);

                    tcg_temp_free_i32(tmp2);

                }

                break;

            case 2: /* Dual multiply add.  */

            case 4: /* Dual multiply subtract.  */

                if (op)

                    gen_swap_half(tmp2);

                gen_smul_dual(tmp, tmp2);

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

                    /* This subtraction cannot overflow. */

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                } else {

                    /* This addition cannot overflow 32 bits;

                     * however it may overflow considered as a signed

                     * operation, in which case we must set the Q flag.

                     */

                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);

                }

                tcg_temp_free_i32(tmp2);

                if (rs != 15)

                  {

                    tmp2 = load_reg(s, rs);

                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);

                    tcg_temp_free_i32(tmp2);

                  }

                break;

            case 3: /* 32 * 16 -> 32msb */

                if (op)

                    tcg_gen_sari_i32(tmp2, tmp2, 16);

                else

                    gen_sxth(tmp2);

                tmp64 = gen_muls_i64_i32(tmp, tmp2);

                tcg_gen_shri_i64(tmp64, tmp64, 16);

                tmp = tcg_temp_new_i32();

                tcg_gen_extrl_i64_i32(tmp, tmp64);

                tcg_temp_free_i64(tmp64);

                if (rs != 15)

                  {

                    tmp2 = load_reg(s, rs);

                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);

                    tcg_temp_free_i32(tmp2);

                  }

                break;

            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */

                tmp64 = gen_muls_i64_i32(tmp, tmp2);

                if (rs != 15) {

                    tmp = load_reg(s, rs);

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

                        tmp64 = gen_addq_msw(tmp64, tmp);

                    } else {

                        tmp64 = gen_subq_msw(tmp64, tmp);

                    }

                }

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

                    tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);

                }

                tcg_gen_shri_i64(tmp64, tmp64, 32);

                tmp = tcg_temp_new_i32();

                tcg_gen_extrl_i64_i32(tmp, tmp64);

                tcg_temp_free_i64(tmp64);

                break;

            case 7: /* Unsigned sum of absolute differences.  */

                gen_helper_usad8(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp2);

                if (rs != 15) {

                    tmp2 = load_reg(s, rs);

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                    tcg_temp_free_i32(tmp2);

                }

                break;

            }

            store_reg(s, rd, tmp);

            break;

        case 6: case 7: /* 64-bit multiply, Divide.  */

            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);

            tmp = load_reg(s, rn);

            tmp2 = load_reg(s, rm);

            if ((op & 0x50) == 0x10) {

                /* sdiv, udiv */

                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {

                    goto illegal_op;

                }

                if (op & 0x20)

                    gen_helper_udiv(tmp, tmp, tmp2);

                else

                    gen_helper_sdiv(tmp, tmp, tmp2);

                tcg_temp_free_i32(tmp2);

                store_reg(s, rd, tmp);

            } else if ((op & 0xe) == 0xc) {

                /* Dual multiply accumulate long.  */

                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {

                    tcg_temp_free_i32(tmp);

                    tcg_temp_free_i32(tmp2);

                    goto illegal_op;

                }

                if (op & 1)

                    gen_swap_half(tmp2);

                gen_smul_dual(tmp, tmp2);

                if (op & 0x10) {

                    tcg_gen_sub_i32(tmp, tmp, tmp2);

                } else {

                    tcg_gen_add_i32(tmp, tmp, tmp2);

                }

                tcg_temp_free_i32(tmp2);

                /* BUGFIX */

                tmp64 = tcg_temp_new_i64();

                tcg_gen_ext_i32_i64(tmp64, tmp);

                tcg_temp_free_i32(tmp);

                gen_addq(s, tmp64, rs, rd);

                gen_storeq_reg(s, rs, rd, tmp64);

                tcg_temp_free_i64(tmp64);

            } else {

                if (op & 0x20) {

                    /* Unsigned 64-bit multiply  */

                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);

                } else {

                    if (op & 8) {

                        /* smlalxy */

                        if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {

                            tcg_temp_free_i32(tmp2);

                            tcg_temp_free_i32(tmp);

                            goto illegal_op;

                        }

                        gen_mulxy(tmp, tmp2, op & 2, op & 1);

                        tcg_temp_free_i32(tmp2);

                        tmp64 = tcg_temp_new_i64();

                        tcg_gen_ext_i32_i64(tmp64, tmp);

                        tcg_temp_free_i32(tmp);

                    } else {

                        /* Signed 64-bit multiply  */

                        tmp64 = gen_muls_i64_i32(tmp, tmp2);

                    }

                }

                if (op & 4) {

                    /* umaal */

                    if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {

                        tcg_temp_free_i64(tmp64);

                        goto illegal_op;

                    }

                    gen_addq_lo(s, tmp64, rs);

                    gen_addq_lo(s, tmp64, rd);

                } else if (op & 0x40) {

                    /* 64-bit accumulate.  */

                    gen_addq(s, tmp64, rs, rd);

                }

                gen_storeq_reg(s, rs, rd, tmp64);

                tcg_temp_free_i64(tmp64);

            }

            break;

        }

        break;

    case 6: case 7: case 14: case 15:

        /* Coprocessor.  */

        if (((insn >> 24) & 3) == 3) {

            /* Translate into the equivalent ARM encoding.  */

            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);

            if (disas_neon_data_insn(s, insn)) {

                goto illegal_op;

            }

        } else if (((insn >> 8) & 0xe) == 10) {

            if (disas_vfp_insn(s, insn)) {

                goto illegal_op;

            }

        } else {

            if (insn & (1 << 28))

                goto illegal_op;

            if (disas_coproc_insn(s, insn)) {

                goto illegal_op;

            }

        }

        break;

    case 8: case 9: case 10: case 11:

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

            /* Branches, misc control.  */

            if (insn & 0x5000) {

                /* Unconditional branch.  */

                /* signextend(hw1[10:0]) -> offset[:12].  */

                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;

                /* hw1[10:0] -> offset[11:1].  */

                offset |= (insn & 0x7ff) << 1;

                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]

                   offset[24:22] already have the same value because of the

                   sign extension above.  */

                offset ^= ((~insn) & (1 << 13)) << 10;

                offset ^= ((~insn) & (1 << 11)) << 11;

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

                    /* Branch and link.  */

                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);

                }

                offset += s->pc;

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

                    /* b/bl */

                    gen_jmp(s, offset);

                } else {

                    /* blx */

                    offset &= ~(uint32_t)2;

                    /* thumb2 bx, no need to check */

                    gen_bx_im(s, offset);

                }

            } else if (((insn >> 23) & 7) == 7) {

                /* Misc control */

                if (insn & (1 << 13))

                    goto illegal_op;

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

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

                        /* Hypervisor call (v7) */

                        int imm16 = extract32(insn, 16, 4) << 12

                            | extract32(insn, 0, 12);

                        ARCH(7);

                        if (IS_USER(s)) {

                            goto illegal_op;

                        }

                        gen_hvc(s, imm16);

                    } else {

                        /* Secure monitor call (v6+) */

                        ARCH(6K);

                        if (IS_USER(s)) {

                            goto illegal_op;

                        }

                        gen_smc(s);

                    }

                } else {

                    op = (insn >> 20) & 7;

                    switch (op) {

                    case 0: /* msr cpsr.  */

                        if (arm_dc_feature(s, ARM_FEATURE_M)) {

                            tmp = load_reg(s, rn);

                            addr = tcg_const_i32(insn & 0xff);

                            gen_helper_v7m_msr(cpu_env, addr, tmp);

                            tcg_temp_free_i32(addr);

                            tcg_temp_free_i32(tmp);

                            gen_lookup_tb(s);

                            break;

                        }

                        /* fall through */

                    case 1: /* msr spsr.  */

                        if (arm_dc_feature(s, ARM_FEATURE_M)) {

                            goto illegal_op;

                        }

                        tmp = load_reg(s, rn);

                        if (gen_set_psr(s,

                              msr_mask(s, (insn >> 8) & 0xf, op == 1),

                              op == 1, tmp))

                            goto illegal_op;

                        break;

                    case 2: /* cps, nop-hint.  */

                        if (((insn >> 8) & 7) == 0) {

                            gen_nop_hint(s, insn & 0xff);

                        }

                        /* Implemented as NOP in user mode.  */

                        if (IS_USER(s))

                            break;

                        offset = 0;

                        imm = 0;

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

                            if (insn & (1 << 7))

                                offset |= CPSR_A;

                            if (insn & (1 << 6))

                                offset |= CPSR_I;

                            if (insn & (1 << 5))

                                offset |= CPSR_F;

                            if (insn & (1 << 9))

                                imm = CPSR_A | CPSR_I | CPSR_F;

                        }

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

                            offset |= 0x1f;

                            imm |= (insn & 0x1f);

                        }

                        if (offset) {

                            gen_set_psr_im(s, offset, 0, imm);

                        }

                        break;

                    case 3: /* Special control operations.  */

                        ARCH(7);

                        op = (insn >> 4) & 0xf;

                        switch (op) {

                        case 2: /* clrex */

                            gen_clrex(s);

                            break;

                        case 4: /* dsb */

                        case 5: /* dmb */

                        case 6: /* isb */

                            /* These execute as NOPs.  */

                            break;

                        default:

                            goto illegal_op;

                        }

                        break;

                    case 4: /* bxj */

                        /* Trivial implementation equivalent to bx.  */

                        tmp = load_reg(s, rn);

                        gen_bx(s, tmp);

                        break;

                    case 5: /* Exception return.  */

                        if (IS_USER(s)) {

                            goto illegal_op;

                        }

                        if (rn != 14 || rd != 15) {

                            goto illegal_op;

                        }

                        tmp = load_reg(s, rn);

                        tcg_gen_subi_i32(tmp, tmp, insn & 0xff);

                        gen_exception_return(s, tmp);

                        break;

                    case 6: /* mrs cpsr.  */

                        tmp = tcg_temp_new_i32();

                        if (arm_dc_feature(s, ARM_FEATURE_M)) {

                            addr = tcg_const_i32(insn & 0xff);

                            gen_helper_v7m_mrs(tmp, cpu_env, addr);

                            tcg_temp_free_i32(addr);

                        } else {

                            gen_helper_cpsr_read(tmp, cpu_env);

                        }

                        store_reg(s, rd, tmp);

                        break;

                    case 7: /* mrs spsr.  */

                        /* Not accessible in user mode.  */

                        if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {

                            goto illegal_op;

                        }

                        tmp = load_cpu_field(spsr);

                        store_reg(s, rd, tmp);

                        break;

                    }

                }

            } else {

                /* Conditional branch.  */

                op = (insn >> 22) & 0xf;

                /* Generate a conditional jump to next instruction.  */

                s->condlabel = gen_new_label();

                arm_gen_test_cc(op ^ 1, s->condlabel);

                s->condjmp = 1;

                /* offset[11:1] = insn[10:0] */

                offset = (insn & 0x7ff) << 1;

                /* offset[17:12] = insn[21:16].  */

                offset |= (insn & 0x003f0000) >> 4;

                /* offset[31:20] = insn[26].  */

                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;

                /* offset[18] = insn[13].  */

                offset |= (insn & (1 << 13)) << 5;

                /* offset[19] = insn[11].  */

                offset |= (insn & (1 << 11)) << 8;

                /* jump to the offset */

                gen_jmp(s, s->pc + offset);

            }

        } else {

            /* Data processing immediate.  */

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

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

                    if (insn & (1 << 20))

                        goto illegal_op;

                    /* Bitfield/Saturate.  */

                    op = (insn >> 21) & 7;

                    imm = insn & 0x1f;

                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);

                    if (rn == 15) {

                        tmp = tcg_temp_new_i32();

                        tcg_gen_movi_i32(tmp, 0);

                    } else {

                        tmp = load_reg(s, rn);

                    }

                    switch (op) {

                    case 2: /* Signed bitfield extract.  */

                        imm++;

                        if (shift + imm > 32)

                            goto illegal_op;

                        if (imm < 32)

                            gen_sbfx(tmp, shift, imm);

                        break;

                    case 6: /* Unsigned bitfield extract.  */

                        imm++;

                        if (shift + imm > 32)

                            goto illegal_op;

                        if (imm < 32)

                            gen_ubfx(tmp, shift, (1u << imm) - 1);

                        break;

                    case 3: /* Bitfield insert/clear.  */

                        if (imm < shift)

                            goto illegal_op;

                        imm = imm + 1 - shift;

                        if (imm != 32) {

                            tmp2 = load_reg(s, rd);

                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);

                            tcg_temp_free_i32(tmp2);

                        }

                        break;

                    case 7:

                        goto illegal_op;

                    default: /* Saturate.  */

                        if (shift) {

                            if (op & 1)

                                tcg_gen_sari_i32(tmp, tmp, shift);

                            else

                                tcg_gen_shli_i32(tmp, tmp, shift);

                        }

                        tmp2 = tcg_const_i32(imm);

                        if (op & 4) {

                            /* Unsigned.  */

                            if ((op & 1) && shift == 0) {

                                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {

                                    tcg_temp_free_i32(tmp);

                                    tcg_temp_free_i32(tmp2);

                                    goto illegal_op;

                                }

                                gen_helper_usat16(tmp, cpu_env, tmp, tmp2);

                            } else {

                                gen_helper_usat(tmp, cpu_env, tmp, tmp2);

                            }

                        } else {

                            /* Signed.  */

                            if ((op & 1) && shift == 0) {

                                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {

                                    tcg_temp_free_i32(tmp);

                                    tcg_temp_free_i32(tmp2);

                                    goto illegal_op;

                                }

                                gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);

                            } else {

                                gen_helper_ssat(tmp, cpu_env, tmp, tmp2);

                            }

                        }

                        tcg_temp_free_i32(tmp2);

                        break;

                    }

                    store_reg(s, rd, tmp);

                } else {

                    imm = ((insn & 0x04000000) >> 15)

                          | ((insn & 0x7000) >> 4) | (insn & 0xff);

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

                        /* 16-bit immediate.  */

                        imm |= (insn >> 4) & 0xf000;

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

                            /* movt */

                            tmp = load_reg(s, rd);

                            tcg_gen_ext16u_i32(tmp, tmp);

                            tcg_gen_ori_i32(tmp, tmp, imm << 16);

                        } else {

                            /* movw */

                            tmp = tcg_temp_new_i32();

                            tcg_gen_movi_i32(tmp, imm);

                        }

                    } else {

                        /* Add/sub 12-bit immediate.  */

                        if (rn == 15) {

                            offset = s->pc & ~(uint32_t)3;

                            if (insn & (1 << 23))

                                offset -= imm;

                            else

                                offset += imm;

                            tmp = tcg_temp_new_i32();

                            tcg_gen_movi_i32(tmp, offset);

                        } else {

                            tmp = load_reg(s, rn);

                            if (insn & (1 << 23))

                                tcg_gen_subi_i32(tmp, tmp, imm);

                            else

                                tcg_gen_addi_i32(tmp, tmp, imm);

                        }

                    }

                    store_reg(s, rd, tmp);

                }

            } else {

                int shifter_out = 0;

                /* modified 12-bit immediate.  */

                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);

                imm = (insn & 0xff);

                switch (shift) {

                case 0: /* XY */

                    /* Nothing to do.  */

                    break;

                case 1: /* 00XY00XY */

                    imm |= imm << 16;

                    break;

                case 2: /* XY00XY00 */

                    imm |= imm << 16;

                    imm <<= 8;

                    break;

                case 3: /* XYXYXYXY */

                    imm |= imm << 16;

                    imm |= imm << 8;

                    break;

                default: /* Rotated constant.  */

                    shift = (shift << 1) | (imm >> 7);

                    imm |= 0x80;

                    imm = imm << (32 - shift);

                    shifter_out = 1;

                    break;

                }

                tmp2 = tcg_temp_new_i32();

                tcg_gen_movi_i32(tmp2, imm);

                rn = (insn >> 16) & 0xf;

                if (rn == 15) {

                    tmp = tcg_temp_new_i32();

                    tcg_gen_movi_i32(tmp, 0);

                } else {

                    tmp = load_reg(s, rn);

                }

                op = (insn >> 21) & 0xf;

                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,

                                       shifter_out, tmp, tmp2))

                    goto illegal_op;

                tcg_temp_free_i32(tmp2);

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

                if (rd != 15) {

                    store_reg(s, rd, tmp);

                } else {

                    tcg_temp_free_i32(tmp);

                }

            }

        }

        break;

    case 12: /* Load/store single data item.  */

        {

        int postinc = 0;

        int writeback = 0;

        int memidx;

        if ((insn & 0x01100000) == 0x01000000) {

            if (disas_neon_ls_insn(s, insn)) {

                goto illegal_op;

            }

            break;

        }

        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);

        if (rs == 15) {

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

                goto illegal_op;

            }

            if (op != 2) {

                /* Byte or halfword load space with dest == r15 : memory hints.

                 * Catch them early so we don't emit pointless addressing code.

                 * This space is a mix of:

                 *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike

                 *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP

                 *     cores)

                 *  unallocated hints, which must be treated as NOPs

                 *  UNPREDICTABLE space, which we NOP or UNDEF depending on

                 *     which is easiest for the decoding logic

                 *  Some space which must UNDEF

                 */

                int op1 = (insn >> 23) & 3;

                int op2 = (insn >> 6) & 0x3f;

                if (op & 2) {

                    goto illegal_op;

                }

                if (rn == 15) {

                    /* UNPREDICTABLE, unallocated hint or

                     * PLD/PLDW/PLI (literal)

                     */

                    return 0;

                }

                if (op1 & 1) {

                    return 0; /* PLD/PLDW/PLI or unallocated hint */

                }

                if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {

                    return 0; /* PLD/PLDW/PLI or unallocated hint */

                }

                /* UNDEF space, or an UNPREDICTABLE */

                return 1;

            }

        }

        memidx = get_mem_index(s);

        if (rn == 15) {

            addr = tcg_temp_new_i32();

            /* PC relative.  */

            /* s->pc has already been incremented by 4.  */

            imm = s->pc & 0xfffffffc;

            if (insn & (1 << 23))

                imm += insn & 0xfff;

            else

                imm -= insn & 0xfff;

            tcg_gen_movi_i32(addr, imm);

        } else {

            addr = load_reg(s, rn);

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

                /* Positive offset.  */

                imm = insn & 0xfff;

                tcg_gen_addi_i32(addr, addr, imm);

            } else {

                imm = insn & 0xff;

                switch ((insn >> 8) & 0xf) {

                case 0x0: /* Shifted Register.  */

                    shift = (insn >> 4) & 0xf;

                    if (shift > 3) {

                        tcg_temp_free_i32(addr);

                        goto illegal_op;

                    }

                    tmp = load_reg(s, rm);

                    if (shift)

                        tcg_gen_shli_i32(tmp, tmp, shift);

                    tcg_gen_add_i32(addr, addr, tmp);

                    tcg_temp_free_i32(tmp);

                    break;

                case 0xc: /* Negative offset.  */

                    tcg_gen_addi_i32(addr, addr, -imm);

                    break;

                case 0xe: /* User privilege.  */

                    tcg_gen_addi_i32(addr, addr, imm);

                    memidx = get_a32_user_mem_index(s);

                    break;

                case 0x9: /* Post-decrement.  */

                    imm = -imm;

                    /* Fall through.  */

                case 0xb: /* Post-increment.  */

                    postinc = 1;

                    writeback = 1;

                    break;

                case 0xd: /* Pre-decrement.  */

                    imm = -imm;

                    /* Fall through.  */

                case 0xf: /* Pre-increment.  */

                    tcg_gen_addi_i32(addr, addr, imm);

                    writeback = 1;

                    break;

                default:

                    tcg_temp_free_i32(addr);

                    goto illegal_op;

                }

            }

        }

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

            /* Load.  */

            tmp = tcg_temp_new_i32();

            switch (op) {

            case 0:

                gen_aa32_ld8u(tmp, addr, memidx);

                break;

            case 4:

                gen_aa32_ld8s(tmp, addr, memidx);

                break;

            case 1:

                gen_aa32_ld16u(tmp, addr, memidx);

                break;

            case 5:

                gen_aa32_ld16s(tmp, addr, memidx);

                break;

            case 2:

                gen_aa32_ld32u(tmp, addr, memidx);

                break;

            default:

                tcg_temp_free_i32(tmp);

                tcg_temp_free_i32(addr);

                goto illegal_op;

            }

            if (rs == 15) {

                gen_bx(s, tmp);

            } else {

                store_reg(s, rs, tmp);

            }

        } else {

            /* Store.  */

            tmp = load_reg(s, rs);

            switch (op) {

            case 0:

                gen_aa32_st8(tmp, addr, memidx);

                break;

            case 1:

                gen_aa32_st16(tmp, addr, memidx);

                break;

            case 2:

                gen_aa32_st32(tmp, addr, memidx);

                break;

            default:

                tcg_temp_free_i32(tmp);

                tcg_temp_free_i32(addr);

                goto illegal_op;

            }

            tcg_temp_free_i32(tmp);

        }

        if (postinc)

            tcg_gen_addi_i32(addr, addr, imm);

        if (writeback) {

            store_reg(s, rn, addr);

        } else {

            tcg_temp_free_i32(addr);

        }

        }

        break;

    default:

        goto illegal_op;

    }

    return 0;

illegal_op:

    return 1;

}


static QIOChannelSocket *nbd_establish_connection(SocketAddress *saddr_flat,

                                                  Error **errp)

{

    SocketAddressLegacy *saddr = socket_address_crumple(saddr_flat);

    QIOChannelSocket *sioc;

    Error *local_err = NULL;

    sioc = qio_channel_socket_new();

    qio_channel_set_name(QIO_CHANNEL(sioc), "nbd-client");

    qio_channel_socket_connect_sync(sioc,

                                    saddr,

                                    &local_err);

    qapi_free_SocketAddressLegacy(saddr);

    if (local_err) {

        object_unref(OBJECT(sioc));

        error_propagate(errp, local_err);

        return NULL;

    }

    qio_channel_set_delay(QIO_CHANNEL(sioc), false);

    return sioc;

}


void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,

                            int shift, int next_eip_addend)

{

    int new_stack, i;

    uint32_t e1, e2, cpl, dpl, rpl, selector, offset, param_count;

    uint32_t ss = 0, ss_e1 = 0, ss_e2 = 0, sp, type, ss_dpl, sp_mask;

    uint32_t val, limit, old_sp_mask;

    target_ulong ssp, old_ssp, next_eip;

    next_eip = env->eip + next_eip_addend;

    LOG_PCALL("lcall %04x:%08x s=%d\n", new_cs, (uint32_t)new_eip, shift);

    LOG_PCALL_STATE(CPU(x86_env_get_cpu(env)));

    if ((new_cs & 0xfffc) == 0) {

        raise_exception_err(env, EXCP0D_GPF, 0);

    }

    if (load_segment(env, &e1, &e2, new_cs) != 0) {

        raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);

    }

    cpl = env->hflags & HF_CPL_MASK;

    LOG_PCALL("desc=%08x:%08x\n", e1, e2);

    if (e2 & DESC_S_MASK) {

        if (!(e2 & DESC_CS_MASK)) {

            raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);

        }

        dpl = (e2 >> DESC_DPL_SHIFT) & 3;

        if (e2 & DESC_C_MASK) {

            /* conforming code segment */

            if (dpl > cpl) {

                raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);

            }

        } else {

            /* non conforming code segment */

            rpl = new_cs & 3;

            if (rpl > cpl) {

                raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);

            }

            if (dpl != cpl) {

                raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);

            }

        }

        if (!(e2 & DESC_P_MASK)) {

            raise_exception_err(env, EXCP0B_NOSEG, new_cs & 0xfffc);

        }

#ifdef TARGET_X86_64

        /* XXX: check 16/32 bit cases in long mode */

        if (shift == 2) {

            target_ulong rsp;

            /* 64 bit case */

            rsp = env->regs[R_ESP];

            PUSHQ(rsp, env->segs[R_CS].selector);

            PUSHQ(rsp, next_eip);

            /* from this point, not restartable */

            env->regs[R_ESP] = rsp;

            cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,

                                   get_seg_base(e1, e2),

                                   get_seg_limit(e1, e2), e2);

            env->eip = new_eip;

        } else

#endif

        {

            sp = env->regs[R_ESP];

            sp_mask = get_sp_mask(env->segs[R_SS].flags);

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

            if (shift) {

                PUSHL(ssp, sp, sp_mask, env->segs[R_CS].selector);

                PUSHL(ssp, sp, sp_mask, next_eip);

            } else {

                PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector);

                PUSHW(ssp, sp, sp_mask, next_eip);

            }

            limit = get_seg_limit(e1, e2);

            if (new_eip > limit) {

                raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);

            }

            /* from this point, not restartable */

            SET_ESP(sp, sp_mask);

            cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl,

                                   get_seg_base(e1, e2), limit, e2);

            env->eip = new_eip;

        }

    } else {

        /* check gate type */

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

        dpl = (e2 >> DESC_DPL_SHIFT) & 3;

        rpl = new_cs & 3;

        switch (type) {

        case 1: /* available 286 TSS */

        case 9: /* available 386 TSS */

        case 5: /* task gate */

            if (dpl < cpl || dpl < rpl) {

                raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);

            }

            switch_tss(env, new_cs, e1, e2, SWITCH_TSS_CALL, next_eip);

            CC_OP = CC_OP_EFLAGS;

            return;

        case 4: /* 286 call gate */

        case 12: /* 386 call gate */

            break;

        default:

            raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);

            break;

        }

        shift = type >> 3;

        if (dpl < cpl || dpl < rpl) {

            raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);

        }

        /* check valid bit */

        if (!(e2 & DESC_P_MASK)) {

            raise_exception_err(env, EXCP0B_NOSEG,  new_cs & 0xfffc);

        }

        selector = e1 >> 16;

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

        param_count = e2 & 0x1f;

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

            raise_exception_err(env, EXCP0D_GPF, 0);

        }

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

            raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

        }

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

            raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

        }

        dpl = (e2 >> DESC_DPL_SHIFT) & 3;

        if (dpl > cpl) {

            raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);

        }

        if (!(e2 & DESC_P_MASK)) {

            raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);

        }

        if (!(e2 & DESC_C_MASK) && dpl < cpl) {

            /* to inner privilege */

            get_ss_esp_from_tss(env, &ss, &sp, dpl);

            LOG_PCALL("new ss:esp=%04x:%08x param_count=%d env->regs[R_ESP]="

                      TARGET_FMT_lx "\n", ss, sp, param_count,

                      env->regs[R_ESP]);

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

                raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

            }

            if ((ss & 3) != dpl) {

                raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

            }

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

                raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

            }

            ss_dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3;

            if (ss_dpl != dpl) {

                raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

            }

            if (!(ss_e2 & DESC_S_MASK) ||

                (ss_e2 & DESC_CS_MASK) ||

                !(ss_e2 & DESC_W_MASK)) {

                raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

            }

            if (!(ss_e2 & DESC_P_MASK)) {

                raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc);

            }

            /* push_size = ((param_count * 2) + 8) << shift; */

            old_sp_mask = get_sp_mask(env->segs[R_SS].flags);

            old_ssp = env->segs[R_SS].base;

            sp_mask = get_sp_mask(ss_e2);

            ssp = get_seg_base(ss_e1, ss_e2);

            if (shift) {

                PUSHL(ssp, sp, sp_mask, env->segs[R_SS].selector);

                PUSHL(ssp, sp, sp_mask, env->regs[R_ESP]);

                for (i = param_count - 1; i >= 0; i--) {

                    val = cpu_ldl_kernel(env, old_ssp +

                                         ((env->regs[R_ESP] + i * 4) &

                                          old_sp_mask));

                    PUSHL(ssp, sp, sp_mask, val);

                }

            } else {

                PUSHW(ssp, sp, sp_mask, env->segs[R_SS].selector);

                PUSHW(ssp, sp, sp_mask, env->regs[R_ESP]);

                for (i = param_count - 1; i >= 0; i--) {

                    val = cpu_lduw_kernel(env, old_ssp +

                                          ((env->regs[R_ESP] + i * 2) &

                                           old_sp_mask));

                    PUSHW(ssp, sp, sp_mask, val);

                }

            }

            new_stack = 1;

        } else {

            /* to same privilege */

            sp = env->regs[R_ESP];

            sp_mask = get_sp_mask(env->segs[R_SS].flags);

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

            /* push_size = (4 << shift); */

            new_stack = 0;

        }

        if (shift) {

            PUSHL(ssp, sp, sp_mask, env->segs[R_CS].selector);

            PUSHL(ssp, sp, sp_mask, next_eip);

        } else {

            PUSHW(ssp, sp, sp_mask, env->segs[R_CS].selector);

            PUSHW(ssp, sp, sp_mask, next_eip);

        }

        /* from this point, not restartable */

        if (new_stack) {

            ss = (ss & ~3) | dpl;

            cpu_x86_load_seg_cache(env, R_SS, ss,

                                   ssp,

                                   get_seg_limit(ss_e1, ss_e2),

                                   ss_e2);

        }

        selector = (selector & ~3) | dpl;

        cpu_x86_load_seg_cache(env, R_CS, selector,

                       get_seg_base(e1, e2),

                       get_seg_limit(e1, e2),

                       e2);

        cpu_x86_set_cpl(env, dpl);

        SET_ESP(sp, sp_mask);

        env->eip = offset;

    }

}


static void tile_codeblocks(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)

{

    Jpeg2000T1Context t1;

    int compno, reslevelno, bandno;

    /* Loop on tile components */

    for (compno = 0; compno < s->ncomponents; compno++) {

        Jpeg2000Component *comp     = tile->comp + compno;

        Jpeg2000CodingStyle *codsty = tile->codsty + compno;

        /* Loop on resolution levels */

        for (reslevelno = 0; reslevelno < codsty->nreslevels2decode; reslevelno++) {

            Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;

            /* Loop on bands */

            for (bandno = 0; bandno < rlevel->nbands; bandno++) {

                uint16_t nb_precincts, precno;

                Jpeg2000Band *band = rlevel->band + bandno;

                int cblkno = 0, bandpos;

                bandpos = bandno + (reslevelno > 0);

                if (band->coord[0][0] == band->coord[0][1] ||

                    band->coord[1][0] == band->coord[1][1])

                    continue;

                nb_precincts = rlevel->num_precincts_x * rlevel->num_precincts_y;

                /* Loop on precincts */

                for (precno = 0; precno < nb_precincts; precno++) {

                    Jpeg2000Prec *prec = band->prec + precno;

                    /* Loop on codeblocks */

                    for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) {

                        int x, y;

                        Jpeg2000Cblk *cblk = prec->cblk + cblkno;

                        decode_cblk(s, codsty, &t1, cblk,

                                    cblk->coord[0][1] - cblk->coord[0][0],

                                    cblk->coord[1][1] - cblk->coord[1][0],

                                    bandpos);

                        x = cblk->coord[0][0];

                        y = cblk->coord[1][0];

                        if (codsty->transform == FF_DWT97)

                            dequantization_float(x, y, cblk, comp, &t1, band);

                        else

                            dequantization_int(x, y, cblk, comp, &t1, band);

                   } /* end cblk */

                } /*end prec */

            } /* end band */

        } /* end reslevel */

        /* inverse DWT */

        ff_dwt_decode(&comp->dwt, codsty->transform == FF_DWT97 ? (void*)comp->f_data : (void*)comp->i_data);

    } /*end comp */

}


static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,

                                         const char *name, int devfn)

{

    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);

    PCIConfigReadFunc *config_read = pc->config_read;

    PCIConfigWriteFunc *config_write = pc->config_write;

    AddressSpace *dma_as;

    if (devfn < 0) {

        for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);

            devfn += PCI_FUNC_MAX) {

            if (!bus->devices[devfn])

                goto found;

        }

        error_report("PCI: no slot/function available for %s, all in use", name);

        return NULL;

    found: ;

    } else if (bus->devices[devfn]) {

        error_report("PCI: slot %d function %d not available for %s, in use by %s",

                     PCI_SLOT(devfn), PCI_FUNC(devfn), name, bus->devices[devfn]->name);

        return NULL;

    }

    pci_dev->bus = bus;

    dma_as = pci_device_iommu_address_space(pci_dev);

    memory_region_init_alias(&pci_dev->bus_master_enable_region,

                             OBJECT(pci_dev), "bus master",

                             dma_as->root, 0, memory_region_size(dma_as->root));

    memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);

    address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region,

                       name);

    pci_dev->devfn = devfn;

    pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);

    pci_dev->irq_state = 0;

    pci_config_alloc(pci_dev);

    pci_config_set_vendor_id(pci_dev->config, pc->vendor_id);

    pci_config_set_device_id(pci_dev->config, pc->device_id);

    pci_config_set_revision(pci_dev->config, pc->revision);

    pci_config_set_class(pci_dev->config, pc->class_id);

    if (!pc->is_bridge) {

        if (pc->subsystem_vendor_id || pc->subsystem_id) {

            pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,

                         pc->subsystem_vendor_id);

            pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,

                         pc->subsystem_id);

        } else {

            pci_set_default_subsystem_id(pci_dev);

        }

    } else {

        /* subsystem_vendor_id/subsystem_id are only for header type 0 */

        assert(!pc->subsystem_vendor_id);

        assert(!pc->subsystem_id);

    }

    pci_init_cmask(pci_dev);

    pci_init_wmask(pci_dev);

    pci_init_w1cmask(pci_dev);

    if (pc->is_bridge) {

        pci_init_mask_bridge(pci_dev);

    }

    if (pci_init_multifunction(bus, pci_dev)) {

        pci_config_free(pci_dev);

        return NULL;

    }

    if (!config_read)

        config_read = pci_default_read_config;

    if (!config_write)

        config_write = pci_default_write_config;

    pci_dev->config_read = config_read;

    pci_dev->config_write = config_write;

    bus->devices[devfn] = pci_dev;

    pci_dev->irq = qemu_allocate_irqs(pci_irq_handler, pci_dev, PCI_NUM_PINS);

    pci_dev->version_id = 2; /* Current pci device vmstate version */

    return pci_dev;

}


static int bdrv_inherited_flags(int flags)

{

    /* Enable protocol handling, disable format probing for bs->file */

    flags |= BDRV_O_PROTOCOL;

    /* Our block drivers take care to send flushes and respect unmap policy,

     * so we can enable both unconditionally on lower layers. */

    flags |= BDRV_O_CACHE_WB | BDRV_O_UNMAP;

    /* The backing file of a temporary snapshot is read-only */

    if (flags & BDRV_O_SNAPSHOT) {

        flags &= ~BDRV_O_RDWR;

    }

    /* Clear flags that only apply to the top layer */

    flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);

    return flags;

}


static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,

                                int cc, int tf)

{

    int cond;

    TCGv_i32 t0 = tcg_temp_new_i32();

    int l1 = gen_new_label();

    int l2 = gen_new_label();

    if (tf)

        cond = TCG_COND_EQ;

    else

        cond = TCG_COND_NE;

    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));

    tcg_gen_brcondi_i32(cond, t0, 0, l1);

    gen_load_fpr32(t0, fs);

    gen_store_fpr32(t0, fd);

    gen_set_label(l1);

    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));

    tcg_gen_brcondi_i32(cond, t0, 0, l2);

    gen_load_fpr32h(ctx, t0, fs);

    gen_store_fpr32h(ctx, t0, fd);

    tcg_temp_free_i32(t0);

    gen_set_label(l2);

}


QEMUFile *qemu_fopen(const char *filename, const char *mode)

{

    QEMUFile *f;

    f = qemu_mallocz(sizeof(QEMUFile));

    if (!f)

        return NULL;

    if (!strcmp(mode, "wb")) {

        f->is_writable = 1;

    } else if (!strcmp(mode, "rb")) {

        f->is_writable = 0;

    } else {

        goto fail;

    }

    f->outfile = fopen(filename, mode);

    if (!f->outfile)

        goto fail;

    f->is_file = 1;

    return f;

 fail:

    if (f->outfile)

        fclose(f->outfile);

    qemu_free(f);

    return NULL;

}


void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr,

                                  int is_write, int is_user, uintptr_t retaddr)

{

    MIPSCPU *cpu = MIPS_CPU(cs);

    CPUMIPSState *env = &cpu->env;

    env->CP0_BadVAddr = addr;

    do_raise_exception(env, (is_write == 1) ? EXCP_AdES : EXCP_AdEL, retaddr);

}


void block_job_cancel(BlockJob *job)

{

    job->cancelled = true;

    block_job_resume(job);

}


PCIBus *pci_pmac_init(qemu_irq *pic,

                      MemoryRegion *address_space_mem,

                      MemoryRegion *address_space_io)

{

    DeviceState *dev;

    SysBusDevice *s;

    PCIHostState *h;

    UNINState *d;

    /* Use values found on a real PowerMac */

    /* Uninorth main bus */

    dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE);

    qdev_init_nofail(dev);

    s = SYS_BUS_DEVICE(dev);

    h = PCI_HOST_BRIDGE(s);

    d = UNI_NORTH_PCI_HOST_BRIDGE(dev);

    memory_region_init(&d->pci_mmio, OBJECT(d), "pci-mmio", 0x100000000ULL);

    memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio,

                             0x80000000ULL, 0x70000000ULL);

    memory_region_add_subregion(address_space_mem, 0x80000000ULL,

                                &d->pci_hole);

    h->bus = pci_register_bus(dev, "pci",

                              pci_unin_set_irq, pci_unin_map_irq,

                              pic,

                              &d->pci_mmio,

                              address_space_io,

                              PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);

#if 0

    pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north");

#endif

    sysbus_mmio_map(s, 0, 0xf2800000);

    sysbus_mmio_map(s, 1, 0xf2c00000);

    /* DEC 21154 bridge */

#if 0

    /* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */

    pci_create_simple(h->bus, PCI_DEVFN(12, 0), "dec-21154");

#endif

    /* Uninorth AGP bus */

    pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp");

    dev = qdev_create(NULL, TYPE_UNI_NORTH_AGP_HOST_BRIDGE);

    qdev_init_nofail(dev);

    s = SYS_BUS_DEVICE(dev);

    sysbus_mmio_map(s, 0, 0xf0800000);

    sysbus_mmio_map(s, 1, 0xf0c00000);

    /* Uninorth internal bus */

#if 0

    /* XXX: not needed for now */

    pci_create_simple(h->bus, PCI_DEVFN(14, 0),

                      "uni-north-internal-pci");

    dev = qdev_create(NULL, TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE);

    qdev_init_nofail(dev);

    s = SYS_BUS_DEVICE(dev);

    sysbus_mmio_map(s, 0, 0xf4800000);

    sysbus_mmio_map(s, 1, 0xf4c00000);

#endif

    return h->bus;

}


static inline void downmix_3f_2r_to_dolby(float *samples)

{

    int i;

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

        samples[i] += (samples[i + 256] - samples[i + 768]);

        samples[i + 256] = (samples[i + 512] + samples[i + 1024]);

        samples[i + 512] = samples[i + 768] = samples[i + 1024] = 0;

    }

}


int qemu_paio_ioctl(struct qemu_paiocb *aiocb)

{

    return qemu_paio_submit(aiocb, QEMU_PAIO_IOCTL);

}


int rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, char *value, int value_size)

{

    skip_spaces(p);

    if(**p) {

        get_word_sep(attr, attr_size, "=", p);

        if (**p == '=')

            (*p)++;

        get_word_sep(value, value_size, ";", p);

        if (**p == ';')

            (*p)++;

        return 1;

    }

    return 0;

}


int av_opencl_init(AVDictionary *options, AVOpenCLExternalEnv *ext_opencl_env)

{

    int ret = 0;

    AVDictionaryEntry *opt_build_entry;

    AVDictionaryEntry *opt_platform_entry;

    AVDictionaryEntry *opt_device_entry;

    LOCK_OPENCL

    if (!gpu_env.init_count) {

        opt_platform_entry = av_dict_get(options, "platform_idx", NULL, 0);

        opt_device_entry   = av_dict_get(options, "device_idx", NULL, 0);

        /*initialize devices, context, command_queue*/

        gpu_env.usr_spec_dev_info.platform_idx = -1;

        gpu_env.usr_spec_dev_info.dev_idx = -1;

        if (opt_platform_entry) {

            gpu_env.usr_spec_dev_info.platform_idx = strtol(opt_platform_entry->value, NULL, 10);

        }

        if (opt_device_entry) {

            gpu_env.usr_spec_dev_info.dev_idx = strtol(opt_device_entry->value, NULL, 10);

        }

        ret = init_opencl_env(&gpu_env, ext_opencl_env);

        if (ret < 0)

            goto end;

    }

    /*initialize program, kernel_name, kernel_count*/

    opt_build_entry = av_dict_get(options, "build_options", NULL, 0);

    if (opt_build_entry)

        ret = compile_kernel_file(&gpu_env, opt_build_entry->value);

    else

        ret = compile_kernel_file(&gpu_env, NULL);

    if (ret < 0)

        goto end;

    av_assert1(gpu_env.kernel_code_count > 0);

    gpu_env.init_count++;

end:

    UNLOCK_OPENCL

    return ret;

}


static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth,

                                 unsigned size)

{

    unsigned i, j;

    CodeBook cb = { 0 };

    if (!can_safely_read(gb, (uint64_t)size * 34))

        return cb;

    if (size >= INT_MAX / sizeof(MacroBlock))

        return cb;

    cb.blocks = av_malloc(size ? size * sizeof(MacroBlock) : 1);

    if (!cb.blocks)

        return cb;

    cb.depth = depth;

    cb.size = size;

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

        unsigned mask_bits = get_bits(gb, 4);

        unsigned color0 = get_bits(gb, 15);

        unsigned color1 = get_bits(gb, 15);

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

            if (mask_bits & (1 << j))

                cb.blocks[i].pixels[j] = color1;

            else

                cb.blocks[i].pixels[j] = color0;

        }

    }

    return cb;

}


static void hybrid4_8_12_cx(float (*in)[2], float (*out)[32][2], const float (*filter)[7][2], int N, int len)

{

    int i, j, ssb;

    for (i = 0; i < len; i++, in++) {

        for (ssb = 0; ssb < N; ssb++) {

            float sum_re = filter[ssb][6][0] * in[6][0], sum_im = filter[ssb][6][0] * in[6][1];

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

                float in0_re = in[j][0];

                float in0_im = in[j][1];

                float in1_re = in[12-j][0];

                float in1_im = in[12-j][1];

                sum_re += filter[ssb][j][0] * (in0_re + in1_re) - filter[ssb][j][1] * (in0_im - in1_im);

                sum_im += filter[ssb][j][0] * (in0_im + in1_im) + filter[ssb][j][1] * (in0_re - in1_re);

            }

            out[ssb][i][0] = sum_re;

            out[ssb][i][1] = sum_im;

        }

    }

}


static int add_metadata(const uint8_t **buf, int count, int type,

                        const char *name, const char *sep, TiffContext *s)

{

    switch(type) {

    case TIFF_DOUBLE: return add_doubles_metadata(buf, count, name, sep, s);

    case TIFF_SHORT : return add_shorts_metadata(buf, count, name, sep, s);

    default         : return AVERROR_INVALIDDATA;

    };

}


static int opt_recording_timestamp(void *optctx, const char *opt, const char *arg)

{

    OptionsContext *o = optctx;

    char buf[128];

    int64_t recording_timestamp = parse_time_or_die(opt, arg, 0) / 1E6;

    struct tm time = *gmtime((time_t*)&recording_timestamp);

    strftime(buf, sizeof(buf), "creation_time=%FT%T%z", &time);

    parse_option(o, "metadata", buf, options);

    av_log(NULL, AV_LOG_WARNING, "%s is deprecated, set the 'creation_time' metadata "

                                 "tag instead.\n", opt);

    return 0;

}


static void tcp_chr_tls_init(CharDriverState *chr)

{

    TCPCharDriver *s = chr->opaque;

    QIOChannelTLS *tioc;

    Error *err = NULL;

    if (s->is_listen) {

        tioc = qio_channel_tls_new_server(

            s->ioc, s->tls_creds,

            NULL, /* XXX Use an ACL */

            &err);

    } else {

        tioc = qio_channel_tls_new_client(

            s->ioc, s->tls_creds,

            s->addr->u.inet.data->host,

            &err);

    }

    if (tioc == NULL) {

        error_free(err);

        tcp_chr_disconnect(chr);

    }

    object_unref(OBJECT(s->ioc));

    s->ioc = QIO_CHANNEL(tioc);

    qio_channel_tls_handshake(tioc,

                              tcp_chr_tls_handshake,

                              chr,

                              NULL);

}


rdt_free_extradata (PayloadContext *rdt)

{

    ff_rm_free_rmstream(rdt->rmst[0]);

    if (rdt->rmctx)

        av_close_input_stream(rdt->rmctx);

    av_freep(&rdt->mlti_data);

    av_free(rdt);

}


static int h263_decode_gob_header(MpegEncContext *s)

{

    unsigned int val, gob_number;

    int left;

    /* Check for GOB Start Code */

    val = show_bits(&s->gb, 16);

    if(val)

        return -1;

        /* We have a GBSC probably with GSTUFF */

    skip_bits(&s->gb, 16); /* Drop the zeros */

    left= get_bits_left(&s->gb);

    //MN: we must check the bits left or we might end in an infinite loop (or segfault)

    for(;left>13; left--){

        if(get_bits1(&s->gb)) break; /* Seek the '1' bit */

    }

    if(left<=13)

        return -1;

    if(s->h263_slice_structured){

        if(check_marker(s->avctx, &s->gb, "before MBA")==0)

            return -1;

        ff_h263_decode_mba(s);

        if(s->mb_num > 1583)

            if(check_marker(s->avctx, &s->gb, "after MBA")==0)

                return -1;

        s->qscale = get_bits(&s->gb, 5); /* SQUANT */

        if(check_marker(s->avctx, &s->gb, "after SQUANT")==0)

            return -1;

        skip_bits(&s->gb, 2); /* GFID */

    }else{

        gob_number = get_bits(&s->gb, 5); /* GN */

        s->mb_x= 0;

        s->mb_y= s->gob_index* gob_number;

        skip_bits(&s->gb, 2); /* GFID */

        s->qscale = get_bits(&s->gb, 5); /* GQUANT */

    }

    if(s->mb_y >= s->mb_height)

        return -1;

    if(s->qscale==0)

        return -1;

    return 0;

}


static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)

{

    int err;

    uint32_t type;

#ifdef DEBUG

    print_atom("wide", atom);

    debug_indent++;

#endif

    if (atom.size < 8)

        return 0; /* continue */

    if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */

        url_fskip(pb, atom.size - 4);

        return 0;

    }

    atom.type = get_le32(pb);

    atom.offset += 8;

    atom.size -= 8;

    if (type != MKTAG('m', 'd', 'a', 't')) {

        url_fskip(pb, atom.size);

        return 0;

    }

    err = mov_read_mdat(c, pb, atom);

#ifdef DEBUG

    debug_indent--;

#endif

    return err;

}


static void net_socket_send(void *opaque)

{

    NetSocketState *s = opaque;

    int l, size, err;

    uint8_t buf1[4096];

    const uint8_t *buf;

    size = recv(s->fd, buf1, sizeof(buf1), 0);

    if (size < 0) {

        err = socket_error();

        if (err != EWOULDBLOCK)

            goto eoc;

    } else if (size == 0) {

        /* end of connection */

    eoc:

        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);

        closesocket(s->fd);

        return;

    }

    buf = buf1;

    while (size > 0) {

        /* reassemble a packet from the network */

        switch(s->state) {

        case 0:

            l = 4 - s->index;

            if (l > size)

                l = size;

            memcpy(s->buf + s->index, buf, l);

            buf += l;

            size -= l;

            s->index += l;

            if (s->index == 4) {

                /* got length */

                s->packet_len = ntohl(*(uint32_t *)s->buf);

                s->index = 0;

                s->state = 1;

            }

            break;

        case 1:

            l = s->packet_len - s->index;

            if (l > size)

                l = size;

            memcpy(s->buf + s->index, buf, l);

            s->index += l;

            buf += l;

            size -= l;

            if (s->index >= s->packet_len) {

                qemu_send_packet(s->vc, s->buf, s->packet_len);

                s->index = 0;

                s->state = 0;

            }

            break;

        }

    }

}


static void stellaris_enet_write(void *opaque, hwaddr offset,

                                 uint64_t value, unsigned size)

{

    stellaris_enet_state *s = (stellaris_enet_state *)opaque;

    switch (offset) {

    case 0x00: /* IACK */

        s->ris &= ~value;

        DPRINTF("IRQ ack %02x/%02x\n", value, s->ris);

        stellaris_enet_update(s);

        /* Clearing TXER also resets the TX fifo.  */

        if (value & SE_INT_TXER)

            s->tx_frame_len = -1;

        break;

    case 0x04: /* IM */

        DPRINTF("IRQ mask %02x/%02x\n", value, s->ris);

        s->im = value;

        stellaris_enet_update(s);

        break;

    case 0x08: /* RCTL */

        s->rctl = value;

        if (value & SE_RCTL_RSTFIFO) {

            s->rx_fifo_len = 0;

            s->np = 0;

            stellaris_enet_update(s);

        }

        break;

    case 0x0c: /* TCTL */

        s->tctl = value;

        break;

    case 0x10: /* DATA */

        if (s->tx_frame_len == -1) {

            s->tx_frame_len = value & 0xffff;

            if (s->tx_frame_len > 2032) {

                DPRINTF("TX frame too long (%d)\n", s->tx_frame_len);

                s->tx_frame_len = 0;

                s->ris |= SE_INT_TXER;

                stellaris_enet_update(s);

            } else {

                DPRINTF("Start TX frame len=%d\n", s->tx_frame_len);

                /* The value written does not include the ethernet header.  */

                s->tx_frame_len += 14;

                if ((s->tctl & SE_TCTL_CRC) == 0)

                    s->tx_frame_len += 4;

                s->tx_fifo_len = 0;

                s->tx_fifo[s->tx_fifo_len++] = value >> 16;

                s->tx_fifo[s->tx_fifo_len++] = value >> 24;

            }

        } else {

            s->tx_fifo[s->tx_fifo_len++] = value;

            s->tx_fifo[s->tx_fifo_len++] = value >> 8;

            s->tx_fifo[s->tx_fifo_len++] = value >> 16;

            s->tx_fifo[s->tx_fifo_len++] = value >> 24;

            if (s->tx_fifo_len >= s->tx_frame_len) {

                /* We don't implement explicit CRC, so just chop it off.  */

                if ((s->tctl & SE_TCTL_CRC) == 0)

                    s->tx_frame_len -= 4;

                if ((s->tctl & SE_TCTL_PADEN) && s->tx_frame_len < 60) {

                    memset(&s->tx_fifo[s->tx_frame_len], 0, 60 - s->tx_frame_len);

                    s->tx_fifo_len = 60;

                }

                qemu_send_packet(qemu_get_queue(s->nic), s->tx_fifo,

                                 s->tx_frame_len);

                s->tx_frame_len = -1;

                s->ris |= SE_INT_TXEMP;

                stellaris_enet_update(s);

                DPRINTF("Done TX\n");

            }

        }

        break;

    case 0x14: /* IA0 */

        s->conf.macaddr.a[0] = value;

        s->conf.macaddr.a[1] = value >> 8;

        s->conf.macaddr.a[2] = value >> 16;

        s->conf.macaddr.a[3] = value >> 24;

        break;

    case 0x18: /* IA1 */

        s->conf.macaddr.a[4] = value;

        s->conf.macaddr.a[5] = value >> 8;

        break;

    case 0x1c: /* THR */

        s->thr = value;

        break;

    case 0x20: /* MCTL */

        s->mctl = value;

        break;

    case 0x24: /* MDV */

        s->mdv = value;

        break;

    case 0x28: /* MADD */

        /* ignored.  */

        break;

    case 0x2c: /* MTXD */

        s->mtxd = value & 0xff;

        break;

    case 0x30: /* MRXD */

    case 0x34: /* NP */

    case 0x38: /* TR */

        /* Ignored.  */

    case 0x3c: /* Undocuented: Timestamp? */

        /* Ignored.  */

        break;

    default:

        hw_error("stellaris_enet_write: Bad offset %x\n", (int)offset);

    }

}


void *av_malloc(unsigned int size)

{

    void *ptr;

#if defined (HAVE_MEMALIGN)

    ptr = memalign(16,size);

    /* Why 64?

       Indeed, we should align it:

         on 4 for 386

         on 16 for 486

	 on 32 for 586, PPro - k6-III

	 on 64 for K7 (maybe for P3 too).

       Because L1 and L2 caches are aligned on those values.

       But I don't want to code such logic here!

     */

     /* Why 16?

        because some cpus need alignment, for example SSE2 on P4, & most RISC cpus

        it will just trigger an exception and the unaligned load will be done in the

        exception handler or it will just segfault (SSE2 on P4)

        Why not larger? because i didnt see a difference in benchmarks ...

     */

     /* benchmarks with p3

        memalign(64)+1		3071,3051,3032

        memalign(64)+2		3051,3032,3041

        memalign(64)+4		2911,2896,2915

        memalign(64)+8		2545,2554,2550

        memalign(64)+16		2543,2572,2563

        memalign(64)+32		2546,2545,2571

        memalign(64)+64		2570,2533,2558

        btw, malloc seems to do 8 byte alignment by default here

     */

#else

    ptr = malloc(size);

#endif

    return ptr;

}


static int posix_aio_process_queue(void *opaque)

{

    PosixAioState *s = opaque;

    struct qemu_paiocb *acb, **pacb;

    int ret;

    int result = 0;

    for(;;) {

        pacb = &s->first_aio;

        for(;;) {

            acb = *pacb;

            if (!acb)

                return result;

            ret = qemu_paio_error(acb);

            if (ret == ECANCELED) {

                /* remove the request */

                *pacb = acb->next;

                qemu_aio_release(acb);

                result = 1;

            } else if (ret != EINPROGRESS) {

                /* end of aio */

                if (ret == 0) {

                    ret = qemu_paio_return(acb);

                    if (ret == acb->aio_nbytes)

                        ret = 0;

                    else

                        ret = -EINVAL;

                } else {

                    ret = -ret;

                }

                trace_paio_complete(acb, acb->common.opaque, ret);

                /* remove the request */

                *pacb = acb->next;

                /* call the callback */

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

                qemu_aio_release(acb);

                result = 1;

                break;

            } else {

                pacb = &acb->next;

            }

        }

    }

    return result;

}


static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)

{

    /* We only advertise 1 auth scheme at a time, so client

     * must pick the one we sent. Verify this */

    if (data[0] != vs->auth) { /* Reject auth */

       VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);

       vnc_write_u32(vs, 1);

       if (vs->minor >= 8) {

           static const char err[] = "Authentication failed";

           vnc_write_u32(vs, sizeof(err));

           vnc_write(vs, err, sizeof(err));

       }

       vnc_client_error(vs);

    } else { /* Accept requested auth */

       VNC_DEBUG("Client requested auth %d\n", (int)data[0]);

       switch (vs->auth) {

       case VNC_AUTH_NONE:

           VNC_DEBUG("Accept auth none\n");

           if (vs->minor >= 8) {

               vnc_write_u32(vs, 0); /* Accept auth completion */

               vnc_flush(vs);

           }

           start_client_init(vs);

           break;

       case VNC_AUTH_VNC:

           VNC_DEBUG("Start VNC auth\n");

           start_auth_vnc(vs);

           break;

       case VNC_AUTH_VENCRYPT:

           VNC_DEBUG("Accept VeNCrypt auth\n");

           start_auth_vencrypt(vs);

           break;

#ifdef CONFIG_VNC_SASL

       case VNC_AUTH_SASL:

           VNC_DEBUG("Accept SASL auth\n");

           start_auth_sasl(vs);

           break;

#endif /* CONFIG_VNC_SASL */

       default: /* Should not be possible, but just in case */

           VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);

           vnc_write_u8(vs, 1);

           if (vs->minor >= 8) {

               static const char err[] = "Authentication failed";

               vnc_write_u32(vs, sizeof(err));

               vnc_write(vs, err, sizeof(err));

           }

           vnc_client_error(vs);

       }

    }

    return 0;

}