static void decode_opc (CPUMIPSState *env, DisasContext *ctx)

{

    int32_t offset;

    int rs, rt, rd, sa;

    uint32_t op, op1;

    int16_t imm;

    /* make sure instructions are on a word boundary */

    if (ctx->pc & 0x3) {

        env->CP0_BadVAddr = ctx->pc;

        generate_exception(ctx, EXCP_AdEL);

        return;

    }

    /* Handle blikely not taken case */

    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {

        int l1 = gen_new_label();

        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);

        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);

        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);

        gen_goto_tb(ctx, 1, ctx->pc + 4);

        gen_set_label(l1);

    }

    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {

        tcg_gen_debug_insn_start(ctx->pc);

    }

    op = MASK_OP_MAJOR(ctx->opcode);

    rs = (ctx->opcode >> 21) & 0x1f;

    rt = (ctx->opcode >> 16) & 0x1f;

    rd = (ctx->opcode >> 11) & 0x1f;

    sa = (ctx->opcode >> 6) & 0x1f;

    imm = (int16_t)ctx->opcode;

    switch (op) {

    case OPC_SPECIAL:

        decode_opc_special(env, ctx);

        break;

    case OPC_SPECIAL2:

        decode_opc_special2_legacy(env, ctx);

        break;

    case OPC_SPECIAL3:

        decode_opc_special3(env, ctx);

        break;

    case OPC_REGIMM:

        op1 = MASK_REGIMM(ctx->opcode);

        switch (op1) {

        case OPC_BLTZL: /* REGIMM branches */

        case OPC_BGEZL:

        case OPC_BLTZALL:

        case OPC_BGEZALL:

            check_insn_opc_removed(ctx, ISA_MIPS32R6);

        case OPC_BLTZ:

        case OPC_BGEZ:

            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);

            break;

        case OPC_BLTZAL:

        case OPC_BGEZAL:

            if (ctx->insn_flags & ISA_MIPS32R6) {

                if (rs == 0) {

                    /* OPC_NAL, OPC_BAL */

                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);

                } else {

                    generate_exception(ctx, EXCP_RI);

                }

            } else {

                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);

            }

            break;

        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */

        case OPC_TNEI:

            check_insn_opc_removed(ctx, ISA_MIPS32R6);

            gen_trap(ctx, op1, rs, -1, imm);

            break;

        case OPC_SYNCI:

            check_insn(ctx, ISA_MIPS32R2);

            /* Break the TB to be able to sync copied instructions

               immediately */

            ctx->bstate = BS_STOP;

            break;

        case OPC_BPOSGE32:    /* MIPS DSP branch */

#if defined(TARGET_MIPS64)

        case OPC_BPOSGE64:

#endif

            check_dsp(ctx);

            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);

            break;

#if defined(TARGET_MIPS64)

        case OPC_DAHI:

            check_insn(ctx, ISA_MIPS32R6);

            check_mips_64(ctx);

            if (rs != 0) {

                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);

            }

            MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);

            break;

        case OPC_DATI:

            check_insn(ctx, ISA_MIPS32R6);

            check_mips_64(ctx);

            if (rs != 0) {

                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);

            }

            MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);

            break;

#endif

        default:            /* Invalid */

            MIPS_INVAL("regimm");

            generate_exception(ctx, EXCP_RI);

            break;

        }

        break;

    case OPC_CP0:

        check_cp0_enabled(ctx);

        op1 = MASK_CP0(ctx->opcode);

        switch (op1) {

        case OPC_MFC0:

        case OPC_MTC0:

        case OPC_MFTR:

        case OPC_MTTR:

#if defined(TARGET_MIPS64)

        case OPC_DMFC0:

        case OPC_DMTC0:

#endif

#ifndef CONFIG_USER_ONLY

            gen_cp0(env, ctx, op1, rt, rd);

#endif /* !CONFIG_USER_ONLY */

            break;

        case OPC_C0_FIRST ... OPC_C0_LAST:

#ifndef CONFIG_USER_ONLY

            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);

#endif /* !CONFIG_USER_ONLY */

            break;

        case OPC_MFMC0:

#ifndef CONFIG_USER_ONLY

            {

                uint32_t op2;

                TCGv t0 = tcg_temp_new();

                op2 = MASK_MFMC0(ctx->opcode);

                switch (op2) {

                case OPC_DMT:

                    check_insn(ctx, ASE_MT);

                    gen_helper_dmt(t0);

                    gen_store_gpr(t0, rt);

                    break;

                case OPC_EMT:

                    check_insn(ctx, ASE_MT);

                    gen_helper_emt(t0);

                    gen_store_gpr(t0, rt);

                    break;

                case OPC_DVPE:

                    check_insn(ctx, ASE_MT);

                    gen_helper_dvpe(t0, cpu_env);

                    gen_store_gpr(t0, rt);

                    break;

                case OPC_EVPE:

                    check_insn(ctx, ASE_MT);

                    gen_helper_evpe(t0, cpu_env);

                    gen_store_gpr(t0, rt);

                    break;

                case OPC_DI:

                    check_insn(ctx, ISA_MIPS32R2);

                    save_cpu_state(ctx, 1);

                    gen_helper_di(t0, cpu_env);

                    gen_store_gpr(t0, rt);

                    /* Stop translation as we may have switched the execution mode */

                    ctx->bstate = BS_STOP;

                    break;

                case OPC_EI:

                    check_insn(ctx, ISA_MIPS32R2);

                    save_cpu_state(ctx, 1);

                    gen_helper_ei(t0, cpu_env);

                    gen_store_gpr(t0, rt);

                    /* Stop translation as we may have switched the execution mode */

                    ctx->bstate = BS_STOP;

                    break;

                default:            /* Invalid */

                    MIPS_INVAL("mfmc0");

                    generate_exception(ctx, EXCP_RI);

                    break;

                }

                tcg_temp_free(t0);

            }

#endif /* !CONFIG_USER_ONLY */

            break;

        case OPC_RDPGPR:

            check_insn(ctx, ISA_MIPS32R2);

            gen_load_srsgpr(rt, rd);

            break;

        case OPC_WRPGPR:

            check_insn(ctx, ISA_MIPS32R2);

            gen_store_srsgpr(rt, rd);

            break;

        default:

            MIPS_INVAL("cp0");

            generate_exception(ctx, EXCP_RI);

            break;

        }

        break;

    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */

        if (ctx->insn_flags & ISA_MIPS32R6) {

            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */

            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);

        } else {

            /* OPC_ADDI */

            /* Arithmetic with immediate opcode */

            gen_arith_imm(ctx, op, rt, rs, imm);

        }

        break;

    case OPC_ADDIU:

         gen_arith_imm(ctx, op, rt, rs, imm);

         break;

    case OPC_SLTI: /* Set on less than with immediate opcode */

    case OPC_SLTIU:

         gen_slt_imm(ctx, op, rt, rs, imm);

         break;

    case OPC_ANDI: /* Arithmetic with immediate opcode */

    case OPC_LUI: /* OPC_AUI */

    case OPC_ORI:

    case OPC_XORI:

         gen_logic_imm(ctx, op, rt, rs, imm);

         break;

    case OPC_J ... OPC_JAL: /* Jump */

         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;

         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);

         break;

    /* Branch */

    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */

        if (ctx->insn_flags & ISA_MIPS32R6) {

            if (rt == 0) {

                generate_exception(ctx, EXCP_RI);

                break;

            }

            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */

            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);

        } else {

            /* OPC_BLEZL */

            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);

        }

        break;

    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */

        if (ctx->insn_flags & ISA_MIPS32R6) {

            if (rt == 0) {

                generate_exception(ctx, EXCP_RI);

                break;

            }

            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */

            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);

        } else {

            /* OPC_BGTZL */

            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);

        }

        break;

    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */

        if (rt == 0) {

            /* OPC_BLEZ */

            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);

        } else {

            check_insn(ctx, ISA_MIPS32R6);

            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */

            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);

        }

        break;

    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */

        if (rt == 0) {

            /* OPC_BGTZ */

            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);

        } else {

            check_insn(ctx, ISA_MIPS32R6);

            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */

            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);

        }

        break;

    case OPC_BEQL:

    case OPC_BNEL:

         check_insn_opc_removed(ctx, ISA_MIPS32R6);

    case OPC_BEQ:

    case OPC_BNE:

         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);

         break;

    case OPC_LWL: /* Load and stores */

    case OPC_LWR:

    case OPC_LL:

        check_insn_opc_removed(ctx, ISA_MIPS32R6);

    case OPC_LB ... OPC_LH:

    case OPC_LW ... OPC_LHU:

         gen_ld(ctx, op, rt, rs, imm);

         break;

    case OPC_SWL:

    case OPC_SWR:

        check_insn_opc_removed(ctx, ISA_MIPS32R6);

    case OPC_SB ... OPC_SH:

    case OPC_SW:

         gen_st(ctx, op, rt, rs, imm);

         break;

    case OPC_SC:

         check_insn_opc_removed(ctx, ISA_MIPS32R6);

         gen_st_cond(ctx, op, rt, rs, imm);

         break;

    case OPC_CACHE:

        check_insn_opc_removed(ctx, ISA_MIPS32R6);

        check_cp0_enabled(ctx);

        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);

        /* Treat as NOP. */

        break;

    case OPC_PREF:

        check_insn_opc_removed(ctx, ISA_MIPS32R6);

        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);

        /* Treat as NOP. */

        break;

    /* Floating point (COP1). */

    case OPC_LWC1:

    case OPC_LDC1:

    case OPC_SWC1:

    case OPC_SDC1:

        gen_cop1_ldst(ctx, op, rt, rs, imm);

        break;

    case OPC_CP1:

        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {

            check_cp1_enabled(ctx);

            op1 = MASK_CP1(ctx->opcode);

            switch (op1) {

            case OPC_MFHC1:

            case OPC_MTHC1:

                check_insn(ctx, ISA_MIPS32R2);

            case OPC_MFC1:

            case OPC_CFC1:

            case OPC_MTC1:

            case OPC_CTC1:

                gen_cp1(ctx, op1, rt, rd);

                break;

#if defined(TARGET_MIPS64)

            case OPC_DMFC1:

            case OPC_DMTC1:

                check_insn(ctx, ISA_MIPS3);

                gen_cp1(ctx, op1, rt, rd);

                break;

#endif

            case OPC_BC1EQZ: /* OPC_BC1ANY2 */

                if (ctx->insn_flags & ISA_MIPS32R6) {

                    /* OPC_BC1EQZ */

                    gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),

                                    rt, imm << 2);

                } else {

                    /* OPC_BC1ANY2 */

                    check_cop1x(ctx);

                    check_insn(ctx, ASE_MIPS3D);

                    gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),

                                    (rt >> 2) & 0x7, imm << 2);

                }

                break;

            case OPC_BC1NEZ:

                check_insn(ctx, ISA_MIPS32R6);

                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),

                                rt, imm << 2);

                break;

            case OPC_BC1ANY4:

                check_insn_opc_removed(ctx, ISA_MIPS32R6);

                check_cop1x(ctx);

                check_insn(ctx, ASE_MIPS3D);

                /* fall through */

            case OPC_BC1:

                check_insn_opc_removed(ctx, ISA_MIPS32R6);

                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),

                                    (rt >> 2) & 0x7, imm << 2);

                break;

            case OPC_PS_FMT:

                check_insn_opc_removed(ctx, ISA_MIPS32R6);

            case OPC_S_FMT:

            case OPC_D_FMT:

                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,

                           (imm >> 8) & 0x7);

                break;

            case OPC_W_FMT:

            case OPC_L_FMT:

            {

                int r6_op = ctx->opcode & FOP(0x3f, 0x1f);

                if (ctx->insn_flags & ISA_MIPS32R6) {

                    switch (r6_op) {

                    case R6_OPC_CMP_AF_S:

                    case R6_OPC_CMP_UN_S:

                    case R6_OPC_CMP_EQ_S:

                    case R6_OPC_CMP_UEQ_S:

                    case R6_OPC_CMP_LT_S:

                    case R6_OPC_CMP_ULT_S:

                    case R6_OPC_CMP_LE_S:

                    case R6_OPC_CMP_ULE_S:

                    case R6_OPC_CMP_SAF_S:

                    case R6_OPC_CMP_SUN_S:

                    case R6_OPC_CMP_SEQ_S:

                    case R6_OPC_CMP_SEUQ_S:

                    case R6_OPC_CMP_SLT_S:

                    case R6_OPC_CMP_SULT_S:

                    case R6_OPC_CMP_SLE_S:

                    case R6_OPC_CMP_SULE_S:

                    case R6_OPC_CMP_OR_S:

                    case R6_OPC_CMP_UNE_S:

                    case R6_OPC_CMP_NE_S:

                    case R6_OPC_CMP_SOR_S:

                    case R6_OPC_CMP_SUNE_S:

                    case R6_OPC_CMP_SNE_S:

                        gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);

                        break;

                    case R6_OPC_CMP_AF_D:

                    case R6_OPC_CMP_UN_D:

                    case R6_OPC_CMP_EQ_D:

                    case R6_OPC_CMP_UEQ_D:

                    case R6_OPC_CMP_LT_D:

                    case R6_OPC_CMP_ULT_D:

                    case R6_OPC_CMP_LE_D:

                    case R6_OPC_CMP_ULE_D:

                    case R6_OPC_CMP_SAF_D:

                    case R6_OPC_CMP_SUN_D:

                    case R6_OPC_CMP_SEQ_D:

                    case R6_OPC_CMP_SEUQ_D:

                    case R6_OPC_CMP_SLT_D:

                    case R6_OPC_CMP_SULT_D:

                    case R6_OPC_CMP_SLE_D:

                    case R6_OPC_CMP_SULE_D:

                    case R6_OPC_CMP_OR_D:

                    case R6_OPC_CMP_UNE_D:

                    case R6_OPC_CMP_NE_D:

                    case R6_OPC_CMP_SOR_D:

                    case R6_OPC_CMP_SUNE_D:

                    case R6_OPC_CMP_SNE_D:

                        gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);

                        break;

                    default:

                        gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,

                                                       (imm >> 8) & 0x7);

                        break;

                    }

                } else {

                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,

                               (imm >> 8) & 0x7);

                }

                break;

            }

            default:

                MIPS_INVAL("cp1");

                generate_exception (ctx, EXCP_RI);

                break;

            }

        } else {

            generate_exception_err(ctx, EXCP_CpU, 1);

        }

        break;

    /* Compact branches [R6] and COP2 [non-R6] */

    case OPC_BC: /* OPC_LWC2 */

    case OPC_BALC: /* OPC_SWC2 */

        if (ctx->insn_flags & ISA_MIPS32R6) {

            /* OPC_BC, OPC_BALC */

            gen_compute_compact_branch(ctx, op, 0, 0,

                                       sextract32(ctx->opcode << 2, 0, 28));

        } else {

            /* OPC_LWC2, OPC_SWC2 */

            /* COP2: Not implemented. */

            generate_exception_err(ctx, EXCP_CpU, 2);

        }

        break;

    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */

    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */

        if (ctx->insn_flags & ISA_MIPS32R6) {

            if (rs != 0) {

                /* OPC_BEQZC, OPC_BNEZC */

                gen_compute_compact_branch(ctx, op, rs, 0,

                                           sextract32(ctx->opcode << 2, 0, 23));

            } else {

                /* OPC_JIC, OPC_JIALC */

                gen_compute_compact_branch(ctx, op, 0, rt, imm);

            }

        } else {

            /* OPC_LWC2, OPC_SWC2 */

            /* COP2: Not implemented. */

            generate_exception_err(ctx, EXCP_CpU, 2);

        }

        break;

    case OPC_CP2:

        check_insn(ctx, INSN_LOONGSON2F);

        /* Note that these instructions use different fields.  */

        gen_loongson_multimedia(ctx, sa, rd, rt);

        break;

    case OPC_CP3:

        check_insn_opc_removed(ctx, ISA_MIPS32R6);

        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {

            check_cp1_enabled(ctx);

            op1 = MASK_CP3(ctx->opcode);

            switch (op1) {

            case OPC_LWXC1:

            case OPC_LDXC1:

            case OPC_LUXC1:

            case OPC_SWXC1:

            case OPC_SDXC1:

            case OPC_SUXC1:

                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);

                break;

            case OPC_PREFX:

                /* Treat as NOP. */

                break;

            case OPC_ALNV_PS:

            case OPC_MADD_S:

            case OPC_MADD_D:

            case OPC_MADD_PS:

            case OPC_MSUB_S:

            case OPC_MSUB_D:

            case OPC_MSUB_PS:

            case OPC_NMADD_S:

            case OPC_NMADD_D:

            case OPC_NMADD_PS:

            case OPC_NMSUB_S:

            case OPC_NMSUB_D:

            case OPC_NMSUB_PS:

                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);

                break;

            default:

                MIPS_INVAL("cp3");

                generate_exception (ctx, EXCP_RI);

                break;

            }

        } else {

            generate_exception_err(ctx, EXCP_CpU, 1);

        }

        break;

