void register_cp_regs_for_features(ARMCPU *cpu)

{

    /* Register all the coprocessor registers based on feature bits */

    CPUARMState *env = &cpu->env;

    if (arm_feature(env, ARM_FEATURE_M)) {

        /* M profile has no coprocessor registers */

        return;

    }

    define_arm_cp_regs(cpu, cp_reginfo);

    if (!arm_feature(env, ARM_FEATURE_V8)) {

        /* Must go early as it is full of wildcards that may be

         * overridden by later definitions.

         */

        define_arm_cp_regs(cpu, not_v8_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_V6)) {

        /* The ID registers all have impdef reset values */

        ARMCPRegInfo v6_idregs[] = {

            { .name = "ID_PFR0", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_pfr0 },

            { .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_pfr1 },

            { .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_dfr0 },

            { .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_afr0 },

            { .name = "ID_MMFR0", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_mmfr0 },

            { .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_mmfr1 },

            { .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_mmfr2 },

            { .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_mmfr3 },

            { .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_isar0 },

            { .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_isar1 },

            { .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_isar2 },

            { .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_isar3 },

            { .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_isar4 },

            { .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_isar5 },

            { .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_mmfr4 },

            /* 7 is as yet unallocated and must RAZ */

            { .name = "ID_ISAR7_RESERVED", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            REGINFO_SENTINEL

        };

        define_arm_cp_regs(cpu, v6_idregs);

        define_arm_cp_regs(cpu, v6_cp_reginfo);

    } else {

        define_arm_cp_regs(cpu, not_v6_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_V6K)) {

        define_arm_cp_regs(cpu, v6k_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_V7MP) &&

        !arm_feature(env, ARM_FEATURE_PMSA)) {

        define_arm_cp_regs(cpu, v7mp_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_V7)) {

        /* v7 performance monitor control register: same implementor

         * field as main ID register, and we implement only the cycle

         * count register.

         */

#ifndef CONFIG_USER_ONLY

        ARMCPRegInfo pmcr = {

            .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,

            .access = PL0_RW,

            .type = ARM_CP_IO | ARM_CP_ALIAS,

            .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),

            .accessfn = pmreg_access, .writefn = pmcr_write,

            .raw_writefn = raw_write,

        };

        ARMCPRegInfo pmcr64 = {

            .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,

            .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,

            .access = PL0_RW, .accessfn = pmreg_access,

            .type = ARM_CP_IO,

            .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),

            .resetvalue = cpu->midr & 0xff000000,

            .writefn = pmcr_write, .raw_writefn = raw_write,

        };

        define_one_arm_cp_reg(cpu, &pmcr);

        define_one_arm_cp_reg(cpu, &pmcr64);

#endif

        ARMCPRegInfo clidr = {

            .name = "CLIDR", .state = ARM_CP_STATE_BOTH,

            .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,

            .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr

        };

        define_one_arm_cp_reg(cpu, &clidr);

        define_arm_cp_regs(cpu, v7_cp_reginfo);

        define_debug_regs(cpu);

    } else {

        define_arm_cp_regs(cpu, not_v7_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_V8)) {

        /* AArch64 ID registers, which all have impdef reset values.

         * Note that within the ID register ranges the unused slots

         * must all RAZ, not UNDEF; future architecture versions may

         * define new registers here.

         */

        ARMCPRegInfo v8_idregs[] = {

            { .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_aa64pfr0 },

            { .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_aa64pfr1},

            { .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64PFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 3,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64PFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64PFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64PFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 7,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_aa64dfr0 },

            { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_aa64dfr1 },

            { .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64DFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 3,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_aa64afr0 },

            { .name = "ID_AA64AFR1_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_aa64afr1 },

            { .name = "ID_AA64AFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 6,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64AFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 7,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_aa64isar0 },

            { .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_aa64isar1 },

            { .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64ISAR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 4,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64ISAR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 5,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64ISAR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 6,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64ISAR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 7,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_aa64mmfr0 },

            { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->id_aa64mmfr1 },

            { .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64MMFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 5,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64MMFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 6,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ID_AA64MMFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 7,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->mvfr0 },

            { .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->mvfr1 },

            { .name = "MVFR2_EL1", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->mvfr2 },

            { .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "MVFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "MVFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "MVFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "PMCEID0", .state = ARM_CP_STATE_AA32,

              .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6,

              .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,

              .resetvalue = cpu->pmceid0 },

            { .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6,

              .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,

              .resetvalue = cpu->pmceid0 },

            { .name = "PMCEID1", .state = ARM_CP_STATE_AA32,

              .cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 7,

              .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,

              .resetvalue = cpu->pmceid1 },

            { .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7,

              .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,

              .resetvalue = cpu->pmceid1 },

            REGINFO_SENTINEL

        };

        /* RVBAR_EL1 is only implemented if EL1 is the highest EL */

        if (!arm_feature(env, ARM_FEATURE_EL3) &&

            !arm_feature(env, ARM_FEATURE_EL2)) {

            ARMCPRegInfo rvbar = {

                .name = "RVBAR_EL1", .state = ARM_CP_STATE_AA64,

                .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,

                .type = ARM_CP_CONST, .access = PL1_R, .resetvalue = cpu->rvbar

            };

            define_one_arm_cp_reg(cpu, &rvbar);

        }

        define_arm_cp_regs(cpu, v8_idregs);

        define_arm_cp_regs(cpu, v8_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_EL2)) {

        uint64_t vmpidr_def = mpidr_read_val(env);

        ARMCPRegInfo vpidr_regs[] = {

            { .name = "VPIDR", .state = ARM_CP_STATE_AA32,

              .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,

              .access = PL2_RW, .accessfn = access_el3_aa32ns,

              .resetvalue = cpu->midr,

              .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },

            { .name = "VPIDR_EL2", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,

              .access = PL2_RW, .resetvalue = cpu->midr,

              .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },

            { .name = "VMPIDR", .state = ARM_CP_STATE_AA32,

              .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,

              .access = PL2_RW, .accessfn = access_el3_aa32ns,

              .resetvalue = vmpidr_def,

              .fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },

            { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,

              .access = PL2_RW,

              .resetvalue = vmpidr_def,

              .fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },

            REGINFO_SENTINEL

        };

        define_arm_cp_regs(cpu, vpidr_regs);

        define_arm_cp_regs(cpu, el2_cp_reginfo);

        /* RVBAR_EL2 is only implemented if EL2 is the highest EL */

        if (!arm_feature(env, ARM_FEATURE_EL3)) {

            ARMCPRegInfo rvbar = {

                .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,

                .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,

                .type = ARM_CP_CONST, .access = PL2_R, .resetvalue = cpu->rvbar

            };

            define_one_arm_cp_reg(cpu, &rvbar);

        }

    } else {

        /* If EL2 is missing but higher ELs are enabled, we need to

         * register the no_el2 reginfos.

         */

        if (arm_feature(env, ARM_FEATURE_EL3)) {

            /* When EL3 exists but not EL2, VPIDR and VMPIDR take the value

             * of MIDR_EL1 and MPIDR_EL1.

             */

            ARMCPRegInfo vpidr_regs[] = {

                { .name = "VPIDR_EL2", .state = ARM_CP_STATE_BOTH,

                  .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,

                  .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any,

                  .type = ARM_CP_CONST, .resetvalue = cpu->midr,

                  .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },

                { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_BOTH,

                  .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,

                  .access = PL2_RW, .accessfn = access_el3_aa32ns_aa64any,

                  .type = ARM_CP_NO_RAW,

                  .writefn = arm_cp_write_ignore, .readfn = mpidr_read },

                REGINFO_SENTINEL

            };

            define_arm_cp_regs(cpu, vpidr_regs);

            define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo);

        }

    }

    if (arm_feature(env, ARM_FEATURE_EL3)) {

        define_arm_cp_regs(cpu, el3_cp_reginfo);

        ARMCPRegInfo el3_regs[] = {

            { .name = "RVBAR_EL3", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 1,

              .type = ARM_CP_CONST, .access = PL3_R, .resetvalue = cpu->rvbar },

            { .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 0,

              .access = PL3_RW,

              .raw_writefn = raw_write, .writefn = sctlr_write,

              .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]),

              .resetvalue = cpu->reset_sctlr },

            REGINFO_SENTINEL

        };

        define_arm_cp_regs(cpu, el3_regs);

    }

    /* The behaviour of NSACR is sufficiently various that we don't

     * try to describe it in a single reginfo:

     *  if EL3 is 64 bit, then trap to EL3 from S EL1,

     *     reads as constant 0xc00 from NS EL1 and NS EL2

     *  if EL3 is 32 bit, then RW at EL3, RO at NS EL1 and NS EL2

     *  if v7 without EL3, register doesn't exist

     *  if v8 without EL3, reads as constant 0xc00 from NS EL1 and NS EL2

     */

    if (arm_feature(env, ARM_FEATURE_EL3)) {

        if (arm_feature(env, ARM_FEATURE_AARCH64)) {

            ARMCPRegInfo nsacr = {

                .name = "NSACR", .type = ARM_CP_CONST,

                .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,

                .access = PL1_RW, .accessfn = nsacr_access,

                .resetvalue = 0xc00

            };

            define_one_arm_cp_reg(cpu, &nsacr);

        } else {

            ARMCPRegInfo nsacr = {

                .name = "NSACR",

                .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,

                .access = PL3_RW | PL1_R,

                .resetvalue = 0,

                .fieldoffset = offsetof(CPUARMState, cp15.nsacr)

            };

            define_one_arm_cp_reg(cpu, &nsacr);

        }

    } else {

        if (arm_feature(env, ARM_FEATURE_V8)) {

            ARMCPRegInfo nsacr = {

                .name = "NSACR", .type = ARM_CP_CONST,

                .cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,

                .access = PL1_R,

                .resetvalue = 0xc00

            };

            define_one_arm_cp_reg(cpu, &nsacr);

        }

    }

    if (arm_feature(env, ARM_FEATURE_PMSA)) {

        if (arm_feature(env, ARM_FEATURE_V6)) {

            /* PMSAv6 not implemented */

            assert(arm_feature(env, ARM_FEATURE_V7));

            define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);

            define_arm_cp_regs(cpu, pmsav7_cp_reginfo);

        } else {

            define_arm_cp_regs(cpu, pmsav5_cp_reginfo);

        }

    } else {

        define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);

        define_arm_cp_regs(cpu, vmsa_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {

        define_arm_cp_regs(cpu, t2ee_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {

        define_arm_cp_regs(cpu, generic_timer_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_VAPA)) {

        define_arm_cp_regs(cpu, vapa_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_CACHE_TEST_CLEAN)) {

        define_arm_cp_regs(cpu, cache_test_clean_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_CACHE_DIRTY_REG)) {

        define_arm_cp_regs(cpu, cache_dirty_status_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_CACHE_BLOCK_OPS)) {

        define_arm_cp_regs(cpu, cache_block_ops_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_OMAPCP)) {

        define_arm_cp_regs(cpu, omap_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_STRONGARM)) {

        define_arm_cp_regs(cpu, strongarm_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_XSCALE)) {

        define_arm_cp_regs(cpu, xscale_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_DUMMY_C15_REGS)) {

        define_arm_cp_regs(cpu, dummy_c15_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_LPAE)) {

        define_arm_cp_regs(cpu, lpae_cp_reginfo);

    }

    /* Slightly awkwardly, the OMAP and StrongARM cores need all of

     * cp15 crn=0 to be writes-ignored, whereas for other cores they should

     * be read-only (ie write causes UNDEF exception).

     */

    {

        ARMCPRegInfo id_pre_v8_midr_cp_reginfo[] = {

            /* Pre-v8 MIDR space.

             * Note that the MIDR isn't a simple constant register because

             * of the TI925 behaviour where writes to another register can

             * cause the MIDR value to change.

             *

             * Unimplemented registers in the c15 0 0 0 space default to

             * MIDR. Define MIDR first as this entire space, then CTR, TCMTR

             * and friends override accordingly.

             */

            { .name = "MIDR",

              .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = CP_ANY,

              .access = PL1_R, .resetvalue = cpu->midr,

              .writefn = arm_cp_write_ignore, .raw_writefn = raw_write,

              .readfn = midr_read,

              .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),

              .type = ARM_CP_OVERRIDE },

            /* crn = 0 op1 = 0 crm = 3..7 : currently unassigned; we RAZ. */

            { .name = "DUMMY",

              .cp = 15, .crn = 0, .crm = 3, .opc1 = 0, .opc2 = CP_ANY,

              .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },

            { .name = "DUMMY",

              .cp = 15, .crn = 0, .crm = 4, .opc1 = 0, .opc2 = CP_ANY,

              .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },

            { .name = "DUMMY",

              .cp = 15, .crn = 0, .crm = 5, .opc1 = 0, .opc2 = CP_ANY,

              .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },

            { .name = "DUMMY",

              .cp = 15, .crn = 0, .crm = 6, .opc1 = 0, .opc2 = CP_ANY,

              .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },

            { .name = "DUMMY",

              .cp = 15, .crn = 0, .crm = 7, .opc1 = 0, .opc2 = CP_ANY,

              .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },

            REGINFO_SENTINEL

        };

        ARMCPRegInfo id_v8_midr_cp_reginfo[] = {

            { .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 0,

              .access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr,

              .fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),

              .readfn = midr_read },

            /* crn = 0 op1 = 0 crm = 0 op2 = 4,7 : AArch32 aliases of MIDR */

            { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,

              .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,

              .access = PL1_R, .resetvalue = cpu->midr },

            { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,

              .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 7,

              .access = PL1_R, .resetvalue = cpu->midr },

            { .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,

              .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr },

            REGINFO_SENTINEL

        };

        ARMCPRegInfo id_cp_reginfo[] = {

            /* These are common to v8 and pre-v8 */

            { .name = "CTR",

              .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,

              .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },

            { .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,

              .access = PL0_R, .accessfn = ctr_el0_access,

              .type = ARM_CP_CONST, .resetvalue = cpu->ctr },

            /* TCMTR and TLBTR exist in v8 but have no 64-bit versions */

            { .name = "TCMTR",

              .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2,

              .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },

            REGINFO_SENTINEL

        };

        /* TLBTR is specific to VMSA */

        ARMCPRegInfo id_tlbtr_reginfo = {

              .name = "TLBTR",

              .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3,

              .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0,

        };

        /* MPUIR is specific to PMSA V6+ */

        ARMCPRegInfo id_mpuir_reginfo = {

              .name = "MPUIR",

              .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,

              .access = PL1_R, .type = ARM_CP_CONST,

              .resetvalue = cpu->pmsav7_dregion << 8

        };

        ARMCPRegInfo crn0_wi_reginfo = {

            .name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,

            .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,

            .type = ARM_CP_NOP | ARM_CP_OVERRIDE

        };

        if (arm_feature(env, ARM_FEATURE_OMAPCP) ||

            arm_feature(env, ARM_FEATURE_STRONGARM)) {

            ARMCPRegInfo *r;

            /* Register the blanket "writes ignored" value first to cover the

             * whole space. Then update the specific ID registers to allow write

             * access, so that they ignore writes rather than causing them to

             * UNDEF.

             */

            define_one_arm_cp_reg(cpu, &crn0_wi_reginfo);

            for (r = id_pre_v8_midr_cp_reginfo;

                 r->type != ARM_CP_SENTINEL; r++) {

                r->access = PL1_RW;

            }

            for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) {

                r->access = PL1_RW;

            }

            id_tlbtr_reginfo.access = PL1_RW;

            id_tlbtr_reginfo.access = PL1_RW;

        }

        if (arm_feature(env, ARM_FEATURE_V8)) {

            define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo);

        } else {

            define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo);

        }

        define_arm_cp_regs(cpu, id_cp_reginfo);

        if (!arm_feature(env, ARM_FEATURE_PMSA)) {

            define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo);

        } else if (arm_feature(env, ARM_FEATURE_V7)) {

            define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);

        }

    }

    if (arm_feature(env, ARM_FEATURE_MPIDR)) {

        define_arm_cp_regs(cpu, mpidr_cp_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_AUXCR)) {

        ARMCPRegInfo auxcr_reginfo[] = {

            { .name = "ACTLR_EL1", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 1,

              .access = PL1_RW, .type = ARM_CP_CONST,

              .resetvalue = cpu->reset_auxcr },

            { .name = "ACTLR_EL2", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 1,

              .access = PL2_RW, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            { .name = "ACTLR_EL3", .state = ARM_CP_STATE_AA64,

              .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 1,

              .access = PL3_RW, .type = ARM_CP_CONST,

              .resetvalue = 0 },

            REGINFO_SENTINEL

        };

        define_arm_cp_regs(cpu, auxcr_reginfo);

    }

    if (arm_feature(env, ARM_FEATURE_CBAR)) {

        if (arm_feature(env, ARM_FEATURE_AARCH64)) {

            /* 32 bit view is [31:18] 0...0 [43:32]. */

            uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)

                | extract64(cpu->reset_cbar, 32, 12);

            ARMCPRegInfo cbar_reginfo[] = {

                { .name = "CBAR",

                  .type = ARM_CP_CONST,

                  .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0,

                  .access = PL1_R, .resetvalue = cpu->reset_cbar },

                { .name = "CBAR_EL1", .state = ARM_CP_STATE_AA64,

                  .type = ARM_CP_CONST,

                  .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 0,

                  .access = PL1_R, .resetvalue = cbar32 },

                REGINFO_SENTINEL

            };

            /* We don't implement a r/w 64 bit CBAR currently */

            assert(arm_feature(env, ARM_FEATURE_CBAR_RO));

            define_arm_cp_regs(cpu, cbar_reginfo);

        } else {

            ARMCPRegInfo cbar = {

                .name = "CBAR",

                .cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0,

                .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar,

                .fieldoffset = offsetof(CPUARMState,

                                        cp15.c15_config_base_address)

            };

            if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {

                cbar.access = PL1_R;

                cbar.fieldoffset = 0;

                cbar.type = ARM_CP_CONST;

            }

            define_one_arm_cp_reg(cpu, &cbar);

        }

    }

    if (arm_feature(env, ARM_FEATURE_VBAR)) {

        ARMCPRegInfo vbar_cp_reginfo[] = {

            { .name = "VBAR", .state = ARM_CP_STATE_BOTH,

              .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,

              .access = PL1_RW, .writefn = vbar_write,

              .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),

                                     offsetof(CPUARMState, cp15.vbar_ns) },

              .resetvalue = 0 },

            REGINFO_SENTINEL

        };

        define_arm_cp_regs(cpu, vbar_cp_reginfo);

    }

    /* Generic registers whose values depend on the implementation */

    {

        ARMCPRegInfo sctlr = {

            .name = "SCTLR", .state = ARM_CP_STATE_BOTH,

            .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,

            .access = PL1_RW,

            .bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),

                                   offsetof(CPUARMState, cp15.sctlr_ns) },

            .writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,

            .raw_writefn = raw_write,

        };

        if (arm_feature(env, ARM_FEATURE_XSCALE)) {

            /* Normally we would always end the TB on an SCTLR write, but Linux

             * arch/arm/mach-pxa/sleep.S expects two instructions following

             * an MMU enable to execute from cache.  Imitate this behaviour.

             */

            sctlr.type |= ARM_CP_SUPPRESS_TB_END;

        }

        define_one_arm_cp_reg(cpu, &sctlr);

    }

}


