static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)

{

    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;

    int dp, veclen;

    TCGv addr;

    TCGv tmp;

    TCGv tmp2;

    if (!arm_feature(env, ARM_FEATURE_VFP))

        return 1;

    if (!s->vfp_enabled) {

        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */

        if ((insn & 0x0fe00fff) != 0x0ee00a10)

            return 1;

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

        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC

            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)

            return 1;

    }

    dp = ((insn & 0xf00) == 0xb00);

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

    case 0xe:

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

            /* single register transfer */

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

            if (dp) {

                int size;

                int pass;

                VFP_DREG_N(rn, insn);

                if (insn & 0xf)

                    return 1;

                if (insn & 0x00c00060

                    && !arm_feature(env, ARM_FEATURE_NEON))

                    return 1;

                pass = (insn >> 21) & 1;

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

                    size = 0;

                    offset = ((insn >> 5) & 3) * 8;

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

                    size = 1;

                    offset = (insn & (1 << 6)) ? 16 : 0;

                } else {

                    size = 2;

                    offset = 0;

                }

                if (insn & ARM_CP_RW_BIT) {

                    /* vfp->arm */

                    tmp = neon_load_reg(rn, pass);

                    switch (size) {

                    case 0:

                        if (offset)

                            tcg_gen_shri_i32(tmp, tmp, offset);

                        if (insn & (1 << 23))

                            gen_uxtb(tmp);

                        else

                            gen_sxtb(tmp);

                        break;

                    case 1:

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

                            if (offset) {

                                tcg_gen_shri_i32(tmp, tmp, 16);

                            } else {

                                gen_uxth(tmp);

                            }

                        } else {

                            if (offset) {

                                tcg_gen_sari_i32(tmp, tmp, 16);

                            } else {

                                gen_sxth(tmp);

                            }

                        }

                        break;

                    case 2:

                        break;

                    }

                    store_reg(s, rd, tmp);

                } else {

                    /* arm->vfp */

                    tmp = load_reg(s, rd);

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

                        /* VDUP */

                        if (size == 0) {

                            gen_neon_dup_u8(tmp, 0);

                        } else if (size == 1) {

                            gen_neon_dup_low16(tmp);

                        }

                        for (n = 0; n <= pass * 2; n++) {

                            tmp2 = tcg_temp_new_i32();

                            tcg_gen_mov_i32(tmp2, tmp);

                            neon_store_reg(rn, n, tmp2);

                        }

                        neon_store_reg(rn, n, tmp);

                    } else {

                        /* VMOV */

                        switch (size) {

                        case 0:

                            tmp2 = neon_load_reg(rn, pass);

                            gen_bfi(tmp, tmp2, tmp, offset, 0xff);

                            tcg_temp_free_i32(tmp2);

                            break;

                        case 1:

                            tmp2 = neon_load_reg(rn, pass);

                            gen_bfi(tmp, tmp2, tmp, offset, 0xffff);

                            tcg_temp_free_i32(tmp2);

                            break;

                        case 2:

                            break;

                        }

                        neon_store_reg(rn, pass, tmp);

                    }

                }

            } else { /* !dp */

                if ((insn & 0x6f) != 0x00)

                    return 1;

                rn = VFP_SREG_N(insn);

                if (insn & ARM_CP_RW_BIT) {

                    /* vfp->arm */

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

                        /* system register */

                        rn >>= 1;

                        switch (rn) {

                        case ARM_VFP_FPSID:

                            /* VFP2 allows access to FSID from userspace.

                               VFP3 restricts all id registers to privileged

                               accesses.  */

                            if (IS_USER(s)

                                && arm_feature(env, ARM_FEATURE_VFP3))

                                return 1;

                            tmp = load_cpu_field(vfp.xregs[rn]);

                            break;

                        case ARM_VFP_FPEXC:

                            if (IS_USER(s))

                                return 1;

                            tmp = load_cpu_field(vfp.xregs[rn]);

                            break;

                        case ARM_VFP_FPINST:

                        case ARM_VFP_FPINST2:

                            /* Not present in VFP3.  */

                            if (IS_USER(s)

                                || arm_feature(env, ARM_FEATURE_VFP3))

                                return 1;

                            tmp = load_cpu_field(vfp.xregs[rn]);

                            break;

                        case ARM_VFP_FPSCR:

                            if (rd == 15) {

                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);

                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);

                            } else {

                                tmp = tcg_temp_new_i32();

                                gen_helper_vfp_get_fpscr(tmp, cpu_env);

                            }

                            break;

                        case ARM_VFP_MVFR0:

                        case ARM_VFP_MVFR1:

                            if (IS_USER(s)

                                || !arm_feature(env, ARM_FEATURE_VFP3))

                                return 1;

                            tmp = load_cpu_field(vfp.xregs[rn]);

                            break;

                        default:

                            return 1;

                        }

                    } else {

                        gen_mov_F0_vreg(0, rn);

                        tmp = gen_vfp_mrs();

                    }

                    if (rd == 15) {

                        /* Set the 4 flag bits in the CPSR.  */

                        gen_set_nzcv(tmp);

                        tcg_temp_free_i32(tmp);

                    } else {

                        store_reg(s, rd, tmp);

                    }

                } else {

                    /* arm->vfp */

                    tmp = load_reg(s, rd);

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

                        rn >>= 1;

                        /* system register */

                        switch (rn) {

                        case ARM_VFP_FPSID:

                        case ARM_VFP_MVFR0:

                        case ARM_VFP_MVFR1:

                            /* Writes are ignored.  */

                            break;

                        case ARM_VFP_FPSCR:

                            gen_helper_vfp_set_fpscr(cpu_env, tmp);

                            tcg_temp_free_i32(tmp);

                            gen_lookup_tb(s);

                            break;

                        case ARM_VFP_FPEXC:

                            if (IS_USER(s))

                                return 1;

                            /* TODO: VFP subarchitecture support.

                             * For now, keep the EN bit only */

                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);

                            store_cpu_field(tmp, vfp.xregs[rn]);

                            gen_lookup_tb(s);

                            break;

                        case ARM_VFP_FPINST:

                        case ARM_VFP_FPINST2:

                            store_cpu_field(tmp, vfp.xregs[rn]);

                            break;

                        default:

                            return 1;

                        }

                    } else {

                        gen_vfp_msr(tmp);

                        gen_mov_vreg_F0(0, rn);

                    }

                }

            }

        } else {

            /* data processing */

            /* The opcode is in bits 23, 21, 20 and 6.  */

            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);

            if (dp) {

                if (op == 15) {

                    /* rn is opcode */

                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);

                } else {

                    /* rn is register number */

                    VFP_DREG_N(rn, insn);

                }

                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {

                    /* Integer or single precision destination.  */

                    rd = VFP_SREG_D(insn);

                } else {

                    VFP_DREG_D(rd, insn);

                }

                if (op == 15 &&

                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {

                    /* VCVT from int is always from S reg regardless of dp bit.

                     * VCVT with immediate frac_bits has same format as SREG_M

                     */

                    rm = VFP_SREG_M(insn);

                } else {

                    VFP_DREG_M(rm, insn);

                }

            } else {

                rn = VFP_SREG_N(insn);

                if (op == 15 && rn == 15) {

                    /* Double precision destination.  */

                    VFP_DREG_D(rd, insn);

                } else {

                    rd = VFP_SREG_D(insn);

                }

                /* NB that we implicitly rely on the encoding for the frac_bits

                 * in VCVT of fixed to float being the same as that of an SREG_M

                 */

                rm = VFP_SREG_M(insn);

            }

            veclen = s->vec_len;

            if (op == 15 && rn > 3)

                veclen = 0;

            /* Shut up compiler warnings.  */

            delta_m = 0;

            delta_d = 0;

            bank_mask = 0;

            if (veclen > 0) {

                if (dp)

                    bank_mask = 0xc;

                else

                    bank_mask = 0x18;

                /* Figure out what type of vector operation this is.  */

                if ((rd & bank_mask) == 0) {

                    /* scalar */

                    veclen = 0;

                } else {

                    if (dp)

                        delta_d = (s->vec_stride >> 1) + 1;

                    else

                        delta_d = s->vec_stride + 1;

                    if ((rm & bank_mask) == 0) {

                        /* mixed scalar/vector */

                        delta_m = 0;

                    } else {

                        /* vector */

                        delta_m = delta_d;

                    }

                }

            }

            /* Load the initial operands.  */

            if (op == 15) {

                switch (rn) {

                case 16:

                case 17:

                    /* Integer source */

                    gen_mov_F0_vreg(0, rm);

                    break;

                case 8:

                case 9:

                    /* Compare */

                    gen_mov_F0_vreg(dp, rd);

                    gen_mov_F1_vreg(dp, rm);

                    break;

                case 10:

                case 11:

                    /* Compare with zero */

                    gen_mov_F0_vreg(dp, rd);

                    gen_vfp_F1_ld0(dp);

                    break;

                case 20:

                case 21:

                case 22:

                case 23:

                case 28:

                case 29:

                case 30:

                case 31:

                    /* Source and destination the same.  */

                    gen_mov_F0_vreg(dp, rd);

                    break;

                default:

                    /* One source operand.  */

                    gen_mov_F0_vreg(dp, rm);

                    break;

                }

            } else {

                /* Two source operands.  */

                gen_mov_F0_vreg(dp, rn);

                gen_mov_F1_vreg(dp, rm);

            }

            for (;;) {

                /* Perform the calculation.  */

                switch (op) {

                case 0: /* VMLA: fd + (fn * fm) */

                    /* Note that order of inputs to the add matters for NaNs */

                    gen_vfp_F1_mul(dp);

                    gen_mov_F0_vreg(dp, rd);

                    gen_vfp_add(dp);

                    break;

                case 1: /* VMLS: fd + -(fn * fm) */

                    gen_vfp_mul(dp);

                    gen_vfp_F1_neg(dp);

                    gen_mov_F0_vreg(dp, rd);

                    gen_vfp_add(dp);

                    break;

                case 2: /* VNMLS: -fd + (fn * fm) */

                    /* Note that it isn't valid to replace (-A + B) with (B - A)

                     * or similar plausible looking simplifications

                     * because this will give wrong results for NaNs.

                     */

                    gen_vfp_F1_mul(dp);

                    gen_mov_F0_vreg(dp, rd);

                    gen_vfp_neg(dp);

                    gen_vfp_add(dp);

                    break;

                case 3: /* VNMLA: -fd + -(fn * fm) */

                    gen_vfp_mul(dp);

                    gen_vfp_F1_neg(dp);

                    gen_mov_F0_vreg(dp, rd);

                    gen_vfp_neg(dp);

                    gen_vfp_add(dp);

                    break;

                case 4: /* mul: fn * fm */

                    gen_vfp_mul(dp);

                    break;

                case 5: /* nmul: -(fn * fm) */

                    gen_vfp_mul(dp);

                    gen_vfp_neg(dp);

                    break;

                case 6: /* add: fn + fm */

                    gen_vfp_add(dp);

                    break;

                case 7: /* sub: fn - fm */

                    gen_vfp_sub(dp);

                    break;

                case 8: /* div: fn / fm */

                    gen_vfp_div(dp);

                    break;

                case 14: /* fconst */

                    if (!arm_feature(env, ARM_FEATURE_VFP3))

                      return 1;

                    n = (insn << 12) & 0x80000000;

                    i = ((insn >> 12) & 0x70) | (insn & 0xf);

                    if (dp) {

                        if (i & 0x40)

                            i |= 0x3f80;

                        else

                            i |= 0x4000;

                        n |= i << 16;

                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);

                    } else {

                        if (i & 0x40)

                            i |= 0x780;

                        else

                            i |= 0x800;

                        n |= i << 19;

                        tcg_gen_movi_i32(cpu_F0s, n);

                    }

                    break;

                case 15: /* extension space */

                    switch (rn) {

                    case 0: /* cpy */

                        /* no-op */

                        break;

                    case 1: /* abs */

                        gen_vfp_abs(dp);

                        break;

                    case 2: /* neg */

                        gen_vfp_neg(dp);

                        break;

                    case 3: /* sqrt */

                        gen_vfp_sqrt(dp);

                        break;

                    case 4: /* vcvtb.f32.f16 */

                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))

                          return 1;

                        tmp = gen_vfp_mrs();

                        tcg_gen_ext16u_i32(tmp, tmp);

                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);

                        tcg_temp_free_i32(tmp);

                        break;

                    case 5: /* vcvtt.f32.f16 */

                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))

                          return 1;

                        tmp = gen_vfp_mrs();

                        tcg_gen_shri_i32(tmp, tmp, 16);

                        gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);

                        tcg_temp_free_i32(tmp);

                        break;

                    case 6: /* vcvtb.f16.f32 */

                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))

                          return 1;

                        tmp = tcg_temp_new_i32();

                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);

                        gen_mov_F0_vreg(0, rd);

                        tmp2 = gen_vfp_mrs();

                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);

                        tcg_gen_or_i32(tmp, tmp, tmp2);

                        tcg_temp_free_i32(tmp2);

                        gen_vfp_msr(tmp);

                        break;

                    case 7: /* vcvtt.f16.f32 */

                        if (!arm_feature(env, ARM_FEATURE_VFP_FP16))

                          return 1;

                        tmp = tcg_temp_new_i32();

                        gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);

                        tcg_gen_shli_i32(tmp, tmp, 16);

                        gen_mov_F0_vreg(0, rd);

                        tmp2 = gen_vfp_mrs();

                        tcg_gen_ext16u_i32(tmp2, tmp2);

                        tcg_gen_or_i32(tmp, tmp, tmp2);

                        tcg_temp_free_i32(tmp2);

                        gen_vfp_msr(tmp);

                        break;

                    case 8: /* cmp */

                        gen_vfp_cmp(dp);

                        break;

                    case 9: /* cmpe */

                        gen_vfp_cmpe(dp);

                        break;

                    case 10: /* cmpz */

                        gen_vfp_cmp(dp);

                        break;

                    case 11: /* cmpez */

                        gen_vfp_F1_ld0(dp);

                        gen_vfp_cmpe(dp);

                        break;

                    case 15: /* single<->double conversion */

                        if (dp)

                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);

                        else

                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);

                        break;

                    case 16: /* fuito */

                        gen_vfp_uito(dp, 0);

                        break;

                    case 17: /* fsito */

                        gen_vfp_sito(dp, 0);

                        break;

                    case 20: /* fshto */

                        if (!arm_feature(env, ARM_FEATURE_VFP3))

                          return 1;

                        gen_vfp_shto(dp, 16 - rm, 0);

                        break;

                    case 21: /* fslto */

                        if (!arm_feature(env, ARM_FEATURE_VFP3))

                          return 1;

                        gen_vfp_slto(dp, 32 - rm, 0);

                        break;

                    case 22: /* fuhto */

                        if (!arm_feature(env, ARM_FEATURE_VFP3))

                          return 1;

                        gen_vfp_uhto(dp, 16 - rm, 0);

                        break;

                    case 23: /* fulto */

                        if (!arm_feature(env, ARM_FEATURE_VFP3))

                          return 1;

                        gen_vfp_ulto(dp, 32 - rm, 0);

                        break;

                    case 24: /* ftoui */

                        gen_vfp_toui(dp, 0);

                        break;

                    case 25: /* ftouiz */

                        gen_vfp_touiz(dp, 0);

                        break;

                    case 26: /* ftosi */

                        gen_vfp_tosi(dp, 0);

                        break;

                    case 27: /* ftosiz */

                        gen_vfp_tosiz(dp, 0);

                        break;

                    case 28: /* ftosh */

                        if (!arm_feature(env, ARM_FEATURE_VFP3))

                          return 1;

                        gen_vfp_tosh(dp, 16 - rm, 0);

                        break;

                    case 29: /* ftosl */

                        if (!arm_feature(env, ARM_FEATURE_VFP3))

                          return 1;

                        gen_vfp_tosl(dp, 32 - rm, 0);

                        break;

                    case 30: /* ftouh */

                        if (!arm_feature(env, ARM_FEATURE_VFP3))

                          return 1;

                        gen_vfp_touh(dp, 16 - rm, 0);

                        break;

                    case 31: /* ftoul */

                        if (!arm_feature(env, ARM_FEATURE_VFP3))

                          return 1;

                        gen_vfp_toul(dp, 32 - rm, 0);

                        break;

                    default: /* undefined */

                        printf ("rn:%d\n", rn);

                        return 1;

                    }

                    break;

                default: /* undefined */

                    printf ("op:%d\n", op);

                    return 1;

                }

                /* Write back the result.  */

                if (op == 15 && (rn >= 8 && rn <= 11))

                    ; /* Comparison, do nothing.  */

                else if (op == 15 && dp && ((rn & 0x1c) == 0x18))

                    /* VCVT double to int: always integer result. */

                    gen_mov_vreg_F0(0, rd);

                else if (op == 15 && rn == 15)

                    /* conversion */

                    gen_mov_vreg_F0(!dp, rd);

                else

                    gen_mov_vreg_F0(dp, rd);

                /* break out of the loop if we have finished  */

                if (veclen == 0)

                    break;

                if (op == 15 && delta_m == 0) {

                    /* single source one-many */

                    while (veclen--) {

                        rd = ((rd + delta_d) & (bank_mask - 1))

                             | (rd & bank_mask);

                        gen_mov_vreg_F0(dp, rd);

                    }

                    break;

                }

                /* Setup the next operands.  */

                veclen--;

                rd = ((rd + delta_d) & (bank_mask - 1))

                     | (rd & bank_mask);

                if (op == 15) {

                    /* One source operand.  */

                    rm = ((rm + delta_m) & (bank_mask - 1))

                         | (rm & bank_mask);

                    gen_mov_F0_vreg(dp, rm);

                } else {

                    /* Two source operands.  */

                    rn = ((rn + delta_d) & (bank_mask - 1))

                         | (rn & bank_mask);

                    gen_mov_F0_vreg(dp, rn);

                    if (delta_m) {

                        rm = ((rm + delta_m) & (bank_mask - 1))

                             | (rm & bank_mask);

                        gen_mov_F1_vreg(dp, rm);

                    }

                }

            }

        }

        break;

    case 0xc:

    case 0xd:

        if ((insn & 0x03e00000) == 0x00400000) {

            /* two-register transfer */

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

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

            if (dp) {

                VFP_DREG_M(rm, insn);

            } else {

                rm = VFP_SREG_M(insn);

            }

            if (insn & ARM_CP_RW_BIT) {

                /* vfp->arm */

                if (dp) {

                    gen_mov_F0_vreg(0, rm * 2);

                    tmp = gen_vfp_mrs();

                    store_reg(s, rd, tmp);

                    gen_mov_F0_vreg(0, rm * 2 + 1);

                    tmp = gen_vfp_mrs();

                    store_reg(s, rn, tmp);

                } else {

                    gen_mov_F0_vreg(0, rm);

                    tmp = gen_vfp_mrs();

                    store_reg(s, rd, tmp);

                    gen_mov_F0_vreg(0, rm + 1);

                    tmp = gen_vfp_mrs();

                    store_reg(s, rn, tmp);

                }

            } else {

                /* arm->vfp */

                if (dp) {

                    tmp = load_reg(s, rd);

                    gen_vfp_msr(tmp);

                    gen_mov_vreg_F0(0, rm * 2);

                    tmp = load_reg(s, rn);

                    gen_vfp_msr(tmp);

                    gen_mov_vreg_F0(0, rm * 2 + 1);

                } else {

                    tmp = load_reg(s, rd);

                    gen_vfp_msr(tmp);

                    gen_mov_vreg_F0(0, rm);

                    tmp = load_reg(s, rn);

                    gen_vfp_msr(tmp);

                    gen_mov_vreg_F0(0, rm + 1);

                }

            }

        } else {

            /* Load/store */

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

            if (dp)

                VFP_DREG_D(rd, insn);

            else

                rd = VFP_SREG_D(insn);

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

                /* Single load/store */

                offset = (insn & 0xff) << 2;

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

                    offset = -offset;

                if (s->thumb && rn == 15) {

                    /* This is actually UNPREDICTABLE */

                    addr = tcg_temp_new_i32();

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

                } else {

                    addr = load_reg(s, rn);

                }

                tcg_gen_addi_i32(addr, addr, offset);

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

                    gen_vfp_ld(s, dp, addr);

                    gen_mov_vreg_F0(dp, rd);

                } else {

                    gen_mov_F0_vreg(dp, rd);

                    gen_vfp_st(s, dp, addr);

                }

                tcg_temp_free_i32(addr);

            } else {

                /* load/store multiple */

                int w = insn & (1 << 21);

                if (dp)

                    n = (insn >> 1) & 0x7f;

                else

                    n = insn & 0xff;

                if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {

                    /* P == U , W == 1  => UNDEF */

                    return 1;

                }

                if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {

                    /* UNPREDICTABLE cases for bad immediates: we choose to

                     * UNDEF to avoid generating huge numbers of TCG ops

                     */

                    return 1;

                }

                if (rn == 15 && w) {

                    /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */

                    return 1;

                }

                if (s->thumb && rn == 15) {

                    /* This is actually UNPREDICTABLE */

                    addr = tcg_temp_new_i32();

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

                } else {

                    addr = load_reg(s, rn);

                }

                if (insn & (1 << 24)) /* pre-decrement */

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

                if (dp)

                    offset = 8;

                else

                    offset = 4;

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

                    if (insn & ARM_CP_RW_BIT) {

                        /* load */

                        gen_vfp_ld(s, dp, addr);

                        gen_mov_vreg_F0(dp, rd + i);

                    } else {

                        /* store */

                        gen_mov_F0_vreg(dp, rd + i);

                        gen_vfp_st(s, dp, addr);

                    }

                    tcg_gen_addi_i32(addr, addr, offset);

                }

                if (w) {

                    /* writeback */

                    if (insn & (1 << 24))

                        offset = -offset * n;

                    else if (dp && (insn & 1))

                        offset = 4;

                    else

                        offset = 0;

                    if (offset != 0)

                        tcg_gen_addi_i32(addr, addr, offset);

                    store_reg(s, rn, addr);

                } else {

                    tcg_temp_free_i32(addr);

                }

            }

        }

        break;

    default:

        /* Should never happen.  */

        return 1;

    }

    return 0;

}


