uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)

{

    long tcg_temps[CPU_TEMP_BUF_NLONGS];

    uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);

    uintptr_t next_tb = 0;

    tci_reg[TCG_AREG0] = (tcg_target_ulong)env;

    tci_reg[TCG_REG_CALL_STACK] = sp_value;

    assert(tb_ptr);

    for (;;) {

        TCGOpcode opc = tb_ptr[0];

#if !defined(NDEBUG)

        uint8_t op_size = tb_ptr[1];

        uint8_t *old_code_ptr = tb_ptr;

#endif

        tcg_target_ulong t0;

        tcg_target_ulong t1;

        tcg_target_ulong t2;

        tcg_target_ulong label;

        TCGCond condition;

        target_ulong taddr;

#ifndef CONFIG_SOFTMMU

        tcg_target_ulong host_addr;

#endif

        uint8_t tmp8;

        uint16_t tmp16;

        uint32_t tmp32;

        uint64_t tmp64;

#if TCG_TARGET_REG_BITS == 32

        uint64_t v64;

#endif

#if defined(GETPC)

        tci_tb_ptr = (uintptr_t)tb_ptr;

#endif

        /* Skip opcode and size entry. */

        tb_ptr += 2;

        switch (opc) {

        case INDEX_op_end:

        case INDEX_op_nop:

            break;

        case INDEX_op_nop1:

        case INDEX_op_nop2:

        case INDEX_op_nop3:

        case INDEX_op_nopn:

        case INDEX_op_discard:

            TODO();

            break;

        case INDEX_op_set_label:

            TODO();

            break;

        case INDEX_op_call:

            t0 = tci_read_ri(&tb_ptr);

#if TCG_TARGET_REG_BITS == 32

            tmp64 = ((helper_function)t0)(tci_read_reg(TCG_REG_R0),

                                          tci_read_reg(TCG_REG_R1),

                                          tci_read_reg(TCG_REG_R2),

                                          tci_read_reg(TCG_REG_R3),

                                          tci_read_reg(TCG_REG_R5),

                                          tci_read_reg(TCG_REG_R6),

                                          tci_read_reg(TCG_REG_R7),

                                          tci_read_reg(TCG_REG_R8),

                                          tci_read_reg(TCG_REG_R9),

                                          tci_read_reg(TCG_REG_R10));

            tci_write_reg(TCG_REG_R0, tmp64);

            tci_write_reg(TCG_REG_R1, tmp64 >> 32);

#else

            tmp64 = ((helper_function)t0)(tci_read_reg(TCG_REG_R0),

                                          tci_read_reg(TCG_REG_R1),

                                          tci_read_reg(TCG_REG_R2),

                                          tci_read_reg(TCG_REG_R3),

                                          tci_read_reg(TCG_REG_R5));

            tci_write_reg(TCG_REG_R0, tmp64);

#endif

            break;

        case INDEX_op_br:

            label = tci_read_label(&tb_ptr);

            assert(tb_ptr == old_code_ptr + op_size);

            tb_ptr = (uint8_t *)label;

            continue;

        case INDEX_op_setcond_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            condition = *tb_ptr++;

            tci_write_reg32(t0, tci_compare32(t1, t2, condition));

            break;

#if TCG_TARGET_REG_BITS == 32

        case INDEX_op_setcond2_i32:

            t0 = *tb_ptr++;

            tmp64 = tci_read_r64(&tb_ptr);

            v64 = tci_read_ri64(&tb_ptr);

            condition = *tb_ptr++;

            tci_write_reg32(t0, tci_compare64(tmp64, v64, condition));

            break;

#elif TCG_TARGET_REG_BITS == 64

        case INDEX_op_setcond_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r64(&tb_ptr);

            t2 = tci_read_ri64(&tb_ptr);

            condition = *tb_ptr++;

            tci_write_reg64(t0, tci_compare64(t1, t2, condition));

            break;

#endif

        case INDEX_op_mov_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r32(&tb_ptr);

            tci_write_reg32(t0, t1);

            break;

        case INDEX_op_movi_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_i32(&tb_ptr);

            tci_write_reg32(t0, t1);

            break;

            /* Load/store operations (32 bit). */

        case INDEX_op_ld8u_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            tci_write_reg8(t0, *(uint8_t *)(t1 + t2));

            break;

        case INDEX_op_ld8s_i32:

        case INDEX_op_ld16u_i32:

            TODO();

            break;

        case INDEX_op_ld16s_i32:

            TODO();

            break;

        case INDEX_op_ld_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            tci_write_reg32(t0, *(uint32_t *)(t1 + t2));

            break;

        case INDEX_op_st8_i32:

            t0 = tci_read_r8(&tb_ptr);

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            *(uint8_t *)(t1 + t2) = t0;

            break;

        case INDEX_op_st16_i32:

            t0 = tci_read_r16(&tb_ptr);

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            *(uint16_t *)(t1 + t2) = t0;

            break;

        case INDEX_op_st_i32:

            t0 = tci_read_r32(&tb_ptr);

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            assert(t1 != sp_value || (int32_t)t2 < 0);

            *(uint32_t *)(t1 + t2) = t0;

            break;

            /* Arithmetic operations (32 bit). */

        case INDEX_op_add_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, t1 + t2);

            break;

        case INDEX_op_sub_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, t1 - t2);

            break;

        case INDEX_op_mul_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, t1 * t2);

            break;

#if TCG_TARGET_HAS_div_i32

        case INDEX_op_div_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, (int32_t)t1 / (int32_t)t2);

            break;

        case INDEX_op_divu_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, t1 / t2);

            break;

        case INDEX_op_rem_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, (int32_t)t1 % (int32_t)t2);

            break;

        case INDEX_op_remu_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, t1 % t2);

            break;

#elif TCG_TARGET_HAS_div2_i32

        case INDEX_op_div2_i32:

        case INDEX_op_divu2_i32:

            TODO();

            break;

#endif

        case INDEX_op_and_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, t1 & t2);

            break;

        case INDEX_op_or_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, t1 | t2);

            break;

        case INDEX_op_xor_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, t1 ^ t2);

            break;

            /* Shift/rotate operations (32 bit). */

        case INDEX_op_shl_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, t1 << t2);

            break;

        case INDEX_op_shr_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, t1 >> t2);

            break;

        case INDEX_op_sar_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, ((int32_t)t1 >> t2));

            break;

#if TCG_TARGET_HAS_rot_i32

        case INDEX_op_rotl_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, rol32(t1, t2));

            break;

        case INDEX_op_rotr_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_ri32(&tb_ptr);

            t2 = tci_read_ri32(&tb_ptr);

            tci_write_reg32(t0, ror32(t1, t2));

            break;

#endif

#if TCG_TARGET_HAS_deposit_i32

        case INDEX_op_deposit_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r32(&tb_ptr);

            t2 = tci_read_r32(&tb_ptr);

            tmp16 = *tb_ptr++;

            tmp8 = *tb_ptr++;

            tmp32 = (((1 << tmp8) - 1) << tmp16);

            tci_write_reg32(t0, (t1 & ~tmp32) | ((t2 << tmp16) & tmp32));

            break;

#endif

        case INDEX_op_brcond_i32:

            t0 = tci_read_r32(&tb_ptr);

            t1 = tci_read_ri32(&tb_ptr);

            condition = *tb_ptr++;

            label = tci_read_label(&tb_ptr);

            if (tci_compare32(t0, t1, condition)) {

                assert(tb_ptr == old_code_ptr + op_size);

                tb_ptr = (uint8_t *)label;

                continue;

            }

            break;

#if TCG_TARGET_REG_BITS == 32

        case INDEX_op_add2_i32:

            t0 = *tb_ptr++;

            t1 = *tb_ptr++;

            tmp64 = tci_read_r64(&tb_ptr);

            tmp64 += tci_read_r64(&tb_ptr);

            tci_write_reg64(t1, t0, tmp64);

            break;

        case INDEX_op_sub2_i32:

            t0 = *tb_ptr++;

            t1 = *tb_ptr++;

            tmp64 = tci_read_r64(&tb_ptr);

            tmp64 -= tci_read_r64(&tb_ptr);

            tci_write_reg64(t1, t0, tmp64);

            break;

        case INDEX_op_brcond2_i32:

            tmp64 = tci_read_r64(&tb_ptr);

            v64 = tci_read_ri64(&tb_ptr);

            condition = *tb_ptr++;

            label = tci_read_label(&tb_ptr);

            if (tci_compare64(tmp64, v64, condition)) {

                assert(tb_ptr == old_code_ptr + op_size);

                tb_ptr = (uint8_t *)label;

                continue;

            }

            break;

        case INDEX_op_mulu2_i32:

            t0 = *tb_ptr++;

            t1 = *tb_ptr++;

            t2 = tci_read_r32(&tb_ptr);

            tmp64 = tci_read_r32(&tb_ptr);

            tci_write_reg64(t1, t0, t2 * tmp64);

            break;

#endif /* TCG_TARGET_REG_BITS == 32 */

#if TCG_TARGET_HAS_ext8s_i32

        case INDEX_op_ext8s_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r8s(&tb_ptr);

            tci_write_reg32(t0, t1);

            break;

#endif

#if TCG_TARGET_HAS_ext16s_i32

        case INDEX_op_ext16s_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r16s(&tb_ptr);

            tci_write_reg32(t0, t1);

            break;

#endif

#if TCG_TARGET_HAS_ext8u_i32

        case INDEX_op_ext8u_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r8(&tb_ptr);

            tci_write_reg32(t0, t1);

            break;

#endif

#if TCG_TARGET_HAS_ext16u_i32

        case INDEX_op_ext16u_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r16(&tb_ptr);

            tci_write_reg32(t0, t1);

            break;

#endif

#if TCG_TARGET_HAS_bswap16_i32

        case INDEX_op_bswap16_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r16(&tb_ptr);

            tci_write_reg32(t0, bswap16(t1));

            break;

#endif

#if TCG_TARGET_HAS_bswap32_i32

        case INDEX_op_bswap32_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r32(&tb_ptr);

            tci_write_reg32(t0, bswap32(t1));

            break;

#endif

#if TCG_TARGET_HAS_not_i32

        case INDEX_op_not_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r32(&tb_ptr);

            tci_write_reg32(t0, ~t1);

            break;

#endif

#if TCG_TARGET_HAS_neg_i32

        case INDEX_op_neg_i32:

            t0 = *tb_ptr++;

            t1 = tci_read_r32(&tb_ptr);

            tci_write_reg32(t0, -t1);

            break;

#endif

#if TCG_TARGET_REG_BITS == 64

        case INDEX_op_mov_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r64(&tb_ptr);

            tci_write_reg64(t0, t1);

            break;

        case INDEX_op_movi_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_i64(&tb_ptr);

            tci_write_reg64(t0, t1);

            break;

            /* Load/store operations (64 bit). */

        case INDEX_op_ld8u_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            tci_write_reg8(t0, *(uint8_t *)(t1 + t2));

            break;

        case INDEX_op_ld8s_i64:

        case INDEX_op_ld16u_i64:

        case INDEX_op_ld16s_i64:

            TODO();

            break;

        case INDEX_op_ld32u_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            tci_write_reg32(t0, *(uint32_t *)(t1 + t2));

            break;

        case INDEX_op_ld32s_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            tci_write_reg32s(t0, *(int32_t *)(t1 + t2));

            break;

        case INDEX_op_ld_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            tci_write_reg64(t0, *(uint64_t *)(t1 + t2));

            break;

        case INDEX_op_st8_i64:

            t0 = tci_read_r8(&tb_ptr);

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            *(uint8_t *)(t1 + t2) = t0;

            break;

        case INDEX_op_st16_i64:

            t0 = tci_read_r16(&tb_ptr);

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            *(uint16_t *)(t1 + t2) = t0;

            break;

        case INDEX_op_st32_i64:

            t0 = tci_read_r32(&tb_ptr);

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            *(uint32_t *)(t1 + t2) = t0;

            break;

        case INDEX_op_st_i64:

            t0 = tci_read_r64(&tb_ptr);

            t1 = tci_read_r(&tb_ptr);

            t2 = tci_read_s32(&tb_ptr);

            assert(t1 != sp_value || (int32_t)t2 < 0);

            *(uint64_t *)(t1 + t2) = t0;

            break;

            /* Arithmetic operations (64 bit). */

        case INDEX_op_add_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_ri64(&tb_ptr);

            t2 = tci_read_ri64(&tb_ptr);

            tci_write_reg64(t0, t1 + t2);

            break;

        case INDEX_op_sub_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_ri64(&tb_ptr);

            t2 = tci_read_ri64(&tb_ptr);

            tci_write_reg64(t0, t1 - t2);

            break;

        case INDEX_op_mul_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_ri64(&tb_ptr);

            t2 = tci_read_ri64(&tb_ptr);

            tci_write_reg64(t0, t1 * t2);

            break;