static void pci_nic_uninit(PCIDevice *pci_dev)

{

    EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);

    vmstate_unregister(&pci_dev->qdev, s->vmstate, s);

    eeprom93xx_free(&pci_dev->qdev, s->eeprom);

    qemu_del_nic(s->nic);

}


void helper_mtc0_status(CPUMIPSState *env, target_ulong arg1)

{

    MIPSCPU *cpu = mips_env_get_cpu(env);

    uint32_t val, old;

    uint32_t mask = env->CP0_Status_rw_bitmask;

    if (env->insn_flags & ISA_MIPS32R6) {

        if (extract32(env->CP0_Status, CP0St_KSU, 2) == 0x3) {

            mask &= ~(3 << CP0St_KSU);

        }

        mask &= ~(0x00180000 & arg1);

    }

    val = arg1 & mask;

    old = env->CP0_Status;

    env->CP0_Status = (env->CP0_Status & ~mask) | val;

    if (env->CP0_Config3 & (1 << CP0C3_MT)) {

        sync_c0_status(env, env, env->current_tc);

    } else {

        compute_hflags(env);

    }

    if (qemu_loglevel_mask(CPU_LOG_EXEC)) {

        qemu_log("Status %08x (%08x) => %08x (%08x) Cause %08x",

                old, old & env->CP0_Cause & CP0Ca_IP_mask,

                val, val & env->CP0_Cause & CP0Ca_IP_mask,

                env->CP0_Cause);

        switch (env->hflags & MIPS_HFLAG_KSU) {

        case MIPS_HFLAG_UM: qemu_log(", UM\n"); break;

        case MIPS_HFLAG_SM: qemu_log(", SM\n"); break;

        case MIPS_HFLAG_KM: qemu_log("\n"); break;

        default:

            cpu_abort(CPU(cpu), "Invalid MMU mode!\n");

            break;

        }

    }

}


