static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)

{

    int addr_reg, data_reg, data_reg2, r0, r1, rbase, mem_index, s_bits, bswap;

#ifdef CONFIG_SOFTMMU

    int r2;

    void *label1_ptr, *label2_ptr;

#endif

#if TARGET_LONG_BITS == 64

    int addr_reg2;

#endif

    data_reg = *args++;

    if (opc == 3)

        data_reg2 = *args++;

    else

        data_reg2 = 0;

    addr_reg = *args++;

#if TARGET_LONG_BITS == 64

    addr_reg2 = *args++;

#endif

    mem_index = *args;

    s_bits = opc & 3;

#ifdef CONFIG_SOFTMMU

    r0 = 3;

    r1 = 4;

    r2 = 0;

    rbase = 0;

    tcg_out32 (s, (RLWINM

                   | RA (r0)

                   | RS (addr_reg)

                   | SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))

                   | MB (32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS))

                   | ME (31 - CPU_TLB_ENTRY_BITS)

                   )

        );

    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));

    tcg_out32 (s, (LWZU

                   | RT (r1)

                   | RA (r0)

                   | offsetof (CPUState, tlb_table[mem_index][0].addr_read)

                   )

        );

    tcg_out32 (s, (RLWINM

                   | RA (r2)

                   | RS (addr_reg)

                   | SH (0)

                   | MB ((32 - s_bits) & 31)

                   | ME (31 - TARGET_PAGE_BITS)

                   )

        );

    tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1));

#if TARGET_LONG_BITS == 64

    tcg_out32 (s, LWZ | RT (r1) | RA (r0) | 4);

    tcg_out32 (s, CMP | BF (6) | RA (addr_reg2) | RB (r1));

    tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ));

#endif

    label1_ptr = s->code_ptr;

#ifdef FAST_PATH

    tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);

#endif

    /* slow path */

#if TARGET_LONG_BITS == 32

    tcg_out_mov (s, 3, addr_reg);

    tcg_out_movi (s, TCG_TYPE_I32, 4, mem_index);

#else

    tcg_out_mov (s, 3, addr_reg2);

    tcg_out_mov (s, 4, addr_reg);

    tcg_out_movi (s, TCG_TYPE_I32, 5, mem_index);

#endif

    tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);

    switch (opc) {

    case 0|4:

        tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));

        break;

    case 1|4:

        tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));

        break;

    case 0:

    case 1:

    case 2:

        if (data_reg != 3)

            tcg_out_mov (s, data_reg, 3);

        break;

    case 3:

        if (data_reg == 3) {

            if (data_reg2 == 4) {

                tcg_out_mov (s, 0, 4);

                tcg_out_mov (s, 4, 3);

                tcg_out_mov (s, 3, 0);

            }

            else {

                tcg_out_mov (s, data_reg2, 3);

                tcg_out_mov (s, 3, 4);

            }

        }

        else {

            if (data_reg != 4) tcg_out_mov (s, data_reg, 4);

            if (data_reg2 != 3) tcg_out_mov (s, data_reg2, 3);

        }

        break;

    }

    label2_ptr = s->code_ptr;

    tcg_out32 (s, B);

    /* label1: fast path */

#ifdef FAST_PATH

    reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);

#endif

    /* r0 now contains &env->tlb_table[mem_index][index].addr_read */

    tcg_out32 (s, (LWZ

                   | RT (r0)

                   | RA (r0)

                   | (ADDEND_OFFSET + offsetof (CPUTLBEntry, addend)

                      - offsetof (CPUTLBEntry, addr_read))

                   ));

    /* r0 = env->tlb_table[mem_index][index].addend */

    tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));

    /* r0 = env->tlb_table[mem_index][index].addend + addr */

#else  /* !CONFIG_SOFTMMU */

    r0 = addr_reg;

    r1 = 3;

    rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;

#endif

#ifdef TARGET_WORDS_BIGENDIAN

    bswap = 0;

#else

    bswap = 1;

#endif

    switch (opc) {

    default:

    case 0:

        tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));

        break;

    case 0|4:

        tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));

        tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));

        break;

    case 1:

        if (bswap)

            tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));

        else

            tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));

        break;

    case 1|4:

        if (bswap) {

            tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));

            tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));

        }

        else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));

        break;

    case 2:

        if (bswap)

            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));

        else

            tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));

        break;

    case 3:

        if (bswap) {

            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);

            tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));

            tcg_out32 (s, LWBRX | TAB (data_reg2, rbase, r1));

        }

        else {

#ifdef CONFIG_USE_GUEST_BASE

            tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);

            tcg_out32 (s, LWZX | TAB (data_reg2, rbase, r0));

            tcg_out32 (s, LWZX | TAB (data_reg, rbase, r1));

#else

            if (r0 == data_reg2) {

                tcg_out32 (s, LWZ | RT (0) | RA (r0));

                tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);

                tcg_out_mov (s, data_reg2, 0);

            }

            else {

                tcg_out32 (s, LWZ | RT (data_reg2) | RA (r0));

                tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);

            }

#endif

        }

        break;

    }

#ifdef CONFIG_SOFTMMU

    reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);

#endif

}


int32_t helper_fstoi(CPUSPARCState *env, float32 src)

{

    int32_t ret;

    clear_float_exceptions(env);

    ret = float32_to_int32_round_to_zero(src, &env->fp_status);

    check_ieee_exceptions(env);

    return ret;

}


static void version(void)

{

    printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION

           ", Copyright (c) 2003-2008 Fabrice Bellard\n");

}


static void raw_aio_flush_io_queue(BlockDriverState *bs)

{

#ifdef CONFIG_LINUX_AIO

    BDRVRawState *s = bs->opaque;

    if (s->use_aio) {

        laio_io_unplug(bs, s->aio_ctx, false);

    }

#endif

}


static inline void RENAME(bgr24ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, long width)

{

#ifdef HAVE_MMX

	asm volatile(

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

		"movq "MANGLE(w1111)", %%mm5		\n\t"

		"movq "MANGLE(bgr2UCoeff)", %%mm6		\n\t"

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

		"lea (%%"REG_a", %%"REG_a", 2), %%"REG_d"	\n\t"

		"add %%"REG_d", %%"REG_d"	\n\t"

		ASMALIGN(4)

		"1:				\n\t"

		PREFETCH" 64(%0, %%"REG_d")	\n\t"

#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)

		"movq (%0, %%"REG_d"), %%mm0	\n\t"

		"movq 6(%0, %%"REG_d"), %%mm2	\n\t"

		"movq %%mm0, %%mm1		\n\t"

		"movq %%mm2, %%mm3		\n\t"

		"psrlq $24, %%mm0		\n\t"

		"psrlq $24, %%mm2		\n\t"

		PAVGB(%%mm1, %%mm0)

		PAVGB(%%mm3, %%mm2)

		"punpcklbw %%mm7, %%mm0		\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

#else

		"movd (%0, %%"REG_d"), %%mm0	\n\t"

		"movd 3(%0, %%"REG_d"), %%mm2	\n\t"

		"punpcklbw %%mm7, %%mm0		\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

		"paddw %%mm2, %%mm0		\n\t"

		"movd 6(%0, %%"REG_d"), %%mm4	\n\t"

		"movd 9(%0, %%"REG_d"), %%mm2	\n\t"

		"punpcklbw %%mm7, %%mm4		\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

		"paddw %%mm4, %%mm2		\n\t"

		"psrlw $1, %%mm0		\n\t"

		"psrlw $1, %%mm2		\n\t"

#endif

		"movq "MANGLE(bgr2VCoeff)", %%mm1		\n\t"

		"movq "MANGLE(bgr2VCoeff)", %%mm3		\n\t"

		"pmaddwd %%mm0, %%mm1		\n\t"

		"pmaddwd %%mm2, %%mm3		\n\t"

		"pmaddwd %%mm6, %%mm0		\n\t"

		"pmaddwd %%mm6, %%mm2		\n\t"

#ifndef FAST_BGR2YV12

		"psrad $8, %%mm0		\n\t"

		"psrad $8, %%mm1		\n\t"

		"psrad $8, %%mm2		\n\t"

		"psrad $8, %%mm3		\n\t"

#endif

		"packssdw %%mm2, %%mm0		\n\t"

		"packssdw %%mm3, %%mm1		\n\t"

		"pmaddwd %%mm5, %%mm0		\n\t"

		"pmaddwd %%mm5, %%mm1		\n\t"

		"packssdw %%mm1, %%mm0		\n\t" // V1 V0 U1 U0

		"psraw $7, %%mm0		\n\t"

#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)

		"movq 12(%0, %%"REG_d"), %%mm4	\n\t"

		"movq 18(%0, %%"REG_d"), %%mm2	\n\t"

		"movq %%mm4, %%mm1		\n\t"

		"movq %%mm2, %%mm3		\n\t"

		"psrlq $24, %%mm4		\n\t"

		"psrlq $24, %%mm2		\n\t"

		PAVGB(%%mm1, %%mm4)

		PAVGB(%%mm3, %%mm2)

		"punpcklbw %%mm7, %%mm4		\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

#else

		"movd 12(%0, %%"REG_d"), %%mm4	\n\t"

		"movd 15(%0, %%"REG_d"), %%mm2	\n\t"

		"punpcklbw %%mm7, %%mm4		\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

		"paddw %%mm2, %%mm4		\n\t"

		"movd 18(%0, %%"REG_d"), %%mm5	\n\t"

		"movd 21(%0, %%"REG_d"), %%mm2	\n\t"

		"punpcklbw %%mm7, %%mm5		\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

		"paddw %%mm5, %%mm2		\n\t"

		"movq "MANGLE(w1111)", %%mm5		\n\t"

		"psrlw $2, %%mm4		\n\t"

		"psrlw $2, %%mm2		\n\t"

#endif

		"movq "MANGLE(bgr2VCoeff)", %%mm1		\n\t"

		"movq "MANGLE(bgr2VCoeff)", %%mm3		\n\t"

		"pmaddwd %%mm4, %%mm1		\n\t"

		"pmaddwd %%mm2, %%mm3		\n\t"

		"pmaddwd %%mm6, %%mm4		\n\t"

		"pmaddwd %%mm6, %%mm2		\n\t"

#ifndef FAST_BGR2YV12

		"psrad $8, %%mm4		\n\t"

		"psrad $8, %%mm1		\n\t"

		"psrad $8, %%mm2		\n\t"

		"psrad $8, %%mm3		\n\t"

#endif

		"packssdw %%mm2, %%mm4		\n\t"

		"packssdw %%mm3, %%mm1		\n\t"

		"pmaddwd %%mm5, %%mm4		\n\t"

		"pmaddwd %%mm5, %%mm1		\n\t"

		"add $24, %%"REG_d"		\n\t"

		"packssdw %%mm1, %%mm4		\n\t" // V3 V2 U3 U2

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

		"movq %%mm0, %%mm1		\n\t"

		"punpckldq %%mm4, %%mm0		\n\t"

		"punpckhdq %%mm4, %%mm1		\n\t"

		"packsswb %%mm1, %%mm0		\n\t"

		"paddb "MANGLE(bgr2UVOffset)", %%mm0	\n\t"

		"movd %%mm0, (%1, %%"REG_a")	\n\t"

		"punpckhdq %%mm0, %%mm0		\n\t"

		"movd %%mm0, (%2, %%"REG_a")	\n\t"

		"add $4, %%"REG_a"		\n\t"

		" js 1b				\n\t"

		: : "r" (src1+width*6), "r" (dstU+width), "r" (dstV+width), "g" (-width)

		: "%"REG_a, "%"REG_d

	);

#else

	int i;

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

	{

		int b= src1[6*i + 0] + src1[6*i + 3];

		int g= src1[6*i + 1] + src1[6*i + 4];

		int r= src1[6*i + 2] + src1[6*i + 5];

		dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+1)) + 128;

		dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+1)) + 128;

	}