#if TCG_TARGET_HAS_div_i64

        case INDEX_op_div_i64:

        case INDEX_op_divu_i64:

        case INDEX_op_rem_i64:

        case INDEX_op_remu_i64:

            TODO();

            break;

#elif TCG_TARGET_HAS_div2_i64

        case INDEX_op_div2_i64:

        case INDEX_op_divu2_i64:

            TODO();

            break;

#endif

        case INDEX_op_and_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_ri64(&tb_ptr);

            t2 = tci_read_ri64(&tb_ptr);

            tci_write_reg64(t0, t1 & t2);

            break;

        case INDEX_op_or_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_ri64(&tb_ptr);

            t2 = tci_read_ri64(&tb_ptr);

            tci_write_reg64(t0, t1 | t2);

            break;

        case INDEX_op_xor_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_ri64(&tb_ptr);

            t2 = tci_read_ri64(&tb_ptr);

            tci_write_reg64(t0, t1 ^ t2);

            break;

            /* Shift/rotate operations (64 bit). */

        case INDEX_op_shl_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_ri64(&tb_ptr);

            t2 = tci_read_ri64(&tb_ptr);

            tci_write_reg64(t0, t1 << t2);

            break;

        case INDEX_op_shr_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_ri64(&tb_ptr);

            t2 = tci_read_ri64(&tb_ptr);

            tci_write_reg64(t0, t1 >> t2);

            break;

        case INDEX_op_sar_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_ri64(&tb_ptr);

            t2 = tci_read_ri64(&tb_ptr);

            tci_write_reg64(t0, ((int64_t)t1 >> t2));

            break;

#if TCG_TARGET_HAS_rot_i64

        case INDEX_op_rotl_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_ri64(&tb_ptr);

            t2 = tci_read_ri64(&tb_ptr);

            tci_write_reg64(t0, rol64(t1, t2));

            break;

        case INDEX_op_rotr_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_ri64(&tb_ptr);

            t2 = tci_read_ri64(&tb_ptr);

            tci_write_reg64(t0, ror64(t1, t2));

            break;

#endif

#if TCG_TARGET_HAS_deposit_i64

        case INDEX_op_deposit_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r64(&tb_ptr);

            t2 = tci_read_r64(&tb_ptr);

            tmp16 = *tb_ptr++;

            tmp8 = *tb_ptr++;

            tmp64 = (((1ULL << tmp8) - 1) << tmp16);

            tci_write_reg64(t0, (t1 & ~tmp64) | ((t2 << tmp16) & tmp64));

            break;

#endif

        case INDEX_op_brcond_i64:

            t0 = tci_read_r64(&tb_ptr);

            t1 = tci_read_ri64(&tb_ptr);

            condition = *tb_ptr++;

            label = tci_read_label(&tb_ptr);

            if (tci_compare64(t0, t1, condition)) {

                assert(tb_ptr == old_code_ptr + op_size);

                tb_ptr = (uint8_t *)label;

                continue;

            }

            break;

#if TCG_TARGET_HAS_ext8u_i64

        case INDEX_op_ext8u_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r8(&tb_ptr);

            tci_write_reg64(t0, t1);

            break;

#endif

#if TCG_TARGET_HAS_ext8s_i64

        case INDEX_op_ext8s_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r8s(&tb_ptr);

            tci_write_reg64(t0, t1);

            break;

#endif

#if TCG_TARGET_HAS_ext16s_i64

        case INDEX_op_ext16s_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r16s(&tb_ptr);

            tci_write_reg64(t0, t1);

            break;

#endif

#if TCG_TARGET_HAS_ext16u_i64

        case INDEX_op_ext16u_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r16(&tb_ptr);

            tci_write_reg64(t0, t1);

            break;

#endif

#if TCG_TARGET_HAS_ext32s_i64

        case INDEX_op_ext32s_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r32s(&tb_ptr);

            tci_write_reg64(t0, t1);

            break;

#endif

#if TCG_TARGET_HAS_ext32u_i64

        case INDEX_op_ext32u_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r32(&tb_ptr);

            tci_write_reg64(t0, t1);

            break;

#endif

#if TCG_TARGET_HAS_bswap16_i64

        case INDEX_op_bswap16_i64:

            TODO();

            t0 = *tb_ptr++;

            t1 = tci_read_r16(&tb_ptr);

            tci_write_reg64(t0, bswap16(t1));

            break;

#endif

#if TCG_TARGET_HAS_bswap32_i64

        case INDEX_op_bswap32_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r32(&tb_ptr);

            tci_write_reg64(t0, bswap32(t1));

            break;

#endif

#if TCG_TARGET_HAS_bswap64_i64

        case INDEX_op_bswap64_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r64(&tb_ptr);

            tci_write_reg64(t0, bswap64(t1));

            break;

#endif

#if TCG_TARGET_HAS_not_i64

        case INDEX_op_not_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r64(&tb_ptr);

            tci_write_reg64(t0, ~t1);

            break;

#endif

#if TCG_TARGET_HAS_neg_i64

        case INDEX_op_neg_i64:

            t0 = *tb_ptr++;

            t1 = tci_read_r64(&tb_ptr);

            tci_write_reg64(t0, -t1);

            break;

#endif

#endif /* TCG_TARGET_REG_BITS == 64 */

            /* QEMU specific operations. */

#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS

        case INDEX_op_debug_insn_start:

            TODO();

            break;

#else

        case INDEX_op_debug_insn_start:

            TODO();

            break;

#endif

        case INDEX_op_exit_tb:

            next_tb = *(uint64_t *)tb_ptr;

            goto exit;

            break;

        case INDEX_op_goto_tb:

            t0 = tci_read_i32(&tb_ptr);

            assert(tb_ptr == old_code_ptr + op_size);

            tb_ptr += (int32_t)t0;

            continue;

        case INDEX_op_qemu_ld8u:

            t0 = *tb_ptr++;

            taddr = tci_read_ulong(&tb_ptr);

#ifdef CONFIG_SOFTMMU

            tmp8 = helper_ldb_mmu(env, taddr, tci_read_i(&tb_ptr));

#else

            host_addr = (tcg_target_ulong)taddr;

            tmp8 = *(uint8_t *)(host_addr + GUEST_BASE);

#endif

            tci_write_reg8(t0, tmp8);

            break;

        case INDEX_op_qemu_ld8s:

            t0 = *tb_ptr++;

            taddr = tci_read_ulong(&tb_ptr);

#ifdef CONFIG_SOFTMMU

            tmp8 = helper_ldb_mmu(env, taddr, tci_read_i(&tb_ptr));

#else

            host_addr = (tcg_target_ulong)taddr;

            tmp8 = *(uint8_t *)(host_addr + GUEST_BASE);

#endif

            tci_write_reg8s(t0, tmp8);

            break;

        case INDEX_op_qemu_ld16u:

            t0 = *tb_ptr++;

            taddr = tci_read_ulong(&tb_ptr);

#ifdef CONFIG_SOFTMMU

            tmp16 = helper_ldw_mmu(env, taddr, tci_read_i(&tb_ptr));

#else

            host_addr = (tcg_target_ulong)taddr;

            tmp16 = tswap16(*(uint16_t *)(host_addr + GUEST_BASE));

#endif

            tci_write_reg16(t0, tmp16);

            break;

        case INDEX_op_qemu_ld16s:

            t0 = *tb_ptr++;

            taddr = tci_read_ulong(&tb_ptr);

#ifdef CONFIG_SOFTMMU

            tmp16 = helper_ldw_mmu(env, taddr, tci_read_i(&tb_ptr));

#else

            host_addr = (tcg_target_ulong)taddr;

            tmp16 = tswap16(*(uint16_t *)(host_addr + GUEST_BASE));

#endif

            tci_write_reg16s(t0, tmp16);

            break;

#if TCG_TARGET_REG_BITS == 64

        case INDEX_op_qemu_ld32u:

            t0 = *tb_ptr++;

            taddr = tci_read_ulong(&tb_ptr);

#ifdef CONFIG_SOFTMMU

            tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr));

#else

            host_addr = (tcg_target_ulong)taddr;

            tmp32 = tswap32(*(uint32_t *)(host_addr + GUEST_BASE));

#endif

            tci_write_reg32(t0, tmp32);

            break;

        case INDEX_op_qemu_ld32s:

            t0 = *tb_ptr++;

            taddr = tci_read_ulong(&tb_ptr);

#ifdef CONFIG_SOFTMMU

            tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr));

#else

            host_addr = (tcg_target_ulong)taddr;

            tmp32 = tswap32(*(uint32_t *)(host_addr + GUEST_BASE));

#endif

            tci_write_reg32s(t0, tmp32);

            break;

#endif /* TCG_TARGET_REG_BITS == 64 */

        case INDEX_op_qemu_ld32:

            t0 = *tb_ptr++;

            taddr = tci_read_ulong(&tb_ptr);

#ifdef CONFIG_SOFTMMU

            tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr));

#else

            host_addr = (tcg_target_ulong)taddr;

            tmp32 = tswap32(*(uint32_t *)(host_addr + GUEST_BASE));

#endif

            tci_write_reg32(t0, tmp32);

            break;

        case INDEX_op_qemu_ld64:

            t0 = *tb_ptr++;

#if TCG_TARGET_REG_BITS == 32

            t1 = *tb_ptr++;

#endif

            taddr = tci_read_ulong(&tb_ptr);

#ifdef CONFIG_SOFTMMU

            tmp64 = helper_ldq_mmu(env, taddr, tci_read_i(&tb_ptr));

#else

            host_addr = (tcg_target_ulong)taddr;

            tmp64 = tswap64(*(uint64_t *)(host_addr + GUEST_BASE));

#endif

            tci_write_reg(t0, tmp64);

#if TCG_TARGET_REG_BITS == 32

            tci_write_reg(t1, tmp64 >> 32);

#endif

            break;

        case INDEX_op_qemu_st8:

            t0 = tci_read_r8(&tb_ptr);

            taddr = tci_read_ulong(&tb_ptr);

#ifdef CONFIG_SOFTMMU

            t2 = tci_read_i(&tb_ptr);

            helper_stb_mmu(env, taddr, t0, t2);

#else

            host_addr = (tcg_target_ulong)taddr;

            *(uint8_t *)(host_addr + GUEST_BASE) = t0;

#endif

            break;

        case INDEX_op_qemu_st16:

            t0 = tci_read_r16(&tb_ptr);

            taddr = tci_read_ulong(&tb_ptr);

#ifdef CONFIG_SOFTMMU

            t2 = tci_read_i(&tb_ptr);

            helper_stw_mmu(env, taddr, t0, t2);

#else

            host_addr = (tcg_target_ulong)taddr;

            *(uint16_t *)(host_addr + GUEST_BASE) = tswap16(t0);

#endif

            break;

        case INDEX_op_qemu_st32:

            t0 = tci_read_r32(&tb_ptr);

            taddr = tci_read_ulong(&tb_ptr);

#ifdef CONFIG_SOFTMMU

            t2 = tci_read_i(&tb_ptr);

            helper_stl_mmu(env, taddr, t0, t2);

#else

            host_addr = (tcg_target_ulong)taddr;

            *(uint32_t *)(host_addr + GUEST_BASE) = tswap32(t0);

#endif

            break;

        case INDEX_op_qemu_st64:

            tmp64 = tci_read_r64(&tb_ptr);

            taddr = tci_read_ulong(&tb_ptr);