void av_register_all(void)

{

    static int initialized;

    if (initialized)

        return;

    initialized = 1;

    avcodec_init();

    avcodec_register_all();

    /* (de)muxers */

    REGISTER_DEMUXER  (AAC, aac);

    REGISTER_MUXDEMUX (AC3, ac3);

    REGISTER_MUXER    (ADTS, adts);

    REGISTER_MUXDEMUX (AIFF, aiff);

    REGISTER_MUXDEMUX (AMR, amr);

    REGISTER_DEMUXER  (APC, apc);

    REGISTER_DEMUXER  (APE, ape);

    REGISTER_MUXDEMUX (ASF, asf);

    REGISTER_MUXER    (ASF_STREAM, asf_stream);

    REGISTER_MUXDEMUX (AU, au);

    REGISTER_MUXDEMUX (AVI, avi);

    REGISTER_DEMUXER  (AVISYNTH, avisynth);

    REGISTER_MUXER    (AVM2, avm2);

    REGISTER_DEMUXER  (AVS, avs);

    REGISTER_DEMUXER  (BETHSOFTVID, bethsoftvid);

    REGISTER_DEMUXER  (BFI, bfi);

    REGISTER_DEMUXER  (C93, c93);

    REGISTER_MUXER    (CRC, crc);

    REGISTER_DEMUXER  (DAUD, daud);

    REGISTER_MUXDEMUX (DIRAC, dirac);

    REGISTER_DEMUXER  (DSICIN, dsicin);

    REGISTER_MUXDEMUX (DTS, dts);

    REGISTER_MUXDEMUX (DV, dv);

    REGISTER_DEMUXER  (DXA, dxa);

    REGISTER_DEMUXER  (EA, ea);

    REGISTER_DEMUXER  (EA_CDATA, ea_cdata);

    REGISTER_MUXDEMUX (FFM, ffm);

    REGISTER_MUXDEMUX (FLAC, flac);

    REGISTER_DEMUXER  (FLIC, flic);

    REGISTER_MUXDEMUX (FLV, flv);

    REGISTER_DEMUXER  (FOURXM, fourxm);

    REGISTER_MUXER    (FRAMECRC, framecrc);

    REGISTER_MUXDEMUX (GIF, gif);

    REGISTER_DEMUXER  (GSM, gsm);

    REGISTER_MUXDEMUX (GXF, gxf);

    REGISTER_MUXDEMUX (H261, h261);

    REGISTER_MUXDEMUX (H263, h263);

    REGISTER_MUXDEMUX (H264, h264);

    REGISTER_DEMUXER  (IDCIN, idcin);

    REGISTER_DEMUXER  (IFF, iff);

    REGISTER_MUXDEMUX (IMAGE2, image2);

    REGISTER_MUXDEMUX (IMAGE2PIPE, image2pipe);

    REGISTER_DEMUXER  (INGENIENT, ingenient);

    REGISTER_DEMUXER  (IPMOVIE, ipmovie);

    REGISTER_MUXER    (IPOD, ipod);

    REGISTER_DEMUXER  (LMLM4, lmlm4);

    REGISTER_MUXDEMUX (M4V, m4v);

    REGISTER_MUXDEMUX (MATROSKA, matroska);

    REGISTER_MUXER    (MATROSKA_AUDIO, matroska_audio);

    REGISTER_MUXDEMUX (MJPEG, mjpeg);

    REGISTER_DEMUXER  (MLP, mlp);

    REGISTER_DEMUXER  (MM, mm);

    REGISTER_MUXDEMUX (MMF, mmf);

    REGISTER_MUXDEMUX (MOV, mov);

    REGISTER_MUXER    (MP2, mp2);

    REGISTER_MUXDEMUX (MP3, mp3);

    REGISTER_MUXER    (MP4, mp4);

    REGISTER_DEMUXER  (MPC, mpc);

    REGISTER_DEMUXER  (MPC8, mpc8);

    REGISTER_MUXER    (MPEG1SYSTEM, mpeg1system);

    REGISTER_MUXER    (MPEG1VCD, mpeg1vcd);

    REGISTER_MUXER    (MPEG1VIDEO, mpeg1video);

    REGISTER_MUXER    (MPEG2DVD, mpeg2dvd);

    REGISTER_MUXER    (MPEG2SVCD, mpeg2svcd);

    REGISTER_MUXER    (MPEG2VIDEO, mpeg2video);

    REGISTER_MUXER    (MPEG2VOB, mpeg2vob);

    REGISTER_DEMUXER  (MPEGPS, mpegps);

    REGISTER_MUXDEMUX (MPEGTS, mpegts);

    REGISTER_DEMUXER  (MPEGTSRAW, mpegtsraw);

    REGISTER_DEMUXER  (MPEGVIDEO, mpegvideo);

    REGISTER_MUXER    (MPJPEG, mpjpeg);

    REGISTER_DEMUXER  (MSNWC_TCP, msnwc_tcp);

    REGISTER_DEMUXER  (MTV, mtv);

    REGISTER_DEMUXER  (MVI, mvi);

    REGISTER_DEMUXER  (MXF, mxf);

    REGISTER_DEMUXER  (NSV, nsv);

    REGISTER_MUXER    (NULL, null);

    REGISTER_MUXDEMUX (NUT, nut);

    REGISTER_DEMUXER  (NUV, nuv);

    REGISTER_MUXDEMUX (OGG, ogg);

    REGISTER_DEMUXER  (OMA, oma);

    REGISTER_MUXDEMUX (PCM_ALAW,  pcm_alaw);

    REGISTER_MUXDEMUX (PCM_MULAW, pcm_mulaw);

    REGISTER_MUXDEMUX (PCM_S16BE, pcm_s16be);

    REGISTER_MUXDEMUX (PCM_S16LE, pcm_s16le);

    REGISTER_MUXDEMUX (PCM_S8,    pcm_s8);

    REGISTER_MUXDEMUX (PCM_U16BE, pcm_u16be);

    REGISTER_MUXDEMUX (PCM_U16LE, pcm_u16le);

    REGISTER_MUXDEMUX (PCM_U8,    pcm_u8);

    REGISTER_MUXER    (PSP, psp);

    REGISTER_DEMUXER  (PVA, pva);

    REGISTER_MUXDEMUX (RAWVIDEO, rawvideo);

    REGISTER_DEMUXER  (REDIR, redir);

    REGISTER_DEMUXER  (RL2, rl2);

    REGISTER_MUXDEMUX (RM, rm);

    REGISTER_MUXDEMUX (ROQ, roq);

    REGISTER_DEMUXER  (RPL, rpl);

    REGISTER_MUXER    (RTP, rtp);

    REGISTER_DEMUXER  (RTSP, rtsp);

    REGISTER_DEMUXER  (SDP, sdp);

#ifdef CONFIG_SDP_DEMUXER

    av_register_rtp_dynamic_payload_handlers();

#endif

    REGISTER_DEMUXER  (SEGAFILM, segafilm);

    REGISTER_DEMUXER  (SHORTEN, shorten);

    REGISTER_DEMUXER  (SIFF, siff);

    REGISTER_DEMUXER  (SMACKER, smacker);

    REGISTER_DEMUXER  (SOL, sol);

    REGISTER_DEMUXER  (STR, str);

    REGISTER_MUXDEMUX (SWF, swf);

    REGISTER_MUXER    (TG2, tg2);

    REGISTER_MUXER    (TGP, tgp);

    REGISTER_DEMUXER  (THP, thp);

    REGISTER_DEMUXER  (TIERTEXSEQ, tiertexseq);

    REGISTER_DEMUXER  (TTA, tta);

    REGISTER_DEMUXER  (TXD, txd);

    REGISTER_DEMUXER  (VC1, vc1);

    REGISTER_DEMUXER  (VC1T, vc1t);

    REGISTER_DEMUXER  (VMD, vmd);

    REGISTER_MUXDEMUX (VOC, voc);

    REGISTER_MUXDEMUX (WAV, wav);

    REGISTER_DEMUXER  (WC3, wc3);

    REGISTER_DEMUXER  (WSAUD, wsaud);

    REGISTER_DEMUXER  (WSVQA, wsvqa);

    REGISTER_DEMUXER  (WV, wv);

    REGISTER_DEMUXER  (XA, xa);

    REGISTER_MUXDEMUX (YUV4MPEGPIPE, yuv4mpegpipe);

    /* external libraries */

    REGISTER_MUXDEMUX (LIBNUT, libnut);

    /* protocols */

    REGISTER_PROTOCOL (FILE, file);

    REGISTER_PROTOCOL (HTTP, http);

    REGISTER_PROTOCOL (PIPE, pipe);

    REGISTER_PROTOCOL (RTP, rtp);

    REGISTER_PROTOCOL (TCP, tcp);

    REGISTER_PROTOCOL (UDP, udp);

}


static void vfio_pci_size_rom(VFIODevice *vdev)

