/*
 *  ARM translation: M-profile MVE instructions
 *
 *  Copyright (c) 2021 Linaro, Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "tcg/tcg-op.h"
#include "tcg/tcg-op-gvec.h"
#include "exec/exec-all.h"
#include "exec/gen-icount.h"
#include "translate.h"
#include "translate-a32.h"

static inline int vidup_imm(DisasContext *s, int x)
{
    return 1 << x;
}

/* Include the generated decoder */
#include "decode-mve.c.inc"

typedef void MVEGenLdStFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
typedef void MVEGenLdStSGFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
typedef void MVEGenLdStIlFn(TCGv_ptr, TCGv_i32, TCGv_i32);
typedef void MVEGenOneOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
typedef void MVEGenTwoOpShiftFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
typedef void MVEGenLongDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
typedef void MVEGenVIDUPFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32, TCGv_i32);
typedef void MVEGenVIWDUPFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32, TCGv_i32, TCGv_i32);
typedef void MVEGenCmpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
typedef void MVEGenScalarCmpFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
typedef void MVEGenVABAVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
typedef void MVEGenDualAccOpFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
typedef void MVEGenVCVTRmodeFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);

/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
static inline long mve_qreg_offset(unsigned reg)
{
    return offsetof(CPUARMState, vfp.zregs[reg].d[0]);
}

static TCGv_ptr mve_qreg_ptr(unsigned reg)
{
    TCGv_ptr ret = tcg_temp_new_ptr();
    tcg_gen_addi_ptr(ret, cpu_env, mve_qreg_offset(reg));
    return ret;
}

static bool mve_no_predication(DisasContext *s)
{
    /*
     * Return true if we are executing the entire MVE instruction
     * with no predication or partial-execution, and so we can safely
     * use an inline TCG vector implementation.
     */
    return s->eci == 0 && s->mve_no_pred;
}

static bool mve_check_qreg_bank(DisasContext *s, int qmask)
{
    /*
     * Check whether Qregs are in range. For v8.1M only Q0..Q7
     * are supported, see VFPSmallRegisterBank().
     */
    return qmask < 8;
}

bool mve_eci_check(DisasContext *s)
{
    /*
     * This is a beatwise insn: check that ECI is valid (not a
     * reserved value) and note that we are handling it.
     * Return true if OK, false if we generated an exception.
     */
    s->eci_handled = true;
    switch (s->eci) {
    case ECI_NONE:
    case ECI_A0:
    case ECI_A0A1:
    case ECI_A0A1A2:
    case ECI_A0A1A2B0:
        return true;
    default:
        /* Reserved value: INVSTATE UsageFault */
        gen_exception_insn(s, 0, EXCP_INVSTATE, syn_uncategorized());
        return false;
    }
}

void mve_update_eci(DisasContext *s)
{
    /*
     * The helper function will always update the CPUState field,
     * so we only need to update the DisasContext field.
     */
    if (s->eci) {
        s->eci = (s->eci == ECI_A0A1A2B0) ? ECI_A0 : ECI_NONE;
    }
}

void mve_update_and_store_eci(DisasContext *s)
{
    /*
     * For insns which don't call a helper function that will call
     * mve_advance_vpt(), this version updates s->eci and also stores
     * it out to the CPUState field.
     */
    if (s->eci) {
        mve_update_eci(s);
        store_cpu_field(tcg_constant_i32(s->eci << 4), condexec_bits);
    }
}

static bool mve_skip_first_beat(DisasContext *s)
{
    /* Return true if PSR.ECI says we must skip the first beat of this insn */
    switch (s->eci) {
    case ECI_NONE:
        return false;
    case ECI_A0:
    case ECI_A0A1:
    case ECI_A0A1A2:
    case ECI_A0A1A2B0:
        return true;
    default:
        g_assert_not_reached();
    }
}

static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
                    unsigned msize)
{
    TCGv_i32 addr;
    uint32_t offset;
    TCGv_ptr qreg;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qd) ||
        !fn) {
        return false;
    }

    /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
    if (a->rn == 15 || (a->rn == 13 && a->w)) {
        return false;
    }

    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    offset = a->imm << msize;
    if (!a->a) {
        offset = -offset;
    }
    addr = load_reg(s, a->rn);
    if (a->p) {
        tcg_gen_addi_i32(addr, addr, offset);
    }

    qreg = mve_qreg_ptr(a->qd);
    fn(cpu_env, qreg, addr);

    /*
     * Writeback always happens after the last beat of the insn,
     * regardless of predication
     */
    if (a->w) {
        if (!a->p) {
            tcg_gen_addi_i32(addr, addr, offset);
        }
        store_reg(s, a->rn, addr);
    }
    mve_update_eci(s);
    return true;
}

static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
{
    static MVEGenLdStFn * const ldstfns[4][2] = {
        { gen_helper_mve_vstrb, gen_helper_mve_vldrb },
        { gen_helper_mve_vstrh, gen_helper_mve_vldrh },
        { gen_helper_mve_vstrw, gen_helper_mve_vldrw },
        { NULL, NULL }
    };
    return do_ldst(s, a, ldstfns[a->size][a->l], a->size);
}

#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE)           \
    static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a)   \
    {                                                           \
        static MVEGenLdStFn * const ldstfns[2][2] = {           \
            { gen_helper_mve_##ST, gen_helper_mve_##SLD },      \
            { NULL, gen_helper_mve_##ULD },                     \
        };                                                      \
        return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE);       \
    }

DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)

static bool do_ldst_sg(DisasContext *s, arg_vldst_sg *a, MVEGenLdStSGFn fn)
{
    TCGv_i32 addr;
    TCGv_ptr qd, qm;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qd | a->qm) ||
        !fn || a->rn == 15) {
        /* Rn case is UNPREDICTABLE */
        return false;
    }

    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    addr = load_reg(s, a->rn);

    qd = mve_qreg_ptr(a->qd);
    qm = mve_qreg_ptr(a->qm);
    fn(cpu_env, qd, qm, addr);
    mve_update_eci(s);
    return true;
}

/*
 * The naming scheme here is "vldrb_sg_sh == in-memory byte loads
 * signextended to halfword elements in register". _os_ indicates that
 * the offsets in Qm should be scaled by the element size.
 */
/* This macro is just to make the arrays more compact in these functions */
#define F(N) gen_helper_mve_##N

/* VLDRB/VSTRB (ie msize 1) with OS=1 is UNPREDICTABLE; we UNDEF */
static bool trans_VLDR_S_sg(DisasContext *s, arg_vldst_sg *a)
{
    static MVEGenLdStSGFn * const fns[2][4][4] = { {
            { NULL, F(vldrb_sg_sh), F(vldrb_sg_sw), NULL },
            { NULL, NULL,           F(vldrh_sg_sw), NULL },
            { NULL, NULL,           NULL,           NULL },
            { NULL, NULL,           NULL,           NULL }
        }, {
            { NULL, NULL,              NULL,              NULL },
            { NULL, NULL,              F(vldrh_sg_os_sw), NULL },
            { NULL, NULL,              NULL,              NULL },
            { NULL, NULL,              NULL,              NULL }
        }
    };
    if (a->qd == a->qm) {
        return false; /* UNPREDICTABLE */
    }
    return do_ldst_sg(s, a, fns[a->os][a->msize][a->size]);
}

static bool trans_VLDR_U_sg(DisasContext *s, arg_vldst_sg *a)
{
    static MVEGenLdStSGFn * const fns[2][4][4] = { {
            { F(vldrb_sg_ub), F(vldrb_sg_uh), F(vldrb_sg_uw), NULL },
            { NULL,           F(vldrh_sg_uh), F(vldrh_sg_uw), NULL },
            { NULL,           NULL,           F(vldrw_sg_uw), NULL },
            { NULL,           NULL,           NULL,           F(vldrd_sg_ud) }
        }, {
            { NULL, NULL,              NULL,              NULL },
            { NULL, F(vldrh_sg_os_uh), F(vldrh_sg_os_uw), NULL },
            { NULL, NULL,              F(vldrw_sg_os_uw), NULL },
            { NULL, NULL,              NULL,              F(vldrd_sg_os_ud) }
        }
    };
    if (a->qd == a->qm) {
        return false; /* UNPREDICTABLE */
    }
    return do_ldst_sg(s, a, fns[a->os][a->msize][a->size]);
}

static bool trans_VSTR_sg(DisasContext *s, arg_vldst_sg *a)
{
    static MVEGenLdStSGFn * const fns[2][4][4] = { {
            { F(vstrb_sg_ub), F(vstrb_sg_uh), F(vstrb_sg_uw), NULL },
            { NULL,           F(vstrh_sg_uh), F(vstrh_sg_uw), NULL },
            { NULL,           NULL,           F(vstrw_sg_uw), NULL },
            { NULL,           NULL,           NULL,           F(vstrd_sg_ud) }
        }, {
            { NULL, NULL,              NULL,              NULL },
            { NULL, F(vstrh_sg_os_uh), F(vstrh_sg_os_uw), NULL },
            { NULL, NULL,              F(vstrw_sg_os_uw), NULL },
            { NULL, NULL,              NULL,              F(vstrd_sg_os_ud) }
        }
    };
    return do_ldst_sg(s, a, fns[a->os][a->msize][a->size]);
}

#undef F

static bool do_ldst_sg_imm(DisasContext *s, arg_vldst_sg_imm *a,
                           MVEGenLdStSGFn *fn, unsigned msize)
{
    uint32_t offset;
    TCGv_ptr qd, qm;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qd | a->qm) ||
        !fn) {
        return false;
    }

    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    offset = a->imm << msize;
    if (!a->a) {
        offset = -offset;
    }

    qd = mve_qreg_ptr(a->qd);
    qm = mve_qreg_ptr(a->qm);
    fn(cpu_env, qd, qm, tcg_constant_i32(offset));
    mve_update_eci(s);
    return true;
}