void cpu_check_irqs(CPUState *env)

{

    uint32_t pil = env->pil_in | (env->softint & ~SOFTINT_TIMER) |

        ((env->softint & SOFTINT_TIMER) << 14);

    if (pil && (env->interrupt_index == 0 ||

                (env->interrupt_index & ~15) == TT_EXTINT)) {

        unsigned int i;

        for (i = 15; i > 0; i--) {

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

                int old_interrupt = env->interrupt_index;

                env->interrupt_index = TT_EXTINT | i;

                if (old_interrupt != env->interrupt_index) {

                    CPUIRQ_DPRINTF("Set CPU IRQ %d\n", i);

                    cpu_interrupt(env, CPU_INTERRUPT_HARD);

                }

                break;

            }

        }

    } else if (!pil && (env->interrupt_index & ~15) == TT_EXTINT) {

        CPUIRQ_DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);

        env->interrupt_index = 0;

        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);

    }

}


static int default_fdset_dup_fd_find(int dup_fd)

{

    return -1;

}


static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)

{

	TCGv t0, t1;

	t0 = tcg_temp_new(TCG_TYPE_I64);

	t1 = tcg_temp_new(TCG_TYPE_I64);

	tcg_gen_ext32s_i64(t0, a);

	tcg_gen_ext32s_i64(t1, b);

	tcg_gen_mul_i64(t0, t0, t1);

	tcg_gen_trunc_i64_i32(d, t0);

	tcg_gen_shri_i64(t0, t0, 32);

	tcg_gen_trunc_i64_i32(d2, t0);

	tcg_temp_free(t0);

	tcg_temp_free(t1);

}