{

    uint32_t orig, size = cpu_to_le32((uint32_t)PCI_ROM_ADDRESS_MASK);

    off_t offset = vdev->config_offset + PCI_ROM_ADDRESS;

    char name[32];

    if (vdev->pdev.romfile || !vdev->pdev.rom_bar) {

        return;

    }

    /*

     * Use the same size ROM BAR as the physical device.  The contents

     * will get filled in later when the guest tries to read it.

     */

    if (pread(vdev->fd, &orig, 4, offset) != 4 ||

        pwrite(vdev->fd, &size, 4, offset) != 4 ||

        pread(vdev->fd, &size, 4, offset) != 4 ||

        pwrite(vdev->fd, &orig, 4, offset) != 4) {

        error_report("%s(%04x:%02x:%02x.%x) failed: %m",

                     __func__, vdev->host.domain, vdev->host.bus,

                     vdev->host.slot, vdev->host.function);

        return;

    }

    size = ~(le32_to_cpu(size) & PCI_ROM_ADDRESS_MASK) + 1;

    if (!size) {

        return;

    }

    DPRINTF("%04x:%02x:%02x.%x ROM size 0x%x\n", vdev->host.domain,

            vdev->host.bus, vdev->host.slot, vdev->host.function, size);

    snprintf(name, sizeof(name), "vfio[%04x:%02x:%02x.%x].rom",

             vdev->host.domain, vdev->host.bus, vdev->host.slot,

             vdev->host.function);

    memory_region_init_io(&vdev->pdev.rom, OBJECT(vdev),

                          &vfio_rom_ops, vdev, name, size);

    pci_register_bar(&vdev->pdev, PCI_ROM_SLOT,

                     PCI_BASE_ADDRESS_SPACE_MEMORY, &vdev->pdev.rom);

    vdev->pdev.has_rom = true;

}


void OPPROTO op_POWER_sraq (void)

{

    env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));

    if (T1 & 0x20UL)

        T0 = -1L;

    else

        T0 = Ts0 >> T1;

    RETURN();

}


static int shorten_decode_frame(AVCodecContext *avctx,

        void *data, int *data_size,

        AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    ShortenContext *s = avctx->priv_data;

    int i, input_buf_size = 0;

    int16_t *samples = data;

    int ret;

    /* allocate internal bitstream buffer */

    if(s->max_framesize == 0){

        void *tmp_ptr;

        s->max_framesize= 1024; // should hopefully be enough for the first header

        tmp_ptr = av_fast_realloc(s->bitstream, &s->allocated_bitstream_size,

                                  s->max_framesize);

        if (!tmp_ptr) {

            av_log(avctx, AV_LOG_ERROR, "error allocating bitstream buffer\n");

            return AVERROR(ENOMEM);

        }

        s->bitstream = tmp_ptr;

    }

    /* append current packet data to bitstream buffer */

    if(1 && s->max_framesize){//FIXME truncated

        buf_size= FFMIN(buf_size, s->max_framesize - s->bitstream_size);

        input_buf_size= buf_size;

        if(s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size){

            memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);

            s->bitstream_index=0;

        }

        memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size);

        buf= &s->bitstream[s->bitstream_index];

        buf_size += s->bitstream_size;

        s->bitstream_size= buf_size;

        /* do not decode until buffer has at least max_framesize bytes */

        if(buf_size < s->max_framesize){

            *data_size = 0;

            return input_buf_size;

        }

    }

    /* init and position bitstream reader */

    init_get_bits(&s->gb, buf, buf_size*8);

    skip_bits(&s->gb, s->bitindex);

    /* process header or next subblock */

    if (!s->blocksize)

    {

        if ((ret = read_header(s)) < 0)

            return ret;

        *data_size = 0;

    }

    else

    {

        int cmd;

        int len;

        cmd = get_ur_golomb_shorten(&s->gb, FNSIZE);

        if (cmd > FN_VERBATIM) {

            av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd);

            if (s->bitstream_size > 0) {

                s->bitstream_index++;

                s->bitstream_size--;

            }

            return -1;

        }

        if (!is_audio_command[cmd]) {

            /* process non-audio command */

            switch (cmd) {

                case FN_VERBATIM:

                    len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);

                    while (len--) {

                        get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);

                    }

                    break;

                case FN_BITSHIFT:

                    s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE);

                    break;

                case FN_BLOCKSIZE: {

                    int blocksize = get_uint(s, av_log2(s->blocksize));

                    if (blocksize > s->blocksize) {

                        av_log(avctx, AV_LOG_ERROR, "Increasing block size is not supported\n");

                        return AVERROR_PATCHWELCOME;

                    }

                    if (!blocksize || blocksize > MAX_BLOCKSIZE) {

                        av_log(avctx, AV_LOG_ERROR, "invalid or unsupported "

                               "block size: %d\n", blocksize);

                        return AVERROR(EINVAL);

                    }

                    s->blocksize = blocksize;

                    break;

                }

                case FN_QUIT:

                    break;

            }

            *data_size = 0;

        } else {

            /* process audio command */

            int residual_size = 0;

            int channel = s->cur_chan;

            int32_t coffset;

            /* get Rice code for residual decoding */

            if (cmd != FN_ZERO) {

                residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE);

                /* this is a hack as version 0 differed in defintion of get_sr_golomb_shorten */

                if (s->version == 0)

                    residual_size--;

            }

            /* calculate sample offset using means from previous blocks */

            if (s->nmean == 0)

                coffset = s->offset[channel][0];

            else {

                int32_t sum = (s->version < 2) ? 0 : s->nmean / 2;

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

                    sum += s->offset[channel][i];

                coffset = sum / s->nmean;

                if (s->version >= 2)

                    coffset >>= FFMIN(1, s->bitshift);

            }

            /* decode samples for this channel */

            if (cmd == FN_ZERO) {

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

                    s->decoded[channel][i] = 0;

            } else {

                if ((ret = decode_subframe_lpc(s, cmd, channel, residual_size, coffset)) < 0)

                    return ret;

            }

            /* update means with info from the current block */

            if (s->nmean > 0) {

                int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2;

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

                    sum += s->decoded[channel][i];

                for (i=1; i<s->nmean; i++)

                    s->offset[channel][i-1] = s->offset[channel][i];

                if (s->version < 2)

                    s->offset[channel][s->nmean - 1] = sum / s->blocksize;

                else

                    s->offset[channel][s->nmean - 1] = (sum / s->blocksize) << s->bitshift;

            }

            /* copy wrap samples for use with next block */

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

                s->decoded[channel][i] = s->decoded[channel][i + s->blocksize];

            /* shift samples to add in unused zero bits which were removed

               during encoding */

            fix_bitshift(s, s->decoded[channel]);

            /* if this is the last channel in the block, output the samples */

            s->cur_chan++;

            if (s->cur_chan == s->channels) {

                samples = interleave_buffer(samples, s->channels, s->blocksize, s->decoded);

                s->cur_chan = 0;

                *data_size = (int8_t *)samples - (int8_t *)data;

            } else {

                *data_size = 0;

            }

        }

    }

    s->bitindex = get_bits_count(&s->gb) - 8*((get_bits_count(&s->gb))/8);

    i= (get_bits_count(&s->gb))/8;

    if (i > buf_size) {

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

        s->bitstream_size=0;

        s->bitstream_index=0;

        return -1;

    }

    if (s->bitstream_size) {

        s->bitstream_index += i;

        s->bitstream_size  -= i;

        return input_buf_size;

    } else

        return i;

}


void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,

                         int secondary_ide_enabled)

{

    PCIDevice *dev;

    dev = pci_create(bus, -1, "CMD646 IDE");

    qdev_prop_set_uint32(&dev->qdev, "secondary", secondary_ide_enabled);

    qdev_init(&dev->qdev);

    pci_ide_create_devs(dev, hd_table);

}


static av_cold int avisynth_load_library(void) {

    avs_library = av_mallocz(sizeof(AviSynthLibrary));

    if (!avs_library)

        return AVERROR_UNKNOWN;

    avs_library->library = LoadLibrary(AVISYNTH_LIB);

    if (!avs_library->library)

        goto init_fail;

#define LOAD_AVS_FUNC(name, continue_on_fail) \

{ \

    avs_library->name = (void*)GetProcAddress(avs_library->library, #name); \

    if(!continue_on_fail && !avs_library->name) \

        goto fail; \

}

    LOAD_AVS_FUNC(avs_bit_blt, 0);

    LOAD_AVS_FUNC(avs_clip_get_error, 0);

    LOAD_AVS_FUNC(avs_create_script_environment, 0);

    LOAD_AVS_FUNC(avs_delete_script_environment, 0);

    LOAD_AVS_FUNC(avs_get_audio, 0);

    LOAD_AVS_FUNC(avs_get_error, 1); // New to AviSynth 2.6

    LOAD_AVS_FUNC(avs_get_frame, 0);

    LOAD_AVS_FUNC(avs_get_video_info, 0);

    LOAD_AVS_FUNC(avs_invoke, 0);

    LOAD_AVS_FUNC(avs_release_clip, 0);

    LOAD_AVS_FUNC(avs_release_value, 0);

    LOAD_AVS_FUNC(avs_release_video_frame, 0);

    LOAD_AVS_FUNC(avs_take_clip, 0);

#undef LOAD_AVS_FUNC

    atexit(avisynth_atexit_handler);

    return 0;

fail:

    FreeLibrary(avs_library->library);

init_fail:

    av_freep(&avs_library);

    return AVERROR_UNKNOWN;

}


static int mjpegb_decode_frame(AVCodecContext *avctx,

                              void *data, int *data_size,

                              uint8_t *buf, int buf_size)

{

    MJpegDecodeContext *s = avctx->priv_data;

    uint8_t *buf_end, *buf_ptr;

    AVFrame *picture = data;

    GetBitContext hgb; /* for the header */

    uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs;

    uint32_t field_size, sod_offs;

    buf_ptr = buf;

    buf_end = buf + buf_size;

read_header:

    /* reset on every SOI */

    s->restart_interval = 0;

    s->restart_count = 0;

    s->mjpb_skiptosod = 0;

    init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8);

    skip_bits(&hgb, 32); /* reserved zeros */

    if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g'))

    {

        av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n");

        return 0;

    }

    field_size = get_bits_long(&hgb, 32); /* field size */

    av_log(avctx, AV_LOG_DEBUG, "field size: 0x%x\n", field_size);

    skip_bits(&hgb, 32); /* padded field size */

    second_field_offs = get_bits_long(&hgb, 32);

    av_log(avctx, AV_LOG_DEBUG, "second field offs: 0x%x\n", second_field_offs);

    if (second_field_offs)

        s->interlaced = 1;

    dqt_offs = get_bits_long(&hgb, 32);

    av_log(avctx, AV_LOG_DEBUG, "dqt offs: 0x%x\n", dqt_offs);

    if (dqt_offs)

    {

        init_get_bits(&s->gb, buf+dqt_offs, (buf_end - (buf+dqt_offs))*8);

        s->start_code = DQT;

        mjpeg_decode_dqt(s);

    }

    dht_offs = get_bits_long(&hgb, 32);

    av_log(avctx, AV_LOG_DEBUG, "dht offs: 0x%x\n", dht_offs);

    if (dht_offs)

    {

        init_get_bits(&s->gb, buf+dht_offs, (buf_end - (buf+dht_offs))*8);

        s->start_code = DHT;

        mjpeg_decode_dht(s);

    }

    sof_offs = get_bits_long(&hgb, 32);

    av_log(avctx, AV_LOG_DEBUG, "sof offs: 0x%x\n", sof_offs);

    if (sof_offs)

    {

        init_get_bits(&s->gb, buf+sof_offs, (buf_end - (buf+sof_offs))*8);

        s->start_code = SOF0;

        if (mjpeg_decode_sof(s) < 0)

            return -1;

    }

    sos_offs = get_bits_long(&hgb, 32);

    av_log(avctx, AV_LOG_DEBUG, "sos offs: 0x%x\n", sos_offs);

    sod_offs = get_bits_long(&hgb, 32);

    av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%x\n", sod_offs);

    if (sos_offs)

    {

//        init_get_bits(&s->gb, buf+sos_offs, (buf_end - (buf+sos_offs))*8);

        init_get_bits(&s->gb, buf+sos_offs, field_size*8);

        s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16));

        s->start_code = SOS;

        mjpeg_decode_sos(s);

    }

    if (s->interlaced) {

        s->bottom_field ^= 1;

        /* if not bottom field, do not output image yet */

        if (s->bottom_field && second_field_offs)

        {

            buf_ptr = buf + second_field_offs;

            second_field_offs = 0;

            goto read_header;

            }

    }

    //XXX FIXME factorize, this looks very similar to the EOI code

    *picture= s->picture;

    *data_size = sizeof(AVFrame);

    if(!s->lossless){

        picture->quality= FFMAX(FFMAX(s->qscale[0], s->qscale[1]), s->qscale[2]);

        picture->qstride= 0;

        picture->qscale_table= s->qscale_table;

        memset(picture->qscale_table, picture->quality, (s->width+15)/16);

        if(avctx->debug & FF_DEBUG_QP)

            av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality);

        picture->quality*= FF_QP2LAMBDA;

    }

    return buf_ptr - buf;

}


