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

{

    int op;

    int q;

    int rd, rn, rm;

    int size;

    int shift;

    int pass;

    int count;

    int pairwise;

    int u;

    int n;

    uint32_t imm, mask;

    TCGv tmp, tmp2, tmp3, tmp4, tmp5;

    TCGv_i64 tmp64;

    if (!s->vfp_enabled)

      return 1;

    q = (insn & (1 << 6)) != 0;

    u = (insn >> 24) & 1;

    VFP_DREG_D(rd, insn);

    VFP_DREG_N(rn, insn);

    VFP_DREG_M(rm, insn);

    size = (insn >> 20) & 3;

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

        /* Three register same length.  */

        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);

        if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9

                          || op == 10 || op  == 11 || op == 16)) {

            /* 64-bit element instructions.  */

            for (pass = 0; pass < (q ? 2 : 1); pass++) {

                neon_load_reg64(cpu_V0, rn + pass);

                neon_load_reg64(cpu_V1, rm + pass);

                switch (op) {

                case 1: /* VQADD */

                    if (u) {

                        gen_helper_neon_add_saturate_u64(CPU_V001);

                    } else {

                        gen_helper_neon_add_saturate_s64(CPU_V001);

                    }

                    break;

                case 5: /* VQSUB */

                    if (u) {

                        gen_helper_neon_sub_saturate_u64(CPU_V001);

                    } else {

                        gen_helper_neon_sub_saturate_s64(CPU_V001);

                    }

                    break;

                case 8: /* VSHL */

                    if (u) {

                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);

                    } else {

                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);

                    }

                    break;

                case 9: /* VQSHL */

                    if (u) {

                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,

                                                 cpu_V1, cpu_V0);

                    } else {

                        gen_helper_neon_qshl_s64(cpu_V0, cpu_env,

                                                 cpu_V1, cpu_V0);

                    }

                    break;

                case 10: /* VRSHL */

                    if (u) {

                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);

                    } else {

                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);

                    }

                    break;

                case 11: /* VQRSHL */

                    if (u) {

                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,

                                                  cpu_V1, cpu_V0);

                    } else {

                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,

                                                  cpu_V1, cpu_V0);

                    }

                    break;

                case 16:

                    if (u) {

                        tcg_gen_sub_i64(CPU_V001);

                    } else {

                        tcg_gen_add_i64(CPU_V001);

                    }

                    break;

                default:

                    abort();

                }

                neon_store_reg64(cpu_V0, rd + pass);

            }

            return 0;

        }

        switch (op) {

        case 8: /* VSHL */

        case 9: /* VQSHL */

        case 10: /* VRSHL */

        case 11: /* VQRSHL */

            {

                int rtmp;

                /* Shift instruction operands are reversed.  */

                rtmp = rn;

                rn = rm;

                rm = rtmp;

                pairwise = 0;

            }

            break;

        case 20: /* VPMAX */

        case 21: /* VPMIN */

        case 23: /* VPADD */

            pairwise = 1;

            break;

        case 26: /* VPADD (float) */

            pairwise = (u && size < 2);

            break;

        case 30: /* VPMIN/VPMAX (float) */

            pairwise = u;

            break;

        default:

            pairwise = 0;

            break;

        }

        for (pass = 0; pass < (q ? 4 : 2); pass++) {

        if (pairwise) {

            /* Pairwise.  */

            if (q)

                n = (pass & 1) * 2;

            else

                n = 0;

            if (pass < q + 1) {

                tmp = neon_load_reg(rn, n);

                tmp2 = neon_load_reg(rn, n + 1);

            } else {

                tmp = neon_load_reg(rm, n);

                tmp2 = neon_load_reg(rm, n + 1);

            }

        } else {

            /* Elementwise.  */

            tmp = neon_load_reg(rn, pass);

            tmp2 = neon_load_reg(rm, pass);

        }

        switch (op) {

        case 0: /* VHADD */

            GEN_NEON_INTEGER_OP(hadd);

            break;

        case 1: /* VQADD */

            GEN_NEON_INTEGER_OP_ENV(qadd);

            break;

        case 2: /* VRHADD */

            GEN_NEON_INTEGER_OP(rhadd);

            break;

        case 3: /* Logic ops.  */

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

            case 0: /* VAND */

                tcg_gen_and_i32(tmp, tmp, tmp2);

                break;

            case 1: /* BIC */

                tcg_gen_andc_i32(tmp, tmp, tmp2);

                break;

            case 2: /* VORR */

                tcg_gen_or_i32(tmp, tmp, tmp2);

                break;

            case 3: /* VORN */

                tcg_gen_orc_i32(tmp, tmp, tmp2);

                break;

            case 4: /* VEOR */

                tcg_gen_xor_i32(tmp, tmp, tmp2);

                break;

            case 5: /* VBSL */

                tmp3 = neon_load_reg(rd, pass);

                gen_neon_bsl(tmp, tmp, tmp2, tmp3);

                dead_tmp(tmp3);

                break;

            case 6: /* VBIT */

                tmp3 = neon_load_reg(rd, pass);

                gen_neon_bsl(tmp, tmp, tmp3, tmp2);

                dead_tmp(tmp3);

                break;

            case 7: /* VBIF */

                tmp3 = neon_load_reg(rd, pass);

                gen_neon_bsl(tmp, tmp3, tmp, tmp2);

                dead_tmp(tmp3);

                break;

            }

            break;

        case 4: /* VHSUB */

            GEN_NEON_INTEGER_OP(hsub);

            break;

        case 5: /* VQSUB */

            GEN_NEON_INTEGER_OP_ENV(qsub);

            break;

        case 6: /* VCGT */

            GEN_NEON_INTEGER_OP(cgt);

            break;

        case 7: /* VCGE */

            GEN_NEON_INTEGER_OP(cge);

            break;

        case 8: /* VSHL */

            GEN_NEON_INTEGER_OP(shl);

            break;

        case 9: /* VQSHL */

            GEN_NEON_INTEGER_OP_ENV(qshl);

            break;

        case 10: /* VRSHL */

            GEN_NEON_INTEGER_OP(rshl);

            break;

        case 11: /* VQRSHL */

            GEN_NEON_INTEGER_OP_ENV(qrshl);

            break;

        case 12: /* VMAX */

            GEN_NEON_INTEGER_OP(max);

            break;

        case 13: /* VMIN */

            GEN_NEON_INTEGER_OP(min);

            break;

        case 14: /* VABD */

            GEN_NEON_INTEGER_OP(abd);

            break;

        case 15: /* VABA */

            GEN_NEON_INTEGER_OP(abd);

            dead_tmp(tmp2);

            tmp2 = neon_load_reg(rd, pass);

            gen_neon_add(size, tmp, tmp2);

            break;

        case 16:

            if (!u) { /* VADD */

                if (gen_neon_add(size, tmp, tmp2))

                    return 1;

            } else { /* VSUB */

                switch (size) {

                case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;

                case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;

                case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;

                default: return 1;

                }

            }

            break;

        case 17:

            if (!u) { /* VTST */

                switch (size) {

                case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;

                case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;

                case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;

                default: return 1;

                }

            } else { /* VCEQ */

                switch (size) {

                case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;

                case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;

                case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;

                default: return 1;

                }

            }

            break;

        case 18: /* Multiply.  */

            switch (size) {

            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;

            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;

            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;

            default: return 1;

            }

            dead_tmp(tmp2);

            tmp2 = neon_load_reg(rd, pass);

            if (u) { /* VMLS */

                gen_neon_rsb(size, tmp, tmp2);

            } else { /* VMLA */

                gen_neon_add(size, tmp, tmp2);

            }

            break;

        case 19: /* VMUL */

            if (u) { /* polynomial */

                gen_helper_neon_mul_p8(tmp, tmp, tmp2);

            } else { /* Integer */

                switch (size) {

                case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;

                case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;

                case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;

                default: return 1;

                }

            }

            break;

        case 20: /* VPMAX */

            GEN_NEON_INTEGER_OP(pmax);

            break;

        case 21: /* VPMIN */

            GEN_NEON_INTEGER_OP(pmin);

            break;

        case 22: /* Hultiply high.  */

            if (!u) { /* VQDMULH */

                switch (size) {

                case 1: gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); break;

                case 2: gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); break;

                default: return 1;

                }

            } else { /* VQRDHMUL */

                switch (size) {

                case 1: gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); break;

                case 2: gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); break;

                default: return 1;

                }

            }

            break;

        case 23: /* VPADD */

            if (u)

                return 1;

            switch (size) {

            case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;

            case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;

            case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;

            default: return 1;

            }

            break;

        case 26: /* Floating point arithnetic.  */

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

            case 0: /* VADD */

                gen_helper_neon_add_f32(tmp, tmp, tmp2);

                break;

            case 2: /* VSUB */

                gen_helper_neon_sub_f32(tmp, tmp, tmp2);

                break;

            case 4: /* VPADD */

                gen_helper_neon_add_f32(tmp, tmp, tmp2);

                break;

            case 6: /* VABD */

                gen_helper_neon_abd_f32(tmp, tmp, tmp2);

                break;

            default:

                return 1;

            }

            break;

        case 27: /* Float multiply.  */

            gen_helper_neon_mul_f32(tmp, tmp, tmp2);

            if (!u) {

                dead_tmp(tmp2);

                tmp2 = neon_load_reg(rd, pass);

                if (size == 0) {

                    gen_helper_neon_add_f32(tmp, tmp, tmp2);

                } else {

                    gen_helper_neon_sub_f32(tmp, tmp2, tmp);

                }

            }

            break;

        case 28: /* Float compare.  */

            if (!u) {

                gen_helper_neon_ceq_f32(tmp, tmp, tmp2);

            } else {

                if (size == 0)

                    gen_helper_neon_cge_f32(tmp, tmp, tmp2);

                else

                    gen_helper_neon_cgt_f32(tmp, tmp, tmp2);

            }

            break;

        case 29: /* Float compare absolute.  */

            if (!u)

                return 1;

            if (size == 0)

                gen_helper_neon_acge_f32(tmp, tmp, tmp2);

            else

                gen_helper_neon_acgt_f32(tmp, tmp, tmp2);

            break;

        case 30: /* Float min/max.  */

            if (size == 0)

                gen_helper_neon_max_f32(tmp, tmp, tmp2);

            else

                gen_helper_neon_min_f32(tmp, tmp, tmp2);

            break;

        case 31:

            if (size == 0)

                gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);

            else

                gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);

            break;

        default:

            abort();

        }

        dead_tmp(tmp2);

        /* Save the result.  For elementwise operations we can put it

           straight into the destination register.  For pairwise operations

           we have to be careful to avoid clobbering the source operands.  */

        if (pairwise && rd == rm) {

            neon_store_scratch(pass, tmp);

        } else {

            neon_store_reg(rd, pass, tmp);

        }

        } /* for pass */

        if (pairwise && rd == rm) {

            for (pass = 0; pass < (q ? 4 : 2); pass++) {

                tmp = neon_load_scratch(pass);

                neon_store_reg(rd, pass, tmp);

            }

        }

        /* End of 3 register same size operations.  */

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

        if ((insn & 0x00380080) != 0) {

            /* Two registers and shift.  */

            op = (insn >> 8) & 0xf;

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

                /* 64-bit shift.   */

                size = 3;

            } else {

                size = 2;

                while ((insn & (1 << (size + 19))) == 0)

                    size--;

            }

            shift = (insn >> 16) & ((1 << (3 + size)) - 1);

            /* To avoid excessive dumplication of ops we implement shift

               by immediate using the variable shift operations.  */

            if (op < 8) {

                /* Shift by immediate:

                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */

                /* Right shifts are encoded as N - shift, where N is the

                   element size in bits.  */

                if (op <= 4)

                    shift = shift - (1 << (size + 3));

                if (size == 3) {

                    count = q + 1;

                } else {

                    count = q ? 4: 2;

                }

                switch (size) {

                case 0:

                    imm = (uint8_t) shift;

                    imm |= imm << 8;

                    imm |= imm << 16;

                    break;

                case 1:

                    imm = (uint16_t) shift;

                    imm |= imm << 16;

                    break;

                case 2:

                case 3:

                    imm = shift;

                    break;

                default:

                    abort();

                }

                for (pass = 0; pass < count; pass++) {

                    if (size == 3) {

                        neon_load_reg64(cpu_V0, rm + pass);

                        tcg_gen_movi_i64(cpu_V1, imm);

                        switch (op) {

                        case 0:  /* VSHR */

                        case 1:  /* VSRA */

                            if (u)

                                gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);

                            else

                                gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);

                            break;

                        case 2: /* VRSHR */

                        case 3: /* VRSRA */

                            if (u)

                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);

                            else

                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);

                            break;

                        case 4: /* VSRI */

                            if (!u)

                                return 1;

                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);

                            break;

                        case 5: /* VSHL, VSLI */

                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);

                            break;

                        case 6: /* VQSHLU */

                            if (u) {

                                gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,

                                                          cpu_V0, cpu_V1);

                            } else {

                                return 1;

                            }

                            break;

                        case 7: /* VQSHL */

                            if (u) {

                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,

                                                         cpu_V0, cpu_V1);

                            } else {

                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,

                                                         cpu_V0, cpu_V1);

                            }

                            break;

                        }

                        if (op == 1 || op == 3) {

                            /* Accumulate.  */

                            neon_load_reg64(cpu_V1, rd + pass);

                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);

                        } else if (op == 4 || (op == 5 && u)) {

                            /* Insert */

                            cpu_abort(env, "VS[LR]I.64 not implemented");

                        }

                        neon_store_reg64(cpu_V0, rd + pass);

                    } else { /* size < 3 */

                        /* Operands in T0 and T1.  */

                        tmp = neon_load_reg(rm, pass);

                        tmp2 = new_tmp();

                        tcg_gen_movi_i32(tmp2, imm);

                        switch (op) {

                        case 0:  /* VSHR */

                        case 1:  /* VSRA */

                            GEN_NEON_INTEGER_OP(shl);

                            break;

                        case 2: /* VRSHR */

                        case 3: /* VRSRA */

                            GEN_NEON_INTEGER_OP(rshl);

                            break;

                        case 4: /* VSRI */

                            if (!u)

                                return 1;

                            GEN_NEON_INTEGER_OP(shl);

                            break;

                        case 5: /* VSHL, VSLI */

                            switch (size) {

                            case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;

                            case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;

                            case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;

                            default: return 1;

                            }

                            break;

                        case 6: /* VQSHLU */

                            if (!u) {

                                return 1;

                            }

                            switch (size) {

                            case 0:

                                gen_helper_neon_qshlu_s8(tmp, cpu_env,

                                                         tmp, tmp2);

                                break;

                            case 1:

                                gen_helper_neon_qshlu_s16(tmp, cpu_env,

                                                          tmp, tmp2);

                                break;

                            case 2:

                                gen_helper_neon_qshlu_s32(tmp, cpu_env,

                                                          tmp, tmp2);

                                break;

                            default:

                                return 1;

                            }

                            break;

                        case 7: /* VQSHL */

                            GEN_NEON_INTEGER_OP_ENV(qshl);

                            break;

                        }

                        dead_tmp(tmp2);

                        if (op == 1 || op == 3) {

                            /* Accumulate.  */

                            tmp2 = neon_load_reg(rd, pass);

                            gen_neon_add(size, tmp, tmp2);

                            dead_tmp(tmp2);

                        } else if (op == 4 || (op == 5 && u)) {

                            /* Insert */

                            switch (size) {

                            case 0:

                                if (op == 4)

                                    mask = 0xff >> -shift;

                                else

                                    mask = (uint8_t)(0xff << shift);

                                mask |= mask << 8;

                                mask |= mask << 16;

                                break;

                            case 1:

                                if (op == 4)

                                    mask = 0xffff >> -shift;

                                else

                                    mask = (uint16_t)(0xffff << shift);

                                mask |= mask << 16;

                                break;

                            case 2:

                                if (shift < -31 || shift > 31) {

                                    mask = 0;

                                } else {

                                    if (op == 4)

                                        mask = 0xffffffffu >> -shift;

                                    else

                                        mask = 0xffffffffu << shift;

                                }

                                break;

                            default:

                                abort();

                            }

                            tmp2 = neon_load_reg(rd, pass);

                            tcg_gen_andi_i32(tmp, tmp, mask);

                            tcg_gen_andi_i32(tmp2, tmp2, ~mask);

                            tcg_gen_or_i32(tmp, tmp, tmp2);

                            dead_tmp(tmp2);

                        }

                        neon_store_reg(rd, pass, tmp);

                    }

                } /* for pass */

            } else if (op < 10) {

                /* Shift by immediate and narrow:

                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */

                shift = shift - (1 << (size + 3));

                size++;

                switch (size) {

                case 1:

                    imm = (uint16_t)shift;

                    imm |= imm << 16;

                    tmp2 = tcg_const_i32(imm);

                    TCGV_UNUSED_I64(tmp64);

                    break;

                case 2:

                    imm = (uint32_t)shift;

                    tmp2 = tcg_const_i32(imm);

                    TCGV_UNUSED_I64(tmp64);

                    break;

                case 3:

                    tmp64 = tcg_const_i64(shift);

                    TCGV_UNUSED(tmp2);

                    break;

                default:

                    abort();

                }

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

                    if (size == 3) {

                        neon_load_reg64(cpu_V0, rm + pass);

                        if (q) {

                          if (u)

                            gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);

                          else

                            gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);

                        } else {

                          if (u)

                            gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);

                          else

                            gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);

                        }

                    } else {

                        tmp = neon_load_reg(rm + pass, 0);

                        gen_neon_shift_narrow(size, tmp, tmp2, q, u);

                        tmp3 = neon_load_reg(rm + pass, 1);

                        gen_neon_shift_narrow(size, tmp3, tmp2, q, u);

                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);

                        dead_tmp(tmp);

                        dead_tmp(tmp3);

                    }

                    tmp = new_tmp();

                    if (op == 8 && !u) {

                        gen_neon_narrow(size - 1, tmp, cpu_V0);

                    } else {

                        if (op == 8)

                            gen_neon_narrow_sats(size - 1, tmp, cpu_V0);

                        else

                            gen_neon_narrow_satu(size - 1, tmp, cpu_V0);

                    }

                    neon_store_reg(rd, pass, tmp);

                } /* for pass */

                if (size == 3) {

                    tcg_temp_free_i64(tmp64);

                } else {

                    tcg_temp_free_i32(tmp2);

                }

            } else if (op == 10) {

                /* VSHLL */

                if (q || size == 3)

                    return 1;

                tmp = neon_load_reg(rm, 0);

                tmp2 = neon_load_reg(rm, 1);

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

                    if (pass == 1)

                        tmp = tmp2;

                    gen_neon_widen(cpu_V0, tmp, size, u);

                    if (shift != 0) {

                        /* The shift is less than the width of the source

                           type, so we can just shift the whole register.  */

                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);

                        if (size < 2 || !u) {

                            uint64_t imm64;

                            if (size == 0) {

                                imm = (0xffu >> (8 - shift));

                                imm |= imm << 16;

                            } else {

                                imm = 0xffff >> (16 - shift);

                            }

                            imm64 = imm | (((uint64_t)imm) << 32);

                            tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);

                        }

                    }

                    neon_store_reg64(cpu_V0, rd + pass);

                }

            } else if (op >= 14) {

                /* VCVT fixed-point.  */

                /* We have already masked out the must-be-1 top bit of imm6,

                 * hence this 32-shift where the ARM ARM has 64-imm6.

                 */

                shift = 32 - shift;

                for (pass = 0; pass < (q ? 4 : 2); pass++) {

                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));

                    if (!(op & 1)) {

                        if (u)

                            gen_vfp_ulto(0, shift);

                        else

                            gen_vfp_slto(0, shift);

                    } else {

                        if (u)

                            gen_vfp_toul(0, shift);

                        else

                            gen_vfp_tosl(0, shift);

                    }

                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));

                }

            } else {

                return 1;

            }

        } else { /* (insn & 0x00380080) == 0 */

            int invert;

            op = (insn >> 8) & 0xf;

            /* One register and immediate.  */

            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);

            invert = (insn & (1 << 5)) != 0;

            switch (op) {

            case 0: case 1:

                /* no-op */

                break;

            case 2: case 3:

                imm <<= 8;

                break;

            case 4: case 5:

                imm <<= 16;

                break;

            case 6: case 7:

                imm <<= 24;

                break;

            case 8: case 9:

                imm |= imm << 16;

                break;

            case 10: case 11:

                imm = (imm << 8) | (imm << 24);

                break;

            case 12:

                imm = (imm << 8) | 0xff;

                break;

            case 13:

                imm = (imm << 16) | 0xffff;

                break;

            case 14:

                imm |= (imm << 8) | (imm << 16) | (imm << 24);

                if (invert)

                    imm = ~imm;

                break;

            case 15:

                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)

                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));

                break;

            }

            if (invert)

                imm = ~imm;

            for (pass = 0; pass < (q ? 4 : 2); pass++) {

                if (op & 1 && op < 12) {

                    tmp = neon_load_reg(rd, pass);

                    if (invert) {

                        /* The immediate value has already been inverted, so

                           BIC becomes AND.  */

                        tcg_gen_andi_i32(tmp, tmp, imm);

                    } else {

                        tcg_gen_ori_i32(tmp, tmp, imm);

                    }

                } else {

                    /* VMOV, VMVN.  */

                    tmp = new_tmp();

                    if (op == 14 && invert) {

                        uint32_t val;

                        val = 0;

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

                            if (imm & (1 << (n + (pass & 1) * 4)))

                                val |= 0xff << (n * 8);

                        }

                        tcg_gen_movi_i32(tmp, val);

                    } else {

                        tcg_gen_movi_i32(tmp, imm);

                    }

                }

                neon_store_reg(rd, pass, tmp);

            }

        }

    } else { /* (insn & 0x00800010 == 0x00800000) */

        if (size != 3) {

            op = (insn >> 8) & 0xf;

            if ((insn & (1 << 6)) == 0) {

                /* Three registers of different lengths.  */

                int src1_wide;

                int src2_wide;

                int prewiden;

                /* prewiden, src1_wide, src2_wide */

                static const int neon_3reg_wide[16][3] = {

                    {1, 0, 0}, /* VADDL */

                    {1, 1, 0}, /* VADDW */

                    {1, 0, 0}, /* VSUBL */

                    {1, 1, 0}, /* VSUBW */

                    {0, 1, 1}, /* VADDHN */

                    {0, 0, 0}, /* VABAL */

                    {0, 1, 1}, /* VSUBHN */

                    {0, 0, 0}, /* VABDL */

                    {0, 0, 0}, /* VMLAL */

                    {0, 0, 0}, /* VQDMLAL */

                    {0, 0, 0}, /* VMLSL */

                    {0, 0, 0}, /* VQDMLSL */

                    {0, 0, 0}, /* Integer VMULL */

                    {0, 0, 0}, /* VQDMULL */

                    {0, 0, 0}  /* Polynomial VMULL */

                };

                prewiden = neon_3reg_wide[op][0];

                src1_wide = neon_3reg_wide[op][1];

                src2_wide = neon_3reg_wide[op][2];

                if (size == 0 && (op == 9 || op == 11 || op == 13))

                    return 1;

                /* Avoid overlapping operands.  Wide source operands are

                   always aligned so will never overlap with wide

                   destinations in problematic ways.  */

                if (rd == rm && !src2_wide) {

                    tmp = neon_load_reg(rm, 1);

                    neon_store_scratch(2, tmp);

                } else if (rd == rn && !src1_wide) {

                    tmp = neon_load_reg(rn, 1);

                    neon_store_scratch(2, tmp);

                }

                TCGV_UNUSED(tmp3);

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

                    if (src1_wide) {

                        neon_load_reg64(cpu_V0, rn + pass);

                        TCGV_UNUSED(tmp);

                    } else {

                        if (pass == 1 && rd == rn) {

                            tmp = neon_load_scratch(2);

                        } else {

                            tmp = neon_load_reg(rn, pass);

                        }

                        if (prewiden) {

                            gen_neon_widen(cpu_V0, tmp, size, u);

                        }

                    }

                    if (src2_wide) {

                        neon_load_reg64(cpu_V1, rm + pass);

                        TCGV_UNUSED(tmp2);

                    } else {

                        if (pass == 1 && rd == rm) {

                            tmp2 = neon_load_scratch(2);

                        } else {

                            tmp2 = neon_load_reg(rm, pass);

                        }

                        if (prewiden) {

                            gen_neon_widen(cpu_V1, tmp2, size, u);

                        }

                    }

                    switch (op) {

                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */

                        gen_neon_addl(size);

                        break;

                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */

                        gen_neon_subl(size);

                        break;

                    case 5: case 7: /* VABAL, VABDL */

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

                        case 0:

                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);

                            break;

                        case 1:

                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);

                            break;

                        case 2:

                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);

                            break;

                        case 3:

                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);

                            break;

                        case 4:

                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);

                            break;

                        case 5:

                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);

                            break;

                        default: abort();

                        }

                        dead_tmp(tmp2);

                        dead_tmp(tmp);

                        break;

                    case 8: case 9: case 10: case 11: case 12: case 13:

                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */

                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);

                        break;

                    case 14: /* Polynomial VMULL */

                        cpu_abort(env, "Polynomial VMULL not implemented");

                    default: /* 15 is RESERVED.  */

                        return 1;

                    }

                    if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {

                        /* Accumulate.  */

                        if (op == 10 || op == 11) {

                            gen_neon_negl(cpu_V0, size);

                        }

                        if (op != 13) {

                            neon_load_reg64(cpu_V1, rd + pass);

                        }

                        switch (op) {

                        case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */

                            gen_neon_addl(size);

                            break;

                        case 9: case 11: /* VQDMLAL, VQDMLSL */

                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);

                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);

                            break;

                            /* Fall through.  */

                        case 13: /* VQDMULL */

                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);

                            break;

                        default:

                            abort();

                        }

                        neon_store_reg64(cpu_V0, rd + pass);

                    } else if (op == 4 || op == 6) {

                        /* Narrowing operation.  */

                        tmp = new_tmp();

                        if (!u) {

                            switch (size) {

                            case 0:

                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);

                                break;

                            case 1:

                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);

                                break;

                            case 2:

                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);

                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);

                                break;

                            default: abort();

                            }

                        } else {

                            switch (size) {

                            case 0:

                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);

                                break;

                            case 1:

                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);

                                break;

                            case 2:

                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);

                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);

                                tcg_gen_trunc_i64_i32(tmp, cpu_V0);

                                break;

                            default: abort();

                            }

                        }

                        if (pass == 0) {

                            tmp3 = tmp;

                        } else {

                            neon_store_reg(rd, 0, tmp3);

                            neon_store_reg(rd, 1, tmp);

                        }

                    } else {

                        /* Write back the result.  */

                        neon_store_reg64(cpu_V0, rd + pass);

                    }

                }

            } else {

                /* Two registers and a scalar.  */

                switch (op) {

                case 0: /* Integer VMLA scalar */

                case 1: /* Float VMLA scalar */

                case 4: /* Integer VMLS scalar */

                case 5: /* Floating point VMLS scalar */

                case 8: /* Integer VMUL scalar */

                case 9: /* Floating point VMUL scalar */

                case 12: /* VQDMULH scalar */

                case 13: /* VQRDMULH scalar */

                    tmp = neon_get_scalar(size, rm);

                    neon_store_scratch(0, tmp);

                    for (pass = 0; pass < (u ? 4 : 2); pass++) {

                        tmp = neon_load_scratch(0);

                        tmp2 = neon_load_reg(rn, pass);

                        if (op == 12) {

                            if (size == 1) {

                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);

                            } else {

                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);

                            }

                        } else if (op == 13) {

                            if (size == 1) {

                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);

                            } else {

                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);

                            }

                        } else if (op & 1) {

                            gen_helper_neon_mul_f32(tmp, tmp, tmp2);

                        } else {

                            switch (size) {

                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;

                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;

                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;

                            default: return 1;

                            }

                        }

                        dead_tmp(tmp2);

                        if (op < 8) {

                            /* Accumulate.  */

                            tmp2 = neon_load_reg(rd, pass);

                            switch (op) {

                            case 0:

                                gen_neon_add(size, tmp, tmp2);

                                break;

                            case 1:

                                gen_helper_neon_add_f32(tmp, tmp, tmp2);

                                break;

                            case 4:

                                gen_neon_rsb(size, tmp, tmp2);

                                break;

                            case 5:

                                gen_helper_neon_sub_f32(tmp, tmp2, tmp);

                                break;

                            default:

                                abort();

                            }

                            dead_tmp(tmp2);

                        }

                        neon_store_reg(rd, pass, tmp);

                    }

                    break;

                case 2: /* VMLAL sclar */

                case 3: /* VQDMLAL scalar */

                case 6: /* VMLSL scalar */

                case 7: /* VQDMLSL scalar */

                case 10: /* VMULL scalar */

                case 11: /* VQDMULL scalar */

                    if (size == 0 && (op == 3 || op == 7 || op == 11))

                        return 1;

                    tmp2 = neon_get_scalar(size, rm);

                    /* We need a copy of tmp2 because gen_neon_mull

                     * deletes it during pass 0.  */

                    tmp4 = new_tmp();

                    tcg_gen_mov_i32(tmp4, tmp2);

                    tmp3 = neon_load_reg(rn, 1);

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

                        if (pass == 0) {

                            tmp = neon_load_reg(rn, 0);

                        } else {

                            tmp = tmp3;

                            tmp2 = tmp4;

                        }

                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);

                        if (op == 6 || op == 7) {

                            gen_neon_negl(cpu_V0, size);

                        }

                        if (op != 11) {

                            neon_load_reg64(cpu_V1, rd + pass);

                        }

                        switch (op) {

                        case 2: case 6:

                            gen_neon_addl(size);

                            break;

                        case 3: case 7:

                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);

                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);

                            break;

                        case 10:

                            /* no-op */

                            break;

                        case 11:

                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);

                            break;

                        default:

                            abort();

                        }

                        neon_store_reg64(cpu_V0, rd + pass);

                    }

                    break;

                default: /* 14 and 15 are RESERVED */

                    return 1;

                }

            }

        } else { /* size == 3 */

            if (!u) {

                /* Extract.  */

                imm = (insn >> 8) & 0xf;

                if (imm > 7 && !q)

                    return 1;

                if (imm == 0) {

                    neon_load_reg64(cpu_V0, rn);

                    if (q) {

                        neon_load_reg64(cpu_V1, rn + 1);

                    }

                } else if (imm == 8) {

                    neon_load_reg64(cpu_V0, rn + 1);

                    if (q) {

                        neon_load_reg64(cpu_V1, rm);

                    }

                } else if (q) {

                    tmp64 = tcg_temp_new_i64();

                    if (imm < 8) {

                        neon_load_reg64(cpu_V0, rn);

                        neon_load_reg64(tmp64, rn + 1);

                    } else {

                        neon_load_reg64(cpu_V0, rn + 1);

                        neon_load_reg64(tmp64, rm);

                    }

                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);

                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));

                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);

                    if (imm < 8) {

                        neon_load_reg64(cpu_V1, rm);

                    } else {

                        neon_load_reg64(cpu_V1, rm + 1);

                        imm -= 8;

                    }

                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));

                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);

                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);

                    tcg_temp_free_i64(tmp64);

                } else {

                    /* BUGFIX */

                    neon_load_reg64(cpu_V0, rn);

                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);

                    neon_load_reg64(cpu_V1, rm);

                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));

                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);

                }

                neon_store_reg64(cpu_V0, rd);

                if (q) {

                    neon_store_reg64(cpu_V1, rd + 1);

                }

            } else if ((insn & (1 << 11)) == 0) {

                /* Two register misc.  */

                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);

                size = (insn >> 18) & 3;

                switch (op) {

                case 0: /* VREV64 */

                    if (size == 3)

                        return 1;

                    for (pass = 0; pass < (q ? 2 : 1); pass++) {

                        tmp = neon_load_reg(rm, pass * 2);

                        tmp2 = neon_load_reg(rm, pass * 2 + 1);

                        switch (size) {

                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;

                        case 1: gen_swap_half(tmp); break;

                        case 2: /* no-op */ break;

                        default: abort();

                        }

                        neon_store_reg(rd, pass * 2 + 1, tmp);

                        if (size == 2) {

                            neon_store_reg(rd, pass * 2, tmp2);

                        } else {

                            switch (size) {

                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;

                            case 1: gen_swap_half(tmp2); break;

                            default: abort();

                            }

                            neon_store_reg(rd, pass * 2, tmp2);

                        }

                    }

                    break;

                case 4: case 5: /* VPADDL */

                case 12: case 13: /* VPADAL */

                    if (size == 3)

                        return 1;

                    for (pass = 0; pass < q + 1; pass++) {

                        tmp = neon_load_reg(rm, pass * 2);

                        gen_neon_widen(cpu_V0, tmp, size, op & 1);

                        tmp = neon_load_reg(rm, pass * 2 + 1);

                        gen_neon_widen(cpu_V1, tmp, size, op & 1);

                        switch (size) {

                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;

                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;

                        case 2: tcg_gen_add_i64(CPU_V001); break;

                        default: abort();

                        }

                        if (op >= 12) {

                            /* Accumulate.  */

                            neon_load_reg64(cpu_V1, rd + pass);

                            gen_neon_addl(size);

                        }

                        neon_store_reg64(cpu_V0, rd + pass);

                    }

                    break;

                case 33: /* VTRN */

                    if (size == 2) {

                        for (n = 0; n < (q ? 4 : 2); n += 2) {

                            tmp = neon_load_reg(rm, n);

                            tmp2 = neon_load_reg(rd, n + 1);

                            neon_store_reg(rm, n, tmp2);

                            neon_store_reg(rd, n + 1, tmp);

                        }

                    } else {

                        goto elementwise;

                    }

                    break;

                case 34: /* VUZP */

                    /* Reg  Before       After

                       Rd   A3 A2 A1 A0  B2 B0 A2 A0

                       Rm   B3 B2 B1 B0  B3 B1 A3 A1

                     */

                    if (size == 3)

                        return 1;

                    gen_neon_unzip(rd, q, 0, size);

                    gen_neon_unzip(rm, q, 4, size);

                    if (q) {

                        static int unzip_order_q[8] =

                            {0, 2, 4, 6, 1, 3, 5, 7};

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

                            int reg = (n < 4) ? rd : rm;

                            tmp = neon_load_scratch(unzip_order_q[n]);

                            neon_store_reg(reg, n % 4, tmp);

                        }

                    } else {

                        static int unzip_order[4] =

                            {0, 4, 1, 5};

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

                            int reg = (n < 2) ? rd : rm;

                            tmp = neon_load_scratch(unzip_order[n]);

                            neon_store_reg(reg, n % 2, tmp);

                        }

                    }

                    break;

                case 35: /* VZIP */

                    /* Reg  Before       After

                       Rd   A3 A2 A1 A0  B1 A1 B0 A0

                       Rm   B3 B2 B1 B0  B3 A3 B2 A2

                     */

                    if (size == 3)

                        return 1;

                    count = (q ? 4 : 2);

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

                        tmp = neon_load_reg(rd, n);

                        tmp2 = neon_load_reg(rd, n);

                        switch (size) {

                        case 0: gen_neon_zip_u8(tmp, tmp2); break;

                        case 1: gen_neon_zip_u16(tmp, tmp2); break;

                        case 2: /* no-op */; break;

                        default: abort();

                        }

                        neon_store_scratch(n * 2, tmp);

                        neon_store_scratch(n * 2 + 1, tmp2);

                    }

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

                        int reg = (n < count) ? rd : rm;

                        tmp = neon_load_scratch(n);

                        neon_store_reg(reg, n % count, tmp);

                    }

                    break;

                case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */

                    if (size == 3)

                        return 1;

                    TCGV_UNUSED(tmp2);

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

                        neon_load_reg64(cpu_V0, rm + pass);

                        tmp = new_tmp();

                        if (op == 36 && q == 0) {

                            gen_neon_narrow(size, tmp, cpu_V0);

                        } else if (q) {

                            gen_neon_narrow_satu(size, tmp, cpu_V0);

                        } else {

                            gen_neon_narrow_sats(size, tmp, cpu_V0);

                        }

                        if (pass == 0) {

                            tmp2 = tmp;

                        } else {

                            neon_store_reg(rd, 0, tmp2);

                            neon_store_reg(rd, 1, tmp);

                        }

                    }

                    break;

                case 38: /* VSHLL */

                    if (q || size == 3)

                        return 1;

                    tmp = neon_load_reg(rm, 0);

                    tmp2 = neon_load_reg(rm, 1);

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

                        if (pass == 1)

                            tmp = tmp2;

                        gen_neon_widen(cpu_V0, tmp, size, 1);

                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);

                        neon_store_reg64(cpu_V0, rd + pass);

                    }

                    break;

                case 44: /* VCVT.F16.F32 */

                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16))

                      return 1;

                    tmp = new_tmp();

                    tmp2 = new_tmp();

                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));

                    gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);

                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));

                    gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);

                    tcg_gen_shli_i32(tmp2, tmp2, 16);

                    tcg_gen_or_i32(tmp2, tmp2, tmp);

                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));

                    gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);

                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));

                    neon_store_reg(rd, 0, tmp2);

                    tmp2 = new_tmp();

                    gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);

                    tcg_gen_shli_i32(tmp2, tmp2, 16);

                    tcg_gen_or_i32(tmp2, tmp2, tmp);

                    neon_store_reg(rd, 1, tmp2);

                    dead_tmp(tmp);

                    break;

                case 46: /* VCVT.F32.F16 */

                    if (!arm_feature(env, ARM_FEATURE_VFP_FP16))

                      return 1;

                    tmp3 = new_tmp();

                    tmp = neon_load_reg(rm, 0);

                    tmp2 = neon_load_reg(rm, 1);

                    tcg_gen_ext16u_i32(tmp3, tmp);

                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);

                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));

                    tcg_gen_shri_i32(tmp3, tmp, 16);

                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);

                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));

                    dead_tmp(tmp);

                    tcg_gen_ext16u_i32(tmp3, tmp2);

                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);

                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));

                    tcg_gen_shri_i32(tmp3, tmp2, 16);

                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);

                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));

                    dead_tmp(tmp2);

                    dead_tmp(tmp3);

                    break;

                default:

                elementwise:

                    for (pass = 0; pass < (q ? 4 : 2); pass++) {

                        if (op == 30 || op == 31 || op >= 58) {

                            tcg_gen_ld_f32(cpu_F0s, cpu_env,

                                           neon_reg_offset(rm, pass));

                            TCGV_UNUSED(tmp);

                        } else {

                            tmp = neon_load_reg(rm, pass);

                        }

                        switch (op) {

                        case 1: /* VREV32 */

                            switch (size) {

                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;

                            case 1: gen_swap_half(tmp); break;

                            default: return 1;

                            }

                            break;

                        case 2: /* VREV16 */

                            if (size != 0)

                                return 1;

                            gen_rev16(tmp);

                            break;

                        case 8: /* CLS */

                            switch (size) {

                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;

                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;

                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;

                            default: return 1;

                            }

                            break;

                        case 9: /* CLZ */

                            switch (size) {

                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;

                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;

                            case 2: gen_helper_clz(tmp, tmp); break;

                            default: return 1;

                            }

                            break;

                        case 10: /* CNT */

                            if (size != 0)

                                return 1;

                            gen_helper_neon_cnt_u8(tmp, tmp);

                            break;

                        case 11: /* VNOT */

                            if (size != 0)

                                return 1;

                            tcg_gen_not_i32(tmp, tmp);

                            break;

                        case 14: /* VQABS */

                            switch (size) {

                            case 0: gen_helper_neon_qabs_s8(tmp, cpu_env, tmp); break;

                            case 1: gen_helper_neon_qabs_s16(tmp, cpu_env, tmp); break;

                            case 2: gen_helper_neon_qabs_s32(tmp, cpu_env, tmp); break;

                            default: return 1;

                            }

                            break;

                        case 15: /* VQNEG */

                            switch (size) {

                            case 0: gen_helper_neon_qneg_s8(tmp, cpu_env, tmp); break;

                            case 1: gen_helper_neon_qneg_s16(tmp, cpu_env, tmp); break;

                            case 2: gen_helper_neon_qneg_s32(tmp, cpu_env, tmp); break;

                            default: return 1;

                            }

                            break;

                        case 16: case 19: /* VCGT #0, VCLE #0 */

                            tmp2 = tcg_const_i32(0);

                            switch(size) {

                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;

                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;

                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;

                            default: return 1;

                            }

                            tcg_temp_free(tmp2);

                            if (op == 19)

                                tcg_gen_not_i32(tmp, tmp);

                            break;

                        case 17: case 20: /* VCGE #0, VCLT #0 */

                            tmp2 = tcg_const_i32(0);

                            switch(size) {

                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;

                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;

                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;

                            default: return 1;

                            }

                            tcg_temp_free(tmp2);

                            if (op == 20)

                                tcg_gen_not_i32(tmp, tmp);

                            break;

                        case 18: /* VCEQ #0 */

                            tmp2 = tcg_const_i32(0);

                            switch(size) {

                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;

                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;

                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;

                            default: return 1;

                            }

                            tcg_temp_free(tmp2);

                            break;

                        case 22: /* VABS */

                            switch(size) {

                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;

                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;

                            case 2: tcg_gen_abs_i32(tmp, tmp); break;

                            default: return 1;

                            }

                            break;

                        case 23: /* VNEG */

                            if (size == 3)

                                return 1;

                            tmp2 = tcg_const_i32(0);

                            gen_neon_rsb(size, tmp, tmp2);

                            tcg_temp_free(tmp2);

                            break;

                        case 24: case 27: /* Float VCGT #0, Float VCLE #0 */

                            tmp2 = tcg_const_i32(0);

                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2);

                            tcg_temp_free(tmp2);

                            if (op == 27)

                                tcg_gen_not_i32(tmp, tmp);

                            break;

                        case 25: case 28: /* Float VCGE #0, Float VCLT #0 */

                            tmp2 = tcg_const_i32(0);

                            gen_helper_neon_cge_f32(tmp, tmp, tmp2);

                            tcg_temp_free(tmp2);

                            if (op == 28)

                                tcg_gen_not_i32(tmp, tmp);

                            break;

                        case 26: /* Float VCEQ #0 */

                            tmp2 = tcg_const_i32(0);

                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2);

                            tcg_temp_free(tmp2);

                            break;

                        case 30: /* Float VABS */

                            gen_vfp_abs(0);

                            break;

                        case 31: /* Float VNEG */

                            gen_vfp_neg(0);

                            break;

                        case 32: /* VSWP */

                            tmp2 = neon_load_reg(rd, pass);

                            neon_store_reg(rm, pass, tmp2);

                            break;

                        case 33: /* VTRN */

                            tmp2 = neon_load_reg(rd, pass);

                            switch (size) {

                            case 0: gen_neon_trn_u8(tmp, tmp2); break;

                            case 1: gen_neon_trn_u16(tmp, tmp2); break;

                            case 2: abort();

                            default: return 1;

                            }

                            neon_store_reg(rm, pass, tmp2);

                            break;

                        case 56: /* Integer VRECPE */

                            gen_helper_recpe_u32(tmp, tmp, cpu_env);

                            break;

                        case 57: /* Integer VRSQRTE */

                            gen_helper_rsqrte_u32(tmp, tmp, cpu_env);

                            break;

                        case 58: /* Float VRECPE */

                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);

                            break;

                        case 59: /* Float VRSQRTE */

                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);

                            break;

                        case 60: /* VCVT.F32.S32 */

                            gen_vfp_sito(0);

                            break;

                        case 61: /* VCVT.F32.U32 */

                            gen_vfp_uito(0);

                            break;

                        case 62: /* VCVT.S32.F32 */

                            gen_vfp_tosiz(0);

                            break;

                        case 63: /* VCVT.U32.F32 */

                            gen_vfp_touiz(0);

                            break;

                        default:

                            /* Reserved: 21, 29, 39-56 */

                            return 1;

                        }

                        if (op == 30 || op == 31 || op >= 58) {

                            tcg_gen_st_f32(cpu_F0s, cpu_env,

                                           neon_reg_offset(rd, pass));

                        } else {

                            neon_store_reg(rd, pass, tmp);

                        }

                    }

                    break;

                }

            } else if ((insn & (1 << 10)) == 0) {

                /* VTBL, VTBX.  */

                n = ((insn >> 5) & 0x18) + 8;

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

                    tmp = neon_load_reg(rd, 0);

                } else {

                    tmp = new_tmp();

                    tcg_gen_movi_i32(tmp, 0);

                }

                tmp2 = neon_load_reg(rm, 0);

                tmp4 = tcg_const_i32(rn);

                tmp5 = tcg_const_i32(n);

                gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);

                dead_tmp(tmp);

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

                    tmp = neon_load_reg(rd, 1);

                } else {

                    tmp = new_tmp();

                    tcg_gen_movi_i32(tmp, 0);

                }

                tmp3 = neon_load_reg(rm, 1);

                gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5);

                tcg_temp_free_i32(tmp5);

                tcg_temp_free_i32(tmp4);

                neon_store_reg(rd, 0, tmp2);

                neon_store_reg(rd, 1, tmp3);

                dead_tmp(tmp);

            } else if ((insn & 0x380) == 0) {

                /* VDUP */

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

                    tmp = neon_load_reg(rm, 1);

                } else {

                    tmp = neon_load_reg(rm, 0);

                }

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

                    gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);

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

                    if ((insn >> 18) & 1)

                        gen_neon_dup_high16(tmp);

                    else

                        gen_neon_dup_low16(tmp);

                }

                for (pass = 0; pass < (q ? 4 : 2); pass++) {

                    tmp2 = new_tmp();

                    tcg_gen_mov_i32(tmp2, tmp);

                    neon_store_reg(rd, pass, tmp2);

                }

                dead_tmp(tmp);

            } else {

                return 1;

            }

        }

    }

    return 0;

}