#if defined(TARGET_MIPS64)

    /* MIPS64 opcodes */

    case OPC_LDL ... OPC_LDR:

    case OPC_LLD:

        check_insn_opc_removed(ctx, ISA_MIPS32R6);

    case OPC_LWU:

    case OPC_LD:

        check_insn(ctx, ISA_MIPS3);

        check_mips_64(ctx);

        gen_ld(ctx, op, rt, rs, imm);

        break;

    case OPC_SDL ... OPC_SDR:

        check_insn_opc_removed(ctx, ISA_MIPS32R6);

    case OPC_SD:

        check_insn(ctx, ISA_MIPS3);

        check_mips_64(ctx);

        gen_st(ctx, op, rt, rs, imm);

        break;

    case OPC_SCD:

        check_insn_opc_removed(ctx, ISA_MIPS32R6);

        check_insn(ctx, ISA_MIPS3);

        check_mips_64(ctx);

        gen_st_cond(ctx, op, rt, rs, imm);

        break;

    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */

        if (ctx->insn_flags & ISA_MIPS32R6) {

            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */

            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);

        } else {

            /* OPC_DADDI */

            check_insn(ctx, ISA_MIPS3);

            check_mips_64(ctx);

            gen_arith_imm(ctx, op, rt, rs, imm);

        }

        break;

    case OPC_DADDIU:

        check_insn(ctx, ISA_MIPS3);

        check_mips_64(ctx);

        gen_arith_imm(ctx, op, rt, rs, imm);

        break;

#else

    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */

        if (ctx->insn_flags & ISA_MIPS32R6) {

            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);

        } else {

            MIPS_INVAL("major opcode");

            generate_exception(ctx, EXCP_RI);

        }

        break;

#endif

    case OPC_DAUI: /* OPC_JALX */

        if (ctx->insn_flags & ISA_MIPS32R6) {

#if defined(TARGET_MIPS64)

            /* OPC_DAUI */

            check_mips_64(ctx);

            if (rt != 0) {

                TCGv t0 = tcg_temp_new();

                gen_load_gpr(t0, rs);

                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);

                tcg_temp_free(t0);

            }

            MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);

#else

            generate_exception(ctx, EXCP_RI);

            MIPS_INVAL("major opcode");

#endif

        } else {

            /* OPC_JALX */

            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);

            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;

            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);

        }

        break;

    case OPC_MDMX:

        check_insn(ctx, ASE_MDMX);

        /* MDMX: Not implemented. */

        break;

    case OPC_PCREL:

        check_insn(ctx, ISA_MIPS32R6);

        gen_pcrel(ctx, rs, imm);

        break;

    default:            /* Invalid */

        MIPS_INVAL("major opcode");

        generate_exception(ctx, EXCP_RI);

        break;

    }

}


bool blk_dev_is_tray_open(BlockBackend *blk)

{

    if (blk->dev_ops && blk->dev_ops->is_tray_open) {

        return blk->dev_ops->is_tray_open(blk->dev_opaque);

    }

    return false;

}


static av_cold int tdsc_init(AVCodecContext *avctx)

{

    TDSCContext *ctx = avctx->priv_data;

    const AVCodec *codec;

    int ret;

    avctx->pix_fmt = AV_PIX_FMT_BGR24;

    /* These needs to be set to estimate buffer and frame size */

    if (!(avctx->width && avctx->height)) {

        av_log(avctx, AV_LOG_ERROR, "Video size not set.\n");

        return AVERROR_INVALIDDATA;

    }

    /* This value should be large enough for a RAW-only frame plus headers */

    ctx->deflatelen = avctx->width * avctx->height * (3 + 1);

    ret = av_reallocp(&ctx->deflatebuffer, ctx->deflatelen);

    if (ret < 0)

        return ret;

    /* Allocate reference and JPEG frame */

    ctx->refframe = av_frame_alloc();

    ctx->jpgframe = av_frame_alloc();

    if (!ctx->refframe || !ctx->jpgframe)

        return AVERROR(ENOMEM);

    /* Prepare everything needed for JPEG decoding */

    codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);

    if (!codec)

        return AVERROR_BUG;

    ctx->jpeg_avctx = avcodec_alloc_context3(codec);

    if (!ctx->jpeg_avctx)

        return AVERROR(ENOMEM);

    ctx->jpeg_avctx->flags = avctx->flags;

    ctx->jpeg_avctx->flags2 = avctx->flags2;

    ctx->jpeg_avctx->dct_algo = avctx->dct_algo;

    ctx->jpeg_avctx->idct_algo = avctx->idct_algo;;

    ret = avcodec_open2(ctx->jpeg_avctx, codec, NULL);

    if (ret < 0)

        return ret;

    /* Set the output pixel format on the reference frame */

    ctx->refframe->format = avctx->pix_fmt;

    return 0;

}


int hvf_vcpu_exec(CPUState *cpu)