#endif

        assert(src1 == src2);

}


static void test_ivshmem_server(void)

{

    IVState state1, state2, *s1, *s2;

    ServerThread thread;

    IvshmemServer server;

    int ret, vm1, vm2;

    int nvectors = 2;

    guint64 end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;

    memset(tmpshmem, 0x42, TMPSHMSIZE);

    ret = ivshmem_server_init(&server, tmpserver, tmpshm,

                              TMPSHMSIZE, nvectors,

                              g_test_verbose());

    g_assert_cmpint(ret, ==, 0);

    ret = ivshmem_server_start(&server);

    g_assert_cmpint(ret, ==, 0);

    setup_vm_with_server(&state1, nvectors);

    s1 = &state1;

    setup_vm_with_server(&state2, nvectors);

    s2 = &state2;

    g_assert_cmpuint(in_reg(s1, IVPOSITION), ==, 0xffffffff);

    g_assert_cmpuint(in_reg(s2, IVPOSITION), ==, 0xffffffff);

    g_assert_cmpuint(qtest_readb(s1->qtest, (uintptr_t)s1->mem_base), ==, 0x00);

    thread.server = &server;

    ret = pipe(thread.pipe);

    g_assert_cmpint(ret, ==, 0);

    thread.thread = g_thread_new("ivshmem-server", server_thread, &thread);

    g_assert(thread.thread != NULL);

    /* waiting until mapping is done */

    while (g_get_monotonic_time() < end_time) {

        g_usleep(1000);

        if (qtest_readb(s1->qtest, (uintptr_t)s1->mem_base) == 0x42 &&

            qtest_readb(s2->qtest, (uintptr_t)s2->mem_base) == 0x42) {

            break;

        }

    }

    /* check got different VM ids */

    vm1 = in_reg(s1, IVPOSITION);

    vm2 = in_reg(s2, IVPOSITION);

    g_assert_cmpuint(vm1, !=, vm2);

    global_qtest = s1->qtest;

    ret = qpci_msix_table_size(s1->dev);

    g_assert_cmpuint(ret, ==, nvectors);

    /* ping vm2 -> vm1 */

    ret = qpci_msix_pending(s1->dev, 0);

    g_assert_cmpuint(ret, ==, 0);

    out_reg(s2, DOORBELL, vm1 << 16);

    do {

        g_usleep(10000);

        ret = qpci_msix_pending(s1->dev, 0);

    } while (ret == 0 && g_get_monotonic_time() < end_time);

    g_assert_cmpuint(ret, !=, 0);

    /* ping vm1 -> vm2 */

    global_qtest = s2->qtest;

    ret = qpci_msix_pending(s2->dev, 0);

    g_assert_cmpuint(ret, ==, 0);

    out_reg(s1, DOORBELL, vm2 << 16);

    do {

        g_usleep(10000);

        ret = qpci_msix_pending(s2->dev, 0);

    } while (ret == 0 && g_get_monotonic_time() < end_time);

    g_assert_cmpuint(ret, !=, 0);

    qtest_quit(s2->qtest);

    qtest_quit(s1->qtest);

    if (qemu_write_full(thread.pipe[1], "q", 1) != 1) {

        g_error("qemu_write_full: %s", g_strerror(errno));

    }

    g_thread_join(thread.thread);

    ivshmem_server_close(&server);

    close(thread.pipe[1]);

    close(thread.pipe[0]);

}