static bool trans_VLDRW_sg_imm(DisasContext *s, arg_vldst_sg_imm *a)
{
    static MVEGenLdStSGFn * const fns[] = {
        gen_helper_mve_vldrw_sg_uw,
        gen_helper_mve_vldrw_sg_wb_uw,
    };
    if (a->qd == a->qm) {
        return false; /* UNPREDICTABLE */
    }
    return do_ldst_sg_imm(s, a, fns[a->w], MO_32);
}

static bool trans_VLDRD_sg_imm(DisasContext *s, arg_vldst_sg_imm *a)
{
    static MVEGenLdStSGFn * const fns[] = {
        gen_helper_mve_vldrd_sg_ud,
        gen_helper_mve_vldrd_sg_wb_ud,
    };
    if (a->qd == a->qm) {
        return false; /* UNPREDICTABLE */
    }
    return do_ldst_sg_imm(s, a, fns[a->w], MO_64);
}

static bool trans_VSTRW_sg_imm(DisasContext *s, arg_vldst_sg_imm *a)
{
    static MVEGenLdStSGFn * const fns[] = {
        gen_helper_mve_vstrw_sg_uw,
        gen_helper_mve_vstrw_sg_wb_uw,
    };
    return do_ldst_sg_imm(s, a, fns[a->w], MO_32);
}

static bool trans_VSTRD_sg_imm(DisasContext *s, arg_vldst_sg_imm *a)
{
    static MVEGenLdStSGFn * const fns[] = {
        gen_helper_mve_vstrd_sg_ud,
        gen_helper_mve_vstrd_sg_wb_ud,
    };
    return do_ldst_sg_imm(s, a, fns[a->w], MO_64);
}

static bool do_vldst_il(DisasContext *s, arg_vldst_il *a, MVEGenLdStIlFn *fn,
                        int addrinc)
{
    TCGv_i32 rn;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qd) ||
        !fn || (a->rn == 13 && a->w) || a->rn == 15) {
        /* Variously UNPREDICTABLE or UNDEF or related-encoding */
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    rn = load_reg(s, a->rn);
    /*
     * We pass the index of Qd, not a pointer, because the helper must
     * access multiple Q registers starting at Qd and working up.
     */
    fn(cpu_env, tcg_constant_i32(a->qd), rn);

    if (a->w) {
        tcg_gen_addi_i32(rn, rn, addrinc);
        store_reg(s, a->rn, rn);
    }
    mve_update_and_store_eci(s);
    return true;
}

/* This macro is just to make the arrays more compact in these functions */
#define F(N) gen_helper_mve_##N

static bool trans_VLD2(DisasContext *s, arg_vldst_il *a)
{
    static MVEGenLdStIlFn * const fns[4][4] = {
        { F(vld20b), F(vld20h), F(vld20w), NULL, },
        { F(vld21b), F(vld21h), F(vld21w), NULL, },
        { NULL, NULL, NULL, NULL },
        { NULL, NULL, NULL, NULL },
    };
    if (a->qd > 6) {
        return false;
    }
    return do_vldst_il(s, a, fns[a->pat][a->size], 32);
}

static bool trans_VLD4(DisasContext *s, arg_vldst_il *a)
{
    static MVEGenLdStIlFn * const fns[4][4] = {
        { F(vld40b), F(vld40h), F(vld40w), NULL, },
        { F(vld41b), F(vld41h), F(vld41w), NULL, },
        { F(vld42b), F(vld42h), F(vld42w), NULL, },
        { F(vld43b), F(vld43h), F(vld43w), NULL, },
    };
    if (a->qd > 4) {
        return false;
    }
    return do_vldst_il(s, a, fns[a->pat][a->size], 64);
}

static bool trans_VST2(DisasContext *s, arg_vldst_il *a)
{
    static MVEGenLdStIlFn * const fns[4][4] = {
        { F(vst20b), F(vst20h), F(vst20w), NULL, },
        { F(vst21b), F(vst21h), F(vst21w), NULL, },
        { NULL, NULL, NULL, NULL },
        { NULL, NULL, NULL, NULL },
    };
    if (a->qd > 6) {
        return false;
    }
    return do_vldst_il(s, a, fns[a->pat][a->size], 32);
}

static bool trans_VST4(DisasContext *s, arg_vldst_il *a)
{
    static MVEGenLdStIlFn * const fns[4][4] = {
        { F(vst40b), F(vst40h), F(vst40w), NULL, },
        { F(vst41b), F(vst41h), F(vst41w), NULL, },
        { F(vst42b), F(vst42h), F(vst42w), NULL, },
        { F(vst43b), F(vst43h), F(vst43w), NULL, },
    };
    if (a->qd > 4) {
        return false;
    }
    return do_vldst_il(s, a, fns[a->pat][a->size], 64);
}

#undef F

static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
{
    TCGv_ptr qd;
    TCGv_i32 rt;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qd)) {
        return false;
    }
    if (a->rt == 13 || a->rt == 15) {
        /* UNPREDICTABLE; we choose to UNDEF */
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    rt = load_reg(s, a->rt);
    if (mve_no_predication(s)) {
        tcg_gen_gvec_dup_i32(a->size, mve_qreg_offset(a->qd), 16, 16, rt);
    } else {
        qd = mve_qreg_ptr(a->qd);
        tcg_gen_dup_i32(a->size, rt, rt);
        gen_helper_mve_vdup(cpu_env, qd, rt);
    }
    mve_update_eci(s);
    return true;
}

static bool do_1op_vec(DisasContext *s, arg_1op *a, MVEGenOneOpFn fn,
                       GVecGen2Fn vecfn)
{
    TCGv_ptr qd, qm;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qd | a->qm) ||
        !fn) {
        return false;
    }

    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    if (vecfn && mve_no_predication(s)) {
        vecfn(a->size, mve_qreg_offset(a->qd), mve_qreg_offset(a->qm), 16, 16);
    } else {
        qd = mve_qreg_ptr(a->qd);
        qm = mve_qreg_ptr(a->qm);
        fn(cpu_env, qd, qm);
    }
    mve_update_eci(s);
    return true;
}

static bool do_1op(DisasContext *s, arg_1op *a, MVEGenOneOpFn fn)
{
    return do_1op_vec(s, a, fn, NULL);
}

#define DO_1OP_VEC(INSN, FN, VECFN)                             \
    static bool trans_##INSN(DisasContext *s, arg_1op *a)       \
    {                                                           \
        static MVEGenOneOpFn * const fns[] = {                  \
            gen_helper_mve_##FN##b,                             \
            gen_helper_mve_##FN##h,                             \
            gen_helper_mve_##FN##w,                             \
            NULL,                                               \
        };                                                      \
        return do_1op_vec(s, a, fns[a->size], VECFN);           \
    }

#define DO_1OP(INSN, FN) DO_1OP_VEC(INSN, FN, NULL)

DO_1OP(VCLZ, vclz)
DO_1OP(VCLS, vcls)
DO_1OP_VEC(VABS, vabs, tcg_gen_gvec_abs)
DO_1OP_VEC(VNEG, vneg, tcg_gen_gvec_neg)
DO_1OP(VQABS, vqabs)
DO_1OP(VQNEG, vqneg)
DO_1OP(VMAXA, vmaxa)
DO_1OP(VMINA, vmina)

/*
 * For simple float/int conversions we use the fixed-point
 * conversion helpers with a zero shift count
 */
#define DO_VCVT(INSN, HFN, SFN)                                         \
    static void gen_##INSN##h(TCGv_ptr env, TCGv_ptr qd, TCGv_ptr qm)   \
    {                                                                   \
        gen_helper_mve_##HFN(env, qd, qm, tcg_constant_i32(0));         \
    }                                                                   \
    static void gen_##INSN##s(TCGv_ptr env, TCGv_ptr qd, TCGv_ptr qm)   \
    {                                                                   \
        gen_helper_mve_##SFN(env, qd, qm, tcg_constant_i32(0));         \
    }                                                                   \
    static bool trans_##INSN(DisasContext *s, arg_1op *a)               \
    {                                                                   \
        static MVEGenOneOpFn * const fns[] = {                          \
            NULL,                                                       \
            gen_##INSN##h,                                              \
            gen_##INSN##s,                                              \
            NULL,                                                       \
        };                                                              \
        if (!dc_isar_feature(aa32_mve_fp, s)) {                         \
            return false;                                               \
        }                                                               \
        return do_1op(s, a, fns[a->size]);                              \
    }

DO_VCVT(VCVT_SF, vcvt_sh, vcvt_sf)
DO_VCVT(VCVT_UF, vcvt_uh, vcvt_uf)
DO_VCVT(VCVT_FS, vcvt_hs, vcvt_fs)
DO_VCVT(VCVT_FU, vcvt_hu, vcvt_fu)

static bool do_vcvt_rmode(DisasContext *s, arg_1op *a,
                          enum arm_fprounding rmode, bool u)
{
    /*
     * Handle VCVT fp to int with specified rounding mode.
     * This is a 1op fn but we must pass the rounding mode as
     * an immediate to the helper.
     */
    TCGv_ptr qd, qm;
    static MVEGenVCVTRmodeFn * const fns[4][2] = {
        { NULL, NULL },
        { gen_helper_mve_vcvt_rm_sh, gen_helper_mve_vcvt_rm_uh },
        { gen_helper_mve_vcvt_rm_ss, gen_helper_mve_vcvt_rm_us },
        { NULL, NULL },
    };
    MVEGenVCVTRmodeFn *fn = fns[a->size][u];

    if (!dc_isar_feature(aa32_mve_fp, s) ||
        !mve_check_qreg_bank(s, a->qd | a->qm) ||
        !fn) {
        return false;
    }

    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    qd = mve_qreg_ptr(a->qd);
    qm = mve_qreg_ptr(a->qm);
    fn(cpu_env, qd, qm, tcg_constant_i32(arm_rmode_to_sf(rmode)));
    mve_update_eci(s);
    return true;
}

#define DO_VCVT_RMODE(INSN, RMODE, U)                           \
    static bool trans_##INSN(DisasContext *s, arg_1op *a)       \
    {                                                           \
        return do_vcvt_rmode(s, a, RMODE, U);                   \
    }                                                           \