static av_cold int pcx_end(AVCodecContext *avctx) {

    PCXContext *s = avctx->priv_data;

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

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

    return 0;

}


static void gen_dccci(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    /* interpreted as no-op */

#endif

}


static void vmsvga_init(struct vmsvga_state_s *s,

                        MemoryRegion *address_space, MemoryRegion *io)

{

    DisplaySurface *surface;

    s->scratch_size = SVGA_SCRATCH_SIZE;

    s->scratch = g_malloc(s->scratch_size * 4);

    s->vga.con = graphic_console_init(vmsvga_update_display,

                                      vmsvga_invalidate_display,

                                      vmsvga_screen_dump,

                                      vmsvga_text_update, s);

    surface = qemu_console_surface(s->vga.con);

    s->fifo_size = SVGA_FIFO_SIZE;

    memory_region_init_ram(&s->fifo_ram, "vmsvga.fifo", s->fifo_size);

    vmstate_register_ram_global(&s->fifo_ram);

    s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);

    vga_common_init(&s->vga);

    vga_init(&s->vga, address_space, io, true);

    vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);

    /* Save some values here in case they are changed later.

     * This is suspicious and needs more though why it is needed. */

    s->depth = surface_bits_per_pixel(surface);

    s->bypp = surface_bytes_per_pixel(surface);

}