#ifdef CONFIG_SOFTMMU

            t2 = tci_read_i(&tb_ptr);

            helper_stq_mmu(env, taddr, tmp64, t2);

#else

            host_addr = (tcg_target_ulong)taddr;

            *(uint64_t *)(host_addr + GUEST_BASE) = tswap64(tmp64);

#endif

            break;

        default:

            TODO();

            break;

        }

        assert(tb_ptr == old_code_ptr + op_size);

    }

exit:

    return next_tb;

}


static int vp9_raw_reorder_make_output(AVBSFContext *bsf,

                                   AVPacket *out,

                                   VP9RawReorderFrame *last_frame)

{

    VP9RawReorderContext *ctx = bsf->priv_data;

    VP9RawReorderFrame *next_output = last_frame,

                      *next_display = last_frame, *frame;

    int s, err;

    for (s = 0; s < FRAME_SLOTS; s++) {

        frame = ctx->slot[s];

        if (!frame)

            continue;

        if (frame->needs_output && (!next_output ||

            frame->sequence < next_output->sequence))

            next_output = frame;

        if (frame->needs_display && (!next_display ||

            frame->pts < next_display->pts))

            next_display = frame;

    }

    if (!next_output && !next_display)

        return AVERROR_EOF;

    if (!next_display || (next_output &&

        next_output->sequence < next_display->sequence))

        frame = next_output;

    else

        frame = next_display;

    if (frame->needs_output && frame->needs_display &&

        next_output == next_display) {

        av_log(bsf, AV_LOG_DEBUG, "Output and display frame "

               "%"PRId64" (%"PRId64") in order.\n",

               frame->sequence, frame->pts);

        av_packet_move_ref(out, frame->packet);

        frame->needs_output = frame->needs_display = 0;

    } else if (frame->needs_output) {

        if (frame->needs_display) {

            av_log(bsf, AV_LOG_DEBUG, "Output frame %"PRId64" "

                   "(%"PRId64") for later display.\n",

                   frame->sequence, frame->pts);

        } else {

            av_log(bsf, AV_LOG_DEBUG, "Output unshown frame "

                   "%"PRId64" (%"PRId64") to keep order.\n",

                   frame->sequence, frame->pts);

        }

        av_packet_move_ref(out, frame->packet);

        out->pts = out->dts;

        frame->needs_output = 0;

    } else {

        PutBitContext pb;

        av_assert0(!frame->needs_output && frame->needs_display);

        if (frame->slots == 0) {

            av_log(bsf, AV_LOG_ERROR, "Attempting to display frame "

                   "which is no longer available?\n");

            frame->needs_display = 0;

            return AVERROR_INVALIDDATA;

        }

        s = ff_ctz(frame->slots);

        av_assert0(s < FRAME_SLOTS);

        av_log(bsf, AV_LOG_DEBUG, "Display frame %"PRId64" "

               "(%"PRId64") from slot %d.\n",

               frame->sequence, frame->pts, s);

        frame->packet = av_packet_alloc();

        if (!frame->packet)

            return AVERROR(ENOMEM);

        err = av_new_packet(out, 2);

        if (err < 0)

            return err;

        init_put_bits(&pb, out->data, 2);

        // frame_marker

        put_bits(&pb, 2, 2);

        // profile_low_bit

        put_bits(&pb, 1, frame->profile & 1);

        // profile_high_bit

        put_bits(&pb, 1, (frame->profile >> 1) & 1);

        if (frame->profile == 3) {

            // reserved_zero

            put_bits(&pb, 1, 0);

        }

        // show_existing_frame

        put_bits(&pb, 1, 1);

        // frame_to_show_map_idx

        put_bits(&pb, 3, s);

        while (put_bits_count(&pb) < 16)

            put_bits(&pb, 1, 0);

        flush_put_bits(&pb);

        out->pts = out->dts = frame->pts;

        frame->needs_display = 0;

    }

    return 0;

}


static void decode_band_structure(GetBitContext *gbc, int blk, int eac3,

                                  int ecpl, int start_subband, int end_subband,

                                  const uint8_t *default_band_struct,

                                  int *num_bands, uint8_t *band_sizes)

{

    int subbnd, bnd, n_subbands, n_bands=0;

    uint8_t bnd_sz[22];

    uint8_t coded_band_struct[22];

    const uint8_t *band_struct;

    n_subbands = end_subband - start_subband;

    /* decode band structure from bitstream or use default */

    if (!eac3 || get_bits1(gbc)) {

        for (subbnd = 0; subbnd < n_subbands - 1; subbnd++) {

            coded_band_struct[subbnd] = get_bits1(gbc);

        }

        band_struct = coded_band_struct;

    } else if (!blk) {

        band_struct = &default_band_struct[start_subband+1];

    } else {

        /* no change in band structure */

        return;

    }

    /* calculate number of bands and band sizes based on band structure.

       note that the first 4 subbands in enhanced coupling span only 6 bins

       instead of 12. */

    if (num_bands || band_sizes ) {

        n_bands = n_subbands;

        bnd_sz[0] = ecpl ? 6 : 12;

        for (bnd = 0, subbnd = 1; subbnd < n_subbands; subbnd++) {

            int subbnd_size = (ecpl && subbnd < 4) ? 6 : 12;

            if (band_struct[subbnd - 1]) {

                n_bands--;

                bnd_sz[bnd] += subbnd_size;

            } else {

                bnd_sz[++bnd] = subbnd_size;

            }

        }

    }

    /* set optional output params */

    if (num_bands)

        *num_bands = n_bands;

    if (band_sizes)

        memcpy(band_sizes, bnd_sz, n_bands);

}


static ExitStatus trans_fop_weww_0e(DisasContext *ctx, uint32_t insn,

                                    const DisasInsn *di)

{

    unsigned rt = assemble_rt64(insn);

    unsigned rb = assemble_rb64(insn);

    unsigned ra = assemble_ra64(insn);

    return do_fop_weww(ctx, rt, ra, rb, di->f_weww);

}


static int decode_block_progressive(MJpegDecodeContext *s, int16_t *block,

                                    uint8_t *last_nnz, int ac_index,

                                    uint16_t *quant_matrix,

                                    int ss, int se, int Al, int *EOBRUN)

{

    int code, i, j, level, val, run;

    if (*EOBRUN) {

        (*EOBRUN)--;

        return 0;

    }

    {

        OPEN_READER(re, &s->gb);

        for (i = ss; ; i++) {

            UPDATE_CACHE(re, &s->gb);

            GET_VLC(code, re, &s->gb, s->vlcs[2][ac_index].table, 9, 2);

            run = ((unsigned) code) >> 4;

            code &= 0xF;

            if (code) {

                i += run;

                if (code > MIN_CACHE_BITS - 16)

                    UPDATE_CACHE(re, &s->gb);

                {

                    int cache = GET_CACHE(re, &s->gb);

                    int sign  = (~cache) >> 31;

                    level     = (NEG_USR32(sign ^ cache,code) ^ sign) - sign;

                }

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

                if (i >= se) {

                    if (i == se) {

                        j = s->scantable.permutated[se];

                        block[j] = level * (quant_matrix[se] << Al);

                        break;

                    }

                    av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i);

                    return AVERROR_INVALIDDATA;

                }

                j = s->scantable.permutated[i];

                block[j] = level * (quant_matrix[i] << Al);

            } else {

                if (run == 0xF) {// ZRL - skip 15 coefficients

                    i += 15;

                    if (i >= se) {

                        av_log(s->avctx, AV_LOG_ERROR, "ZRL overflow: %d\n", i);

                        return AVERROR_INVALIDDATA;

                    }

                } else {

                    val = (1 << run);

                    if (run) {

                        UPDATE_CACHE(re, &s->gb);

                        val += NEG_USR32(GET_CACHE(re, &s->gb), run);

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

                    }

                    *EOBRUN = val - 1;

                    break;

                }

            }

        }

        CLOSE_READER(re, &s->gb);

    }

    if (i > *last_nnz)

        *last_nnz = i;

    return 0;

}


static int asf_read_header(AVFormatContext *s)

{

    ASFContext *asf = s->priv_data;

    ff_asf_guid g;

    AVIOContext *pb = s->pb;

    int i;

    int64_t gsize;

    ff_get_guid(pb, &g);

    if (ff_guidcmp(&g, &ff_asf_header))

        return AVERROR_INVALIDDATA;

    avio_rl64(pb);

    avio_rl32(pb);

    avio_r8(pb);

    avio_r8(pb);

    memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid));

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

        asf->streams[i].stream_language_index = 128; // invalid stream index means no language info

    for (;;) {

        uint64_t gpos = avio_tell(pb);

        ff_get_guid(pb, &g);

        gsize = avio_rl64(pb);

        print_guid(&g);

        if (!ff_guidcmp(&g, &ff_asf_data_header)) {

            asf->data_object_offset = avio_tell(pb);

            /* If not streaming, gsize is not unlimited (how?),

             * and there is enough space in the file.. */

            if (!(asf->hdr.flags & 0x01) && gsize >= 100)

                asf->data_object_size = gsize - 24;

            else

                asf->data_object_size = (uint64_t)-1;

            break;

        }

        if (gsize < 24)

            return AVERROR_INVALIDDATA;

        if (!ff_guidcmp(&g, &ff_asf_file_header)) {

            int ret = asf_read_file_properties(s, gsize);

            if (ret < 0)

                return ret;

        } else if (!ff_guidcmp(&g, &ff_asf_stream_header)) {

            int ret = asf_read_stream_properties(s, gsize);

            if (ret < 0)

                return ret;

        } else if (!ff_guidcmp(&g, &ff_asf_comment_header)) {

            asf_read_content_desc(s, gsize);

        } else if (!ff_guidcmp(&g, &ff_asf_language_guid)) {

            asf_read_language_list(s, gsize);

        } else if (!ff_guidcmp(&g, &ff_asf_extended_content_header)) {

            asf_read_ext_content_desc(s, gsize);

        } else if (!ff_guidcmp(&g, &ff_asf_metadata_header)) {

            asf_read_metadata(s, gsize);

        } else if (!ff_guidcmp(&g, &ff_asf_metadata_library_header)) {

            asf_read_metadata(s, gsize);

        } else if (!ff_guidcmp(&g, &ff_asf_ext_stream_header)) {

            asf_read_ext_stream_properties(s, gsize);

            // there could be a optional stream properties object to follow

            // if so the next iteration will pick it up

            continue;

        } else if (!ff_guidcmp(&g, &ff_asf_head1_guid)) {

            ff_get_guid(pb, &g);

            avio_skip(pb, 6);

            continue;

        } else if (!ff_guidcmp(&g, &ff_asf_marker_header)) {

            asf_read_marker(s, gsize);

        } else if (avio_feof(pb)) {

            return AVERROR_EOF;

        } else {

            if (!s->keylen) {

                if (!ff_guidcmp(&g, &ff_asf_content_encryption)) {

                    unsigned int len;

                    int ret;

                    AVPacket pkt;

                    av_log(s, AV_LOG_WARNING,

                           "DRM protected stream detected, decoding will likely fail!\n");

                    len= avio_rl32(pb);

                    av_log(s, AV_LOG_DEBUG, "Secret data:\n");

                    if ((ret = av_get_packet(pb, &pkt, len)) < 0)

                        return ret;

                    av_hex_dump_log(s, AV_LOG_DEBUG, pkt.data, pkt.size);

                    av_free_packet(&pkt);

                    len= avio_rl32(pb);

                    get_tag(s, "ASF_Protection_Type", -1, len, 32);

                    len= avio_rl32(pb);

                    get_tag(s, "ASF_Key_ID", -1, len, 32);

                    len= avio_rl32(pb);

                    get_tag(s, "ASF_License_URL", -1, len, 32);

                } else if (!ff_guidcmp(&g, &ff_asf_ext_content_encryption)) {

                    av_log(s, AV_LOG_WARNING,

                           "Ext DRM protected stream detected, decoding will likely fail!\n");

                    av_dict_set(&s->metadata, "encryption", "ASF Extended Content Encryption", 0);

                } else if (!ff_guidcmp(&g, &ff_asf_digital_signature)) {

                    av_log(s, AV_LOG_INFO, "Digital signature detected!\n");

                }

            }

        }

        if (avio_tell(pb) != gpos + gsize)

            av_log(s, AV_LOG_DEBUG,

                   "gpos mismatch our pos=%"PRIu64", end=%"PRId64"\n",

                   avio_tell(pb) - gpos, gsize);

        avio_seek(pb, gpos + gsize, SEEK_SET);

    }

    ff_get_guid(pb, &g);

    avio_rl64(pb);

    avio_r8(pb);

    avio_r8(pb);

    if (avio_feof(pb))

        return AVERROR_EOF;

    asf->data_offset      = avio_tell(pb);

    asf->packet_size_left = 0;

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

        int stream_num = asf->asfid2avid[i];

        if (stream_num >= 0) {

            AVStream *st = s->streams[stream_num];

            if (!st->codec->bit_rate)

                st->codec->bit_rate = asf->stream_bitrates[i];

            if (asf->dar[i].num > 0 && asf->dar[i].den > 0) {

                av_reduce(&st->sample_aspect_ratio.num,

                          &st->sample_aspect_ratio.den,

                          asf->dar[i].num, asf->dar[i].den, INT_MAX);

            } else if ((asf->dar[0].num > 0) && (asf->dar[0].den > 0) &&

                       // Use ASF container value if the stream doesn't set AR.

                       (st->codec->codec_type == AVMEDIA_TYPE_VIDEO))

                av_reduce(&st->sample_aspect_ratio.num,

                          &st->sample_aspect_ratio.den,

                          asf->dar[0].num, asf->dar[0].den, INT_MAX);

            av_log(s, AV_LOG_TRACE, "i=%d, st->codec->codec_type:%d, asf->dar %d:%d sar=%d:%d\n",

                    i, st->codec->codec_type, asf->dar[i].num, asf->dar[i].den,

                    st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);

            // copy and convert language codes to the frontend

            if (asf->streams[i].stream_language_index < 128) {

                const char *rfc1766 = asf->stream_languages[asf->streams[i].stream_language_index];

                if (rfc1766 && strlen(rfc1766) > 1) {

                    const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' }; // ignore country code if any

                    const char *iso6392       = av_convert_lang_to(primary_tag,

                                                                   AV_LANG_ISO639_2_BIBL);

                    if (iso6392)

                        av_dict_set(&st->metadata, "language", iso6392, 0);

                }

            }

        }

    }

    ff_metadata_conv(&s->metadata, NULL, ff_asf_metadata_conv);

    return 0;

}