static int escape124_decode_frame(AVCodecContext *avctx,
                                  void *data, int *got_frame,
                                  AVPacket *avpkt)
{
    int buf_size = avpkt->size;
    Escape124Context *s = avctx->priv_data;
    AVFrame *frame = data;
    GetBitContext gb;
    unsigned frame_flags, frame_size;
    unsigned i;
    unsigned superblock_index, cb_index = 1,
             superblock_col_index = 0,
             superblocks_per_row = avctx->width / 8, skip = -1;
    uint16_t* old_frame_data, *new_frame_data;
    unsigned old_stride, new_stride;
    int ret;
    if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
        return ret;
    // This call also guards the potential depth reads for the
    // codebook unpacking.
    if (get_bits_left(&gb) < 64)
        return -1;
    frame_flags = get_bits_long(&gb, 32);
    frame_size  = get_bits_long(&gb, 32);
    // Leave last frame unchanged
    // FIXME: Is this necessary?  I haven't seen it in any real samples
    if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) {
        if (!s->frame->data[0])
        av_log(avctx, AV_LOG_DEBUG, "Skipping frame\n");
        *got_frame = 1;
        if ((ret = av_frame_ref(frame, s->frame)) < 0)
            return ret;
        return frame_size;
    for (i = 0; i < 3; i++) {
        if (frame_flags & (1 << (17 + i))) {
            unsigned cb_depth, cb_size;
            if (i == 2) {
                // This codebook can be cut off at places other than
                // powers of 2, leaving some of the entries undefined.
                cb_size = get_bits_long(&gb, 20);
                if (!cb_size) {
                    av_log(avctx, AV_LOG_ERROR, "Invalid codebook size 0.\n");
                cb_depth = av_log2(cb_size - 1) + 1;
            } else {
                cb_depth = get_bits(&gb, 4);
                if (i == 0) {
                    // This is the most basic codebook: pow(2,depth) entries
                    // for a depth-length key
                    cb_size = 1 << cb_depth;
                } else {
                    // This codebook varies per superblock
                    // FIXME: I don't think this handles integer overflow
                    // properly
                    cb_size = s->num_superblocks << cb_depth;
            av_freep(&s->codebooks[i].blocks);
            s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size);
            if (!s->codebooks[i].blocks)
                return -1;
    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
        return ret;
    new_frame_data = (uint16_t*)frame->data[0];
    new_stride = frame->linesize[0] / 2;
    old_frame_data = (uint16_t*)s->frame->data[0];
    old_stride = s->frame->linesize[0] / 2;
    for (superblock_index = 0; superblock_index < s->num_superblocks;
         superblock_index++) {
        MacroBlock mb;
        SuperBlock sb;
        unsigned multi_mask = 0;
        if (skip == -1) {
            // Note that this call will make us skip the rest of the blocks
            // if the frame prematurely ends
            skip = decode_skip_count(&gb);
        if (skip) {
            copy_superblock(new_frame_data, new_stride,
                            old_frame_data, old_stride);
        } else {
            copy_superblock(sb.pixels, 8,
                            old_frame_data, old_stride);
            while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) {
                unsigned mask;
                mb = decode_macroblock(s, &gb, &cb_index, superblock_index);
                mask = get_bits(&gb, 16);
                multi_mask |= mask;
                for (i = 0; i < 16; i++) {
                    if (mask & mask_matrix[i]) {
                        insert_mb_into_sb(&sb, mb, i);
            if (!get_bits1(&gb)) {
                unsigned inv_mask = get_bits(&gb, 4);
                for (i = 0; i < 4; i++) {
                    if (inv_mask & (1 << i)) {
                        multi_mask ^= 0xF << i*4;
                    } else {
                        multi_mask ^= get_bits(&gb, 4) << i*4;
                for (i = 0; i < 16; i++) {
                    if (multi_mask & mask_matrix[i]) {
                        mb = decode_macroblock(s, &gb, &cb_index,
                                               superblock_index);
                        insert_mb_into_sb(&sb, mb, i);
            } else if (frame_flags & (1 << 16)) {
                while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) {
                    mb = decode_macroblock(s, &gb, &cb_index, superblock_index);
                    insert_mb_into_sb(&sb, mb, get_bits(&gb, 4));
            copy_superblock(new_frame_data, new_stride, sb.pixels, 8);
        superblock_col_index++;
        new_frame_data += 8;
        if (old_frame_data)
            old_frame_data += 8;
        if (superblock_col_index == superblocks_per_row) {
            new_frame_data += new_stride * 8 - superblocks_per_row * 8;
            if (old_frame_data)
                old_frame_data += old_stride * 8 - superblocks_per_row * 8;
            superblock_col_index = 0;
        skip--;
    av_log(avctx, AV_LOG_DEBUG,
           "Escape sizes: %i, %i, %i\n",
           frame_size, buf_size, get_bits_count(&gb) / 8);
    av_frame_unref(s->frame);
    if ((ret = av_frame_ref(s->frame, frame)) < 0)
        return ret;
    *got_frame = 1;
    return frame_size;


DeviceState *qdev_create(BusState *bus, const char *name)

{

    DeviceState *dev;

    dev = qdev_try_create(bus, name);

    if (!dev) {

        hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);

    }

    return dev;

}


static void quantize_and_encode_band_cost_SQUAD_mips(struct AACEncContext *s,

                                                     PutBitContext *pb, const float *in, float *out,

                                                     const float *scaled, int size, int scale_idx,

                                                     int cb, const float lambda, const float uplim,

                                                     int *bits, const float ROUNDING)

{

    const float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];

    const float IQ  = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];

    int i;

    int qc1, qc2, qc3, qc4;

    uint8_t  *p_bits  = (uint8_t  *)ff_aac_spectral_bits[cb-1];

    uint16_t *p_codes = (uint16_t *)ff_aac_spectral_codes[cb-1];

    float    *p_vec   = (float    *)ff_aac_codebook_vectors[cb-1];

    abs_pow34_v(s->scoefs, in, size);

    scaled = s->scoefs;

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

        int curidx;

        int *in_int = (int *)&in[i];

        int t0, t1, t2, t3, t4, t5, t6, t7;

        const float *vec;

        qc1 = scaled[i  ] * Q34 + ROUND_STANDARD;

        qc2 = scaled[i+1] * Q34 + ROUND_STANDARD;

        qc3 = scaled[i+2] * Q34 + ROUND_STANDARD;

        qc4 = scaled[i+3] * Q34 + ROUND_STANDARD;

        __asm__ volatile (

            ".set push                      \n\t"

            ".set noreorder                 \n\t"

            "slt    %[qc1], $zero,  %[qc1]  \n\t"

            "slt    %[qc2], $zero,  %[qc2]  \n\t"

            "slt    %[qc3], $zero,  %[qc3]  \n\t"

            "slt    %[qc4], $zero,  %[qc4]  \n\t"

            "lw     %[t0],  0(%[in_int])    \n\t"

            "lw     %[t1],  4(%[in_int])    \n\t"

            "lw     %[t2],  8(%[in_int])    \n\t"

            "lw     %[t3],  12(%[in_int])   \n\t"

            "srl    %[t0],  %[t0],  31      \n\t"

            "srl    %[t1],  %[t1],  31      \n\t"

            "srl    %[t2],  %[t2],  31      \n\t"

            "srl    %[t3],  %[t3],  31      \n\t"

            "subu   %[t4],  $zero,  %[qc1]  \n\t"

            "subu   %[t5],  $zero,  %[qc2]  \n\t"

            "subu   %[t6],  $zero,  %[qc3]  \n\t"

            "subu   %[t7],  $zero,  %[qc4]  \n\t"

            "movn   %[qc1], %[t4],  %[t0]   \n\t"

            "movn   %[qc2], %[t5],  %[t1]   \n\t"

            "movn   %[qc3], %[t6],  %[t2]   \n\t"

            "movn   %[qc4], %[t7],  %[t3]   \n\t"

            ".set pop                       \n\t"

            : [qc1]"+r"(qc1), [qc2]"+r"(qc2),

              [qc3]"+r"(qc3), [qc4]"+r"(qc4),

              [t0]"=&r"(t0), [t1]"=&r"(t1), [t2]"=&r"(t2), [t3]"=&r"(t3),

              [t4]"=&r"(t4), [t5]"=&r"(t5), [t6]"=&r"(t6), [t7]"=&r"(t7)

            : [in_int]"r"(in_int)

            : "memory"

        );

        curidx = qc1;

        curidx *= 3;

        curidx += qc2;

        curidx *= 3;

        curidx += qc3;

        curidx *= 3;

        curidx += qc4;

        curidx += 40;

        put_bits(pb, p_bits[curidx], p_codes[curidx]);

        if (out) {

           vec = &p_vec[curidx*4];

           out[i+0] = vec[0] * IQ;

           out[i+1] = vec[1] * IQ;

           out[i+2] = vec[2] * IQ;

           out[i+3] = vec[3] * IQ;

        }

    }

}


static void vhost_begin(MemoryListener *listener)

{

}


void ff_tls_deinit(void)

{

#if CONFIG_TLS_OPENSSL_PROTOCOL

    ff_openssl_deinit();

#endif

#if CONFIG_TLS_GNUTLS_PROTOCOL

    ff_gnutls_deinit();

#endif

}


static void xbr2x(AVFrame * input, AVFrame * output, const uint32_t * r2y)

{

    int x,y;

    int next_line = output->linesize[0]>>2;

    for (y = 0; y < input->height; y++) {

        uint32_t pprev;

        uint32_t pprev2;

        uint32_t * E = (uint32_t *)(output->data[0] + y * output->linesize[0] * 2);

        /* middle. Offset of -8 is given */

        uint32_t * sa2 = (uint32_t *)(input->data[0] + y * input->linesize[0] - 8);

        /* up one */

        uint32_t * sa1 = sa2 - (input->linesize[0]>>2);

        /* up two */

        uint32_t * sa0 = sa1 - (input->linesize[0]>>2);

        /* down one */

        uint32_t * sa3 = sa2 + (input->linesize[0]>>2);

        /* down two */

        uint32_t * sa4 = sa3 + (input->linesize[0]>>2);

        if (y <= 1) {

            sa0 = sa1;

            if (y == 0) {

                sa0 = sa1 = sa2;

            }

        }

        if (y >= input->height - 2) {

            sa4 = sa3;

            if (y == input->height - 1) {

                sa4 = sa3 = sa2;

            }

        }

        pprev = pprev2 = 2;

        for (x = 0; x < input->width; x++) {

            uint32_t B1 = sa0[2];

            uint32_t PB = sa1[2];

            uint32_t PE = sa2[2];

            uint32_t PH = sa3[2];

            uint32_t H5 = sa4[2];

            uint32_t A1 = sa0[pprev];

            uint32_t PA = sa1[pprev];

            uint32_t PD = sa2[pprev];

            uint32_t PG = sa3[pprev];

            uint32_t G5 = sa4[pprev];

            uint32_t A0 = sa1[pprev2];

            uint32_t D0 = sa2[pprev2];

            uint32_t G0 = sa3[pprev2];

            uint32_t C1 = 0;

            uint32_t PC = 0;

            uint32_t PF = 0;

            uint32_t PI = 0;

            uint32_t I5 = 0;

            uint32_t C4 = 0;

            uint32_t F4 = 0;

            uint32_t I4 = 0;

            if (x >= input->width - 2) {

                if (x == input->width - 1) {

                    C1 = sa0[2];

                    PC = sa1[2];

                    PF = sa2[2];

                    PI = sa3[2];

                    I5 = sa4[2];

                    C4 = sa1[2];

                    F4 = sa2[2];

                    I4 = sa3[2];

                } else {

                    C1 = sa0[3];

                    PC = sa1[3];

                    PF = sa2[3];

                    PI = sa3[3];

                    I5 = sa4[3];

                    C4 = sa1[3];

                    F4 = sa2[3];

                    I4 = sa3[3];

                }

            } else {

                C1 = sa0[3];

                PC = sa1[3];

                PF = sa2[3];

                PI = sa3[3];

                I5 = sa4[3];

                C4 = sa1[4];

                F4 = sa2[4];

                I4 = sa3[4];

            }

            E[0] = E[1] = E[next_line] = E[next_line + 1] = PE; // 0, 1, 2, 3

            FILT2(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, 0, 1, next_line, next_line+1);

            FILT2(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0, next_line, 0, next_line+1, 1);

            FILT2(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5, next_line+1, next_line, 1, 0);

            FILT2(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, 1, next_line+1, 0, next_line);

            sa0 += 1;

            sa1 += 1;

            sa2 += 1;

            sa3 += 1;

            sa4 += 1;

            E += 2;

            if (pprev2){

                pprev2--;

                pprev = 1;

            }

        }

    }

}


static inline int32_t mipsdsp_sat_add_i32(int32_t a, int32_t b,

                                          CPUMIPSState *env)

{

    int32_t tempI;

    tempI = a + b;

    if (MIPSDSP_OVERFLOW(a, b, tempI, 0x80000000)) {

        if (a > 0) {

            tempI = 0x7FFFFFFF;

        } else {

            tempI = 0x80000000;

        }

        set_DSPControl_overflow_flag(1, 20, env);

    }

    return tempI;

}


CharDriverState *uart_hci_init(qemu_irq wakeup)

{

    struct csrhci_s *s = (struct csrhci_s *)

            g_malloc0(sizeof(struct csrhci_s));

    s->chr.opaque = s;

    s->chr.chr_write = csrhci_write;

    s->chr.chr_ioctl = csrhci_ioctl;

    s->hci = qemu_next_hci();

    s->hci->opaque = s;

    s->hci->evt_recv = csrhci_out_hci_packet_event;

    s->hci->acl_recv = csrhci_out_hci_packet_acl;

    s->out_tm = qemu_new_timer_ns(vm_clock, csrhci_out_tick, s);

    s->pins = qemu_allocate_irqs(csrhci_pins, s, __csrhci_pins);

    csrhci_reset(s);

    return &s->chr;

}


static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                            AVPacket *avpkt) {
    const uint8_t *buf = avpkt->data;
    const uint8_t *buf_end = avpkt->data + avpkt->size;
    PTXContext * const s = avctx->priv_data;
    AVFrame *picture = data;
    AVFrame * const p = &s->picture;
    unsigned int offset, w, h, y, stride, bytes_per_pixel;
    uint8_t *ptr;
    if (buf_end - buf < 14)
    offset          = AV_RL16(buf);
    w               = AV_RL16(buf+8);
    h               = AV_RL16(buf+10);
    bytes_per_pixel = AV_RL16(buf+12) >> 3;
    if (bytes_per_pixel != 2) {
        av_log_ask_for_sample(avctx, "Image format is not RGB15.\n");
        return -1;
    }
    avctx->pix_fmt = PIX_FMT_RGB555;
    if (offset != 0x2c)
        av_log_ask_for_sample(avctx, "offset != 0x2c\n");
    buf += offset;
    if (p->data[0])
        avctx->release_buffer(avctx, p);
    if (av_image_check_size(w, h, 0, avctx))
        return -1;
    if (w != avctx->width || h != avctx->height)
        avcodec_set_dimensions(avctx, w, h);
    if (avctx->get_buffer(avctx, p) < 0) {
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return -1;
    }
    p->pict_type = AV_PICTURE_TYPE_I;
    ptr    = p->data[0];
    stride = p->linesize[0];
    for (y=0; y<h; y++) {
        if (buf_end - buf < w * bytes_per_pixel)
            break;
#if HAVE_BIGENDIAN
        unsigned int x;
        for (x=0; x<w*bytes_per_pixel; x+=bytes_per_pixel)
            AV_WN16(ptr+x, AV_RL16(buf+x));
#else
        memcpy(ptr, buf, w*bytes_per_pixel);
#endif
        ptr += stride;
        buf += w*bytes_per_pixel;
    }
    *picture = s->picture;
    *data_size = sizeof(AVPicture);
    return offset + w*h*bytes_per_pixel;
}


static int64_t alloc_clusters_noref(BlockDriverState *bs, uint64_t size)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t i, nb_clusters;

    int refcount;

    nb_clusters = size_to_clusters(s, size);

retry:

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

        uint64_t next_cluster_index = s->free_cluster_index++;

        refcount = get_refcount(bs, next_cluster_index);

        if (refcount < 0) {

            return refcount;

        } else if (refcount != 0) {

            goto retry;

        }

    }

    /* Make sure that all offsets in the "allocated" range are representable

     * in an int64_t */

    if (s->free_cluster_index - 1 > (INT64_MAX >> s->cluster_bits)) {

        return -EFBIG;

    }

#ifdef DEBUG_ALLOC2

    fprintf(stderr, "alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n",

            size,

            (s->free_cluster_index - nb_clusters) << s->cluster_bits);

#endif

    return (s->free_cluster_index - nb_clusters) << s->cluster_bits;

}


static void vhost_region_del(MemoryListener *listener,

                             MemoryRegionSection *section)

{

    struct vhost_dev *dev = container_of(listener, struct vhost_dev,

                                         memory_listener);

    int i;

    vhost_set_memory(listener, section, false);

    for (i = 0; i < dev->n_mem_sections; ++i) {

        if (dev->mem_sections[i].offset_within_address_space

            == section->offset_within_address_space) {

            --dev->n_mem_sections;

            memmove(&dev->mem_sections[i], &dev->mem_sections[i+1],

                    dev->n_mem_sections - i);

            break;

        }

    }

}


static int wma_decode_block(WMADecodeContext *s)

{

    int n, v, a, ch, code, bsize;

    int coef_nb_bits, total_gain, parse_exponents;

    DECLARE_ALIGNED_16(float, window[BLOCK_MAX_SIZE * 2]);

    int nb_coefs[MAX_CHANNELS];

    float mdct_norm;

#ifdef TRACE

    tprintf("***decode_block: %d:%d\n", s->frame_count - 1, s->block_num);

#endif

    /* compute current block length */

    if (s->use_variable_block_len) {

        n = av_log2(s->nb_block_sizes - 1) + 1;

        if (s->reset_block_lengths) {

            s->reset_block_lengths = 0;

            v = get_bits(&s->gb, n);

            if (v >= s->nb_block_sizes)

                return -1;

            s->prev_block_len_bits = s->frame_len_bits - v;

            v = get_bits(&s->gb, n);

            if (v >= s->nb_block_sizes)

                return -1;

            s->block_len_bits = s->frame_len_bits - v;

        } else {

            /* update block lengths */

            s->prev_block_len_bits = s->block_len_bits;

            s->block_len_bits = s->next_block_len_bits;

        }

        v = get_bits(&s->gb, n);

        if (v >= s->nb_block_sizes)

            return -1;

        s->next_block_len_bits = s->frame_len_bits - v;

    } else {

        /* fixed block len */

        s->next_block_len_bits = s->frame_len_bits;

        s->prev_block_len_bits = s->frame_len_bits;

        s->block_len_bits = s->frame_len_bits;

    }

    /* now check if the block length is coherent with the frame length */

    s->block_len = 1 << s->block_len_bits;

    if ((s->block_pos + s->block_len) > s->frame_len)

        return -1;

    if (s->nb_channels == 2) {

        s->ms_stereo = get_bits(&s->gb, 1);

    }

    v = 0;

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

        a = get_bits(&s->gb, 1);

        s->channel_coded[ch] = a;

        v |= a;

    }

    /* if no channel coded, no need to go further */

    /* XXX: fix potential framing problems */

    if (!v)

        goto next;

    bsize = s->frame_len_bits - s->block_len_bits;

    /* read total gain and extract corresponding number of bits for

       coef escape coding */

    total_gain = 1;

    for(;;) {

        a = get_bits(&s->gb, 7);

        total_gain += a;

        if (a != 127)

            break;

    }

    if (total_gain < 15)

        coef_nb_bits = 13;

    else if (total_gain < 32)

        coef_nb_bits = 12;

    else if (total_gain < 40)

        coef_nb_bits = 11;

    else if (total_gain < 45)

        coef_nb_bits = 10;

    else

        coef_nb_bits = 9;

    /* compute number of coefficients */

    n = s->coefs_end[bsize] - s->coefs_start;

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

        nb_coefs[ch] = n;

    /* complex coding */

    if (s->use_noise_coding) {

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

            if (s->channel_coded[ch]) {

                int i, n, a;

                n = s->exponent_high_sizes[bsize];

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

                    a = get_bits(&s->gb, 1);

                    s->high_band_coded[ch][i] = a;

                    /* if noise coding, the coefficients are not transmitted */

                    if (a)

                        nb_coefs[ch] -= s->exponent_high_bands[bsize][i];

                }

            }

        }

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

            if (s->channel_coded[ch]) {

                int i, n, val, code;

                n = s->exponent_high_sizes[bsize];

                val = (int)0x80000000;

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

                    if (s->high_band_coded[ch][i]) {

                        if (val == (int)0x80000000) {

                            val = get_bits(&s->gb, 7) - 19;

                        } else {

                            code = get_vlc2(&s->gb, s->hgain_vlc.table, HGAINVLCBITS, HGAINMAX);

                            if (code < 0)

                                return -1;

                            val += code - 18;

                        }

                        s->high_band_values[ch][i] = val;

                    }

                }

            }

        }

    }

    /* exposant can be interpolated in short blocks. */

    parse_exponents = 1;

    if (s->block_len_bits != s->frame_len_bits) {

        parse_exponents = get_bits(&s->gb, 1);

    }

    if (parse_exponents) {

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

            if (s->channel_coded[ch]) {

                if (s->use_exp_vlc) {

                    if (decode_exp_vlc(s, ch) < 0)

                        return -1;

                } else {

                    decode_exp_lsp(s, ch);

                }

            }

        }

    } else {

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

            if (s->channel_coded[ch]) {

                interpolate_array(s->exponents[ch], 1 << s->prev_block_len_bits,

                                  s->block_len);

            }

        }

    }

    /* parse spectral coefficients : just RLE encoding */

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

        if (s->channel_coded[ch]) {

            VLC *coef_vlc;

            int level, run, sign, tindex;

            int16_t *ptr, *eptr;

            const uint16_t *level_table, *run_table;

            /* special VLC tables are used for ms stereo because

               there is potentially less energy there */

            tindex = (ch == 1 && s->ms_stereo);

            coef_vlc = &s->coef_vlc[tindex];

            run_table = s->run_table[tindex];

            level_table = s->level_table[tindex];

            /* XXX: optimize */

            ptr = &s->coefs1[ch][0];

            eptr = ptr + nb_coefs[ch];

            memset(ptr, 0, s->block_len * sizeof(int16_t));

            for(;;) {

                code = get_vlc2(&s->gb, coef_vlc->table, VLCBITS, VLCMAX);

                if (code < 0)

                    return -1;

                if (code == 1) {

                    /* EOB */

                    break;

                } else if (code == 0) {

                    /* escape */

                    level = get_bits(&s->gb, coef_nb_bits);

                    /* NOTE: this is rather suboptimal. reading

                       block_len_bits would be better */

                    run = get_bits(&s->gb, s->frame_len_bits);

                } else {

                    /* normal code */

                    run = run_table[code];

                    level = level_table[code];

                }

                sign = get_bits(&s->gb, 1);

                if (!sign)

                    level = -level;

                ptr += run;

                if (ptr >= eptr)

                {

                    av_log(NULL, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n");

                    break;

                }

                *ptr++ = level;

                /* NOTE: EOB can be omitted */

                if (ptr >= eptr)

                    break;

            }

        }

        if (s->version == 1 && s->nb_channels >= 2) {

            align_get_bits(&s->gb);

        }

    }

    /* normalize */

    {

        int n4 = s->block_len / 2;

        mdct_norm = 1.0 / (float)n4;

        if (s->version == 1) {

            mdct_norm *= sqrt(n4);

        }

    }

    /* finally compute the MDCT coefficients */

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

        if (s->channel_coded[ch]) {

            int16_t *coefs1;

            float *coefs, *exponents, mult, mult1, noise, *exp_ptr;

            int i, j, n, n1, last_high_band;

            float exp_power[HIGH_BAND_MAX_SIZE];

            coefs1 = s->coefs1[ch];

            exponents = s->exponents[ch];

            mult = pow(10, total_gain * 0.05) / s->max_exponent[ch];

            mult *= mdct_norm;

            coefs = s->coefs[ch];

            if (s->use_noise_coding) {

                mult1 = mult;

                /* very low freqs : noise */

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

                    *coefs++ = s->noise_table[s->noise_index] * (*exponents++) * mult1;

                    s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);

                }

                n1 = s->exponent_high_sizes[bsize];

                /* compute power of high bands */

                exp_ptr = exponents +

                    s->high_band_start[bsize] -

                    s->coefs_start;

                last_high_band = 0; /* avoid warning */

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

                    n = s->exponent_high_bands[s->frame_len_bits -

                                              s->block_len_bits][j];

                    if (s->high_band_coded[ch][j]) {

                        float e2, v;

                        e2 = 0;

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

                            v = exp_ptr[i];

                            e2 += v * v;

                        }

                        exp_power[j] = e2 / n;

                        last_high_band = j;

                        tprintf("%d: power=%f (%d)\n", j, exp_power[j], n);

                    }

                    exp_ptr += n;

                }

                /* main freqs and high freqs */

                for(j=-1;j<n1;j++) {

                    if (j < 0) {

                        n = s->high_band_start[bsize] -

                            s->coefs_start;

                    } else {

                        n = s->exponent_high_bands[s->frame_len_bits -

                                                  s->block_len_bits][j];

                    }

                    if (j >= 0 && s->high_band_coded[ch][j]) {

                        /* use noise with specified power */

                        mult1 = sqrt(exp_power[j] / exp_power[last_high_band]);

                        /* XXX: use a table */

                        mult1 = mult1 * pow(10, s->high_band_values[ch][j] * 0.05);

                        mult1 = mult1 / (s->max_exponent[ch] * s->noise_mult);

                        mult1 *= mdct_norm;

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

                            noise = s->noise_table[s->noise_index];

                            s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);

                            *coefs++ = (*exponents++) * noise * mult1;

                        }

                    } else {

                        /* coded values + small noise */

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

                            noise = s->noise_table[s->noise_index];

                            s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);

                            *coefs++ = ((*coefs1++) + noise) * (*exponents++) * mult;

                        }

                    }

                }

                /* very high freqs : noise */

                n = s->block_len - s->coefs_end[bsize];

                mult1 = mult * exponents[-1];

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

                    *coefs++ = s->noise_table[s->noise_index] * mult1;

                    s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);

                }

            } else {

                /* XXX: optimize more */

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

                    *coefs++ = 0.0;

                n = nb_coefs[ch];

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

                    *coefs++ = coefs1[i] * exponents[i] * mult;

                }

                n = s->block_len - s->coefs_end[bsize];

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

                    *coefs++ = 0.0;

            }

        }

    }