DO_VCVT_RMODE(VCVTAS, FPROUNDING_TIEAWAY, false)
DO_VCVT_RMODE(VCVTAU, FPROUNDING_TIEAWAY, true)
DO_VCVT_RMODE(VCVTNS, FPROUNDING_TIEEVEN, false)
DO_VCVT_RMODE(VCVTNU, FPROUNDING_TIEEVEN, true)
DO_VCVT_RMODE(VCVTPS, FPROUNDING_POSINF, false)
DO_VCVT_RMODE(VCVTPU, FPROUNDING_POSINF, true)
DO_VCVT_RMODE(VCVTMS, FPROUNDING_NEGINF, false)
DO_VCVT_RMODE(VCVTMU, FPROUNDING_NEGINF, true)

#define DO_VCVT_SH(INSN, FN)                                    \
    static bool trans_##INSN(DisasContext *s, arg_1op *a)       \
    {                                                           \
        if (!dc_isar_feature(aa32_mve_fp, s)) {                 \
            return false;                                       \
        }                                                       \
        return do_1op(s, a, gen_helper_mve_##FN);               \
    }                                                           \

DO_VCVT_SH(VCVTB_SH, vcvtb_sh)
DO_VCVT_SH(VCVTT_SH, vcvtt_sh)
DO_VCVT_SH(VCVTB_HS, vcvtb_hs)
DO_VCVT_SH(VCVTT_HS, vcvtt_hs)

#define DO_VRINT(INSN, RMODE)                                           \
    static void gen_##INSN##h(TCGv_ptr env, TCGv_ptr qd, TCGv_ptr qm)   \
    {                                                                   \
        gen_helper_mve_vrint_rm_h(env, qd, qm,                          \
                                  tcg_constant_i32(arm_rmode_to_sf(RMODE))); \
    }                                                                   \
    static void gen_##INSN##s(TCGv_ptr env, TCGv_ptr qd, TCGv_ptr qm)   \
    {                                                                   \
        gen_helper_mve_vrint_rm_s(env, qd, qm,                          \
                                  tcg_constant_i32(arm_rmode_to_sf(RMODE))); \
    }                                                                   \
    static bool trans_##INSN(DisasContext *s, arg_1op *a)               \
    {                                                                   \
        static MVEGenOneOpFn * const fns[] = {                          \
            NULL,                                                       \
            gen_##INSN##h,                                              \
            gen_##INSN##s,                                              \
            NULL,                                                       \
        };                                                              \
        if (!dc_isar_feature(aa32_mve_fp, s)) {                         \
            return false;                                               \
        }                                                               \
        return do_1op(s, a, fns[a->size]);                              \
    }

DO_VRINT(VRINTN, FPROUNDING_TIEEVEN)
DO_VRINT(VRINTA, FPROUNDING_TIEAWAY)
DO_VRINT(VRINTZ, FPROUNDING_ZERO)
DO_VRINT(VRINTM, FPROUNDING_NEGINF)
DO_VRINT(VRINTP, FPROUNDING_POSINF)

static bool trans_VRINTX(DisasContext *s, arg_1op *a)
{
    static MVEGenOneOpFn * const fns[] = {
        NULL,
        gen_helper_mve_vrintx_h,
        gen_helper_mve_vrintx_s,
        NULL,
    };
    if (!dc_isar_feature(aa32_mve_fp, s)) {
        return false;
    }
    return do_1op(s, a, fns[a->size]);
}

/* Narrowing moves: only size 0 and 1 are valid */
#define DO_VMOVN(INSN, FN) \
    static bool trans_##INSN(DisasContext *s, arg_1op *a)       \
    {                                                           \
        static MVEGenOneOpFn * const fns[] = {                  \
            gen_helper_mve_##FN##b,                             \
            gen_helper_mve_##FN##h,                             \
            NULL,                                               \
            NULL,                                               \
        };                                                      \
        return do_1op(s, a, fns[a->size]);                      \
    }

DO_VMOVN(VMOVNB, vmovnb)
DO_VMOVN(VMOVNT, vmovnt)
DO_VMOVN(VQMOVUNB, vqmovunb)
DO_VMOVN(VQMOVUNT, vqmovunt)
DO_VMOVN(VQMOVN_BS, vqmovnbs)
DO_VMOVN(VQMOVN_TS, vqmovnts)
DO_VMOVN(VQMOVN_BU, vqmovnbu)
DO_VMOVN(VQMOVN_TU, vqmovntu)

static bool trans_VREV16(DisasContext *s, arg_1op *a)
{
    static MVEGenOneOpFn * const fns[] = {
        gen_helper_mve_vrev16b,
        NULL,
        NULL,
        NULL,
    };
    return do_1op(s, a, fns[a->size]);
}

static bool trans_VREV32(DisasContext *s, arg_1op *a)
{
    static MVEGenOneOpFn * const fns[] = {
        gen_helper_mve_vrev32b,
        gen_helper_mve_vrev32h,
        NULL,
        NULL,
    };
    return do_1op(s, a, fns[a->size]);
}

static bool trans_VREV64(DisasContext *s, arg_1op *a)
{
    static MVEGenOneOpFn * const fns[] = {
        gen_helper_mve_vrev64b,
        gen_helper_mve_vrev64h,
        gen_helper_mve_vrev64w,
        NULL,
    };
    return do_1op(s, a, fns[a->size]);
}

static bool trans_VMVN(DisasContext *s, arg_1op *a)
{
    return do_1op_vec(s, a, gen_helper_mve_vmvn, tcg_gen_gvec_not);
}

static bool trans_VABS_fp(DisasContext *s, arg_1op *a)
{
    static MVEGenOneOpFn * const fns[] = {
        NULL,
        gen_helper_mve_vfabsh,
        gen_helper_mve_vfabss,
        NULL,
    };
    if (!dc_isar_feature(aa32_mve_fp, s)) {
        return false;
    }
    return do_1op(s, a, fns[a->size]);
}

static bool trans_VNEG_fp(DisasContext *s, arg_1op *a)
{
    static MVEGenOneOpFn * const fns[] = {
        NULL,
        gen_helper_mve_vfnegh,
        gen_helper_mve_vfnegs,
        NULL,
    };
    if (!dc_isar_feature(aa32_mve_fp, s)) {
        return false;
    }
    return do_1op(s, a, fns[a->size]);
}

static bool do_2op_vec(DisasContext *s, arg_2op *a, MVEGenTwoOpFn fn,
                       GVecGen3Fn *vecfn)
{
    TCGv_ptr qd, qn, qm;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qd | a->qn | a->qm) ||
        !fn) {
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    if (vecfn && mve_no_predication(s)) {
        vecfn(a->size, mve_qreg_offset(a->qd), mve_qreg_offset(a->qn),
              mve_qreg_offset(a->qm), 16, 16);
    } else {
        qd = mve_qreg_ptr(a->qd);
        qn = mve_qreg_ptr(a->qn);
        qm = mve_qreg_ptr(a->qm);
        fn(cpu_env, qd, qn, qm);
    }
    mve_update_eci(s);
    return true;
}

static bool do_2op(DisasContext *s, arg_2op *a, MVEGenTwoOpFn *fn)
{
    return do_2op_vec(s, a, fn, NULL);
}

#define DO_LOGIC(INSN, HELPER, VECFN)                           \
    static bool trans_##INSN(DisasContext *s, arg_2op *a)       \
    {                                                           \
        return do_2op_vec(s, a, HELPER, VECFN);                 \
    }

DO_LOGIC(VAND, gen_helper_mve_vand, tcg_gen_gvec_and)
DO_LOGIC(VBIC, gen_helper_mve_vbic, tcg_gen_gvec_andc)
DO_LOGIC(VORR, gen_helper_mve_vorr, tcg_gen_gvec_or)
DO_LOGIC(VORN, gen_helper_mve_vorn, tcg_gen_gvec_orc)
DO_LOGIC(VEOR, gen_helper_mve_veor, tcg_gen_gvec_xor)

static bool trans_VPSEL(DisasContext *s, arg_2op *a)
{
    /* This insn updates predication bits */
    s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
    return do_2op(s, a, gen_helper_mve_vpsel);
}

#define DO_2OP_VEC(INSN, FN, VECFN)                             \
    static bool trans_##INSN(DisasContext *s, arg_2op *a)       \
    {                                                           \
        static MVEGenTwoOpFn * const fns[] = {                  \
            gen_helper_mve_##FN##b,                             \
            gen_helper_mve_##FN##h,                             \
            gen_helper_mve_##FN##w,                             \
            NULL,                                               \
        };                                                      \
        return do_2op_vec(s, a, fns[a->size], VECFN);           \
    }

#define DO_2OP(INSN, FN) DO_2OP_VEC(INSN, FN, NULL)