int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,

                                 AVPacket *pkt, int flush)

{

    AVPacketList *pktl;

    int stream_count = 0;

    int i;

    if (pkt) {

        ff_interleave_add_packet(s, pkt, interleave_compare_dts);

    }

    if (s->max_interleave_delta > 0 && s->packet_buffer && !flush) {

        AVPacket *top_pkt = &s->packet_buffer->pkt;

        int64_t delta_dts = INT64_MIN;

        int64_t top_dts = av_rescale_q(top_pkt->dts,

                                       s->streams[top_pkt->stream_index]->time_base,

                                       AV_TIME_BASE_Q);

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

            int64_t last_dts;

            const AVPacketList *last = s->streams[i]->last_in_packet_buffer;

            if (!last)

                continue;

            last_dts = av_rescale_q(last->pkt.dts,

                                    s->streams[i]->time_base,

                                    AV_TIME_BASE_Q);

            delta_dts = FFMAX(delta_dts, last_dts - top_dts);

            stream_count++;

        }

        if (delta_dts > s->max_interleave_delta) {

            av_log(s, AV_LOG_DEBUG,

                   "Delay between the first packet and last packet in the "

                   "muxing queue is %"PRId64" > %"PRId64": forcing output\n",

                   delta_dts, s->max_interleave_delta);

            flush = 1;

        }

    } else {

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

            stream_count += !!s->streams[i]->last_in_packet_buffer;

    }

    if (stream_count && (s->internal->nb_interleaved_streams == stream_count || flush)) {

        pktl = s->packet_buffer;

        *out = pktl->pkt;

        s->packet_buffer = pktl->next;

        if (!s->packet_buffer)

            s->packet_buffer_end = NULL;

        if (s->streams[out->stream_index]->last_in_packet_buffer == pktl)

            s->streams[out->stream_index]->last_in_packet_buffer = NULL;

        av_freep(&pktl);

        return 1;

    } else {

        av_init_packet(out);

        return 0;

    }

}


static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)

{

    H264Context *h = &s->h;

    int i, j, k, m, dir, mode;

    int cbp = 0;

    uint32_t vlc;

    int8_t *top, *left;

    const int mb_xy         = h->mb_xy;

    const int b_xy          = 4 * h->mb_x + 4 * h->mb_y * h->b_stride;

    h->top_samples_available      = (h->mb_y == 0) ? 0x33FF : 0xFFFF;

    h->left_samples_available     = (h->mb_x == 0) ? 0x5F5F : 0xFFFF;

    h->topright_samples_available = 0xFFFF;

    if (mb_type == 0) {           /* SKIP */

        if (h->pict_type == AV_PICTURE_TYPE_P ||

            s->next_pic->mb_type[mb_xy] == -1) {

            svq3_mc_dir_part(s, 16 * h->mb_x, 16 * h->mb_y, 16, 16,

                             0, 0, 0, 0, 0, 0);

            if (h->pict_type == AV_PICTURE_TYPE_B)

                svq3_mc_dir_part(s, 16 * h->mb_x, 16 * h->mb_y, 16, 16,

                                 0, 0, 0, 0, 1, 1);

            mb_type = MB_TYPE_SKIP;

        } else {

            mb_type = FFMIN(s->next_pic->mb_type[mb_xy], 6);

            if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 0, 0) < 0)

                return -1;

            if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 1, 1) < 0)

                return -1;

            mb_type = MB_TYPE_16x16;

        }

    } else if (mb_type < 8) {     /* INTER */

        if (s->thirdpel_flag && s->halfpel_flag == !get_bits1(&h->gb))

            mode = THIRDPEL_MODE;

        else if (s->halfpel_flag &&

                 s->thirdpel_flag == !get_bits1(&h->gb))

            mode = HALFPEL_MODE;

        else

            mode = FULLPEL_MODE;

        /* fill caches */

        /* note ref_cache should contain here:

         *  ????????

         *  ???11111

         *  N??11111

         *  N??11111

         *  N??11111

         */

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

            if (h->mb_x > 0 && h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6] != -1) {

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

                    AV_COPY32(h->mv_cache[m][scan8[0] - 1 + i * 8],

                              h->cur_pic.motion_val[m][b_xy - 1 + i * h->b_stride]);

            } else {

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

                    AV_ZERO32(h->mv_cache[m][scan8[0] - 1 + i * 8]);

            }

            if (h->mb_y > 0) {

                memcpy(h->mv_cache[m][scan8[0] - 1 * 8],

                       h->cur_pic.motion_val[m][b_xy - h->b_stride],

                       4 * 2 * sizeof(int16_t));

                memset(&h->ref_cache[m][scan8[0] - 1 * 8],

                       (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4);

                if (h->mb_x < h->mb_width - 1) {

                    AV_COPY32(h->mv_cache[m][scan8[0] + 4 - 1 * 8],

                              h->cur_pic.motion_val[m][b_xy - h->b_stride + 4]);

                    h->ref_cache[m][scan8[0] + 4 - 1 * 8] =

                        (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride + 1] + 6] == -1 ||

                         h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1;

                } else

                    h->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE;

                if (h->mb_x > 0) {

                    AV_COPY32(h->mv_cache[m][scan8[0] - 1 - 1 * 8],

                              h->cur_pic.motion_val[m][b_xy - h->b_stride - 1]);

                    h->ref_cache[m][scan8[0] - 1 - 1 * 8] =

                        (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1;

                } else

                    h->ref_cache[m][scan8[0] - 1 - 1 * 8] = PART_NOT_AVAILABLE;

            } else

                memset(&h->ref_cache[m][scan8[0] - 1 * 8 - 1],

                       PART_NOT_AVAILABLE, 8);

            if (h->pict_type != AV_PICTURE_TYPE_B)

                break;

        }

        /* decode motion vector(s) and form prediction(s) */

        if (h->pict_type == AV_PICTURE_TYPE_P) {

            if (svq3_mc_dir(s, mb_type - 1, mode, 0, 0) < 0)

                return -1;

        } else {        /* AV_PICTURE_TYPE_B */

            if (mb_type != 2) {

                if (svq3_mc_dir(s, 0, mode, 0, 0) < 0)

                    return -1;

            } else {

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

                    memset(h->cur_pic.motion_val[0][b_xy + i * h->b_stride],

                           0, 4 * 2 * sizeof(int16_t));

            }

            if (mb_type != 1) {

                if (svq3_mc_dir(s, 0, mode, 1, mb_type == 3) < 0)

                    return -1;

            } else {

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

                    memset(h->cur_pic.motion_val[1][b_xy + i * h->b_stride],

                           0, 4 * 2 * sizeof(int16_t));

            }

        }

        mb_type = MB_TYPE_16x16;

    } else if (mb_type == 8 || mb_type == 33) {   /* INTRA4x4 */

        memset(h->intra4x4_pred_mode_cache, -1, 8 * 5 * sizeof(int8_t));

        if (mb_type == 8) {

            if (h->mb_x > 0) {

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

                    h->intra4x4_pred_mode_cache[scan8[0] - 1 + i * 8] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6 - i];

                if (h->intra4x4_pred_mode_cache[scan8[0] - 1] == -1)

                    h->left_samples_available = 0x5F5F;

            }

            if (h->mb_y > 0) {

                h->intra4x4_pred_mode_cache[4 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 0];

                h->intra4x4_pred_mode_cache[5 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 1];

                h->intra4x4_pred_mode_cache[6 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 2];

                h->intra4x4_pred_mode_cache[7 + 8 * 0] = h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 3];

                if (h->intra4x4_pred_mode_cache[4 + 8 * 0] == -1)

                    h->top_samples_available = 0x33FF;

            }

            /* decode prediction codes for luma blocks */

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

                vlc = svq3_get_ue_golomb(&h->gb);

                if (vlc >= 25U) {

                    av_log(h->avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc);

                    return -1;

                }

                left = &h->intra4x4_pred_mode_cache[scan8[i] - 1];

                top  = &h->intra4x4_pred_mode_cache[scan8[i] - 8];

                left[1] = svq3_pred_1[top[0] + 1][left[0] + 1][svq3_pred_0[vlc][0]];

                left[2] = svq3_pred_1[top[1] + 1][left[1] + 1][svq3_pred_0[vlc][1]];

                if (left[1] == -1 || left[2] == -1) {

                    av_log(h->avctx, AV_LOG_ERROR, "weird prediction\n");

                    return -1;

                }

            }

        } else {    /* mb_type == 33, DC_128_PRED block type */

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

                memset(&h->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_PRED, 4);

        }

        write_back_intra_pred_mode(h);

        if (mb_type == 8) {

            ff_h264_check_intra4x4_pred_mode(h);

            h->top_samples_available  = (h->mb_y == 0) ? 0x33FF : 0xFFFF;

            h->left_samples_available = (h->mb_x == 0) ? 0x5F5F : 0xFFFF;

        } else {

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

                memset(&h->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_128_PRED, 4);

            h->top_samples_available  = 0x33FF;

            h->left_samples_available = 0x5F5F;

        }

        mb_type = MB_TYPE_INTRA4x4;

    } else {                      /* INTRA16x16 */

        dir = i_mb_type_info[mb_type - 8].pred_mode;

        dir = (dir >> 1) ^ 3 * (dir & 1) ^ 1;

        if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir, 0)) == -1) {

            av_log(h->avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n");

            return -1;

        }

        cbp     = i_mb_type_info[mb_type - 8].cbp;

        mb_type = MB_TYPE_INTRA16x16;

    }

    if (!IS_INTER(mb_type) && h->pict_type != AV_PICTURE_TYPE_I) {

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

            memset(h->cur_pic.motion_val[0][b_xy + i * h->b_stride],

                   0, 4 * 2 * sizeof(int16_t));

        if (h->pict_type == AV_PICTURE_TYPE_B) {

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

                memset(h->cur_pic.motion_val[1][b_xy + i * h->b_stride],

                       0, 4 * 2 * sizeof(int16_t));

        }

    }

    if (!IS_INTRA4x4(mb_type)) {

        memset(h->intra4x4_pred_mode + h->mb2br_xy[mb_xy], DC_PRED, 8);

    }

    if (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B) {

        memset(h->non_zero_count_cache + 8, 0, 14 * 8 * sizeof(uint8_t));

    }

    if (!IS_INTRA16x16(mb_type) &&

        (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B)) {

        if ((vlc = svq3_get_ue_golomb(&h->gb)) >= 48U){

            av_log(h->avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc);

            return -1;

        }

        cbp = IS_INTRA(mb_type) ? golomb_to_intra4x4_cbp[vlc]

                                : golomb_to_inter_cbp[vlc];

    }

    if (IS_INTRA16x16(mb_type) ||

        (h->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) {

        h->qscale += svq3_get_se_golomb(&h->gb);

        if (h->qscale > 31u) {

            av_log(h->avctx, AV_LOG_ERROR, "qscale:%d\n", h->qscale);

            return -1;

        }

    }

    if (IS_INTRA16x16(mb_type)) {

        AV_ZERO128(h->mb_luma_dc[0] + 0);

        AV_ZERO128(h->mb_luma_dc[0] + 8);

        if (svq3_decode_block(&h->gb, h->mb_luma_dc[0], 0, 1)) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "error while decoding intra luma dc\n");

            return -1;

        }

    }

    if (cbp) {

        const int index = IS_INTRA16x16(mb_type) ? 1 : 0;

        const int type  = ((h->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1);

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

            if ((cbp & (1 << i))) {

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

                    k = index ? (1 * (j & 1) + 2 * (i & 1) +

                                 2 * (j & 2) + 4 * (i & 2))

                              : (4 * i + j);

                    h->non_zero_count_cache[scan8[k]] = 1;

                    if (svq3_decode_block(&h->gb, &h->mb[16 * k], index, type)) {

                        av_log(h->avctx, AV_LOG_ERROR,

                               "error while decoding block\n");

                        return -1;

                    }

                }

            }

        if ((cbp & 0x30)) {

            for (i = 1; i < 3; ++i)

                if (svq3_decode_block(&h->gb, &h->mb[16 * 16 * i], 0, 3)) {

                    av_log(h->avctx, AV_LOG_ERROR,

                           "error while decoding chroma dc block\n");

                    return -1;

                }

            if ((cbp & 0x20)) {

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

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

                        k                                 = 16 * i + j;

                        h->non_zero_count_cache[scan8[k]] = 1;

                        if (svq3_decode_block(&h->gb, &h->mb[16 * k], 1, 1)) {

                            av_log(h->avctx, AV_LOG_ERROR,

                                   "error while decoding chroma ac block\n");

                            return -1;

                        }

                    }

                }

            }

        }

    }

    h->cbp                              = cbp;

    h->cur_pic.mb_type[mb_xy] = mb_type;

    if (IS_INTRA(mb_type))

        h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8, 1);

    return 0;

}