#ifdef TRACE

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

        if (s->channel_coded[ch]) {

            dump_floats("exponents", 3, s->exponents[ch], s->block_len);

            dump_floats("coefs", 1, s->coefs[ch], s->block_len);

        }

    }

#endif

    if (s->ms_stereo && s->channel_coded[1]) {

        float a, b;

        int i;

        /* nominal case for ms stereo: we do it before mdct */

        /* no need to optimize this case because it should almost

           never happen */

        if (!s->channel_coded[0]) {

            tprintf("rare ms-stereo case happened\n");

            memset(s->coefs[0], 0, sizeof(float) * s->block_len);

            s->channel_coded[0] = 1;

        }

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

            a = s->coefs[0][i];

            b = s->coefs[1][i];

            s->coefs[0][i] = a + b;

            s->coefs[1][i] = a - b;

        }

    }

    /* build the window : we ensure that when the windows overlap

       their squared sum is always 1 (MDCT reconstruction rule) */

    /* XXX: merge with output */

    {

        int i, next_block_len, block_len, prev_block_len, n;

        float *wptr;

        block_len = s->block_len;

        prev_block_len = 1 << s->prev_block_len_bits;

        next_block_len = 1 << s->next_block_len_bits;

        /* right part */

        wptr = window + block_len;

        if (block_len <= next_block_len) {

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

                *wptr++ = s->windows[bsize][i];

        } else {

            /* overlap */

            n = (block_len / 2) - (next_block_len / 2);

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

                *wptr++ = 1.0;

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

                *wptr++ = s->windows[s->frame_len_bits - s->next_block_len_bits][i];

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

                *wptr++ = 0.0;

        }

        /* left part */

        wptr = window + block_len;

        if (block_len <= prev_block_len) {

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

                *--wptr = s->windows[bsize][i];

        } else {

            /* overlap */

            n = (block_len / 2) - (prev_block_len / 2);

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

                *--wptr = 1.0;

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

                *--wptr = s->windows[s->frame_len_bits - s->prev_block_len_bits][i];

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

                *--wptr = 0.0;

        }

    }

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

        if (s->channel_coded[ch]) {

            DECLARE_ALIGNED_16(FFTSample, output[BLOCK_MAX_SIZE * 2]);

            float *ptr;

            int n4, index, n;

            n = s->block_len;

            n4 = s->block_len / 2;

            s->mdct_ctx[bsize].fft.imdct_calc(&s->mdct_ctx[bsize],

                          output, s->coefs[ch], s->mdct_tmp);

            /* XXX: optimize all that by build the window and

               multipying/adding at the same time */

            /* multiply by the window and add in the frame */

            index = (s->frame_len / 2) + s->block_pos - n4;

            ptr = &s->frame_out[ch][index];

            s->dsp.vector_fmul_add_add(ptr,window,output,ptr,0,2*n,1);

            /* specific fast case for ms-stereo : add to second

               channel if it is not coded */

            if (s->ms_stereo && !s->channel_coded[1]) {

                ptr = &s->frame_out[1][index];

                s->dsp.vector_fmul_add_add(ptr,window,output,ptr,0,2*n,1);

            }

        }

    }

 next:

    /* update block number */

    s->block_num++;

    s->block_pos += s->block_len;

    if (s->block_pos >= s->frame_len)

        return 1;

    else

        return 0;

}


static int swf_probe(AVProbeData *p)

{

    if(p->buf_size < 15)

        return 0;

    /* check file header */

    if (   AV_RB24(p->buf) != AV_RB24("CWS")

        && AV_RB24(p->buf) != AV_RB24("FWS"))

        return 0;

    if (p->buf[3] >= 20)

        return AVPROBE_SCORE_MAX / 4;

    return AVPROBE_SCORE_MAX;

}


static void RENAME(yuv2yuyv422_1)(SwsContext *c, const int16_t *buf0,

                                  const int16_t *ubuf[2], const int16_t *bguf[2],

                                  const int16_t *abuf0, uint8_t *dest,

                                  int dstW, int uvalpha, int y)