DO_2OP_VEC(VADD, vadd, tcg_gen_gvec_add)
DO_2OP_VEC(VSUB, vsub, tcg_gen_gvec_sub)
DO_2OP_VEC(VMUL, vmul, tcg_gen_gvec_mul)
DO_2OP(VMULH_S, vmulhs)
DO_2OP(VMULH_U, vmulhu)
DO_2OP(VRMULH_S, vrmulhs)
DO_2OP(VRMULH_U, vrmulhu)
DO_2OP_VEC(VMAX_S, vmaxs, tcg_gen_gvec_smax)
DO_2OP_VEC(VMAX_U, vmaxu, tcg_gen_gvec_umax)
DO_2OP_VEC(VMIN_S, vmins, tcg_gen_gvec_smin)
DO_2OP_VEC(VMIN_U, vminu, tcg_gen_gvec_umin)
DO_2OP(VABD_S, vabds)
DO_2OP(VABD_U, vabdu)
DO_2OP(VHADD_S, vhadds)
DO_2OP(VHADD_U, vhaddu)
DO_2OP(VHSUB_S, vhsubs)
DO_2OP(VHSUB_U, vhsubu)
DO_2OP(VMULL_BS, vmullbs)
DO_2OP(VMULL_BU, vmullbu)
DO_2OP(VMULL_TS, vmullts)
DO_2OP(VMULL_TU, vmulltu)
DO_2OP(VQDMULH, vqdmulh)
DO_2OP(VQRDMULH, vqrdmulh)
DO_2OP(VQADD_S, vqadds)
DO_2OP(VQADD_U, vqaddu)
DO_2OP(VQSUB_S, vqsubs)
DO_2OP(VQSUB_U, vqsubu)
DO_2OP(VSHL_S, vshls)
DO_2OP(VSHL_U, vshlu)
DO_2OP(VRSHL_S, vrshls)
DO_2OP(VRSHL_U, vrshlu)
DO_2OP(VQSHL_S, vqshls)
DO_2OP(VQSHL_U, vqshlu)
DO_2OP(VQRSHL_S, vqrshls)
DO_2OP(VQRSHL_U, vqrshlu)
DO_2OP(VQDMLADH, vqdmladh)
DO_2OP(VQDMLADHX, vqdmladhx)
DO_2OP(VQRDMLADH, vqrdmladh)
DO_2OP(VQRDMLADHX, vqrdmladhx)
DO_2OP(VQDMLSDH, vqdmlsdh)
DO_2OP(VQDMLSDHX, vqdmlsdhx)
DO_2OP(VQRDMLSDH, vqrdmlsdh)
DO_2OP(VQRDMLSDHX, vqrdmlsdhx)
DO_2OP(VRHADD_S, vrhadds)
DO_2OP(VRHADD_U, vrhaddu)
/*
 * VCADD Qd == Qm at size MO_32 is UNPREDICTABLE; we choose not to diagnose
 * so we can reuse the DO_2OP macro. (Our implementation calculates the
 * "expected" results in this case.) Similarly for VHCADD.
 */
DO_2OP(VCADD90, vcadd90)
DO_2OP(VCADD270, vcadd270)
DO_2OP(VHCADD90, vhcadd90)
DO_2OP(VHCADD270, vhcadd270)

static bool trans_VQDMULLB(DisasContext *s, arg_2op *a)
{
    static MVEGenTwoOpFn * const fns[] = {
        NULL,
        gen_helper_mve_vqdmullbh,
        gen_helper_mve_vqdmullbw,
        NULL,
    };
    if (a->size == MO_32 && (a->qd == a->qm || a->qd == a->qn)) {
        /* UNPREDICTABLE; we choose to undef */
        return false;
    }
    return do_2op(s, a, fns[a->size]);
}

static bool trans_VQDMULLT(DisasContext *s, arg_2op *a)
{
    static MVEGenTwoOpFn * const fns[] = {
        NULL,
        gen_helper_mve_vqdmullth,
        gen_helper_mve_vqdmulltw,
        NULL,
    };
    if (a->size == MO_32 && (a->qd == a->qm || a->qd == a->qn)) {
        /* UNPREDICTABLE; we choose to undef */
        return false;
    }
    return do_2op(s, a, fns[a->size]);
}

static bool trans_VMULLP_B(DisasContext *s, arg_2op *a)
{
    /*
     * Note that a->size indicates the output size, ie VMULL.P8
     * is the 8x8->16 operation and a->size is MO_16; VMULL.P16
     * is the 16x16->32 operation and a->size is MO_32.
     */
    static MVEGenTwoOpFn * const fns[] = {
        NULL,
        gen_helper_mve_vmullpbh,
        gen_helper_mve_vmullpbw,
        NULL,
    };
    return do_2op(s, a, fns[a->size]);
}

static bool trans_VMULLP_T(DisasContext *s, arg_2op *a)
{
    /* a->size is as for trans_VMULLP_B */
    static MVEGenTwoOpFn * const fns[] = {
        NULL,
        gen_helper_mve_vmullpth,
        gen_helper_mve_vmullptw,
        NULL,
    };
    return do_2op(s, a, fns[a->size]);
}

/*
 * VADC and VSBC: these perform an add-with-carry or subtract-with-carry
 * of the 32-bit elements in each lane of the input vectors, where the
 * carry-out of each add is the carry-in of the next.  The initial carry
 * input is either fixed (0 for VADCI, 1 for VSBCI) or is from FPSCR.C
 * (for VADC and VSBC); the carry out at the end is written back to FPSCR.C.
 * These insns are subject to beat-wise execution.  Partial execution
 * of an I=1 (initial carry input fixed) insn which does not
 * execute the first beat must start with the current FPSCR.NZCV
 * value, not the fixed constant input.
 */
static bool trans_VADC(DisasContext *s, arg_2op *a)
{
    return do_2op(s, a, gen_helper_mve_vadc);
}

static bool trans_VADCI(DisasContext *s, arg_2op *a)
{
    if (mve_skip_first_beat(s)) {
        return trans_VADC(s, a);
    }
    return do_2op(s, a, gen_helper_mve_vadci);
}

static bool trans_VSBC(DisasContext *s, arg_2op *a)
{
    return do_2op(s, a, gen_helper_mve_vsbc);
}

static bool trans_VSBCI(DisasContext *s, arg_2op *a)
{
    if (mve_skip_first_beat(s)) {
        return trans_VSBC(s, a);
    }
    return do_2op(s, a, gen_helper_mve_vsbci);
}

#define DO_2OP_FP(INSN, FN)                                     \
    static bool trans_##INSN(DisasContext *s, arg_2op *a)       \
    {                                                           \
        static MVEGenTwoOpFn * const fns[] = {                  \
            NULL,                                               \
            gen_helper_mve_##FN##h,                             \
            gen_helper_mve_##FN##s,                             \
            NULL,                                               \
        };                                                      \
        if (!dc_isar_feature(aa32_mve_fp, s)) {                 \
            return false;                                       \
        }                                                       \
        return do_2op(s, a, fns[a->size]);                      \
    }

DO_2OP_FP(VADD_fp, vfadd)
DO_2OP_FP(VSUB_fp, vfsub)
DO_2OP_FP(VMUL_fp, vfmul)
DO_2OP_FP(VABD_fp, vfabd)
DO_2OP_FP(VMAXNM, vmaxnm)
DO_2OP_FP(VMINNM, vminnm)
DO_2OP_FP(VCADD90_fp, vfcadd90)
DO_2OP_FP(VCADD270_fp, vfcadd270)
DO_2OP_FP(VFMA, vfma)
DO_2OP_FP(VFMS, vfms)
DO_2OP_FP(VCMUL0, vcmul0)
DO_2OP_FP(VCMUL90, vcmul90)
DO_2OP_FP(VCMUL180, vcmul180)
DO_2OP_FP(VCMUL270, vcmul270)
DO_2OP_FP(VCMLA0, vcmla0)
DO_2OP_FP(VCMLA90, vcmla90)
DO_2OP_FP(VCMLA180, vcmla180)
DO_2OP_FP(VCMLA270, vcmla270)
DO_2OP_FP(VMAXNMA, vmaxnma)
DO_2OP_FP(VMINNMA, vminnma)

static bool do_2op_scalar(DisasContext *s, arg_2scalar *a,
                          MVEGenTwoOpScalarFn fn)
{
    TCGv_ptr qd, qn;
    TCGv_i32 rm;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qd | a->qn) ||
        !fn) {
        return false;
    }
    if (a->rm == 13 || a->rm == 15) {
        /* UNPREDICTABLE */
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    qd = mve_qreg_ptr(a->qd);
    qn = mve_qreg_ptr(a->qn);
    rm = load_reg(s, a->rm);
    fn(cpu_env, qd, qn, rm);
    mve_update_eci(s);
    return true;
}

#define DO_2OP_SCALAR(INSN, FN)                                 \
    static bool trans_##INSN(DisasContext *s, arg_2scalar *a)   \
    {                                                           \
        static MVEGenTwoOpScalarFn * const fns[] = {            \
            gen_helper_mve_##FN##b,                             \
            gen_helper_mve_##FN##h,                             \
            gen_helper_mve_##FN##w,                             \
            NULL,                                               \
        };                                                      \
        return do_2op_scalar(s, a, fns[a->size]);               \
    }

DO_2OP_SCALAR(VADD_scalar, vadd_scalar)
DO_2OP_SCALAR(VSUB_scalar, vsub_scalar)
DO_2OP_SCALAR(VMUL_scalar, vmul_scalar)
DO_2OP_SCALAR(VHADD_S_scalar, vhadds_scalar)
DO_2OP_SCALAR(VHADD_U_scalar, vhaddu_scalar)
DO_2OP_SCALAR(VHSUB_S_scalar, vhsubs_scalar)
DO_2OP_SCALAR(VHSUB_U_scalar, vhsubu_scalar)
DO_2OP_SCALAR(VQADD_S_scalar, vqadds_scalar)
DO_2OP_SCALAR(VQADD_U_scalar, vqaddu_scalar)
DO_2OP_SCALAR(VQSUB_S_scalar, vqsubs_scalar)
DO_2OP_SCALAR(VQSUB_U_scalar, vqsubu_scalar)
DO_2OP_SCALAR(VQDMULH_scalar, vqdmulh_scalar)
DO_2OP_SCALAR(VQRDMULH_scalar, vqrdmulh_scalar)
DO_2OP_SCALAR(VBRSR, vbrsr)
DO_2OP_SCALAR(VMLA, vmla)
DO_2OP_SCALAR(VMLAS, vmlas)
DO_2OP_SCALAR(VQDMLAH, vqdmlah)
DO_2OP_SCALAR(VQRDMLAH, vqrdmlah)
DO_2OP_SCALAR(VQDMLASH, vqdmlash)
DO_2OP_SCALAR(VQRDMLASH, vqrdmlash)

static bool trans_VQDMULLB_scalar(DisasContext *s, arg_2scalar *a)
{
    static MVEGenTwoOpScalarFn * const fns[] = {
        NULL,
        gen_helper_mve_vqdmullb_scalarh,
        gen_helper_mve_vqdmullb_scalarw,
        NULL,
    };
    if (a->qd == a->qn && a->size == MO_32) {
        /* UNPREDICTABLE; we choose to undef */
        return false;
    }
    return do_2op_scalar(s, a, fns[a->size]);
}