{

    X86CPU *x86_cpu = X86_CPU(cpu);

    CPUX86State *env = &x86_cpu->env;

    int ret = 0;

    uint64_t rip = 0;

    cpu->halted = 0;

    if (hvf_process_events(cpu)) {

        return EXCP_HLT;

    }

    do {

        if (cpu->vcpu_dirty) {

            hvf_put_registers(cpu);

            cpu->vcpu_dirty = false;

        }

        if (hvf_inject_interrupts(cpu)) {

            return EXCP_INTERRUPT;

        }

        vmx_update_tpr(cpu);

        qemu_mutex_unlock_iothread();

        if (!cpu_is_bsp(X86_CPU(cpu)) && cpu->halted) {

            qemu_mutex_lock_iothread();

            return EXCP_HLT;

        }

        hv_return_t r  = hv_vcpu_run(cpu->hvf_fd);

        assert_hvf_ok(r);

        /* handle VMEXIT */

        uint64_t exit_reason = rvmcs(cpu->hvf_fd, VMCS_EXIT_REASON);

        uint64_t exit_qual = rvmcs(cpu->hvf_fd, VMCS_EXIT_QUALIFICATION);

        uint32_t ins_len = (uint32_t)rvmcs(cpu->hvf_fd,

                                           VMCS_EXIT_INSTRUCTION_LENGTH);

        uint64_t idtvec_info = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_INFO);

        hvf_store_events(cpu, ins_len, idtvec_info);

        rip = rreg(cpu->hvf_fd, HV_X86_RIP);

        RFLAGS(env) = rreg(cpu->hvf_fd, HV_X86_RFLAGS);

        env->eflags = RFLAGS(env);

        qemu_mutex_lock_iothread();

        update_apic_tpr(cpu);

        current_cpu = cpu;

        ret = 0;

        switch (exit_reason) {

        case EXIT_REASON_HLT: {

            macvm_set_rip(cpu, rip + ins_len);

            if (!((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&

                (EFLAGS(env) & IF_MASK))

                && !(cpu->interrupt_request & CPU_INTERRUPT_NMI) &&

                !(idtvec_info & VMCS_IDT_VEC_VALID)) {

                cpu->halted = 1;

                ret = EXCP_HLT;

            }

            ret = EXCP_INTERRUPT;

            break;

        }

        case EXIT_REASON_MWAIT: {

            ret = EXCP_INTERRUPT;

            break;

        }

            /* Need to check if MMIO or unmmaped fault */

        case EXIT_REASON_EPT_FAULT:

        {

            hvf_slot *slot;

            addr_t gpa = rvmcs(cpu->hvf_fd, VMCS_GUEST_PHYSICAL_ADDRESS);

            if (((idtvec_info & VMCS_IDT_VEC_VALID) == 0) &&

                ((exit_qual & EXIT_QUAL_NMIUDTI) != 0)) {

                vmx_set_nmi_blocking(cpu);

            }

            slot = hvf_find_overlap_slot(gpa, gpa);

            /* mmio */

            if (ept_emulation_fault(slot, gpa, exit_qual)) {

                struct x86_decode decode;

                load_regs(cpu);

                env->hvf_emul->fetch_rip = rip;

                decode_instruction(env, &decode);

                exec_instruction(env, &decode);

                store_regs(cpu);

                break;

            }

            break;

        }

        case EXIT_REASON_INOUT:

        {

            uint32_t in = (exit_qual & 8) != 0;

            uint32_t size =  (exit_qual & 7) + 1;

            uint32_t string =  (exit_qual & 16) != 0;

            uint32_t port =  exit_qual >> 16;

            /*uint32_t rep = (exit_qual & 0x20) != 0;*/

#if 1

            if (!string && in) {

                uint64_t val = 0;

                load_regs(cpu);

                hvf_handle_io(env, port, &val, 0, size, 1);

                if (size == 1) {

                    AL(env) = val;

                } else if (size == 2) {

                    AX(env) = val;

                } else if (size == 4) {

                    RAX(env) = (uint32_t)val;

                } else {

                    VM_PANIC("size");

                }

                RIP(env) += ins_len;

                store_regs(cpu);

                break;

            } else if (!string && !in) {

                RAX(env) = rreg(cpu->hvf_fd, HV_X86_RAX);

                hvf_handle_io(env, port, &RAX(env), 1, size, 1);

                macvm_set_rip(cpu, rip + ins_len);

                break;

            }

#endif

            struct x86_decode decode;

            load_regs(cpu);

            env->hvf_emul->fetch_rip = rip;

            decode_instruction(env, &decode);

            VM_PANIC_ON(ins_len != decode.len);

            exec_instruction(env, &decode);

            store_regs(cpu);

            break;

        }

        case EXIT_REASON_CPUID: {

            uint32_t rax = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RAX);

            uint32_t rbx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RBX);

            uint32_t rcx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);

            uint32_t rdx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);

            cpu_x86_cpuid(env, rax, rcx, &rax, &rbx, &rcx, &rdx);

            wreg(cpu->hvf_fd, HV_X86_RAX, rax);

            wreg(cpu->hvf_fd, HV_X86_RBX, rbx);

            wreg(cpu->hvf_fd, HV_X86_RCX, rcx);

            wreg(cpu->hvf_fd, HV_X86_RDX, rdx);

            macvm_set_rip(cpu, rip + ins_len);

            break;

        }

        case EXIT_REASON_XSETBV: {

            X86CPU *x86_cpu = X86_CPU(cpu);

            CPUX86State *env = &x86_cpu->env;

            uint32_t eax = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RAX);

            uint32_t ecx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);

            uint32_t edx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);

            if (ecx) {

                macvm_set_rip(cpu, rip + ins_len);

                break;

            }

            env->xcr0 = ((uint64_t)edx << 32) | eax;

            wreg(cpu->hvf_fd, HV_X86_XCR0, env->xcr0 | 1);

            macvm_set_rip(cpu, rip + ins_len);

            break;

        }

        case EXIT_REASON_INTR_WINDOW:

            vmx_clear_int_window_exiting(cpu);

            ret = EXCP_INTERRUPT;

            break;

        case EXIT_REASON_NMI_WINDOW:

            vmx_clear_nmi_window_exiting(cpu);

            ret = EXCP_INTERRUPT;

            break;

        case EXIT_REASON_EXT_INTR:

            /* force exit and allow io handling */

            ret = EXCP_INTERRUPT;

            break;

        case EXIT_REASON_RDMSR:

        case EXIT_REASON_WRMSR:

        {

            load_regs(cpu);

            if (exit_reason == EXIT_REASON_RDMSR) {

                simulate_rdmsr(cpu);

            } else {

                simulate_wrmsr(cpu);

            }

            RIP(env) += rvmcs(cpu->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);

            store_regs(cpu);

            break;

        }

        case EXIT_REASON_CR_ACCESS: {

            int cr;

            int reg;

            load_regs(cpu);

            cr = exit_qual & 15;

            reg = (exit_qual >> 8) & 15;

            switch (cr) {

            case 0x0: {

                macvm_set_cr0(cpu->hvf_fd, RRX(env, reg));

                break;

            }

            case 4: {

                macvm_set_cr4(cpu->hvf_fd, RRX(env, reg));

                break;

            }

            case 8: {

                X86CPU *x86_cpu = X86_CPU(cpu);

                if (exit_qual & 0x10) {

                    RRX(env, reg) = cpu_get_apic_tpr(x86_cpu->apic_state);

                } else {

                    int tpr = RRX(env, reg);

                    cpu_set_apic_tpr(x86_cpu->apic_state, tpr);

                    ret = EXCP_INTERRUPT;

                }

                break;

            }

            default:

                error_report("Unrecognized CR %d\n", cr);

                abort();

            }

            RIP(env) += ins_len;

            store_regs(cpu);

            break;

        }

        case EXIT_REASON_APIC_ACCESS: { /* TODO */

            struct x86_decode decode;

            load_regs(cpu);

            env->hvf_emul->fetch_rip = rip;

            decode_instruction(env, &decode);

            exec_instruction(env, &decode);

            store_regs(cpu);

            break;

        }

        case EXIT_REASON_TPR: {

            ret = 1;

            break;

        }

        case EXIT_REASON_TASK_SWITCH: {

            uint64_t vinfo = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_INFO);

            x68_segment_selector sel = {.sel = exit_qual & 0xffff};

            vmx_handle_task_switch(cpu, sel, (exit_qual >> 30) & 0x3,

             vinfo & VMCS_INTR_VALID, vinfo & VECTORING_INFO_VECTOR_MASK, vinfo

             & VMCS_INTR_T_MASK);

            break;

        }

        case EXIT_REASON_TRIPLE_FAULT: {

            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);

            ret = EXCP_INTERRUPT;

            break;

        }

        case EXIT_REASON_RDPMC:

            wreg(cpu->hvf_fd, HV_X86_RAX, 0);

            wreg(cpu->hvf_fd, HV_X86_RDX, 0);

            macvm_set_rip(cpu, rip + ins_len);

            break;

        case VMX_REASON_VMCALL:

            /* TODO: inject #GP fault */

            break;

        default:

            error_report("%llx: unhandled exit %llx\n", rip, exit_reason);

        }

    } while (ret == 0);

    return ret;

}


int intel_h263_decode_picture_header(MpegEncContext *s)

{

    int format;

    /* picture header */

    if (get_bits_long(&s->gb, 22) != 0x20) {

        av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n");

        return -1;

    }

    s->picture_number = get_bits(&s->gb, 8); /* picture timestamp */

    if (get_bits1(&s->gb) != 1) {

        av_log(s->avctx, AV_LOG_ERROR, "Bad marker\n");

        return -1;	/* marker */

    }

    if (get_bits1(&s->gb) != 0) {

        av_log(s->avctx, AV_LOG_ERROR, "Bad H263 id\n");

        return -1;	/* h263 id */

    }

    skip_bits1(&s->gb);	/* split screen off */

    skip_bits1(&s->gb);	/* camera  off */

    skip_bits1(&s->gb);	/* freeze picture release off */

    format = get_bits(&s->gb, 3);

    if (format != 7) {

        av_log(s->avctx, AV_LOG_ERROR, "Intel H263 free format not supported\n");

        return -1;

    }

    s->h263_plus = 0;

    s->pict_type = I_TYPE + get_bits1(&s->gb);

    s->unrestricted_mv = get_bits1(&s->gb);

    s->h263_long_vectors = s->unrestricted_mv;

    if (get_bits1(&s->gb) != 0) {

        av_log(s->avctx, AV_LOG_ERROR, "SAC not supported\n");

        return -1;	/* SAC: off */

    }

    if (get_bits1(&s->gb) != 0) {

        s->obmc= 1;

        av_log(s->avctx, AV_LOG_ERROR, "Advanced Prediction Mode not supported\n");

//        return -1;	/* advanced prediction mode: off */

    }

    if (get_bits1(&s->gb) != 0) {

        av_log(s->avctx, AV_LOG_ERROR, "PB frame mode no supported\n");

        return -1;	/* PB frame mode */

    }

    /* skip unknown header garbage */

    skip_bits(&s->gb, 41);

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

    skip_bits1(&s->gb);	/* Continuous Presence Multipoint mode: off */

    /* PEI */

    while (get_bits1(&s->gb) != 0) {

        skip_bits(&s->gb, 8);

    }

    s->f_code = 1;

    s->y_dc_scale_table=

    s->c_dc_scale_table= ff_mpeg1_dc_scale_table;

    return 0;

}


int bdrv_pwrite(BlockDriverState *bs, int64_t offset,

                const void *buf1, int count1)

{

    BlockDriver *drv = bs->drv;

    if (!drv)

        return -ENOMEDIUM;

    if (!drv->bdrv_pwrite)

        return bdrv_pwrite_em(bs, offset, buf1, count1);

    if (bdrv_wr_badreq_bytes(bs, offset, count1))

        return -EDOM;

    return drv->bdrv_pwrite(bs, offset, buf1, count1);

}


static int local_truncate(FsContext *ctx, V9fsPath *fs_path, off_t size)

{

    char *buffer;

    int ret;

    char *path = fs_path->data;

    buffer = rpath(ctx, path);

    ret = truncate(buffer, size);

    g_free(buffer);

    return ret;

}


static int stellaris_enet_can_receive(void *opaque)

{

    stellaris_enet_state *s = (stellaris_enet_state *)opaque;

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

        return 1;

    return (s->np < 31);

}


void acpi_memory_unplug_cb(MemHotplugState *mem_st,

                           DeviceState *dev, Error **errp)

{

    MemStatus *mdev;

    mdev = acpi_memory_slot_status(mem_st, dev, errp);

    if (!mdev) {

        return;

    }

    /* nvdimm device hot unplug is not supported yet. */

    assert(!object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM));

    mdev->is_enabled = false;

    mdev->dimm = NULL;

}


alloc_f(int argc, char **argv)

{

	int64_t offset;

	int nb_sectors;

	char s1[64];

	int num;

	int ret;

	const char *retstr;

	offset = cvtnum(argv[1]);

	if (offset & 0x1ff) {

		printf("offset %lld is not sector aligned\n",

			(long long)offset);

		return 0;

	}

	if (argc == 3)

		nb_sectors = cvtnum(argv[2]);

	else

		nb_sectors = 1;

	ret = bdrv_is_allocated(bs, offset >> 9, nb_sectors, &num);

	cvtstr(offset, s1, sizeof(s1));

	retstr = ret ? "allocated" : "not allocated";

	if (nb_sectors == 1)

		printf("sector %s at offset %s\n", retstr, s1);

	else

		printf("%d/%d sectors %s at offset %s\n",

			num, nb_sectors, retstr, s1);

	return 0;

}