static void vnc_client_write(void *opaque)

{

    long ret;

    VncState *vs = opaque;

#ifdef CONFIG_VNC_TLS

    if (vs->tls_session) {

	ret = gnutls_write(vs->tls_session, vs->output.buffer, vs->output.offset);

	if (ret < 0) {

	    if (ret == GNUTLS_E_AGAIN)

		errno = EAGAIN;

	    else

		errno = EIO;

	    ret = -1;

	}

    } else

#endif /* CONFIG_VNC_TLS */

	ret = send(vs->csock, vs->output.buffer, vs->output.offset, 0);

    ret = vnc_client_io_error(vs, ret, socket_error());

    if (!ret)

	return;

    memmove(vs->output.buffer, vs->output.buffer + ret, (vs->output.offset - ret));

    vs->output.offset -= ret;

    if (vs->output.offset == 0) {

	qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs);

    }

}


static void test_drive_del_device_del(void)

{

    /* Start with a drive used by a device that unplugs instantaneously */

    qtest_start("-drive if=none,id=drive0,file=null-co://,format=raw"

                " -device virtio-scsi-pci"

                " -device scsi-hd,drive=drive0,id=dev0");

    /*

     * Delete the drive, and then the device

     * Doing it in this order takes notoriously tricky special paths

     */

    drive_del();

    device_del();

    qtest_end();

}


static void omap_uwire_write(void *opaque, target_phys_addr_t addr,

                             uint64_t value, unsigned size)

{

    struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;

    int offset = addr & OMAP_MPUI_REG_MASK;

    if (size != 2) {

        return omap_badwidth_write16(opaque, addr, value);

    }

    switch (offset) {

    case 0x00:	/* TDR */

        s->txbuf = value;				/* TD */

        if ((s->setup[4] & (1 << 2)) &&			/* AUTO_TX_EN */

                        ((s->setup[4] & (1 << 3)) ||	/* CS_TOGGLE_TX_EN */

                         (s->control & (1 << 12)))) {	/* CS_CMD */

            s->control |= 1 << 14;			/* CSRB */

            omap_uwire_transfer_start(s);

        }

        break;

    case 0x04:	/* CSR */

        s->control = value & 0x1fff;

        if (value & (1 << 13))				/* START */

            omap_uwire_transfer_start(s);

        break;

    case 0x08:	/* SR1 */

        s->setup[0] = value & 0x003f;

        break;

    case 0x0c:	/* SR2 */

        s->setup[1] = value & 0x0fc0;

        break;

    case 0x10:	/* SR3 */

        s->setup[2] = value & 0x0003;

        break;

    case 0x14:	/* SR4 */

        s->setup[3] = value & 0x0001;

        break;

    case 0x18:	/* SR5 */

        s->setup[4] = value & 0x000f;

        break;

    default:

        OMAP_BAD_REG(addr);

        return;

    }

}


static inline void _t_gen_mov_env_TN(int offset, TCGv tn)

{

    if (offset > sizeof(CPUCRISState)) {

        fprintf(stderr, "wrong store to env at off=%d\n", offset);

    }

    tcg_gen_st_tl(tn, cpu_env, offset);

}


static QDict *do_info_vnc_client(Monitor *mon, VncState *client)

{

    QDict *qdict;

    qdict = qdict_new();

    if (vnc_qdict_remote_addr(qdict, client->csock) < 0) {

        QDECREF(qdict);

        return NULL;

    }

#ifdef CONFIG_VNC_TLS

    if (client->tls.session &&

        client->tls.dname) {

        qdict_put(qdict, "x509_dname", qstring_from_str(client->tls.dname));

    }

#endif

#ifdef CONFIG_VNC_SASL

    if (client->sasl.conn &&

        client->sasl.username) {

        qdict_put(qdict, "sasl_username",

                  qstring_from_str(client->sasl.username));

    }

#endif

    return qdict;

}


static av_cold int vp3_decode_init(AVCodecContext *avctx)