static int dv_write_header(AVFormatContext *s)

{

    s->priv_data = dv_init_mux(s);

    if (!s->priv_data) {

        av_log(s, AV_LOG_ERROR, "Can't initialize DV format!\n"

                    "Make sure that you supply exactly two streams:\n"

                    "     video: 25fps or 29.97fps, audio: 2ch/48Khz/PCM\n"

                    "     (50Mbps allows an optional second audio stream)\n");

        return -1;

    }

    return 0;

}


static void print_type_size(Visitor *v, uint64_t *obj, const char *name,

                           Error **errp)

{

    StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v);

    static const char suffixes[] = { 'B', 'K', 'M', 'G', 'T' };

    uint64_t div, val;

    char *out;

    int i;

    if (!sov->human) {

        out = g_strdup_printf("%llu", (long long) *obj);

        string_output_set(sov, out);

        return;

    }

    val = *obj;

    /* Compute floor(log2(val)).  */

    i = 64 - clz64(val);

    /* Find the power of 1024 that we'll display as the units.  */

    i /= 10;

    if (i >= ARRAY_SIZE(suffixes)) {

        i = ARRAY_SIZE(suffixes) - 1;

    }

    div = 1ULL << (i * 10);

    out = g_strdup_printf("%0.03f%c", (double)val/div, suffixes[i]);

    string_output_set(sov, out);

}


static void avc_h_loop_filter_chroma422_msa(uint8_t *src,

                                            int32_t stride,

                                            int32_t alpha_in,

                                            int32_t beta_in,

                                            int8_t *tc0)

{

    int32_t col, tc_val;

    int16_t out0, out1, out2, out3;

    v16u8 alpha, beta, res;

    alpha = (v16u8) __msa_fill_b(alpha_in);

    beta = (v16u8) __msa_fill_b(beta_in);

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

        tc_val = (tc0[col] - 1) + 1;

        if (tc_val <= 0) {

            src += (4 * stride);

            continue;

        }

        AVC_LPF_H_CHROMA_422(src, stride, tc_val, alpha, beta, res);

        out0 = __msa_copy_s_h((v8i16) res, 0);

        out1 = __msa_copy_s_h((v8i16) res, 1);

        out2 = __msa_copy_s_h((v8i16) res, 2);

        out3 = __msa_copy_s_h((v8i16) res, 3);

        STORE_HWORD((src - 1), out0);

        src += stride;

        STORE_HWORD((src - 1), out1);

        src += stride;

        STORE_HWORD((src - 1), out2);

        src += stride;

        STORE_HWORD((src - 1), out3);

        src += stride;

    }

}


static int test_vector_dmac_scalar(AVFloatDSPContext *fdsp, AVFloatDSPContext *cdsp,

                                   const double *v1, const double *src0, double scale)

{

    LOCAL_ALIGNED(32, double, cdst, [LEN]);

    LOCAL_ALIGNED(32, double, odst, [LEN]);

    int ret;

    memcpy(cdst, v1, LEN * sizeof(*v1));

    memcpy(odst, v1, LEN * sizeof(*v1));

    cdsp->vector_dmac_scalar(cdst, src0, scale, LEN);

    fdsp->vector_dmac_scalar(odst, src0, scale, LEN);

    if (ret = compare_doubles(cdst, odst, LEN, ARBITRARY_DMAC_SCALAR_CONST))

        av_log(NULL, AV_LOG_ERROR, "vector_dmac_scalar failed\n");

    return ret;

}


static av_always_inline int cmp_inline(MpegEncContext *s, const int x, const int y, const int subx, const int suby,

                      const int size, const int h, int ref_index, int src_index,

                      me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel, int chroma){

    MotionEstContext * const c= &s->me;

    const int stride= c->stride;

    const int uvstride= c->uvstride;

    const int dxy= subx + (suby<<(1+qpel)); //FIXME log2_subpel?

    const int hx= subx + (x<<(1+qpel));

    const int hy= suby + (y<<(1+qpel));

    uint8_t * const * const ref= c->ref[ref_index];

    uint8_t * const * const src= c->src[src_index];

    int d;

    //FIXME check chroma 4mv, (no crashes ...)

        int uvdxy;              /* no, it might not be used uninitialized */

        if(dxy){

            if(qpel){

                c->qpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride); //FIXME prototype (add h)

                if(chroma){

                    int cx= hx/2;

                    int cy= hy/2;

                    cx= (cx>>1)|(cx&1);

                    cy= (cy>>1)|(cy&1);

                    uvdxy= (cx&1) + 2*(cy&1);

                    //FIXME x/y wrong, but mpeg4 qpel is sick anyway, we should drop as much of it as possible in favor for h264

                }

            }else{

                c->hpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride, h);

                if(chroma)

                    uvdxy= dxy | (x&1) | (2*(y&1));

            }

            d = cmp_func(s, c->temp, src[0], stride, h);

        }else{

            d = cmp_func(s, src[0], ref[0] + x + y*stride, stride, h);

            if(chroma)

                uvdxy= (x&1) + 2*(y&1);

        }

        if(chroma){

            uint8_t * const uvtemp= c->temp + 16*stride;

            c->hpel_put[size+1][uvdxy](uvtemp  , ref[1] + (x>>1) + (y>>1)*uvstride, uvstride, h>>1);

            c->hpel_put[size+1][uvdxy](uvtemp+8, ref[2] + (x>>1) + (y>>1)*uvstride, uvstride, h>>1);

            d += chroma_cmp_func(s, uvtemp  , src[1], uvstride, h>>1);

            d += chroma_cmp_func(s, uvtemp+8, src[2], uvstride, h>>1);

        }

    return d;

}


static void do_video_out(AVFormatContext *s, OutputStream *ost,

                         InputStream *ist, AVFrame *in_picture)

{

    int nb_frames, i, ret, format_video_sync;

    AVFrame *final_picture;

    AVCodecContext *enc;

    double sync_ipts;

    double duration = 0;

    int frame_size = 0;

    float quality = same_quant ? in_picture->quality

                               : ost->st->codec->global_quality;

    enc = ost->st->codec;

    if (ist->st->start_time != AV_NOPTS_VALUE && ist->st->first_dts != AV_NOPTS_VALUE) {

        duration = FFMAX(av_q2d(ist->st->time_base), av_q2d(ist->st->codec->time_base));

        if(ist->st->avg_frame_rate.num)

            duration= FFMAX(duration, 1/av_q2d(ist->st->avg_frame_rate));

        duration /= av_q2d(enc->time_base);

    }

    sync_ipts = get_sync_ipts(ost, in_picture->pts) / av_q2d(enc->time_base);

    /* by default, we output a single frame */

    nb_frames = 1;

    format_video_sync = video_sync_method;

    if (format_video_sync == VSYNC_AUTO)

        format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : 1;

    if (format_video_sync != VSYNC_PASSTHROUGH && format_video_sync != VSYNC_DROP) {

        double vdelta = sync_ipts - ost->sync_opts + duration;

        // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c

        if (vdelta < -1.1)

            nb_frames = 0;

        else if (format_video_sync == VSYNC_VFR) {

            if (vdelta <= -0.6) {

                nb_frames = 0;

            } else if (vdelta > 0.6)

                ost->sync_opts = lrintf(sync_ipts);

        } else if (vdelta > 1.1)

            nb_frames = lrintf(vdelta);

        if (nb_frames == 0) {

            ++nb_frames_drop;

            av_log(NULL, AV_LOG_VERBOSE, "*** drop!\n");

        } else if (nb_frames > 1) {

            nb_frames_dup += nb_frames - 1;

            av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1);

        }

    } else

        ost->sync_opts = lrintf(sync_ipts);

    nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number);

    if (nb_frames <= 0)

        return;

    do_video_resample(ost, ist, in_picture, &final_picture);

    /* duplicates frame if needed */

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

        AVPacket pkt;

        av_init_packet(&pkt);

        pkt.data = NULL;

        pkt.size = 0;

        if (s->oformat->flags & AVFMT_RAWPICTURE &&

            enc->codec->id == CODEC_ID_RAWVIDEO) {

            /* raw pictures are written as AVPicture structure to

               avoid any copies. We support temporarily the older

               method. */

            enc->coded_frame->interlaced_frame = in_picture->interlaced_frame;

            enc->coded_frame->top_field_first  = in_picture->top_field_first;

            pkt.data   = (uint8_t *)final_picture;

            pkt.size   =  sizeof(AVPicture);

            pkt.pts    = av_rescale_q(ost->sync_opts, enc->time_base, ost->st->time_base);

            pkt.flags |= AV_PKT_FLAG_KEY;

            write_frame(s, &pkt, ost);

        } else {

            int got_packet;

            AVFrame big_picture;

            big_picture = *final_picture;

            /* better than nothing: use input picture interlaced

               settings */

            big_picture.interlaced_frame = in_picture->interlaced_frame;

            if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)) {

                if (ost->top_field_first == -1)

                    big_picture.top_field_first = in_picture->top_field_first;

                else

                    big_picture.top_field_first = !!ost->top_field_first;

            }

            /* handles same_quant here. This is not correct because it may

               not be a global option */

            big_picture.quality = quality;

            if (!enc->me_threshold)

                big_picture.pict_type = 0;

            big_picture.pts = ost->sync_opts;

            if (ost->forced_kf_index < ost->forced_kf_count &&

                big_picture.pts >= ost->forced_kf_pts[ost->forced_kf_index]) {

                big_picture.pict_type = AV_PICTURE_TYPE_I;

                ost->forced_kf_index++;

            }

            ret = avcodec_encode_video2(enc, &pkt, &big_picture, &got_packet);

            if (ret < 0) {

                av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");

                exit_program(1);

            }

            if (got_packet) {

                if (pkt.pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & CODEC_CAP_DELAY))

                    pkt.pts = ost->sync_opts;

                if (pkt.pts != AV_NOPTS_VALUE)

                    pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base);

                if (pkt.dts != AV_NOPTS_VALUE)

                    pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base);

                if (debug_ts) {

                    av_log(NULL, AV_LOG_INFO, "encoder -> type:video "

                           "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",

                           av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->st->time_base),

                           av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base));

                }

                if (format_video_sync == VSYNC_DROP)

                    pkt.pts = pkt.dts = AV_NOPTS_VALUE;

                write_frame(s, &pkt, ost);

                frame_size = pkt.size;

                video_size += pkt.size;

                /* if two pass, output log */

                if (ost->logfile && enc->stats_out) {

                    fprintf(ost->logfile, "%s", enc->stats_out);

                }

            }

        }

        ost->sync_opts++;

        /*

         * For video, number of frames in == number of packets out.

         * But there may be reordering, so we can't throw away frames on encoder

         * flush, we need to limit them here, before they go into encoder.

         */

        ost->frame_number++;

    }

    if (vstats_filename && frame_size)

        do_video_stats(output_files[ost->file_index].ctx, ost, frame_size);

}


ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size)