static void hmp_cont_cb(void *opaque, int err)

{

    if (!err) {

        qmp_cont(NULL);

    }

}


static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)

{

    PCIDevice *pci_dev = PCI_DEVICE(s);

    PCIDeviceClass *pci_class = PCI_DEVICE_GET_CLASS(pci_dev);

    MegasasBaseClass *base_class = MEGASAS_DEVICE_GET_CLASS(s);

    struct mfi_ctrl_info info;

    size_t dcmd_size = sizeof(info);

    BusChild *kid;

    int num_pd_disks = 0;

    memset(&info, 0x0, cmd->iov_size);

    if (cmd->iov_size < dcmd_size) {

        trace_megasas_dcmd_invalid_xfer_len(cmd->index, cmd->iov_size,

                                            dcmd_size);

        return MFI_STAT_INVALID_PARAMETER;

    }

    info.pci.vendor = cpu_to_le16(pci_class->vendor_id);

    info.pci.device = cpu_to_le16(pci_class->device_id);

    info.pci.subvendor = cpu_to_le16(pci_class->subsystem_vendor_id);

    info.pci.subdevice = cpu_to_le16(pci_class->subsystem_id);

    /*

     * For some reason the firmware supports

     * only up to 8 device ports.

     * Despite supporting a far larger number

     * of devices for the physical devices.

     * So just display the first 8 devices

     * in the device port list, independent

     * of how many logical devices are actually

     * present.

     */

    info.host.type = MFI_INFO_HOST_PCIE;

    info.device.type = MFI_INFO_DEV_SAS3G;

    info.device.port_count = 8;

    QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {

        SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child);

        uint16_t pd_id;

        if (num_pd_disks < 8) {

            pd_id = ((sdev->id & 0xFF) << 8) | (sdev->lun & 0xFF);

            info.device.port_addr[num_pd_disks] =

                cpu_to_le64(megasas_get_sata_addr(pd_id));

        }

        num_pd_disks++;

    }

    memcpy(info.product_name, base_class->product_name, 24);

    snprintf(info.serial_number, 32, "%s", s->hba_serial);

    snprintf(info.package_version, 0x60, "%s-QEMU", qemu_hw_version());

    memcpy(info.image_component[0].name, "APP", 3);

    snprintf(info.image_component[0].version, 10, "%s-QEMU",

             base_class->product_version);

    memcpy(info.image_component[0].build_date, "Apr  1 2014", 11);

    memcpy(info.image_component[0].build_time, "12:34:56", 8);

    info.image_component_count = 1;

    if (pci_dev->has_rom) {

        uint8_t biosver[32];

        uint8_t *ptr;

        ptr = memory_region_get_ram_ptr(&pci_dev->rom);

        memcpy(biosver, ptr + 0x41, 31);

        memcpy(info.image_component[1].name, "BIOS", 4);

        memcpy(info.image_component[1].version, biosver,

               strlen((const char *)biosver));

        info.image_component_count++;

    }

    info.current_fw_time = cpu_to_le32(megasas_fw_time());

    info.max_arms = 32;

    info.max_spans = 8;

    info.max_arrays = MEGASAS_MAX_ARRAYS;

    info.max_lds = MFI_MAX_LD;

    info.max_cmds = cpu_to_le16(s->fw_cmds);

    info.max_sg_elements = cpu_to_le16(s->fw_sge);

    info.max_request_size = cpu_to_le32(MEGASAS_MAX_SECTORS);

    if (!megasas_is_jbod(s))

        info.lds_present = cpu_to_le16(num_pd_disks);

    info.pd_present = cpu_to_le16(num_pd_disks);

    info.pd_disks_present = cpu_to_le16(num_pd_disks);

    info.hw_present = cpu_to_le32(MFI_INFO_HW_NVRAM |

                                   MFI_INFO_HW_MEM |

                                   MFI_INFO_HW_FLASH);

    info.memory_size = cpu_to_le16(512);

    info.nvram_size = cpu_to_le16(32);

    info.flash_size = cpu_to_le16(16);

    info.raid_levels = cpu_to_le32(MFI_INFO_RAID_0);

    info.adapter_ops = cpu_to_le32(MFI_INFO_AOPS_RBLD_RATE |

                                    MFI_INFO_AOPS_SELF_DIAGNOSTIC |

                                    MFI_INFO_AOPS_MIXED_ARRAY);

    info.ld_ops = cpu_to_le32(MFI_INFO_LDOPS_DISK_CACHE_POLICY |

                               MFI_INFO_LDOPS_ACCESS_POLICY |

                               MFI_INFO_LDOPS_IO_POLICY |

                               MFI_INFO_LDOPS_WRITE_POLICY |

                               MFI_INFO_LDOPS_READ_POLICY);

    info.max_strips_per_io = cpu_to_le16(s->fw_sge);

    info.stripe_sz_ops.min = 3;

    info.stripe_sz_ops.max = ctz32(MEGASAS_MAX_SECTORS + 1);

    info.properties.pred_fail_poll_interval = cpu_to_le16(300);

    info.properties.intr_throttle_cnt = cpu_to_le16(16);

    info.properties.intr_throttle_timeout = cpu_to_le16(50);

    info.properties.rebuild_rate = 30;

    info.properties.patrol_read_rate = 30;

    info.properties.bgi_rate = 30;

    info.properties.cc_rate = 30;

    info.properties.recon_rate = 30;

    info.properties.cache_flush_interval = 4;

    info.properties.spinup_drv_cnt = 2;

    info.properties.spinup_delay = 6;

    info.properties.ecc_bucket_size = 15;

    info.properties.ecc_bucket_leak_rate = cpu_to_le16(1440);

    info.properties.expose_encl_devices = 1;

    info.properties.OnOffProperties = cpu_to_le32(MFI_CTRL_PROP_EnableJBOD);

    info.pd_ops = cpu_to_le32(MFI_INFO_PDOPS_FORCE_ONLINE |

                               MFI_INFO_PDOPS_FORCE_OFFLINE);

    info.pd_mix_support = cpu_to_le32(MFI_INFO_PDMIX_SAS |

                                       MFI_INFO_PDMIX_SATA |

                                       MFI_INFO_PDMIX_LD);

    cmd->iov_size -= dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg);

    return MFI_STAT_OK;

}


int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr){

    ThreadContext *c = avctx->internal->frame_thread_encoder;

    Task task;

    int ret;

    av_assert1(!*got_packet_ptr);

    if(frame){

        if(!(avctx->flags & CODEC_FLAG_INPUT_PRESERVED)){

            AVFrame *new = avcodec_alloc_frame();

            if(!new)

                return AVERROR(ENOMEM);

            pthread_mutex_lock(&c->buffer_mutex);

            ret = c->parent_avctx->get_buffer(c->parent_avctx, new);

            pthread_mutex_unlock(&c->buffer_mutex);

            if(ret<0)

                return ret;

            new->pts = frame->pts;

            new->quality = frame->quality;

            new->pict_type = frame->pict_type;

            av_image_copy(new->data, new->linesize, (const uint8_t **)frame->data, frame->linesize,

                          avctx->pix_fmt, avctx->width, avctx->height);

            frame = new;

        }

        task.index = c->task_index;

        task.indata = (void*)frame;

        pthread_mutex_lock(&c->task_fifo_mutex);

        av_fifo_generic_write(c->task_fifo, &task, sizeof(task), NULL);

        pthread_cond_signal(&c->task_fifo_cond);

        pthread_mutex_unlock(&c->task_fifo_mutex);

        c->task_index = (c->task_index+1) % BUFFER_SIZE;

        if(!c->finished_tasks[c->finished_task_index].outdata && (c->task_index - c->finished_task_index) % BUFFER_SIZE <= avctx->thread_count)

            return 0;

    }

    if(c->task_index == c->finished_task_index)

        return 0;

    pthread_mutex_lock(&c->finished_task_mutex);

    while (!c->finished_tasks[c->finished_task_index].outdata) {

        pthread_cond_wait(&c->finished_task_cond, &c->finished_task_mutex);

    }

    task = c->finished_tasks[c->finished_task_index];

    *pkt = *(AVPacket*)(task.outdata);

    av_freep(&c->finished_tasks[c->finished_task_index].outdata);

    c->finished_task_index = (c->finished_task_index+1) % BUFFER_SIZE;

    pthread_mutex_unlock(&c->finished_task_mutex);

    *got_packet_ptr = 1;

    return task.return_code;

}


int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,

                       void *opaque, int version_id)

{

    VMStateField *field = vmsd->fields;

    if (version_id > vmsd->version_id) {

        return -EINVAL;

    }

    if (version_id < vmsd->minimum_version_id_old) {

        return -EINVAL;

    }

    if  (version_id < vmsd->minimum_version_id) {

        return vmsd->load_state_old(f, opaque, version_id);

    }

    while(field->name) {

        if (field->version_id <= version_id) {

            void *base_addr = opaque + field->offset;

            int ret, i, n_elems = 1;

            if (field->flags & VMS_ARRAY) {

                n_elems = field->num;

            } else if (field->flags & VMS_VARRAY) {

                n_elems = *(size_t *)(opaque+field->num_offset);

            }

            if (field->flags & VMS_POINTER) {

                base_addr = *(void **)base_addr;

            }

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

                void *addr = base_addr + field->size * i;

                if (field->flags & VMS_STRUCT) {

                    ret = vmstate_load_state(f, field->vmsd, addr, version_id);

                } else {

                    ret = field->info->get(f, addr, field->size);

                }

                if (ret < 0) {

                    return ret;

                }

            }

        }

        field++;

    }

    if (vmsd->run_after_load)

        return vmsd->run_after_load(opaque);

    return 0;

}


static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,

                             TCGReg al, TCGReg ah, TCGReg bl, TCGReg bh)

{

    TCGReg tmp0 = TCG_TMP0;

    TCGReg tmp1 = ret;

    assert(ret != TCG_TMP0);

    if (ret == ah || ret == bh) {

        assert(ret != TCG_TMP1);

        tmp1 = TCG_TMP1;

    }

    switch (cond) {

    case TCG_COND_EQ:

    case TCG_COND_NE:

        tmp1 = tcg_out_reduce_eq2(s, tmp0, tmp1, al, ah, bl, bh);

        tcg_out_setcond(s, cond, ret, tmp1, TCG_REG_ZERO);

        break;

    default:

        tcg_out_setcond(s, TCG_COND_EQ, tmp0, ah, bh);

        tcg_out_setcond(s, tcg_unsigned_cond(cond), tmp1, al, bl);

        tcg_out_opc_reg(s, OPC_AND, tmp1, tmp1, tmp0);

        tcg_out_setcond(s, tcg_high_cond(cond), tmp0, ah, bh);

        tcg_out_opc_reg(s, OPC_OR, ret, tmp1, tmp0);

        break;

    }

}


static void display_mouse_define(DisplayChangeListener *dcl,

                                 QEMUCursor *c)

{

    SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);

    qemu_mutex_lock(&ssd->lock);

    if (c) {

        cursor_get(c);

    }

    cursor_put(ssd->cursor);

    ssd->cursor = c;

    ssd->hot_x = c->hot_x;

    ssd->hot_y = c->hot_y;

    g_free(ssd->ptr_move);

    ssd->ptr_move = NULL;

    g_free(ssd->ptr_define);

    ssd->ptr_define = qemu_spice_create_cursor_update(ssd, c, 0);

    qemu_mutex_unlock(&ssd->lock);

}


static inline void stw_phys_internal(hwaddr addr, uint32_t val,

                                     enum device_endian endian)

{

    uint8_t *ptr;