{

    const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1];

    const int16_t *buf1= buf0; //FIXME needed for RGB1/BGR1

    if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster

        __asm__ volatile(

            "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"

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

            "push %%"REG_BP"                        \n\t"

            YSCALEYUV2PACKED1(%%REGBP, %5)

            WRITEYUY2(%%REGb, 8280(%5), %%REGBP)

            "pop %%"REG_BP"                         \n\t"

            "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"

            :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),

               "a" (&c->redDither)

        );

    } else {

        __asm__ volatile(

            "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"

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

            "push %%"REG_BP"                        \n\t"

            YSCALEYUV2PACKED1b(%%REGBP, %5)

            WRITEYUY2(%%REGb, 8280(%5), %%REGBP)

            "pop %%"REG_BP"                         \n\t"

            "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"

            :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),

               "a" (&c->redDither)

        );

    }

}


void command_loop(void)

{

    int c, i, j = 0, done = 0, fetchable = 0, prompted = 0;

    char *input;

    char **v;

    const cmdinfo_t *ct;

    for (i = 0; !done && i < ncmdline; i++) {

        input = strdup(cmdline[i]);

        if (!input) {

            fprintf(stderr, _("cannot strdup command '%s': %s\n"),

                    cmdline[i], strerror(errno));

            exit(1);

        }

        v = breakline(input, &c);

        if (c) {

            ct = find_command(v[0]);

            if (ct) {

                if (ct->flags & CMD_FLAG_GLOBAL) {

                    done = command(ct, c, v);

                } else {

                    j = 0;

                    while (!done && (j = args_command(j))) {

                        done = command(ct, c, v);

                    }

                }

            } else {

                fprintf(stderr, _("command \"%s\" not found\n"), v[0]);

            }

	}

        doneline(input, v);

    }

    if (cmdline) {

        free(cmdline);

        return;

    }

    while (!done) {

        if (!prompted) {

            printf("%s", get_prompt());

            fflush(stdout);

            qemu_aio_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, NULL,

                                    NULL, &fetchable);

            prompted = 1;

        }

        qemu_aio_wait();

        if (!fetchable) {

            continue;

        }

        input = fetchline();

        if (input == NULL) {

            break;

        }

        v = breakline(input, &c);

        if (c) {

            ct = find_command(v[0]);

            if (ct) {

                done = command(ct, c, v);

            } else {

                fprintf(stderr, _("command \"%s\" not found\n"), v[0]);

            }

        }

        doneline(input, v);

        prompted = 0;

        fetchable = 0;

    }

    qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL);

}


static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)

{

    TCGv_i64 tmp;

    switch ((size << 1) | u) {

    case 0: gen_helper_neon_mull_s8(dest, a, b); break;

    case 1: gen_helper_neon_mull_u8(dest, a, b); break;

    case 2: gen_helper_neon_mull_s16(dest, a, b); break;

    case 3: gen_helper_neon_mull_u16(dest, a, b); break;

    case 4:

        tmp = gen_muls_i64_i32(a, b);

        tcg_gen_mov_i64(dest, tmp);

        break;

    case 5:

        tmp = gen_mulu_i64_i32(a, b);

        tcg_gen_mov_i64(dest, tmp);

        break;

    default: abort();

    }

    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.

       Don't forget to clean them now.  */

    if (size < 2) {

        tcg_temp_free_i32(a);

        tcg_temp_free_i32(b);

    }

}


void mips_malta_init (ram_addr_t ram_size,

                      const char *boot_device,

                      const char *kernel_filename, const char *kernel_cmdline,

                      const char *initrd_filename, const char *cpu_model)

{

    char *filename;

    ram_addr_t ram_offset;

    ram_addr_t bios_offset;

    target_long bios_size;

    int64_t kernel_entry;

    PCIBus *pci_bus;

    ISADevice *isa_dev;

    CPUState *env;

    RTCState *rtc_state;

    fdctrl_t *floppy_controller;

    MaltaFPGAState *malta_fpga;

    qemu_irq *i8259;

    int piix4_devfn;

    uint8_t *eeprom_buf;

    i2c_bus *smbus;

    int i;

    DriveInfo *dinfo;

    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];

    DriveInfo *fd[MAX_FD];

    int fl_idx = 0;

    int fl_sectors = 0;

    /* Make sure the first 3 serial ports are associated with a device. */

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

        if (!serial_hds[i]) {

            char label[32];

            snprintf(label, sizeof(label), "serial%d", i);

            serial_hds[i] = qemu_chr_open(label, "null", NULL);

        }

    }

    /* init CPUs */

    if (cpu_model == NULL) {

#ifdef TARGET_MIPS64

        cpu_model = "20Kc";

#else

        cpu_model = "24Kf";

#endif

    }

    env = cpu_init(cpu_model);

    if (!env) {

        fprintf(stderr, "Unable to find CPU definition\n");

        exit(1);

    }

    qemu_register_reset(main_cpu_reset, env);

    /* allocate RAM */

    if (ram_size > (256 << 20)) {

        fprintf(stderr,

                "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n",

                ((unsigned int)ram_size / (1 << 20)));

        exit(1);

    }

    ram_offset = qemu_ram_alloc(ram_size);

    bios_offset = qemu_ram_alloc(BIOS_SIZE);

    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);

    /* Map the bios at two physical locations, as on the real board. */

    cpu_register_physical_memory(0x1e000000LL,

                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);

    cpu_register_physical_memory(0x1fc00000LL,

                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);

    /* FPGA */

    malta_fpga = malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);

    /* Load firmware in flash / BIOS unless we boot directly into a kernel. */

    if (kernel_filename) {

        /* Write a small bootloader to the flash location. */

        loaderparams.ram_size = ram_size;

        loaderparams.kernel_filename = kernel_filename;

        loaderparams.kernel_cmdline = kernel_cmdline;

        loaderparams.initrd_filename = initrd_filename;

        kernel_entry = load_kernel(env);

        env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));

        write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry);

    } else {

        dinfo = drive_get(IF_PFLASH, 0, fl_idx);

        if (dinfo) {

            /* Load firmware from flash. */

            bios_size = 0x400000;

            fl_sectors = bios_size >> 16;

#ifdef DEBUG_BOARD_INIT

            printf("Register parallel flash %d size " TARGET_FMT_lx " at "

                   "offset %08lx addr %08llx '%s' %x\n",

                   fl_idx, bios_size, bios_offset, 0x1e000000LL,

                   bdrv_get_device_name(dinfo->bdrv), fl_sectors);

#endif

            pflash_cfi01_register(0x1e000000LL, bios_offset,

                                  dinfo->bdrv, 65536, fl_sectors,

                                  4, 0x0000, 0x0000, 0x0000, 0x0000);

            fl_idx++;

        } else {

            /* Load a BIOS image. */

            if (bios_name == NULL)

                bios_name = BIOS_FILENAME;

            filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

            if (filename) {

                bios_size = load_image_targphys(filename, 0x1fc00000LL,

                                                BIOS_SIZE);

                qemu_free(filename);

            } else {

                bios_size = -1;

            }

            if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {

                fprintf(stderr,

                        "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n",

                        bios_name);

                exit(1);

            }

        }

        /* In little endian mode the 32bit words in the bios are swapped,

           a neat trick which allows bi-endian firmware. */

#ifndef TARGET_WORDS_BIGENDIAN

        {

            uint32_t *addr = qemu_get_ram_ptr(bios_offset);;

            uint32_t *end = addr + bios_size;

            while (addr < end) {

                bswap32s(addr);

            }

        }

#endif

    }

    /* Board ID = 0x420 (Malta Board with CoreLV)

       XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should

       map to the board ID. */

    stl_phys(0x1fc00010LL, 0x00000420);

    /* Init internal devices */

    cpu_mips_irq_init_cpu(env);

    cpu_mips_clock_init(env);

    /* Interrupt controller */

    /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */

    i8259 = i8259_init(env->irq[2]);

    /* Northbridge */

    pci_bus = pci_gt64120_init(i8259);

    /* Southbridge */

    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {

        fprintf(stderr, "qemu: too many IDE bus\n");

        exit(1);

    }

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

        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);

    }

    piix4_devfn = piix4_init(pci_bus, 80);

    isa_bus_irqs(i8259);

    pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);

    usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);

    smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_reserve_irq(9));

    eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */

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

        /* TODO: Populate SPD eeprom data.  */

        DeviceState *eeprom;

        eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");

        qdev_prop_set_uint8(eeprom, "address", 0x50 + i);

        qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));

        qdev_init(eeprom);

    }

    pit = pit_init(0x40, isa_reserve_irq(0));

    DMA_init(0);

    /* Super I/O */

    isa_dev = isa_create_simple("i8042");

    rtc_state = rtc_init(2000);

    serial_isa_init(0, serial_hds[0]);

    serial_isa_init(1, serial_hds[1]);

    if (parallel_hds[0])

        parallel_init(0, parallel_hds[0]);

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

        fd[i] = drive_get(IF_FLOPPY, 0, i);

    }

    floppy_controller = fdctrl_init_isa(fd);

    /* Sound card */

#ifdef HAS_AUDIO

    audio_init(pci_bus);

#endif

    /* Network card */

    network_init();

    /* Optional PCI video card */

    if (cirrus_vga_enabled) {

        pci_cirrus_vga_init(pci_bus);

    } else if (vmsvga_enabled) {

        pci_vmsvga_init(pci_bus);

    } else if (std_vga_enabled) {

        pci_vga_init(pci_bus, 0, 0);

    }

}


void HELPER(set_cp15)(CPUState *env, uint32_t insn, uint32_t val)