{

    Vp3DecodeContext *s = avctx->priv_data;

    int i, inter, plane;

    int c_width;

    int c_height;

    int y_fragment_count, c_fragment_count;

    if (avctx->codec_tag == MKTAG('V','P','3','0'))

        s->version = 0;

    else

        s->version = 1;

    s->avctx = avctx;

    s->width = FFALIGN(avctx->width, 16);

    s->height = FFALIGN(avctx->height, 16);

    if (avctx->pix_fmt == PIX_FMT_NONE)

        avctx->pix_fmt = PIX_FMT_YUV420P;

    avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;

    if(avctx->idct_algo==FF_IDCT_AUTO)

        avctx->idct_algo=FF_IDCT_VP3;

    ff_dsputil_init(&s->dsp, avctx);

    ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct);

    /* initialize to an impossible value which will force a recalculation

     * in the first frame decode */

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

        s->qps[i] = -1;

    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);

    s->y_superblock_width = (s->width + 31) / 32;

    s->y_superblock_height = (s->height + 31) / 32;

    s->y_superblock_count = s->y_superblock_width * s->y_superblock_height;

    /* work out the dimensions for the C planes */

    c_width = s->width >> s->chroma_x_shift;

    c_height = s->height >> s->chroma_y_shift;

    s->c_superblock_width = (c_width + 31) / 32;

    s->c_superblock_height = (c_height + 31) / 32;

    s->c_superblock_count = s->c_superblock_width * s->c_superblock_height;

    s->superblock_count = s->y_superblock_count + (s->c_superblock_count * 2);

    s->u_superblock_start = s->y_superblock_count;

    s->v_superblock_start = s->u_superblock_start + s->c_superblock_count;

    s->macroblock_width = (s->width + 15) / 16;

    s->macroblock_height = (s->height + 15) / 16;

    s->macroblock_count = s->macroblock_width * s->macroblock_height;

    s->fragment_width[0] = s->width / FRAGMENT_PIXELS;

    s->fragment_height[0] = s->height / FRAGMENT_PIXELS;

    s->fragment_width[1]  = s->fragment_width[0]  >> s->chroma_x_shift;

    s->fragment_height[1] = s->fragment_height[0] >> s->chroma_y_shift;

    /* fragment count covers all 8x8 blocks for all 3 planes */

    y_fragment_count     = s->fragment_width[0] * s->fragment_height[0];

    c_fragment_count     = s->fragment_width[1] * s->fragment_height[1];

    s->fragment_count    = y_fragment_count + 2*c_fragment_count;

    s->fragment_start[1] = y_fragment_count;

    s->fragment_start[2] = y_fragment_count + c_fragment_count;

    if (!s->theora_tables)

    {

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

            s->coded_dc_scale_factor[i] = vp31_dc_scale_factor[i];

            s->coded_ac_scale_factor[i] = vp31_ac_scale_factor[i];

            s->base_matrix[0][i] = vp31_intra_y_dequant[i];

            s->base_matrix[1][i] = vp31_intra_c_dequant[i];

            s->base_matrix[2][i] = vp31_inter_dequant[i];

            s->filter_limit_values[i] = vp31_filter_limit_values[i];

        }

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

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

                s->qr_count[inter][plane]= 1;

                s->qr_size [inter][plane][0]= 63;

                s->qr_base [inter][plane][0]=

                s->qr_base [inter][plane][1]= 2*inter + (!!plane)*!inter;

            }

        }

        /* init VLC tables */

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

            /* DC histograms */

            init_vlc(&s->dc_vlc[i], 11, 32,

                &dc_bias[i][0][1], 4, 2,

                &dc_bias[i][0][0], 4, 2, 0);

            /* group 1 AC histograms */

            init_vlc(&s->ac_vlc_1[i], 11, 32,

                &ac_bias_0[i][0][1], 4, 2,

                &ac_bias_0[i][0][0], 4, 2, 0);

            /* group 2 AC histograms */

            init_vlc(&s->ac_vlc_2[i], 11, 32,

                &ac_bias_1[i][0][1], 4, 2,

                &ac_bias_1[i][0][0], 4, 2, 0);

            /* group 3 AC histograms */

            init_vlc(&s->ac_vlc_3[i], 11, 32,

                &ac_bias_2[i][0][1], 4, 2,

                &ac_bias_2[i][0][0], 4, 2, 0);

            /* group 4 AC histograms */

            init_vlc(&s->ac_vlc_4[i], 11, 32,

                &ac_bias_3[i][0][1], 4, 2,

                &ac_bias_3[i][0][0], 4, 2, 0);

        }

    } else {

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

            /* DC histograms */

            if (init_vlc(&s->dc_vlc[i], 11, 32,

                &s->huffman_table[i][0][1], 8, 4,

                &s->huffman_table[i][0][0], 8, 4, 0) < 0)

                goto vlc_fail;

            /* group 1 AC histograms */

            if (init_vlc(&s->ac_vlc_1[i], 11, 32,

                &s->huffman_table[i+16][0][1], 8, 4,

                &s->huffman_table[i+16][0][0], 8, 4, 0) < 0)

                goto vlc_fail;

            /* group 2 AC histograms */

            if (init_vlc(&s->ac_vlc_2[i], 11, 32,

                &s->huffman_table[i+16*2][0][1], 8, 4,

                &s->huffman_table[i+16*2][0][0], 8, 4, 0) < 0)

                goto vlc_fail;

            /* group 3 AC histograms */

            if (init_vlc(&s->ac_vlc_3[i], 11, 32,

                &s->huffman_table[i+16*3][0][1], 8, 4,

                &s->huffman_table[i+16*3][0][0], 8, 4, 0) < 0)

                goto vlc_fail;

            /* group 4 AC histograms */

            if (init_vlc(&s->ac_vlc_4[i], 11, 32,

                &s->huffman_table[i+16*4][0][1], 8, 4,

                &s->huffman_table[i+16*4][0][0], 8, 4, 0) < 0)

                goto vlc_fail;

        }

    }

    init_vlc(&s->superblock_run_length_vlc, 6, 34,

        &superblock_run_length_vlc_table[0][1], 4, 2,

        &superblock_run_length_vlc_table[0][0], 4, 2, 0);

    init_vlc(&s->fragment_run_length_vlc, 5, 30,

        &fragment_run_length_vlc_table[0][1], 4, 2,

        &fragment_run_length_vlc_table[0][0], 4, 2, 0);

    init_vlc(&s->mode_code_vlc, 3, 8,

        &mode_code_vlc_table[0][1], 2, 1,

        &mode_code_vlc_table[0][0], 2, 1, 0);

    init_vlc(&s->motion_vector_vlc, 6, 63,

        &motion_vector_vlc_table[0][1], 2, 1,

        &motion_vector_vlc_table[0][0], 2, 1, 0);

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

        s->current_frame.data[i] = NULL;

        s->last_frame.data[i] = NULL;

        s->golden_frame.data[i] = NULL;

    }

    return allocate_tables(avctx);

vlc_fail:

    av_log(avctx, AV_LOG_FATAL, "Invalid huffman table\n");

    return -1;

}


static void nvdimm_build_fit(Aml *dev)

{

    Aml *method, *pkg, *buf, *buf_size, *offset, *call_result;

    Aml *whilectx, *ifcond, *ifctx, *elsectx, *fit;

    buf = aml_local(0);

    buf_size = aml_local(1);

    fit = aml_local(2);

    aml_append(dev, aml_create_dword_field(aml_buffer(4, NULL),

               aml_int(0), NVDIMM_DSM_RFIT_STATUS));

    /* build helper function, RFIT. */

    method = aml_method("RFIT", 1, AML_SERIALIZED);

    aml_append(method, aml_create_dword_field(aml_buffer(4, NULL),

                                              aml_int(0), "OFST"));

    /* prepare input package. */

    pkg = aml_package(1);

    aml_append(method, aml_store(aml_arg(0), aml_name("OFST")));

    aml_append(pkg, aml_name("OFST"));

    /* call Read_FIT function. */

    call_result = aml_call5(NVDIMM_COMMON_DSM,

                            aml_touuid(NVDIMM_QEMU_RSVD_UUID),

                            aml_int(1) /* Revision 1 */,

                            aml_int(0x1) /* Read FIT */,

                            pkg, aml_int(NVDIMM_QEMU_RSVD_HANDLE_ROOT));

    aml_append(method, aml_store(call_result, buf));

    /* handle _DSM result. */

    aml_append(method, aml_create_dword_field(buf,

               aml_int(0) /* offset at byte 0 */, "STAU"));

    aml_append(method, aml_store(aml_name("STAU"),

                                 aml_name(NVDIMM_DSM_RFIT_STATUS)));

     /* if something is wrong during _DSM. */

    ifcond = aml_equal(aml_int(NVDIMM_DSM_RET_STATUS_SUCCESS),

                       aml_name("STAU"));

    ifctx = aml_if(aml_lnot(ifcond));

    aml_append(ifctx, aml_return(aml_buffer(0, NULL)));

    aml_append(method, ifctx);

    aml_append(method, aml_store(aml_sizeof(buf), buf_size));

    aml_append(method, aml_subtract(buf_size,

                                    aml_int(4) /* the size of "STAU" */,

                                    buf_size));

    /* if we read the end of fit. */

    ifctx = aml_if(aml_equal(buf_size, aml_int(0)));

    aml_append(ifctx, aml_return(aml_buffer(0, NULL)));

    aml_append(method, ifctx);

    aml_append(method, aml_create_field(buf,

                            aml_int(4 * BITS_PER_BYTE), /* offset at byte 4.*/

                            aml_shiftleft(buf_size, aml_int(3)), "BUFF"));

    aml_append(method, aml_return(aml_name("BUFF")));

    aml_append(dev, method);

    /* build _FIT. */

    method = aml_method("_FIT", 0, AML_SERIALIZED);

    offset = aml_local(3);

    aml_append(method, aml_store(aml_buffer(0, NULL), fit));

    aml_append(method, aml_store(aml_int(0), offset));

    whilectx = aml_while(aml_int(1));

    aml_append(whilectx, aml_store(aml_call1("RFIT", offset), buf));

    aml_append(whilectx, aml_store(aml_sizeof(buf), buf_size));

    /*

     * if fit buffer was changed during RFIT, read from the beginning

     * again.

     */

    ifctx = aml_if(aml_equal(aml_name(NVDIMM_DSM_RFIT_STATUS),

                             aml_int(NVDIMM_DSM_RET_STATUS_FIT_CHANGED)));

    aml_append(ifctx, aml_store(aml_buffer(0, NULL), fit));

    aml_append(ifctx, aml_store(aml_int(0), offset));

    aml_append(whilectx, ifctx);

    elsectx = aml_else();

    /* finish fit read if no data is read out. */

    ifctx = aml_if(aml_equal(buf_size, aml_int(0)));

    aml_append(ifctx, aml_return(fit));

    aml_append(elsectx, ifctx);

    /* update the offset. */

    aml_append(elsectx, aml_add(offset, buf_size, offset));

    /* append the data we read out to the fit buffer. */

    aml_append(elsectx, aml_concatenate(fit, buf, fit));

    aml_append(whilectx, elsectx);

    aml_append(method, whilectx);

    aml_append(dev, method);

}


PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,

                                 hwaddr base, qemu_irq irq)

{

    PXA2xxLCDState *s;

    DisplaySurface *surface;

    s = (PXA2xxLCDState *) g_malloc0(sizeof(PXA2xxLCDState));

    s->invalidated = 1;

    s->irq = irq;

    s->sysmem = sysmem;

    pxa2xx_lcdc_orientation(s, graphic_rotate);

    memory_region_init_io(&s->iomem, NULL, &pxa2xx_lcdc_ops, s,

                          "pxa2xx-lcd-controller", 0x00100000);

    memory_region_add_subregion(sysmem, base, &s->iomem);

    s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);

    surface = qemu_console_surface(s->con);

    switch (surface_bits_per_pixel(surface)) {

    case 0:

        s->dest_width = 0;

        break;

    case 8:

        s->line_fn[0] = pxa2xx_draw_fn_8;

        s->line_fn[1] = pxa2xx_draw_fn_8t;

        s->dest_width = 1;

        break;

    case 15:

        s->line_fn[0] = pxa2xx_draw_fn_15;

        s->line_fn[1] = pxa2xx_draw_fn_15t;

        s->dest_width = 2;

        break;

    case 16:

        s->line_fn[0] = pxa2xx_draw_fn_16;

        s->line_fn[1] = pxa2xx_draw_fn_16t;

        s->dest_width = 2;

        break;

    case 24:

        s->line_fn[0] = pxa2xx_draw_fn_24;

        s->line_fn[1] = pxa2xx_draw_fn_24t;

        s->dest_width = 3;

        break;

    case 32:

        s->line_fn[0] = pxa2xx_draw_fn_32;

        s->line_fn[1] = pxa2xx_draw_fn_32t;

        s->dest_width = 4;

        break;

    default:

        fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);

        exit(1);

    }

    vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);

    return s;

}


static unsigned int dec_movem_mr(DisasContext *dc)

{

	TCGv tmp[16];

	TCGv addr;

	int i;

	int nr = dc->op2 + 1;

	DIS(fprintf (logfile, "movem [$r%u%s, $r%u\n", dc->op1,

		    dc->postinc ? "+]" : "]", dc->op2));

	addr = tcg_temp_new(TCG_TYPE_TL);

	/* There are probably better ways of doing this.  */

	cris_flush_cc_state(dc);

	for (i = 0; i < (nr >> 1); i++) {

		tmp[i] = tcg_temp_new(TCG_TYPE_I64);

		tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);

		gen_load(dc, tmp[i], addr, 8, 0);

	}

	if (nr & 1) {

		tmp[i] = tcg_temp_new(TCG_TYPE_I32);

		tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);

		gen_load(dc, tmp[i], addr, 4, 0);

	}

	tcg_temp_free(addr);

	for (i = 0; i < (nr >> 1); i++) {

		tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);

		tcg_gen_shri_i64(tmp[i], tmp[i], 32);

		tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);

		tcg_temp_free(tmp[i]);

	}

	if (nr & 1) {

		tcg_gen_mov_tl(cpu_R[dc->op2], tmp[i]);

		tcg_temp_free(tmp[i]);

	}

	/* writeback the updated pointer value.  */

	if (dc->postinc)

		tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);

	/* gen_load might want to evaluate the previous insns flags.  */

	cris_cc_mask(dc, 0);

	return 2;

}