    MemoryRegionSection *section;

    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);

    if (!memory_region_is_ram(section->mr) || section->readonly) {

        addr = memory_region_section_addr(section, addr);

        if (memory_region_is_ram(section->mr)) {

            section = &phys_sections[phys_section_rom];

        }

#if defined(TARGET_WORDS_BIGENDIAN)

        if (endian == DEVICE_LITTLE_ENDIAN) {

            val = bswap16(val);

        }

#else

        if (endian == DEVICE_BIG_ENDIAN) {

            val = bswap16(val);

        }

#endif

        io_mem_write(section->mr, addr, val, 2);

    } else {

        unsigned long addr1;

        addr1 = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)

            + memory_region_section_addr(section, addr);

        /* RAM case */

        ptr = qemu_get_ram_ptr(addr1);

        switch (endian) {

        case DEVICE_LITTLE_ENDIAN:

            stw_le_p(ptr, val);

            break;

        case DEVICE_BIG_ENDIAN:

            stw_be_p(ptr, val);

            break;

        default:

            stw_p(ptr, val);

            break;

        }

        invalidate_and_set_dirty(addr1, 2);

    }

}


static void compute_scale_factors(unsigned char scale_code[SBLIMIT],

                                  unsigned char scale_factors[SBLIMIT][3],

                                  int sb_samples[3][12][SBLIMIT],

                                  int sblimit)

{

    int *p, vmax, v, n, i, j, k, code;

    int index, d1, d2;

    unsigned char *sf = &scale_factors[0][0];

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

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

            /* find the max absolute value */

            p = &sb_samples[i][0][j];

            vmax = abs(*p);

            for(k=1;k<12;k++) {

                p += SBLIMIT;

                v = abs(*p);

                if (v > vmax)

                    vmax = v;

            }

            /* compute the scale factor index using log 2 computations */

            if (vmax > 0) {

                n = av_log2(vmax);

                /* n is the position of the MSB of vmax. now

                   use at most 2 compares to find the index */

                index = (21 - n) * 3 - 3;

                if (index >= 0) {

                    while (vmax <= scale_factor_table[index+1])

                        index++;

                } else {

                    index = 0; /* very unlikely case of overflow */

                }

            } else {

                index = 63;

            }

#if 0

            printf("%2d:%d in=%x %x %d\n",

                   j, i, vmax, scale_factor_table[index], index);

#endif

            /* store the scale factor */

            assert(index >=0 && index <= 63);

            sf[i] = index;

        }

        /* compute the transmission factor : look if the scale factors

           are close enough to each other */

        d1 = scale_diff_table[sf[0] - sf[1] + 64];

        d2 = scale_diff_table[sf[1] - sf[2] + 64];

        /* handle the 25 cases */

        switch(d1 * 5 + d2) {

        case 0*5+0:

        case 0*5+4:

        case 3*5+4:

        case 4*5+0:

        case 4*5+4:

            code = 0;

            break;

        case 0*5+1:

        case 0*5+2:

        case 4*5+1:

        case 4*5+2:

            code = 3;

            sf[2] = sf[1];

            break;

        case 0*5+3:

        case 4*5+3:

            code = 3;

            sf[1] = sf[2];

            break;

        case 1*5+0:

        case 1*5+4:

        case 2*5+4:

            code = 1;

            sf[1] = sf[0];

            break;

        case 1*5+1:

        case 1*5+2:

        case 2*5+0:

        case 2*5+1:

        case 2*5+2:

            code = 2;

            sf[1] = sf[2] = sf[0];

            break;

        case 2*5+3:

        case 3*5+3:

            code = 2;

            sf[0] = sf[1] = sf[2];

            break;

        case 3*5+0:

        case 3*5+1:

        case 3*5+2:

            code = 2;

            sf[0] = sf[2] = sf[1];

            break;

        case 1*5+3:

            code = 2;

            if (sf[0] > sf[2])

              sf[0] = sf[2];

            sf[1] = sf[2] = sf[0];

            break;

        default:

            abort();

        }

#if 0

        printf("%d: %2d %2d %2d %d %d -> %d\n", j,

               sf[0], sf[1], sf[2], d1, d2, code);

#endif

        scale_code[j] = code;

        sf += 3;

    }

}


static void opt_new_stream(const char *opt, const char *arg)

{

    AVFormatContext *oc;

    if (nb_output_files <= 0) {

        fprintf(stderr, "At least one output file must be specified\n");

        ffmpeg_exit(1);

    }

    oc = output_files[nb_output_files - 1];

    if      (!strcmp(opt, "newvideo"   )) new_video_stream   (oc);

    else if (!strcmp(opt, "newaudio"   )) new_audio_stream   (oc);

    else if (!strcmp(opt, "newsubtitle")) new_subtitle_stream(oc);

    else assert(0);

}


static inline void RENAME(yuy2toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,

	unsigned int width, unsigned int height,

	int lumStride, int chromStride, int srcStride)

{

	unsigned y;

	const unsigned chromWidth= width>>1;

	for(y=0; y<height; y+=2)

	{

#ifdef HAVE_MMX

		asm volatile(

			"xor %%"REG_a", %%"REG_a"	\n\t"

			"pcmpeqw %%mm7, %%mm7		\n\t"

			"psrlw $8, %%mm7		\n\t" // FF,00,FF,00...

			".balign 16			\n\t"

			"1:				\n\t"

			PREFETCH" 64(%0, %%"REG_a", 4)	\n\t"

			"movq (%0, %%"REG_a", 4), %%mm0	\n\t" // YUYV YUYV(0)

			"movq 8(%0, %%"REG_a", 4), %%mm1\n\t" // YUYV YUYV(4)

			"movq %%mm0, %%mm2		\n\t" // YUYV YUYV(0)

			"movq %%mm1, %%mm3		\n\t" // YUYV YUYV(4)

			"psrlw $8, %%mm0		\n\t" // U0V0 U0V0(0)

			"psrlw $8, %%mm1		\n\t" // U0V0 U0V0(4)

			"pand %%mm7, %%mm2		\n\t" // Y0Y0 Y0Y0(0)

			"pand %%mm7, %%mm3		\n\t" // Y0Y0 Y0Y0(4)

			"packuswb %%mm1, %%mm0		\n\t" // UVUV UVUV(0)

			"packuswb %%mm3, %%mm2		\n\t" // YYYY YYYY(0)

			MOVNTQ" %%mm2, (%1, %%"REG_a", 2)\n\t"

			"movq 16(%0, %%"REG_a", 4), %%mm1\n\t" // YUYV YUYV(8)

			"movq 24(%0, %%"REG_a", 4), %%mm2\n\t" // YUYV YUYV(12)

			"movq %%mm1, %%mm3		\n\t" // YUYV YUYV(8)

			"movq %%mm2, %%mm4		\n\t" // YUYV YUYV(12)

			"psrlw $8, %%mm1		\n\t" // U0V0 U0V0(8)

			"psrlw $8, %%mm2		\n\t" // U0V0 U0V0(12)

			"pand %%mm7, %%mm3		\n\t" // Y0Y0 Y0Y0(8)

			"pand %%mm7, %%mm4		\n\t" // Y0Y0 Y0Y0(12)

			"packuswb %%mm2, %%mm1		\n\t" // UVUV UVUV(8)

			"packuswb %%mm4, %%mm3		\n\t" // YYYY YYYY(8)

			MOVNTQ" %%mm3, 8(%1, %%"REG_a", 2)\n\t"

			"movq %%mm0, %%mm2		\n\t" // UVUV UVUV(0)

			"movq %%mm1, %%mm3		\n\t" // UVUV UVUV(8)

			"psrlw $8, %%mm0		\n\t" // V0V0 V0V0(0)

			"psrlw $8, %%mm1		\n\t" // V0V0 V0V0(8)

			"pand %%mm7, %%mm2		\n\t" // U0U0 U0U0(0)

			"pand %%mm7, %%mm3		\n\t" // U0U0 U0U0(8)

			"packuswb %%mm1, %%mm0		\n\t" // VVVV VVVV(0)

			"packuswb %%mm3, %%mm2		\n\t" // UUUU UUUU(0)

			MOVNTQ" %%mm0, (%3, %%"REG_a")	\n\t"

			MOVNTQ" %%mm2, (%2, %%"REG_a")	\n\t"

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

			"cmp %4, %%"REG_a"		\n\t"

			" jb 1b				\n\t"

			::"r"(src), "r"(ydst), "r"(udst), "r"(vdst), "g" ((long)chromWidth)

			: "memory", "%"REG_a

		);

		ydst += lumStride;

		src  += srcStride;

		asm volatile(

			"xor %%"REG_a", %%"REG_a"	\n\t"

			".balign 16			\n\t"

			"1:				\n\t"

			PREFETCH" 64(%0, %%"REG_a", 4)	\n\t"

			"movq (%0, %%"REG_a", 4), %%mm0	\n\t" // YUYV YUYV(0)

			"movq 8(%0, %%"REG_a", 4), %%mm1\n\t" // YUYV YUYV(4)

			"movq 16(%0, %%"REG_a", 4), %%mm2\n\t" // YUYV YUYV(8)

			"movq 24(%0, %%"REG_a", 4), %%mm3\n\t" // YUYV YUYV(12)

			"pand %%mm7, %%mm0		\n\t" // Y0Y0 Y0Y0(0)

			"pand %%mm7, %%mm1		\n\t" // Y0Y0 Y0Y0(4)

			"pand %%mm7, %%mm2		\n\t" // Y0Y0 Y0Y0(8)

			"pand %%mm7, %%mm3		\n\t" // Y0Y0 Y0Y0(12)

			"packuswb %%mm1, %%mm0		\n\t" // YYYY YYYY(0)

			"packuswb %%mm3, %%mm2		\n\t" // YYYY YYYY(8)

			MOVNTQ" %%mm0, (%1, %%"REG_a", 2)\n\t"

			MOVNTQ" %%mm2, 8(%1, %%"REG_a", 2)\n\t"

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

			"cmp %4, %%"REG_a"		\n\t"

			" jb 1b				\n\t"

			::"r"(src), "r"(ydst), "r"(udst), "r"(vdst), "g" ((long)chromWidth)

			: "memory", "%"REG_a

		);

#else

		unsigned i;

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

		{

			ydst[2*i+0] 	= src[4*i+0];

			udst[i] 	= src[4*i+1];

			ydst[2*i+1] 	= src[4*i+2];

			vdst[i] 	= src[4*i+3];

		}

		ydst += lumStride;

		src  += srcStride;

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

		{

			ydst[2*i+0] 	= src[4*i+0];

			ydst[2*i+1] 	= src[4*i+2];

		}

#endif

		udst += chromStride;

		vdst += chromStride;

		ydst += lumStride;

		src  += srcStride;

	}

#ifdef HAVE_MMX

asm volatile(   EMMS" \n\t"

        	SFENCE" \n\t"

        	:::"memory");

#endif

}


static int huf_uncompress(GetByteContext *gb,

                          uint16_t *dst, int dst_size)

{

    int32_t src_size, im, iM;

    uint32_t nBits;

    uint64_t *freq;

    HufDec *hdec;

    int ret, i;

    src_size = bytestream2_get_le32(gb);

    im = bytestream2_get_le32(gb);

    iM = bytestream2_get_le32(gb);

    bytestream2_skip(gb, 4);

    nBits = bytestream2_get_le32(gb);

    if (im < 0 || im >= HUF_ENCSIZE ||

        iM < 0 || iM >= HUF_ENCSIZE ||

        src_size < 0)

        return AVERROR_INVALIDDATA;

    bytestream2_skip(gb, 4);

    freq = av_calloc(HUF_ENCSIZE, sizeof(*freq));

    hdec = av_calloc(HUF_DECSIZE, sizeof(*hdec));

    if (!freq || !hdec) {

        ret = AVERROR(ENOMEM);

        goto fail;

    }

    if ((ret = huf_unpack_enc_table(gb, im, iM, freq)) < 0)

        goto fail;

    if (nBits > 8 * bytestream2_get_bytes_left(gb)) {

        ret = AVERROR_INVALIDDATA;

        goto fail;

    }

    if ((ret = huf_build_dec_table(freq, im, iM, hdec)) < 0)

        goto fail;

    ret = huf_decode(freq, hdec, gb, nBits, iM, dst_size, dst);

fail:

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

        if (hdec[i].p)

            av_freep(&hdec[i].p);

    }

    av_free(freq);

    av_free(hdec);

    return ret;

}