static void init_frame_decoder(APEContext *ctx)

{

    int i;

    init_entropy_decoder(ctx);

    init_predictor_decoder(ctx);

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

        if (!ape_filter_orders[ctx->fset][i])

            break;

        init_filter(ctx, ctx->filters[i], ctx->filterbuf[i],

                    ape_filter_orders[ctx->fset][i]);

    }

}


static ssize_t local_readlink(FsContext *fs_ctx, const char *path,

        char *buf, size_t bufsz)

{

    ssize_t tsize = -1;

    if (fs_ctx->fs_sm == SM_MAPPED) {

        int fd;

        fd = open(rpath(fs_ctx, path), O_RDONLY);

        if (fd == -1) {

            return -1;

        }

        do {

            tsize = read(fd, (void *)buf, bufsz);

        } while (tsize == -1 && errno == EINTR);

        close(fd);

        return tsize;

    } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) {

        tsize = readlink(rpath(fs_ctx, path), buf, bufsz);

    }

    return tsize;

}


static int dump_cleanup(DumpState *s)

{

    int ret = 0;

    guest_phys_blocks_free(&s->guest_phys_blocks);

    memory_mapping_list_free(&s->list);

    if (s->fd != -1) {

        close(s->fd);

    }

    if (s->resume) {

        vm_start();

    }

    return ret;

}