static int xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,

                                    XenPTReg *cfg_entry, uint16_t *val,

                                    uint16_t dev_value, uint16_t valid_mask)

{

    XenPTRegInfo *reg = cfg_entry->reg;

    XenPTMSI *msi = s->msi;

    uint16_t writable_mask = 0;

    uint16_t old_data = cfg_entry->data;

    uint32_t offset = reg->offset;

    /* check the offset whether matches the type or not */

    if (!xen_pt_msi_check_type(offset, msi->flags, DATA)) {

        /* exit I/O emulator */

        XEN_PT_ERR(&s->dev, "the offset does not match the 32/64 bit type!\n");

        return -1;

    }

    /* modify emulate register */

    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;

    cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);

    /* update the msi_info too */

    msi->data = cfg_entry->data;

    /* create value for writing to I/O device register */

    *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0);

    /* update MSI */

    if (cfg_entry->data != old_data) {

        if (msi->mapped) {

            xen_pt_msi_update(s);

        }

    }

    return 0;

}


void HELPER(cdsg)(CPUS390XState *env, uint64_t addr,

                  uint32_t r1, uint32_t r3)

{

    uintptr_t ra = GETPC();

    Int128 cmpv = int128_make128(env->regs[r1 + 1], env->regs[r1]);

    Int128 newv = int128_make128(env->regs[r3 + 1], env->regs[r3]);

    Int128 oldv;

    bool fail;

    if (parallel_cpus) {

#ifndef CONFIG_ATOMIC128

        cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);

#else

        int mem_idx = cpu_mmu_index(env, false);

        TCGMemOpIdx oi = make_memop_idx(MO_TEQ | MO_ALIGN_16, mem_idx);

        oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);

        fail = !int128_eq(oldv, cmpv);

#endif

    } else {

        uint64_t oldh, oldl;

        check_alignment(env, addr, 16, ra);

        oldh = cpu_ldq_data_ra(env, addr + 0, ra);

        oldl = cpu_ldq_data_ra(env, addr + 8, ra);

        oldv = int128_make128(oldl, oldh);

        fail = !int128_eq(oldv, cmpv);

        if (fail) {

            newv = oldv;

        }

        cpu_stq_data_ra(env, addr + 0, int128_gethi(newv), ra);

        cpu_stq_data_ra(env, addr + 8, int128_getlo(newv), ra);

    }

    env->cc_op = fail;

    env->regs[r1] = int128_gethi(oldv);

    env->regs[r1 + 1] = int128_getlo(oldv);

}


static int qcow2_do_open(BlockDriverState *bs, QDict *options, int flags,

                         Error **errp)

{

    BDRVQcow2State *s = bs->opaque;

    unsigned int len, i;

    int ret = 0;

    QCowHeader header;

    Error *local_err = NULL;

    uint64_t ext_end;

    uint64_t l1_vm_state_index;

    ret = bdrv_pread(bs->file, 0, &header, sizeof(header));

    if (ret < 0) {

        error_setg_errno(errp, -ret, "Could not read qcow2 header");

        goto fail;

    }

    be32_to_cpus(&header.magic);

    be32_to_cpus(&header.version);

    be64_to_cpus(&header.backing_file_offset);

    be32_to_cpus(&header.backing_file_size);

    be64_to_cpus(&header.size);

    be32_to_cpus(&header.cluster_bits);

    be32_to_cpus(&header.crypt_method);

    be64_to_cpus(&header.l1_table_offset);

    be32_to_cpus(&header.l1_size);

    be64_to_cpus(&header.refcount_table_offset);

    be32_to_cpus(&header.refcount_table_clusters);

    be64_to_cpus(&header.snapshots_offset);

    be32_to_cpus(&header.nb_snapshots);

    if (header.magic != QCOW_MAGIC) {

        error_setg(errp, "Image is not in qcow2 format");

        ret = -EINVAL;

        goto fail;

    }

    if (header.version < 2 || header.version > 3) {

        error_setg(errp, "Unsupported qcow2 version %" PRIu32, header.version);

        ret = -ENOTSUP;

        goto fail;

    }

    s->qcow_version = header.version;

    /* Initialise cluster size */

    if (header.cluster_bits < MIN_CLUSTER_BITS ||

        header.cluster_bits > MAX_CLUSTER_BITS) {

        error_setg(errp, "Unsupported cluster size: 2^%" PRIu32,

                   header.cluster_bits);

        ret = -EINVAL;

        goto fail;

    }

    s->cluster_bits = header.cluster_bits;

    s->cluster_size = 1 << s->cluster_bits;

    s->cluster_sectors = 1 << (s->cluster_bits - 9);

    /* Initialise version 3 header fields */

    if (header.version == 2) {

        header.incompatible_features    = 0;

        header.compatible_features      = 0;

        header.autoclear_features       = 0;

        header.refcount_order           = 4;

        header.header_length            = 72;

    } else {

        be64_to_cpus(&header.incompatible_features);

        be64_to_cpus(&header.compatible_features);

        be64_to_cpus(&header.autoclear_features);

        be32_to_cpus(&header.refcount_order);

        be32_to_cpus(&header.header_length);

        if (header.header_length < 104) {

            error_setg(errp, "qcow2 header too short");

            ret = -EINVAL;

            goto fail;

        }

    }

    if (header.header_length > s->cluster_size) {

        error_setg(errp, "qcow2 header exceeds cluster size");

        ret = -EINVAL;

        goto fail;

    }

    if (header.header_length > sizeof(header)) {

        s->unknown_header_fields_size = header.header_length - sizeof(header);

        s->unknown_header_fields = g_malloc(s->unknown_header_fields_size);

        ret = bdrv_pread(bs->file, sizeof(header), s->unknown_header_fields,

                         s->unknown_header_fields_size);

        if (ret < 0) {

            error_setg_errno(errp, -ret, "Could not read unknown qcow2 header "

                             "fields");

            goto fail;

        }

    }

    if (header.backing_file_offset > s->cluster_size) {

        error_setg(errp, "Invalid backing file offset");

        ret = -EINVAL;

        goto fail;

    }

    if (header.backing_file_offset) {

        ext_end = header.backing_file_offset;

    } else {

        ext_end = 1 << header.cluster_bits;

    }

    /* Handle feature bits */

    s->incompatible_features    = header.incompatible_features;

    s->compatible_features      = header.compatible_features;

    s->autoclear_features       = header.autoclear_features;

    if (s->incompatible_features & ~QCOW2_INCOMPAT_MASK) {

        void *feature_table = NULL;

        qcow2_read_extensions(bs, header.header_length, ext_end,

                              &feature_table, NULL);

        report_unsupported_feature(errp, feature_table,

                                   s->incompatible_features &

                                   ~QCOW2_INCOMPAT_MASK);

        ret = -ENOTSUP;

        g_free(feature_table);

        goto fail;

    }

    if (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT) {

        /* Corrupt images may not be written to unless they are being repaired

         */

        if ((flags & BDRV_O_RDWR) && !(flags & BDRV_O_CHECK)) {

            error_setg(errp, "qcow2: Image is corrupt; cannot be opened "

                       "read/write");

            ret = -EACCES;

            goto fail;

        }

    }

    /* Check support for various header values */

    if (header.refcount_order > 6) {

        error_setg(errp, "Reference count entry width too large; may not "

                   "exceed 64 bits");

        ret = -EINVAL;

        goto fail;

    }

    s->refcount_order = header.refcount_order;

    s->refcount_bits = 1 << s->refcount_order;

    s->refcount_max = UINT64_C(1) << (s->refcount_bits - 1);

    s->refcount_max += s->refcount_max - 1;

    if (header.crypt_method > QCOW_CRYPT_AES) {

        error_setg(errp, "Unsupported encryption method: %" PRIu32,

                   header.crypt_method);

        ret = -EINVAL;

        goto fail;

    }

    if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALG_AES_128,

                                 QCRYPTO_CIPHER_MODE_CBC)) {

        error_setg(errp, "AES cipher not available");

        ret = -EINVAL;

        goto fail;

    }

    s->crypt_method_header = header.crypt_method;

    if (s->crypt_method_header) {

        if (bdrv_uses_whitelist() &&

            s->crypt_method_header == QCOW_CRYPT_AES) {

            error_setg(errp,

                       "Use of AES-CBC encrypted qcow2 images is no longer "

                       "supported in system emulators");

            error_append_hint(errp,

                              "You can use 'qemu-img convert' to convert your "

                              "image to an alternative supported format, such "

                              "as unencrypted qcow2, or raw with the LUKS "

                              "format instead.\n");

            ret = -ENOSYS;

            goto fail;

        }

        bs->encrypted = true;

    }

    s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */

    s->l2_size = 1 << s->l2_bits;

    /* 2^(s->refcount_order - 3) is the refcount width in bytes */

    s->refcount_block_bits = s->cluster_bits - (s->refcount_order - 3);

    s->refcount_block_size = 1 << s->refcount_block_bits;

    bs->total_sectors = header.size / 512;

    s->csize_shift = (62 - (s->cluster_bits - 8));

    s->csize_mask = (1 << (s->cluster_bits - 8)) - 1;

    s->cluster_offset_mask = (1LL << s->csize_shift) - 1;

    s->refcount_table_offset = header.refcount_table_offset;

    s->refcount_table_size =

        header.refcount_table_clusters << (s->cluster_bits - 3);

    if (header.refcount_table_clusters > qcow2_max_refcount_clusters(s)) {

        error_setg(errp, "Reference count table too large");

        ret = -EINVAL;

        goto fail;

    }

    ret = validate_table_offset(bs, s->refcount_table_offset,

                                s->refcount_table_size, sizeof(uint64_t));

    if (ret < 0) {

        error_setg(errp, "Invalid reference count table offset");

        goto fail;

    }

    /* Snapshot table offset/length */

    if (header.nb_snapshots > QCOW_MAX_SNAPSHOTS) {

        error_setg(errp, "Too many snapshots");

        ret = -EINVAL;

        goto fail;

    }

    ret = validate_table_offset(bs, header.snapshots_offset,

                                header.nb_snapshots,

                                sizeof(QCowSnapshotHeader));

    if (ret < 0) {

        error_setg(errp, "Invalid snapshot table offset");

        goto fail;

    }

    /* read the level 1 table */

    if (header.l1_size > QCOW_MAX_L1_SIZE / sizeof(uint64_t)) {

        error_setg(errp, "Active L1 table too large");

        ret = -EFBIG;

        goto fail;

    }

    s->l1_size = header.l1_size;

    l1_vm_state_index = size_to_l1(s, header.size);

    if (l1_vm_state_index > INT_MAX) {

        error_setg(errp, "Image is too big");

        ret = -EFBIG;

        goto fail;

    }

    s->l1_vm_state_index = l1_vm_state_index;

    /* the L1 table must contain at least enough entries to put

       header.size bytes */

    if (s->l1_size < s->l1_vm_state_index) {

        error_setg(errp, "L1 table is too small");

        ret = -EINVAL;

        goto fail;

    }

    ret = validate_table_offset(bs, header.l1_table_offset,

                                header.l1_size, sizeof(uint64_t));

    if (ret < 0) {

        error_setg(errp, "Invalid L1 table offset");

        goto fail;

    }

    s->l1_table_offset = header.l1_table_offset;

    if (s->l1_size > 0) {

        s->l1_table = qemu_try_blockalign(bs->file->bs,

            align_offset(s->l1_size * sizeof(uint64_t), 512));

        if (s->l1_table == NULL) {

            error_setg(errp, "Could not allocate L1 table");

            ret = -ENOMEM;

            goto fail;

        }

        ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table,

                         s->l1_size * sizeof(uint64_t));

        if (ret < 0) {

            error_setg_errno(errp, -ret, "Could not read L1 table");

            goto fail;

        }

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

            be64_to_cpus(&s->l1_table[i]);

        }

    }

    /* Parse driver-specific options */

    ret = qcow2_update_options(bs, options, flags, errp);

    if (ret < 0) {

        goto fail;

    }

    s->cluster_cache = g_malloc(s->cluster_size);

    /* one more sector for decompressed data alignment */

    s->cluster_data = qemu_try_blockalign(bs->file->bs, QCOW_MAX_CRYPT_CLUSTERS

                                                    * s->cluster_size + 512);

    if (s->cluster_data == NULL) {

        error_setg(errp, "Could not allocate temporary cluster buffer");

        ret = -ENOMEM;

        goto fail;

    }

    s->cluster_cache_offset = -1;

    s->flags = flags;

    ret = qcow2_refcount_init(bs);

    if (ret != 0) {

        error_setg_errno(errp, -ret, "Could not initialize refcount handling");

        goto fail;

    }

    QLIST_INIT(&s->cluster_allocs);

    QTAILQ_INIT(&s->discards);

    /* read qcow2 extensions */

    if (qcow2_read_extensions(bs, header.header_length, ext_end, NULL,

        &local_err)) {

        error_propagate(errp, local_err);

        ret = -EINVAL;

        goto fail;

    }

    /* read the backing file name */

    if (header.backing_file_offset != 0) {

        len = header.backing_file_size;

        if (len > MIN(1023, s->cluster_size - header.backing_file_offset) ||

            len >= sizeof(bs->backing_file)) {

            error_setg(errp, "Backing file name too long");

            ret = -EINVAL;

            goto fail;

        }

        ret = bdrv_pread(bs->file, header.backing_file_offset,

                         bs->backing_file, len);

        if (ret < 0) {

            error_setg_errno(errp, -ret, "Could not read backing file name");

            goto fail;

        }

        bs->backing_file[len] = '\0';

        s->image_backing_file = g_strdup(bs->backing_file);

    }

    /* Internal snapshots */

    s->snapshots_offset = header.snapshots_offset;

    s->nb_snapshots = header.nb_snapshots;

    ret = qcow2_read_snapshots(bs);

    if (ret < 0) {

        error_setg_errno(errp, -ret, "Could not read snapshots");

        goto fail;

    }

    /* Clear unknown autoclear feature bits */

    if (!bs->read_only && !(flags & BDRV_O_INACTIVE) && s->autoclear_features) {

        s->autoclear_features = 0;

        ret = qcow2_update_header(bs);

        if (ret < 0) {

            error_setg_errno(errp, -ret, "Could not update qcow2 header");

            goto fail;

        }

    }

    /* Initialise locks */

    qemu_co_mutex_init(&s->lock);

    bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP;

    /* Repair image if dirty */

    if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only &&

        (s->incompatible_features & QCOW2_INCOMPAT_DIRTY)) {

        BdrvCheckResult result = {0};

        ret = qcow2_check(bs, &result, BDRV_FIX_ERRORS | BDRV_FIX_LEAKS);

        if (ret < 0) {

            error_setg_errno(errp, -ret, "Could not repair dirty image");

            goto fail;

        }

    }