static void do_getfd(Monitor *mon, const QDict *qdict)

{

    const char *fdname = qdict_get_str(qdict, "fdname");

    mon_fd_t *monfd;

    int fd;

    fd = qemu_chr_get_msgfd(mon->chr);

    if (fd == -1) {

        monitor_printf(mon, "getfd: no file descriptor supplied via SCM_RIGHTS\n");

        return;

    }

    if (qemu_isdigit(fdname[0])) {

        monitor_printf(mon, "getfd: monitor names may not begin with a number\n");

        return;

    }

    fd = dup(fd);

    if (fd == -1) {

        monitor_printf(mon, "Failed to dup() file descriptor: %s\n",

                       strerror(errno));

        return;

    }

    LIST_FOREACH(monfd, &mon->fds, next) {

        if (strcmp(monfd->name, fdname) != 0) {

            continue;

        }

        close(monfd->fd);

        monfd->fd = fd;

        return;

    }

    monfd = qemu_mallocz(sizeof(mon_fd_t));

    monfd->name = qemu_strdup(fdname);

    monfd->fd = fd;

    LIST_INSERT_HEAD(&mon->fds, monfd, next);

}


hwaddr get_pteg_offset32(PowerPCCPU *cpu, hwaddr hash)

{

    CPUPPCState *env = &cpu->env;

    return (hash * HASH_PTEG_SIZE_32) & env->htab_mask;

}


static void mv88w8618_register_devices(void)

{

#ifdef HAS_AUDIO

    sysbus_register_withprop(&mv88w8618_audio_info);

#endif

}


static int vfio_get_device(VFIOGroup *group, const char *name, VFIODevice *vdev)

{

    struct vfio_device_info dev_info = { .argsz = sizeof(dev_info) };

    struct vfio_region_info reg_info = { .argsz = sizeof(reg_info) };

    struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) };

    int ret, i;

    ret = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, name);

    if (ret < 0) {

        error_report("vfio: error getting device %s from group %d: %m",

                     name, group->groupid);

        error_printf("Verify all devices in group %d are bound to vfio-pci "

                     "or pci-stub and not already in use\n", group->groupid);

        return ret;

    }

    vdev->fd = ret;

    vdev->group = group;

    QLIST_INSERT_HEAD(&group->device_list, vdev, next);

    /* Sanity check device */

    ret = ioctl(vdev->fd, VFIO_DEVICE_GET_INFO, &dev_info);

    if (ret) {

        error_report("vfio: error getting device info: %m");

        goto error;

    }

    DPRINTF("Device %s flags: %u, regions: %u, irgs: %u\n", name,

            dev_info.flags, dev_info.num_regions, dev_info.num_irqs);

    if (!(dev_info.flags & VFIO_DEVICE_FLAGS_PCI)) {

        error_report("vfio: Um, this isn't a PCI device");

        goto error;

    }

    vdev->reset_works = !!(dev_info.flags & VFIO_DEVICE_FLAGS_RESET);

    if (!vdev->reset_works) {

        error_report("Warning, device %s does not support reset", name);

    }

    if (dev_info.num_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {

        error_report("vfio: unexpected number of io regions %u",

                     dev_info.num_regions);

        goto error;

    }

    if (dev_info.num_irqs < VFIO_PCI_MSIX_IRQ_INDEX + 1) {

        error_report("vfio: unexpected number of irqs %u", dev_info.num_irqs);

        goto error;

    }

    for (i = VFIO_PCI_BAR0_REGION_INDEX; i < VFIO_PCI_ROM_REGION_INDEX; i++) {

        reg_info.index = i;

        ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info);

        if (ret) {

            error_report("vfio: Error getting region %d info: %m", i);

            goto error;

        }

        DPRINTF("Device %s region %d:\n", name, i);

        DPRINTF("  size: 0x%lx, offset: 0x%lx, flags: 0x%lx\n",

                (unsigned long)reg_info.size, (unsigned long)reg_info.offset,

                (unsigned long)reg_info.flags);

        vdev->bars[i].flags = reg_info.flags;

        vdev->bars[i].size = reg_info.size;

        vdev->bars[i].fd_offset = reg_info.offset;

        vdev->bars[i].fd = vdev->fd;

        vdev->bars[i].nr = i;

        QLIST_INIT(&vdev->bars[i].quirks);

    }

    reg_info.index = VFIO_PCI_ROM_REGION_INDEX;

    ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info);

    if (ret) {

        error_report("vfio: Error getting ROM info: %m");

        goto error;

    }

    DPRINTF("Device %s ROM:\n", name);

    DPRINTF("  size: 0x%lx, offset: 0x%lx, flags: 0x%lx\n",

            (unsigned long)reg_info.size, (unsigned long)reg_info.offset,

            (unsigned long)reg_info.flags);

    vdev->rom_size = reg_info.size;

    vdev->rom_offset = reg_info.offset;

    reg_info.index = VFIO_PCI_CONFIG_REGION_INDEX;

    ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, &reg_info);

    if (ret) {

        error_report("vfio: Error getting config info: %m");

        goto error;

    }

    DPRINTF("Device %s config:\n", name);

    DPRINTF("  size: 0x%lx, offset: 0x%lx, flags: 0x%lx\n",

            (unsigned long)reg_info.size, (unsigned long)reg_info.offset,

            (unsigned long)reg_info.flags);

    vdev->config_size = reg_info.size;

    if (vdev->config_size == PCI_CONFIG_SPACE_SIZE) {

        vdev->pdev.cap_present &= ~QEMU_PCI_CAP_EXPRESS;

    }

    vdev->config_offset = reg_info.offset;

    if ((vdev->features & VFIO_FEATURE_ENABLE_VGA) &&

        dev_info.num_regions > VFIO_PCI_VGA_REGION_INDEX) {

        struct vfio_region_info vga_info = {

            .argsz = sizeof(vga_info),

            .index = VFIO_PCI_VGA_REGION_INDEX,

         };

        ret = ioctl(vdev->fd, VFIO_DEVICE_GET_REGION_INFO, &vga_info);

        if (ret) {

            error_report(

                "vfio: Device does not support requested feature x-vga");

            goto error;

        }

        if (!(vga_info.flags & VFIO_REGION_INFO_FLAG_READ) ||

            !(vga_info.flags & VFIO_REGION_INFO_FLAG_WRITE) ||

            vga_info.size < 0xbffff + 1) {

            error_report("vfio: Unexpected VGA info, flags 0x%lx, size 0x%lx",

                         (unsigned long)vga_info.flags,

                         (unsigned long)vga_info.size);

            goto error;

        }

        vdev->vga.fd_offset = vga_info.offset;

        vdev->vga.fd = vdev->fd;

        vdev->vga.region[QEMU_PCI_VGA_MEM].offset = QEMU_PCI_VGA_MEM_BASE;

        vdev->vga.region[QEMU_PCI_VGA_MEM].nr = QEMU_PCI_VGA_MEM;

        QLIST_INIT(&vdev->vga.region[QEMU_PCI_VGA_MEM].quirks);

        vdev->vga.region[QEMU_PCI_VGA_IO_LO].offset = QEMU_PCI_VGA_IO_LO_BASE;

        vdev->vga.region[QEMU_PCI_VGA_IO_LO].nr = QEMU_PCI_VGA_IO_LO;

        QLIST_INIT(&vdev->vga.region[QEMU_PCI_VGA_IO_LO].quirks);

        vdev->vga.region[QEMU_PCI_VGA_IO_HI].offset = QEMU_PCI_VGA_IO_HI_BASE;

        vdev->vga.region[QEMU_PCI_VGA_IO_HI].nr = QEMU_PCI_VGA_IO_HI;

        QLIST_INIT(&vdev->vga.region[QEMU_PCI_VGA_IO_HI].quirks);

        vdev->has_vga = true;

    }

    irq_info.index = VFIO_PCI_ERR_IRQ_INDEX;

    ret = ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info);

    if (ret) {

        /* This can fail for an old kernel or legacy PCI dev */

        DPRINTF("VFIO_DEVICE_GET_IRQ_INFO failure ret=%d\n", ret);

        ret = 0;

    } else if (irq_info.count == 1) {

        vdev->pci_aer = true;

    } else {

        error_report("vfio: Warning: "

                     "Could not enable error recovery for the device\n");

    }

error:

    if (ret) {

        QLIST_REMOVE(vdev, next);

        vdev->group = NULL;

        close(vdev->fd);

    }

    return ret;

}


static void loop_filter(H264Context *h, H264SliceContext *sl, int start_x, int end_x)