static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels,

                                   ptrdiff_t pitch)

{

    uint32_t bit_cache;

    uint8_t *list[63];

    uint32_t *dst;

    const uint32_t *codebook;

    int entries[6];

    int i, j, m, n;

    int stages;

    unsigned mean;

    unsigned x, y, width, height, level;

    uint32_t n1, n2, n3, n4;

    /* initialize list for breadth first processing of vectors */

    list[0] = pixels;

    /* recursively process vector */

    for (i = 0, m = 1, n = 1, level = 5; i < n; i++) {

        SVQ1_PROCESS_VECTOR();

        /* destination address and vector size */

        dst    = (uint32_t *)list[i];

        width  = 1 << ((4 + level) / 2);

        height = 1 << ((3 + level) / 2);

        /* get number of stages (-1 skips vector, 0 for mean only) */

        stages = get_vlc2(bitbuf, svq1_intra_multistage[level].table, 3, 3) - 1;

        if (stages == -1) {

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

                memset(&dst[y * (pitch / 4)], 0, width);

            continue;   /* skip vector */

        }

        if ((stages > 0 && level >= 4)) {

            ff_dlog(NULL,

                    "Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n",

                    stages, level);

            return AVERROR_INVALIDDATA;  /* invalid vector */

        }

        av_assert0(stages >= 0);

        mean = get_vlc2(bitbuf, svq1_intra_mean.table, 8, 3);

        if (stages == 0) {

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

                memset(&dst[y * (pitch / 4)], mean, width);

        } else {

            SVQ1_CALC_CODEBOOK_ENTRIES(ff_svq1_intra_codebooks);

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

                for (x = 0; x < width / 4; x++, codebook++) {

                    n1 = n4;

                    n2 = n4;

                    SVQ1_ADD_CODEBOOK()

                    /* store result */

                    dst[x] = n1 << 8 | n2;

                }

                dst += pitch / 4;

            }

        }

    }

    return 0;

}