#ifdef DEBUG_ALLOC

    {

        BdrvCheckResult result = {0};

        qcow2_check_refcounts(bs, &result, 0);

    }

#endif

    return ret;

 fail:

    g_free(s->unknown_header_fields);

    cleanup_unknown_header_ext(bs);

    qcow2_free_snapshots(bs);

    qcow2_refcount_close(bs);

    qemu_vfree(s->l1_table);

    /* else pre-write overlap checks in cache_destroy may crash */

    s->l1_table = NULL;

    cache_clean_timer_del(bs);

    if (s->l2_table_cache) {

        qcow2_cache_destroy(bs, s->l2_table_cache);

    }

    if (s->refcount_block_cache) {

        qcow2_cache_destroy(bs, s->refcount_block_cache);

    }

    g_free(s->cluster_cache);

    qemu_vfree(s->cluster_data);

    return ret;

}


static XHCIEPContext *xhci_alloc_epctx(XHCIState *xhci,

                                       unsigned int slotid,

                                       unsigned int epid)

{

    XHCIEPContext *epctx;

    int i;

    epctx = g_new0(XHCIEPContext, 1);

    epctx->xhci = xhci;

    epctx->slotid = slotid;

    epctx->epid = epid;

    for (i = 0; i < ARRAY_SIZE(epctx->transfers); i++) {

        epctx->transfers[i].xhci = xhci;

        epctx->transfers[i].slotid = slotid;

        epctx->transfers[i].epid = epid;

        usb_packet_init(&epctx->transfers[i].packet);

    }

    epctx->kick_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, xhci_ep_kick_timer, epctx);

    return epctx;

}


static uint16_t phys_map_node_alloc(void)

{

    unsigned i;

    uint16_t ret;

    ret = next_map.nodes_nb++;

    assert(ret != PHYS_MAP_NODE_NIL);

    assert(ret != next_map.nodes_nb_alloc);

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

        next_map.nodes[ret][i].is_leaf = 0;

        next_map.nodes[ret][i].ptr = PHYS_MAP_NODE_NIL;

    }

    return ret;

}


bool qemu_peer_has_vnet_hdr_len(NetClientState *nc, int len)

{

    if (!nc->peer || !nc->peer->info->has_vnet_hdr_len) {

        return false;

    }

    return nc->peer->info->has_vnet_hdr_len(nc->peer, len);

}


static void avc_luma_midh_qrt_16w_msa(const uint8_t *src, int32_t src_stride,

                                      uint8_t *dst, int32_t dst_stride,

                                      int32_t height, uint8_t horiz_offset)

{

    uint32_t multiple8_cnt;

    for (multiple8_cnt = 4; multiple8_cnt--;) {

        avc_luma_midh_qrt_4w_msa(src, src_stride, dst, dst_stride, height,

                                 horiz_offset);

        src += 4;

        dst += 4;

    }

}


static void vc1_put_block(VC1Context *v, DCTELEM block[6][64])

{

    uint8_t *Y;

    int ys, us, vs;

    DSPContext *dsp = &v->s.dsp;

    if(v->rangeredfrm) {

        int i, j, k;

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

            for(j = 0; j < 8; j++)

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

                    block[k][i + j*8] = (block[k][i + j*8] - 64) << 1;

    }

    ys = v->s.current_picture.linesize[0];

    us = v->s.current_picture.linesize[1];

    vs = v->s.current_picture.linesize[2];

    Y = v->s.dest[0];

    dsp->put_pixels_clamped(block[0], Y, ys);

    dsp->put_pixels_clamped(block[1], Y + 8, ys);

    Y += ys * 8;

    dsp->put_pixels_clamped(block[2], Y, ys);

    dsp->put_pixels_clamped(block[3], Y + 8, ys);

    if(!(v->s.flags & CODEC_FLAG_GRAY)) {

        dsp->put_pixels_clamped(block[4], v->s.dest[1], us);

        dsp->put_pixels_clamped(block[5], v->s.dest[2], vs);

    }

}