static int hevc_frame_start(HEVCContext *s)

{

    HEVCLocalContext *lc = &s->HEVClc;

    int ret;

    memset(s->horizontal_bs, 0, 2 * s->bs_width * (s->bs_height + 1));

    memset(s->vertical_bs,   0, 2 * s->bs_width * (s->bs_height + 1));

    memset(s->cbf_luma,      0, s->sps->min_tb_width * s->sps->min_tb_height);

    memset(s->is_pcm,        0, s->sps->min_pu_width * s->sps->min_pu_height);

    lc->start_of_tiles_x = 0;

    s->is_decoded        = 0;

    if (s->pps->tiles_enabled_flag)

        lc->end_of_tiles_x = s->pps->column_width[0] << s->sps->log2_ctb_size;

    ret = ff_hevc_set_new_ref(s, s->sps->sao_enabled ? &s->sao_frame : &s->frame,

                              s->poc);

    if (ret < 0)

        goto fail;

    ret = ff_hevc_frame_rps(s);

    if (ret < 0) {

        av_log(s->avctx, AV_LOG_ERROR, "Error constructing the frame RPS.\n");

        goto fail;

    }

    ret = set_side_data(s);

    if (ret < 0)

        goto fail;

    av_frame_unref(s->output_frame);

    ret = ff_hevc_output_frame(s, s->output_frame, 0);

    if (ret < 0)

        goto fail;

    ff_thread_finish_setup(s->avctx);

    return 0;

fail:

    if (s->ref)

        ff_thread_report_progress(&s->ref->tf, INT_MAX, 0);

    s->ref = NULL;

    return ret;

}


static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,

                       int flags, FsCred *credp, V9fsFidOpenState *fs)

{

    char *path;

    int fd = -1;

    int err = -1;

    int serrno = 0;

    V9fsString fullname;

    char *buffer;

    /*

     * Mark all the open to not follow symlinks

     */

    flags |= O_NOFOLLOW;

    v9fs_string_init(&fullname);

    v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);

    path = fullname.data;

    /* Determine the security model */

    if (fs_ctx->export_flags & V9FS_SM_MAPPED) {

        buffer = rpath(fs_ctx, path);

        fd = open(buffer, flags, SM_LOCAL_MODE_BITS);

        if (fd == -1) {

            g_free(buffer);

            err = fd;

            goto out;

        }

        credp->fc_mode = credp->fc_mode|S_IFREG;

        /* Set cleint credentials in xattr */

        err = local_set_xattr(buffer, credp);

        if (err == -1) {

            serrno = errno;

            goto err_end;

        }

    } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {

        buffer = rpath(fs_ctx, path);

        fd = open(buffer, flags, SM_LOCAL_MODE_BITS);

        if (fd == -1) {

            g_free(buffer);

            err = fd;

            goto out;

        }

        credp->fc_mode = credp->fc_mode|S_IFREG;

        /* Set client credentials in .virtfs_metadata directory files */

        err = local_set_mapped_file_attr(fs_ctx, path, credp);

        if (err == -1) {

            serrno = errno;

            goto err_end;

        }

    } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||

               (fs_ctx->export_flags & V9FS_SM_NONE)) {

        buffer = rpath(fs_ctx, path);

        fd = open(buffer, flags, credp->fc_mode);

        if (fd == -1) {

            g_free(buffer);

            err = fd;

            goto out;

        }

        err = local_post_create_passthrough(fs_ctx, path, credp);

        if (err == -1) {

            serrno = errno;

            goto err_end;

        }

    }

    err = fd;

    fs->fd = fd;

    goto out;

err_end:

    close(fd);

    remove(buffer);

    errno = serrno;

    g_free(buffer);

out:

    v9fs_string_free(&fullname);

    return err;

}


static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_method)

{

    int j,k;

    int ch;

    int run, case_val;

    int switchtable[23] = {0,5,1,5,5,5,5,5,2,5,5,5,5,5,5,5,3,5,5,5,5,5,4};

    for (ch = 0; ch < channels; ch++) {

        for (j = 0; j < 64; ) {

            if((coding_method[ch][sb][j] - 8) > 22) {

                run = 1;

                case_val = 8;

            } else {

                switch (switchtable[coding_method[ch][sb][j]]) {

                    case 0: run = 10; case_val = 10; break;

                    case 1: run = 1; case_val = 16; break;

                    case 2: run = 5; case_val = 24; break;

                    case 3: run = 3; case_val = 30; break;

                    case 4: run = 1; case_val = 30; break;

                    case 5: run = 1; case_val = 8; break;

                    default: run = 1; case_val = 8; break;

                }

            }

            for (k = 0; k < run; k++)

                if (j + k < 128)

                    if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j])

                        if (k > 0) {

                           SAMPLES_NEEDED

                            //not debugged, almost never used

                            memset(&coding_method[ch][sb][j + k], case_val, k * sizeof(int8_t));

                            memset(&coding_method[ch][sb][j + k], case_val, 3 * sizeof(int8_t));

                        }

            j += run;

        }

    }

}


static void gen_mtdcrx(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);

        return;

    }

    /* NIP cannot be restored if the memory exception comes from an helper */

    gen_update_nip(ctx, ctx->nip - 4);

    gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],

                         cpu_gpr[rS(ctx->opcode)]);

    /* Note: Rc update flag set leads to undefined state of Rc0 */

#endif

}


int usb_packet_map(USBPacket *p, QEMUSGList *sgl)

{

    int is_write = (p->pid == USB_TOKEN_IN);

    target_phys_addr_t len;

    void *mem;

    int i;

    for (i = 0; i < sgl->nsg; i++) {

        len = sgl->sg[i].len;

        mem = cpu_physical_memory_map(sgl->sg[i].base, &len,

                                      is_write);

        if (!mem) {

            goto err;

        }

        qemu_iovec_add(&p->iov, mem, len);

        if (len != sgl->sg[i].len) {

            goto err;

        }

    }

    return 0;

err:

    usb_packet_unmap(p);

    return -1;

}


static void get_sensor_evt_status(IPMIBmcSim *ibs,

                                  uint8_t *cmd, unsigned int cmd_len,

                                  uint8_t *rsp, unsigned int *rsp_len,

                                  unsigned int max_rsp_len)

{

    IPMISensor *sens;

    IPMI_CHECK_CMD_LEN(3);

    if ((cmd[2] > MAX_SENSORS) ||

        !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {

        rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;

        return;

    }

    sens = ibs->sensors + cmd[2];

    IPMI_ADD_RSP_DATA(sens->reading);

    IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens));

    IPMI_ADD_RSP_DATA(sens->assert_states & 0xff);

    IPMI_ADD_RSP_DATA((sens->assert_states >> 8) & 0xff);

    IPMI_ADD_RSP_DATA(sens->deassert_states & 0xff);

    IPMI_ADD_RSP_DATA((sens->deassert_states >> 8) & 0xff);

}


void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64])

{

    int i;

    if (s->chroma_format == CHROMA_444) {

        encode_block(s, block[0], 0);

        encode_block(s, block[2], 2);

        encode_block(s, block[4], 4);

        encode_block(s, block[8], 8);

        encode_block(s, block[5], 5);

        encode_block(s, block[9], 9);

        if (16*s->mb_x+8 < s->width) {

            encode_block(s, block[1], 1);

            encode_block(s, block[3], 3);

            encode_block(s, block[6], 6);

            encode_block(s, block[10], 10);

            encode_block(s, block[7], 7);

            encode_block(s, block[11], 11);

        }

    } else {

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

            encode_block(s, block[i], i);

        }

        if (s->chroma_format == CHROMA_420) {

            encode_block(s, block[5], 5);

        } else {

            encode_block(s, block[6], 6);

            encode_block(s, block[5], 5);

            encode_block(s, block[7], 7);

        }

    }

}


int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,

                     int ret, int rw)

{

    int store = 0;

    /* Update page flags */

    if (!(*pte1p & 0x00000100)) {

        /* Update accessed flag */

        *pte1p |= 0x00000100;

        store = 1;

    }

    if (!(*pte1p & 0x00000080)) {

        if (rw == 1 && ret == 0) {

            /* Update changed flag */

            *pte1p |= 0x00000080;

            store = 1;

        } else {

            /* Force page fault for first write access */

            ctx->prot &= ~PAGE_WRITE;

        }

    }

    return store;

}


static void enable_device(AcpiPciHpState *s, unsigned bsel, int slot)

{

    s->acpi_pcihp_pci_status[bsel].device_present |= (1U << slot);

}


void ff_avg_h264_qpel16_mc12_msa(uint8_t *dst, const uint8_t *src,

                                 ptrdiff_t stride)

{

    avc_luma_midh_qrt_and_aver_dst_16w_msa(src - (2 * stride) - 2,

                                           stride, dst, stride, 16, 0);

}


int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,

                   void *log_ctx)

{

    char *tail, color_string2[128];

    const ColorEntry *entry;

    int len, hex_offset = 0;

    if (color_string[0] == '#') {

        hex_offset = 1;

    } else if (!strncmp(color_string, "0x", 2))

        hex_offset = 2;

    if (slen < 0)

        slen = strlen(color_string);

    av_strlcpy(color_string2, color_string + hex_offset,

               FFMIN(slen-hex_offset+1, sizeof(color_string2)));

    if ((tail = strchr(color_string2, ALPHA_SEP)))

        *tail++ = 0;

    len = strlen(color_string2);

    rgba_color[3] = 255;

    if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) {

        int rgba = av_get_random_seed();

        rgba_color[0] = rgba >> 24;

        rgba_color[1] = rgba >> 16;

        rgba_color[2] = rgba >> 8;

        rgba_color[3] = rgba;

    } else if (hex_offset ||

               strspn(color_string2, "0123456789ABCDEFabcdef") == len) {

        char *tail;

        unsigned int rgba = strtoul(color_string2, &tail, 16);

        if (*tail || (len != 6 && len != 8)) {

            av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string2);

            return AVERROR(EINVAL);

        }

        if (len == 8) {

            rgba_color[3] = rgba;

            rgba >>= 8;

        }

        rgba_color[0] = rgba >> 16;

        rgba_color[1] = rgba >> 8;

        rgba_color[2] = rgba;

    } else {

        entry = bsearch(color_string2,

                        color_table,

                        FF_ARRAY_ELEMS(color_table),

                        sizeof(ColorEntry),

                        color_table_compare);

        if (!entry) {

            av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string2);

            return AVERROR(EINVAL);

        }

        memcpy(rgba_color, entry->rgb_color, 3);

    }

    if (tail) {

        unsigned long int alpha;

        const char *alpha_string = tail;

        if (!strncmp(alpha_string, "0x", 2)) {

            alpha = strtoul(alpha_string, &tail, 16);

        } else {

            alpha = 255 * strtod(alpha_string, &tail);

        }

        if (tail == alpha_string || *tail || alpha > 255) {

            av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n",

                   alpha_string, color_string);

            return AVERROR(EINVAL);

        }

        rgba_color[3] = alpha;

    }

    return 0;

}


static int raw_inactivate(BlockDriverState *bs)

{

    int ret;

    uint64_t perm = 0;

    uint64_t shared = BLK_PERM_ALL;

    ret = raw_handle_perm_lock(bs, RAW_PL_PREPARE, perm, shared, NULL);

    if (ret) {

        return ret;

    }

    raw_handle_perm_lock(bs, RAW_PL_COMMIT, perm, shared, NULL);

    return 0;

}