{

    FdMigrationState *s = opaque;

    ssize_t ret;

    do {

        ret = s->write(s, data, size);

    } while (ret == -1 && ((s->get_error(s)) == EINTR));

    if (ret == -1)

        ret = -(s->get_error(s));

    if (ret == -EAGAIN) {

        qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);

    } else if (ret < 0) {

        s->state = MIG_STATE_ERROR;

        notifier_list_notify(&migration_state_notifiers, NULL);

    }

    return ret;

}


static void do_sdl_resize(int new_width, int new_height, int bpp)

{

    int flags;

    //    printf("resizing to %d %d\n", w, h);

    flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_RESIZABLE;

    if (gui_fullscreen)

        flags |= SDL_FULLSCREEN;

    if (gui_noframe)

        flags |= SDL_NOFRAME;

    width = new_width;

    height = new_height;

    real_screen = SDL_SetVideoMode(width, height, bpp, flags);

    if (!real_screen) {

	fprintf(stderr, "Could not open SDL display (%dx%dx%d): %s\n", width,

		height, bpp, SDL_GetError());

        exit(1);

    }

}


static int wavpack_decode_block(AVCodecContext *avctx, int block_no,

                                AVFrame *frame, const uint8_t *buf, int buf_size)

{

    WavpackContext *wc = avctx->priv_data;

    ThreadFrame tframe = { .f = frame };

    WavpackFrameContext *s;

    GetByteContext gb;

    void *samples_l = NULL, *samples_r = NULL;

    int ret;

    int got_terms   = 0, got_weights = 0, got_samples = 0,

        got_entropy = 0, got_bs      = 0, got_float   = 0, got_hybrid = 0;

    int i, j, id, size, ssize, weights, t;

    int bpp, chan = 0, chmask = 0, orig_bpp, sample_rate = 0;

    int multiblock;

    if (block_no >= wc->fdec_num && wv_alloc_frame_context(wc) < 0) {

        av_log(avctx, AV_LOG_ERROR, "Error creating frame decode context\n");

        return AVERROR_INVALIDDATA;

    }

    s = wc->fdec[block_no];

    if (!s) {

        av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n",

               block_no);

        return AVERROR_INVALIDDATA;

    }

    memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));

    memset(s->ch, 0, sizeof(s->ch));

    s->extra_bits     = 0;

    s->and            = s->or = s->shift = 0;

    s->got_extra_bits = 0;

    bytestream2_init(&gb, buf, buf_size);

    s->samples = bytestream2_get_le32(&gb);

    if (s->samples != wc->samples) {

        av_log(avctx, AV_LOG_ERROR, "Mismatching number of samples in "

               "a sequence: %d and %d\n", wc->samples, s->samples);

        return AVERROR_INVALIDDATA;

    }

    s->frame_flags = bytestream2_get_le32(&gb);

    bpp            = av_get_bytes_per_sample(avctx->sample_fmt);

    orig_bpp       = ((s->frame_flags & 0x03) + 1) << 3;

    multiblock     = (s->frame_flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK;

    s->stereo         = !(s->frame_flags & WV_MONO);

    s->stereo_in      =  (s->frame_flags & WV_FALSE_STEREO) ? 0 : s->stereo;

    s->joint          =   s->frame_flags & WV_JOINT_STEREO;

    s->hybrid         =   s->frame_flags & WV_HYBRID_MODE;

    s->hybrid_bitrate =   s->frame_flags & WV_HYBRID_BITRATE;

    s->post_shift     = bpp * 8 - orig_bpp + ((s->frame_flags >> 13) & 0x1f);

    s->hybrid_maxclip =  ((1LL << (orig_bpp - 1)) - 1);

    s->hybrid_minclip = ((-1LL << (orig_bpp - 1)));

    s->CRC            = bytestream2_get_le32(&gb);

    // parse metadata blocks

    while (bytestream2_get_bytes_left(&gb)) {

        id   = bytestream2_get_byte(&gb);

        size = bytestream2_get_byte(&gb);

        if (id & WP_IDF_LONG) {

            size |= (bytestream2_get_byte(&gb)) << 8;

            size |= (bytestream2_get_byte(&gb)) << 16;

        }

        size <<= 1; // size is specified in words

        ssize  = size;

        if (id & WP_IDF_ODD)

            size--;

        if (size < 0) {

            av_log(avctx, AV_LOG_ERROR,

                   "Got incorrect block %02X with size %i\n", id, size);

            break;

        }

        if (bytestream2_get_bytes_left(&gb) < ssize) {

            av_log(avctx, AV_LOG_ERROR,

                   "Block size %i is out of bounds\n", size);

            break;

        }

        switch (id & WP_IDF_MASK) {

        case WP_ID_DECTERMS:

            if (size > MAX_TERMS) {

                av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n");

                s->terms = 0;

                bytestream2_skip(&gb, ssize);

                continue;

            }

            s->terms = size;

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

                uint8_t val = bytestream2_get_byte(&gb);

                s->decorr[s->terms - i - 1].value = (val & 0x1F) - 5;

                s->decorr[s->terms - i - 1].delta =  val >> 5;

            }

            got_terms = 1;

            break;

        case WP_ID_DECWEIGHTS:

            if (!got_terms) {

                av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");

                continue;

            }

            weights = size >> s->stereo_in;

            if (weights > MAX_TERMS || weights > s->terms) {

                av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n");

                bytestream2_skip(&gb, ssize);

                continue;

            }

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

                t = (int8_t)bytestream2_get_byte(&gb);

                s->decorr[s->terms - i - 1].weightA = t << 3;

                if (s->decorr[s->terms - i - 1].weightA > 0)

                    s->decorr[s->terms - i - 1].weightA +=

                        (s->decorr[s->terms - i - 1].weightA + 64) >> 7;

                if (s->stereo_in) {

                    t = (int8_t)bytestream2_get_byte(&gb);

                    s->decorr[s->terms - i - 1].weightB = t << 3;

                    if (s->decorr[s->terms - i - 1].weightB > 0)

                        s->decorr[s->terms - i - 1].weightB +=

                            (s->decorr[s->terms - i - 1].weightB + 64) >> 7;

                }

            }

            got_weights = 1;

            break;

        case WP_ID_DECSAMPLES:

            if (!got_terms) {

                av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");

                continue;

            }

            t = 0;

            for (i = s->terms - 1; (i >= 0) && (t < size); i--) {

                if (s->decorr[i].value > 8) {

                    s->decorr[i].samplesA[0] =

                        wp_exp2(bytestream2_get_le16(&gb));

                    s->decorr[i].samplesA[1] =

                        wp_exp2(bytestream2_get_le16(&gb));

                    if (s->stereo_in) {

                        s->decorr[i].samplesB[0] =

                            wp_exp2(bytestream2_get_le16(&gb));

                        s->decorr[i].samplesB[1] =

                            wp_exp2(bytestream2_get_le16(&gb));

                        t                       += 4;

                    }

                    t += 4;

                } else if (s->decorr[i].value < 0) {

                    s->decorr[i].samplesA[0] =

                        wp_exp2(bytestream2_get_le16(&gb));

                    s->decorr[i].samplesB[0] =

                        wp_exp2(bytestream2_get_le16(&gb));

                    t                       += 4;

                } else {

                    for (j = 0; j < s->decorr[i].value; j++) {

                        s->decorr[i].samplesA[j] =

                            wp_exp2(bytestream2_get_le16(&gb));

                        if (s->stereo_in) {

                            s->decorr[i].samplesB[j] =

                                wp_exp2(bytestream2_get_le16(&gb));

                        }

                    }

                    t += s->decorr[i].value * 2 * (s->stereo_in + 1);

                }

            }

            got_samples = 1;

            break;

        case WP_ID_ENTROPY:

            if (size != 6 * (s->stereo_in + 1)) {

                av_log(avctx, AV_LOG_ERROR,

                       "Entropy vars size should be %i, got %i.\n",

                       6 * (s->stereo_in + 1), size);

                bytestream2_skip(&gb, ssize);

                continue;

            }

            for (j = 0; j <= s->stereo_in; j++)

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

                    s->ch[j].median[i] = wp_exp2(bytestream2_get_le16(&gb));

                }

            got_entropy = 1;

            break;

        case WP_ID_HYBRID:

            if (s->hybrid_bitrate) {

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

                    s->ch[i].slow_level = wp_exp2(bytestream2_get_le16(&gb));

                    size               -= 2;

                }

            }

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

                s->ch[i].bitrate_acc = bytestream2_get_le16(&gb) << 16;

                size                -= 2;

            }

            if (size > 0) {

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

                    s->ch[i].bitrate_delta =

                        wp_exp2((int16_t)bytestream2_get_le16(&gb));

                }

            } else {

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

                    s->ch[i].bitrate_delta = 0;

            }

            got_hybrid = 1;

            break;

        case WP_ID_INT32INFO: {

            uint8_t val[4];

            if (size != 4) {

                av_log(avctx, AV_LOG_ERROR,

                       "Invalid INT32INFO, size = %i\n",

                       size);

                bytestream2_skip(&gb, ssize - 4);

                continue;

            }

            bytestream2_get_buffer(&gb, val, 4);

            if (val[0] > 32) {

                av_log(avctx, AV_LOG_ERROR,

                       "Invalid INT32INFO, extra_bits = %d (> 32)\n", val[0]);

                continue;

            } else if (val[0]) {

                s->extra_bits = val[0];

            } else if (val[1]) {

                s->shift = val[1];

            } else if (val[2]) {

                s->and   = s->or = 1;

                s->shift = val[2];

            } else if (val[3]) {

                s->and   = 1;

                s->shift = val[3];

            }

            /* original WavPack decoder forces 32-bit lossy sound to be treated

             * as 24-bit one in order to have proper clipping */

            if (s->hybrid && bpp == 4 && s->post_shift < 8 && s->shift > 8) {

                s->post_shift      += 8;

                s->shift           -= 8;

                s->hybrid_maxclip >>= 8;

                s->hybrid_minclip >>= 8;

            }

            break;

        }

        case WP_ID_FLOATINFO:

            if (size != 4) {

                av_log(avctx, AV_LOG_ERROR,

                       "Invalid FLOATINFO, size = %i\n", size);

                bytestream2_skip(&gb, ssize);

                continue;

            }

            s->float_flag    = bytestream2_get_byte(&gb);

            s->float_shift   = bytestream2_get_byte(&gb);

            s->float_max_exp = bytestream2_get_byte(&gb);

            got_float        = 1;

            bytestream2_skip(&gb, 1);

            break;

        case WP_ID_DATA:

            s->sc.offset = bytestream2_tell(&gb);

            s->sc.size   = size * 8;

            if ((ret = init_get_bits8(&s->gb, gb.buffer, size)) < 0)

                return ret;

            s->data_size = size * 8;

            bytestream2_skip(&gb, size);

            got_bs       = 1;

            break;

        case WP_ID_EXTRABITS:

            if (size <= 4) {

                av_log(avctx, AV_LOG_ERROR, "Invalid EXTRABITS, size = %i\n",

                       size);

                bytestream2_skip(&gb, size);

                continue;

            }

            s->extra_sc.offset = bytestream2_tell(&gb);

            s->extra_sc.size   = size * 8;

            if ((ret = init_get_bits8(&s->gb_extra_bits, gb.buffer, size)) < 0)

                return ret;

            s->crc_extra_bits  = get_bits_long(&s->gb_extra_bits, 32);

            bytestream2_skip(&gb, size);

            s->got_extra_bits  = 1;

            break;

        case WP_ID_CHANINFO:

            if (size <= 1) {

                av_log(avctx, AV_LOG_ERROR,

                       "Insufficient channel information\n");

                return AVERROR_INVALIDDATA;

            }

            chan = bytestream2_get_byte(&gb);

            switch (size - 2) {

            case 0:

                chmask = bytestream2_get_byte(&gb);

                break;

            case 1:

                chmask = bytestream2_get_le16(&gb);

                break;

            case 2:

                chmask = bytestream2_get_le24(&gb);

                break;

            case 3:

                chmask = bytestream2_get_le32(&gb);

                break;

            case 5:

                size = bytestream2_get_byte(&gb);

                if (avctx->channels != size)

                    av_log(avctx, AV_LOG_WARNING, "%i channels signalled"

                           " instead of %i.\n", size, avctx->channels);

                chan  |= (bytestream2_get_byte(&gb) & 0xF) << 8;

                chmask = bytestream2_get_le16(&gb);

                break;

            default:

                av_log(avctx, AV_LOG_ERROR, "Invalid channel info size %d\n",

                       size);

                chan   = avctx->channels;

                chmask = avctx->channel_layout;

            }

            break;

        case WP_ID_SAMPLE_RATE:

            if (size != 3) {

                av_log(avctx, AV_LOG_ERROR, "Invalid custom sample rate.\n");

                return AVERROR_INVALIDDATA;

            }

            sample_rate = bytestream2_get_le24(&gb);

            break;

        default:

            bytestream2_skip(&gb, size);

        }

        if (id & WP_IDF_ODD)

            bytestream2_skip(&gb, 1);

    }

    if (!got_terms) {

        av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n");

        return AVERROR_INVALIDDATA;

    }

    if (!got_weights) {

        av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n");

        return AVERROR_INVALIDDATA;

    }

    if (!got_samples) {

        av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n");

        return AVERROR_INVALIDDATA;

    }

    if (!got_entropy) {

        av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n");

        return AVERROR_INVALIDDATA;

    }

    if (s->hybrid && !got_hybrid) {

        av_log(avctx, AV_LOG_ERROR, "Hybrid config not found\n");

        return AVERROR_INVALIDDATA;

    }

    if (!got_bs) {

        av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n");

        return AVERROR_INVALIDDATA;

    }

    if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) {

        av_log(avctx, AV_LOG_ERROR, "Float information not found\n");

        return AVERROR_INVALIDDATA;

    }

    if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLTP) {

        const int size   = get_bits_left(&s->gb_extra_bits);

        const int wanted = s->samples * s->extra_bits << s->stereo_in;

        if (size < wanted) {

            av_log(avctx, AV_LOG_ERROR, "Too small EXTRABITS\n");

            s->got_extra_bits = 0;

        }

    }

    if (!wc->ch_offset) {

        int sr = (s->frame_flags >> 23) & 0xf;

        if (sr == 0xf) {

            if (!sample_rate) {

                av_log(avctx, AV_LOG_ERROR, "Custom sample rate missing.\n");

                return AVERROR_INVALIDDATA;

            }

            avctx->sample_rate = sample_rate;

        } else

            avctx->sample_rate = wv_rates[sr];

        if (multiblock) {

            if (chan)

                avctx->channels = chan;

            if (chmask)

                avctx->channel_layout = chmask;

        } else {

            avctx->channels       = s->stereo ? 2 : 1;

            avctx->channel_layout = s->stereo ? AV_CH_LAYOUT_STEREO :

                                                AV_CH_LAYOUT_MONO;

        }

        /* get output buffer */

        frame->nb_samples = s->samples + 1;

        if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)

            return ret;

        frame->nb_samples = s->samples;

    }

    if (wc->ch_offset + s->stereo >= avctx->channels) {

        av_log(avctx, AV_LOG_WARNING, "Too many channels coded in a packet.\n");

        return (avctx->err_recognition & AV_EF_EXPLODE) ? AVERROR_INVALIDDATA : 0;

    }

    samples_l = frame->extended_data[wc->ch_offset];

    if (s->stereo)

        samples_r = frame->extended_data[wc->ch_offset + 1];

    wc->ch_offset += 1 + s->stereo;

    if (s->stereo_in) {

        ret = wv_unpack_stereo(s, &s->gb, samples_l, samples_r, avctx->sample_fmt);

        if (ret < 0)

            return ret;

    } else {

        ret = wv_unpack_mono(s, &s->gb, samples_l, avctx->sample_fmt);

        if (ret < 0)

            return ret;

        if (s->stereo)

            memcpy(samples_r, samples_l, bpp * s->samples);

    }

    return 0;

}