static bool trans_VQDMULLT_scalar(DisasContext *s, arg_2scalar *a)
{
    static MVEGenTwoOpScalarFn * const fns[] = {
        NULL,
        gen_helper_mve_vqdmullt_scalarh,
        gen_helper_mve_vqdmullt_scalarw,
        NULL,
    };
    if (a->qd == a->qn && a->size == MO_32) {
        /* UNPREDICTABLE; we choose to undef */
        return false;
    }
    return do_2op_scalar(s, a, fns[a->size]);
}


#define DO_2OP_FP_SCALAR(INSN, FN)                              \
    static bool trans_##INSN(DisasContext *s, arg_2scalar *a)   \
    {                                                           \
        static MVEGenTwoOpScalarFn * const fns[] = {            \
            NULL,                                               \
            gen_helper_mve_##FN##h,                             \
            gen_helper_mve_##FN##s,                             \
            NULL,                                               \
        };                                                      \
        if (!dc_isar_feature(aa32_mve_fp, s)) {                 \
            return false;                                       \
        }                                                       \
        return do_2op_scalar(s, a, fns[a->size]);               \
    }

DO_2OP_FP_SCALAR(VADD_fp_scalar, vfadd_scalar)
DO_2OP_FP_SCALAR(VSUB_fp_scalar, vfsub_scalar)
DO_2OP_FP_SCALAR(VMUL_fp_scalar, vfmul_scalar)
DO_2OP_FP_SCALAR(VFMA_scalar, vfma_scalar)
DO_2OP_FP_SCALAR(VFMAS_scalar, vfmas_scalar)

static bool do_long_dual_acc(DisasContext *s, arg_vmlaldav *a,
                             MVEGenLongDualAccOpFn *fn)
{
    TCGv_ptr qn, qm;
    TCGv_i64 rda;
    TCGv_i32 rdalo, rdahi;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qn | a->qm) ||
        !fn) {
        return false;
    }
    /*
     * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
     * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
     */
    if (a->rdahi == 13 || a->rdahi == 15) {
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    qn = mve_qreg_ptr(a->qn);
    qm = mve_qreg_ptr(a->qm);

    /*
     * This insn is subject to beat-wise execution. Partial execution
     * of an A=0 (no-accumulate) insn which does not execute the first
     * beat must start with the current rda value, not 0.
     */
    if (a->a || mve_skip_first_beat(s)) {
        rda = tcg_temp_new_i64();
        rdalo = load_reg(s, a->rdalo);
        rdahi = load_reg(s, a->rdahi);
        tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
    } else {
        rda = tcg_const_i64(0);
    }

    fn(rda, cpu_env, qn, qm, rda);

    rdalo = tcg_temp_new_i32();
    rdahi = tcg_temp_new_i32();
    tcg_gen_extrl_i64_i32(rdalo, rda);
    tcg_gen_extrh_i64_i32(rdahi, rda);
    store_reg(s, a->rdalo, rdalo);
    store_reg(s, a->rdahi, rdahi);
    mve_update_eci(s);
    return true;
}

static bool trans_VMLALDAV_S(DisasContext *s, arg_vmlaldav *a)
{
    static MVEGenLongDualAccOpFn * const fns[4][2] = {
        { NULL, NULL },
        { gen_helper_mve_vmlaldavsh, gen_helper_mve_vmlaldavxsh },
        { gen_helper_mve_vmlaldavsw, gen_helper_mve_vmlaldavxsw },
        { NULL, NULL },
    };
    return do_long_dual_acc(s, a, fns[a->size][a->x]);
}

static bool trans_VMLALDAV_U(DisasContext *s, arg_vmlaldav *a)
{
    static MVEGenLongDualAccOpFn * const fns[4][2] = {
        { NULL, NULL },
        { gen_helper_mve_vmlaldavuh, NULL },
        { gen_helper_mve_vmlaldavuw, NULL },
        { NULL, NULL },
    };
    return do_long_dual_acc(s, a, fns[a->size][a->x]);
}

static bool trans_VMLSLDAV(DisasContext *s, arg_vmlaldav *a)
{
    static MVEGenLongDualAccOpFn * const fns[4][2] = {
        { NULL, NULL },
        { gen_helper_mve_vmlsldavsh, gen_helper_mve_vmlsldavxsh },
        { gen_helper_mve_vmlsldavsw, gen_helper_mve_vmlsldavxsw },
        { NULL, NULL },
    };
    return do_long_dual_acc(s, a, fns[a->size][a->x]);
}

static bool trans_VRMLALDAVH_S(DisasContext *s, arg_vmlaldav *a)
{
    static MVEGenLongDualAccOpFn * const fns[] = {
        gen_helper_mve_vrmlaldavhsw, gen_helper_mve_vrmlaldavhxsw,
    };
    return do_long_dual_acc(s, a, fns[a->x]);
}

static bool trans_VRMLALDAVH_U(DisasContext *s, arg_vmlaldav *a)
{
    static MVEGenLongDualAccOpFn * const fns[] = {
        gen_helper_mve_vrmlaldavhuw, NULL,
    };
    return do_long_dual_acc(s, a, fns[a->x]);
}

static bool trans_VRMLSLDAVH(DisasContext *s, arg_vmlaldav *a)
{
    static MVEGenLongDualAccOpFn * const fns[] = {
        gen_helper_mve_vrmlsldavhsw, gen_helper_mve_vrmlsldavhxsw,
    };
    return do_long_dual_acc(s, a, fns[a->x]);
}

static bool do_dual_acc(DisasContext *s, arg_vmladav *a, MVEGenDualAccOpFn *fn)
{
    TCGv_ptr qn, qm;
    TCGv_i32 rda;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qn) ||
        !fn) {
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    qn = mve_qreg_ptr(a->qn);
    qm = mve_qreg_ptr(a->qm);

    /*
     * This insn is subject to beat-wise execution. Partial execution
     * of an A=0 (no-accumulate) insn which does not execute the first
     * beat must start with the current rda value, not 0.
     */
    if (a->a || mve_skip_first_beat(s)) {
        rda = load_reg(s, a->rda);
    } else {
        rda = tcg_const_i32(0);
    }

    fn(rda, cpu_env, qn, qm, rda);
    store_reg(s, a->rda, rda);

    mve_update_eci(s);
    return true;
}