static int omap2_intc_init(SysBusDevice *sbd)

{

    DeviceState *dev = DEVICE(sbd);

    struct omap_intr_handler_s *s = OMAP_INTC(dev);

    if (!s->iclk) {

        hw_error("omap2-intc: iclk not connected\n");

    }

    if (!s->fclk) {

        hw_error("omap2-intc: fclk not connected\n");

    }

    s->level_only = 1;

    s->nbanks = 3;

    sysbus_init_irq(sbd, &s->parent_intr[0]);

    sysbus_init_irq(sbd, &s->parent_intr[1]);

    qdev_init_gpio_in(dev, omap_set_intr_noedge, s->nbanks * 32);

    memory_region_init_io(&s->mmio, OBJECT(s), &omap2_inth_mem_ops, s,

                          "omap2-intc", 0x1000);

    sysbus_init_mmio(sbd, &s->mmio);

    return 0;

}


static int h264_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame, AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size       = avpkt->size;
    H264Context *h     = avctx->priv_data;
    AVFrame *pict      = data;
    int buf_index      = 0;
    H264Picture *out;
    int i, out_idx;
    int ret;
    h->flags = avctx->flags;
    ff_h264_unref_picture(h, &h->last_pic_for_ec);
    /* end of stream, output what is still in the buffers */
    if (buf_size == 0) {
 out:
        h->cur_pic_ptr = NULL;
        h->first_field = 0;
        // 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]->f->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) {
            out->reference &= ~DELAYED_PIC_REF;
            ret = output_frame(h, pict, out);
            if (ret < 0)
                return ret;
            *got_frame = 1;
        return buf_index;
    if (h->is_avc && av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) {
        int side_size;
        uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
        if (is_extra(side, side_size))
            ff_h264_decode_extradata(h, side, side_size);
    if(h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC && (buf[5]&0x1F) && buf[8]==0x67){
        if (is_extra(buf, buf_size))
            return ff_h264_decode_extradata(h, buf, buf_size);
    buf_index = decode_nal_units(h, buf, buf_size, 0);
    if (buf_index < 0)
        return AVERROR_INVALIDDATA;
    if (!h->cur_pic_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
        av_assert0(buf_index <= buf_size);
        goto out;
    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) && !h->cur_pic_ptr) {
        if (avctx->skip_frame >= AVDISCARD_NONREF ||
            buf_size >= 4 && !memcmp("Q264", buf, 4))
            return buf_size;
        av_log(avctx, AV_LOG_ERROR, "no frame!\n");
        return AVERROR_INVALIDDATA;
    if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) ||
        (h->mb_y >= h->mb_height && h->mb_height)) {
        if (avctx->flags2 & CODEC_FLAG2_CHUNKS)
            decode_postinit(h, 1);
        ff_h264_field_end(h, &h->slice_ctx[0], 0);
        /* Wait for second field. */
        *got_frame = 0;
        if (h->next_output_pic && (
                                   h->next_output_pic->recovered)) {
            if (!h->next_output_pic->recovered)
                h->next_output_pic->f->flags |= AV_FRAME_FLAG_CORRUPT;
            if (!h->avctx->hwaccel &&
                 (h->next_output_pic->field_poc[0] == INT_MAX ||
                  h->next_output_pic->field_poc[1] == INT_MAX)
            ) {
                int p;
                AVFrame *f = h->next_output_pic->f;
                int field = h->next_output_pic->field_poc[0] == INT_MAX;
                uint8_t *dst_data[4];
                int linesizes[4];
                const uint8_t *src_data[4];
                av_log(h->avctx, AV_LOG_DEBUG, "Duplicating field %d to fill missing\n", field);
                for (p = 0; p<4; p++) {
                    dst_data[p] = f->data[p] + (field^1)*f->linesize[p];
                    src_data[p] = f->data[p] +  field   *f->linesize[p];
                    linesizes[p] = 2*f->linesize[p];
                av_image_copy(dst_data, linesizes, src_data, linesizes,
                              f->format, f->width, f->height>>1);
            ret = output_frame(h, pict, h->next_output_pic);
            if (ret < 0)
                return ret;
            *got_frame = 1;
            if (CONFIG_MPEGVIDEO) {
                ff_print_debug_info2(h->avctx, pict, NULL,
                                    h->next_output_pic->mb_type,
                                    h->next_output_pic->qscale_table,
                                    h->next_output_pic->motion_val,
                                    &h->low_delay,
                                    h->mb_width, h->mb_height, h->mb_stride, 1);
    av_assert0(pict->buf[0] || !*got_frame);
    ff_h264_unref_picture(h, &h->last_pic_for_ec);
    return get_consumed_bytes(buf_index, buf_size);


static void core_rtas_register_types(void)

{

    spapr_rtas_register(RTAS_DISPLAY_CHARACTER, "display-character",

                        rtas_display_character);

    spapr_rtas_register(RTAS_GET_TIME_OF_DAY, "get-time-of-day",

                        rtas_get_time_of_day);

    spapr_rtas_register(RTAS_SET_TIME_OF_DAY, "set-time-of-day",

                        rtas_set_time_of_day);

    spapr_rtas_register(RTAS_POWER_OFF, "power-off", rtas_power_off);

    spapr_rtas_register(RTAS_SYSTEM_REBOOT, "system-reboot",

                        rtas_system_reboot);

    spapr_rtas_register(RTAS_QUERY_CPU_STOPPED_STATE, "query-cpu-stopped-state",

                        rtas_query_cpu_stopped_state);

    spapr_rtas_register(RTAS_START_CPU, "start-cpu", rtas_start_cpu);

    spapr_rtas_register(RTAS_STOP_SELF, "stop-self", rtas_stop_self);

    spapr_rtas_register(RTAS_IBM_GET_SYSTEM_PARAMETER,

                        "ibm,get-system-parameter",

                        rtas_ibm_get_system_parameter);

    spapr_rtas_register(RTAS_IBM_SET_SYSTEM_PARAMETER,

                        "ibm,set-system-parameter",

                        rtas_ibm_set_system_parameter);

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    sPAPRPHBClass *spc = SPAPR_PCI_HOST_BRIDGE_CLASS(klass);

    dc->props = spapr_phb_vfio_properties;

    spc->finish_realize = spapr_phb_vfio_finish_realize;

}


static void mxf_write_preface(AVFormatContext *s)

{

    MXFContext *mxf = s->priv_data;

    AVIOContext *pb = s->pb;

    mxf_write_metadata_key(pb, 0x012f00);

    PRINT_KEY(s, "preface key", pb->buf_ptr - 16);

    klv_encode_ber_length(pb, 130 + 16 * mxf->essence_container_count);

    // write preface set uid

    mxf_write_local_tag(pb, 16, 0x3C0A);

    mxf_write_uuid(pb, Preface, 0);

    PRINT_KEY(s, "preface uid", pb->buf_ptr - 16);

    // last modified date

    mxf_write_local_tag(pb, 8, 0x3B02);

    avio_wb64(pb, mxf->timestamp);

    // write version

    mxf_write_local_tag(pb, 2, 0x3B05);

    avio_wb16(pb, 258); // v1.2

    // write identification_refs

    mxf_write_local_tag(pb, 16 + 8, 0x3B06);

    mxf_write_refs_count(pb, 1);

    mxf_write_uuid(pb, Identification, 0);

    // write content_storage_refs

    mxf_write_local_tag(pb, 16, 0x3B03);

    mxf_write_uuid(pb, ContentStorage, 0);

    // operational pattern

    mxf_write_local_tag(pb, 16, 0x3B09);

    avio_write(pb, op1a_ul, 16);

    // write essence_container_refs

    mxf_write_local_tag(pb, 8 + 16 * mxf->essence_container_count, 0x3B0A);

    mxf_write_essence_container_refs(s);

    // write dm_scheme_refs

    mxf_write_local_tag(pb, 8, 0x3B0B);

    avio_wb64(pb, 0);

}


static void add_machine_test_cases(void)

{

    const char *arch = qtest_get_arch();

    QDict *response, *minfo;

    QList *list;

    const QListEntry *p;

    QObject *qobj;

    QString *qstr;

    const char *mname, *path;

    qtest_start("-machine none");

    response = qmp("{ 'execute': 'query-machines' }");

    g_assert(response);

    list = qdict_get_qlist(response, "return");

    g_assert(list);

    for (p = qlist_first(list); p; p = qlist_next(p)) {

        minfo = qobject_to_qdict(qlist_entry_obj(p));

        g_assert(minfo);

        qobj = qdict_get(minfo, "name");

        g_assert(qobj);

        qstr = qobject_to_qstring(qobj);

        g_assert(qstr);

        mname = qstring_get_str(qstr);

        if (!is_blacklisted(arch, mname)) {

            path = g_strdup_printf("qom/%s", mname);

            qtest_add_data_func(path, g_strdup(mname), test_machine);

        }

    }

    qtest_end();

    QDECREF(response);

}


static int adx_decode_frame(AVCodecContext *avctx,

			    void *data, int *data_size,

			    const uint8_t *buf0, int buf_size)

{

	ADXContext *c = avctx->priv_data;

	short *samples = data;

	const uint8_t *buf = buf0;

	int rest = buf_size;

	if (!c->header_parsed) {

		int hdrsize = adx_decode_header(avctx,buf,rest);

		if (hdrsize==0) return -1;

		c->header_parsed = 1;

		buf  += hdrsize;

		rest -= hdrsize;

	}

	if (c->in_temp) {

		int copysize = 18*avctx->channels - c->in_temp;

		memcpy(c->dec_temp+c->in_temp,buf,copysize);

		rest -= copysize;

		buf  += copysize;

		if (avctx->channels==1) {

			adx_decode(samples,c->dec_temp,c->prev);

			samples += 32;

		} else {

			adx_decode_stereo(samples,c->dec_temp,c->prev);

			samples += 32*2;

		}

	}

	//

	if (avctx->channels==1) {

		while(rest>=18) {

			adx_decode(samples,buf,c->prev);

			rest-=18;

			buf+=18;

			samples+=32;

		}

	} else {

		while(rest>=18*2) {

			adx_decode_stereo(samples,buf,c->prev);

			rest-=18*2;

			buf+=18*2;

			samples+=32*2;

		}

	}

	//

	c->in_temp = rest;

	if (rest) {

		memcpy(c->dec_temp,buf,rest);

		buf+=rest;

	}

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

//	printf("%d:%d ",buf-buf0,*data_size); fflush(stdout);

	return buf-buf0;

}


static void vmxnet3_process_tx_queue(VMXNET3State *s, int qidx)

{

    struct Vmxnet3_TxDesc txd;

    uint32_t txd_idx;

    uint32_t data_len;

    hwaddr data_pa;

    for (;;) {

        if (!vmxnet3_pop_next_tx_descr(s, qidx, &txd, &txd_idx)) {

            break;

        }

        vmxnet3_dump_tx_descr(&txd);

        if (!s->skip_current_tx_pkt) {

            data_len = (txd.len > 0) ? txd.len : VMXNET3_MAX_TX_BUF_SIZE;

            data_pa = le64_to_cpu(txd.addr);

            if (!net_tx_pkt_add_raw_fragment(s->tx_pkt,

                                                data_pa,

                                                data_len)) {

                s->skip_current_tx_pkt = true;

            }

        }

        if (s->tx_sop) {

            vmxnet3_tx_retrieve_metadata(s, &txd);

            s->tx_sop = false;

        }

        if (txd.eop) {

            if (!s->skip_current_tx_pkt && net_tx_pkt_parse(s->tx_pkt)) {

                if (s->needs_vlan) {

                    net_tx_pkt_setup_vlan_header(s->tx_pkt, s->tci);

                }

                vmxnet3_send_packet(s, qidx);

            } else {

                vmxnet3_on_tx_done_update_stats(s, qidx,

                                                VMXNET3_PKT_STATUS_ERROR);

            }

            vmxnet3_complete_packet(s, qidx, txd_idx);

            s->tx_sop = true;

            s->skip_current_tx_pkt = false;

            net_tx_pkt_reset(s->tx_pkt);

        }

    }

}


static void spatial_compose53i(IDWTELEM *buffer, int width, int height, int stride){

    dwt_compose_t cs;

    spatial_compose53i_init(&cs, buffer, height, stride);

    while(cs.y <= height)

        spatial_compose53i_dy(&cs, buffer, width, height, stride);

}


static void assert_codec_experimental(AVCodecContext *c, int encoder)

{

    const char *codec_string = encoder ? "encoder" : "decoder";

    AVCodec *codec;

    if (c->codec->capabilities & CODEC_CAP_EXPERIMENTAL &&

        c->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {

        av_log(NULL, AV_LOG_FATAL, "%s '%s' is experimental and might produce bad "

                "results.\nAdd '-strict experimental' if you want to use it.\n",

                codec_string, c->codec->name);

        codec = encoder ? avcodec_find_encoder(c->codec->id) : avcodec_find_decoder(c->codec->id);

        if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL))

            av_log(NULL, AV_LOG_FATAL, "Or use the non experimental %s '%s'.\n",

                   codec_string, codec->name);

        exit(1);

    }

}


static int vp3_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    Vp3DecodeContext *s = avctx->priv_data;

    GetBitContext gb;

    static int counter = 0;

    int i;

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

    if (s->theora && get_bits1(&gb))

    {

        av_log(avctx, AV_LOG_ERROR, "Header packet passed to frame decoder, skipping\n");

        return -1;

    }

    s->keyframe = !get_bits1(&gb);

    if (!s->theora)

        skip_bits(&gb, 1);

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

        s->last_qps[i] = s->qps[i];

    s->nqps=0;

    do{

        s->qps[s->nqps++]= get_bits(&gb, 6);

    } while(s->theora >= 0x030200 && s->nqps<3 && get_bits1(&gb));

    for (i = s->nqps; i < 3; i++)

        s->qps[i] = -1;

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

        av_log(s->avctx, AV_LOG_INFO, " VP3 %sframe #%d: Q index = %d\n",

            s->keyframe?"key":"", counter, s->qps[0]);

    counter++;

    if (s->qps[0] != s->last_qps[0])

        init_loop_filter(s);

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

        // reinit all dequantizers if the first one changed, because

        // the DC of the first quantizer must be used for all matrices

        if (s->qps[i] != s->last_qps[i] || s->qps[0] != s->last_qps[0])

            init_dequantizer(s, i);

    if (avctx->skip_frame >= AVDISCARD_NONKEY && !s->keyframe)

        return buf_size;

    if (s->keyframe) {

        if (!s->theora)

        {

            skip_bits(&gb, 4); /* width code */

            skip_bits(&gb, 4); /* height code */

            if (s->version)

            {

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

                if (counter == 1)

                    av_log(s->avctx, AV_LOG_DEBUG, "VP version: %d\n", s->version);

            }

        }

        if (s->version || s->theora)

        {

                if (get_bits1(&gb))

                    av_log(s->avctx, AV_LOG_ERROR, "Warning, unsupported keyframe coding type?!\n");

            skip_bits(&gb, 2); /* reserved? */

        }

        if (s->last_frame.data[0] == s->golden_frame.data[0]) {

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

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

            s->last_frame= s->golden_frame; /* ensure that we catch any access to this released frame */

        } else {

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

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

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

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

        }

        s->golden_frame.reference = 3;

        if(avctx->get_buffer(avctx, &s->golden_frame) < 0) {

            av_log(s->avctx, AV_LOG_ERROR, "vp3: get_buffer() failed\n");

            return -1;

        }

        /* golden frame is also the current frame */

        s->current_frame= s->golden_frame;

        /* time to figure out pixel addresses? */

        if (!s->pixel_addresses_initialized)

        {

            vp3_calculate_pixel_addresses(s);

            s->pixel_addresses_initialized = 1;

        }

    } else {

        /* allocate a new current frame */

        s->current_frame.reference = 3;

        if (!s->pixel_addresses_initialized) {

            av_log(s->avctx, AV_LOG_ERROR, "vp3: first frame not a keyframe\n");

            return -1;

        }

        if(avctx->get_buffer(avctx, &s->current_frame) < 0) {

            av_log(s->avctx, AV_LOG_ERROR, "vp3: get_buffer() failed\n");

            return -1;

        }

    }

    s->current_frame.qscale_table= s->qscale_table; //FIXME allocate individual tables per AVFrame

    s->current_frame.qstride= 0;

    init_frame(s, &gb);

    if (unpack_superblocks(s, &gb)){

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_superblocks\n");

        return -1;

    }

    if (unpack_modes(s, &gb)){

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_modes\n");

        return -1;

    }

    if (unpack_vectors(s, &gb)){

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_vectors\n");

        return -1;

    }

    if (unpack_block_qpis(s, &gb)){

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_block_qpis\n");

        return -1;

    }

    if (unpack_dct_coeffs(s, &gb)){

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_dct_coeffs\n");

        return -1;

    }

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

        render_slice(s, i);

    apply_loop_filter(s);

    *data_size=sizeof(AVFrame);

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

    /* release the last frame, if it is allocated and if it is not the

     * golden frame */

    if ((s->last_frame.data[0]) &&

        (s->last_frame.data[0] != s->golden_frame.data[0]))

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

    /* shuffle frames (last = current) */

    s->last_frame= s->current_frame;

    s->current_frame.data[0]= NULL; /* ensure that we catch any access to this released frame */

    return buf_size;

}


static av_cold int pnm_encode_close(AVCodecContext *avctx)

{

    av_frame_free(&avctx->coded_frame);

    return 0;

}


void ff_vc1dsp_init(DSPContext* dsp, AVCodecContext *avctx) {

    dsp->vc1_inv_trans_8x8 = vc1_inv_trans_8x8_c;

    dsp->vc1_inv_trans_4x8 = vc1_inv_trans_4x8_c;

    dsp->vc1_inv_trans_8x4 = vc1_inv_trans_8x4_c;

    dsp->vc1_inv_trans_4x4 = vc1_inv_trans_4x4_c;

    dsp->vc1_h_overlap = vc1_h_overlap_c;

    dsp->vc1_v_overlap = vc1_v_overlap_c;

    dsp->vc1_loop_filter = vc1_loop_filter;

    dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_c;

    dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_c;

    dsp->put_vc1_mspel_pixels_tab[ 2] = put_vc1_mspel_mc20_c;

    dsp->put_vc1_mspel_pixels_tab[ 3] = put_vc1_mspel_mc30_c;

    dsp->put_vc1_mspel_pixels_tab[ 4] = put_vc1_mspel_mc01_c;

    dsp->put_vc1_mspel_pixels_tab[ 5] = put_vc1_mspel_mc11_c;

    dsp->put_vc1_mspel_pixels_tab[ 6] = put_vc1_mspel_mc21_c;

    dsp->put_vc1_mspel_pixels_tab[ 7] = put_vc1_mspel_mc31_c;

    dsp->put_vc1_mspel_pixels_tab[ 8] = put_vc1_mspel_mc02_c;

    dsp->put_vc1_mspel_pixels_tab[ 9] = put_vc1_mspel_mc12_c;

    dsp->put_vc1_mspel_pixels_tab[10] = put_vc1_mspel_mc22_c;

    dsp->put_vc1_mspel_pixels_tab[11] = put_vc1_mspel_mc32_c;

    dsp->put_vc1_mspel_pixels_tab[12] = put_vc1_mspel_mc03_c;

    dsp->put_vc1_mspel_pixels_tab[13] = put_vc1_mspel_mc13_c;

    dsp->put_vc1_mspel_pixels_tab[14] = put_vc1_mspel_mc23_c;

    dsp->put_vc1_mspel_pixels_tab[15] = put_vc1_mspel_mc33_c;

    dsp->avg_vc1_mspel_pixels_tab[ 0] = ff_avg_vc1_mspel_mc00_c;

    dsp->avg_vc1_mspel_pixels_tab[ 1] = avg_vc1_mspel_mc10_c;

    dsp->avg_vc1_mspel_pixels_tab[ 2] = avg_vc1_mspel_mc20_c;

    dsp->avg_vc1_mspel_pixels_tab[ 3] = avg_vc1_mspel_mc30_c;

    dsp->avg_vc1_mspel_pixels_tab[ 4] = avg_vc1_mspel_mc01_c;

    dsp->avg_vc1_mspel_pixels_tab[ 5] = avg_vc1_mspel_mc11_c;

    dsp->avg_vc1_mspel_pixels_tab[ 6] = avg_vc1_mspel_mc21_c;

    dsp->avg_vc1_mspel_pixels_tab[ 7] = avg_vc1_mspel_mc31_c;

    dsp->avg_vc1_mspel_pixels_tab[ 8] = avg_vc1_mspel_mc02_c;

    dsp->avg_vc1_mspel_pixels_tab[ 9] = avg_vc1_mspel_mc12_c;

    dsp->avg_vc1_mspel_pixels_tab[10] = avg_vc1_mspel_mc22_c;

    dsp->avg_vc1_mspel_pixels_tab[11] = avg_vc1_mspel_mc32_c;

    dsp->avg_vc1_mspel_pixels_tab[12] = avg_vc1_mspel_mc03_c;

    dsp->avg_vc1_mspel_pixels_tab[13] = avg_vc1_mspel_mc13_c;

    dsp->avg_vc1_mspel_pixels_tab[14] = avg_vc1_mspel_mc23_c;

    dsp->avg_vc1_mspel_pixels_tab[15] = avg_vc1_mspel_mc33_c;

}


static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,

    unsigned size)

{

    switch (offset) {

    case 0xc:

        n->bar.intms |= data & 0xffffffff;

        n->bar.intmc = n->bar.intms;

        break;

    case 0x10:

        n->bar.intms &= ~(data & 0xffffffff);

        n->bar.intmc = n->bar.intms;

        break;

    case 0x14:

        /* Windows first sends data, then sends enable bit */

        if (!NVME_CC_EN(data) && !NVME_CC_EN(n->bar.cc) &&

            !NVME_CC_SHN(data) && !NVME_CC_SHN(n->bar.cc))

        {

            n->bar.cc = data;

        }

        if (NVME_CC_EN(data) && !NVME_CC_EN(n->bar.cc)) {

            n->bar.cc = data;

            if (nvme_start_ctrl(n)) {

                n->bar.csts = NVME_CSTS_FAILED;

            } else {

                n->bar.csts = NVME_CSTS_READY;

            }

        } else if (!NVME_CC_EN(data) && NVME_CC_EN(n->bar.cc)) {

            nvme_clear_ctrl(n);

            n->bar.csts &= ~NVME_CSTS_READY;

        }

        if (NVME_CC_SHN(data) && !(NVME_CC_SHN(n->bar.cc))) {

                nvme_clear_ctrl(n);

                n->bar.cc = data;

                n->bar.csts |= NVME_CSTS_SHST_COMPLETE;

        } else if (!NVME_CC_SHN(data) && NVME_CC_SHN(n->bar.cc)) {

                n->bar.csts &= ~NVME_CSTS_SHST_COMPLETE;

                n->bar.cc = data;

        }

        break;

    case 0x24:

        n->bar.aqa = data & 0xffffffff;

        break;

    case 0x28:

        n->bar.asq = data;

        break;

    case 0x2c:

        n->bar.asq |= data << 32;

        break;

    case 0x30:

        n->bar.acq = data;

        break;

    case 0x34:

        n->bar.acq |= data << 32;

        break;

    default:

        break;

    }

}


static void gen_wrtee(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    TCGv t0;

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    t0 = tcg_temp_new();

    tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));

    tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));

    tcg_gen_or_tl(cpu_msr, cpu_msr, t0);

    tcg_temp_free(t0);

    /* Stop translation to have a chance to raise an exception

     * if we just set msr_ee to 1

     */

    gen_stop_exception(ctx);

#endif

}