static int http_connect(URLContext *h, const char *path, const char *hoststr)

{

    HTTPContext *s = h->priv_data;

    int post, err, ch;

    char line[1024], *q;

    /* send http header */

    post = h->flags & URL_WRONLY;

    snprintf(s->buffer, sizeof(s->buffer),

             "%s %s HTTP/1.0\r\n"

             "User-Agent: %s\r\n"

             "Accept: */*\r\n"

             "Host: %s\r\n"

             "\r\n",

             post ? "POST" : "GET",

             path,

             LIBAVFORMAT_IDENT,

             hoststr);

    if (http_write(h, s->buffer, strlen(s->buffer)) < 0)

        return AVERROR_IO;

    /* init input buffer */

    s->buf_ptr = s->buffer;

    s->buf_end = s->buffer;

    s->line_count = 0;

    s->location[0] = '\0';

    if (post) {

        sleep(1);

        return 0;

    }

    /* wait for header */

    q = line;

    for(;;) {

        ch = http_getc(s);

        if (ch < 0)

            return AVERROR_IO;

        if (ch == '\n') {

            /* process line */

            if (q > line && q[-1] == '\r')

                q--;

            *q = '\0';

#ifdef DEBUG

            printf("header='%s'\n", line);

#endif

            err = process_line(s, line, s->line_count);

            if (err < 0)

                return err;

            if (err == 0)

                return 0;

            s->line_count++;

            q = line;

        } else {

            if ((q - line) < sizeof(line) - 1)

                *q++ = ch;

        }

    }

}


static void decodeplane8(uint8_t *dst, const uint8_t *const buf, int buf_size, int bps, int plane)

{

    GetBitContext gb;

    int i, b;

    init_get_bits(&gb, buf, buf_size * 8);

    for(i = 0; i < (buf_size * 8 + bps - 1) / bps; i++) {

        for (b = 0; b < bps; b++) {

            dst[ i*bps + b ] |= get_bits1(&gb) << plane;

        }

    }

}


static void mpeg_decode_sequence_extension(MpegEncContext *s)