static void qmp_output_type_any(Visitor *v, const char *name, QObject **obj,

                                Error **errp)

{

    QmpOutputVisitor *qov = to_qov(v);

    qobject_incref(*obj);

    qmp_output_add_obj(qov, name, *obj);

}


static int setup_sigcontext(struct target_sigcontext *sc,

                            CPUSH4State *regs, unsigned long mask)

{

    int err = 0;

    int i;

#define COPY(x)         __put_user(regs->x, &sc->sc_##x)

    COPY(gregs[0]); COPY(gregs[1]);

    COPY(gregs[2]); COPY(gregs[3]);

    COPY(gregs[4]); COPY(gregs[5]);

    COPY(gregs[6]); COPY(gregs[7]);

    COPY(gregs[8]); COPY(gregs[9]);

    COPY(gregs[10]); COPY(gregs[11]);

    COPY(gregs[12]); COPY(gregs[13]);

    COPY(gregs[14]); COPY(gregs[15]);

    COPY(gbr); COPY(mach);

    COPY(macl); COPY(pr);

    COPY(sr); COPY(pc);

#undef COPY

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

        __put_user(regs->fregs[i], &sc->sc_fpregs[i]);

    }

    __put_user(regs->fpscr, &sc->sc_fpscr);

    __put_user(regs->fpul, &sc->sc_fpul);

    /* non-iBCS2 extensions.. */

    __put_user(mask, &sc->oldmask);

    return err;

}


static void vfio_unmap_bar(VFIODevice *vdev, int nr)

{

    VFIOBAR *bar = &vdev->bars[nr];

    if (!bar->size) {

        return;

    }

    vfio_bar_quirk_teardown(vdev, nr);

    memory_region_del_subregion(&bar->mem, &bar->mmap_mem);

    munmap(bar->mmap, memory_region_size(&bar->mmap_mem));

    if (vdev->msix && vdev->msix->table_bar == nr) {

        memory_region_del_subregion(&bar->mem, &vdev->msix->mmap_mem);

        munmap(vdev->msix->mmap, memory_region_size(&vdev->msix->mmap_mem));

    }

    memory_region_destroy(&bar->mem);

}


static bool ept_emulation_fault(uint64_t ept_qual)

{

    int read, write;

    /* EPT fault on an instruction fetch doesn't make sense here */

    if (ept_qual & EPT_VIOLATION_INST_FETCH) {

        return false;

    }

    /* EPT fault must be a read fault or a write fault */

    read = ept_qual & EPT_VIOLATION_DATA_READ ? 1 : 0;

    write = ept_qual & EPT_VIOLATION_DATA_WRITE ? 1 : 0;

    if ((read | write) == 0) {

        return false;

    }

    /*

     * The EPT violation must have been caused by accessing a

     * guest-physical address that is a translation of a guest-linear

     * address.

     */

    if ((ept_qual & EPT_VIOLATION_GLA_VALID) == 0 ||

        (ept_qual & EPT_VIOLATION_XLAT_VALID) == 0) {

        return false;

    }

    return true;

}


yuv2rgba64_full_X_c_template(SwsContext *c, const int16_t *lumFilter,

                       const int32_t **lumSrc, int lumFilterSize,

                       const int16_t *chrFilter, const int32_t **chrUSrc,

                       const int32_t **chrVSrc, int chrFilterSize,

                       const int32_t **alpSrc, uint16_t *dest, int dstW,

                       int y, enum AVPixelFormat target, int hasAlpha, int eightbytes)

{

    int i;

    int A = 0xffff<<14;

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

        int j;

        int Y  = -0x40000000;

        int U  = -128 << 23; // 19

        int V  = -128 << 23;

        int R, G, B;

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

            Y += lumSrc[j][i]  * (unsigned)lumFilter[j];

        }

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

            U += chrUSrc[j][i] * (unsigned)chrFilter[j];

            V += chrVSrc[j][i] * (unsigned)chrFilter[j];

        }

        if (hasAlpha) {

            A = -0x40000000;

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

                A += alpSrc[j][i] * (unsigned)lumFilter[j];

            }

            A >>= 1;

            A += 0x20002000;

        }

        // 8bit: 12+15=27; 16-bit: 12+19=31

        Y  >>= 14; // 10

        Y += 0x10000;

        U  >>= 14;

        V  >>= 14;

        // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit

        Y -= c->yuv2rgb_y_offset;

        Y *= c->yuv2rgb_y_coeff;

        Y += 1 << 13; // 21

        // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit

        R = V * c->yuv2rgb_v2r_coeff;

        G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;

        B =                            U * c->yuv2rgb_u2b_coeff;

        // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit

        output_pixel(&dest[0], av_clip_uintp2(R_B + Y, 30) >> 14);

        output_pixel(&dest[1], av_clip_uintp2(  G + Y, 30) >> 14);

        output_pixel(&dest[2], av_clip_uintp2(B_R + Y, 30) >> 14);

        if (eightbytes) {

            output_pixel(&dest[3], av_clip_uintp2(A, 30) >> 14);

            dest += 4;

        } else {

            dest += 3;

        }

    }

}


static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,

                            int opc)

{

    int addr_regl, addr_reg1, addr_meml;

    int data_regl, data_regh, data_reg1, data_reg2;

    int mem_index, s_bits;

#if defined(CONFIG_SOFTMMU)

    void *label1_ptr, *label2_ptr;

    int sp_args;

#endif

#if TARGET_LONG_BITS == 64

# if defined(CONFIG_SOFTMMU)

    uint8_t *label3_ptr;

# endif

    int addr_regh, addr_reg2, addr_memh;

#endif

    data_regl = *args++;

    if (opc == 3)

        data_regh = *args++;

    else

        data_regh = 0;

    addr_regl = *args++;

#if TARGET_LONG_BITS == 64

    addr_regh = *args++;

#endif

    mem_index = *args;

    s_bits = opc & 3;

    if (opc == 3) {

#if defined(TCG_TARGET_WORDS_BIGENDIAN)

        data_reg1 = data_regh;

        data_reg2 = data_regl;

#else

        data_reg1 = data_regl;

        data_reg2 = data_regh;

#endif

    } else {

        data_reg1 = data_regl;

        data_reg2 = 0;

    }

#if TARGET_LONG_BITS == 64

# if defined(TCG_TARGET_WORDS_BIGENDIAN)

    addr_reg1 = addr_regh;

    addr_reg2 = addr_regl;

    addr_memh = 0;

    addr_meml = 4;

# else

    addr_reg1 = addr_regl;

    addr_reg2 = addr_regh;

    addr_memh = 4;

    addr_meml = 0;

# endif

#else

    addr_reg1 = addr_regl;

    addr_meml = 0;

#endif

#if defined(CONFIG_SOFTMMU)

    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);

    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);

    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);

    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,

                    offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_meml);

    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));

    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);

# if TARGET_LONG_BITS == 64

    label3_ptr = s->code_ptr;

    tcg_out_opc_imm(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT, 0);

    tcg_out_nop(s);

    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,

                    offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_memh);

    label1_ptr = s->code_ptr;

    tcg_out_opc_imm(s, OPC_BEQ, addr_regh, TCG_REG_AT, 0);

    tcg_out_nop(s);

    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);

# else

    label1_ptr = s->code_ptr;

    tcg_out_opc_imm(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT, 0);

    tcg_out_nop(s);

# endif

    /* slow path */

    sp_args = TCG_REG_A0;

    tcg_out_mov(s, sp_args++, addr_reg1);

# if TARGET_LONG_BITS == 64

    tcg_out_mov(s, sp_args++, addr_reg2);

# endif

    tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index);

    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);

    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);

    tcg_out_nop(s);

    switch(opc) {

    case 0:

        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);

        break;

    case 0 | 4:

        tcg_out_opc_sa(s, OPC_SLL, TCG_REG_V0, TCG_REG_V0, 24);

        tcg_out_opc_sa(s, OPC_SRA, data_reg1, TCG_REG_V0, 24);

        break;

    case 1:

        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);

        break;

    case 1 | 4:

        tcg_out_opc_sa(s, OPC_SLL, TCG_REG_V0, TCG_REG_V0, 16);

        tcg_out_opc_sa(s, OPC_SRA, data_reg1, TCG_REG_V0, 16);

        break;

    case 2:

        tcg_out_mov(s, data_reg1, TCG_REG_V0);

        break;

    case 3:

        tcg_out_mov(s, data_reg2, TCG_REG_V1);

        tcg_out_mov(s, data_reg1, TCG_REG_V0);

        break;

    default:

        tcg_abort();

    }

    label2_ptr = s->code_ptr;

    tcg_out_opc_imm(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO, 0);

    tcg_out_nop(s);

    /* label1: fast path */

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

    tcg_out_opc_imm(s, OPC_LW, TCG_REG_V0, TCG_REG_A0,

                    offsetof(CPUState, tlb_table[mem_index][0].addend) + addr_meml);

    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);

    addr_reg1 = TCG_REG_V0;

#endif

    switch(opc) {

    case 0:

        tcg_out_opc_imm(s, OPC_LBU, data_reg1, addr_reg1, 0);

        break;

    case 0 | 4:

        tcg_out_opc_imm(s, OPC_LB, data_reg1, addr_reg1, 0);

        break;

    case 1:

        if (TCG_NEED_BSWAP) {

            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, addr_reg1, 0);

            tcg_out_bswap16(s, data_reg1, TCG_REG_T0);

        } else {

            tcg_out_opc_imm(s, OPC_LHU, data_reg1, addr_reg1, 0);

        }

        break;

    case 1 | 4:

        if (TCG_NEED_BSWAP) {

            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, addr_reg1, 0);

            tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);

        } else {

            tcg_out_opc_imm(s, OPC_LH, data_reg1, addr_reg1, 0);

        }

        break;

    case 2:

        if (TCG_NEED_BSWAP) {

            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, addr_reg1, 0);

            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);

        } else {

            tcg_out_opc_imm(s, OPC_LW, data_reg1, addr_reg1, 0);

        }

        break;

    case 3:

#if !defined(CONFIG_SOFTMMU)

        tcg_out_mov(s, TCG_REG_V0, addr_reg1);

        addr_reg1 = TCG_REG_V0;

#endif

        if (TCG_NEED_BSWAP) {

            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, addr_reg1, 4);

            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);

            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, addr_reg1, 0);

            tcg_out_bswap32(s, data_reg2, TCG_REG_T0);

        } else {

            tcg_out_opc_imm(s, OPC_LW, data_reg1, addr_reg1, 0);

            tcg_out_opc_imm(s, OPC_LW, data_reg2, addr_reg1, 4);

        }

        break;

    default:

        tcg_abort();

    }

#if defined(CONFIG_SOFTMMU)

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

#endif

}


static void dec_calc(DisasContext *dc, uint32_t insn)