{

    uint8_t *dest_y, *dest_cb, *dest_cr;

    int linesize, uvlinesize, mb_x, mb_y;

    const int end_mb_y       = h->mb_y + FRAME_MBAFF(h);

    const int old_slice_type = sl->slice_type;

    const int pixel_shift    = h->pixel_shift;

    const int block_h        = 16 >> h->chroma_y_shift;

    if (h->deblocking_filter) {

        for (mb_x = start_x; mb_x < end_x; mb_x++)

            for (mb_y = end_mb_y - FRAME_MBAFF(h); mb_y <= end_mb_y; mb_y++) {

                int mb_xy, mb_type;

                mb_xy         = h->mb_xy = mb_x + mb_y * h->mb_stride;

                sl->slice_num = h->slice_table[mb_xy];

                mb_type       = h->cur_pic.mb_type[mb_xy];

                sl->list_count = h->list_counts[mb_xy];

                if (FRAME_MBAFF(h))

                    h->mb_mbaff               =

                    h->mb_field_decoding_flag = !!IS_INTERLACED(mb_type);

                h->mb_x = mb_x;

                h->mb_y = mb_y;

                dest_y  = h->cur_pic.f.data[0] +

                          ((mb_x << pixel_shift) + mb_y * h->linesize) * 16;

                dest_cb = h->cur_pic.f.data[1] +

                          (mb_x << pixel_shift) * (8 << CHROMA444(h)) +

                          mb_y * h->uvlinesize * block_h;

                dest_cr = h->cur_pic.f.data[2] +

                          (mb_x << pixel_shift) * (8 << CHROMA444(h)) +

                          mb_y * h->uvlinesize * block_h;

                // FIXME simplify above

                if (MB_FIELD(h)) {

                    linesize   = sl->mb_linesize   = h->linesize   * 2;

                    uvlinesize = sl->mb_uvlinesize = h->uvlinesize * 2;

                    if (mb_y & 1) { // FIXME move out of this function?

                        dest_y  -= h->linesize   * 15;

                        dest_cb -= h->uvlinesize * (block_h - 1);

                        dest_cr -= h->uvlinesize * (block_h - 1);

                    }

                } else {

                    linesize   = sl->mb_linesize   = h->linesize;

                    uvlinesize = sl->mb_uvlinesize = h->uvlinesize;

                }

                backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize,

                                 uvlinesize, 0);

                if (fill_filter_caches(h, sl, mb_type))

                    continue;

                sl->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.qscale_table[mb_xy]);

                sl->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.qscale_table[mb_xy]);

                if (FRAME_MBAFF(h)) {

                    ff_h264_filter_mb(h, sl, mb_x, mb_y, dest_y, dest_cb, dest_cr,

                                      linesize, uvlinesize);

                } else {

                    ff_h264_filter_mb_fast(h, sl, mb_x, mb_y, dest_y, dest_cb,

                                           dest_cr, linesize, uvlinesize);

                }

            }

    }

    sl->slice_type  = old_slice_type;

    h->mb_x         = end_x;

    h->mb_y         = end_mb_y - FRAME_MBAFF(h);

    sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);

    sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);

}


static void xenfb_update(void *opaque)

{

    struct XenFB *xenfb = opaque;

    DisplaySurface *surface;

    int i;

    if (xenfb->c.xendev.be_state != XenbusStateConnected)

        return;

    if (!xenfb->feature_update) {

        /* we don't get update notifications, thus use the

         * sledge hammer approach ... */

        xenfb->up_fullscreen = 1;

    }

    /* resize if needed */

    if (xenfb->do_resize) {

        pixman_format_code_t format;

        xenfb->do_resize = 0;

        switch (xenfb->depth) {

        case 16:

        case 32:

            /* console.c supported depth -> buffer can be used directly */

            format = qemu_default_pixman_format(xenfb->depth, true);

            surface = qemu_create_displaysurface_from

                (xenfb->width, xenfb->height, format,

                 xenfb->row_stride, xenfb->pixels + xenfb->offset);

            break;

        default:

            /* we must convert stuff */

            surface = qemu_create_displaysurface(xenfb->width, xenfb->height);

            break;

        }

        dpy_gfx_replace_surface(xenfb->c.con, surface);

        xen_pv_printf(&xenfb->c.xendev, 1,

                      "update: resizing: %dx%d @ %d bpp%s\n",

                      xenfb->width, xenfb->height, xenfb->depth,

                      is_buffer_shared(surface) ? " (shared)" : "");

        xenfb->up_fullscreen = 1;

    }

    /* run queued updates */

    if (xenfb->up_fullscreen) {

        xen_pv_printf(&xenfb->c.xendev, 3, "update: fullscreen\n");

        xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);

    } else if (xenfb->up_count) {

        xen_pv_printf(&xenfb->c.xendev, 3, "update: %d rects\n",

                      xenfb->up_count);

        for (i = 0; i < xenfb->up_count; i++)

            xenfb_guest_copy(xenfb,

                             xenfb->up_rects[i].x,

                             xenfb->up_rects[i].y,

                             xenfb->up_rects[i].w,

                             xenfb->up_rects[i].h);

    } else {

        xen_pv_printf(&xenfb->c.xendev, 3, "update: nothing\n");

    }

    xenfb->up_count = 0;

    xenfb->up_fullscreen = 0;

}


petalogix_s3adsp1800_init(MachineState *machine)

{

    ram_addr_t ram_size = machine->ram_size;

    const char *cpu_model = machine->cpu_model;

    DeviceState *dev;

    MicroBlazeCPU *cpu;

    DriveInfo *dinfo;

    int i;

    hwaddr ddr_base = MEMORY_BASEADDR;

    MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1);

    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);

    qemu_irq irq[32];

    MemoryRegion *sysmem = get_system_memory();

    /* init CPUs */

    if (cpu_model == NULL) {

        cpu_model = "microblaze";

    }

    cpu = cpu_mb_init(cpu_model);

    /* Attach emulated BRAM through the LMB.  */

    memory_region_init_ram(phys_lmb_bram, NULL,

                           "petalogix_s3adsp1800.lmb_bram", LMB_BRAM_SIZE,

                           &error_abort);

    vmstate_register_ram_global(phys_lmb_bram);

    memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram);

    memory_region_init_ram(phys_ram, NULL, "petalogix_s3adsp1800.ram",

                           ram_size, &error_abort);

    vmstate_register_ram_global(phys_ram);

    memory_region_add_subregion(sysmem, ddr_base, phys_ram);

    dinfo = drive_get(IF_PFLASH, 0, 0);

    pflash_cfi01_register(FLASH_BASEADDR,

                          NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE,

                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,

                          (64 * 1024), FLASH_SIZE >> 16,

                          1, 0x89, 0x18, 0x0000, 0x0, 1);

    dev = qdev_create(NULL, "xlnx.xps-intc");

    qdev_prop_set_uint32(dev, "kind-of-intr",

                         1 << ETHLITE_IRQ | 1 << UARTLITE_IRQ);

    qdev_init_nofail(dev);

    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR);

    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,

                       qdev_get_gpio_in(DEVICE(cpu), MB_CPU_IRQ));

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

        irq[i] = qdev_get_gpio_in(dev, i);

    }

    sysbus_create_simple("xlnx.xps-uartlite", UARTLITE_BASEADDR,

                         irq[UARTLITE_IRQ]);

    /* 2 timers at irq 2 @ 62 Mhz.  */

    dev = qdev_create(NULL, "xlnx.xps-timer");

    qdev_prop_set_uint32(dev, "one-timer-only", 0);

    qdev_prop_set_uint32(dev, "clock-frequency", 62 * 1000000);

    qdev_init_nofail(dev);

    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR);

    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]);

    qemu_check_nic_model(&nd_table[0], "xlnx.xps-ethernetlite");

    dev = qdev_create(NULL, "xlnx.xps-ethernetlite");

    qdev_set_nic_properties(dev, &nd_table[0]);

    qdev_prop_set_uint32(dev, "tx-ping-pong", 0);

    qdev_prop_set_uint32(dev, "rx-ping-pong", 0);

    qdev_init_nofail(dev);

    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, ETHLITE_BASEADDR);

    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[ETHLITE_IRQ]);

    microblaze_load_kernel(cpu, ddr_base, ram_size,

                           machine->initrd_filename,

                           BINARY_DEVICE_TREE_FILE,

                           machine_cpu_reset);

}


static void mainstone_common_init(ram_addr_t ram_size,

                const char *kernel_filename,

                const char *kernel_cmdline, const char *initrd_filename,

                const char *cpu_model, enum mainstone_model_e model, int arm_id)

{

    uint32_t sector_len = 256 * 1024;

    target_phys_addr_t mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 };

    PXA2xxState *cpu;

    DeviceState *mst_irq;

    DriveInfo *dinfo;

    int i;

    int be;

    if (!cpu_model)

        cpu_model = "pxa270-c5";

    /* Setup CPU & memory */

    cpu = pxa270_init(mainstone_binfo.ram_size, cpu_model);

    cpu_register_physical_memory(0, MAINSTONE_ROM,

                    qemu_ram_alloc(NULL, "mainstone.rom",

                                   MAINSTONE_ROM) | IO_MEM_ROM);

#ifdef TARGET_WORDS_BIGENDIAN

    be = 1;

#else

    be = 0;

#endif

    /* There are two 32MiB flash devices on the board */

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

        dinfo = drive_get(IF_PFLASH, 0, i);

        if (!dinfo) {

            fprintf(stderr, "Two flash images must be given with the "

                    "'pflash' parameter\n");

            exit(1);

        }

        if (!pflash_cfi01_register(mainstone_flash_base[i],

                                   qemu_ram_alloc(NULL, i ? "mainstone.flash1" :

                                                  "mainstone.flash0",

                                                  MAINSTONE_FLASH),

                                   dinfo->bdrv, sector_len,

                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0,

                                   be)) {

            fprintf(stderr, "qemu: Error registering flash memory.\n");

            exit(1);

        }

    }

    mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS,

                    cpu->pic[PXA2XX_PIC_GPIO_0]);

    /* setup keypad */

    printf("map addr %p\n", &map);

    pxa27x_register_keypad(cpu->kp, map, 0xe0);

    /* MMC/SD host */

    pxa2xx_mmci_handlers(cpu->mmc, NULL, qdev_get_gpio_in(mst_irq, MMC_IRQ));

    smc91c111_init(&nd_table[0], MST_ETH_PHYS,

                    qdev_get_gpio_in(mst_irq, ETHERNET_IRQ));

    mainstone_binfo.kernel_filename = kernel_filename;

    mainstone_binfo.kernel_cmdline = kernel_cmdline;

    mainstone_binfo.initrd_filename = initrd_filename;

    mainstone_binfo.board_id = arm_id;

    arm_load_kernel(cpu->env, &mainstone_binfo);

}


static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp)

{

    DeviceState *dev = DEVICE(pci_dev);

    VMXNET3State *s = VMXNET3(pci_dev);

    int ret;

    VMW_CBPRN("Starting init...");

    memory_region_init_io(&s->bar0, OBJECT(s), &b0_ops, s,

                          "vmxnet3-b0", VMXNET3_PT_REG_SIZE);

    pci_register_bar(pci_dev, VMXNET3_BAR0_IDX,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0);

    memory_region_init_io(&s->bar1, OBJECT(s), &b1_ops, s,

                          "vmxnet3-b1", VMXNET3_VD_REG_SIZE);

    pci_register_bar(pci_dev, VMXNET3_BAR1_IDX,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar1);

    memory_region_init(&s->msix_bar, OBJECT(s), "vmxnet3-msix-bar",

                       VMXNET3_MSIX_BAR_SIZE);

    pci_register_bar(pci_dev, VMXNET3_MSIX_BAR_IDX,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->msix_bar);

    vmxnet3_reset_interrupt_states(s);

    /* Interrupt pin A */

    pci_dev->config[PCI_INTERRUPT_PIN] = 0x01;

    ret = msi_init(pci_dev, VMXNET3_MSI_OFFSET(s), VMXNET3_MAX_NMSIX_INTRS,

                   VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK, NULL);

    /* Any error other than -ENOTSUP(board's MSI support is broken)

     * is a programming error. Fall back to INTx silently on -ENOTSUP */

    assert(!ret || ret == -ENOTSUP);

    if (!vmxnet3_init_msix(s)) {

        VMW_WRPRN("Failed to initialize MSI-X, configuration is inconsistent.");

    }

    vmxnet3_net_init(s);

    if (pci_is_express(pci_dev)) {

        if (pci_bus_is_express(pci_dev->bus)) {

            pcie_endpoint_cap_init(pci_dev, VMXNET3_EXP_EP_OFFSET);

        }

        pcie_dev_ser_num_init(pci_dev, VMXNET3_DSN_OFFSET,

                              vmxnet3_device_serial_num(s));

    }

    register_savevm_live(dev, "vmxnet3-msix", -1, 1, &savevm_vmxnet3_msix, s);

}