{

    int horiz_size_ext, vert_size_ext;

    int bit_rate_ext;

    int level, profile;

    skip_bits(&s->gb, 1); /* profil and level esc*/

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

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

    s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */

    s->chroma_format = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */

    horiz_size_ext = get_bits(&s->gb, 2);

    vert_size_ext = get_bits(&s->gb, 2);

    s->width |= (horiz_size_ext << 12);

    s->height |= (vert_size_ext << 12);

    bit_rate_ext = get_bits(&s->gb, 12);  /* XXX: handle it */

    s->bit_rate += (bit_rate_ext << 12) * 400;

    skip_bits1(&s->gb); /* marker */

    s->avctx->rc_buffer_size += get_bits(&s->gb, 8)*1024*16<<10;

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

    if(s->flags & CODEC_FLAG_LOW_DELAY) s->low_delay=1;

    s->frame_rate_ext_n = get_bits(&s->gb, 2);

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

    dprintf("sequence extension\n");

    s->codec_id= s->avctx->codec_id= CODEC_ID_MPEG2VIDEO;

    s->avctx->sub_id = 2; /* indicates mpeg2 found */

    if(s->avctx->debug & FF_DEBUG_PICT_INFO)

        av_log(s->avctx, AV_LOG_DEBUG, "profile: %d, level: %d vbv buffer: %d, bitrate:%d\n",

               profile, level, s->avctx->rc_buffer_size, s->bit_rate);

}


static int init(AVFilterContext *ctx, const char *args)

{

    EvalContext *eval = ctx->priv;

    char *args1 = av_strdup(eval->exprs);

    char *expr, *buf;

    int ret, i;

    if (!args1) {

        av_log(ctx, AV_LOG_ERROR, "Channels expressions list is empty\n");

        ret = args ? AVERROR(ENOMEM) : AVERROR(EINVAL);

        goto end;

    }

    /* parse expressions */

    buf = args1;

    i = 0;

    while (i < FF_ARRAY_ELEMS(eval->expr) && (expr = av_strtok(buf, "|", &buf))) {

        ret = av_expr_parse(&eval->expr[i], expr, var_names,

                            NULL, NULL, NULL, NULL, 0, ctx);

        if (ret < 0)

            goto end;

        i++;

    }

    eval->nb_channels = i;

    if (eval->chlayout_str) {

        int n;

        ret = ff_parse_channel_layout(&eval->chlayout, eval->chlayout_str, ctx);

        if (ret < 0)

            goto end;

        n = av_get_channel_layout_nb_channels(eval->chlayout);

        if (n != eval->nb_channels) {

            av_log(ctx, AV_LOG_ERROR,

                   "Mismatch between the specified number of channels '%d' "

                   "and the number of channels '%d' in the specified channel layout '%s'\n",

                   eval->nb_channels, n, eval->chlayout_str);

            ret = AVERROR(EINVAL);

            goto end;

        }

    } else {

        /* guess channel layout from nb expressions/channels */

        eval->chlayout = av_get_default_channel_layout(eval->nb_channels);

        if (!eval->chlayout) {

            av_log(ctx, AV_LOG_ERROR, "Invalid number of channels '%d' provided\n",

                   eval->nb_channels);

            ret = AVERROR(EINVAL);

            goto end;

        }

    }

    if ((ret = ff_parse_sample_rate(&eval->sample_rate, eval->sample_rate_str, ctx)))

        goto end;

    eval->duration = -1;

    if (eval->duration_str) {

        int64_t us = -1;

        if ((ret = av_parse_time(&us, eval->duration_str, 1)) < 0) {

            av_log(ctx, AV_LOG_ERROR, "Invalid duration: '%s'\n", eval->duration_str);

            goto end;

        }

        eval->duration = (double)us / 1000000;

    }

    eval->n = 0;

end:

    av_free(args1);

    return ret;

}


static void vc1_loop_filter_iblk(MpegEncContext *s, int pq)

{

    int i, j;

    if(!s->first_slice_line)

        s->dsp.vc1_loop_filter(s->dest[0], 1, s->linesize, 16, pq);

    s->dsp.vc1_loop_filter(s->dest[0] + 8*s->linesize, 1, s->linesize, 16, pq);

    for(i = !s->mb_x*8; i < 16; i += 8)

        s->dsp.vc1_loop_filter(s->dest[0] + i, s->linesize, 1, 16, pq);

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

        if(!s->first_slice_line)

            s->dsp.vc1_loop_filter(s->dest[j+1], 1, s->uvlinesize, 8, pq);

        if(s->mb_x)

            s->dsp.vc1_loop_filter(s->dest[j+1], s->uvlinesize, 1, 8, pq);

    }

}


static int dnxhd_decode_dct_block_10(const DNXHDContext *ctx,

                                     RowContext *row, int n)

{

    return dnxhd_decode_dct_block(ctx, row, n, 6, 8, 4);

}


static inline void RENAME(hScale)(int16_t *dst, int dstW, const uint8_t *src, int srcW, int xInc,

                                  const int16_t *filter, const int16_t *filterPos, long filterSize)

{

#if COMPILE_TEMPLATE_MMX

    assert(filterSize % 4 == 0 && filterSize>0);

    if (filterSize==4) { // Always true for upscaling, sometimes for down, too.

        x86_reg counter= -2*dstW;

        filter-= counter*2;

        filterPos-= counter/2;

        dst-= counter/2;

        __asm__ volatile(

#if defined(PIC)

            "push            %%"REG_b"              \n\t"

#endif

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

            "push           %%"REG_BP"              \n\t" // we use 7 regs here ...

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

            ".p2align                4              \n\t"

            "1:                                     \n\t"

            "movzwl   (%2, %%"REG_BP"), %%eax       \n\t"

            "movzwl  2(%2, %%"REG_BP"), %%ebx       \n\t"

            "movq  (%1, %%"REG_BP", 4), %%mm1       \n\t"

            "movq 8(%1, %%"REG_BP", 4), %%mm3       \n\t"

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

            "movd      (%3, %%"REG_b"), %%mm2       \n\t"

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

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

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

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

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

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

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

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

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

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

            "movd                %%mm0, (%4, %%"REG_BP")    \n\t"

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

            " jnc                   1b              \n\t"

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

#if defined(PIC)

            "pop             %%"REG_b"              \n\t"

#endif

            : "+a" (counter)

            : "c" (filter), "d" (filterPos), "S" (src), "D" (dst)

#if !defined(PIC)

            : "%"REG_b

#endif

        );

    } else if (filterSize==8) {

        x86_reg counter= -2*dstW;

        filter-= counter*4;

        filterPos-= counter/2;

        dst-= counter/2;

        __asm__ volatile(

#if defined(PIC)

            "push             %%"REG_b"             \n\t"

#endif

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

            "push            %%"REG_BP"             \n\t" // we use 7 regs here ...

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

            ".p2align                 4             \n\t"

            "1:                                     \n\t"

            "movzwl    (%2, %%"REG_BP"), %%eax      \n\t"

            "movzwl   2(%2, %%"REG_BP"), %%ebx      \n\t"

            "movq   (%1, %%"REG_BP", 8), %%mm1      \n\t"

            "movq 16(%1, %%"REG_BP", 8), %%mm3      \n\t"

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

            "movd       (%3, %%"REG_b"), %%mm2      \n\t"

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

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

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

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

            "movq  8(%1, %%"REG_BP", 8), %%mm1      \n\t"

            "movq 24(%1, %%"REG_BP", 8), %%mm5      \n\t"

            "movd      4(%3, %%"REG_a"), %%mm4      \n\t"

            "movd      4(%3, %%"REG_b"), %%mm2      \n\t"

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

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

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

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

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

            "paddd                %%mm5, %%mm3      \n\t"

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

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

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

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

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

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

            "movd                 %%mm0, (%4, %%"REG_BP")   \n\t"

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

            " jnc                    1b             \n\t"

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

#if defined(PIC)

            "pop              %%"REG_b"             \n\t"

#endif

            : "+a" (counter)

            : "c" (filter), "d" (filterPos), "S" (src), "D" (dst)

#if !defined(PIC)

            : "%"REG_b

#endif

        );

    } else {

        const uint8_t *offset = src+filterSize;

        x86_reg counter= -2*dstW;

        //filter-= counter*filterSize/2;

        filterPos-= counter/2;

        dst-= counter/2;

        __asm__ volatile(

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

            ".p2align                  4            \n\t"

            "1:                                     \n\t"

            "mov                      %2, %%"REG_c" \n\t"

            "movzwl      (%%"REG_c", %0), %%eax     \n\t"

            "movzwl     2(%%"REG_c", %0), %%edx     \n\t"

            "mov                      %5, %%"REG_c" \n\t"

            "pxor                  %%mm4, %%mm4     \n\t"

            "pxor                  %%mm5, %%mm5     \n\t"

            "2:                                     \n\t"

            "movq                   (%1), %%mm1     \n\t"

            "movq               (%1, %6), %%mm3     \n\t"

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

            "movd (%%"REG_c", %%"REG_d"), %%mm2     \n\t"

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

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

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

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

            "paddd                 %%mm3, %%mm5     \n\t"

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

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

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

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

            " jb                      2b            \n\t"

            "add                      %6, %1        \n\t"

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

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

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

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

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

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

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

            "movd                  %%mm4, (%%"REG_a", %0)   \n\t"

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

            " jnc                     1b            \n\t"

            : "+r" (counter), "+r" (filter)

            : "m" (filterPos), "m" (dst), "m"(offset),

            "m" (src), "r" ((x86_reg)filterSize*2)

            : "%"REG_a, "%"REG_c, "%"REG_d

        );

    }

#else

#if COMPILE_TEMPLATE_ALTIVEC

    hScale_altivec_real(dst, dstW, src, srcW, xInc, filter, filterPos, filterSize);

#else

    int i;

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

        int j;

        int srcPos= filterPos[i];

        int val=0;

        //printf("filterPos: %d\n", filterPos[i]);

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

            //printf("filter: %d, src: %d\n", filter[i], src[srcPos + j]);

            val += ((int)src[srcPos + j])*filter[filterSize*i + j];

        }

        //filter += hFilterSize;

        dst[i] = FFMIN(val>>7, (1<<15)-1); // the cubic equation does overflow ...

        //dst[i] = val>>7;

    }

#endif /* COMPILE_TEMPLATE_ALTIVEC */

#endif /* COMPILE_MMX */

}