{

    int op1;

    int op2;

    int crm;

    op1 = (insn >> 21) & 7;

    op2 = (insn >> 5) & 7;

    crm = insn & 0xf;

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

    case 0:

        /* ID codes.  */

        if (arm_feature(env, ARM_FEATURE_XSCALE))

            break;

        if (arm_feature(env, ARM_FEATURE_OMAPCP))

            break;

        if (arm_feature(env, ARM_FEATURE_V7)

                && op1 == 2 && crm == 0 && op2 == 0) {

            env->cp15.c0_cssel = val & 0xf;

            break;

        }

        goto bad_reg;

    case 1: /* System configuration.  */

        if (arm_feature(env, ARM_FEATURE_V7)

                && op1 == 0 && crm == 1 && op2 == 0) {

            env->cp15.c1_scr = val;

            break;

        }

        if (arm_feature(env, ARM_FEATURE_OMAPCP))

            op2 = 0;

        switch (op2) {

        case 0:

            if (!arm_feature(env, ARM_FEATURE_XSCALE) || crm == 0)

                env->cp15.c1_sys = val;

            /* ??? Lots of these bits are not implemented.  */

            /* This may enable/disable the MMU, so do a TLB flush.  */

            tlb_flush(env, 1);

            break;

        case 1: /* Auxiliary control register.  */

            if (arm_feature(env, ARM_FEATURE_XSCALE)) {

                env->cp15.c1_xscaleauxcr = val;

                break;

            }

            /* Not implemented.  */

            break;

        case 2:

            if (arm_feature(env, ARM_FEATURE_XSCALE))

                goto bad_reg;

            if (env->cp15.c1_coproc != val) {

                env->cp15.c1_coproc = val;

                /* ??? Is this safe when called from within a TB?  */

                tb_flush(env);

            }

            break;

        default:

            goto bad_reg;

        }

        break;

    case 2: /* MMU Page table control / MPU cache control.  */

        if (arm_feature(env, ARM_FEATURE_MPU)) {

            switch (op2) {

            case 0:

                env->cp15.c2_data = val;

                break;

            case 1:

                env->cp15.c2_insn = val;

                break;

            default:

                goto bad_reg;

            }

        } else {

	    switch (op2) {

	    case 0:

		env->cp15.c2_base0 = val;

		break;

	    case 1:

		env->cp15.c2_base1 = val;

		break;

	    case 2:

                val &= 7;

                env->cp15.c2_control = val;

		env->cp15.c2_mask = ~(((uint32_t)0xffffffffu) >> val);

                env->cp15.c2_base_mask = ~((uint32_t)0x3fffu >> val);

		break;

	    default:

		goto bad_reg;

	    }

        }

        break;

    case 3: /* MMU Domain access control / MPU write buffer control.  */

        env->cp15.c3 = val;

        tlb_flush(env, 1); /* Flush TLB as domain not tracked in TLB */

        break;

    case 4: /* Reserved.  */

        goto bad_reg;

    case 5: /* MMU Fault status / MPU access permission.  */

        if (arm_feature(env, ARM_FEATURE_OMAPCP))

            op2 = 0;

        switch (op2) {

        case 0:

            if (arm_feature(env, ARM_FEATURE_MPU))

                val = extended_mpu_ap_bits(val);

            env->cp15.c5_data = val;

            break;

        case 1:

            if (arm_feature(env, ARM_FEATURE_MPU))

                val = extended_mpu_ap_bits(val);

            env->cp15.c5_insn = val;

            break;

        case 2:

            if (!arm_feature(env, ARM_FEATURE_MPU))

                goto bad_reg;

            env->cp15.c5_data = val;

            break;

        case 3:

            if (!arm_feature(env, ARM_FEATURE_MPU))

                goto bad_reg;

            env->cp15.c5_insn = val;

            break;

        default:

            goto bad_reg;

        }

        break;

    case 6: /* MMU Fault address / MPU base/size.  */

        if (arm_feature(env, ARM_FEATURE_MPU)) {

            if (crm >= 8)

                goto bad_reg;

            env->cp15.c6_region[crm] = val;

        } else {

            if (arm_feature(env, ARM_FEATURE_OMAPCP))

                op2 = 0;

            switch (op2) {

            case 0:

                env->cp15.c6_data = val;

                break;

            case 1: /* ??? This is WFAR on armv6 */

            case 2:

                env->cp15.c6_insn = val;

                break;

            default:

                goto bad_reg;

            }

        }

        break;

    case 7: /* Cache control.  */

        env->cp15.c15_i_max = 0x000;

        env->cp15.c15_i_min = 0xff0;

        if (op1 != 0) {

            goto bad_reg;

        }

        /* No cache, so nothing to do except VA->PA translations. */

        if (arm_feature(env, ARM_FEATURE_VAPA)) {

            switch (crm) {

            case 4:

                if (arm_feature(env, ARM_FEATURE_V7)) {

                    env->cp15.c7_par = val & 0xfffff6ff;

                } else {

                    env->cp15.c7_par = val & 0xfffff1ff;

                }

                break;

            case 8: {

                uint32_t phys_addr;

                target_ulong page_size;

                int prot;

                int ret, is_user = op2 & 2;

                int access_type = op2 & 1;

                if (op2 & 4) {

                    /* Other states are only available with TrustZone */

                    goto bad_reg;

                }

                ret = get_phys_addr(env, val, access_type, is_user,

                                    &phys_addr, &prot, &page_size);

                if (ret == 0) {

                    /* We do not set any attribute bits in the PAR */

                    if (page_size == (1 << 24)

                        && arm_feature(env, ARM_FEATURE_V7)) {

                        env->cp15.c7_par = (phys_addr & 0xff000000) | 1 << 1;

                    } else {

                        env->cp15.c7_par = phys_addr & 0xfffff000;

                    }

                } else {

                    env->cp15.c7_par = ((ret & (10 << 1)) >> 5) |

                                       ((ret & (12 << 1)) >> 6) |

                                       ((ret & 0xf) << 1) | 1;

                }

                break;

            }

            }

        }

        break;

    case 8: /* MMU TLB control.  */

        switch (op2) {

        case 0: /* Invalidate all.  */

            tlb_flush(env, 0);

            break;

        case 1: /* Invalidate single TLB entry.  */

            tlb_flush_page(env, val & TARGET_PAGE_MASK);

            break;

        case 2: /* Invalidate on ASID.  */

            tlb_flush(env, val == 0);

            break;

        case 3: /* Invalidate single entry on MVA.  */

            /* ??? This is like case 1, but ignores ASID.  */

            tlb_flush(env, 1);

            break;

        default:

            goto bad_reg;

        }

        break;

    case 9:

        if (arm_feature(env, ARM_FEATURE_OMAPCP))

            break;

        if (arm_feature(env, ARM_FEATURE_STRONGARM))

            break; /* Ignore ReadBuffer access */

        switch (crm) {

        case 0: /* Cache lockdown.  */

	    switch (op1) {

	    case 0: /* L1 cache.  */

		switch (op2) {

		case 0:

		    env->cp15.c9_data = val;

		    break;

		case 1:

		    env->cp15.c9_insn = val;

		    break;

		default:

		    goto bad_reg;

		}

		break;

	    case 1: /* L2 cache.  */

		/* Ignore writes to L2 lockdown/auxiliary registers.  */

		break;

	    default:

		goto bad_reg;

	    }

	    break;

        case 1: /* TCM memory region registers.  */

            /* Not implemented.  */

            goto bad_reg;

        case 12: /* Performance monitor control */

            /* Performance monitors are implementation defined in v7,

             * but with an ARM recommended set of registers, which we

             * follow (although we don't actually implement any counters)

             */

            if (!arm_feature(env, ARM_FEATURE_V7)) {

                goto bad_reg;

            }

            switch (op2) {

            case 0: /* performance monitor control register */

                /* only the DP, X, D and E bits are writable */

                env->cp15.c9_pmcr &= ~0x39;

                env->cp15.c9_pmcr |= (val & 0x39);

                break;

            case 1: /* Count enable set register */

                val &= (1 << 31);

                env->cp15.c9_pmcnten |= val;

                break;

            case 2: /* Count enable clear */

                val &= (1 << 31);

                env->cp15.c9_pmcnten &= ~val;

                break;

            case 3: /* Overflow flag status */

                env->cp15.c9_pmovsr &= ~val;

                break;

            case 4: /* Software increment */

                /* RAZ/WI since we don't implement the software-count event */

                break;

            case 5: /* Event counter selection register */

                /* Since we don't implement any events, writing to this register

                 * is actually UNPREDICTABLE. So we choose to RAZ/WI.

                 */

                break;

            default:

                goto bad_reg;

            }

            break;

        case 13: /* Performance counters */

            if (!arm_feature(env, ARM_FEATURE_V7)) {

                goto bad_reg;

            }

            switch (op2) {

            case 0: /* Cycle count register: not implemented, so RAZ/WI */

                break;

            case 1: /* Event type select */

                env->cp15.c9_pmxevtyper = val & 0xff;

                break;

            case 2: /* Event count register */

                /* Unimplemented (we have no events), RAZ/WI */

                break;

            default:

                goto bad_reg;

            }

            break;

        case 14: /* Performance monitor control */

            if (!arm_feature(env, ARM_FEATURE_V7)) {

                goto bad_reg;

            }

            switch (op2) {

            case 0: /* user enable */

                env->cp15.c9_pmuserenr = val & 1;

                /* changes access rights for cp registers, so flush tbs */

                tb_flush(env);

                break;

            case 1: /* interrupt enable set */

                /* We have no event counters so only the C bit can be changed */

                val &= (1 << 31);

                env->cp15.c9_pminten |= val;

                break;

            case 2: /* interrupt enable clear */

                val &= (1 << 31);

                env->cp15.c9_pminten &= ~val;

                break;

            }

            break;

        default:

            goto bad_reg;

        }

        break;

    case 10: /* MMU TLB lockdown.  */

        /* ??? TLB lockdown not implemented.  */

        break;

    case 12: /* Reserved.  */

        goto bad_reg;

    case 13: /* Process ID.  */

        switch (op2) {

        case 0:

            /* Unlike real hardware the qemu TLB uses virtual addresses,

               not modified virtual addresses, so this causes a TLB flush.

             */

            if (env->cp15.c13_fcse != val)

              tlb_flush(env, 1);

            env->cp15.c13_fcse = val;

            break;

        case 1:

            /* This changes the ASID, so do a TLB flush.  */

            if (env->cp15.c13_context != val

                && !arm_feature(env, ARM_FEATURE_MPU))

              tlb_flush(env, 0);

            env->cp15.c13_context = val;

            break;

        default:

            goto bad_reg;

        }

        break;

    case 14: /* Reserved.  */

        goto bad_reg;

    case 15: /* Implementation specific.  */

        if (arm_feature(env, ARM_FEATURE_XSCALE)) {

            if (op2 == 0 && crm == 1) {

                if (env->cp15.c15_cpar != (val & 0x3fff)) {

                    /* Changes cp0 to cp13 behavior, so needs a TB flush.  */

                    tb_flush(env);

                    env->cp15.c15_cpar = val & 0x3fff;

                }

                break;

            }

            goto bad_reg;

        }

        if (arm_feature(env, ARM_FEATURE_OMAPCP)) {

            switch (crm) {

            case 0:

                break;

            case 1: /* Set TI925T configuration.  */

                env->cp15.c15_ticonfig = val & 0xe7;

                env->cp15.c0_cpuid = (val & (1 << 5)) ? /* OS_TYPE bit */

                        ARM_CPUID_TI915T : ARM_CPUID_TI925T;

                break;

            case 2: /* Set I_max.  */

                env->cp15.c15_i_max = val;

                break;

            case 3: /* Set I_min.  */

                env->cp15.c15_i_min = val;

                break;

            case 4: /* Set thread-ID.  */

                env->cp15.c15_threadid = val & 0xffff;

                break;

            case 8: /* Wait-for-interrupt (deprecated).  */

                cpu_interrupt(env, CPU_INTERRUPT_HALT);

                break;

            default:

                goto bad_reg;

            }

        }

        if (ARM_CPUID(env) == ARM_CPUID_CORTEXA9) {

            switch (crm) {

            case 0:

                if ((op1 == 0) && (op2 == 0)) {

                    env->cp15.c15_power_control = val;

                } else if ((op1 == 0) && (op2 == 1)) {

                    env->cp15.c15_diagnostic = val;

                } else if ((op1 == 0) && (op2 == 2)) {

                    env->cp15.c15_power_diagnostic = val;

                }

            default:

                break;

            }

        }

        break;

    }

    return;

bad_reg:

    /* ??? For debugging only.  Should raise illegal instruction exception.  */

    cpu_abort(env, "Unimplemented cp15 register write (c%d, c%d, {%d, %d})\n",

              (insn >> 16) & 0xf, crm, op1, op2);

}


S390CPU *s390x_new_cpu(const char *typename, uint32_t core_id, Error **errp)

{

    S390CPU *cpu = S390_CPU(object_new(typename));

    Error *err = NULL;

    object_property_set_int(OBJECT(cpu), core_id, "core-id", &err);

    if (err != NULL) {

        goto out;

    }

    object_property_set_bool(OBJECT(cpu), true, "realized", &err);

out:

    if (err) {

        error_propagate(errp, err);

        object_unref(OBJECT(cpu));

        cpu = NULL;

    }

    return cpu;

}


static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)

{

    switch (mmu_idx) {

    case ARMMMUIdx_S1SE0:

    case ARMMMUIdx_S1NSE0:

        return true;

    default:

        return false;

    case ARMMMUIdx_S12NSE0:

    case ARMMMUIdx_S12NSE1:

        g_assert_not_reached();

    }

}


int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w, uint8_t dst_color[4],

                            enum AVPixelFormat pix_fmt, uint8_t rgba_color[4],

                            int *is_packed_rgba, uint8_t rgba_map_ptr[4])