static int decode_frame(AVCodecContext *avctx,

                             void *data, int *data_size,

                             AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    H264Context *h = avctx->priv_data;

    MpegEncContext *s = &h->s;

    AVFrame *pict = data;

    int buf_index;

    s->flags= avctx->flags;

    s->flags2= avctx->flags2;

   /* end of stream, output what is still in the buffers */

 out:

    if (buf_size == 0) {

        Picture *out;

        int i, out_idx;

        s->current_picture_ptr = NULL;

//FIXME factorize this with the output code below

        out = h->delayed_pic[0];

        out_idx = 0;

        for(i=1; h->delayed_pic[i] && !h->delayed_pic[i]->key_frame && !h->delayed_pic[i]->mmco_reset; i++)

            if(h->delayed_pic[i]->poc < out->poc){

                out = h->delayed_pic[i];

                out_idx = i;

            }

        for(i=out_idx; h->delayed_pic[i]; i++)

            h->delayed_pic[i] = h->delayed_pic[i+1];

        if(out){

            *data_size = sizeof(AVFrame);

            *pict= *(AVFrame*)out;

        }

        return 0;

    }

    buf_index=decode_nal_units(h, buf, buf_size);

    if(buf_index < 0)

        return -1;

    if (!s->current_picture_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {

        buf_size = 0;

        goto out;

    }

    if(!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr){

        if (avctx->skip_frame >= AVDISCARD_NONREF)

            return 0;

        av_log(avctx, AV_LOG_ERROR, "no frame!\n");

        return -1;

    }

    if(!(s->flags2 & CODEC_FLAG2_CHUNKS) || (s->mb_y >= s->mb_height && s->mb_height)){

        if(s->flags2 & CODEC_FLAG2_CHUNKS) decode_postinit(h);

        field_end(h, 0);

        if (!h->next_output_pic) {

            /* Wait for second field. */

            *data_size = 0;

        } else {

            *data_size = sizeof(AVFrame);

            *pict = *(AVFrame*)h->next_output_pic;

        }

    }

    assert(pict->data[0] || !*data_size);

    ff_print_debug_info(s, pict);

//printf("out %d\n", (int)pict->data[0]);

    return get_consumed_bytes(s, buf_index, buf_size);

}


void kvm_remove_all_breakpoints(CPUState *cpu)

{

    struct kvm_sw_breakpoint *bp, *next;

    KVMState *s = cpu->kvm_state;

    QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {

        if (kvm_arch_remove_sw_breakpoint(cpu, bp) != 0) {

            /* Try harder to find a CPU that currently sees the breakpoint. */

            CPU_FOREACH(cpu) {

                if (kvm_arch_remove_sw_breakpoint(cpu, bp) == 0) {

                    break;

                }

            }

        }

        QTAILQ_REMOVE(&s->kvm_sw_breakpoints, bp, entry);

        g_free(bp);

    }

    kvm_arch_remove_all_hw_breakpoints();

    CPU_FOREACH(cpu) {

        kvm_update_guest_debug(cpu, 0);

    }

}


static unsigned int read_sbr_data(AACContext *ac, SpectralBandReplication *sbr,

                                  GetBitContext *gb, int id_aac)

{

    unsigned int cnt = get_bits_count(gb);

    if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) {

        read_sbr_single_channel_element(ac, sbr, gb);

    } else if (id_aac == TYPE_CPE) {

        read_sbr_channel_pair_element(ac, sbr, gb);

    } else {

        av_log(ac->avccontext, AV_LOG_ERROR,

            "Invalid bitstream - cannot apply SBR to element type %d\n", id_aac);

        sbr->start = 0;

        return get_bits_count(gb) - cnt;

    }

    if (get_bits1(gb)) { // bs_extended_data

        int num_bits_left = get_bits(gb, 4); // bs_extension_size

        if (num_bits_left == 15)

            num_bits_left += get_bits(gb, 8); // bs_esc_count

        num_bits_left <<= 3;

        while (num_bits_left > 7) {

            num_bits_left -= 2;

            read_sbr_extension(ac, sbr, gb, get_bits(gb, 2), &num_bits_left); // bs_extension_id

        }

    }

    return get_bits_count(gb) - cnt;

}


ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,

                                   MemoryRegion *mr)

{

    RAMBlock *new_block;

    size = TARGET_PAGE_ALIGN(size);

    new_block = g_malloc0(sizeof(*new_block));

    new_block->mr = mr;

    new_block->offset = find_ram_offset(size);

    if (host) {

        new_block->host = host;

        new_block->flags |= RAM_PREALLOC_MASK;

    } else {

        if (mem_path) {

#if defined (__linux__) && !defined(TARGET_S390X)

            new_block->host = file_ram_alloc(new_block, size, mem_path);

            if (!new_block->host) {

                new_block->host = qemu_vmalloc(size);

                qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);

            }

#else

            fprintf(stderr, "-mem-path option unsupported\n");

            exit(1);

#endif

        } else {

            if (xen_enabled()) {

                xen_ram_alloc(new_block->offset, size, mr);

            } else if (kvm_enabled()) {

                /* some s390/kvm configurations have special constraints */

                new_block->host = kvm_vmalloc(size);

            } else {

                new_block->host = qemu_vmalloc(size);

            }

            qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);

        }

    }

    new_block->length = size;

    QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);

    ram_list.phys_dirty = g_realloc(ram_list.phys_dirty,

                                       last_ram_offset() >> TARGET_PAGE_BITS);

    cpu_physical_memory_set_dirty_range(new_block->offset, size, 0xff);

    if (kvm_enabled())

        kvm_setup_guest_memory(new_block->host, size);

    return new_block->offset;

}


static MemTxResult  memory_region_read_accessor(MemoryRegion *mr,

                                                hwaddr addr,

                                                uint64_t *value,

                                                unsigned size,

                                                unsigned shift,

                                                uint64_t mask,

                                                MemTxAttrs attrs)

{

    uint64_t tmp;

    tmp = mr->ops->read(mr->opaque, addr, size);

    if (mr->subpage) {

        trace_memory_region_subpage_read(get_cpu_index(), mr, addr, tmp, size);

    } else if (TRACE_MEMORY_REGION_OPS_READ_ENABLED) {

        hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr);

        trace_memory_region_ops_read(get_cpu_index(), mr, abs_addr, tmp, size);

    }

    *value |= (tmp & mask) << shift;

    return MEMTX_OK;

}


static void unmanageable_intercept(S390CPU *cpu, const char *str, int pswoffset)

{

    CPUState *cs = CPU(cpu);

    error_report("Unmanageable %s! CPU%i new PSW: 0x%016lx:%016lx",

                 str, cs->cpu_index, ldq_phys(cs->as, cpu->env.psa + pswoffset),

                 ldq_phys(cs->as, cpu->env.psa + pswoffset + 8));

    s390_cpu_halt(cpu);

    guest_panicked();

}


static int cook_decode_init(AVCodecContext *avctx)

{

    COOKextradata *e = (COOKextradata *)avctx->extradata;

    COOKContext *q = avctx->priv_data;

    /* Take care of the codec specific extradata. */

    if (avctx->extradata_size <= 0) {

        av_log(avctx,AV_LOG_ERROR,"Necessary extradata missing!\n");

        return -1;

    } else {

        /* 8 for mono, 16 for stereo, ? for multichannel

           Swap to right endianness so we don't need to care later on. */

        av_log(avctx,AV_LOG_DEBUG,"codecdata_length=%d\n",avctx->extradata_size);

        if (avctx->extradata_size >= 8){

            e->cookversion = be2me_32(e->cookversion);

            e->samples_per_frame = be2me_16(e->samples_per_frame);

            e->subbands = be2me_16(e->subbands);

        }

        if (avctx->extradata_size >= 16){

            e->js_subband_start = be2me_16(e->js_subband_start);

            e->js_vlc_bits = be2me_16(e->js_vlc_bits);

        }

    }

    /* Take data from the AVCodecContext (RM container). */

    q->sample_rate = avctx->sample_rate;

    q->nb_channels = avctx->channels;

    q->bit_rate = avctx->bit_rate;

    /* Initialize state. */

    q->random_state = 1;

    /* Initialize extradata related variables. */

    q->samples_per_channel = e->samples_per_frame / q->nb_channels;

    q->samples_per_frame = e->samples_per_frame;

    q->subbands = e->subbands;

    q->bits_per_subpacket = avctx->block_align * 8;

    /* Initialize default data states. */

    q->js_subband_start = 0;

    q->log2_numvector_size = 5;

    q->total_subbands = q->subbands;

    /* Initialize version-dependent variables */

    av_log(NULL,AV_LOG_DEBUG,"e->cookversion=%x\n",e->cookversion);

    q->joint_stereo = 0;

    switch (e->cookversion) {

        case MONO:

            if (q->nb_channels != 1) {

                av_log(avctx,AV_LOG_ERROR,"Container channels != 1, report sample!\n");

                return -1;

            }

            av_log(avctx,AV_LOG_DEBUG,"MONO\n");

            break;

        case STEREO:

            if (q->nb_channels != 1) {

                q->bits_per_subpacket = q->bits_per_subpacket/2;

            }

            av_log(avctx,AV_LOG_DEBUG,"STEREO\n");

            break;

        case JOINT_STEREO:

            if (q->nb_channels != 2) {

                av_log(avctx,AV_LOG_ERROR,"Container channels != 2, report sample!\n");

                return -1;

            }

            av_log(avctx,AV_LOG_DEBUG,"JOINT_STEREO\n");

            if (avctx->extradata_size >= 16){

                q->total_subbands = q->subbands + e->js_subband_start;

                q->js_subband_start = e->js_subband_start;

                q->joint_stereo = 1;

                q->js_vlc_bits = e->js_vlc_bits;

            }

            if (q->samples_per_channel > 256) {

                q->log2_numvector_size  = 6;

            }

            if (q->samples_per_channel > 512) {

                q->log2_numvector_size  = 7;

            }

            break;

        case MC_COOK:

            av_log(avctx,AV_LOG_ERROR,"MC_COOK not supported!\n");

            return -1;

            break;

        default:

            av_log(avctx,AV_LOG_ERROR,"Unknown Cook version, report sample!\n");

            return -1;

            break;

    }

    /* Initialize variable relations */

    q->mlt_size = q->samples_per_channel;

    q->numvector_size = (1 << q->log2_numvector_size);

    /* Generate tables */

    init_rootpow2table(q);

    init_pow2table(q);

    init_gain_table(q);

    if (init_cook_vlc_tables(q) != 0)

        return -1;

    if(avctx->block_align >= UINT_MAX/2)

        return -1;

    /* Pad the databuffer with:

       DECODE_BYTES_PAD1 or DECODE_BYTES_PAD2 for decode_bytes(),

       FF_INPUT_BUFFER_PADDING_SIZE, for the bitstreamreader. */

    if (q->nb_channels==2 && q->joint_stereo==0) {

        q->decoded_bytes_buffer =

          av_mallocz(avctx->block_align/2

                     + DECODE_BYTES_PAD2(avctx->block_align/2)

                     + FF_INPUT_BUFFER_PADDING_SIZE);

    } else {

        q->decoded_bytes_buffer =

          av_mallocz(avctx->block_align

                     + DECODE_BYTES_PAD1(avctx->block_align)

                     + FF_INPUT_BUFFER_PADDING_SIZE);

    }

    if (q->decoded_bytes_buffer == NULL)

        return -1;

    q->gain_ptr1[0] = &q->gain_1;

    q->gain_ptr1[1] = &q->gain_2;

    q->gain_ptr2[0] = &q->gain_3;

    q->gain_ptr2[1] = &q->gain_4;

    /* Initialize transform. */

    if ( init_cook_mlt(q) == 0 )

        return -1;

    /* Try to catch some obviously faulty streams, othervise it might be exploitable */

    if (q->total_subbands > 53) {

        av_log(avctx,AV_LOG_ERROR,"total_subbands > 53, report sample!\n");

        return -1;

    }

    if (q->subbands > 50) {

        av_log(avctx,AV_LOG_ERROR,"subbands > 50, report sample!\n");

        return -1;

    }

    if ((q->samples_per_channel == 256) || (q->samples_per_channel == 512) || (q->samples_per_channel == 1024)) {

    } else {

        av_log(avctx,AV_LOG_ERROR,"unknown amount of samples_per_channel = %d, report sample!\n",q->samples_per_channel);

        return -1;

    }

#ifdef COOKDEBUG

    dump_cook_context(q,e);

#endif

    return 0;

}