static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,

                        uint64_t value)

{

    ARMCPU *cpu = arm_env_get_cpu(env);

    if (env->cp15.c1_sys == value) {

        /* Skip the TLB flush if nothing actually changed; Linux likes

         * to do a lot of pointless SCTLR writes.

         */

        return;

    }

    env->cp15.c1_sys = value;

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

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

    tlb_flush(CPU(cpu), 1);

}


static Visitor *validate_test_init_internal(TestInputVisitorData *data,

                                            const char *json_string,

                                            va_list *ap)

{

    validate_teardown(data, NULL);

    data->obj = qobject_from_jsonv(json_string, ap);

    g_assert(data->obj);

    data->qiv = qmp_input_visitor_new(data->obj, true);

    g_assert(data->qiv);

    return data->qiv;

}


static void monitor_find_completion(Monitor *mon,

                                    const char *cmdline)

{

    char *args[MAX_ARGS];

    int nb_args, len;

    /* 1. parse the cmdline */

    if (parse_cmdline(cmdline, &nb_args, args) < 0) {

        return;

    }

#ifdef DEBUG_COMPLETION

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

        monitor_printf(mon, "arg%d = '%s'\n", i, args[i]);

    }

#endif

    /* if the line ends with a space, it means we want to complete the

       next arg */

    len = strlen(cmdline);

    if (len > 0 && qemu_isspace(cmdline[len - 1])) {

        if (nb_args >= MAX_ARGS) {

            goto cleanup;

        }

        args[nb_args++] = g_strdup("");

    }

    /* 2. auto complete according to args */

    monitor_find_completion_by_table(mon, mon->cmd_table, args, nb_args);

cleanup:

    free_cmdline_args(args, nb_args);

}


static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)

{

#if defined(TARGET_I386)

    cpu_synchronize_state(s->c_cpu);

    s->c_cpu->eip = pc;

#elif defined (TARGET_PPC)

    s->c_cpu->nip = pc;

#elif defined (TARGET_SPARC)

    s->c_cpu->pc = pc;

    s->c_cpu->npc = pc + 4;

#elif defined (TARGET_ARM)

    s->c_cpu->regs[15] = pc;

#elif defined (TARGET_SH4)

    s->c_cpu->pc = pc;

#elif defined (TARGET_MIPS)

    s->c_cpu->active_tc.PC = pc;

#elif defined (TARGET_MICROBLAZE)

    s->c_cpu->sregs[SR_PC] = pc;

#elif defined (TARGET_CRIS)

    s->c_cpu->pc = pc;

#elif defined (TARGET_ALPHA)

    s->c_cpu->pc = pc;

#elif defined (TARGET_S390X)

    cpu_synchronize_state(s->c_cpu);

    s->c_cpu->psw.addr = pc;

#endif

}


bool hvf_inject_interrupts(CPUState *cpu_state)

{

    int allow_nmi = !(rvmcs(cpu_state->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY) &

                VMCS_INTERRUPTIBILITY_NMI_BLOCKING);

    X86CPU *x86cpu = X86_CPU(cpu_state);

    CPUX86State *env = &x86cpu->env;

    uint64_t idt_info = rvmcs(cpu_state->hvf_fd, VMCS_IDT_VECTORING_INFO);

    uint64_t info = 0;

    if (idt_info & VMCS_IDT_VEC_VALID) {

        uint8_t vector = idt_info & 0xff;

        uint64_t intr_type = idt_info & VMCS_INTR_T_MASK;

        info = idt_info;

        uint64_t reason = rvmcs(cpu_state->hvf_fd, VMCS_EXIT_REASON);

        if (intr_type == VMCS_INTR_T_NMI && reason != EXIT_REASON_TASK_SWITCH) {

            allow_nmi = 1;

            vmx_clear_nmi_blocking(cpu_state);

        }

        if ((allow_nmi || intr_type != VMCS_INTR_T_NMI)) {

            info &= ~(1 << 12); /* clear undefined bit */

            if (intr_type == VMCS_INTR_T_SWINTR ||

                intr_type == VMCS_INTR_T_PRIV_SWEXCEPTION ||

                intr_type == VMCS_INTR_T_SWEXCEPTION) {

                uint64_t ins_len = rvmcs(cpu_state->hvf_fd,

                                         VMCS_EXIT_INSTRUCTION_LENGTH);

                wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INST_LENGTH, ins_len);

            }

            if (vector == EXCEPTION_BP || vector == EXCEPTION_OF) {

                /*

                 * VT-x requires #BP and #OF to be injected as software

                 * exceptions.

                 */

                info &= ~VMCS_INTR_T_MASK;

                info |= VMCS_INTR_T_SWEXCEPTION;

                uint64_t ins_len = rvmcs(cpu_state->hvf_fd,

                                         VMCS_EXIT_INSTRUCTION_LENGTH);

                wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INST_LENGTH, ins_len);

            }

            uint64_t err = 0;

            if (idt_info & VMCS_INTR_DEL_ERRCODE) {

                err = rvmcs(cpu_state->hvf_fd, VMCS_IDT_VECTORING_ERROR);

                wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_EXCEPTION_ERROR, err);

            }

            /*printf("reinject  %lx err %d\n", info, err);*/

            wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, info);

        };

    }

    if (cpu_state->interrupt_request & CPU_INTERRUPT_NMI) {

        if (allow_nmi && !(info & VMCS_INTR_VALID)) {

            cpu_state->interrupt_request &= ~CPU_INTERRUPT_NMI;

            info = VMCS_INTR_VALID | VMCS_INTR_T_NMI | NMI_VEC;

            wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, info);

        } else {

            vmx_set_nmi_window_exiting(cpu_state);

        }

    }

    if (env->hvf_emul->interruptable &&

        (cpu_state->interrupt_request & CPU_INTERRUPT_HARD) &&

        (EFLAGS(env) & IF_MASK) && !(info & VMCS_INTR_VALID)) {

        int line = cpu_get_pic_interrupt(&x86cpu->env);

        cpu_state->interrupt_request &= ~CPU_INTERRUPT_HARD;

        if (line >= 0) {

            wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, line |

                  VMCS_INTR_VALID | VMCS_INTR_T_HWINTR);

        }

    }

    if (cpu_state->interrupt_request & CPU_INTERRUPT_HARD) {

        vmx_set_int_window_exiting(cpu_state);

    }

}


static void jpeg_prepare_row(VncState *vs, uint8_t *dst, int x, int y,

                                       int count)

{

    if (vs->tight_pixel24)

        jpeg_prepare_row24(vs, dst, x, y, count);

    else if (ds_get_bytes_per_pixel(vs->ds) == 4)

        jpeg_prepare_row32(vs, dst, x, y, count);

    else

        jpeg_prepare_row16(vs, dst, x, y, count);

}


static int detect_stream_specific(AVFormatContext *avf, int idx)

{

    ConcatContext *cat = avf->priv_data;

    AVStream *st = cat->avf->streams[idx];

    ConcatStream *cs = &cat->cur_file->streams[idx];

    AVBitStreamFilterContext *bsf;

    int ret;

    if (cat->auto_convert && st->codecpar->codec_id == AV_CODEC_ID_H264 &&

        (st->codecpar->extradata_size < 4 || AV_RB32(st->codecpar->extradata) != 1)) {

        av_log(cat->avf, AV_LOG_INFO,

               "Auto-inserting h264_mp4toannexb bitstream filter\n");

        if (!(bsf = av_bitstream_filter_init("h264_mp4toannexb"))) {

            av_log(avf, AV_LOG_ERROR, "h264_mp4toannexb bitstream filter "

                   "required for H.264 streams\n");

            return AVERROR_BSF_NOT_FOUND;

        }

        cs->bsf = bsf;

        cs->avctx = avcodec_alloc_context3(NULL);

        if (!cs->avctx)

            return AVERROR(ENOMEM);

        /* This really should be part of the bsf work.

           Note: input bitstream filtering will not work with bsf that

           create extradata from the first packet. */

        av_freep(&st->codecpar->extradata);

        st->codecpar->extradata_size = 0;

        ret = avcodec_parameters_to_context(cs->avctx, st->codecpar);

        if (ret < 0) {

            avcodec_free_context(&cs->avctx);

            return ret;

        }

    }

    return 0;

}


void pc_basic_device_init(qemu_irq *isa_irq,

                          FDCtrl **floppy_controller,

                          ISADevice **rtc_state)

{

    int i;

    DriveInfo *fd[MAX_FD];

    PITState *pit;

    qemu_irq rtc_irq = NULL;

    qemu_irq *a20_line;

    ISADevice *i8042, *port92, *vmmouse;

    qemu_irq *cpu_exit_irq;

    register_ioport_write(0x80, 1, 1, ioport80_write, NULL);

    register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);

    if (!no_hpet) {

        DeviceState *hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL);

        if (hpet) {

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

                sysbus_connect_irq(sysbus_from_qdev(hpet), i, isa_irq[i]);

            }

            rtc_irq = qdev_get_gpio_in(hpet, 0);

        }

    }

    *rtc_state = rtc_init(2000, rtc_irq);

    qemu_register_boot_set(pc_boot_set, *rtc_state);

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

    pcspk_init(pit);

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

        if (serial_hds[i]) {

            serial_isa_init(i, serial_hds[i]);

        }

    }

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

        if (parallel_hds[i]) {

            parallel_init(i, parallel_hds[i]);

        }

    }

    a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2);

    i8042 = isa_create_simple("i8042");

    i8042_setup_a20_line(i8042, &a20_line[0]);

    vmport_init();

    vmmouse = isa_try_create("vmmouse");

    if (vmmouse) {

        qdev_prop_set_ptr(&vmmouse->qdev, "ps2_mouse", i8042);

    }

    port92 = isa_create_simple("port92");

    port92_init(port92, &a20_line[1]);

    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);

    DMA_init(0, cpu_exit_irq);

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

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

    }

    *floppy_controller = fdctrl_init_isa(fd);

}


static void dump_json_image_check(ImageCheck *check, bool quiet)

{

    QString *str;

    QObject *obj;

    Visitor *v = qmp_output_visitor_new(&obj);

    visit_type_ImageCheck(v, NULL, &check, &error_abort);

    visit_complete(v, &obj);

    str = qobject_to_json_pretty(obj);

    assert(str != NULL);

    qprintf(quiet, "%s\n", qstring_get_str(str));

    qobject_decref(obj);

    visit_free(v);

    QDECREF(str);

}


INLINE bits32 extractFloat32Frac( float32 a )

{

    return a & 0x007FFFFF;

}


int rom_load_fw(void *fw_cfg)

{

    Rom *rom;

    QTAILQ_FOREACH(rom, &roms, next) {

        if (!rom->fw_file) {

            continue;

        }

        fw_cfg_add_file(fw_cfg, rom->fw_dir, rom->fw_file, rom->data, rom->romsize);

    }

    return 0;

}


static inline void gen_branch2(DisasContext *dc, target_ulong pc1,

                               target_ulong pc2, TCGv r_cond)

{

    int l1;

    l1 = gen_new_label();

    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);

    gen_goto_tb(dc, 0, pc1, pc1 + 4);

    gen_set_label(l1);

    gen_goto_tb(dc, 1, pc2, pc2 + 4);

}


static int u3_agp_pci_host_init(PCIDevice *d)

{

    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);

    pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_U3_AGP);

    /* revision */

    d->config[0x08] = 0x00;

    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);

    /* cache line size */

    d->config[0x0C] = 0x08;

    /* latency timer */

    d->config[0x0D] = 0x10;

    return 0;

}


static void nographic_update(void *opaque)

{

    uint64_t interval = GUI_REFRESH_INTERVAL;

    qemu_flush_coalesced_mmio_buffer();

    qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));

}