{

    uint8_t rgba_map[4] = {0};

    int i;

    const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(pix_fmt);

    int hsub = pix_desc->log2_chroma_w;

    *is_packed_rgba = ff_fill_rgba_map(rgba_map, pix_fmt) >= 0;

    if (*is_packed_rgba) {

        pixel_step[0] = (av_get_bits_per_pixel(pix_desc))>>3;

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

            dst_color[rgba_map[i]] = rgba_color[i];

        line[0] = av_malloc_array(w, pixel_step[0]);

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

            memcpy(line[0] + i * pixel_step[0], dst_color, pixel_step[0]);

        if (rgba_map_ptr)

            memcpy(rgba_map_ptr, rgba_map, sizeof(rgba_map[0]) * 4);

    } else {

        int plane;

        dst_color[0] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]);

        dst_color[1] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);

        dst_color[2] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);

        dst_color[3] = rgba_color[3];

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

            int line_size;

            int hsub1 = (plane == 1 || plane == 2) ? hsub : 0;

            pixel_step[plane] = 1;

            line_size = FF_CEIL_RSHIFT(w, hsub1) * pixel_step[plane];

            line[plane] = av_malloc(line_size);

            if (!line[plane]) {

                while(plane && line[plane-1])

                    av_freep(&line[--plane]);

            }

            memset(line[plane], dst_color[plane], line_size);

        }

    }

    return 0;

}


static int bfi_decode_frame(AVCodecContext * avctx, void *data,

                            int *data_size, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    BFIContext *bfi = avctx->priv_data;

    uint8_t *dst = bfi->dst;

    uint8_t *src, *dst_offset, colour1, colour2;

    uint8_t *frame_end = bfi->dst + avctx->width * avctx->height;

    uint32_t *pal;

    int i, j, height = avctx->height;

    if (bfi->frame.data[0])

        avctx->release_buffer(avctx, &bfi->frame);

    bfi->frame.reference = 1;

    if (avctx->get_buffer(avctx, &bfi->frame) < 0) {

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

        return -1;

    }

    /* Set frame parameters and palette, if necessary */

    if (!avctx->frame_number) {

        bfi->frame.pict_type = FF_I_TYPE;

        bfi->frame.key_frame = 1;

        /* Setting the palette */

        if(avctx->extradata_size>768) {

            av_log(NULL, AV_LOG_ERROR, "Palette is too large.\n");

            return -1;

        }

        pal = (uint32_t *) bfi->frame.data[1];

        for (i = 0; i < avctx->extradata_size / 3; i++) {

            int shift = 16;

            *pal = 0;

            for (j = 0; j < 3; j++, shift -= 8)

                *pal +=

                    ((avctx->extradata[i * 3 + j] << 2) |

                    (avctx->extradata[i * 3 + j] >> 4)) << shift;

            pal++;

        }

        bfi->frame.palette_has_changed = 1;

    } else {

        bfi->frame.pict_type = FF_P_TYPE;

        bfi->frame.key_frame = 0;

    }

    buf += 4; //Unpacked size, not required.

    while (dst != frame_end) {

        static const uint8_t lentab[4]={0,2,0,1};

        unsigned int byte = *buf++, av_uninit(offset);

        unsigned int code = byte >> 6;

        unsigned int length = byte & ~0xC0;

        /* Get length and offset(if required) */

        if (length == 0) {

            if (code == 1) {

                length = bytestream_get_byte(&buf);

                offset = bytestream_get_le16(&buf);

            } else {

                length = bytestream_get_le16(&buf);

                if (code == 2 && length == 0)

                    break;

            }

        } else {

            if (code == 1)

                offset = bytestream_get_byte(&buf);

        }

        /* Do boundary check */

        if (dst + (length<<lentab[code]) > frame_end)

            break;

        switch (code) {

        case 0:                //Normal Chain

            bytestream_get_buffer(&buf, dst, length);

            dst += length;

            break;

        case 1:                //Back Chain

            dst_offset = dst - offset;

            length *= 4;        //Convert dwords to bytes.

            if (dst_offset < bfi->dst)

                break;

            while (length--)

                *dst++ = *dst_offset++;

            break;

        case 2:                //Skip Chain

            dst += length;

            break;

        case 3:                //Fill Chain

            colour1 = bytestream_get_byte(&buf);

            colour2 = bytestream_get_byte(&buf);

            while (length--) {

                *dst++ = colour1;

                *dst++ = colour2;

            }

            break;

        }

    }

    src = bfi->dst;

    dst = bfi->frame.data[0];

    while (height--) {

        memcpy(dst, src, avctx->width);

        src += avctx->width;

        dst += bfi->frame.linesize[0];

    }

    *data_size = sizeof(AVFrame);

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

    return buf_size;

}


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

{

    DeviceClass *k = DEVICE_CLASS(klass);

    k->init = sysbus_device_init;

    k->bus_type = TYPE_SYSTEM_BUS;

}


static av_cold int g726_init(AVCodecContext * avctx)

{

    G726Context* c = avctx->priv_data;

    unsigned int index= (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate - 2;

    if (avctx->bit_rate % avctx->sample_rate && avctx->codec->encode) {

        av_log(avctx, AV_LOG_ERROR, "Bitrate - Samplerate combination is invalid\n");

        return -1;

    }

    if(avctx->channels != 1){

        av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");

        return -1;

    }

    if(index>3){

        av_log(avctx, AV_LOG_ERROR, "Unsupported number of bits %d\n", index+2);

        return -1;

    }

    g726_reset(c, index);

    c->code_size = index+2;

    avctx->coded_frame = avcodec_alloc_frame();

    if (!avctx->coded_frame)

        return AVERROR(ENOMEM);

    avctx->coded_frame->key_frame = 1;

    if (avctx->codec->decode)

        avctx->sample_fmt = SAMPLE_FMT_S16;

    return 0;

}


static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,

                            AVPacket *avpkt)

{

    YopDecContext *s = avctx->priv_data;

    int tag, firstcolor, is_odd_frame;

    int ret, i, x, y;

    uint32_t *palette;

    if (s->frame.data[0])

        avctx->release_buffer(avctx, &s->frame);

    ret = ff_get_buffer(avctx, &s->frame);

    if (ret < 0) {

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

        return ret;

    }

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

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

    s->srcptr     = avpkt->data + 4;

    s->low_nibble = NULL;

    is_odd_frame = avpkt->data[0];

    firstcolor   = s->first_color[is_odd_frame];

    palette      = (uint32_t *)s->frame.data[1];

    for (i = 0; i < s->num_pal_colors; i++, s->srcptr += 3)

        palette[i + firstcolor] = (s->srcptr[0] << 18) |

                                  (s->srcptr[1] << 10) |

                                  (s->srcptr[2] << 2);

    s->frame.palette_has_changed = 1;

    for (y = 0; y < avctx->height; y += 2) {

        for (x = 0; x < avctx->width; x += 2) {

            if (s->srcptr - avpkt->data >= avpkt->size) {

                av_log(avctx, AV_LOG_ERROR, "Packet too small.\n");

                return AVERROR_INVALIDDATA;

            }

            tag = yop_get_next_nibble(s);

            if (tag != 0xf) {

                yop_paint_block(s, tag);

            } else {

                tag = yop_get_next_nibble(s);

                ret = yop_copy_previous_block(s, tag);

                if (ret < 0) {

                    avctx->release_buffer(avctx, &s->frame);

                    return ret;

                }

            }

            s->dstptr += 2;

        }

        s->dstptr += 2*s->frame.linesize[0] - x;

    }

    *got_frame = 1;

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

    return avpkt->size;

}


static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,

                                 uint8_t *buf, int lun)

{

    SCSIDeviceState *s = d->state;

    uint64_t nb_sectors;

    uint32_t lba;

    uint32_t len;

    int cmdlen;

    int is_write;

    uint8_t command;

    uint8_t *outbuf;

    SCSIRequest *r;

    command = buf[0];

    r = scsi_find_request(s, tag);

    if (r) {

        BADF("Tag 0x%x already in use\n", tag);

        scsi_cancel_io(d, tag);

    }

    /* ??? Tags are not unique for different luns.  We only implement a

       single lun, so this should not matter.  */

    r = scsi_new_request(s, tag);

    outbuf = r->dma_buf;

    is_write = 0;

    DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);

    switch (command >> 5) {

    case 0:

        lba = buf[3] | (buf[2] << 8) | ((buf[1] & 0x1f) << 16);

        len = buf[4];

        cmdlen = 6;

        break;

    case 1:

    case 2:

        lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);

        len = buf[8] | (buf[7] << 8);

        cmdlen = 10;

        break;

    case 4:

        lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);

        len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);

        cmdlen = 16;

        break;

    case 5:

        lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);

        len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);

        cmdlen = 12;

        break;

    default:

        BADF("Unsupported command length, command %x\n", command);

        goto fail;

    }

#ifdef DEBUG_SCSI

    {

        int i;

        for (i = 1; i < cmdlen; i++) {

            printf(" 0x%02x", buf[i]);

        }

        printf("\n");

    }