#define DO_DUAL_ACC(INSN, FN)                                           \
    static bool trans_##INSN(DisasContext *s, arg_vmladav *a)           \
    {                                                                   \
        static MVEGenDualAccOpFn * const fns[4][2] = {                  \
            { gen_helper_mve_##FN##b, gen_helper_mve_##FN##xb },        \
            { gen_helper_mve_##FN##h, gen_helper_mve_##FN##xh },        \
            { gen_helper_mve_##FN##w, gen_helper_mve_##FN##xw },        \
            { NULL, NULL },                                             \
        };                                                              \
        return do_dual_acc(s, a, fns[a->size][a->x]);                   \
    }

DO_DUAL_ACC(VMLADAV_S, vmladavs)
DO_DUAL_ACC(VMLSDAV, vmlsdav)

static bool trans_VMLADAV_U(DisasContext *s, arg_vmladav *a)
{
    static MVEGenDualAccOpFn * const fns[4][2] = {
        { gen_helper_mve_vmladavub, NULL },
        { gen_helper_mve_vmladavuh, NULL },
        { gen_helper_mve_vmladavuw, NULL },
        { NULL, NULL },
    };
    return do_dual_acc(s, a, fns[a->size][a->x]);
}

static void gen_vpst(DisasContext *s, uint32_t mask)
{
    /*
     * Set the VPR mask fields. We take advantage of MASK01 and MASK23
     * being adjacent fields in the register.
     *
     * Updating the masks is not predicated, but it is subject to beat-wise
     * execution, and the mask is updated on the odd-numbered beats.
     * So if PSR.ECI says we should skip beat 1, we mustn't update the
     * 01 mask field.
     */
    TCGv_i32 vpr = load_cpu_field(v7m.vpr);
    switch (s->eci) {
    case ECI_NONE:
    case ECI_A0:
        /* Update both 01 and 23 fields */
        tcg_gen_deposit_i32(vpr, vpr,
                            tcg_constant_i32(mask | (mask << 4)),
                            R_V7M_VPR_MASK01_SHIFT,
                            R_V7M_VPR_MASK01_LENGTH + R_V7M_VPR_MASK23_LENGTH);
        break;
    case ECI_A0A1:
    case ECI_A0A1A2:
    case ECI_A0A1A2B0:
        /* Update only the 23 mask field */
        tcg_gen_deposit_i32(vpr, vpr,
                            tcg_constant_i32(mask),
                            R_V7M_VPR_MASK23_SHIFT, R_V7M_VPR_MASK23_LENGTH);
        break;
    default:
        g_assert_not_reached();
    }
    store_cpu_field(vpr, v7m.vpr);
}

static bool trans_VPST(DisasContext *s, arg_VPST *a)
{
    /* mask == 0 is a "related encoding" */
    if (!dc_isar_feature(aa32_mve, s) || !a->mask) {
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }
    gen_vpst(s, a->mask);
    mve_update_and_store_eci(s);
    return true;
}

static bool trans_VPNOT(DisasContext *s, arg_VPNOT *a)
{
    /*
     * Invert the predicate in VPR.P0. We have call out to
     * a helper because this insn itself is beatwise and can
     * be predicated.
     */
    if (!dc_isar_feature(aa32_mve, s)) {
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    gen_helper_mve_vpnot(cpu_env);
    /* This insn updates predication bits */
    s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
    mve_update_eci(s);
    return true;
}

static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
{
    /* VADDV: vector add across vector */
    static MVEGenVADDVFn * const fns[4][2] = {
        { gen_helper_mve_vaddvsb, gen_helper_mve_vaddvub },
        { gen_helper_mve_vaddvsh, gen_helper_mve_vaddvuh },
        { gen_helper_mve_vaddvsw, gen_helper_mve_vaddvuw },
        { NULL, NULL }
    };
    TCGv_ptr qm;
    TCGv_i32 rda;

    if (!dc_isar_feature(aa32_mve, s) ||
        a->size == 3) {
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    /*
     * This insn is subject to beat-wise execution. Partial execution
     * of an A=0 (no-accumulate) insn which does not execute the first
     * beat must start with the current value of Rda, not zero.
     */
    if (a->a || mve_skip_first_beat(s)) {
        /* Accumulate input from Rda */
        rda = load_reg(s, a->rda);
    } else {
        /* Accumulate starting at zero */
        rda = tcg_const_i32(0);
    }

    qm = mve_qreg_ptr(a->qm);
    fns[a->size][a->u](rda, cpu_env, qm, rda);
    store_reg(s, a->rda, rda);

    mve_update_eci(s);
    return true;
}

static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
{
    /*
     * Vector Add Long Across Vector: accumulate the 32-bit
     * elements of the vector into a 64-bit result stored in
     * a pair of general-purpose registers.
     * No need to check Qm's bank: it is only 3 bits in decode.
     */
    TCGv_ptr qm;
    TCGv_i64 rda;
    TCGv_i32 rdalo, rdahi;

    if (!dc_isar_feature(aa32_mve, s)) {
        return false;
    }
    /*
     * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
     * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
     */
    if (a->rdahi == 13 || a->rdahi == 15) {
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    /*
     * This insn is subject to beat-wise execution. Partial execution
     * of an A=0 (no-accumulate) insn which does not execute the first
     * beat must start with the current value of RdaHi:RdaLo, not zero.
     */
    if (a->a || mve_skip_first_beat(s)) {
        /* Accumulate input from RdaHi:RdaLo */
        rda = tcg_temp_new_i64();
        rdalo = load_reg(s, a->rdalo);
        rdahi = load_reg(s, a->rdahi);
        tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
    } else {
        /* Accumulate starting at zero */
        rda = tcg_const_i64(0);
    }

    qm = mve_qreg_ptr(a->qm);
    if (a->u) {
        gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
    } else {
        gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
    }

    rdalo = tcg_temp_new_i32();
    rdahi = tcg_temp_new_i32();
    tcg_gen_extrl_i64_i32(rdalo, rda);
    tcg_gen_extrh_i64_i32(rdahi, rda);
    store_reg(s, a->rdalo, rdalo);
    store_reg(s, a->rdahi, rdahi);
    mve_update_eci(s);
    return true;
}

static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn,
                    GVecGen2iFn *vecfn)
{
    TCGv_ptr qd;
    uint64_t imm;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qd) ||
        !fn) {
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    imm = asimd_imm_const(a->imm, a->cmode, a->op);

    if (vecfn && mve_no_predication(s)) {
        vecfn(MO_64, mve_qreg_offset(a->qd), mve_qreg_offset(a->qd),
              imm, 16, 16);
    } else {
        qd = mve_qreg_ptr(a->qd);
        fn(cpu_env, qd, tcg_constant_i64(imm));
    }
    mve_update_eci(s);
    return true;
}

static void gen_gvec_vmovi(unsigned vece, uint32_t dofs, uint32_t aofs,
                           int64_t c, uint32_t oprsz, uint32_t maxsz)
{
    tcg_gen_gvec_dup_imm(vece, dofs, oprsz, maxsz, c);
}

static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
{
    /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
    MVEGenOneOpImmFn *fn;
    GVecGen2iFn *vecfn;

    if ((a->cmode & 1) && a->cmode < 12) {
        if (a->op) {
            /*
             * For op=1, the immediate will be inverted by asimd_imm_const(),
             * so the VBIC becomes a logical AND operation.
             */
            fn = gen_helper_mve_vandi;
            vecfn = tcg_gen_gvec_andi;
        } else {
            fn = gen_helper_mve_vorri;
            vecfn = tcg_gen_gvec_ori;
        }
    } else {
        /* There is one unallocated cmode/op combination in this space */
        if (a->cmode == 15 && a->op == 1) {
            return false;
        }
        /* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
        fn = gen_helper_mve_vmovi;
        vecfn = gen_gvec_vmovi;
    }
    return do_1imm(s, a, fn, vecfn);
}

static bool do_2shift_vec(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
                          bool negateshift, GVecGen2iFn vecfn)
{
    TCGv_ptr qd, qm;
    int shift = a->shift;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qd | a->qm) ||
        !fn) {
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    /*
     * When we handle a right shift insn using a left-shift helper
     * which permits a negative shift count to indicate a right-shift,
     * we must negate the shift count.
     */
    if (negateshift) {
        shift = -shift;
    }

    if (vecfn && mve_no_predication(s)) {
        vecfn(a->size, mve_qreg_offset(a->qd), mve_qreg_offset(a->qm),
              shift, 16, 16);
    } else {
        qd = mve_qreg_ptr(a->qd);
        qm = mve_qreg_ptr(a->qm);
        fn(cpu_env, qd, qm, tcg_constant_i32(shift));
    }
    mve_update_eci(s);
    return true;
}

static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
                      bool negateshift)
{
    return do_2shift_vec(s, a, fn, negateshift, NULL);
}

#define DO_2SHIFT_VEC(INSN, FN, NEGATESHIFT, VECFN)                     \
    static bool trans_##INSN(DisasContext *s, arg_2shift *a)            \
    {                                                                   \
        static MVEGenTwoOpShiftFn * const fns[] = {                     \
            gen_helper_mve_##FN##b,                                     \
            gen_helper_mve_##FN##h,                                     \
            gen_helper_mve_##FN##w,                                     \
            NULL,                                                       \
        };                                                              \
        return do_2shift_vec(s, a, fns[a->size], NEGATESHIFT, VECFN);   \
    }

#define DO_2SHIFT(INSN, FN, NEGATESHIFT)        \
    DO_2SHIFT_VEC(INSN, FN, NEGATESHIFT, NULL)

static void do_gvec_shri_s(unsigned vece, uint32_t dofs, uint32_t aofs,
                           int64_t shift, uint32_t oprsz, uint32_t maxsz)
{
    /*
     * We get here with a negated shift count, and we must handle
     * shifts by the element size, which tcg_gen_gvec_sari() does not do.
     */
    shift = -shift;
    if (shift == (8 << vece)) {
        shift--;
    }
    tcg_gen_gvec_sari(vece, dofs, aofs, shift, oprsz, maxsz);
}

static void do_gvec_shri_u(unsigned vece, uint32_t dofs, uint32_t aofs,
                           int64_t shift, uint32_t oprsz, uint32_t maxsz)
{
    /*
     * We get here with a negated shift count, and we must handle
     * shifts by the element size, which tcg_gen_gvec_shri() does not do.
     */
    shift = -shift;
    if (shift == (8 << vece)) {
        tcg_gen_gvec_dup_imm(vece, dofs, oprsz, maxsz, 0);
    } else {
        tcg_gen_gvec_shri(vece, dofs, aofs, shift, oprsz, maxsz);
    }
}

DO_2SHIFT_VEC(VSHLI, vshli_u, false, tcg_gen_gvec_shli)
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
/* These right shifts use a left-shift helper with negated shift count */
DO_2SHIFT_VEC(VSHRI_S, vshli_s, true, do_gvec_shri_s)
DO_2SHIFT_VEC(VSHRI_U, vshli_u, true, do_gvec_shri_u)
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
DO_2SHIFT(VRSHRI_U, vrshli_u, true)

DO_2SHIFT_VEC(VSRI, vsri, false, gen_gvec_sri)
DO_2SHIFT_VEC(VSLI, vsli, false, gen_gvec_sli)

#define DO_2SHIFT_FP(INSN, FN)                                  \
    static bool trans_##INSN(DisasContext *s, arg_2shift *a)    \
    {                                                           \
        if (!dc_isar_feature(aa32_mve_fp, s)) {                 \
            return false;                                       \
        }                                                       \
        return do_2shift(s, a, gen_helper_mve_##FN, false);     \
    }

DO_2SHIFT_FP(VCVT_SH_fixed, vcvt_sh)
DO_2SHIFT_FP(VCVT_UH_fixed, vcvt_uh)
DO_2SHIFT_FP(VCVT_HS_fixed, vcvt_hs)
DO_2SHIFT_FP(VCVT_HU_fixed, vcvt_hu)
DO_2SHIFT_FP(VCVT_SF_fixed, vcvt_sf)
DO_2SHIFT_FP(VCVT_UF_fixed, vcvt_uf)
DO_2SHIFT_FP(VCVT_FS_fixed, vcvt_fs)
DO_2SHIFT_FP(VCVT_FU_fixed, vcvt_fu)

static bool do_2shift_scalar(DisasContext *s, arg_shl_scalar *a,
                             MVEGenTwoOpShiftFn *fn)
{
    TCGv_ptr qda;
    TCGv_i32 rm;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qda) ||
        a->rm == 13 || a->rm == 15 || !fn) {
        /* Rm cases are UNPREDICTABLE */
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    qda = mve_qreg_ptr(a->qda);
    rm = load_reg(s, a->rm);
    fn(cpu_env, qda, qda, rm);
    mve_update_eci(s);
    return true;
}

#define DO_2SHIFT_SCALAR(INSN, FN)                                      \
    static bool trans_##INSN(DisasContext *s, arg_shl_scalar *a)        \
    {                                                                   \
        static MVEGenTwoOpShiftFn * const fns[] = {                     \
            gen_helper_mve_##FN##b,                                     \
            gen_helper_mve_##FN##h,                                     \
            gen_helper_mve_##FN##w,                                     \
            NULL,                                                       \
        };                                                              \
        return do_2shift_scalar(s, a, fns[a->size]);                    \
    }

DO_2SHIFT_SCALAR(VSHL_S_scalar, vshli_s)
DO_2SHIFT_SCALAR(VSHL_U_scalar, vshli_u)
DO_2SHIFT_SCALAR(VRSHL_S_scalar, vrshli_s)
DO_2SHIFT_SCALAR(VRSHL_U_scalar, vrshli_u)
DO_2SHIFT_SCALAR(VQSHL_S_scalar, vqshli_s)
DO_2SHIFT_SCALAR(VQSHL_U_scalar, vqshli_u)
DO_2SHIFT_SCALAR(VQRSHL_S_scalar, vqrshli_s)
DO_2SHIFT_SCALAR(VQRSHL_U_scalar, vqrshli_u)

#define DO_VSHLL(INSN, FN)                                              \
    static bool trans_##INSN(DisasContext *s, arg_2shift *a)            \
    {                                                                   \
        static MVEGenTwoOpShiftFn * const fns[] = {                     \
            gen_helper_mve_##FN##b,                                     \
            gen_helper_mve_##FN##h,                                     \
        };                                                              \
        return do_2shift_vec(s, a, fns[a->size], false, do_gvec_##FN);  \
    }

/*
 * For the VSHLL vector helpers, the vece is the size of the input
 * (ie MO_8 or MO_16); the helpers want to work in the output size.
 * The shift count can be 0..<input size>, inclusive. (0 is VMOVL.)
 */
static void do_gvec_vshllbs(unsigned vece, uint32_t dofs, uint32_t aofs,
                            int64_t shift, uint32_t oprsz, uint32_t maxsz)
{
    unsigned ovece = vece + 1;
    unsigned ibits = vece == MO_8 ? 8 : 16;
    tcg_gen_gvec_shli(ovece, dofs, aofs, ibits, oprsz, maxsz);
    tcg_gen_gvec_sari(ovece, dofs, dofs, ibits - shift, oprsz, maxsz);
}

static void do_gvec_vshllbu(unsigned vece, uint32_t dofs, uint32_t aofs,
                            int64_t shift, uint32_t oprsz, uint32_t maxsz)
{
    unsigned ovece = vece + 1;
    tcg_gen_gvec_andi(ovece, dofs, aofs,
                      ovece == MO_16 ? 0xff : 0xffff, oprsz, maxsz);
    tcg_gen_gvec_shli(ovece, dofs, dofs, shift, oprsz, maxsz);
}

static void do_gvec_vshllts(unsigned vece, uint32_t dofs, uint32_t aofs,
                            int64_t shift, uint32_t oprsz, uint32_t maxsz)
{
    unsigned ovece = vece + 1;
    unsigned ibits = vece == MO_8 ? 8 : 16;
    if (shift == 0) {
        tcg_gen_gvec_sari(ovece, dofs, aofs, ibits, oprsz, maxsz);
    } else {
        tcg_gen_gvec_andi(ovece, dofs, aofs,
                          ovece == MO_16 ? 0xff00 : 0xffff0000, oprsz, maxsz);
        tcg_gen_gvec_sari(ovece, dofs, dofs, ibits - shift, oprsz, maxsz);
    }
}

static void do_gvec_vshlltu(unsigned vece, uint32_t dofs, uint32_t aofs,
                            int64_t shift, uint32_t oprsz, uint32_t maxsz)
{
    unsigned ovece = vece + 1;
    unsigned ibits = vece == MO_8 ? 8 : 16;
    if (shift == 0) {
        tcg_gen_gvec_shri(ovece, dofs, aofs, ibits, oprsz, maxsz);
    } else {
        tcg_gen_gvec_andi(ovece, dofs, aofs,
                          ovece == MO_16 ? 0xff00 : 0xffff0000, oprsz, maxsz);
        tcg_gen_gvec_shri(ovece, dofs, dofs, ibits - shift, oprsz, maxsz);
    }
}

DO_VSHLL(VSHLL_BS, vshllbs)
DO_VSHLL(VSHLL_BU, vshllbu)
DO_VSHLL(VSHLL_TS, vshllts)
DO_VSHLL(VSHLL_TU, vshlltu)

#define DO_2SHIFT_N(INSN, FN)                                   \
    static bool trans_##INSN(DisasContext *s, arg_2shift *a)    \
    {                                                           \
        static MVEGenTwoOpShiftFn * const fns[] = {             \
            gen_helper_mve_##FN##b,                             \
            gen_helper_mve_##FN##h,                             \
        };                                                      \
        return do_2shift(s, a, fns[a->size], false);            \
    }

DO_2SHIFT_N(VSHRNB, vshrnb)
DO_2SHIFT_N(VSHRNT, vshrnt)
DO_2SHIFT_N(VRSHRNB, vrshrnb)
DO_2SHIFT_N(VRSHRNT, vrshrnt)
DO_2SHIFT_N(VQSHRNB_S, vqshrnb_s)
DO_2SHIFT_N(VQSHRNT_S, vqshrnt_s)
DO_2SHIFT_N(VQSHRNB_U, vqshrnb_u)
DO_2SHIFT_N(VQSHRNT_U, vqshrnt_u)
DO_2SHIFT_N(VQSHRUNB, vqshrunb)
DO_2SHIFT_N(VQSHRUNT, vqshrunt)
DO_2SHIFT_N(VQRSHRNB_S, vqrshrnb_s)
DO_2SHIFT_N(VQRSHRNT_S, vqrshrnt_s)
DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)

static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
{
    /*
     * Whole Vector Left Shift with Carry. The carry is taken
     * from a general purpose register and written back there.
     * An imm of 0 means "shift by 32".
     */
    TCGv_ptr qd;
    TCGv_i32 rdm;

    if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
        return false;
    }
    if (a->rdm == 13 || a->rdm == 15) {
        /* CONSTRAINED UNPREDICTABLE: we UNDEF */
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    qd = mve_qreg_ptr(a->qd);
    rdm = load_reg(s, a->rdm);
    gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
    store_reg(s, a->rdm, rdm);
    mve_update_eci(s);
    return true;
}

static bool do_vidup(DisasContext *s, arg_vidup *a, MVEGenVIDUPFn *fn)
{
    TCGv_ptr qd;
    TCGv_i32 rn;

    /*
     * Vector increment/decrement with wrap and duplicate (VIDUP, VDDUP).
     * This fills the vector with elements of successively increasing
     * or decreasing values, starting from Rn.
     */
    if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
        return false;
    }
    if (a->size == MO_64) {
        /* size 0b11 is another encoding */
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    qd = mve_qreg_ptr(a->qd);
    rn = load_reg(s, a->rn);
    fn(rn, cpu_env, qd, rn, tcg_constant_i32(a->imm));
    store_reg(s, a->rn, rn);
    mve_update_eci(s);
    return true;
}

static bool do_viwdup(DisasContext *s, arg_viwdup *a, MVEGenVIWDUPFn *fn)
{
    TCGv_ptr qd;
    TCGv_i32 rn, rm;

    /*
     * Vector increment/decrement with wrap and duplicate (VIWDUp, VDWDUP)
     * This fills the vector with elements of successively increasing
     * or decreasing values, starting from Rn. Rm specifies a point where
     * the count wraps back around to 0. The updated offset is written back
     * to Rn.
     */
    if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
        return false;
    }
    if (!fn || a->rm == 13 || a->rm == 15) {
        /*
         * size 0b11 is another encoding; Rm == 13 is UNPREDICTABLE;
         * Rm == 13 is VIWDUP, VDWDUP.
         */
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    qd = mve_qreg_ptr(a->qd);
    rn = load_reg(s, a->rn);
    rm = load_reg(s, a->rm);
    fn(rn, cpu_env, qd, rn, rm, tcg_constant_i32(a->imm));
    store_reg(s, a->rn, rn);
    mve_update_eci(s);
    return true;
}

static bool trans_VIDUP(DisasContext *s, arg_vidup *a)
{
    static MVEGenVIDUPFn * const fns[] = {
        gen_helper_mve_vidupb,
        gen_helper_mve_viduph,
        gen_helper_mve_vidupw,
        NULL,
    };
    return do_vidup(s, a, fns[a->size]);
}

static bool trans_VDDUP(DisasContext *s, arg_vidup *a)
{
    static MVEGenVIDUPFn * const fns[] = {
        gen_helper_mve_vidupb,
        gen_helper_mve_viduph,
        gen_helper_mve_vidupw,
        NULL,
    };
    /* VDDUP is just like VIDUP but with a negative immediate */
    a->imm = -a->imm;
    return do_vidup(s, a, fns[a->size]);
}

static bool trans_VIWDUP(DisasContext *s, arg_viwdup *a)
{
    static MVEGenVIWDUPFn * const fns[] = {
        gen_helper_mve_viwdupb,
        gen_helper_mve_viwduph,
        gen_helper_mve_viwdupw,
        NULL,
    };
    return do_viwdup(s, a, fns[a->size]);
}

static bool trans_VDWDUP(DisasContext *s, arg_viwdup *a)
{
    static MVEGenVIWDUPFn * const fns[] = {
        gen_helper_mve_vdwdupb,
        gen_helper_mve_vdwduph,
        gen_helper_mve_vdwdupw,
        NULL,
    };
    return do_viwdup(s, a, fns[a->size]);
}

static bool do_vcmp(DisasContext *s, arg_vcmp *a, MVEGenCmpFn *fn)
{
    TCGv_ptr qn, qm;

    if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qm) ||
        !fn) {
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    qn = mve_qreg_ptr(a->qn);
    qm = mve_qreg_ptr(a->qm);
    fn(cpu_env, qn, qm);
    if (a->mask) {
        /* VPT */
        gen_vpst(s, a->mask);
    }
    /* This insn updates predication bits */
    s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
    mve_update_eci(s);
    return true;
}

static bool do_vcmp_scalar(DisasContext *s, arg_vcmp_scalar *a,
                           MVEGenScalarCmpFn *fn)
{
    TCGv_ptr qn;
    TCGv_i32 rm;

    if (!dc_isar_feature(aa32_mve, s) || !fn || a->rm == 13) {
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    qn = mve_qreg_ptr(a->qn);
    if (a->rm == 15) {
        /* Encoding Rm=0b1111 means "constant zero" */
        rm = tcg_constant_i32(0);
    } else {
        rm = load_reg(s, a->rm);
    }
    fn(cpu_env, qn, rm);
    if (a->mask) {
        /* VPT */
        gen_vpst(s, a->mask);
    }
    /* This insn updates predication bits */
    s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
    mve_update_eci(s);
    return true;
}

#define DO_VCMP(INSN, FN)                                       \
    static bool trans_##INSN(DisasContext *s, arg_vcmp *a)      \
    {                                                           \
        static MVEGenCmpFn * const fns[] = {                    \
            gen_helper_mve_##FN##b,                             \
            gen_helper_mve_##FN##h,                             \
            gen_helper_mve_##FN##w,                             \
            NULL,                                               \
        };                                                      \
        return do_vcmp(s, a, fns[a->size]);                     \
    }                                                           \
    static bool trans_##INSN##_scalar(DisasContext *s,          \
                                      arg_vcmp_scalar *a)       \
    {                                                           \
        static MVEGenScalarCmpFn * const fns[] = {              \
            gen_helper_mve_##FN##_scalarb,                      \
            gen_helper_mve_##FN##_scalarh,                      \
            gen_helper_mve_##FN##_scalarw,                      \
            NULL,                                               \
        };                                                      \
        return do_vcmp_scalar(s, a, fns[a->size]);              \
    }

DO_VCMP(VCMPEQ, vcmpeq)
DO_VCMP(VCMPNE, vcmpne)
DO_VCMP(VCMPCS, vcmpcs)
DO_VCMP(VCMPHI, vcmphi)
DO_VCMP(VCMPGE, vcmpge)
DO_VCMP(VCMPLT, vcmplt)
DO_VCMP(VCMPGT, vcmpgt)
DO_VCMP(VCMPLE, vcmple)

#define DO_VCMP_FP(INSN, FN)                                    \
    static bool trans_##INSN(DisasContext *s, arg_vcmp *a)      \
    {                                                           \
        static MVEGenCmpFn * const fns[] = {                    \
            NULL,                                               \
            gen_helper_mve_##FN##h,                             \
            gen_helper_mve_##FN##s,                             \
            NULL,                                               \
        };                                                      \
        if (!dc_isar_feature(aa32_mve_fp, s)) {                 \
            return false;                                       \
        }                                                       \
        return do_vcmp(s, a, fns[a->size]);                     \
    }                                                           \
    static bool trans_##INSN##_scalar(DisasContext *s,          \
                                      arg_vcmp_scalar *a)       \
    {                                                           \
        static MVEGenScalarCmpFn * const fns[] = {              \
            NULL,                                               \
            gen_helper_mve_##FN##_scalarh,                      \
            gen_helper_mve_##FN##_scalars,                      \
            NULL,                                               \
        };                                                      \
        if (!dc_isar_feature(aa32_mve_fp, s)) {                 \
            return false;                                       \
        }                                                       \
        return do_vcmp_scalar(s, a, fns[a->size]);              \
    }

DO_VCMP_FP(VCMPEQ_fp, vfcmpeq)
DO_VCMP_FP(VCMPNE_fp, vfcmpne)
DO_VCMP_FP(VCMPGE_fp, vfcmpge)
DO_VCMP_FP(VCMPLT_fp, vfcmplt)
DO_VCMP_FP(VCMPGT_fp, vfcmpgt)
DO_VCMP_FP(VCMPLE_fp, vfcmple)

static bool do_vmaxv(DisasContext *s, arg_vmaxv *a, MVEGenVADDVFn fn)
{
    /*
     * MIN/MAX operations across a vector: compute the min or
     * max of the initial value in a general purpose register
     * and all the elements in the vector, and store it back
     * into the general purpose register.
     */
    TCGv_ptr qm;
    TCGv_i32 rda;

    if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qm) ||
        !fn || a->rda == 13 || a->rda == 15) {
        /* Rda cases are UNPREDICTABLE */
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    qm = mve_qreg_ptr(a->qm);
    rda = load_reg(s, a->rda);
    fn(rda, cpu_env, qm, rda);
    store_reg(s, a->rda, rda);
    mve_update_eci(s);
    return true;
}

#define DO_VMAXV(INSN, FN)                                      \
    static bool trans_##INSN(DisasContext *s, arg_vmaxv *a)     \
    {                                                           \
        static MVEGenVADDVFn * const fns[] = {                  \
            gen_helper_mve_##FN##b,                             \
            gen_helper_mve_##FN##h,                             \
            gen_helper_mve_##FN##w,                             \
            NULL,                                               \
        };                                                      \
        return do_vmaxv(s, a, fns[a->size]);                    \
    }

DO_VMAXV(VMAXV_S, vmaxvs)
DO_VMAXV(VMAXV_U, vmaxvu)
DO_VMAXV(VMAXAV, vmaxav)
DO_VMAXV(VMINV_S, vminvs)
DO_VMAXV(VMINV_U, vminvu)
DO_VMAXV(VMINAV, vminav)

#define DO_VMAXV_FP(INSN, FN)                                   \
    static bool trans_##INSN(DisasContext *s, arg_vmaxv *a)     \
    {                                                           \
        static MVEGenVADDVFn * const fns[] = {                  \
            NULL,                                               \
            gen_helper_mve_##FN##h,                             \
            gen_helper_mve_##FN##s,                             \
            NULL,                                               \
        };                                                      \
        if (!dc_isar_feature(aa32_mve_fp, s)) {                 \
            return false;                                       \
        }                                                       \
        return do_vmaxv(s, a, fns[a->size]);                    \
    }

DO_VMAXV_FP(VMAXNMV, vmaxnmv)
DO_VMAXV_FP(VMINNMV, vminnmv)
DO_VMAXV_FP(VMAXNMAV, vmaxnmav)
DO_VMAXV_FP(VMINNMAV, vminnmav)

static bool do_vabav(DisasContext *s, arg_vabav *a, MVEGenVABAVFn *fn)
{
    /* Absolute difference accumulated across vector */
    TCGv_ptr qn, qm;
    TCGv_i32 rda;

    if (!dc_isar_feature(aa32_mve, s) ||
        !mve_check_qreg_bank(s, a->qm | a->qn) ||
        !fn || a->rda == 13 || a->rda == 15) {
        /* Rda cases are UNPREDICTABLE */
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    qm = mve_qreg_ptr(a->qm);
    qn = mve_qreg_ptr(a->qn);
    rda = load_reg(s, a->rda);
    fn(rda, cpu_env, qn, qm, rda);
    store_reg(s, a->rda, rda);
    mve_update_eci(s);
    return true;
}

#define DO_VABAV(INSN, FN)                                      \
    static bool trans_##INSN(DisasContext *s, arg_vabav *a)     \
    {                                                           \
        static MVEGenVABAVFn * const fns[] = {                  \
            gen_helper_mve_##FN##b,                             \
            gen_helper_mve_##FN##h,                             \
            gen_helper_mve_##FN##w,                             \
            NULL,                                               \
        };                                                      \
        return do_vabav(s, a, fns[a->size]);                    \
    }

DO_VABAV(VABAV_S, vabavs)
DO_VABAV(VABAV_U, vabavu)

static bool trans_VMOV_to_2gp(DisasContext *s, arg_VMOV_to_2gp *a)
{
    /*
     * VMOV two 32-bit vector lanes to two general-purpose registers.
     * This insn is not predicated but it is subject to beat-wise
     * execution if it is not in an IT block. For us this means
     * only that if PSR.ECI says we should not be executing the beat
     * corresponding to the lane of the vector register being accessed
     * then we should skip perfoming the move, and that we need to do
     * the usual check for bad ECI state and advance of ECI state.
     * (If PSR.ECI is non-zero then we cannot be in an IT block.)
     */
    TCGv_i32 tmp;
    int vd;

    if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd) ||
        a->rt == 13 || a->rt == 15 || a->rt2 == 13 || a->rt2 == 15 ||
        a->rt == a->rt2) {
        /* Rt/Rt2 cases are UNPREDICTABLE */
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    /* Convert Qreg index to Dreg for read_neon_element32() etc */
    vd = a->qd * 2;

    if (!mve_skip_vmov(s, vd, a->idx, MO_32)) {
        tmp = tcg_temp_new_i32();
        read_neon_element32(tmp, vd, a->idx, MO_32);
        store_reg(s, a->rt, tmp);
    }
    if (!mve_skip_vmov(s, vd + 1, a->idx, MO_32)) {
        tmp = tcg_temp_new_i32();
        read_neon_element32(tmp, vd + 1, a->idx, MO_32);
        store_reg(s, a->rt2, tmp);
    }

    mve_update_and_store_eci(s);
    return true;
}

static bool trans_VMOV_from_2gp(DisasContext *s, arg_VMOV_to_2gp *a)
{
    /*
     * VMOV two general-purpose registers to two 32-bit vector lanes.
     * This insn is not predicated but it is subject to beat-wise
     * execution if it is not in an IT block. For us this means
     * only that if PSR.ECI says we should not be executing the beat
     * corresponding to the lane of the vector register being accessed
     * then we should skip perfoming the move, and that we need to do
     * the usual check for bad ECI state and advance of ECI state.
     * (If PSR.ECI is non-zero then we cannot be in an IT block.)
     */
    TCGv_i32 tmp;
    int vd;

    if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd) ||
        a->rt == 13 || a->rt == 15 || a->rt2 == 13 || a->rt2 == 15) {
        /* Rt/Rt2 cases are UNPREDICTABLE */
        return false;
    }
    if (!mve_eci_check(s) || !vfp_access_check(s)) {
        return true;
    }

    /* Convert Qreg idx to Dreg for read_neon_element32() etc */
    vd = a->qd * 2;

    if (!mve_skip_vmov(s, vd, a->idx, MO_32)) {
        tmp = load_reg(s, a->rt);
        write_neon_element32(tmp, vd, a->idx, MO_32);
    }
    if (!mve_skip_vmov(s, vd + 1, a->idx, MO_32)) {
        tmp = load_reg(s, a->rt2);
        write_neon_element32(tmp, vd + 1, a->idx, MO_32);
    }

    mve_update_and_store_eci(s);
    return true;
}