static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,

                          int remaining_sectors, QEMUIOVector *qiov)

{

    BDRVQcowState *s = bs->opaque;

    int index_in_cluster, n1;

    int ret;

    int cur_nr_sectors; /* number of sectors in current iteration */

    uint64_t cluster_offset = 0;

    uint64_t bytes_done = 0;

    QEMUIOVector hd_qiov;

    uint8_t *cluster_data = NULL;

    qemu_iovec_init(&hd_qiov, qiov->niov);

    qemu_co_mutex_lock(&s->lock);

    while (remaining_sectors != 0) {

        /* prepare next request */

        cur_nr_sectors = remaining_sectors;

        if (s->crypt_method) {

            cur_nr_sectors = MIN(cur_nr_sectors,

                QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);

        }

        ret = qcow2_get_cluster_offset(bs, sector_num << 9,

            &cur_nr_sectors, &cluster_offset);

        if (ret < 0) {

            goto fail;

        }

        index_in_cluster = sector_num & (s->cluster_sectors - 1);

        qemu_iovec_reset(&hd_qiov);

        qemu_iovec_concat(&hd_qiov, qiov, bytes_done,

            cur_nr_sectors * 512);

        switch (ret) {

        case QCOW2_CLUSTER_UNALLOCATED:

            if (bs->backing_hd) {

                /* read from the base image */

                n1 = qcow2_backing_read1(bs->backing_hd, &hd_qiov,

                    sector_num, cur_nr_sectors);

                if (n1 > 0) {

                    BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);

                    qemu_co_mutex_unlock(&s->lock);

                    ret = bdrv_co_readv(bs->backing_hd, sector_num,

                                        n1, &hd_qiov);

                    qemu_co_mutex_lock(&s->lock);

                    if (ret < 0) {

                        goto fail;

                    }

                }

            } else {

                /* Note: in this case, no need to wait */

                qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors);

            }

            break;

        case QCOW2_CLUSTER_ZERO:

            if (s->qcow_version < 3) {

                ret = -EIO;

                goto fail;

            }

            qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors);

            break;

        case QCOW2_CLUSTER_COMPRESSED:

            /* add AIO support for compressed blocks ? */

            ret = qcow2_decompress_cluster(bs, cluster_offset);

            if (ret < 0) {

                goto fail;

            }

            qemu_iovec_from_buf(&hd_qiov, 0,

                s->cluster_cache + index_in_cluster * 512,

                512 * cur_nr_sectors);

            break;

        case QCOW2_CLUSTER_NORMAL:

            if ((cluster_offset & 511) != 0) {

                ret = -EIO;

                goto fail;

            }

            if (s->crypt_method) {

                /*

                 * For encrypted images, read everything into a temporary

                 * contiguous buffer on which the AES functions can work.

                 */

                if (!cluster_data) {

                    cluster_data =

                        qemu_blockalign(bs, QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);

                }

                assert(cur_nr_sectors <=

                    QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);

                qemu_iovec_reset(&hd_qiov);

                qemu_iovec_add(&hd_qiov, cluster_data,

                    512 * cur_nr_sectors);

            }

            BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);

            qemu_co_mutex_unlock(&s->lock);

            ret = bdrv_co_readv(bs->file,

                                (cluster_offset >> 9) + index_in_cluster,

                                cur_nr_sectors, &hd_qiov);

            qemu_co_mutex_lock(&s->lock);

            if (ret < 0) {

                goto fail;

            }

            if (s->crypt_method) {

                qcow2_encrypt_sectors(s, sector_num,  cluster_data,

                    cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key);

                qemu_iovec_from_buf(qiov, bytes_done,

                    cluster_data, 512 * cur_nr_sectors);

            }

            break;

        default:

            g_assert_not_reached();

            ret = -EIO;

            goto fail;

        }

        remaining_sectors -= cur_nr_sectors;

        sector_num += cur_nr_sectors;

        bytes_done += cur_nr_sectors * 512;

    }

    ret = 0;

fail:

    qemu_co_mutex_unlock(&s->lock);

    qemu_iovec_destroy(&hd_qiov);

    qemu_vfree(cluster_data);

    return ret;

}


static int sh_pci_init_device(SysBusDevice *dev)

{

    SHPCIState *s;

    int i;

    s = FROM_SYSBUS(SHPCIState, dev);

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

        sysbus_init_irq(dev, &s->irq[i]);

    }

    s->bus = pci_register_bus(&s->busdev.qdev, "pci",

                              sh_pci_set_irq, sh_pci_map_irq,

                              s->irq,

                              get_system_memory(),

                              get_system_io(),

                              PCI_DEVFN(0, 0), 4);

    memory_region_init_io(&s->memconfig_p4, &sh_pci_reg_ops, s,

                          "sh_pci", 0x224);

    memory_region_init_alias(&s->memconfig_a7, "sh_pci.2", &s->memconfig_a7,

                             0, 0x224);

    isa_mmio_setup(&s->isa, 0x40000);

    sysbus_init_mmio_cb2(dev, sh_pci_map, sh_pci_unmap);

    sysbus_init_mmio_region(dev, &s->memconfig_a7);

    sysbus_init_mmio_region(dev, &s->isa);

    s->dev = pci_create_simple(s->bus, PCI_DEVFN(0, 0), "sh_pci_host");

    return 0;

}


static uint64_t pxa2xx_lcdc_read(void *opaque, hwaddr offset,

                                 unsigned size)

{

    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;

    int ch;

    switch (offset) {

    case LCCR0:

        return s->control[0];

    case LCCR1:

        return s->control[1];

    case LCCR2:

        return s->control[2];

    case LCCR3:

        return s->control[3];

    case LCCR4:

        return s->control[4];

    case LCCR5:

        return s->control[5];

    case OVL1C1:

        return s->ovl1c[0];

    case OVL1C2:

        return s->ovl1c[1];

    case OVL2C1:

        return s->ovl2c[0];

    case OVL2C2:

        return s->ovl2c[1];

    case CCR:

        return s->ccr;

    case CMDCR:

        return s->cmdcr;

    case TRGBR:

        return s->trgbr;

    case TCR:

        return s->tcr;

    case 0x200 ... 0x1000:	/* DMA per-channel registers */

        ch = (offset - 0x200) >> 4;

        if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS))

            goto fail;

        switch (offset & 0xf) {

        case DMA_FDADR:

            return s->dma_ch[ch].descriptor;

        case DMA_FSADR:

            return s->dma_ch[ch].source;

        case DMA_FIDR:

            return s->dma_ch[ch].id;

        case DMA_LDCMD:

            return s->dma_ch[ch].command;

        default:

            goto fail;

        }

    case FBR0:

        return s->dma_ch[0].branch;

    case FBR1:

        return s->dma_ch[1].branch;

    case FBR2:

        return s->dma_ch[2].branch;

    case FBR3:

        return s->dma_ch[3].branch;

    case FBR4:

        return s->dma_ch[4].branch;

    case FBR5:

        return s->dma_ch[5].branch;

    case FBR6:

        return s->dma_ch[6].branch;

    case BSCNTR:

        return s->bscntr;

    case PRSR:

        return 0;

    case LCSR0:

        return s->status[0];

    case LCSR1:

        return s->status[1];

    case LIIDR:

        return s->liidr;

    default:

    fail:

        hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);

    }

    return 0;

}


int main_loop(void)

{

#ifndef _WIN32

    struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;

    IOHandlerRecord *ioh, *ioh_next;

    uint8_t buf[4096];

    int n, max_size;

#endif

    int ret, timeout;

    CPUState *env = global_env;

    for(;;) {

        if (vm_running) {

            ret = cpu_exec(env);

            if (shutdown_requested) {

                ret = EXCP_INTERRUPT;

                break;

            }

            if (reset_requested) {

                reset_requested = 0;

                qemu_system_reset();

                ret = EXCP_INTERRUPT;

            }

            if (ret == EXCP_DEBUG) {

                vm_stop(EXCP_DEBUG);

            }

            /* if hlt instruction, we wait until the next IRQ */

            /* XXX: use timeout computed from timers */

            if (ret == EXCP_HLT)

                timeout = 10;

            else

                timeout = 0;

        } else {

            timeout = 10;

        }

#ifdef _WIN32

        if (timeout > 0)

            Sleep(timeout);

#else

        /* poll any events */

        /* XXX: separate device handlers from system ones */

        pf = ufds;

        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {

            if (!ioh->fd_can_read) {

                max_size = 0;

                pf->fd = ioh->fd;

                pf->events = POLLIN;

                ioh->ufd = pf;

                pf++;

            } else {

                max_size = ioh->fd_can_read(ioh->opaque);

                if (max_size > 0) {

                    if (max_size > sizeof(buf))

                        max_size = sizeof(buf);

                    pf->fd = ioh->fd;

                    pf->events = POLLIN;

                    ioh->ufd = pf;

                    pf++;

                } else {

                    ioh->ufd = NULL;

                }

            }

            ioh->max_size = max_size;

        }

        ret = poll(ufds, pf - ufds, timeout);

        if (ret > 0) {

            /* XXX: better handling of removal */

            for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {

                ioh_next = ioh->next;

                pf = ioh->ufd;

                if (pf) {

                    if (pf->revents & POLLIN) {

                        if (ioh->max_size == 0) {

                            /* just a read event */

                            ioh->fd_read(ioh->opaque, NULL, 0);

                        } else {

                            n = read(ioh->fd, buf, ioh->max_size);

                            if (n >= 0) {

                                ioh->fd_read(ioh->opaque, buf, n);

                            } else if (errno != EAGAIN) {

                                ioh->fd_read(ioh->opaque, NULL, -errno);

                            }

                        }

                    }

                }

            }

        }

#if defined(CONFIG_SLIRP)

        /* XXX: merge with poll() */

        if (slirp_inited) {

            fd_set rfds, wfds, xfds;

            int nfds;

            struct timeval tv;

            nfds = -1;

            FD_ZERO(&rfds);

            FD_ZERO(&wfds);

            FD_ZERO(&xfds);

            slirp_select_fill(&nfds, &rfds, &wfds, &xfds);

            tv.tv_sec = 0;

            tv.tv_usec = 0;

            ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);

            if (ret >= 0) {

                slirp_select_poll(&rfds, &wfds, &xfds);

            }

        }

#endif

#endif

        if (vm_running) {

            qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],

                            qemu_get_clock(vm_clock));

            if (audio_enabled) {

                /* XXX: add explicit timer */

                SB16_run();

            }

            /* run dma transfers, if any */

            DMA_run();

        }

        /* real time timers */

        qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],

                        qemu_get_clock(rt_clock));

    }

    cpu_disable_ticks();

    return ret;

}


static void intel_hda_corb_run(IntelHDAState *d)

{

    hwaddr addr;

    uint32_t rp, verb;

    if (d->ics & ICH6_IRS_BUSY) {

        dprint(d, 2, "%s: [icw] verb 0x%08x\n", __FUNCTION__, d->icw);

        intel_hda_send_command(d, d->icw);

        return;

    }

    for (;;) {

        if (!(d->corb_ctl & ICH6_CORBCTL_RUN)) {

            dprint(d, 2, "%s: !run\n", __FUNCTION__);

            return;

        }

        if ((d->corb_rp & 0xff) == d->corb_wp) {

            dprint(d, 2, "%s: corb ring empty\n", __FUNCTION__);

            return;

        }

        if (d->rirb_count == d->rirb_cnt) {

            dprint(d, 2, "%s: rirb count reached\n", __FUNCTION__);

            return;

        }

        rp = (d->corb_rp + 1) & 0xff;

        addr = intel_hda_addr(d->corb_lbase, d->corb_ubase);

        verb = ldl_le_pci_dma(&d->pci, addr + 4*rp);

        d->corb_rp = rp;

        dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __FUNCTION__, rp, verb);

        intel_hda_send_command(d, verb);

    }

}


static inline int valid_flags(int flag)

{

    if (flag & O_NOCTTY || flag & O_NONBLOCK || flag & O_ASYNC ||

            flag & O_CLOEXEC)

        return 0;

    else

        return 1;

}