#endif

    if (lun || buf[1] >> 5) {

        /* Only LUN 0 supported.  */

        DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);

        if (command != 0x03 && command != 0x12) /* REQUEST SENSE and INQUIRY */

            goto fail;

    }

    switch (command) {

    case 0x0:

	DPRINTF("Test Unit Ready\n");

	break;

    case 0x03:

        DPRINTF("Request Sense (len %d)\n", len);

        if (len < 4)

            goto fail;

        memset(outbuf, 0, 4);

        outbuf[0] = 0xf0;

        outbuf[1] = 0;

        outbuf[2] = s->sense;

        r->buf_len = 4;

        break;

    case 0x12:

        DPRINTF("Inquiry (len %d)\n", len);

        if (buf[1] & 0x2) {

            /* Command support data - optional, not implemented */

            BADF("optional INQUIRY command support request not implemented\n");

            goto fail;

        }

        else if (buf[1] & 0x1) {

            /* Vital product data */

            uint8_t page_code = buf[2];

            if (len < 4) {

                BADF("Error: Inquiry (EVPD[%02X]) buffer size %d is "

                     "less than 4\n", page_code, len);

                goto fail;

            }

            switch (page_code) {

                case 0x00:

                    {

                        /* Supported page codes, mandatory */

                        DPRINTF("Inquiry EVPD[Supported pages] "

                                "buffer size %d\n", len);

                        r->buf_len = 0;

                        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {

                            outbuf[r->buf_len++] = 5;

                        } else {

                            outbuf[r->buf_len++] = 0;

                        }

                        outbuf[r->buf_len++] = 0x00; // this page

                        outbuf[r->buf_len++] = 0x00;

                        outbuf[r->buf_len++] = 3;    // number of pages

                        outbuf[r->buf_len++] = 0x00; // list of supported pages (this page)

                        outbuf[r->buf_len++] = 0x80; // unit serial number

                        outbuf[r->buf_len++] = 0x83; // device identification

                    }

                    break;

                case 0x80:

                    {

                        /* Device serial number, optional */

                        if (len < 4) {

                            BADF("Error: EVPD[Serial number] Inquiry buffer "

                                 "size %d too small, %d needed\n", len, 4);

                            goto fail;

                        }

                        DPRINTF("Inquiry EVPD[Serial number] buffer size %d\n", len);

                        r->buf_len = 0;

                        /* Supported page codes */

                        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {

                            outbuf[r->buf_len++] = 5;

                        } else {

                            outbuf[r->buf_len++] = 0;

                        }

                        outbuf[r->buf_len++] = 0x80; // this page

                        outbuf[r->buf_len++] = 0x00;

                        outbuf[r->buf_len++] = 0x01; // 1 byte data follow

                        outbuf[r->buf_len++] = '0';  // 1 byte data follow

                    }

                    break;

                case 0x83:

                    {

                        /* Device identification page, mandatory */

                        int max_len = 255 - 8;

                        int id_len = strlen(bdrv_get_device_name(s->bdrv));

                        if (id_len > max_len)

                            id_len = max_len;

                        DPRINTF("Inquiry EVPD[Device identification] "

                                "buffer size %d\n", len);

                        r->buf_len = 0;

                        if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {

                            outbuf[r->buf_len++] = 5;

                        } else {

                            outbuf[r->buf_len++] = 0;

                        }

                        outbuf[r->buf_len++] = 0x83; // this page

                        outbuf[r->buf_len++] = 0x00;

                        outbuf[r->buf_len++] = 3 + id_len;

                        outbuf[r->buf_len++] = 0x2; // ASCII

                        outbuf[r->buf_len++] = 0;   // not officially assigned

                        outbuf[r->buf_len++] = 0;   // reserved

                        outbuf[r->buf_len++] = id_len; // length of data following

                        memcpy(&outbuf[r->buf_len],

                               bdrv_get_device_name(s->bdrv), id_len);

                        r->buf_len += id_len;

                    }

                    break;

                default:

                    BADF("Error: unsupported Inquiry (EVPD[%02X]) "

                         "buffer size %d\n", page_code, len);

                    goto fail;

            }

            /* done with EVPD */

            break;

        }

        else {

            /* Standard INQUIRY data */

            if (buf[2] != 0) {

                BADF("Error: Inquiry (STANDARD) page or code "

                     "is non-zero [%02X]\n", buf[2]);

                goto fail;

            }

            /* PAGE CODE == 0 */

            if (len < 5) {

                BADF("Error: Inquiry (STANDARD) buffer size %d "

                     "is less than 5\n", len);

                goto fail;

            }

            if (len < 36) {

                BADF("Error: Inquiry (STANDARD) buffer size %d "

                     "is less than 36 (TODO: only 5 required)\n", len);

            }

        }

	memset(outbuf, 0, 36);

        if (lun || buf[1] >> 5) {

            outbuf[0] = 0x7f;	/* LUN not supported */

	} else if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {

	    outbuf[0] = 5;

            outbuf[1] = 0x80;

	    memcpy(&outbuf[16], "QEMU CD-ROM    ", 16);

	} else {

	    outbuf[0] = 0;

	    memcpy(&outbuf[16], "QEMU HARDDISK  ", 16);

	}

	memcpy(&outbuf[8], "QEMU   ", 8);

        memcpy(&outbuf[32], QEMU_VERSION, 4);

        /* Identify device as SCSI-3 rev 1.

           Some later commands are also implemented. */

	outbuf[2] = 3;

	outbuf[3] = 2; /* Format 2 */

	outbuf[4] = 31;

        /* Sync data transfer and TCQ.  */

        outbuf[7] = 0x10 | (s->tcq ? 0x02 : 0);

	r->buf_len = 36;

	break;

    case 0x16:

        DPRINTF("Reserve(6)\n");

        if (buf[1] & 1)

            goto fail;

        break;

    case 0x17:

        DPRINTF("Release(6)\n");

        if (buf[1] & 1)

            goto fail;

        break;

    case 0x1a:

    case 0x5a:

        {

            uint8_t *p;

            int page;

            page = buf[2] & 0x3f;

            DPRINTF("Mode Sense (page %d, len %d)\n", page, len);

            p = outbuf;

            memset(p, 0, 4);

            outbuf[1] = 0; /* Default media type.  */

            outbuf[3] = 0; /* Block descriptor length.  */

            if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {

                outbuf[2] = 0x80; /* Readonly.  */

            }

            p += 4;

            if (page == 4) {

                int cylinders, heads, secs;

                /* Rigid disk device geometry page. */

                p[0] = 4;

                p[1] = 0x16;

                /* if a geometry hint is available, use it */

                bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);

                p[2] = (cylinders >> 16) & 0xff;

                p[3] = (cylinders >> 8) & 0xff;

                p[4] = cylinders & 0xff;

                p[5] = heads & 0xff;

                /* Write precomp start cylinder, disabled */

                p[6] = (cylinders >> 16) & 0xff;

                p[7] = (cylinders >> 8) & 0xff;

                p[8] = cylinders & 0xff;

                /* Reduced current start cylinder, disabled */

                p[9] = (cylinders >> 16) & 0xff;

                p[10] = (cylinders >> 8) & 0xff;

                p[11] = cylinders & 0xff;

                /* Device step rate [ns], 200ns */

                p[12] = 0;

                p[13] = 200;

                /* Landing zone cylinder */

                p[14] = 0xff;

                p[15] =  0xff;

                p[16] = 0xff;

                /* Medium rotation rate [rpm], 5400 rpm */

                p[20] = (5400 >> 8) & 0xff;

                p[21] = 5400 & 0xff;

                p += 0x16;

            } else if (page == 5) {

                int cylinders, heads, secs;

                /* Flexible disk device geometry page. */

                p[0] = 5;

                p[1] = 0x1e;

                /* Transfer rate [kbit/s], 5Mbit/s */

                p[2] = 5000 >> 8;

                p[3] = 5000 & 0xff;

                /* if a geometry hint is available, use it */

                bdrv_get_geometry_hint(s->bdrv, &cylinders, &heads, &secs);

                p[4] = heads & 0xff;

                p[5] = secs & 0xff;

                p[6] = s->cluster_size * 2;

                p[8] = (cylinders >> 8) & 0xff;

                p[9] = cylinders & 0xff;

                /* Write precomp start cylinder, disabled */

                p[10] = (cylinders >> 8) & 0xff;

                p[11] = cylinders & 0xff;

                /* Reduced current start cylinder, disabled */

                p[12] = (cylinders >> 8) & 0xff;

                p[13] = cylinders & 0xff;

                /* Device step rate [100us], 100us */

                p[14] = 0;

                p[15] = 1;

                /* Device step pulse width [us], 1us */

                p[16] = 1;

                /* Device head settle delay [100us], 100us */

                p[17] = 0;

                p[18] = 1;

                /* Motor on delay [0.1s], 0.1s */

                p[19] = 1;

                /* Motor off delay [0.1s], 0.1s */

                p[20] = 1;

                /* Medium rotation rate [rpm], 5400 rpm */

                p[28] = (5400 >> 8) & 0xff;

                p[29] = 5400 & 0xff;

                p += 0x1e;

            } else if ((page == 8 || page == 0x3f)) {

                /* Caching page.  */

                memset(p,0,20);

                p[0] = 8;

                p[1] = 0x12;

                p[2] = 4; /* WCE */

                p += 20;

            }

            if ((page == 0x3f || page == 0x2a)

                    && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {

                /* CD Capabilities and Mechanical Status page. */

                p[0] = 0x2a;

                p[1] = 0x14;

                p[2] = 3; // CD-R & CD-RW read

                p[3] = 0; // Writing not supported

                p[4] = 0x7f; /* Audio, composite, digital out,

                                         mode 2 form 1&2, multi session */

                p[5] = 0xff; /* CD DA, DA accurate, RW supported,

                                         RW corrected, C2 errors, ISRC,

                                         UPC, Bar code */

                p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);

                /* Locking supported, jumper present, eject, tray */

                p[7] = 0; /* no volume & mute control, no

                                      changer */

                p[8] = (50 * 176) >> 8; // 50x read speed

                p[9] = (50 * 176) & 0xff;

                p[10] = 0 >> 8; // No volume

                p[11] = 0 & 0xff;

                p[12] = 2048 >> 8; // 2M buffer

                p[13] = 2048 & 0xff;

                p[14] = (16 * 176) >> 8; // 16x read speed current

                p[15] = (16 * 176) & 0xff;

                p[18] = (16 * 176) >> 8; // 16x write speed

                p[19] = (16 * 176) & 0xff;

                p[20] = (16 * 176) >> 8; // 16x write speed current

                p[21] = (16 * 176) & 0xff;

                p += 22;

            }

            r->buf_len = p - outbuf;

            outbuf[0] = r->buf_len - 4;

            if (r->buf_len > len)

                r->buf_len = len;

        }

        break;

    case 0x1b:

        DPRINTF("Start Stop Unit\n");

	break;

    case 0x1e:

        DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);

        bdrv_set_locked(s->bdrv, buf[4] & 1);

	break;

    case 0x25:

	DPRINTF("Read Capacity\n");

        /* The normal LEN field for this command is zero.  */

	memset(outbuf, 0, 8);

	bdrv_get_geometry(s->bdrv, &nb_sectors);

        /* Returned value is the address of the last sector.  */

        if (nb_sectors) {

            nb_sectors--;

            outbuf[0] = (nb_sectors >> 24) & 0xff;

            outbuf[1] = (nb_sectors >> 16) & 0xff;

            outbuf[2] = (nb_sectors >> 8) & 0xff;

            outbuf[3] = nb_sectors & 0xff;

            outbuf[4] = 0;

            outbuf[5] = 0;

            outbuf[6] = s->cluster_size * 2;

            outbuf[7] = 0;

            r->buf_len = 8;

        } else {

            scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY);

            return 0;

        }

	break;

    case 0x08:

    case 0x28:

        DPRINTF("Read (sector %d, count %d)\n", lba, len);

        r->sector = lba * s->cluster_size;

        r->sector_count = len * s->cluster_size;

        break;

    case 0x0a:

    case 0x2a:

        DPRINTF("Write (sector %d, count %d)\n", lba, len);

        r->sector = lba * s->cluster_size;

        r->sector_count = len * s->cluster_size;

        is_write = 1;

        break;

    case 0x35:

        DPRINTF("Synchronise cache (sector %d, count %d)\n", lba, len);

        bdrv_flush(s->bdrv);

        break;

    case 0x43:

        {

            int start_track, format, msf, toclen;

            msf = buf[1] & 2;

            format = buf[2] & 0xf;

            start_track = buf[6];

            bdrv_get_geometry(s->bdrv, &nb_sectors);

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

            switch(format) {

            case 0:

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

                break;

            case 1:

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

                toclen = 12;

                memset(outbuf, 0, 12);

                outbuf[1] = 0x0a;

                outbuf[2] = 0x01;

                outbuf[3] = 0x01;

                break;

            case 2:

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

                break;

            default:

                goto error_cmd;

            }

            if (toclen > 0) {

                if (len > toclen)

                  len = toclen;

                r->buf_len = len;

                break;

            }

        error_cmd:

            DPRINTF("Read TOC error\n");

            goto fail;

        }

    case 0x46:

        DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);

        memset(outbuf, 0, 8);

        /* ??? This should probably return much more information.  For now

           just return the basic header indicating the CD-ROM profile.  */

        outbuf[7] = 8; // CD-ROM

        r->buf_len = 8;

        break;

    case 0x56:

        DPRINTF("Reserve(10)\n");

        if (buf[1] & 3)

            goto fail;

        break;

    case 0x57:

        DPRINTF("Release(10)\n");

        if (buf[1] & 3)

            goto fail;

        break;

    case 0xa0:

        DPRINTF("Report LUNs (len %d)\n", len);

        if (len < 16)

            goto fail;

        memset(outbuf, 0, 16);

        outbuf[3] = 8;

        r->buf_len = 16;

        break;

    case 0x2f:

        DPRINTF("Verify (sector %d, count %d)\n", lba, len);

        break;

    default:

	DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);

    fail:

        scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_ILLEGAL_REQUEST);

	return 0;

    }

    if (r->sector_count == 0 && r->buf_len == 0) {

        scsi_command_complete(r, STATUS_GOOD, SENSE_NO_SENSE);

    }

    len = r->sector_count * 512 + r->buf_len;

    if (is_write) {

        return -len;

    } else {

        if (!r->sector_count)

            r->sector_count = -1;

        return len;

    }

}