{

    uint32_t op0, op1, op2;

    uint32_t ra, rb, rd;

    op0 = extract32(insn, 0, 4);

    op1 = extract32(insn, 8, 2);

    op2 = extract32(insn, 6, 2);

    ra = extract32(insn, 16, 5);

    rb = extract32(insn, 11, 5);

    rd = extract32(insn, 21, 5);

    switch (op0) {

    case 0x0000:

        switch (op1) {

        case 0x00:    /* l.add */

            LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);

            {

                TCGLabel *lab = gen_new_label();

                TCGv_i64 ta = tcg_temp_new_i64();

                TCGv_i64 tb = tcg_temp_new_i64();

                TCGv_i64 td = tcg_temp_local_new_i64();

                TCGv_i32 res = tcg_temp_local_new_i32();

                TCGv_i32 sr_ove = tcg_temp_local_new_i32();

                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);

                tcg_gen_extu_i32_i64(tb, cpu_R[rb]);

                tcg_gen_add_i64(td, ta, tb);

                tcg_gen_extrl_i64_i32(res, td);

                tcg_gen_shri_i64(td, td, 31);

                tcg_gen_andi_i64(td, td, 0x3);

                /* Jump to lab when no overflow.  */

                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);

                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);

                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);

                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);

                gen_exception(dc, EXCP_RANGE);

                gen_set_label(lab);

                tcg_gen_mov_i32(cpu_R[rd], res);

                tcg_temp_free_i64(ta);

                tcg_temp_free_i64(tb);

                tcg_temp_free_i64(td);

                tcg_temp_free_i32(res);

                tcg_temp_free_i32(sr_ove);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0001:    /* l.addc */

        switch (op1) {

        case 0x00:

            LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);

            {

                TCGLabel *lab = gen_new_label();

                TCGv_i64 ta = tcg_temp_new_i64();

                TCGv_i64 tb = tcg_temp_new_i64();

                TCGv_i64 tcy = tcg_temp_local_new_i64();

                TCGv_i64 td = tcg_temp_local_new_i64();

                TCGv_i32 res = tcg_temp_local_new_i32();

                TCGv_i32 sr_cy = tcg_temp_local_new_i32();

                TCGv_i32 sr_ove = tcg_temp_local_new_i32();

                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);

                tcg_gen_extu_i32_i64(tb, cpu_R[rb]);

                tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY);

                tcg_gen_extu_i32_i64(tcy, sr_cy);

                tcg_gen_shri_i64(tcy, tcy, 10);

                tcg_gen_add_i64(td, ta, tb);

                tcg_gen_add_i64(td, td, tcy);

                tcg_gen_extrl_i64_i32(res, td);

                tcg_gen_shri_i64(td, td, 32);

                tcg_gen_andi_i64(td, td, 0x3);

                /* Jump to lab when no overflow.  */

                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);

                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);

                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);

                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);

                gen_exception(dc, EXCP_RANGE);

                gen_set_label(lab);

                tcg_gen_mov_i32(cpu_R[rd], res);

                tcg_temp_free_i64(ta);

                tcg_temp_free_i64(tb);

                tcg_temp_free_i64(tcy);

                tcg_temp_free_i64(td);

                tcg_temp_free_i32(res);

                tcg_temp_free_i32(sr_cy);

                tcg_temp_free_i32(sr_ove);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0002:    /* l.sub */

        switch (op1) {

        case 0x00:

            LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);

            {

                TCGLabel *lab = gen_new_label();

                TCGv_i64 ta = tcg_temp_new_i64();

                TCGv_i64 tb = tcg_temp_new_i64();

                TCGv_i64 td = tcg_temp_local_new_i64();

                TCGv_i32 res = tcg_temp_local_new_i32();

                TCGv_i32 sr_ove = tcg_temp_local_new_i32();

                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);

                tcg_gen_extu_i32_i64(tb, cpu_R[rb]);

                tcg_gen_sub_i64(td, ta, tb);

                tcg_gen_extrl_i64_i32(res, td);

                tcg_gen_shri_i64(td, td, 31);

                tcg_gen_andi_i64(td, td, 0x3);

                /* Jump to lab when no overflow.  */

                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);

                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);

                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);

                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);

                gen_exception(dc, EXCP_RANGE);

                gen_set_label(lab);

                tcg_gen_mov_i32(cpu_R[rd], res);

                tcg_temp_free_i64(ta);

                tcg_temp_free_i64(tb);

                tcg_temp_free_i64(td);

                tcg_temp_free_i32(res);

                tcg_temp_free_i32(sr_ove);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0003:    /* l.and */

        switch (op1) {

        case 0x00:

            LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb);

            tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0004:    /* l.or */

        switch (op1) {

        case 0x00:

            LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb);

            tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0005:

        switch (op1) {

        case 0x00:    /* l.xor */

            LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb);

            tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0006:

        switch (op1) {

        case 0x03:    /* l.mul */

            LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);

            if (ra != 0 && rb != 0) {

                gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);

            } else {

                tcg_gen_movi_tl(cpu_R[rd], 0x0);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0009:

        switch (op1) {

        case 0x03:    /* l.div */

            LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);

            {

                TCGLabel *lab0 = gen_new_label();

                TCGLabel *lab1 = gen_new_label();

                TCGLabel *lab2 = gen_new_label();

                TCGLabel *lab3 = gen_new_label();

                TCGv_i32 sr_ove = tcg_temp_local_new_i32();

                if (rb == 0) {

                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);

                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);

                    gen_exception(dc, EXCP_RANGE);

                    gen_set_label(lab0);

                } else {

                    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[rb],

                                       0x00000000, lab1);

                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[ra],

                                       0x80000000, lab2);

                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],

                                       0xffffffff, lab2);

                    gen_set_label(lab1);

                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);

                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab3);

                    gen_exception(dc, EXCP_RANGE);

                    gen_set_label(lab2);

                    tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

                    gen_set_label(lab3);

                }

                tcg_temp_free_i32(sr_ove);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x000a:

        switch (op1) {

        case 0x03:    /* l.divu */

            LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);

            {

                TCGLabel *lab0 = gen_new_label();

                TCGLabel *lab1 = gen_new_label();

                TCGLabel *lab2 = gen_new_label();

                TCGv_i32 sr_ove = tcg_temp_local_new_i32();

                if (rb == 0) {

                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);

                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);

                    gen_exception(dc, EXCP_RANGE);

                    gen_set_label(lab0);

                } else {

                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],

                                       0x00000000, lab1);

                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);

                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab2);

                    gen_exception(dc, EXCP_RANGE);

                    gen_set_label(lab1);

                    tcg_gen_divu_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

                    gen_set_label(lab2);

                }

                tcg_temp_free_i32(sr_ove);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x000b:

        switch (op1) {

        case 0x03:    /* l.mulu */

            LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);

            if (rb != 0 && ra != 0) {

                TCGv_i64 result = tcg_temp_local_new_i64();

                TCGv_i64 tra = tcg_temp_local_new_i64();

                TCGv_i64 trb = tcg_temp_local_new_i64();

                TCGv_i64 high = tcg_temp_new_i64();

                TCGv_i32 sr_ove = tcg_temp_local_new_i32();

                TCGLabel *lab = gen_new_label();

                /* Calculate each result. */

                tcg_gen_extu_i32_i64(tra, cpu_R[ra]);

                tcg_gen_extu_i32_i64(trb, cpu_R[rb]);

                tcg_gen_mul_i64(result, tra, trb);

                tcg_temp_free_i64(tra);

                tcg_temp_free_i64(trb);

                tcg_gen_shri_i64(high, result, TARGET_LONG_BITS);

                /* Overflow or not. */

                tcg_gen_brcondi_i64(TCG_COND_EQ, high, 0x00000000, lab);

                tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);

                tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab);

                gen_exception(dc, EXCP_RANGE);

                gen_set_label(lab);

                tcg_temp_free_i64(high);

                tcg_gen_trunc_i64_tl(cpu_R[rd], result);

                tcg_temp_free_i64(result);

                tcg_temp_free_i32(sr_ove);

            } else {

                tcg_gen_movi_tl(cpu_R[rd], 0);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x000e:

        switch (op1) {

        case 0x00:    /* l.cmov */

            LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);

            {

                TCGLabel *lab = gen_new_label();

                TCGv res = tcg_temp_local_new();

                TCGv sr_f = tcg_temp_new();

                tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);

                tcg_gen_mov_tl(res, cpu_R[rb]);

                tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab);

                tcg_gen_mov_tl(res, cpu_R[ra]);

                gen_set_label(lab);

                tcg_gen_mov_tl(cpu_R[rd], res);

                tcg_temp_free(sr_f);

                tcg_temp_free(res);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x000f:

        switch (op1) {

        case 0x00:    /* l.ff1 */

            LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb);

            tcg_gen_ctzi_tl(cpu_R[rd], cpu_R[ra], -1);

            tcg_gen_addi_tl(cpu_R[rd], cpu_R[rd], 1);

            break;

        case 0x01:    /* l.fl1 */

            LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb);

            tcg_gen_clzi_tl(cpu_R[rd], cpu_R[ra], TARGET_LONG_BITS);

            tcg_gen_subfi_tl(cpu_R[rd], TARGET_LONG_BITS, cpu_R[rd]);

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0008:

        switch (op1) {

        case 0x00:

            switch (op2) {

            case 0x00:    /* l.sll */

                LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);

                tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

                break;

            case 0x01:    /* l.srl */

                LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);

                tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

                break;

            case 0x02:    /* l.sra */

                LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);

                tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

                break;

            case 0x03:    /* l.ror */

                LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);

                tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

                break;

            default:

                gen_illegal_exception(dc);

                break;

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x000c:

        switch (op1) {

        case 0x00:

            switch (op2) {

            case 0x00:    /* l.exths */

                LOG_DIS("l.exths r%d, r%d\n", rd, ra);

                tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);

                break;

            case 0x01:    /* l.extbs */

                LOG_DIS("l.extbs r%d, r%d\n", rd, ra);

                tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);

                break;

            case 0x02:    /* l.exthz */

                LOG_DIS("l.exthz r%d, r%d\n", rd, ra);

                tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);

                break;

            case 0x03:    /* l.extbz */

                LOG_DIS("l.extbz r%d, r%d\n", rd, ra);

                tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);

                break;

            default:

                gen_illegal_exception(dc);

                break;

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x000d:

        switch (op1) {

        case 0x00:

            switch (op2) {

            case 0x00:    /* l.extws */

                LOG_DIS("l.extws r%d, r%d\n", rd, ra);

                tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);

                break;

            case 0x01:    /* l.extwz */

                LOG_DIS("l.extwz r%d, r%d\n", rd, ra);

                tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);

                break;

            default:

                gen_illegal_exception(dc);

                break;

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    default:

        gen_illegal_exception(dc);

        break;

    }

}


int qemu_calculate_timeout(void)

{

#ifndef CONFIG_IOTHREAD

    int timeout;

    if (!vm_running)

        timeout = 5000;

    else {

     /* XXX: use timeout computed from timers */

        int64_t add;

        int64_t delta;

        /* Advance virtual time to the next event.  */

	delta = qemu_icount_delta();

        if (delta > 0) {

            /* If virtual time is ahead of real time then just

               wait for IO.  */

            timeout = (delta + 999999) / 1000000;

        } else {

            /* Wait for either IO to occur or the next

               timer event.  */

            add = qemu_next_deadline();

            /* We advance the timer before checking for IO.

               Limit the amount we advance so that early IO

               activity won't get the guest too far ahead.  */

            if (add > 10000000)

                add = 10000000;

            delta += add;

            qemu_icount += qemu_icount_round (add);

            timeout = delta / 1000000;

            if (timeout < 0)

                timeout = 0;

        }

    }

    return timeout;

#else /* CONFIG_IOTHREAD */

    return 1000;

#endif

}


static int ftp_abort(URLContext *h)

{

    static const char *command = "ABOR\r\n";

    int err;

    static const int abor_codes[] = {225, 226, 0};

    FTPContext *s = h->priv_data;

    /* According to RCF 959:

       "ABOR command tells the server to abort the previous FTP

       service command and any associated transfer of data."

       There are FTP server implementations that don't response

       to any commands during data transfer in passive mode (including ABOR).

       This implementation closes data connection by force.

    */

    if (ftp_send_command(s, command, NULL, NULL) < 0) {

        ftp_close_both_connections(s);

        if ((err = ftp_connect_control_connection(h)) < 0) {

            av_log(h, AV_LOG_ERROR, "Reconnect failed.\n");

            return err;

        }

    } else {

        ftp_close_data_connection(s);

    }

    if (ftp_status(s, NULL, abor_codes) < 225) {

        /* wu-ftpd also closes control connection after data connection closing */

        ffurl_closep(&s->conn_control);

        if ((err = ftp_connect_control_connection(h)) < 0) {

            av_log(h, AV_LOG_ERROR, "Reconnect failed.\n");

            return err;

        }

    }

    return 0;

}