static void decode_clnpass(Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1,

                           int width, int height, int bpno, int bandno,

                           int seg_symbols, int vert_causal_ctx_csty_symbol)

{

    int mask = 3 << (bpno - 1), y0, x, y, runlen, dec;

    for (y0 = 0; y0 < height; y0 += 4) {

        for (x = 0; x < width; x++) {

            int flags_mask = -1;

            if (vert_causal_ctx_csty_symbol)

                flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S);

            if (y0 + 3 < height &&

                !((t1->flags[y0 + 1][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||

                  (t1->flags[y0 + 2][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||

                  (t1->flags[y0 + 3][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||

                  (t1->flags[y0 + 4][x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG) & flags_mask))) {

                if (!ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_RL))

                    continue;

                runlen = ff_mqc_decode(&t1->mqc,

                                       t1->mqc.cx_states + MQC_CX_UNI);

                runlen = (runlen << 1) | ff_mqc_decode(&t1->mqc,

                                                       t1->mqc.cx_states +

                                                       MQC_CX_UNI);

                dec = 1;

            } else {

                runlen = 0;

                dec    = 0;

            }

            for (y = y0 + runlen; y < y0 + 4 && y < height; y++) {

                int flags_mask = -1;

                if (vert_causal_ctx_csty_symbol && y == y0 + 3)

                    flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S);

                if (!dec) {

                    if (!(t1->flags[y+1][x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {

                        dec = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[y+1][x+1] & flags_mask,

                                                                                bandno));

                    }

                }

                if (dec) {

                    int xorbit;

                    int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y + 1][x + 1] & flags_mask,

                                                        &xorbit);

                    t1->data[y][x] = (ff_mqc_decode(&t1->mqc,

                                                    t1->mqc.cx_states + ctxno) ^

                                      xorbit)

                                     ? -mask : mask;

                    ff_jpeg2000_set_significance(t1, x, y, t1->data[y][x] < 0);

                }

                dec = 0;

                t1->flags[y + 1][x + 1] &= ~JPEG2000_T1_VIS;

            }

        }

    }

    if (seg_symbols) {

        int val;

        val = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);

        val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);

        val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);

        val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);

        if (val != 0xa)

            av_log(s->avctx, AV_LOG_ERROR,

                   "Segmentation symbol value incorrect\n");

    }

}


static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)

{

    HLSContext *hls = s->priv_data;

    AVFormatContext *oc = NULL;

    AVStream *st = s->streams[pkt->stream_index];

    int64_t end_pts = 0;

    int is_ref_pkt = 1;

    int ret = 0, can_split = 1, i, j;

    int stream_index = 0;

    int range_length = 0;

    uint8_t *buffer = NULL;

    VariantStream *vs = NULL;

    for (i = 0; i < hls->nb_varstreams; i++) {

        vs = &hls->var_streams[i];

        for (j = 0; j < vs->nb_streams; j++) {

            if (vs->streams[j] == st) {

                if( st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE ) {

                    oc = vs->vtt_avf;

                    stream_index = 0;

                } else {

                    oc = vs->avf;

                    stream_index = j;

                }

                break;

            }

        }

        if (oc)

            break;

    }

    if (!oc) {

        av_log(s, AV_LOG_ERROR, "Unable to find mapping variant stream\n");

        return AVERROR(ENOMEM);

    }

    end_pts = hls->recording_time * vs->number;

    if (vs->sequence - vs->nb_entries > hls->start_sequence && hls->init_time > 0) {

        /* reset end_pts, hls->recording_time at end of the init hls list */

        int init_list_dur = hls->init_time * vs->nb_entries * AV_TIME_BASE;

        int after_init_list_dur = (vs->sequence - vs->nb_entries ) * hls->time * AV_TIME_BASE;

        hls->recording_time = hls->time * AV_TIME_BASE;

        end_pts = init_list_dur + after_init_list_dur ;

    }

    if (vs->start_pts == AV_NOPTS_VALUE) {

        vs->start_pts = pkt->pts;

        vs->end_pts   = pkt->pts;

    }

    if (vs->has_video) {

        can_split = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&

                    ((pkt->flags & AV_PKT_FLAG_KEY) || (hls->flags & HLS_SPLIT_BY_TIME));

        is_ref_pkt = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO;

    }

    if (pkt->pts == AV_NOPTS_VALUE)

        is_ref_pkt = can_split = 0;

    if (is_ref_pkt) {

        if (vs->new_start) {

            vs->new_start = 0;

            vs->duration = (double)(pkt->pts - vs->end_pts)

                                       * st->time_base.num / st->time_base.den;

            vs->dpp = (double)(pkt->duration) * st->time_base.num / st->time_base.den;

        } else {

            if (pkt->duration) {

                vs->duration += (double)(pkt->duration) * st->time_base.num / st->time_base.den;

            } else {

                av_log(s, AV_LOG_WARNING, "pkt->duration = 0, maybe the hls segment duration will not precise\n");

                vs->duration = (double)(pkt->pts - vs->end_pts) * st->time_base.num / st->time_base.den;

            }

        }

    }

    if (vs->packets_written && can_split && av_compare_ts(pkt->pts - vs->start_pts, st->time_base,

                                   end_pts, AV_TIME_BASE_Q) >= 0) {

        int64_t new_start_pos;

        char *old_filename = av_strdup(vs->avf->filename);

        int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);

        if (!old_filename) {

            return AVERROR(ENOMEM);

        }

        av_write_frame(vs->avf, NULL); /* Flush any buffered data */

        new_start_pos = avio_tell(vs->avf->pb);

        vs->size = new_start_pos - vs->start_pos;

        if (!byterange_mode) {

            if (hls->segment_type == SEGMENT_TYPE_FMP4 && !vs->init_range_length) {

                avio_flush(oc->pb);

                range_length = avio_close_dyn_buf(oc->pb, &buffer);

                avio_write(vs->out, buffer, range_length);

                vs->init_range_length = range_length;

                avio_open_dyn_buf(&oc->pb);

                vs->packets_written = 0;

                ff_format_io_close(s, &vs->out);

            } else {

                ff_format_io_close(s, &oc->pb);

            }

            if (vs->vtt_avf) {

                ff_format_io_close(s, &vs->vtt_avf->pb);

            }

        }

        if ((hls->flags & HLS_TEMP_FILE) && oc->filename[0]) {

            if (!(hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size <= 0))

                if ((vs->avf->oformat->priv_class && vs->avf->priv_data) && hls->segment_type != SEGMENT_TYPE_FMP4)

                    av_opt_set(vs->avf->priv_data, "mpegts_flags", "resend_headers", 0);

            hls_rename_temp_file(s, oc);

        }

        if (vs->fmp4_init_mode) {

            vs->number--;

        }

        if (!vs->fmp4_init_mode || byterange_mode)

            ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size);

        vs->start_pos = new_start_pos;

        if (ret < 0) {

            av_free(old_filename);

            return ret;

        }

        vs->end_pts = pkt->pts;

        vs->duration = 0;

        vs->fmp4_init_mode = 0;

        if (hls->flags & HLS_SINGLE_FILE) {

            vs->number++;

        } else if (hls->max_seg_size > 0) {

            if (vs->start_pos >= hls->max_seg_size) {

                vs->sequence++;

                sls_flag_file_rename(hls, vs, old_filename);

                ret = hls_start(s, vs);

                vs->start_pos = 0;

                /* When split segment by byte, the duration is short than hls_time,

                 * so it is not enough one segment duration as hls_time, */

                vs->number--;

            }

            vs->number++;

        } else {

            sls_flag_file_rename(hls, vs, old_filename);

            ret = hls_start(s, vs);

        }

        av_free(old_filename);

        if (ret < 0) {

            return ret;

        }

        if (!vs->fmp4_init_mode || byterange_mode)

            if ((ret = hls_window(s, 0, vs)) < 0) {

                return ret;

            }

    }

    vs->packets_written++;

    ret = ff_write_chained(oc, stream_index, pkt, s, 0);

    return ret;

}


void sample_dump(int fnum, int32_t *tab, int n)

{

    static FILE *files[16], *f;

    char buf[512];

    int i;

    int32_t v;

    f = files[fnum];

    if (!f) {

        snprintf(buf, sizeof(buf), "/tmp/out%d.%s.pcm",

                fnum,

#ifdef USE_HIGHPRECISION

                "hp"

#else

                "lp"

#endif

                );

        f = fopen(buf, "w");

        if (!f)

            return;

        files[fnum] = f;

    }

    if (fnum == 0) {

        static int pos = 0;

        printf("pos=%d\n", pos);

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

            printf(" %0.4f", (double)tab[i] / FRAC_ONE);

            if ((i % 18) == 17)

                printf("\n");

        }

        pos += n;

    }

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

        /* normalize to 23 frac bits */

        v = tab[i] << (23 - FRAC_BITS);

        fwrite(&v, 1, sizeof(int32_t), f);

    }

}


int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx)

{

    AVVDPAUContext *hwctx = avctx->hwaccel_context;

    MpegEncContext *s = avctx->priv_data;

    Picture *pic = s->current_picture_ptr;

    struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;

    VdpVideoSurface surf = ff_vdpau_get_surface_id(&pic->f);

    hwctx->render(hwctx->decoder, surf, (void *)&pic_ctx->info,

                  pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers);

    ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);

    av_freep(&pic_ctx->bitstream_buffers);

    return 0;

}


static void skip_data_stream_element(GetBitContext *gb)

{

    int byte_align = get_bits1(gb);

    int count = get_bits(gb, 8);

    if (count == 255)

        count += get_bits(gb, 8);

    if (byte_align)

        align_get_bits(gb);

    skip_bits_long(gb, 8 * count);

}


NetQueue *qemu_new_net_queue(void *opaque)

{

    NetQueue *queue;

    queue = g_malloc0(sizeof(NetQueue));

    queue->opaque = opaque;

    QTAILQ_INIT(&queue->packets);

    queue->delivering = 0;

    return queue;

}