/*
 *  AArch64 translation
 *
 *  Copyright (c) 2013 Alexander Graf <agraf@suse.de>
 *
 * 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 "exec/exec-all.h"
#include "translate.h"
#include "translate-a64.h"
#include "qemu/log.h"
#include "arm_ldst.h"
#include "semihosting/semihost.h"
#include "cpregs.h"

static TCGv_i64 cpu_X[32];
static TCGv_i64 cpu_pc;

/* Load/store exclusive handling */
static TCGv_i64 cpu_exclusive_high;

static const char *regnames[] = {
    "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
    "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
    "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
    "x24", "x25", "x26", "x27", "x28", "x29", "lr", "sp"
};

enum a64_shift_type {
    A64_SHIFT_TYPE_LSL = 0,
    A64_SHIFT_TYPE_LSR = 1,
    A64_SHIFT_TYPE_ASR = 2,
    A64_SHIFT_TYPE_ROR = 3
};

/*
 * Helpers for extracting complex instruction fields
 */

/*
 * For load/store with an unsigned 12 bit immediate scaled by the element
 * size. The input has the immediate field in bits [14:3] and the element
 * size in [2:0].
 */
static int uimm_scaled(DisasContext *s, int x)
{
    unsigned imm = x >> 3;
    unsigned scale = extract32(x, 0, 3);
    return imm << scale;
}

/* For load/store memory tags: scale offset by LOG2_TAG_GRANULE */
static int scale_by_log2_tag_granule(DisasContext *s, int x)
{
    return x << LOG2_TAG_GRANULE;
}

/*
 * Include the generated decoders.
 */

#include "decode-sme-fa64.c.inc"
#include "decode-a64.c.inc"

/* Table based decoder typedefs - used when the relevant bits for decode
 * are too awkwardly scattered across the instruction (eg SIMD).
 */
typedef void AArch64DecodeFn(DisasContext *s, uint32_t insn);

typedef struct AArch64DecodeTable {
    uint32_t pattern;
    uint32_t mask;
    AArch64DecodeFn *disas_fn;
} AArch64DecodeTable;

/* initialize TCG globals.  */
void a64_translate_init(void)
{
    int i;

    cpu_pc = tcg_global_mem_new_i64(tcg_env,
                                    offsetof(CPUARMState, pc),
                                    "pc");
    for (i = 0; i < 32; i++) {
        cpu_X[i] = tcg_global_mem_new_i64(tcg_env,
                                          offsetof(CPUARMState, xregs[i]),
                                          regnames[i]);
    }

    cpu_exclusive_high = tcg_global_mem_new_i64(tcg_env,
        offsetof(CPUARMState, exclusive_high), "exclusive_high");
}

/*
 * Return the core mmu_idx to use for A64 load/store insns which
 * have a "unprivileged load/store" variant. Those insns access
 * EL0 if executed from an EL which has control over EL0 (usually
 * EL1) but behave like normal loads and stores if executed from
 * elsewhere (eg EL3).
 *
 * @unpriv : true for the unprivileged encoding; false for the
 *           normal encoding (in which case we will return the same
 *           thing as get_mem_index().
 */
static int get_a64_user_mem_index(DisasContext *s, bool unpriv)
{
    /*
     * If AccType_UNPRIV is not used, the insn uses AccType_NORMAL,
     * which is the usual mmu_idx for this cpu state.
     */
    ARMMMUIdx useridx = s->mmu_idx;

    if (unpriv && s->unpriv) {
        /*
         * We have pre-computed the condition for AccType_UNPRIV.
         * Therefore we should never get here with a mmu_idx for
         * which we do not know the corresponding user mmu_idx.
         */
        switch (useridx) {
        case ARMMMUIdx_E10_1:
        case ARMMMUIdx_E10_1_PAN:
            useridx = ARMMMUIdx_E10_0;
            break;
        case ARMMMUIdx_E20_2:
        case ARMMMUIdx_E20_2_PAN:
            useridx = ARMMMUIdx_E20_0;
            break;
        default:
            g_assert_not_reached();
        }
    }
    return arm_to_core_mmu_idx(useridx);
}

static void set_btype_raw(int val)
{
    tcg_gen_st_i32(tcg_constant_i32(val), tcg_env,
                   offsetof(CPUARMState, btype));
}

static void set_btype(DisasContext *s, int val)
{
    /* BTYPE is a 2-bit field, and 0 should be done with reset_btype.  */
    tcg_debug_assert(val >= 1 && val <= 3);
    set_btype_raw(val);
    s->btype = -1;
}

static void reset_btype(DisasContext *s)
{
    if (s->btype != 0) {
        set_btype_raw(0);
        s->btype = 0;
    }
}

static void gen_pc_plus_diff(DisasContext *s, TCGv_i64 dest, target_long diff)
{
    assert(s->pc_save != -1);
    if (tb_cflags(s->base.tb) & CF_PCREL) {
        tcg_gen_addi_i64(dest, cpu_pc, (s->pc_curr - s->pc_save) + diff);
    } else {
        tcg_gen_movi_i64(dest, s->pc_curr + diff);
    }
}

void gen_a64_update_pc(DisasContext *s, target_long diff)
{
    gen_pc_plus_diff(s, cpu_pc, diff);
    s->pc_save = s->pc_curr + diff;
}

/*
 * Handle Top Byte Ignore (TBI) bits.
 *
 * If address tagging is enabled via the TCR TBI bits:
 *  + for EL2 and EL3 there is only one TBI bit, and if it is set
 *    then the address is zero-extended, clearing bits [63:56]
 *  + for EL0 and EL1, TBI0 controls addresses with bit 55 == 0
 *    and TBI1 controls addresses with bit 55 == 1.
 *    If the appropriate TBI bit is set for the address then
 *    the address is sign-extended from bit 55 into bits [63:56]
 *
 * Here We have concatenated TBI{1,0} into tbi.
 */
static void gen_top_byte_ignore(DisasContext *s, TCGv_i64 dst,
                                TCGv_i64 src, int tbi)
{
    if (tbi == 0) {
        /* Load unmodified address */
        tcg_gen_mov_i64(dst, src);
    } else if (!regime_has_2_ranges(s->mmu_idx)) {
        /* Force tag byte to all zero */
        tcg_gen_extract_i64(dst, src, 0, 56);
    } else {
        /* Sign-extend from bit 55.  */
        tcg_gen_sextract_i64(dst, src, 0, 56);

        switch (tbi) {
        case 1:
            /* tbi0 but !tbi1: only use the extension if positive */
            tcg_gen_and_i64(dst, dst, src);
            break;
        case 2:
            /* !tbi0 but tbi1: only use the extension if negative */
            tcg_gen_or_i64(dst, dst, src);
            break;
        case 3:
            /* tbi0 and tbi1: always use the extension */
            break;
        default:
            g_assert_not_reached();
        }
    }
}

static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
{
    /*
     * If address tagging is enabled for instructions via the TCR TBI bits,
     * then loading an address into the PC will clear out any tag.
     */
    gen_top_byte_ignore(s, cpu_pc, src, s->tbii);
    s->pc_save = -1;
}

/*
 * Handle MTE and/or TBI.
 *
 * For TBI, ideally, we would do nothing.  Proper behaviour on fault is
 * for the tag to be present in the FAR_ELx register.  But for user-only
 * mode we do not have a TLB with which to implement this, so we must
 * remove the top byte now.
 *
 * Always return a fresh temporary that we can increment independently
 * of the write-back address.
 */

TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr)
{
    TCGv_i64 clean = tcg_temp_new_i64();
#ifdef CONFIG_USER_ONLY
    gen_top_byte_ignore(s, clean, addr, s->tbid);
#else
    tcg_gen_mov_i64(clean, addr);
#endif
    return clean;
}

/* Insert a zero tag into src, with the result at dst. */
static void gen_address_with_allocation_tag0(TCGv_i64 dst, TCGv_i64 src)
{
    tcg_gen_andi_i64(dst, src, ~MAKE_64BIT_MASK(56, 4));
}

static void gen_probe_access(DisasContext *s, TCGv_i64 ptr,
                             MMUAccessType acc, int log2_size)
{
    gen_helper_probe_access(tcg_env, ptr,
                            tcg_constant_i32(acc),
                            tcg_constant_i32(get_mem_index(s)),
                            tcg_constant_i32(1 << log2_size));
}

/*
 * For MTE, check a single logical or atomic access.  This probes a single
 * address, the exact one specified.  The size and alignment of the access
 * is not relevant to MTE, per se, but watchpoints do require the size,
 * and we want to recognize those before making any other changes to state.
 */
static TCGv_i64 gen_mte_check1_mmuidx(DisasContext *s, TCGv_i64 addr,
                                      bool is_write, bool tag_checked,
                                      MemOp memop, bool is_unpriv,
                                      int core_idx)
{
    if (tag_checked && s->mte_active[is_unpriv]) {
        TCGv_i64 ret;
        int desc = 0;

        desc = FIELD_DP32(desc, MTEDESC, MIDX, core_idx);
        desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
        desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
        desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
        desc = FIELD_DP32(desc, MTEDESC, ALIGN, get_alignment_bits(memop));
        desc = FIELD_DP32(desc, MTEDESC, SIZEM1, memop_size(memop) - 1);

        ret = tcg_temp_new_i64();
        gen_helper_mte_check(ret, tcg_env, tcg_constant_i32(desc), addr);

        return ret;
    }
    return clean_data_tbi(s, addr);
}

TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
                        bool tag_checked, MemOp memop)
{
    return gen_mte_check1_mmuidx(s, addr, is_write, tag_checked, memop,
                                 false, get_mem_index(s));
}

/*
 * For MTE, check multiple logical sequential accesses.
 */
TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
                        bool tag_checked, int total_size, MemOp single_mop)
{
    if (tag_checked && s->mte_active[0]) {
        TCGv_i64 ret;
        int desc = 0;

        desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
        desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
        desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
        desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
        desc = FIELD_DP32(desc, MTEDESC, ALIGN, get_alignment_bits(single_mop));
        desc = FIELD_DP32(desc, MTEDESC, SIZEM1, total_size - 1);

        ret = tcg_temp_new_i64();
        gen_helper_mte_check(ret, tcg_env, tcg_constant_i32(desc), addr);

        return ret;
    }
    return clean_data_tbi(s, addr);
}

/*
 * Generate the special alignment check that applies to AccType_ATOMIC
 * and AccType_ORDERED insns under FEAT_LSE2: the access need not be
 * naturally aligned, but it must not cross a 16-byte boundary.
 * See AArch64.CheckAlignment().
 */
static void check_lse2_align(DisasContext *s, int rn, int imm,
                             bool is_write, MemOp mop)
{
    TCGv_i32 tmp;
    TCGv_i64 addr;
    TCGLabel *over_label;
    MMUAccessType type;
    int mmu_idx;

    tmp = tcg_temp_new_i32();
    tcg_gen_extrl_i64_i32(tmp, cpu_reg_sp(s, rn));
    tcg_gen_addi_i32(tmp, tmp, imm & 15);
    tcg_gen_andi_i32(tmp, tmp, 15);
    tcg_gen_addi_i32(tmp, tmp, memop_size(mop));

    over_label = gen_new_label();
    tcg_gen_brcondi_i32(TCG_COND_LEU, tmp, 16, over_label);

    addr = tcg_temp_new_i64();
    tcg_gen_addi_i64(addr, cpu_reg_sp(s, rn), imm);

    type = is_write ? MMU_DATA_STORE : MMU_DATA_LOAD,
    mmu_idx = get_mem_index(s);
    gen_helper_unaligned_access(tcg_env, addr, tcg_constant_i32(type),
                                tcg_constant_i32(mmu_idx));

    gen_set_label(over_label);

}

/* Handle the alignment check for AccType_ATOMIC instructions. */
static MemOp check_atomic_align(DisasContext *s, int rn, MemOp mop)
{
    MemOp size = mop & MO_SIZE;

    if (size == MO_8) {
        return mop;
    }

    /*
     * If size == MO_128, this is a LDXP, and the operation is single-copy
     * atomic for each doubleword, not the entire quadword; it still must
     * be quadword aligned.
     */
    if (size == MO_128) {
        return finalize_memop_atom(s, MO_128 | MO_ALIGN,
                                   MO_ATOM_IFALIGN_PAIR);
    }
    if (dc_isar_feature(aa64_lse2, s)) {
        check_lse2_align(s, rn, 0, true, mop);
    } else {
        mop |= MO_ALIGN;
    }
    return finalize_memop(s, mop);
}

/* Handle the alignment check for AccType_ORDERED instructions. */
static MemOp check_ordered_align(DisasContext *s, int rn, int imm,
                                 bool is_write, MemOp mop)
{
    MemOp size = mop & MO_SIZE;

    if (size == MO_8) {
        return mop;
    }
    if (size == MO_128) {
        return finalize_memop_atom(s, MO_128 | MO_ALIGN,
                                   MO_ATOM_IFALIGN_PAIR);
    }
    if (!dc_isar_feature(aa64_lse2, s)) {
        mop |= MO_ALIGN;
    } else if (!s->naa) {
        check_lse2_align(s, rn, imm, is_write, mop);
    }
    return finalize_memop(s, mop);
}

typedef struct DisasCompare64 {
    TCGCond cond;
    TCGv_i64 value;
} DisasCompare64;

static void a64_test_cc(DisasCompare64 *c64, int cc)
{
    DisasCompare c32;

    arm_test_cc(&c32, cc);

    /*
     * Sign-extend the 32-bit value so that the GE/LT comparisons work
     * properly.  The NE/EQ comparisons are also fine with this choice.
      */
    c64->cond = c32.cond;
    c64->value = tcg_temp_new_i64();
    tcg_gen_ext_i32_i64(c64->value, c32.value);
}

static void gen_rebuild_hflags(DisasContext *s)
{
    gen_helper_rebuild_hflags_a64(tcg_env, tcg_constant_i32(s->current_el));
}

static void gen_exception_internal(int excp)
{
    assert(excp_is_internal(excp));
    gen_helper_exception_internal(tcg_env, tcg_constant_i32(excp));
}

static void gen_exception_internal_insn(DisasContext *s, int excp)
{
    gen_a64_update_pc(s, 0);
    gen_exception_internal(excp);
    s->base.is_jmp = DISAS_NORETURN;
}

static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syndrome)
{
    gen_a64_update_pc(s, 0);
    gen_helper_exception_bkpt_insn(tcg_env, tcg_constant_i32(syndrome));
    s->base.is_jmp = DISAS_NORETURN;
}

static void gen_step_complete_exception(DisasContext *s)
{
    /* We just completed step of an insn. Move from Active-not-pending
     * to Active-pending, and then also take the swstep exception.
     * This corresponds to making the (IMPDEF) choice to prioritize
     * swstep exceptions over asynchronous exceptions taken to an exception
     * level where debug is disabled. This choice has the advantage that
     * we do not need to maintain internal state corresponding to the
     * ISV/EX syndrome bits between completion of the step and generation
     * of the exception, and our syndrome information is always correct.
     */
    gen_ss_advance(s);
    gen_swstep_exception(s, 1, s->is_ldex);
    s->base.is_jmp = DISAS_NORETURN;
}

static inline bool use_goto_tb(DisasContext *s, uint64_t dest)
{
    if (s->ss_active) {
        return false;
    }
    return translator_use_goto_tb(&s->base, dest);
}

static void gen_goto_tb(DisasContext *s, int n, int64_t diff)
{
    if (use_goto_tb(s, s->pc_curr + diff)) {
        /*
         * For pcrel, the pc must always be up-to-date on entry to
         * the linked TB, so that it can use simple additions for all
         * further adjustments.  For !pcrel, the linked TB is compiled
         * to know its full virtual address, so we can delay the
         * update to pc to the unlinked path.  A long chain of links
         * can thus avoid many updates to the PC.
         */
        if (tb_cflags(s->base.tb) & CF_PCREL) {
            gen_a64_update_pc(s, diff);
            tcg_gen_goto_tb(n);
        } else {
            tcg_gen_goto_tb(n);
            gen_a64_update_pc(s, diff);
        }
        tcg_gen_exit_tb(s->base.tb, n);
        s->base.is_jmp = DISAS_NORETURN;
    } else {
        gen_a64_update_pc(s, diff);
        if (s->ss_active) {
            gen_step_complete_exception(s);
        } else {
            tcg_gen_lookup_and_goto_ptr();
            s->base.is_jmp = DISAS_NORETURN;
        }
    }
}

/*
 * Register access functions
 *
 * These functions are used for directly accessing a register in where
 * changes to the final register value are likely to be made. If you
 * need to use a register for temporary calculation (e.g. index type
 * operations) use the read_* form.
 *
 * B1.2.1 Register mappings
 *
 * In instruction register encoding 31 can refer to ZR (zero register) or
 * the SP (stack pointer) depending on context. In QEMU's case we map SP
 * to cpu_X[31] and ZR accesses to a temporary which can be discarded.
 * This is the point of the _sp forms.
 */
TCGv_i64 cpu_reg(DisasContext *s, int reg)
{
    if (reg == 31) {
        TCGv_i64 t = tcg_temp_new_i64();
        tcg_gen_movi_i64(t, 0);
        return t;
    } else {
        return cpu_X[reg];
    }
}

/* register access for when 31 == SP */
TCGv_i64 cpu_reg_sp(DisasContext *s, int reg)
{
    return cpu_X[reg];
}

/* read a cpu register in 32bit/64bit mode. Returns a TCGv_i64
 * representing the register contents. This TCGv is an auto-freed
 * temporary so it need not be explicitly freed, and may be modified.
 */
TCGv_i64 read_cpu_reg(DisasContext *s, int reg, int sf)
{
    TCGv_i64 v = tcg_temp_new_i64();
    if (reg != 31) {
        if (sf) {
            tcg_gen_mov_i64(v, cpu_X[reg]);
        } else {
            tcg_gen_ext32u_i64(v, cpu_X[reg]);
        }
    } else {
        tcg_gen_movi_i64(v, 0);
    }
    return v;
}

TCGv_i64 read_cpu_reg_sp(DisasContext *s, int reg, int sf)
{
    TCGv_i64 v = tcg_temp_new_i64();
    if (sf) {
        tcg_gen_mov_i64(v, cpu_X[reg]);
    } else {
        tcg_gen_ext32u_i64(v, cpu_X[reg]);
    }
    return v;
}

/* Return the offset into CPUARMState of a slice (from
 * the least significant end) of FP register Qn (ie
 * Dn, Sn, Hn or Bn).
 * (Note that this is not the same mapping as for A32; see cpu.h)
 */
static inline int fp_reg_offset(DisasContext *s, int regno, MemOp size)
{
    return vec_reg_offset(s, regno, 0, size);
}

/* Offset of the high half of the 128 bit vector Qn */
static inline int fp_reg_hi_offset(DisasContext *s, int regno)
{
    return vec_reg_offset(s, regno, 1, MO_64);
}

/* Convenience accessors for reading and writing single and double
 * FP registers. Writing clears the upper parts of the associated
 * 128 bit vector register, as required by the architecture.
 * Note that unlike the GP register accessors, the values returned
 * by the read functions must be manually freed.
 */
static TCGv_i64 read_fp_dreg(DisasContext *s, int reg)
{
    TCGv_i64 v = tcg_temp_new_i64();

    tcg_gen_ld_i64(v, tcg_env, fp_reg_offset(s, reg, MO_64));
    return v;
}

static TCGv_i32 read_fp_sreg(DisasContext *s, int reg)
{
    TCGv_i32 v = tcg_temp_new_i32();

    tcg_gen_ld_i32(v, tcg_env, fp_reg_offset(s, reg, MO_32));
    return v;
}

static TCGv_i32 read_fp_hreg(DisasContext *s, int reg)
{
    TCGv_i32 v = tcg_temp_new_i32();

    tcg_gen_ld16u_i32(v, tcg_env, fp_reg_offset(s, reg, MO_16));
    return v;
}

/* Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64).
 * If SVE is not enabled, then there are only 128 bits in the vector.
 */
static void clear_vec_high(DisasContext *s, bool is_q, int rd)
{
    unsigned ofs = fp_reg_offset(s, rd, MO_64);
    unsigned vsz = vec_full_reg_size(s);

    /* Nop move, with side effect of clearing the tail. */
    tcg_gen_gvec_mov(MO_64, ofs, ofs, is_q ? 16 : 8, vsz);
}

void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v)
{
    unsigned ofs = fp_reg_offset(s, reg, MO_64);

    tcg_gen_st_i64(v, tcg_env, ofs);
    clear_vec_high(s, false, reg);
}

static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v)
{
    TCGv_i64 tmp = tcg_temp_new_i64();

    tcg_gen_extu_i32_i64(tmp, v);
    write_fp_dreg(s, reg, tmp);
}

/* Expand a 2-operand AdvSIMD vector operation using an expander function.  */
static void gen_gvec_fn2(DisasContext *s, bool is_q, int rd, int rn,
                         GVecGen2Fn *gvec_fn, int vece)
{
    gvec_fn(vece, vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
            is_q ? 16 : 8, vec_full_reg_size(s));
}

/* Expand a 2-operand + immediate AdvSIMD vector operation using
 * an expander function.
 */
static void gen_gvec_fn2i(DisasContext *s, bool is_q, int rd, int rn,
                          int64_t imm, GVecGen2iFn *gvec_fn, int vece)
{
    gvec_fn(vece, vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
            imm, is_q ? 16 : 8, vec_full_reg_size(s));
}

/* Expand a 3-operand AdvSIMD vector operation using an expander function.  */
static void gen_gvec_fn3(DisasContext *s, bool is_q, int rd, int rn, int rm,
                         GVecGen3Fn *gvec_fn, int vece)
{
    gvec_fn(vece, vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
            vec_full_reg_offset(s, rm), is_q ? 16 : 8, vec_full_reg_size(s));
}

/* Expand a 4-operand AdvSIMD vector operation using an expander function.  */
static void gen_gvec_fn4(DisasContext *s, bool is_q, int rd, int rn, int rm,
                         int rx, GVecGen4Fn *gvec_fn, int vece)
{
    gvec_fn(vece, vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
            vec_full_reg_offset(s, rm), vec_full_reg_offset(s, rx),
            is_q ? 16 : 8, vec_full_reg_size(s));
}

/* Expand a 2-operand operation using an out-of-line helper.  */
static void gen_gvec_op2_ool(DisasContext *s, bool is_q, int rd,
                             int rn, int data, gen_helper_gvec_2 *fn)
{
    tcg_gen_gvec_2_ool(vec_full_reg_offset(s, rd),
                       vec_full_reg_offset(s, rn),
                       is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
}

/* Expand a 3-operand operation using an out-of-line helper.  */
static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd,
                             int rn, int rm, int data, gen_helper_gvec_3 *fn)
{
    tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
                       vec_full_reg_offset(s, rn),
                       vec_full_reg_offset(s, rm),
                       is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
}

/* Expand a 3-operand + fpstatus pointer + simd data value operation using
 * an out-of-line helper.
 */
static void gen_gvec_op3_fpst(DisasContext *s, bool is_q, int rd, int rn,
                              int rm, bool is_fp16, int data,
                              gen_helper_gvec_3_ptr *fn)
{
    TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR);
    tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
                       vec_full_reg_offset(s, rn),
                       vec_full_reg_offset(s, rm), fpst,
                       is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
}

/* Expand a 3-operand + qc + operation using an out-of-line helper.  */
static void gen_gvec_op3_qc(DisasContext *s, bool is_q, int rd, int rn,
                            int rm, gen_helper_gvec_3_ptr *fn)
{
    TCGv_ptr qc_ptr = tcg_temp_new_ptr();

    tcg_gen_addi_ptr(qc_ptr, tcg_env, offsetof(CPUARMState, vfp.qc));
    tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
                       vec_full_reg_offset(s, rn),
                       vec_full_reg_offset(s, rm), qc_ptr,
                       is_q ? 16 : 8, vec_full_reg_size(s), 0, fn);
}

/* Expand a 4-operand operation using an out-of-line helper.  */
static void gen_gvec_op4_ool(DisasContext *s, bool is_q, int rd, int rn,
                             int rm, int ra, int data, gen_helper_gvec_4 *fn)
{
    tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
                       vec_full_reg_offset(s, rn),
                       vec_full_reg_offset(s, rm),
                       vec_full_reg_offset(s, ra),
                       is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
}

/*
 * Expand a 4-operand + fpstatus pointer + simd data value operation using
 * an out-of-line helper.
 */
static void gen_gvec_op4_fpst(DisasContext *s, bool is_q, int rd, int rn,
                              int rm, int ra, bool is_fp16, int data,
                              gen_helper_gvec_4_ptr *fn)
{
    TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR);
    tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd),
                       vec_full_reg_offset(s, rn),
                       vec_full_reg_offset(s, rm),
                       vec_full_reg_offset(s, ra), fpst,
                       is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
}

/* Set ZF and NF based on a 64 bit result. This is alas fiddlier
 * than the 32 bit equivalent.
 */
static inline void gen_set_NZ64(TCGv_i64 result)
{
    tcg_gen_extr_i64_i32(cpu_ZF, cpu_NF, result);
    tcg_gen_or_i32(cpu_ZF, cpu_ZF, cpu_NF);
}

/* Set NZCV as for a logical operation: NZ as per result, CV cleared. */
static inline void gen_logic_CC(int sf, TCGv_i64 result)
{
    if (sf) {
        gen_set_NZ64(result);
    } else {
        tcg_gen_extrl_i64_i32(cpu_ZF, result);
        tcg_gen_mov_i32(cpu_NF, cpu_ZF);
    }
    tcg_gen_movi_i32(cpu_CF, 0);
    tcg_gen_movi_i32(cpu_VF, 0);
}

/* dest = T0 + T1; compute C, N, V and Z flags */
static void gen_add64_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
{
    TCGv_i64 result, flag, tmp;
    result = tcg_temp_new_i64();
    flag = tcg_temp_new_i64();
    tmp = tcg_temp_new_i64();

    tcg_gen_movi_i64(tmp, 0);
    tcg_gen_add2_i64(result, flag, t0, tmp, t1, tmp);

    tcg_gen_extrl_i64_i32(cpu_CF, flag);

    gen_set_NZ64(result);

    tcg_gen_xor_i64(flag, result, t0);
    tcg_gen_xor_i64(tmp, t0, t1);
    tcg_gen_andc_i64(flag, flag, tmp);
    tcg_gen_extrh_i64_i32(cpu_VF, flag);

    tcg_gen_mov_i64(dest, result);
}

static void gen_add32_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
{
    TCGv_i32 t0_32 = tcg_temp_new_i32();
    TCGv_i32 t1_32 = tcg_temp_new_i32();
    TCGv_i32 tmp = tcg_temp_new_i32();

    tcg_gen_movi_i32(tmp, 0);
    tcg_gen_extrl_i64_i32(t0_32, t0);
    tcg_gen_extrl_i64_i32(t1_32, t1);
    tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, t1_32, tmp);
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
    tcg_gen_xor_i32(tmp, t0_32, t1_32);
    tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
    tcg_gen_extu_i32_i64(dest, cpu_NF);
}

static void gen_add_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
{
    if (sf) {
        gen_add64_CC(dest, t0, t1);
    } else {
        gen_add32_CC(dest, t0, t1);
    }
}

/* dest = T0 - T1; compute C, N, V and Z flags */
static void gen_sub64_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
{
    /* 64 bit arithmetic */
    TCGv_i64 result, flag, tmp;

    result = tcg_temp_new_i64();
    flag = tcg_temp_new_i64();
    tcg_gen_sub_i64(result, t0, t1);

    gen_set_NZ64(result);

    tcg_gen_setcond_i64(TCG_COND_GEU, flag, t0, t1);
    tcg_gen_extrl_i64_i32(cpu_CF, flag);

    tcg_gen_xor_i64(flag, result, t0);
    tmp = tcg_temp_new_i64();
    tcg_gen_xor_i64(tmp, t0, t1);
    tcg_gen_and_i64(flag, flag, tmp);
    tcg_gen_extrh_i64_i32(cpu_VF, flag);
    tcg_gen_mov_i64(dest, result);
}

static void gen_sub32_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
{
    /* 32 bit arithmetic */
    TCGv_i32 t0_32 = tcg_temp_new_i32();
    TCGv_i32 t1_32 = tcg_temp_new_i32();
    TCGv_i32 tmp;

    tcg_gen_extrl_i64_i32(t0_32, t0);
    tcg_gen_extrl_i64_i32(t1_32, t1);
    tcg_gen_sub_i32(cpu_NF, t0_32, t1_32);
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
    tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0_32, t1_32);
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
    tmp = tcg_temp_new_i32();
    tcg_gen_xor_i32(tmp, t0_32, t1_32);
    tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
    tcg_gen_extu_i32_i64(dest, cpu_NF);
}

static void gen_sub_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
{
    if (sf) {
        gen_sub64_CC(dest, t0, t1);
    } else {
        gen_sub32_CC(dest, t0, t1);
    }
}

/* dest = T0 + T1 + CF; do not compute flags. */
static void gen_adc(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
{
    TCGv_i64 flag = tcg_temp_new_i64();
    tcg_gen_extu_i32_i64(flag, cpu_CF);
    tcg_gen_add_i64(dest, t0, t1);
    tcg_gen_add_i64(dest, dest, flag);

    if (!sf) {
        tcg_gen_ext32u_i64(dest, dest);
    }
}

/* dest = T0 + T1 + CF; compute C, N, V and Z flags. */
static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
{
    if (sf) {
        TCGv_i64 result = tcg_temp_new_i64();
        TCGv_i64 cf_64 = tcg_temp_new_i64();
        TCGv_i64 vf_64 = tcg_temp_new_i64();
        TCGv_i64 tmp = tcg_temp_new_i64();
        TCGv_i64 zero = tcg_constant_i64(0);

        tcg_gen_extu_i32_i64(cf_64, cpu_CF);
        tcg_gen_add2_i64(result, cf_64, t0, zero, cf_64, zero);
        tcg_gen_add2_i64(result, cf_64, result, cf_64, t1, zero);
        tcg_gen_extrl_i64_i32(cpu_CF, cf_64);
        gen_set_NZ64(result);

        tcg_gen_xor_i64(vf_64, result, t0);
        tcg_gen_xor_i64(tmp, t0, t1);
        tcg_gen_andc_i64(vf_64, vf_64, tmp);
        tcg_gen_extrh_i64_i32(cpu_VF, vf_64);

        tcg_gen_mov_i64(dest, result);
    } else {
        TCGv_i32 t0_32 = tcg_temp_new_i32();
        TCGv_i32 t1_32 = tcg_temp_new_i32();
        TCGv_i32 tmp = tcg_temp_new_i32();
        TCGv_i32 zero = tcg_constant_i32(0);

        tcg_gen_extrl_i64_i32(t0_32, t0);
        tcg_gen_extrl_i64_i32(t1_32, t1);
        tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, zero, cpu_CF, zero);
        tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1_32, zero);

        tcg_gen_mov_i32(cpu_ZF, cpu_NF);
        tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
        tcg_gen_xor_i32(tmp, t0_32, t1_32);
        tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
        tcg_gen_extu_i32_i64(dest, cpu_NF);
    }
}

/*
 * Load/Store generators
 */

/*
 * Store from GPR register to memory.
 */
static void do_gpr_st_memidx(DisasContext *s, TCGv_i64 source,
                             TCGv_i64 tcg_addr, MemOp memop, int memidx,
                             bool iss_valid,
                             unsigned int iss_srt,
                             bool iss_sf, bool iss_ar)
{
    tcg_gen_qemu_st_i64(source, tcg_addr, memidx, memop);

    if (iss_valid) {
        uint32_t syn;

        syn = syn_data_abort_with_iss(0,
                                      (memop & MO_SIZE),
                                      false,
                                      iss_srt,
                                      iss_sf,
                                      iss_ar,
                                      0, 0, 0, 0, 0, false);
        disas_set_insn_syndrome(s, syn);
    }
}

static void do_gpr_st(DisasContext *s, TCGv_i64 source,
                      TCGv_i64 tcg_addr, MemOp memop,
                      bool iss_valid,
                      unsigned int iss_srt,
                      bool iss_sf, bool iss_ar)
{
    do_gpr_st_memidx(s, source, tcg_addr, memop, get_mem_index(s),
                     iss_valid, iss_srt, iss_sf, iss_ar);
}

/*
 * Load from memory to GPR register
 */
static void do_gpr_ld_memidx(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
                             MemOp memop, bool extend, int memidx,
                             bool iss_valid, unsigned int iss_srt,
                             bool iss_sf, bool iss_ar)
{
    tcg_gen_qemu_ld_i64(dest, tcg_addr, memidx, memop);

    if (extend && (memop & MO_SIGN)) {
        g_assert((memop & MO_SIZE) <= MO_32);
        tcg_gen_ext32u_i64(dest, dest);
    }

    if (iss_valid) {
        uint32_t syn;

        syn = syn_data_abort_with_iss(0,
                                      (memop & MO_SIZE),
                                      (memop & MO_SIGN) != 0,
                                      iss_srt,
                                      iss_sf,
                                      iss_ar,
                                      0, 0, 0, 0, 0, false);
        disas_set_insn_syndrome(s, syn);
    }
}

static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
                      MemOp memop, bool extend,
                      bool iss_valid, unsigned int iss_srt,
                      bool iss_sf, bool iss_ar)
{
    do_gpr_ld_memidx(s, dest, tcg_addr, memop, extend, get_mem_index(s),
                     iss_valid, iss_srt, iss_sf, iss_ar);
}

/*
 * Store from FP register to memory
 */
static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, MemOp mop)
{
    /* This writes the bottom N bits of a 128 bit wide vector to memory */
    TCGv_i64 tmplo = tcg_temp_new_i64();

    tcg_gen_ld_i64(tmplo, tcg_env, fp_reg_offset(s, srcidx, MO_64));

    if ((mop & MO_SIZE) < MO_128) {
        tcg_gen_qemu_st_i64(tmplo, tcg_addr, get_mem_index(s), mop);
    } else {
        TCGv_i64 tmphi = tcg_temp_new_i64();
        TCGv_i128 t16 = tcg_temp_new_i128();

        tcg_gen_ld_i64(tmphi, tcg_env, fp_reg_hi_offset(s, srcidx));
        tcg_gen_concat_i64_i128(t16, tmplo, tmphi);

        tcg_gen_qemu_st_i128(t16, tcg_addr, get_mem_index(s), mop);
    }
}

/*
 * Load from memory to FP register
 */
static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, MemOp mop)
{
    /* This always zero-extends and writes to a full 128 bit wide vector */
    TCGv_i64 tmplo = tcg_temp_new_i64();
    TCGv_i64 tmphi = NULL;

    if ((mop & MO_SIZE) < MO_128) {
        tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), mop);
    } else {
        TCGv_i128 t16 = tcg_temp_new_i128();

        tcg_gen_qemu_ld_i128(t16, tcg_addr, get_mem_index(s), mop);

        tmphi = tcg_temp_new_i64();
        tcg_gen_extr_i128_i64(tmplo, tmphi, t16);
    }

    tcg_gen_st_i64(tmplo, tcg_env, fp_reg_offset(s, destidx, MO_64));

    if (tmphi) {
        tcg_gen_st_i64(tmphi, tcg_env, fp_reg_hi_offset(s, destidx));
    }
    clear_vec_high(s, tmphi != NULL, destidx);
}

/*
 * Vector load/store helpers.
 *
 * The principal difference between this and a FP load is that we don't
 * zero extend as we are filling a partial chunk of the vector register.
 * These functions don't support 128 bit loads/stores, which would be
 * normal load/store operations.
 *
 * The _i32 versions are useful when operating on 32 bit quantities
 * (eg for floating point single or using Neon helper functions).
 */

/* Get value of an element within a vector register */
static void read_vec_element(DisasContext *s, TCGv_i64 tcg_dest, int srcidx,
                             int element, MemOp memop)
{
    int vect_off = vec_reg_offset(s, srcidx, element, memop & MO_SIZE);
    switch ((unsigned)memop) {
    case MO_8:
        tcg_gen_ld8u_i64(tcg_dest, tcg_env, vect_off);
        break;
    case MO_16:
        tcg_gen_ld16u_i64(tcg_dest, tcg_env, vect_off);
        break;
    case MO_32:
        tcg_gen_ld32u_i64(tcg_dest, tcg_env, vect_off);
        break;
    case MO_8|MO_SIGN:
        tcg_gen_ld8s_i64(tcg_dest, tcg_env, vect_off);
        break;
    case MO_16|MO_SIGN:
        tcg_gen_ld16s_i64(tcg_dest, tcg_env, vect_off);
        break;
    case MO_32|MO_SIGN:
        tcg_gen_ld32s_i64(tcg_dest, tcg_env, vect_off);
        break;
    case MO_64:
    case MO_64|MO_SIGN:
        tcg_gen_ld_i64(tcg_dest, tcg_env, vect_off);
        break;
    default:
        g_assert_not_reached();
    }
}

static void read_vec_element_i32(DisasContext *s, TCGv_i32 tcg_dest, int srcidx,
                                 int element, MemOp memop)
{
    int vect_off = vec_reg_offset(s, srcidx, element, memop & MO_SIZE);
    switch (memop) {
    case MO_8:
        tcg_gen_ld8u_i32(tcg_dest, tcg_env, vect_off);
        break;
    case MO_16:
        tcg_gen_ld16u_i32(tcg_dest, tcg_env, vect_off);
        break;
    case MO_8|MO_SIGN:
        tcg_gen_ld8s_i32(tcg_dest, tcg_env, vect_off);
        break;
    case MO_16|MO_SIGN:
        tcg_gen_ld16s_i32(tcg_dest, tcg_env, vect_off);
        break;
    case MO_32:
    case MO_32|MO_SIGN:
        tcg_gen_ld_i32(tcg_dest, tcg_env, vect_off);
        break;
    default:
        g_assert_not_reached();
    }
}

/* Set value of an element within a vector register */
static void write_vec_element(DisasContext *s, TCGv_i64 tcg_src, int destidx,
                              int element, MemOp memop)
{
    int vect_off = vec_reg_offset(s, destidx, element, memop & MO_SIZE);
    switch (memop) {
    case MO_8:
        tcg_gen_st8_i64(tcg_src, tcg_env, vect_off);
        break;
    case MO_16:
        tcg_gen_st16_i64(tcg_src, tcg_env, vect_off);
        break;
    case MO_32:
        tcg_gen_st32_i64(tcg_src, tcg_env, vect_off);
        break;
    case MO_64:
        tcg_gen_st_i64(tcg_src, tcg_env, vect_off);
        break;
    default:
        g_assert_not_reached();
    }
}

static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src,
                                  int destidx, int element, MemOp memop)
{
    int vect_off = vec_reg_offset(s, destidx, element, memop & MO_SIZE);
    switch (memop) {
    case MO_8:
        tcg_gen_st8_i32(tcg_src, tcg_env, vect_off);
        break;
    case MO_16:
        tcg_gen_st16_i32(tcg_src, tcg_env, vect_off);
        break;
    case MO_32:
        tcg_gen_st_i32(tcg_src, tcg_env, vect_off);
        break;
    default:
        g_assert_not_reached();
    }
}

/* Store from vector register to memory */
static void do_vec_st(DisasContext *s, int srcidx, int element,
                      TCGv_i64 tcg_addr, MemOp mop)
{
    TCGv_i64 tcg_tmp = tcg_temp_new_i64();

    read_vec_element(s, tcg_tmp, srcidx, element, mop & MO_SIZE);
    tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), mop);
}

/* Load from memory to vector register */
static void do_vec_ld(DisasContext *s, int destidx, int element,
                      TCGv_i64 tcg_addr, MemOp mop)
{
    TCGv_i64 tcg_tmp = tcg_temp_new_i64();

    tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), mop);
    write_vec_element(s, tcg_tmp, destidx, element, mop & MO_SIZE);
}

/* Check that FP/Neon access is enabled. If it is, return
 * true. If not, emit code to generate an appropriate exception,
 * and return false; the caller should not emit any code for
 * the instruction. Note that this check must happen after all
 * unallocated-encoding checks (otherwise the syndrome information
 * for the resulting exception will be incorrect).
 */
static bool fp_access_check_only(DisasContext *s)
{
    if (s->fp_excp_el) {
        assert(!s->fp_access_checked);
        s->fp_access_checked = true;

        gen_exception_insn_el(s, 0, EXCP_UDEF,
                              syn_fp_access_trap(1, 0xe, false, 0),
                              s->fp_excp_el);
        return false;
    }
    s->fp_access_checked = true;
    return true;
}

static bool fp_access_check(DisasContext *s)
{
    if (!fp_access_check_only(s)) {
        return false;
    }
    if (s->sme_trap_nonstreaming && s->is_nonstreaming) {
        gen_exception_insn(s, 0, EXCP_UDEF,
                           syn_smetrap(SME_ET_Streaming, false));
        return false;
    }
    return true;
}

/*
 * Check that SVE access is enabled.  If it is, return true.
 * If not, emit code to generate an appropriate exception and return false.
 * This function corresponds to CheckSVEEnabled().
 */
bool sve_access_check(DisasContext *s)
{
    if (s->pstate_sm || !dc_isar_feature(aa64_sve, s)) {
        assert(dc_isar_feature(aa64_sme, s));
        if (!sme_sm_enabled_check(s)) {
            goto fail_exit;
        }
    } else if (s->sve_excp_el) {
        gen_exception_insn_el(s, 0, EXCP_UDEF,
                              syn_sve_access_trap(), s->sve_excp_el);
        goto fail_exit;
    }
    s->sve_access_checked = true;
    return fp_access_check(s);

 fail_exit:
    /* Assert that we only raise one exception per instruction. */
    assert(!s->sve_access_checked);
    s->sve_access_checked = true;
    return false;
}

/*
 * Check that SME access is enabled, raise an exception if not.
 * Note that this function corresponds to CheckSMEAccess and is
 * only used directly for cpregs.
 */
static bool sme_access_check(DisasContext *s)
{
    if (s->sme_excp_el) {
        gen_exception_insn_el(s, 0, EXCP_UDEF,
                              syn_smetrap(SME_ET_AccessTrap, false),
                              s->sme_excp_el);
        return false;
    }
    return true;
}

/* This function corresponds to CheckSMEEnabled. */
bool sme_enabled_check(DisasContext *s)
{
    /*
     * Note that unlike sve_excp_el, we have not constrained sme_excp_el
     * to be zero when fp_excp_el has priority.  This is because we need
     * sme_excp_el by itself for cpregs access checks.
     */
    if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) {
        s->fp_access_checked = true;
        return sme_access_check(s);
    }
    return fp_access_check_only(s);
}

/* Common subroutine for CheckSMEAnd*Enabled. */
bool sme_enabled_check_with_svcr(DisasContext *s, unsigned req)
{
    if (!sme_enabled_check(s)) {
        return false;
    }
    if (FIELD_EX64(req, SVCR, SM) && !s->pstate_sm) {
        gen_exception_insn(s, 0, EXCP_UDEF,
                           syn_smetrap(SME_ET_NotStreaming, false));
        return false;
    }
    if (FIELD_EX64(req, SVCR, ZA) && !s->pstate_za) {
        gen_exception_insn(s, 0, EXCP_UDEF,
                           syn_smetrap(SME_ET_InactiveZA, false));
        return false;
    }
    return true;
}

/*
 * Expanders for AdvSIMD translation functions.
 */

static bool do_gvec_op2_ool(DisasContext *s, arg_qrr_e *a, int data,
                            gen_helper_gvec_2 *fn)
{
    if (!a->q && a->esz == MO_64) {
        return false;
    }
    if (fp_access_check(s)) {
        gen_gvec_op2_ool(s, a->q, a->rd, a->rn, data, fn);
    }
    return true;
}

static bool do_gvec_op3_ool(DisasContext *s, arg_qrrr_e *a, int data,
                            gen_helper_gvec_3 *fn)
{
    if (!a->q && a->esz == MO_64) {
        return false;
    }
    if (fp_access_check(s)) {
        gen_gvec_op3_ool(s, a->q, a->rd, a->rn, a->rm, data, fn);
    }
    return true;
}

static bool do_gvec_fn3(DisasContext *s, arg_qrrr_e *a, GVecGen3Fn *fn)
{
    if (!a->q && a->esz == MO_64) {
        return false;
    }
    if (fp_access_check(s)) {
        gen_gvec_fn3(s, a->q, a->rd, a->rn, a->rm, fn, a->esz);
    }
    return true;
}

static bool do_gvec_fn4(DisasContext *s, arg_qrrrr_e *a, GVecGen4Fn *fn)
{
    if (!a->q && a->esz == MO_64) {
        return false;
    }
    if (fp_access_check(s)) {
        gen_gvec_fn4(s, a->q, a->rd, a->rn, a->rm, a->ra, fn, a->esz);
    }
    return true;
}

/*
 * This utility function is for doing register extension with an
 * optional shift. You will likely want to pass a temporary for the
 * destination register. See DecodeRegExtend() in the ARM ARM.
 */
static void ext_and_shift_reg(TCGv_i64 tcg_out, TCGv_i64 tcg_in,
                              int option, unsigned int shift)
{
    int extsize = extract32(option, 0, 2);
    bool is_signed = extract32(option, 2, 1);

    tcg_gen_ext_i64(tcg_out, tcg_in, extsize | (is_signed ? MO_SIGN : 0));
    tcg_gen_shli_i64(tcg_out, tcg_out, shift);
}

static inline void gen_check_sp_alignment(DisasContext *s)
{
    /* The AArch64 architecture mandates that (if enabled via PSTATE
     * or SCTLR bits) there is a check that SP is 16-aligned on every
     * SP-relative load or store (with an exception generated if it is not).
     * In line with general QEMU practice regarding misaligned accesses,
     * we omit these checks for the sake of guest program performance.
     * This function is provided as a hook so we can more easily add these
     * checks in future (possibly as a "favour catching guest program bugs
     * over speed" user selectable option).
     */
}

/*
 * This provides a simple table based table lookup decoder. It is
 * intended to be used when the relevant bits for decode are too
 * awkwardly placed and switch/if based logic would be confusing and
 * deeply nested. Since it's a linear search through the table, tables
 * should be kept small.
 *
 * It returns the first handler where insn & mask == pattern, or
 * NULL if there is no match.
 * The table is terminated by an empty mask (i.e. 0)
 */
static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
                                               uint32_t insn)
{
    const AArch64DecodeTable *tptr = table;

    while (tptr->mask) {
        if ((insn & tptr->mask) == tptr->pattern) {
            return tptr->disas_fn;
        }
        tptr++;
    }
    return NULL;
}

/*
 * The instruction disassembly implemented here matches
 * the instruction encoding classifications in chapter C4
 * of the ARM Architecture Reference Manual (DDI0487B_a);
 * classification names and decode diagrams here should generally
 * match up with those in the manual.
 */

static bool trans_B(DisasContext *s, arg_i *a)
{
    reset_btype(s);
    gen_goto_tb(s, 0, a->imm);
    return true;
}

static bool trans_BL(DisasContext *s, arg_i *a)
{
    gen_pc_plus_diff(s, cpu_reg(s, 30), curr_insn_len(s));
    reset_btype(s);
    gen_goto_tb(s, 0, a->imm);
    return true;
}


static bool trans_CBZ(DisasContext *s, arg_cbz *a)
{
    DisasLabel match;
    TCGv_i64 tcg_cmp;

    tcg_cmp = read_cpu_reg(s, a->rt, a->sf);
    reset_btype(s);

    match = gen_disas_label(s);
    tcg_gen_brcondi_i64(a->nz ? TCG_COND_NE : TCG_COND_EQ,
                        tcg_cmp, 0, match.label);
    gen_goto_tb(s, 0, 4);
    set_disas_label(s, match);
    gen_goto_tb(s, 1, a->imm);
    return true;
}

static bool trans_TBZ(DisasContext *s, arg_tbz *a)
{
    DisasLabel match;
    TCGv_i64 tcg_cmp;

    tcg_cmp = tcg_temp_new_i64();
    tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, a->rt), 1ULL << a->bitpos);

    reset_btype(s);

    match = gen_disas_label(s);
    tcg_gen_brcondi_i64(a->nz ? TCG_COND_NE : TCG_COND_EQ,
                        tcg_cmp, 0, match.label);
    gen_goto_tb(s, 0, 4);
    set_disas_label(s, match);
    gen_goto_tb(s, 1, a->imm);
    return true;
}

static bool trans_B_cond(DisasContext *s, arg_B_cond *a)
{
    /* BC.cond is only present with FEAT_HBC */
    if (a->c && !dc_isar_feature(aa64_hbc, s)) {
        return false;
    }
    reset_btype(s);
    if (a->cond < 0x0e) {
        /* genuinely conditional branches */
        DisasLabel match = gen_disas_label(s);
        arm_gen_test_cc(a->cond, match.label);
        gen_goto_tb(s, 0, 4);
        set_disas_label(s, match);
        gen_goto_tb(s, 1, a->imm);
    } else {
        /* 0xe and 0xf are both "always" conditions */
        gen_goto_tb(s, 0, a->imm);
    }
    return true;
}

static void set_btype_for_br(DisasContext *s, int rn)
{
    if (dc_isar_feature(aa64_bti, s)) {
        /* BR to {x16,x17} or !guard -> 1, else 3.  */
        set_btype(s, rn == 16 || rn == 17 || !s->guarded_page ? 1 : 3);
    }
}

static void set_btype_for_blr(DisasContext *s)
{
    if (dc_isar_feature(aa64_bti, s)) {
        /* BLR sets BTYPE to 2, regardless of source guarded page.  */
        set_btype(s, 2);
    }
}

static bool trans_BR(DisasContext *s, arg_r *a)
{
    gen_a64_set_pc(s, cpu_reg(s, a->rn));
    set_btype_for_br(s, a->rn);
    s->base.is_jmp = DISAS_JUMP;
    return true;
}

static bool trans_BLR(DisasContext *s, arg_r *a)
{
    TCGv_i64 dst = cpu_reg(s, a->rn);
    TCGv_i64 lr = cpu_reg(s, 30);
    if (dst == lr) {
        TCGv_i64 tmp = tcg_temp_new_i64();
        tcg_gen_mov_i64(tmp, dst);
        dst = tmp;
    }
    gen_pc_plus_diff(s, lr, curr_insn_len(s));
    gen_a64_set_pc(s, dst);
    set_btype_for_blr(s);
    s->base.is_jmp = DISAS_JUMP;
    return true;
}

static bool trans_RET(DisasContext *s, arg_r *a)
{
    gen_a64_set_pc(s, cpu_reg(s, a->rn));
    s->base.is_jmp = DISAS_JUMP;
    return true;
}

static TCGv_i64 auth_branch_target(DisasContext *s, TCGv_i64 dst,
                                   TCGv_i64 modifier, bool use_key_a)
{
    TCGv_i64 truedst;
    /*
     * Return the branch target for a BRAA/RETA/etc, which is either
     * just the destination dst, or that value with the pauth check
     * done and the code removed from the high bits.
     */
    if (!s->pauth_active) {
        return dst;
    }

    truedst = tcg_temp_new_i64();
    if (use_key_a) {
        gen_helper_autia_combined(truedst, tcg_env, dst, modifier);
    } else {
        gen_helper_autib_combined(truedst, tcg_env, dst, modifier);
    }
    return truedst;
}

static bool trans_BRAZ(DisasContext *s, arg_braz *a)
{
    TCGv_i64 dst;

    if (!dc_isar_feature(aa64_pauth, s)) {
        return false;
    }

    dst = auth_branch_target(s, cpu_reg(s, a->rn), tcg_constant_i64(0), !a->m);
    gen_a64_set_pc(s, dst);
    set_btype_for_br(s, a->rn);
    s->base.is_jmp = DISAS_JUMP;
    return true;
}

static bool trans_BLRAZ(DisasContext *s, arg_braz *a)
{
    TCGv_i64 dst, lr;

    if (!dc_isar_feature(aa64_pauth, s)) {
        return false;
    }

    dst = auth_branch_target(s, cpu_reg(s, a->rn), tcg_constant_i64(0), !a->m);
    lr = cpu_reg(s, 30);
    if (dst == lr) {
        TCGv_i64 tmp = tcg_temp_new_i64();
        tcg_gen_mov_i64(tmp, dst);
        dst = tmp;
    }
    gen_pc_plus_diff(s, lr, curr_insn_len(s));
    gen_a64_set_pc(s, dst);
    set_btype_for_blr(s);
    s->base.is_jmp = DISAS_JUMP;
    return true;
}

static bool trans_RETA(DisasContext *s, arg_reta *a)
{
    TCGv_i64 dst;

    dst = auth_branch_target(s, cpu_reg(s, 30), cpu_X[31], !a->m);
    gen_a64_set_pc(s, dst);
    s->base.is_jmp = DISAS_JUMP;
    return true;
}

static bool trans_BRA(DisasContext *s, arg_bra *a)
{
    TCGv_i64 dst;

    if (!dc_isar_feature(aa64_pauth, s)) {
        return false;
    }
    dst = auth_branch_target(s, cpu_reg(s,a->rn), cpu_reg_sp(s, a->rm), !a->m);
    gen_a64_set_pc(s, dst);
    set_btype_for_br(s, a->rn);
    s->base.is_jmp = DISAS_JUMP;
    return true;
}

static bool trans_BLRA(DisasContext *s, arg_bra *a)
{
    TCGv_i64 dst, lr;

    if (!dc_isar_feature(aa64_pauth, s)) {
        return false;
    }
    dst = auth_branch_target(s, cpu_reg(s, a->rn), cpu_reg_sp(s, a->rm), !a->m);
    lr = cpu_reg(s, 30);
    if (dst == lr) {
        TCGv_i64 tmp = tcg_temp_new_i64();
        tcg_gen_mov_i64(tmp, dst);
        dst = tmp;
    }
    gen_pc_plus_diff(s, lr, curr_insn_len(s));
    gen_a64_set_pc(s, dst);
    set_btype_for_blr(s);
    s->base.is_jmp = DISAS_JUMP;
    return true;
}

static bool trans_ERET(DisasContext *s, arg_ERET *a)
{
    TCGv_i64 dst;

    if (s->current_el == 0) {
        return false;
    }
    if (s->trap_eret) {
        gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(0), 2);
        return true;
    }
    dst = tcg_temp_new_i64();
    tcg_gen_ld_i64(dst, tcg_env,
                   offsetof(CPUARMState, elr_el[s->current_el]));

    translator_io_start(&s->base);

    gen_helper_exception_return(tcg_env, dst);
    /* Must exit loop to check un-masked IRQs */
    s->base.is_jmp = DISAS_EXIT;
    return true;
}

static bool trans_ERETA(DisasContext *s, arg_reta *a)
{
    TCGv_i64 dst;

    if (!dc_isar_feature(aa64_pauth, s)) {
        return false;
    }
    if (s->current_el == 0) {
        return false;
    }
    /* The FGT trap takes precedence over an auth trap. */
    if (s->trap_eret) {
        gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(a->m ? 3 : 2), 2);
        return true;
    }
    dst = tcg_temp_new_i64();
    tcg_gen_ld_i64(dst, tcg_env,
                   offsetof(CPUARMState, elr_el[s->current_el]));

    dst = auth_branch_target(s, dst, cpu_X[31], !a->m);

    translator_io_start(&s->base);

    gen_helper_exception_return(tcg_env, dst);
    /* Must exit loop to check un-masked IRQs */
    s->base.is_jmp = DISAS_EXIT;
    return true;
}

static bool trans_NOP(DisasContext *s, arg_NOP *a)
{
    return true;
}

static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
{
    /*
     * When running in MTTCG we don't generate jumps to the yield and
     * WFE helpers as it won't affect the scheduling of other vCPUs.
     * If we wanted to more completely model WFE/SEV so we don't busy
     * spin unnecessarily we would need to do something more involved.
     */
    if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
        s->base.is_jmp = DISAS_YIELD;
    }
    return true;
}

static bool trans_WFI(DisasContext *s, arg_WFI *a)
{
    s->base.is_jmp = DISAS_WFI;
    return true;
}

static bool trans_WFE(DisasContext *s, arg_WFI *a)
{
    /*
     * When running in MTTCG we don't generate jumps to the yield and
     * WFE helpers as it won't affect the scheduling of other vCPUs.
     * If we wanted to more completely model WFE/SEV so we don't busy
     * spin unnecessarily we would need to do something more involved.
     */
    if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
        s->base.is_jmp = DISAS_WFE;
    }
    return true;
}

static bool trans_XPACLRI(DisasContext *s, arg_XPACLRI *a)
{
    if (s->pauth_active) {
        gen_helper_xpaci(cpu_X[30], tcg_env, cpu_X[30]);
    }
    return true;
}

static bool trans_PACIA1716(DisasContext *s, arg_PACIA1716 *a)
{
    if (s->pauth_active) {
        gen_helper_pacia(cpu_X[17], tcg_env, cpu_X[17], cpu_X[16]);
    }
    return true;
}

static bool trans_PACIB1716(DisasContext *s, arg_PACIB1716 *a)
{
    if (s->pauth_active) {
        gen_helper_pacib(cpu_X[17], tcg_env, cpu_X[17], cpu_X[16]);
    }
    return true;
}

static bool trans_AUTIA1716(DisasContext *s, arg_AUTIA1716 *a)
{
    if (s->pauth_active) {
        gen_helper_autia(cpu_X[17], tcg_env, cpu_X[17], cpu_X[16]);
    }
    return true;
}

static bool trans_AUTIB1716(DisasContext *s, arg_AUTIB1716 *a)
{
    if (s->pauth_active) {
        gen_helper_autib(cpu_X[17], tcg_env, cpu_X[17], cpu_X[16]);
    }
    return true;
}

static bool trans_ESB(DisasContext *s, arg_ESB *a)
{
    /* Without RAS, we must implement this as NOP. */
    if (dc_isar_feature(aa64_ras, s)) {
        /*
         * QEMU does not have a source of physical SErrors,
         * so we are only concerned with virtual SErrors.
         * The pseudocode in the ARM for this case is
         *   if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then
         *      AArch64.vESBOperation();
         * Most of the condition can be evaluated at translation time.
         * Test for EL2 present, and defer test for SEL2 to runtime.
         */
        if (s->current_el <= 1 && arm_dc_feature(s, ARM_FEATURE_EL2)) {
            gen_helper_vesb(tcg_env);
        }
    }
    return true;
}

static bool trans_PACIAZ(DisasContext *s, arg_PACIAZ *a)
{
    if (s->pauth_active) {
        gen_helper_pacia(cpu_X[30], tcg_env, cpu_X[30], tcg_constant_i64(0));
    }
    return true;
}

static bool trans_PACIASP(DisasContext *s, arg_PACIASP *a)
{
    if (s->pauth_active) {
        gen_helper_pacia(cpu_X[30], tcg_env, cpu_X[30], cpu_X[31]);
    }
    return true;
}

static bool trans_PACIBZ(DisasContext *s, arg_PACIBZ *a)
{
    if (s->pauth_active) {
        gen_helper_pacib(cpu_X[30], tcg_env, cpu_X[30], tcg_constant_i64(0));
    }
    return true;
}

static bool trans_PACIBSP(DisasContext *s, arg_PACIBSP *a)
{
    if (s->pauth_active) {
        gen_helper_pacib(cpu_X[30], tcg_env, cpu_X[30], cpu_X[31]);
    }
    return true;
}

static bool trans_AUTIAZ(DisasContext *s, arg_AUTIAZ *a)
{
    if (s->pauth_active) {
        gen_helper_autia(cpu_X[30], tcg_env, cpu_X[30], tcg_constant_i64(0));
    }
    return true;
}

static bool trans_AUTIASP(DisasContext *s, arg_AUTIASP *a)
{
    if (s->pauth_active) {
        gen_helper_autia(cpu_X[30], tcg_env, cpu_X[30], cpu_X[31]);
    }
    return true;
}

static bool trans_AUTIBZ(DisasContext *s, arg_AUTIBZ *a)
{
    if (s->pauth_active) {
        gen_helper_autib(cpu_X[30], tcg_env, cpu_X[30], tcg_constant_i64(0));
    }
    return true;
}

static bool trans_AUTIBSP(DisasContext *s, arg_AUTIBSP *a)
{
    if (s->pauth_active) {
        gen_helper_autib(cpu_X[30], tcg_env, cpu_X[30], cpu_X[31]);
    }
    return true;
}

static bool trans_CLREX(DisasContext *s, arg_CLREX *a)
{
    tcg_gen_movi_i64(cpu_exclusive_addr, -1);
    return true;
}

static bool trans_DSB_DMB(DisasContext *s, arg_DSB_DMB *a)
{
    /* We handle DSB and DMB the same way */
    TCGBar bar;

    switch (a->types) {
    case 1: /* MBReqTypes_Reads */
        bar = TCG_BAR_SC | TCG_MO_LD_LD | TCG_MO_LD_ST;
        break;
    case 2: /* MBReqTypes_Writes */
        bar = TCG_BAR_SC | TCG_MO_ST_ST;
        break;
    default: /* MBReqTypes_All */
        bar = TCG_BAR_SC | TCG_MO_ALL;
        break;
    }
    tcg_gen_mb(bar);
    return true;
}

static bool trans_ISB(DisasContext *s, arg_ISB *a)
{
    /*
     * We need to break the TB after this insn to execute
     * self-modifying code correctly and also to take
     * any pending interrupts immediately.
     */
    reset_btype(s);
    gen_goto_tb(s, 0, 4);
    return true;
}

static bool trans_SB(DisasContext *s, arg_SB *a)
{
    if (!dc_isar_feature(aa64_sb, s)) {
        return false;
    }
    /*
     * TODO: There is no speculation barrier opcode for TCG;
     * MB and end the TB instead.
     */
    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
    gen_goto_tb(s, 0, 4);
    return true;
}

static bool trans_CFINV(DisasContext *s, arg_CFINV *a)
{
    if (!dc_isar_feature(aa64_condm_4, s)) {
        return false;
    }
    tcg_gen_xori_i32(cpu_CF, cpu_CF, 1);
    return true;
}

static bool trans_XAFLAG(DisasContext *s, arg_XAFLAG *a)
{
    TCGv_i32 z;

    if (!dc_isar_feature(aa64_condm_5, s)) {
        return false;
    }

    z = tcg_temp_new_i32();

    tcg_gen_setcondi_i32(TCG_COND_EQ, z, cpu_ZF, 0);

    /*
     * (!C & !Z) << 31
     * (!(C | Z)) << 31
     * ~((C | Z) << 31)
     * ~-(C | Z)
     * (C | Z) - 1
     */
    tcg_gen_or_i32(cpu_NF, cpu_CF, z);
    tcg_gen_subi_i32(cpu_NF, cpu_NF, 1);

    /* !(Z & C) */
    tcg_gen_and_i32(cpu_ZF, z, cpu_CF);
    tcg_gen_xori_i32(cpu_ZF, cpu_ZF, 1);

    /* (!C & Z) << 31 -> -(Z & ~C) */
    tcg_gen_andc_i32(cpu_VF, z, cpu_CF);
    tcg_gen_neg_i32(cpu_VF, cpu_VF);

    /* C | Z */
    tcg_gen_or_i32(cpu_CF, cpu_CF, z);

    return true;
}

static bool trans_AXFLAG(DisasContext *s, arg_AXFLAG *a)
{
    if (!dc_isar_feature(aa64_condm_5, s)) {
        return false;
    }

    tcg_gen_sari_i32(cpu_VF, cpu_VF, 31);         /* V ? -1 : 0 */
    tcg_gen_andc_i32(cpu_CF, cpu_CF, cpu_VF);     /* C & !V */

    /* !(Z | V) -> !(!ZF | V) -> ZF & !V -> ZF & ~VF */
    tcg_gen_andc_i32(cpu_ZF, cpu_ZF, cpu_VF);

    tcg_gen_movi_i32(cpu_NF, 0);
    tcg_gen_movi_i32(cpu_VF, 0);

    return true;
}

static bool trans_MSR_i_UAO(DisasContext *s, arg_i *a)
{
    if (!dc_isar_feature(aa64_uao, s) || s->current_el == 0) {
        return false;
    }
    if (a->imm & 1) {
        set_pstate_bits(PSTATE_UAO);
    } else {
        clear_pstate_bits(PSTATE_UAO);
    }
    gen_rebuild_hflags(s);
    s->base.is_jmp = DISAS_TOO_MANY;
    return true;
}

static bool trans_MSR_i_PAN(DisasContext *s, arg_i *a)
{
    if (!dc_isar_feature(aa64_pan, s) || s->current_el == 0) {
        return false;
    }
    if (a->imm & 1) {
        set_pstate_bits(PSTATE_PAN);
    } else {
        clear_pstate_bits(PSTATE_PAN);
    }
    gen_rebuild_hflags(s);
    s->base.is_jmp = DISAS_TOO_MANY;
    return true;
}

static bool trans_MSR_i_SPSEL(DisasContext *s, arg_i *a)
{
    if (s->current_el == 0) {
        return false;
    }
    gen_helper_msr_i_spsel(tcg_env, tcg_constant_i32(a->imm & PSTATE_SP));
    s->base.is_jmp = DISAS_TOO_MANY;
    return true;
}

static bool trans_MSR_i_SBSS(DisasContext *s, arg_i *a)
{
    if (!dc_isar_feature(aa64_ssbs, s)) {
        return false;
    }
    if (a->imm & 1) {
        set_pstate_bits(PSTATE_SSBS);
    } else {
        clear_pstate_bits(PSTATE_SSBS);
    }
    /* Don't need to rebuild hflags since SSBS is a nop */
    s->base.is_jmp = DISAS_TOO_MANY;
    return true;
}

static bool trans_MSR_i_DIT(DisasContext *s, arg_i *a)
{
    if (!dc_isar_feature(aa64_dit, s)) {
        return false;
    }
    if (a->imm & 1) {
        set_pstate_bits(PSTATE_DIT);
    } else {
        clear_pstate_bits(PSTATE_DIT);
    }
    /* There's no need to rebuild hflags because DIT is a nop */
    s->base.is_jmp = DISAS_TOO_MANY;
    return true;
}

static bool trans_MSR_i_TCO(DisasContext *s, arg_i *a)
{
    if (dc_isar_feature(aa64_mte, s)) {
        /* Full MTE is enabled -- set the TCO bit as directed. */
        if (a->imm & 1) {
            set_pstate_bits(PSTATE_TCO);
        } else {
            clear_pstate_bits(PSTATE_TCO);
        }
        gen_rebuild_hflags(s);
        /* Many factors, including TCO, go into MTE_ACTIVE. */
        s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
        return true;
    } else if (dc_isar_feature(aa64_mte_insn_reg, s)) {
        /* Only "instructions accessible at EL0" -- PSTATE.TCO is WI.  */
        return true;
    } else {
        /* Insn not present */
        return false;
    }
}

static bool trans_MSR_i_DAIFSET(DisasContext *s, arg_i *a)
{
    gen_helper_msr_i_daifset(tcg_env, tcg_constant_i32(a->imm));
    s->base.is_jmp = DISAS_TOO_MANY;
    return true;
}

static bool trans_MSR_i_DAIFCLEAR(DisasContext *s, arg_i *a)
{
    gen_helper_msr_i_daifclear(tcg_env, tcg_constant_i32(a->imm));
    /* Exit the cpu loop to re-evaluate pending IRQs. */
    s->base.is_jmp = DISAS_UPDATE_EXIT;
    return true;
}

static bool trans_MSR_i_ALLINT(DisasContext *s, arg_i *a)
{
    if (!dc_isar_feature(aa64_nmi, s) || s->current_el == 0) {
        return false;
    }

    if (a->imm == 0) {
        clear_pstate_bits(PSTATE_ALLINT);
    } else if (s->current_el > 1) {
        set_pstate_bits(PSTATE_ALLINT);
    } else {
        gen_helper_msr_set_allint_el1(tcg_env);
    }

    /* Exit the cpu loop to re-evaluate pending IRQs. */
    s->base.is_jmp = DISAS_UPDATE_EXIT;
    return true;
}

static bool trans_MSR_i_SVCR(DisasContext *s, arg_MSR_i_SVCR *a)
{
    if (!dc_isar_feature(aa64_sme, s) || a->mask == 0) {
        return false;
    }
    if (sme_access_check(s)) {
        int old = s->pstate_sm | (s->pstate_za << 1);
        int new = a->imm * 3;

        if ((old ^ new) & a->mask) {
            /* At least one bit changes. */
            gen_helper_set_svcr(tcg_env, tcg_constant_i32(new),
                                tcg_constant_i32(a->mask));
            s->base.is_jmp = DISAS_TOO_MANY;
        }
    }
    return true;
}

static void gen_get_nzcv(TCGv_i64 tcg_rt)
{
    TCGv_i32 tmp = tcg_temp_new_i32();
    TCGv_i32 nzcv = tcg_temp_new_i32();

    /* build bit 31, N */
    tcg_gen_andi_i32(nzcv, cpu_NF, (1U << 31));
    /* build bit 30, Z */
    tcg_gen_setcondi_i32(TCG_COND_EQ, tmp, cpu_ZF, 0);
    tcg_gen_deposit_i32(nzcv, nzcv, tmp, 30, 1);
    /* build bit 29, C */
    tcg_gen_deposit_i32(nzcv, nzcv, cpu_CF, 29, 1);
    /* build bit 28, V */
    tcg_gen_shri_i32(tmp, cpu_VF, 31);
    tcg_gen_deposit_i32(nzcv, nzcv, tmp, 28, 1);
    /* generate result */
    tcg_gen_extu_i32_i64(tcg_rt, nzcv);
}

static void gen_set_nzcv(TCGv_i64 tcg_rt)
{
    TCGv_i32 nzcv = tcg_temp_new_i32();

    /* take NZCV from R[t] */
    tcg_gen_extrl_i64_i32(nzcv, tcg_rt);

    /* bit 31, N */
    tcg_gen_andi_i32(cpu_NF, nzcv, (1U << 31));
    /* bit 30, Z */
    tcg_gen_andi_i32(cpu_ZF, nzcv, (1 << 30));
    tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_ZF, cpu_ZF, 0);
    /* bit 29, C */
    tcg_gen_andi_i32(cpu_CF, nzcv, (1 << 29));
    tcg_gen_shri_i32(cpu_CF, cpu_CF, 29);
    /* bit 28, V */
    tcg_gen_andi_i32(cpu_VF, nzcv, (1 << 28));
    tcg_gen_shli_i32(cpu_VF, cpu_VF, 3);
}

static void gen_sysreg_undef(DisasContext *s, bool isread,
                             uint8_t op0, uint8_t op1, uint8_t op2,
                             uint8_t crn, uint8_t crm, uint8_t rt)
{
    /*
     * Generate code to emit an UNDEF with correct syndrome
     * information for a failed system register access.
     * This is EC_UNCATEGORIZED (ie a standard UNDEF) in most cases,
     * but if FEAT_IDST is implemented then read accesses to registers
     * in the feature ID space are reported with the EC_SYSTEMREGISTERTRAP
     * syndrome.
     */
    uint32_t syndrome;

    if (isread && dc_isar_feature(aa64_ids, s) &&
        arm_cpreg_encoding_in_idspace(op0, op1, op2, crn, crm)) {
        syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
    } else {
        syndrome = syn_uncategorized();
    }
    gen_exception_insn(s, 0, EXCP_UDEF, syndrome);
}

/* MRS - move from system register
 * MSR (register) - move to system register
 * SYS
 * SYSL
 * These are all essentially the same insn in 'read' and 'write'
 * versions, with varying op0 fields.
 */
static void handle_sys(DisasContext *s, bool isread,
                       unsigned int op0, unsigned int op1, unsigned int op2,
                       unsigned int crn, unsigned int crm, unsigned int rt)
{
    uint32_t key = ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
                                      crn, crm, op0, op1, op2);
    const ARMCPRegInfo *ri = get_arm_cp_reginfo(s->cp_regs, key);
    bool need_exit_tb = false;
    bool nv_trap_to_el2 = false;
    bool nv_redirect_reg = false;
    bool skip_fp_access_checks = false;
    bool nv2_mem_redirect = false;
    TCGv_ptr tcg_ri = NULL;
    TCGv_i64 tcg_rt;
    uint32_t syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);

    if (crn == 11 || crn == 15) {
        /*
         * Check for TIDCP trap, which must take precedence over
         * the UNDEF for "no such register" etc.
         */
        switch (s->current_el) {
        case 0:
            if (dc_isar_feature(aa64_tidcp1, s)) {
                gen_helper_tidcp_el0(tcg_env, tcg_constant_i32(syndrome));
            }
            break;
        case 1:
            gen_helper_tidcp_el1(tcg_env, tcg_constant_i32(syndrome));
            break;
        }
    }

    if (!ri) {
        /* Unknown register; this might be a guest error or a QEMU
         * unimplemented feature.
         */
        qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch64 "
                      "system register op0:%d op1:%d crn:%d crm:%d op2:%d\n",
                      isread ? "read" : "write", op0, op1, crn, crm, op2);
        gen_sysreg_undef(s, isread, op0, op1, op2, crn, crm, rt);
        return;
    }

    if (s->nv2 && ri->nv2_redirect_offset) {
        /*
         * Some registers always redirect to memory; some only do so if
         * HCR_EL2.NV1 is 0, and some only if NV1 is 1 (these come in
         * pairs which share an offset; see the table in R_CSRPQ).
         */
        if (ri->nv2_redirect_offset & NV2_REDIR_NV1) {
            nv2_mem_redirect = s->nv1;
        } else if (ri->nv2_redirect_offset & NV2_REDIR_NO_NV1) {
            nv2_mem_redirect = !s->nv1;
        } else {
            nv2_mem_redirect = true;
        }
    }

    /* Check access permissions */
    if (!cp_access_ok(s->current_el, ri, isread)) {
        /*
         * FEAT_NV/NV2 handling does not do the usual FP access checks
         * for registers only accessible at EL2 (though it *does* do them
         * for registers accessible at EL1).
         */
        skip_fp_access_checks = true;
        if (s->nv2 && (ri->type & ARM_CP_NV2_REDIRECT)) {
            /*
             * This is one of the few EL2 registers which should redirect
             * to the equivalent EL1 register. We do that after running
             * the EL2 register's accessfn.
             */
            nv_redirect_reg = true;
            assert(!nv2_mem_redirect);
        } else if (nv2_mem_redirect) {
            /*
             * NV2 redirect-to-memory takes precedence over trap to EL2 or
             * UNDEF to EL1.
             */
        } else if (s->nv && arm_cpreg_traps_in_nv(ri)) {
            /*
             * This register / instruction exists and is an EL2 register, so
             * we must trap to EL2 if accessed in nested virtualization EL1
             * instead of UNDEFing. We'll do that after the usual access checks.
             * (This makes a difference only for a couple of registers like
             * VSTTBR_EL2 where the "UNDEF if NonSecure" should take priority
             * over the trap-to-EL2. Most trapped-by-FEAT_NV registers have
             * an accessfn which does nothing when called from EL1, because
             * the trap-to-EL3 controls which would apply to that register
             * at EL2 don't take priority over the FEAT_NV trap-to-EL2.)
             */
            nv_trap_to_el2 = true;
        } else {
            gen_sysreg_undef(s, isread, op0, op1, op2, crn, crm, rt);
            return;
        }
    }

    if (ri->accessfn || (ri->fgt && s->fgt_active)) {
        /* Emit code to perform further access permissions checks at
         * runtime; this may result in an exception.
         */
        gen_a64_update_pc(s, 0);
        tcg_ri = tcg_temp_new_ptr();
        gen_helper_access_check_cp_reg(tcg_ri, tcg_env,
                                       tcg_constant_i32(key),
                                       tcg_constant_i32(syndrome),
                                       tcg_constant_i32(isread));
    } else if (ri->type & ARM_CP_RAISES_EXC) {
        /*
         * The readfn or writefn might raise an exception;
         * synchronize the CPU state in case it does.
         */
        gen_a64_update_pc(s, 0);
    }

    if (!skip_fp_access_checks) {
        if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
            return;
        } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
            return;
        } else if ((ri->type & ARM_CP_SME) && !sme_access_check(s)) {
            return;
        }
    }

    if (nv_trap_to_el2) {
        gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
        return;
    }

    if (nv_redirect_reg) {
        /*
         * FEAT_NV2 redirection of an EL2 register to an EL1 register.
         * Conveniently in all cases the encoding of the EL1 register is
         * identical to the EL2 register except that opc1 is 0.
         * Get the reginfo for the EL1 register to use for the actual access.
         * We don't use the EL1 register's access function, and
         * fine-grained-traps on EL1 also do not apply here.
         */
        key = ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
                                 crn, crm, op0, 0, op2);
        ri = get_arm_cp_reginfo(s->cp_regs, key);
        assert(ri);
        assert(cp_access_ok(s->current_el, ri, isread));
        /*
         * We might not have done an update_pc earlier, so check we don't
         * need it. We could support this in future if necessary.
         */
        assert(!(ri->type & ARM_CP_RAISES_EXC));
    }

    if (nv2_mem_redirect) {
        /*
         * This system register is being redirected into an EL2 memory access.
         * This means it is not an IO operation, doesn't change hflags,
         * and need not end the TB, because it has no side effects.
         *
         * The access is 64-bit single copy atomic, guaranteed aligned because
         * of the definition of VCNR_EL2. Its endianness depends on
         * SCTLR_EL2.EE, not on the data endianness of EL1.
         * It is done under either the EL2 translation regime or the EL2&0
         * translation regime, depending on HCR_EL2.E2H. It behaves as if
         * PSTATE.PAN is 0.
         */
        TCGv_i64 ptr = tcg_temp_new_i64();
        MemOp mop = MO_64 | MO_ALIGN | MO_ATOM_IFALIGN;
        ARMMMUIdx armmemidx = s->nv2_mem_e20 ? ARMMMUIdx_E20_2 : ARMMMUIdx_E2;
        int memidx = arm_to_core_mmu_idx(armmemidx);
        uint32_t syn;

        mop |= (s->nv2_mem_be ? MO_BE : MO_LE);

        tcg_gen_ld_i64(ptr, tcg_env, offsetof(CPUARMState, cp15.vncr_el2));
        tcg_gen_addi_i64(ptr, ptr,
                         (ri->nv2_redirect_offset & ~NV2_REDIR_FLAG_MASK));
        tcg_rt = cpu_reg(s, rt);

        syn = syn_data_abort_vncr(0, !isread, 0);
        disas_set_insn_syndrome(s, syn);
        if (isread) {
            tcg_gen_qemu_ld_i64(tcg_rt, ptr, memidx, mop);
        } else {
            tcg_gen_qemu_st_i64(tcg_rt, ptr, memidx, mop);
        }
        return;
    }

    /* Handle special cases first */
    switch (ri->type & ARM_CP_SPECIAL_MASK) {
    case 0:
        break;
    case ARM_CP_NOP:
        return;
    case ARM_CP_NZCV:
        tcg_rt = cpu_reg(s, rt);
        if (isread) {
            gen_get_nzcv(tcg_rt);
        } else {
            gen_set_nzcv(tcg_rt);
        }
        return;
    case ARM_CP_CURRENTEL:
    {
        /*
         * Reads as current EL value from pstate, which is
         * guaranteed to be constant by the tb flags.
         * For nested virt we should report EL2.
         */
        int el = s->nv ? 2 : s->current_el;
        tcg_rt = cpu_reg(s, rt);
        tcg_gen_movi_i64(tcg_rt, el << 2);
        return;
    }
    case ARM_CP_DC_ZVA:
        /* Writes clear the aligned block of memory which rt points into. */
        if (s->mte_active[0]) {
            int desc = 0;

            desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
            desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
            desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);

            tcg_rt = tcg_temp_new_i64();
            gen_helper_mte_check_zva(tcg_rt, tcg_env,
                                     tcg_constant_i32(desc), cpu_reg(s, rt));
        } else {
            tcg_rt = clean_data_tbi(s, cpu_reg(s, rt));
        }
        gen_helper_dc_zva(tcg_env, tcg_rt);
        return;
    case ARM_CP_DC_GVA:
        {
            TCGv_i64 clean_addr, tag;

            /*
             * DC_GVA, like DC_ZVA, requires that we supply the original
             * pointer for an invalid page.  Probe that address first.
             */
            tcg_rt = cpu_reg(s, rt);
            clean_addr = clean_data_tbi(s, tcg_rt);
            gen_probe_access(s, clean_addr, MMU_DATA_STORE, MO_8);

            if (s->ata[0]) {
                /* Extract the tag from the register to match STZGM.  */
                tag = tcg_temp_new_i64();
                tcg_gen_shri_i64(tag, tcg_rt, 56);
                gen_helper_stzgm_tags(tcg_env, clean_addr, tag);
            }
        }
        return;
    case ARM_CP_DC_GZVA:
        {
            TCGv_i64 clean_addr, tag;

            /* For DC_GZVA, we can rely on DC_ZVA for the proper fault. */
            tcg_rt = cpu_reg(s, rt);
            clean_addr = clean_data_tbi(s, tcg_rt);
            gen_helper_dc_zva(tcg_env, clean_addr);

            if (s->ata[0]) {
                /* Extract the tag from the register to match STZGM.  */
                tag = tcg_temp_new_i64();
                tcg_gen_shri_i64(tag, tcg_rt, 56);
                gen_helper_stzgm_tags(tcg_env, clean_addr, tag);
            }
        }
        return;
    default:
        g_assert_not_reached();
    }

    if (ri->type & ARM_CP_IO) {
        /* I/O operations must end the TB here (whether read or write) */
        need_exit_tb = translator_io_start(&s->base);
    }

    tcg_rt = cpu_reg(s, rt);

    if (isread) {
        if (ri->type & ARM_CP_CONST) {
            tcg_gen_movi_i64(tcg_rt, ri->resetvalue);
        } else if (ri->readfn) {
            if (!tcg_ri) {
                tcg_ri = gen_lookup_cp_reg(key);
            }
            gen_helper_get_cp_reg64(tcg_rt, tcg_env, tcg_ri);
        } else {
            tcg_gen_ld_i64(tcg_rt, tcg_env, ri->fieldoffset);
        }
    } else {
        if (ri->type & ARM_CP_CONST) {
            /* If not forbidden by access permissions, treat as WI */
            return;
        } else if (ri->writefn) {
            if (!tcg_ri) {
                tcg_ri = gen_lookup_cp_reg(key);
            }
            gen_helper_set_cp_reg64(tcg_env, tcg_ri, tcg_rt);
        } else {
            tcg_gen_st_i64(tcg_rt, tcg_env, ri->fieldoffset);
        }
    }

    if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
        /*
         * A write to any coprocessor register that ends a TB
         * must rebuild the hflags for the next TB.
         */
        gen_rebuild_hflags(s);
        /*
         * We default to ending the TB on a coprocessor register write,
         * but allow this to be suppressed by the register definition
         * (usually only necessary to work around guest bugs).
         */
        need_exit_tb = true;
    }
    if (need_exit_tb) {
        s->base.is_jmp = DISAS_UPDATE_EXIT;
    }
}

static bool trans_SYS(DisasContext *s, arg_SYS *a)
{
    handle_sys(s, a->l, a->op0, a->op1, a->op2, a->crn, a->crm, a->rt);
    return true;
}

static bool trans_SVC(DisasContext *s, arg_i *a)
{
    /*
     * For SVC, HVC and SMC we advance the single-step state
     * machine before taking the exception. This is architecturally
     * mandated, to ensure that single-stepping a system call
     * instruction works properly.
     */
    uint32_t syndrome = syn_aa64_svc(a->imm);
    if (s->fgt_svc) {
        gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
        return true;
    }
    gen_ss_advance(s);
    gen_exception_insn(s, 4, EXCP_SWI, syndrome);
    return true;
}

static bool trans_HVC(DisasContext *s, arg_i *a)
{
    int target_el = s->current_el == 3 ? 3 : 2;

    if (s->current_el == 0) {
        unallocated_encoding(s);
        return true;
    }
    /*
     * The pre HVC helper handles cases when HVC gets trapped
     * as an undefined insn by runtime configuration.
     */
    gen_a64_update_pc(s, 0);
    gen_helper_pre_hvc(tcg_env);
    /* Architecture requires ss advance before we do the actual work */
    gen_ss_advance(s);
    gen_exception_insn_el(s, 4, EXCP_HVC, syn_aa64_hvc(a->imm), target_el);
    return true;
}

static bool trans_SMC(DisasContext *s, arg_i *a)
{
    if (s->current_el == 0) {
        unallocated_encoding(s);
        return true;
    }
    gen_a64_update_pc(s, 0);
    gen_helper_pre_smc(tcg_env, tcg_constant_i32(syn_aa64_smc(a->imm)));
    /* Architecture requires ss advance before we do the actual work */
    gen_ss_advance(s);
    gen_exception_insn_el(s, 4, EXCP_SMC, syn_aa64_smc(a->imm), 3);
    return true;
}

static bool trans_BRK(DisasContext *s, arg_i *a)
{
    gen_exception_bkpt_insn(s, syn_aa64_bkpt(a->imm));
    return true;
}

static bool trans_HLT(DisasContext *s, arg_i *a)
{
    /*
     * HLT. This has two purposes.
     * Architecturally, it is an external halting debug instruction.
     * Since QEMU doesn't implement external debug, we treat this as
     * it is required for halting debug disabled: it will UNDEF.
     * Secondly, "HLT 0xf000" is the A64 semihosting syscall instruction.
     */
    if (semihosting_enabled(s->current_el == 0) && a->imm == 0xf000) {
        gen_exception_internal_insn(s, EXCP_SEMIHOST);
    } else {
        unallocated_encoding(s);
    }
    return true;
}

/*
 * Load/Store exclusive instructions are implemented by remembering
 * the value/address loaded, and seeing if these are the same
 * when the store is performed. This is not actually the architecturally
 * mandated semantics, but it works for typical guest code sequences
 * and avoids having to monitor regular stores.
 *
 * The store exclusive uses the atomic cmpxchg primitives to avoid
 * races in multi-threaded linux-user and when MTTCG softmmu is
 * enabled.
 */
static void gen_load_exclusive(DisasContext *s, int rt, int rt2, int rn,
                               int size, bool is_pair)
{
    int idx = get_mem_index(s);
    TCGv_i64 dirty_addr, clean_addr;
    MemOp memop = check_atomic_align(s, rn, size + is_pair);

    s->is_ldex = true;
    dirty_addr = cpu_reg_sp(s, rn);
    clean_addr = gen_mte_check1(s, dirty_addr, false, rn != 31, memop);

    g_assert(size <= 3);
    if (is_pair) {
        g_assert(size >= 2);
        if (size == 2) {
            tcg_gen_qemu_ld_i64(cpu_exclusive_val, clean_addr, idx, memop);
            if (s->be_data == MO_LE) {
                tcg_gen_extract_i64(cpu_reg(s, rt), cpu_exclusive_val, 0, 32);
                tcg_gen_extract_i64(cpu_reg(s, rt2), cpu_exclusive_val, 32, 32);
            } else {
                tcg_gen_extract_i64(cpu_reg(s, rt), cpu_exclusive_val, 32, 32);
                tcg_gen_extract_i64(cpu_reg(s, rt2), cpu_exclusive_val, 0, 32);
            }
        } else {
            TCGv_i128 t16 = tcg_temp_new_i128();

            tcg_gen_qemu_ld_i128(t16, clean_addr, idx, memop);

            if (s->be_data == MO_LE) {
                tcg_gen_extr_i128_i64(cpu_exclusive_val,
                                      cpu_exclusive_high, t16);
            } else {
                tcg_gen_extr_i128_i64(cpu_exclusive_high,
                                      cpu_exclusive_val, t16);
            }
            tcg_gen_mov_i64(cpu_reg(s, rt), cpu_exclusive_val);
            tcg_gen_mov_i64(cpu_reg(s, rt2), cpu_exclusive_high);
        }
    } else {
        tcg_gen_qemu_ld_i64(cpu_exclusive_val, clean_addr, idx, memop);
        tcg_gen_mov_i64(cpu_reg(s, rt), cpu_exclusive_val);
    }
    tcg_gen_mov_i64(cpu_exclusive_addr, clean_addr);
}

static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
                                int rn, int size, int is_pair)
{
    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]
     *     && (!is_pair || env->exclusive_high == [addr + datasize])) {
     *     [addr] = {Rt};
     *     if (is_pair) {
     *         [addr + datasize] = {Rt2};
     *     }
     *     {Rd} = 0;
     * } else {
     *     {Rd} = 1;
     * }
     * env->exclusive_addr = -1;
     */
    TCGLabel *fail_label = gen_new_label();
    TCGLabel *done_label = gen_new_label();
    TCGv_i64 tmp, clean_addr;
    MemOp memop;

    /*
     * FIXME: We are out of spec here.  We have recorded only the address
     * from load_exclusive, not the entire range, and we assume that the
     * size of the access on both sides match.  The architecture allows the
     * store to be smaller than the load, so long as the stored bytes are
     * within the range recorded by the load.
     */

    /* See AArch64.ExclusiveMonitorsPass() and AArch64.IsExclusiveVA(). */
    clean_addr = clean_data_tbi(s, cpu_reg_sp(s, rn));
    tcg_gen_brcond_i64(TCG_COND_NE, clean_addr, cpu_exclusive_addr, fail_label);

    /*
     * The write, and any associated faults, only happen if the virtual
     * and physical addresses pass the exclusive monitor check.  These
     * faults are exceedingly unlikely, because normally the guest uses
     * the exact same address register for the load_exclusive, and we
     * would have recognized these faults there.
     *
     * It is possible to trigger an alignment fault pre-LSE2, e.g. with an
     * unaligned 4-byte write within the range of an aligned 8-byte load.
     * With LSE2, the store would need to cross a 16-byte boundary when the
     * load did not, which would mean the store is outside the range
     * recorded for the monitor, which would have failed a corrected monitor
     * check above.  For now, we assume no size change and retain the
     * MO_ALIGN to let tcg know what we checked in the load_exclusive.
     *
     * It is possible to trigger an MTE fault, by performing the load with
     * a virtual address with a valid tag and performing the store with the
     * same virtual address and a different invalid tag.
     */
    memop = size + is_pair;
    if (memop == MO_128 || !dc_isar_feature(aa64_lse2, s)) {
        memop |= MO_ALIGN;
    }
    memop = finalize_memop(s, memop);
    gen_mte_check1(s, cpu_reg_sp(s, rn), true, rn != 31, memop);

    tmp = tcg_temp_new_i64();
    if (is_pair) {
        if (size == 2) {
            if (s->be_data == MO_LE) {
                tcg_gen_concat32_i64(tmp, cpu_reg(s, rt), cpu_reg(s, rt2));
            } else {
                tcg_gen_concat32_i64(tmp, cpu_reg(s, rt2), cpu_reg(s, rt));
            }
            tcg_gen_atomic_cmpxchg_i64(tmp, cpu_exclusive_addr,
                                       cpu_exclusive_val, tmp,
                                       get_mem_index(s), memop);
            tcg_gen_setcond_i64(TCG_COND_NE, tmp, tmp, cpu_exclusive_val);
        } else {
            TCGv_i128 t16 = tcg_temp_new_i128();
            TCGv_i128 c16 = tcg_temp_new_i128();
            TCGv_i64 a, b;

            if (s->be_data == MO_LE) {
                tcg_gen_concat_i64_i128(t16, cpu_reg(s, rt), cpu_reg(s, rt2));
                tcg_gen_concat_i64_i128(c16, cpu_exclusive_val,
                                        cpu_exclusive_high);
            } else {
                tcg_gen_concat_i64_i128(t16, cpu_reg(s, rt2), cpu_reg(s, rt));
                tcg_gen_concat_i64_i128(c16, cpu_exclusive_high,
                                        cpu_exclusive_val);
            }

            tcg_gen_atomic_cmpxchg_i128(t16, cpu_exclusive_addr, c16, t16,
                                        get_mem_index(s), memop);

            a = tcg_temp_new_i64();
            b = tcg_temp_new_i64();
            if (s->be_data == MO_LE) {
                tcg_gen_extr_i128_i64(a, b, t16);
            } else {
                tcg_gen_extr_i128_i64(b, a, t16);
            }

            tcg_gen_xor_i64(a, a, cpu_exclusive_val);
            tcg_gen_xor_i64(b, b, cpu_exclusive_high);
            tcg_gen_or_i64(tmp, a, b);

            tcg_gen_setcondi_i64(TCG_COND_NE, tmp, tmp, 0);
        }
    } else {
        tcg_gen_atomic_cmpxchg_i64(tmp, cpu_exclusive_addr, cpu_exclusive_val,
                                   cpu_reg(s, rt), get_mem_index(s), memop);
        tcg_gen_setcond_i64(TCG_COND_NE, tmp, tmp, cpu_exclusive_val);
    }
    tcg_gen_mov_i64(cpu_reg(s, rd), tmp);
    tcg_gen_br(done_label);

    gen_set_label(fail_label);
    tcg_gen_movi_i64(cpu_reg(s, rd), 1);
    gen_set_label(done_label);
    tcg_gen_movi_i64(cpu_exclusive_addr, -1);
}

static void gen_compare_and_swap(DisasContext *s, int rs, int rt,
                                 int rn, int size)
{
    TCGv_i64 tcg_rs = cpu_reg(s, rs);
    TCGv_i64 tcg_rt = cpu_reg(s, rt);
    int memidx = get_mem_index(s);
    TCGv_i64 clean_addr;
    MemOp memop;

    if (rn == 31) {
        gen_check_sp_alignment(s);
    }
    memop = check_atomic_align(s, rn, size);
    clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn), true, rn != 31, memop);
    tcg_gen_atomic_cmpxchg_i64(tcg_rs, clean_addr, tcg_rs, tcg_rt,
                               memidx, memop);
}

static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt,
                                      int rn, int size)
{
    TCGv_i64 s1 = cpu_reg(s, rs);
    TCGv_i64 s2 = cpu_reg(s, rs + 1);
    TCGv_i64 t1 = cpu_reg(s, rt);
    TCGv_i64 t2 = cpu_reg(s, rt + 1);
    TCGv_i64 clean_addr;
    int memidx = get_mem_index(s);
    MemOp memop;

    if (rn == 31) {
        gen_check_sp_alignment(s);
    }

    /* This is a single atomic access, despite the "pair". */
    memop = check_atomic_align(s, rn, size + 1);
    clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn), true, rn != 31, memop);

    if (size == 2) {
        TCGv_i64 cmp = tcg_temp_new_i64();
        TCGv_i64 val = tcg_temp_new_i64();

        if (s->be_data == MO_LE) {
            tcg_gen_concat32_i64(val, t1, t2);
            tcg_gen_concat32_i64(cmp, s1, s2);
        } else {
            tcg_gen_concat32_i64(val, t2, t1);
            tcg_gen_concat32_i64(cmp, s2, s1);
        }

        tcg_gen_atomic_cmpxchg_i64(cmp, clean_addr, cmp, val, memidx, memop);

        if (s->be_data == MO_LE) {
            tcg_gen_extr32_i64(s1, s2, cmp);
        } else {
            tcg_gen_extr32_i64(s2, s1, cmp);
        }
    } else {
        TCGv_i128 cmp = tcg_temp_new_i128();
        TCGv_i128 val = tcg_temp_new_i128();

        if (s->be_data == MO_LE) {
            tcg_gen_concat_i64_i128(val, t1, t2);
            tcg_gen_concat_i64_i128(cmp, s1, s2);
        } else {
            tcg_gen_concat_i64_i128(val, t2, t1);
            tcg_gen_concat_i64_i128(cmp, s2, s1);
        }

        tcg_gen_atomic_cmpxchg_i128(cmp, clean_addr, cmp, val, memidx, memop);

        if (s->be_data == MO_LE) {
            tcg_gen_extr_i128_i64(s1, s2, cmp);
        } else {
            tcg_gen_extr_i128_i64(s2, s1, cmp);
        }
    }
}

/*
 * Compute the ISS.SF bit for syndrome information if an exception
 * is taken on a load or store. This indicates whether the instruction
 * is accessing a 32-bit or 64-bit register. This logic is derived
 * from the ARMv8 specs for LDR (Shared decode for all encodings).
 */
static bool ldst_iss_sf(int size, bool sign, bool ext)
{

    if (sign) {
        /*
         * Signed loads are 64 bit results if we are not going to
         * do a zero-extend from 32 to 64 after the load.
         * (For a store, sign and ext are always false.)
         */
        return !ext;
    } else {
        /* Unsigned loads/stores work at the specified size */
        return size == MO_64;
    }
}

static bool trans_STXR(DisasContext *s, arg_stxr *a)
{
    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }
    if (a->lasr) {
        tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
    }
    gen_store_exclusive(s, a->rs, a->rt, a->rt2, a->rn, a->sz, false);
    return true;
}

static bool trans_LDXR(DisasContext *s, arg_stxr *a)
{
    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }
    gen_load_exclusive(s, a->rt, a->rt2, a->rn, a->sz, false);
    if (a->lasr) {
        tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
    }
    return true;
}

static bool trans_STLR(DisasContext *s, arg_stlr *a)
{
    TCGv_i64 clean_addr;
    MemOp memop;
    bool iss_sf = ldst_iss_sf(a->sz, false, false);

    /*
     * StoreLORelease is the same as Store-Release for QEMU, but
     * needs the feature-test.
     */
    if (!a->lasr && !dc_isar_feature(aa64_lor, s)) {
        return false;
    }
    /* Generate ISS for non-exclusive accesses including LASR.  */
    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }
    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
    memop = check_ordered_align(s, a->rn, 0, true, a->sz);
    clean_addr = gen_mte_check1(s, cpu_reg_sp(s, a->rn),
                                true, a->rn != 31, memop);
    do_gpr_st(s, cpu_reg(s, a->rt), clean_addr, memop, true, a->rt,
              iss_sf, a->lasr);
    return true;
}

static bool trans_LDAR(DisasContext *s, arg_stlr *a)
{
    TCGv_i64 clean_addr;
    MemOp memop;
    bool iss_sf = ldst_iss_sf(a->sz, false, false);

    /* LoadLOAcquire is the same as Load-Acquire for QEMU.  */
    if (!a->lasr && !dc_isar_feature(aa64_lor, s)) {
        return false;
    }
    /* Generate ISS for non-exclusive accesses including LASR.  */
    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }
    memop = check_ordered_align(s, a->rn, 0, false, a->sz);
    clean_addr = gen_mte_check1(s, cpu_reg_sp(s, a->rn),
                                false, a->rn != 31, memop);
    do_gpr_ld(s, cpu_reg(s, a->rt), clean_addr, memop, false, true,
              a->rt, iss_sf, a->lasr);
    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
    return true;
}

static bool trans_STXP(DisasContext *s, arg_stxr *a)
{
    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }
    if (a->lasr) {
        tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
    }
    gen_store_exclusive(s, a->rs, a->rt, a->rt2, a->rn, a->sz, true);
    return true;
}

static bool trans_LDXP(DisasContext *s, arg_stxr *a)
{
    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }
    gen_load_exclusive(s, a->rt, a->rt2, a->rn, a->sz, true);
    if (a->lasr) {
        tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
    }
    return true;
}

static bool trans_CASP(DisasContext *s, arg_CASP *a)
{
    if (!dc_isar_feature(aa64_atomics, s)) {
        return false;
    }
    if (((a->rt | a->rs) & 1) != 0) {
        return false;
    }

    gen_compare_and_swap_pair(s, a->rs, a->rt, a->rn, a->sz);
    return true;
}

static bool trans_CAS(DisasContext *s, arg_CAS *a)
{
    if (!dc_isar_feature(aa64_atomics, s)) {
        return false;
    }
    gen_compare_and_swap(s, a->rs, a->rt, a->rn, a->sz);
    return true;
}

static bool trans_LD_lit(DisasContext *s, arg_ldlit *a)
{
    bool iss_sf = ldst_iss_sf(a->sz, a->sign, false);
    TCGv_i64 tcg_rt = cpu_reg(s, a->rt);
    TCGv_i64 clean_addr = tcg_temp_new_i64();
    MemOp memop = finalize_memop(s, a->sz + a->sign * MO_SIGN);

    gen_pc_plus_diff(s, clean_addr, a->imm);
    do_gpr_ld(s, tcg_rt, clean_addr, memop,
              false, true, a->rt, iss_sf, false);
    return true;
}

static bool trans_LD_lit_v(DisasContext *s, arg_ldlit *a)
{
    /* Load register (literal), vector version */
    TCGv_i64 clean_addr;
    MemOp memop;

    if (!fp_access_check(s)) {
        return true;
    }
    memop = finalize_memop_asimd(s, a->sz);
    clean_addr = tcg_temp_new_i64();
    gen_pc_plus_diff(s, clean_addr, a->imm);
    do_fp_ld(s, a->rt, clean_addr, memop);
    return true;
}

static void op_addr_ldstpair_pre(DisasContext *s, arg_ldstpair *a,
                                 TCGv_i64 *clean_addr, TCGv_i64 *dirty_addr,
                                 uint64_t offset, bool is_store, MemOp mop)
{
    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    *dirty_addr = read_cpu_reg_sp(s, a->rn, 1);
    if (!a->p) {
        tcg_gen_addi_i64(*dirty_addr, *dirty_addr, offset);
    }

    *clean_addr = gen_mte_checkN(s, *dirty_addr, is_store,
                                 (a->w || a->rn != 31), 2 << a->sz, mop);
}

static void op_addr_ldstpair_post(DisasContext *s, arg_ldstpair *a,
                                  TCGv_i64 dirty_addr, uint64_t offset)
{
    if (a->w) {
        if (a->p) {
            tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
        }
        tcg_gen_mov_i64(cpu_reg_sp(s, a->rn), dirty_addr);
    }
}

static bool trans_STP(DisasContext *s, arg_ldstpair *a)
{
    uint64_t offset = a->imm << a->sz;
    TCGv_i64 clean_addr, dirty_addr, tcg_rt, tcg_rt2;
    MemOp mop = finalize_memop(s, a->sz);

    op_addr_ldstpair_pre(s, a, &clean_addr, &dirty_addr, offset, true, mop);
    tcg_rt = cpu_reg(s, a->rt);
    tcg_rt2 = cpu_reg(s, a->rt2);
    /*
     * We built mop above for the single logical access -- rebuild it
     * now for the paired operation.
     *
     * With LSE2, non-sign-extending pairs are treated atomically if
     * aligned, and if unaligned one of the pair will be completely
     * within a 16-byte block and that element will be atomic.
     * Otherwise each element is separately atomic.
     * In all cases, issue one operation with the correct atomicity.
     */
    mop = a->sz + 1;
    if (s->align_mem) {
        mop |= (a->sz == 2 ? MO_ALIGN_4 : MO_ALIGN_8);
    }
    mop = finalize_memop_pair(s, mop);
    if (a->sz == 2) {
        TCGv_i64 tmp = tcg_temp_new_i64();

        if (s->be_data == MO_LE) {
            tcg_gen_concat32_i64(tmp, tcg_rt, tcg_rt2);
        } else {
            tcg_gen_concat32_i64(tmp, tcg_rt2, tcg_rt);
        }
        tcg_gen_qemu_st_i64(tmp, clean_addr, get_mem_index(s), mop);
    } else {
        TCGv_i128 tmp = tcg_temp_new_i128();

        if (s->be_data == MO_LE) {
            tcg_gen_concat_i64_i128(tmp, tcg_rt, tcg_rt2);
        } else {
            tcg_gen_concat_i64_i128(tmp, tcg_rt2, tcg_rt);
        }
        tcg_gen_qemu_st_i128(tmp, clean_addr, get_mem_index(s), mop);
    }
    op_addr_ldstpair_post(s, a, dirty_addr, offset);
    return true;
}

static bool trans_LDP(DisasContext *s, arg_ldstpair *a)
{
    uint64_t offset = a->imm << a->sz;
    TCGv_i64 clean_addr, dirty_addr, tcg_rt, tcg_rt2;
    MemOp mop = finalize_memop(s, a->sz);

    op_addr_ldstpair_pre(s, a, &clean_addr, &dirty_addr, offset, false, mop);
    tcg_rt = cpu_reg(s, a->rt);
    tcg_rt2 = cpu_reg(s, a->rt2);

    /*
     * We built mop above for the single logical access -- rebuild it
     * now for the paired operation.
     *
     * With LSE2, non-sign-extending pairs are treated atomically if
     * aligned, and if unaligned one of the pair will be completely
     * within a 16-byte block and that element will be atomic.
     * Otherwise each element is separately atomic.
     * In all cases, issue one operation with the correct atomicity.
     *
     * This treats sign-extending loads like zero-extending loads,
     * since that reuses the most code below.
     */
    mop = a->sz + 1;
    if (s->align_mem) {
        mop |= (a->sz == 2 ? MO_ALIGN_4 : MO_ALIGN_8);
    }
    mop = finalize_memop_pair(s, mop);
    if (a->sz == 2) {
        int o2 = s->be_data == MO_LE ? 32 : 0;
        int o1 = o2 ^ 32;

        tcg_gen_qemu_ld_i64(tcg_rt, clean_addr, get_mem_index(s), mop);
        if (a->sign) {
            tcg_gen_sextract_i64(tcg_rt2, tcg_rt, o2, 32);
            tcg_gen_sextract_i64(tcg_rt, tcg_rt, o1, 32);
        } else {
            tcg_gen_extract_i64(tcg_rt2, tcg_rt, o2, 32);
            tcg_gen_extract_i64(tcg_rt, tcg_rt, o1, 32);
        }
    } else {
        TCGv_i128 tmp = tcg_temp_new_i128();

        tcg_gen_qemu_ld_i128(tmp, clean_addr, get_mem_index(s), mop);
        if (s->be_data == MO_LE) {
            tcg_gen_extr_i128_i64(tcg_rt, tcg_rt2, tmp);
        } else {
            tcg_gen_extr_i128_i64(tcg_rt2, tcg_rt, tmp);
        }
    }
    op_addr_ldstpair_post(s, a, dirty_addr, offset);
    return true;
}

static bool trans_STP_v(DisasContext *s, arg_ldstpair *a)
{
    uint64_t offset = a->imm << a->sz;
    TCGv_i64 clean_addr, dirty_addr;
    MemOp mop;

    if (!fp_access_check(s)) {
        return true;
    }

    /* LSE2 does not merge FP pairs; leave these as separate operations. */
    mop = finalize_memop_asimd(s, a->sz);
    op_addr_ldstpair_pre(s, a, &clean_addr, &dirty_addr, offset, true, mop);
    do_fp_st(s, a->rt, clean_addr, mop);
    tcg_gen_addi_i64(clean_addr, clean_addr, 1 << a->sz);
    do_fp_st(s, a->rt2, clean_addr, mop);
    op_addr_ldstpair_post(s, a, dirty_addr, offset);
    return true;
}

static bool trans_LDP_v(DisasContext *s, arg_ldstpair *a)
{
    uint64_t offset = a->imm << a->sz;
    TCGv_i64 clean_addr, dirty_addr;
    MemOp mop;

    if (!fp_access_check(s)) {
        return true;
    }

    /* LSE2 does not merge FP pairs; leave these as separate operations. */
    mop = finalize_memop_asimd(s, a->sz);
    op_addr_ldstpair_pre(s, a, &clean_addr, &dirty_addr, offset, false, mop);
    do_fp_ld(s, a->rt, clean_addr, mop);
    tcg_gen_addi_i64(clean_addr, clean_addr, 1 << a->sz);
    do_fp_ld(s, a->rt2, clean_addr, mop);
    op_addr_ldstpair_post(s, a, dirty_addr, offset);
    return true;
}

static bool trans_STGP(DisasContext *s, arg_ldstpair *a)
{
    TCGv_i64 clean_addr, dirty_addr, tcg_rt, tcg_rt2;
    uint64_t offset = a->imm << LOG2_TAG_GRANULE;
    MemOp mop;
    TCGv_i128 tmp;

    /* STGP only comes in one size. */
    tcg_debug_assert(a->sz == MO_64);

    if (!dc_isar_feature(aa64_mte_insn_reg, s)) {
        return false;
    }

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    dirty_addr = read_cpu_reg_sp(s, a->rn, 1);
    if (!a->p) {
        tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
    }

    clean_addr = clean_data_tbi(s, dirty_addr);
    tcg_rt = cpu_reg(s, a->rt);
    tcg_rt2 = cpu_reg(s, a->rt2);

    /*
     * STGP is defined as two 8-byte memory operations, aligned to TAG_GRANULE,
     * and one tag operation.  We implement it as one single aligned 16-byte
     * memory operation for convenience.  Note that the alignment ensures
     * MO_ATOM_IFALIGN_PAIR produces 8-byte atomicity for the memory store.
     */
    mop = finalize_memop_atom(s, MO_128 | MO_ALIGN, MO_ATOM_IFALIGN_PAIR);

    tmp = tcg_temp_new_i128();
    if (s->be_data == MO_LE) {
        tcg_gen_concat_i64_i128(tmp, tcg_rt, tcg_rt2);
    } else {
        tcg_gen_concat_i64_i128(tmp, tcg_rt2, tcg_rt);
    }
    tcg_gen_qemu_st_i128(tmp, clean_addr, get_mem_index(s), mop);

    /* Perform the tag store, if tag access enabled. */
    if (s->ata[0]) {
        if (tb_cflags(s->base.tb) & CF_PARALLEL) {
            gen_helper_stg_parallel(tcg_env, dirty_addr, dirty_addr);
        } else {
            gen_helper_stg(tcg_env, dirty_addr, dirty_addr);
        }
    }

    op_addr_ldstpair_post(s, a, dirty_addr, offset);
    return true;
}

static void op_addr_ldst_imm_pre(DisasContext *s, arg_ldst_imm *a,
                                 TCGv_i64 *clean_addr, TCGv_i64 *dirty_addr,
                                 uint64_t offset, bool is_store, MemOp mop)
{
    int memidx;

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    *dirty_addr = read_cpu_reg_sp(s, a->rn, 1);
    if (!a->p) {
        tcg_gen_addi_i64(*dirty_addr, *dirty_addr, offset);
    }
    memidx = get_a64_user_mem_index(s, a->unpriv);
    *clean_addr = gen_mte_check1_mmuidx(s, *dirty_addr, is_store,
                                        a->w || a->rn != 31,
                                        mop, a->unpriv, memidx);
}

static void op_addr_ldst_imm_post(DisasContext *s, arg_ldst_imm *a,
                                  TCGv_i64 dirty_addr, uint64_t offset)
{
    if (a->w) {
        if (a->p) {
            tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
        }
        tcg_gen_mov_i64(cpu_reg_sp(s, a->rn), dirty_addr);
    }
}

static bool trans_STR_i(DisasContext *s, arg_ldst_imm *a)
{
    bool iss_sf, iss_valid = !a->w;
    TCGv_i64 clean_addr, dirty_addr, tcg_rt;
    int memidx = get_a64_user_mem_index(s, a->unpriv);
    MemOp mop = finalize_memop(s, a->sz + a->sign * MO_SIGN);

    op_addr_ldst_imm_pre(s, a, &clean_addr, &dirty_addr, a->imm, true, mop);

    tcg_rt = cpu_reg(s, a->rt);
    iss_sf = ldst_iss_sf(a->sz, a->sign, a->ext);

    do_gpr_st_memidx(s, tcg_rt, clean_addr, mop, memidx,
                     iss_valid, a->rt, iss_sf, false);
    op_addr_ldst_imm_post(s, a, dirty_addr, a->imm);
    return true;
}

static bool trans_LDR_i(DisasContext *s, arg_ldst_imm *a)
{
    bool iss_sf, iss_valid = !a->w;
    TCGv_i64 clean_addr, dirty_addr, tcg_rt;
    int memidx = get_a64_user_mem_index(s, a->unpriv);
    MemOp mop = finalize_memop(s, a->sz + a->sign * MO_SIGN);

    op_addr_ldst_imm_pre(s, a, &clean_addr, &dirty_addr, a->imm, false, mop);

    tcg_rt = cpu_reg(s, a->rt);
    iss_sf = ldst_iss_sf(a->sz, a->sign, a->ext);

    do_gpr_ld_memidx(s, tcg_rt, clean_addr, mop,
                     a->ext, memidx, iss_valid, a->rt, iss_sf, false);
    op_addr_ldst_imm_post(s, a, dirty_addr, a->imm);
    return true;
}

static bool trans_STR_v_i(DisasContext *s, arg_ldst_imm *a)
{
    TCGv_i64 clean_addr, dirty_addr;
    MemOp mop;

    if (!fp_access_check(s)) {
        return true;
    }
    mop = finalize_memop_asimd(s, a->sz);
    op_addr_ldst_imm_pre(s, a, &clean_addr, &dirty_addr, a->imm, true, mop);
    do_fp_st(s, a->rt, clean_addr, mop);
    op_addr_ldst_imm_post(s, a, dirty_addr, a->imm);
    return true;
}

static bool trans_LDR_v_i(DisasContext *s, arg_ldst_imm *a)
{
    TCGv_i64 clean_addr, dirty_addr;
    MemOp mop;

    if (!fp_access_check(s)) {
        return true;
    }
    mop = finalize_memop_asimd(s, a->sz);
    op_addr_ldst_imm_pre(s, a, &clean_addr, &dirty_addr, a->imm, false, mop);
    do_fp_ld(s, a->rt, clean_addr, mop);
    op_addr_ldst_imm_post(s, a, dirty_addr, a->imm);
    return true;
}

static void op_addr_ldst_pre(DisasContext *s, arg_ldst *a,
                             TCGv_i64 *clean_addr, TCGv_i64 *dirty_addr,
                             bool is_store, MemOp memop)
{
    TCGv_i64 tcg_rm;

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }
    *dirty_addr = read_cpu_reg_sp(s, a->rn, 1);

    tcg_rm = read_cpu_reg(s, a->rm, 1);
    ext_and_shift_reg(tcg_rm, tcg_rm, a->opt, a->s ? a->sz : 0);

    tcg_gen_add_i64(*dirty_addr, *dirty_addr, tcg_rm);
    *clean_addr = gen_mte_check1(s, *dirty_addr, is_store, true, memop);
}

static bool trans_LDR(DisasContext *s, arg_ldst *a)
{
    TCGv_i64 clean_addr, dirty_addr, tcg_rt;
    bool iss_sf = ldst_iss_sf(a->sz, a->sign, a->ext);
    MemOp memop;

    if (extract32(a->opt, 1, 1) == 0) {
        return false;
    }

    memop = finalize_memop(s, a->sz + a->sign * MO_SIGN);
    op_addr_ldst_pre(s, a, &clean_addr, &dirty_addr, false, memop);
    tcg_rt = cpu_reg(s, a->rt);
    do_gpr_ld(s, tcg_rt, clean_addr, memop,
              a->ext, true, a->rt, iss_sf, false);
    return true;
}

static bool trans_STR(DisasContext *s, arg_ldst *a)
{
    TCGv_i64 clean_addr, dirty_addr, tcg_rt;
    bool iss_sf = ldst_iss_sf(a->sz, a->sign, a->ext);
    MemOp memop;

    if (extract32(a->opt, 1, 1) == 0) {
        return false;
    }

    memop = finalize_memop(s, a->sz);
    op_addr_ldst_pre(s, a, &clean_addr, &dirty_addr, true, memop);
    tcg_rt = cpu_reg(s, a->rt);
    do_gpr_st(s, tcg_rt, clean_addr, memop, true, a->rt, iss_sf, false);
    return true;
}

static bool trans_LDR_v(DisasContext *s, arg_ldst *a)
{
    TCGv_i64 clean_addr, dirty_addr;
    MemOp memop;

    if (extract32(a->opt, 1, 1) == 0) {
        return false;
    }

    if (!fp_access_check(s)) {
        return true;
    }

    memop = finalize_memop_asimd(s, a->sz);
    op_addr_ldst_pre(s, a, &clean_addr, &dirty_addr, false, memop);
    do_fp_ld(s, a->rt, clean_addr, memop);
    return true;
}

static bool trans_STR_v(DisasContext *s, arg_ldst *a)
{
    TCGv_i64 clean_addr, dirty_addr;
    MemOp memop;

    if (extract32(a->opt, 1, 1) == 0) {
        return false;
    }

    if (!fp_access_check(s)) {
        return true;
    }

    memop = finalize_memop_asimd(s, a->sz);
    op_addr_ldst_pre(s, a, &clean_addr, &dirty_addr, true, memop);
    do_fp_st(s, a->rt, clean_addr, memop);
    return true;
}


static bool do_atomic_ld(DisasContext *s, arg_atomic *a, AtomicThreeOpFn *fn,
                         int sign, bool invert)
{
    MemOp mop = a->sz | sign;
    TCGv_i64 clean_addr, tcg_rs, tcg_rt;

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }
    mop = check_atomic_align(s, a->rn, mop);
    clean_addr = gen_mte_check1(s, cpu_reg_sp(s, a->rn), false,
                                a->rn != 31, mop);
    tcg_rs = read_cpu_reg(s, a->rs, true);
    tcg_rt = cpu_reg(s, a->rt);
    if (invert) {
        tcg_gen_not_i64(tcg_rs, tcg_rs);
    }
    /*
     * The tcg atomic primitives are all full barriers.  Therefore we
     * can ignore the Acquire and Release bits of this instruction.
     */
    fn(tcg_rt, clean_addr, tcg_rs, get_mem_index(s), mop);

    if (mop & MO_SIGN) {
        switch (a->sz) {
        case MO_8:
            tcg_gen_ext8u_i64(tcg_rt, tcg_rt);
            break;
        case MO_16:
            tcg_gen_ext16u_i64(tcg_rt, tcg_rt);
            break;
        case MO_32:
            tcg_gen_ext32u_i64(tcg_rt, tcg_rt);
            break;
        case MO_64:
            break;
        default:
            g_assert_not_reached();
        }
    }
    return true;
}

TRANS_FEAT(LDADD, aa64_atomics, do_atomic_ld, a, tcg_gen_atomic_fetch_add_i64, 0, false)
TRANS_FEAT(LDCLR, aa64_atomics, do_atomic_ld, a, tcg_gen_atomic_fetch_and_i64, 0, true)
TRANS_FEAT(LDEOR, aa64_atomics, do_atomic_ld, a, tcg_gen_atomic_fetch_xor_i64, 0, false)
TRANS_FEAT(LDSET, aa64_atomics, do_atomic_ld, a, tcg_gen_atomic_fetch_or_i64, 0, false)
TRANS_FEAT(LDSMAX, aa64_atomics, do_atomic_ld, a, tcg_gen_atomic_fetch_smax_i64, MO_SIGN, false)
TRANS_FEAT(LDSMIN, aa64_atomics, do_atomic_ld, a, tcg_gen_atomic_fetch_smin_i64, MO_SIGN, false)
TRANS_FEAT(LDUMAX, aa64_atomics, do_atomic_ld, a, tcg_gen_atomic_fetch_umax_i64, 0, false)
TRANS_FEAT(LDUMIN, aa64_atomics, do_atomic_ld, a, tcg_gen_atomic_fetch_umin_i64, 0, false)
TRANS_FEAT(SWP, aa64_atomics, do_atomic_ld, a, tcg_gen_atomic_xchg_i64, 0, false)

static bool trans_LDAPR(DisasContext *s, arg_LDAPR *a)
{
    bool iss_sf = ldst_iss_sf(a->sz, false, false);
    TCGv_i64 clean_addr;
    MemOp mop;

    if (!dc_isar_feature(aa64_atomics, s) ||
        !dc_isar_feature(aa64_rcpc_8_3, s)) {
        return false;
    }
    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }
    mop = check_atomic_align(s, a->rn, a->sz);
    clean_addr = gen_mte_check1(s, cpu_reg_sp(s, a->rn), false,
                                a->rn != 31, mop);
    /*
     * LDAPR* are a special case because they are a simple load, not a
     * fetch-and-do-something op.
     * The architectural consistency requirements here are weaker than
     * full load-acquire (we only need "load-acquire processor consistent"),
     * but we choose to implement them as full LDAQ.
     */
    do_gpr_ld(s, cpu_reg(s, a->rt), clean_addr, mop, false,
              true, a->rt, iss_sf, true);
    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
    return true;
}

static bool trans_LDRA(DisasContext *s, arg_LDRA *a)
{
    TCGv_i64 clean_addr, dirty_addr, tcg_rt;
    MemOp memop;

    /* Load with pointer authentication */
    if (!dc_isar_feature(aa64_pauth, s)) {
        return false;
    }

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }
    dirty_addr = read_cpu_reg_sp(s, a->rn, 1);

    if (s->pauth_active) {
        if (!a->m) {
            gen_helper_autda_combined(dirty_addr, tcg_env, dirty_addr,
                                      tcg_constant_i64(0));
        } else {
            gen_helper_autdb_combined(dirty_addr, tcg_env, dirty_addr,
                                      tcg_constant_i64(0));
        }
    }

    tcg_gen_addi_i64(dirty_addr, dirty_addr, a->imm);

    memop = finalize_memop(s, MO_64);

    /* Note that "clean" and "dirty" here refer to TBI not PAC.  */
    clean_addr = gen_mte_check1(s, dirty_addr, false,
                                a->w || a->rn != 31, memop);

    tcg_rt = cpu_reg(s, a->rt);
    do_gpr_ld(s, tcg_rt, clean_addr, memop,
              /* extend */ false, /* iss_valid */ !a->w,
              /* iss_srt */ a->rt, /* iss_sf */ true, /* iss_ar */ false);

    if (a->w) {
        tcg_gen_mov_i64(cpu_reg_sp(s, a->rn), dirty_addr);
    }
    return true;
}

static bool trans_LDAPR_i(DisasContext *s, arg_ldapr_stlr_i *a)
{
    TCGv_i64 clean_addr, dirty_addr;
    MemOp mop = a->sz | (a->sign ? MO_SIGN : 0);
    bool iss_sf = ldst_iss_sf(a->sz, a->sign, a->ext);

    if (!dc_isar_feature(aa64_rcpc_8_4, s)) {
        return false;
    }

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    mop = check_ordered_align(s, a->rn, a->imm, false, mop);
    dirty_addr = read_cpu_reg_sp(s, a->rn, 1);
    tcg_gen_addi_i64(dirty_addr, dirty_addr, a->imm);
    clean_addr = clean_data_tbi(s, dirty_addr);

    /*
     * Load-AcquirePC semantics; we implement as the slightly more
     * restrictive Load-Acquire.
     */
    do_gpr_ld(s, cpu_reg(s, a->rt), clean_addr, mop, a->ext, true,
              a->rt, iss_sf, true);
    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
    return true;
}

static bool trans_STLR_i(DisasContext *s, arg_ldapr_stlr_i *a)
{
    TCGv_i64 clean_addr, dirty_addr;
    MemOp mop = a->sz;
    bool iss_sf = ldst_iss_sf(a->sz, a->sign, a->ext);

    if (!dc_isar_feature(aa64_rcpc_8_4, s)) {
        return false;
    }

    /* TODO: ARMv8.4-LSE SCTLR.nAA */

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    mop = check_ordered_align(s, a->rn, a->imm, true, mop);
    dirty_addr = read_cpu_reg_sp(s, a->rn, 1);
    tcg_gen_addi_i64(dirty_addr, dirty_addr, a->imm);
    clean_addr = clean_data_tbi(s, dirty_addr);

    /* Store-Release semantics */
    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
    do_gpr_st(s, cpu_reg(s, a->rt), clean_addr, mop, true, a->rt, iss_sf, true);
    return true;
}

static bool trans_LD_mult(DisasContext *s, arg_ldst_mult *a)
{
    TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
    MemOp endian, align, mop;

    int total;    /* total bytes */
    int elements; /* elements per vector */
    int r;
    int size = a->sz;

    if (!a->p && a->rm != 0) {
        /* For non-postindexed accesses the Rm field must be 0 */
        return false;
    }
    if (size == 3 && !a->q && a->selem != 1) {
        return false;
    }
    if (!fp_access_check(s)) {
        return true;
    }

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    /* For our purposes, bytes are always little-endian.  */
    endian = s->be_data;
    if (size == 0) {
        endian = MO_LE;
    }

    total = a->rpt * a->selem * (a->q ? 16 : 8);
    tcg_rn = cpu_reg_sp(s, a->rn);

    /*
     * Issue the MTE check vs the logical repeat count, before we
     * promote consecutive little-endian elements below.
     */
    clean_addr = gen_mte_checkN(s, tcg_rn, false, a->p || a->rn != 31, total,
                                finalize_memop_asimd(s, size));

    /*
     * Consecutive little-endian elements from a single register
     * can be promoted to a larger little-endian operation.
     */
    align = MO_ALIGN;
    if (a->selem == 1 && endian == MO_LE) {
        align = pow2_align(size);
        size = 3;
    }
    if (!s->align_mem) {
        align = 0;
    }
    mop = endian | size | align;

    elements = (a->q ? 16 : 8) >> size;
    tcg_ebytes = tcg_constant_i64(1 << size);
    for (r = 0; r < a->rpt; r++) {
        int e;
        for (e = 0; e < elements; e++) {
            int xs;
            for (xs = 0; xs < a->selem; xs++) {
                int tt = (a->rt + r + xs) % 32;
                do_vec_ld(s, tt, e, clean_addr, mop);
                tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
            }
        }
    }

    /*
     * For non-quad operations, setting a slice of the low 64 bits of
     * the register clears the high 64 bits (in the ARM ARM pseudocode
     * this is implicit in the fact that 'rval' is a 64 bit wide
     * variable).  For quad operations, we might still need to zero
     * the high bits of SVE.
     */
    for (r = 0; r < a->rpt * a->selem; r++) {
        int tt = (a->rt + r) % 32;
        clear_vec_high(s, a->q, tt);
    }

    if (a->p) {
        if (a->rm == 31) {
            tcg_gen_addi_i64(tcg_rn, tcg_rn, total);
        } else {
            tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, a->rm));
        }
    }
    return true;
}

static bool trans_ST_mult(DisasContext *s, arg_ldst_mult *a)
{
    TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
    MemOp endian, align, mop;

    int total;    /* total bytes */
    int elements; /* elements per vector */
    int r;
    int size = a->sz;

    if (!a->p && a->rm != 0) {
        /* For non-postindexed accesses the Rm field must be 0 */
        return false;
    }
    if (size == 3 && !a->q && a->selem != 1) {
        return false;
    }
    if (!fp_access_check(s)) {
        return true;
    }

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    /* For our purposes, bytes are always little-endian.  */
    endian = s->be_data;
    if (size == 0) {
        endian = MO_LE;
    }

    total = a->rpt * a->selem * (a->q ? 16 : 8);
    tcg_rn = cpu_reg_sp(s, a->rn);

    /*
     * Issue the MTE check vs the logical repeat count, before we
     * promote consecutive little-endian elements below.
     */
    clean_addr = gen_mte_checkN(s, tcg_rn, true, a->p || a->rn != 31, total,
                                finalize_memop_asimd(s, size));

    /*
     * Consecutive little-endian elements from a single register
     * can be promoted to a larger little-endian operation.
     */
    align = MO_ALIGN;
    if (a->selem == 1 && endian == MO_LE) {
        align = pow2_align(size);
        size = 3;
    }
    if (!s->align_mem) {
        align = 0;
    }
    mop = endian | size | align;

    elements = (a->q ? 16 : 8) >> size;
    tcg_ebytes = tcg_constant_i64(1 << size);
    for (r = 0; r < a->rpt; r++) {
        int e;
        for (e = 0; e < elements; e++) {
            int xs;
            for (xs = 0; xs < a->selem; xs++) {
                int tt = (a->rt + r + xs) % 32;
                do_vec_st(s, tt, e, clean_addr, mop);
                tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
            }
        }
    }

    if (a->p) {
        if (a->rm == 31) {
            tcg_gen_addi_i64(tcg_rn, tcg_rn, total);
        } else {
            tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, a->rm));
        }
    }
    return true;
}

static bool trans_ST_single(DisasContext *s, arg_ldst_single *a)
{
    int xs, total, rt;
    TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
    MemOp mop;

    if (!a->p && a->rm != 0) {
        return false;
    }
    if (!fp_access_check(s)) {
        return true;
    }

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    total = a->selem << a->scale;
    tcg_rn = cpu_reg_sp(s, a->rn);

    mop = finalize_memop_asimd(s, a->scale);
    clean_addr = gen_mte_checkN(s, tcg_rn, true, a->p || a->rn != 31,
                                total, mop);

    tcg_ebytes = tcg_constant_i64(1 << a->scale);
    for (xs = 0, rt = a->rt; xs < a->selem; xs++, rt = (rt + 1) % 32) {
        do_vec_st(s, rt, a->index, clean_addr, mop);
        tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
    }

    if (a->p) {
        if (a->rm == 31) {
            tcg_gen_addi_i64(tcg_rn, tcg_rn, total);
        } else {
            tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, a->rm));
        }
    }
    return true;
}

static bool trans_LD_single(DisasContext *s, arg_ldst_single *a)
{
    int xs, total, rt;
    TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
    MemOp mop;

    if (!a->p && a->rm != 0) {
        return false;
    }
    if (!fp_access_check(s)) {
        return true;
    }

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    total = a->selem << a->scale;
    tcg_rn = cpu_reg_sp(s, a->rn);

    mop = finalize_memop_asimd(s, a->scale);
    clean_addr = gen_mte_checkN(s, tcg_rn, false, a->p || a->rn != 31,
                                total, mop);

    tcg_ebytes = tcg_constant_i64(1 << a->scale);
    for (xs = 0, rt = a->rt; xs < a->selem; xs++, rt = (rt + 1) % 32) {
        do_vec_ld(s, rt, a->index, clean_addr, mop);
        tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
    }

    if (a->p) {
        if (a->rm == 31) {
            tcg_gen_addi_i64(tcg_rn, tcg_rn, total);
        } else {
            tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, a->rm));
        }
    }
    return true;
}

static bool trans_LD_single_repl(DisasContext *s, arg_LD_single_repl *a)
{
    int xs, total, rt;
    TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
    MemOp mop;

    if (!a->p && a->rm != 0) {
        return false;
    }
    if (!fp_access_check(s)) {
        return true;
    }

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    total = a->selem << a->scale;
    tcg_rn = cpu_reg_sp(s, a->rn);

    mop = finalize_memop_asimd(s, a->scale);
    clean_addr = gen_mte_checkN(s, tcg_rn, false, a->p || a->rn != 31,
                                total, mop);

    tcg_ebytes = tcg_constant_i64(1 << a->scale);
    for (xs = 0, rt = a->rt; xs < a->selem; xs++, rt = (rt + 1) % 32) {
        /* Load and replicate to all elements */
        TCGv_i64 tcg_tmp = tcg_temp_new_i64();

        tcg_gen_qemu_ld_i64(tcg_tmp, clean_addr, get_mem_index(s), mop);
        tcg_gen_gvec_dup_i64(a->scale, vec_full_reg_offset(s, rt),
                             (a->q + 1) * 8, vec_full_reg_size(s), tcg_tmp);
        tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
    }

    if (a->p) {
        if (a->rm == 31) {
            tcg_gen_addi_i64(tcg_rn, tcg_rn, total);
        } else {
            tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, a->rm));
        }
    }
    return true;
}

static bool trans_STZGM(DisasContext *s, arg_ldst_tag *a)
{
    TCGv_i64 addr, clean_addr, tcg_rt;
    int size = 4 << s->dcz_blocksize;

    if (!dc_isar_feature(aa64_mte, s)) {
        return false;
    }
    if (s->current_el == 0) {
        return false;
    }

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    addr = read_cpu_reg_sp(s, a->rn, true);
    tcg_gen_addi_i64(addr, addr, a->imm);
    tcg_rt = cpu_reg(s, a->rt);

    if (s->ata[0]) {
        gen_helper_stzgm_tags(tcg_env, addr, tcg_rt);
    }
    /*
     * The non-tags portion of STZGM is mostly like DC_ZVA,
     * except the alignment happens before the access.
     */
    clean_addr = clean_data_tbi(s, addr);
    tcg_gen_andi_i64(clean_addr, clean_addr, -size);
    gen_helper_dc_zva(tcg_env, clean_addr);
    return true;
}

static bool trans_STGM(DisasContext *s, arg_ldst_tag *a)
{
    TCGv_i64 addr, clean_addr, tcg_rt;

    if (!dc_isar_feature(aa64_mte, s)) {
        return false;
    }
    if (s->current_el == 0) {
        return false;
    }

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    addr = read_cpu_reg_sp(s, a->rn, true);
    tcg_gen_addi_i64(addr, addr, a->imm);
    tcg_rt = cpu_reg(s, a->rt);

    if (s->ata[0]) {
        gen_helper_stgm(tcg_env, addr, tcg_rt);
    } else {
        MMUAccessType acc = MMU_DATA_STORE;
        int size = 4 << s->gm_blocksize;

        clean_addr = clean_data_tbi(s, addr);
        tcg_gen_andi_i64(clean_addr, clean_addr, -size);
        gen_probe_access(s, clean_addr, acc, size);
    }
    return true;
}

static bool trans_LDGM(DisasContext *s, arg_ldst_tag *a)
{
    TCGv_i64 addr, clean_addr, tcg_rt;

    if (!dc_isar_feature(aa64_mte, s)) {
        return false;
    }
    if (s->current_el == 0) {
        return false;
    }

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    addr = read_cpu_reg_sp(s, a->rn, true);
    tcg_gen_addi_i64(addr, addr, a->imm);
    tcg_rt = cpu_reg(s, a->rt);

    if (s->ata[0]) {
        gen_helper_ldgm(tcg_rt, tcg_env, addr);
    } else {
        MMUAccessType acc = MMU_DATA_LOAD;
        int size = 4 << s->gm_blocksize;

        clean_addr = clean_data_tbi(s, addr);
        tcg_gen_andi_i64(clean_addr, clean_addr, -size);
        gen_probe_access(s, clean_addr, acc, size);
        /* The result tags are zeros.  */
        tcg_gen_movi_i64(tcg_rt, 0);
    }
    return true;
}

static bool trans_LDG(DisasContext *s, arg_ldst_tag *a)
{
    TCGv_i64 addr, clean_addr, tcg_rt;

    if (!dc_isar_feature(aa64_mte_insn_reg, s)) {
        return false;
    }

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    addr = read_cpu_reg_sp(s, a->rn, true);
    if (!a->p) {
        /* pre-index or signed offset */
        tcg_gen_addi_i64(addr, addr, a->imm);
    }

    tcg_gen_andi_i64(addr, addr, -TAG_GRANULE);
    tcg_rt = cpu_reg(s, a->rt);
    if (s->ata[0]) {
        gen_helper_ldg(tcg_rt, tcg_env, addr, tcg_rt);
    } else {
        /*
         * Tag access disabled: we must check for aborts on the load
         * load from [rn+offset], and then insert a 0 tag into rt.
         */
        clean_addr = clean_data_tbi(s, addr);
        gen_probe_access(s, clean_addr, MMU_DATA_LOAD, MO_8);
        gen_address_with_allocation_tag0(tcg_rt, tcg_rt);
    }

    if (a->w) {
        /* pre-index or post-index */
        if (a->p) {
            /* post-index */
            tcg_gen_addi_i64(addr, addr, a->imm);
        }
        tcg_gen_mov_i64(cpu_reg_sp(s, a->rn), addr);
    }
    return true;
}

static bool do_STG(DisasContext *s, arg_ldst_tag *a, bool is_zero, bool is_pair)
{
    TCGv_i64 addr, tcg_rt;

    if (a->rn == 31) {
        gen_check_sp_alignment(s);
    }

    addr = read_cpu_reg_sp(s, a->rn, true);
    if (!a->p) {
        /* pre-index or signed offset */
        tcg_gen_addi_i64(addr, addr, a->imm);
    }
    tcg_rt = cpu_reg_sp(s, a->rt);
    if (!s->ata[0]) {
        /*
         * For STG and ST2G, we need to check alignment and probe memory.
         * TODO: For STZG and STZ2G, we could rely on the stores below,
         * at least for system mode; user-only won't enforce alignment.
         */
        if (is_pair) {
            gen_helper_st2g_stub(tcg_env, addr);
        } else {
            gen_helper_stg_stub(tcg_env, addr);
        }
    } else if (tb_cflags(s->base.tb) & CF_PARALLEL) {
        if (is_pair) {
            gen_helper_st2g_parallel(tcg_env, addr, tcg_rt);
        } else {
            gen_helper_stg_parallel(tcg_env, addr, tcg_rt);
        }
    } else {
        if (is_pair) {
            gen_helper_st2g(tcg_env, addr, tcg_rt);
        } else {
            gen_helper_stg(tcg_env, addr, tcg_rt);
        }
    }

    if (is_zero) {
        TCGv_i64 clean_addr = clean_data_tbi(s, addr);
        TCGv_i64 zero64 = tcg_constant_i64(0);
        TCGv_i128 zero128 = tcg_temp_new_i128();
        int mem_index = get_mem_index(s);
        MemOp mop = finalize_memop(s, MO_128 | MO_ALIGN);

        tcg_gen_concat_i64_i128(zero128, zero64, zero64);

        /* This is 1 or 2 atomic 16-byte operations. */
        tcg_gen_qemu_st_i128(zero128, clean_addr, mem_index, mop);
        if (is_pair) {
            tcg_gen_addi_i64(clean_addr, clean_addr, 16);
            tcg_gen_qemu_st_i128(zero128, clean_addr, mem_index, mop);
        }
    }

    if (a->w) {
        /* pre-index or post-index */
        if (a->p) {
            /* post-index */
            tcg_gen_addi_i64(addr, addr, a->imm);
        }
        tcg_gen_mov_i64(cpu_reg_sp(s, a->rn), addr);
    }
    return true;
}

TRANS_FEAT(STG, aa64_mte_insn_reg, do_STG, a, false, false)
TRANS_FEAT(STZG, aa64_mte_insn_reg, do_STG, a, true, false)
TRANS_FEAT(ST2G, aa64_mte_insn_reg, do_STG, a, false, true)
TRANS_FEAT(STZ2G, aa64_mte_insn_reg, do_STG, a, true, true)

typedef void SetFn(TCGv_env, TCGv_i32, TCGv_i32);

static bool do_SET(DisasContext *s, arg_set *a, bool is_epilogue,
                   bool is_setg, SetFn fn)
{
    int memidx;
    uint32_t syndrome, desc = 0;

    if (is_setg && !dc_isar_feature(aa64_mte, s)) {
        return false;
    }

    /*
     * UNPREDICTABLE cases: we choose to UNDEF, which allows
     * us to pull this check before the CheckMOPSEnabled() test
     * (which we do in the helper function)
     */
    if (a->rs == a->rn || a->rs == a->rd || a->rn == a->rd ||
        a->rd == 31 || a->rn == 31) {
        return false;
    }

    memidx = get_a64_user_mem_index(s, a->unpriv);

    /*
     * We pass option_a == true, matching our implementation;
     * we pass wrong_option == false: helper function may set that bit.
     */
    syndrome = syn_mop(true, is_setg, (a->nontemp << 1) | a->unpriv,
                       is_epilogue, false, true, a->rd, a->rs, a->rn);

    if (is_setg ? s->ata[a->unpriv] : s->mte_active[a->unpriv]) {
        /* We may need to do MTE tag checking, so assemble the descriptor */
        desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
        desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
        desc = FIELD_DP32(desc, MTEDESC, WRITE, true);
        /* SIZEM1 and ALIGN we leave 0 (byte write) */
    }
    /* The helper function always needs the memidx even with MTE disabled */
    desc = FIELD_DP32(desc, MTEDESC, MIDX, memidx);

    /*
     * The helper needs the register numbers, but since they're in
     * the syndrome anyway, we let it extract them from there rather
     * than passing in an extra three integer arguments.
     */
    fn(tcg_env, tcg_constant_i32(syndrome), tcg_constant_i32(desc));
    return true;
}

TRANS_FEAT(SETP, aa64_mops, do_SET, a, false, false, gen_helper_setp)
TRANS_FEAT(SETM, aa64_mops, do_SET, a, false, false, gen_helper_setm)
TRANS_FEAT(SETE, aa64_mops, do_SET, a, true, false, gen_helper_sete)
TRANS_FEAT(SETGP, aa64_mops, do_SET, a, false, true, gen_helper_setgp)
TRANS_FEAT(SETGM, aa64_mops, do_SET, a, false, true, gen_helper_setgm)
TRANS_FEAT(SETGE, aa64_mops, do_SET, a, true, true, gen_helper_setge)

typedef void CpyFn(TCGv_env, TCGv_i32, TCGv_i32, TCGv_i32);

static bool do_CPY(DisasContext *s, arg_cpy *a, bool is_epilogue, CpyFn fn)
{
    int rmemidx, wmemidx;
    uint32_t syndrome, rdesc = 0, wdesc = 0;
    bool wunpriv = extract32(a->options, 0, 1);
    bool runpriv = extract32(a->options, 1, 1);

    /*
     * UNPREDICTABLE cases: we choose to UNDEF, which allows
     * us to pull this check before the CheckMOPSEnabled() test
     * (which we do in the helper function)
     */
    if (a->rs == a->rn || a->rs == a->rd || a->rn == a->rd ||
        a->rd == 31 || a->rs == 31 || a->rn == 31) {
        return false;
    }

    rmemidx = get_a64_user_mem_index(s, runpriv);
    wmemidx = get_a64_user_mem_index(s, wunpriv);

    /*
     * We pass option_a == true, matching our implementation;
     * we pass wrong_option == false: helper function may set that bit.
     */
    syndrome = syn_mop(false, false, a->options, is_epilogue,
                       false, true, a->rd, a->rs, a->rn);

    /* If we need to do MTE tag checking, assemble the descriptors */
    if (s->mte_active[runpriv]) {
        rdesc = FIELD_DP32(rdesc, MTEDESC, TBI, s->tbid);
        rdesc = FIELD_DP32(rdesc, MTEDESC, TCMA, s->tcma);
    }
    if (s->mte_active[wunpriv]) {
        wdesc = FIELD_DP32(wdesc, MTEDESC, TBI, s->tbid);
        wdesc = FIELD_DP32(wdesc, MTEDESC, TCMA, s->tcma);
        wdesc = FIELD_DP32(wdesc, MTEDESC, WRITE, true);
    }
    /* The helper function needs these parts of the descriptor regardless */
    rdesc = FIELD_DP32(rdesc, MTEDESC, MIDX, rmemidx);
    wdesc = FIELD_DP32(wdesc, MTEDESC, MIDX, wmemidx);

    /*
     * The helper needs the register numbers, but since they're in
     * the syndrome anyway, we let it extract them from there rather
     * than passing in an extra three integer arguments.
     */
    fn(tcg_env, tcg_constant_i32(syndrome), tcg_constant_i32(wdesc),
       tcg_constant_i32(rdesc));
    return true;
}

TRANS_FEAT(CPYP, aa64_mops, do_CPY, a, false, gen_helper_cpyp)
TRANS_FEAT(CPYM, aa64_mops, do_CPY, a, false, gen_helper_cpym)
TRANS_FEAT(CPYE, aa64_mops, do_CPY, a, true, gen_helper_cpye)
TRANS_FEAT(CPYFP, aa64_mops, do_CPY, a, false, gen_helper_cpyfp)
TRANS_FEAT(CPYFM, aa64_mops, do_CPY, a, false, gen_helper_cpyfm)
TRANS_FEAT(CPYFE, aa64_mops, do_CPY, a, true, gen_helper_cpyfe)

typedef void ArithTwoOp(TCGv_i64, TCGv_i64, TCGv_i64);

static bool gen_rri(DisasContext *s, arg_rri_sf *a,
                    bool rd_sp, bool rn_sp, ArithTwoOp *fn)
{
    TCGv_i64 tcg_rn = rn_sp ? cpu_reg_sp(s, a->rn) : cpu_reg(s, a->rn);
    TCGv_i64 tcg_rd = rd_sp ? cpu_reg_sp(s, a->rd) : cpu_reg(s, a->rd);
    TCGv_i64 tcg_imm = tcg_constant_i64(a->imm);

    fn(tcg_rd, tcg_rn, tcg_imm);
    if (!a->sf) {
        tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
    }
    return true;
}

/*
 * PC-rel. addressing
 */

static bool trans_ADR(DisasContext *s, arg_ri *a)
{
    gen_pc_plus_diff(s, cpu_reg(s, a->rd), a->imm);
    return true;
}

static bool trans_ADRP(DisasContext *s, arg_ri *a)
{
    int64_t offset = (int64_t)a->imm << 12;

    /* The page offset is ok for CF_PCREL. */
    offset -= s->pc_curr & 0xfff;
    gen_pc_plus_diff(s, cpu_reg(s, a->rd), offset);
    return true;
}

/*
 * Add/subtract (immediate)
 */
TRANS(ADD_i, gen_rri, a, 1, 1, tcg_gen_add_i64)
TRANS(SUB_i, gen_rri, a, 1, 1, tcg_gen_sub_i64)
TRANS(ADDS_i, gen_rri, a, 0, 1, a->sf ? gen_add64_CC : gen_add32_CC)
TRANS(SUBS_i, gen_rri, a, 0, 1, a->sf ? gen_sub64_CC : gen_sub32_CC)

/*
 * Add/subtract (immediate, with tags)
 */

static bool gen_add_sub_imm_with_tags(DisasContext *s, arg_rri_tag *a,
                                      bool sub_op)
{
    TCGv_i64 tcg_rn, tcg_rd;
    int imm;

    imm = a->uimm6 << LOG2_TAG_GRANULE;
    if (sub_op) {
        imm = -imm;
    }

    tcg_rn = cpu_reg_sp(s, a->rn);
    tcg_rd = cpu_reg_sp(s, a->rd);

    if (s->ata[0]) {
        gen_helper_addsubg(tcg_rd, tcg_env, tcg_rn,
                           tcg_constant_i32(imm),
                           tcg_constant_i32(a->uimm4));
    } else {
        tcg_gen_addi_i64(tcg_rd, tcg_rn, imm);
        gen_address_with_allocation_tag0(tcg_rd, tcg_rd);
    }
    return true;
}

TRANS_FEAT(ADDG_i, aa64_mte_insn_reg, gen_add_sub_imm_with_tags, a, false)
TRANS_FEAT(SUBG_i, aa64_mte_insn_reg, gen_add_sub_imm_with_tags, a, true)

/* The input should be a value in the bottom e bits (with higher
 * bits zero); returns that value replicated into every element
 * of size e in a 64 bit integer.
 */
static uint64_t bitfield_replicate(uint64_t mask, unsigned int e)
{
    assert(e != 0);
    while (e < 64) {
        mask |= mask << e;
        e *= 2;
    }
    return mask;
}

/*
 * Logical (immediate)
 */

/*
 * Simplified variant of pseudocode DecodeBitMasks() for the case where we
 * only require the wmask. Returns false if the imms/immr/immn are a reserved
 * value (ie should cause a guest UNDEF exception), and true if they are
 * valid, in which case the decoded bit pattern is written to result.
 */
bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
                            unsigned int imms, unsigned int immr)
{
    uint64_t mask;
    unsigned e, levels, s, r;
    int len;

    assert(immn < 2 && imms < 64 && immr < 64);

    /* The bit patterns we create here are 64 bit patterns which
     * are vectors of identical elements of size e = 2, 4, 8, 16, 32 or
     * 64 bits each. Each element contains the same value: a run
     * of between 1 and e-1 non-zero bits, rotated within the
     * element by between 0 and e-1 bits.
     *
     * The element size and run length are encoded into immn (1 bit)
     * and imms (6 bits) as follows:
     * 64 bit elements: immn = 1, imms = <length of run - 1>
     * 32 bit elements: immn = 0, imms = 0 : <length of run - 1>
     * 16 bit elements: immn = 0, imms = 10 : <length of run - 1>
     *  8 bit elements: immn = 0, imms = 110 : <length of run - 1>
     *  4 bit elements: immn = 0, imms = 1110 : <length of run - 1>
     *  2 bit elements: immn = 0, imms = 11110 : <length of run - 1>
     * Notice that immn = 0, imms = 11111x is the only combination
     * not covered by one of the above options; this is reserved.
     * Further, <length of run - 1> all-ones is a reserved pattern.
     *
     * In all cases the rotation is by immr % e (and immr is 6 bits).
     */

    /* First determine the element size */
    len = 31 - clz32((immn << 6) | (~imms & 0x3f));
    if (len < 1) {
        /* This is the immn == 0, imms == 0x11111x case */
        return false;
    }
    e = 1 << len;

    levels = e - 1;
    s = imms & levels;
    r = immr & levels;

    if (s == levels) {
        /* <length of run - 1> mustn't be all-ones. */
        return false;
    }

    /* Create the value of one element: s+1 set bits rotated
     * by r within the element (which is e bits wide)...
     */
    mask = MAKE_64BIT_MASK(0, s + 1);
    if (r) {
        mask = (mask >> r) | (mask << (e - r));
        mask &= MAKE_64BIT_MASK(0, e);
    }
    /* ...then replicate the element over the whole 64 bit value */
    mask = bitfield_replicate(mask, e);
    *result = mask;
    return true;
}

static bool gen_rri_log(DisasContext *s, arg_rri_log *a, bool set_cc,
                        void (*fn)(TCGv_i64, TCGv_i64, int64_t))
{
    TCGv_i64 tcg_rd, tcg_rn;
    uint64_t imm;

    /* Some immediate field values are reserved. */
    if (!logic_imm_decode_wmask(&imm, extract32(a->dbm, 12, 1),
                                extract32(a->dbm, 0, 6),
                                extract32(a->dbm, 6, 6))) {
        return false;
    }
    if (!a->sf) {
        imm &= 0xffffffffull;
    }

    tcg_rd = set_cc ? cpu_reg(s, a->rd) : cpu_reg_sp(s, a->rd);
    tcg_rn = cpu_reg(s, a->rn);

    fn(tcg_rd, tcg_rn, imm);
    if (set_cc) {
        gen_logic_CC(a->sf, tcg_rd);
    }
    if (!a->sf) {
        tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
    }
    return true;
}

TRANS(AND_i, gen_rri_log, a, false, tcg_gen_andi_i64)
TRANS(ORR_i, gen_rri_log, a, false, tcg_gen_ori_i64)
TRANS(EOR_i, gen_rri_log, a, false, tcg_gen_xori_i64)
TRANS(ANDS_i, gen_rri_log, a, true, tcg_gen_andi_i64)

/*
 * Move wide (immediate)
 */

static bool trans_MOVZ(DisasContext *s, arg_movw *a)
{
    int pos = a->hw << 4;
    tcg_gen_movi_i64(cpu_reg(s, a->rd), (uint64_t)a->imm << pos);
    return true;
}

static bool trans_MOVN(DisasContext *s, arg_movw *a)
{
    int pos = a->hw << 4;
    uint64_t imm = a->imm;

    imm = ~(imm << pos);
    if (!a->sf) {
        imm = (uint32_t)imm;
    }
    tcg_gen_movi_i64(cpu_reg(s, a->rd), imm);
    return true;
}

static bool trans_MOVK(DisasContext *s, arg_movw *a)
{
    int pos = a->hw << 4;
    TCGv_i64 tcg_rd, tcg_im;

    tcg_rd = cpu_reg(s, a->rd);
    tcg_im = tcg_constant_i64(a->imm);
    tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_im, pos, 16);
    if (!a->sf) {
        tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
    }
    return true;
}

/*
 * Bitfield
 */

static bool trans_SBFM(DisasContext *s, arg_SBFM *a)
{
    TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
    TCGv_i64 tcg_tmp = read_cpu_reg(s, a->rn, 1);
    unsigned int bitsize = a->sf ? 64 : 32;
    unsigned int ri = a->immr;
    unsigned int si = a->imms;
    unsigned int pos, len;

    if (si >= ri) {
        /* Wd<s-r:0> = Wn<s:r> */
        len = (si - ri) + 1;
        tcg_gen_sextract_i64(tcg_rd, tcg_tmp, ri, len);
        if (!a->sf) {
            tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
        }
    } else {
        /* Wd<32+s-r,32-r> = Wn<s:0> */
        len = si + 1;
        pos = (bitsize - ri) & (bitsize - 1);

        if (len < ri) {
            /*
             * Sign extend the destination field from len to fill the
             * balance of the word.  Let the deposit below insert all
             * of those sign bits.
             */
            tcg_gen_sextract_i64(tcg_tmp, tcg_tmp, 0, len);
            len = ri;
        }

        /*
         * We start with zero, and we haven't modified any bits outside
         * bitsize, therefore no final zero-extension is unneeded for !sf.
         */
        tcg_gen_deposit_z_i64(tcg_rd, tcg_tmp, pos, len);
    }
    return true;
}

static bool trans_UBFM(DisasContext *s, arg_UBFM *a)
{
    TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
    TCGv_i64 tcg_tmp = read_cpu_reg(s, a->rn, 1);
    unsigned int bitsize = a->sf ? 64 : 32;
    unsigned int ri = a->immr;
    unsigned int si = a->imms;
    unsigned int pos, len;

    tcg_rd = cpu_reg(s, a->rd);
    tcg_tmp = read_cpu_reg(s, a->rn, 1);

    if (si >= ri) {
        /* Wd<s-r:0> = Wn<s:r> */
        len = (si - ri) + 1;
        tcg_gen_extract_i64(tcg_rd, tcg_tmp, ri, len);
    } else {
        /* Wd<32+s-r,32-r> = Wn<s:0> */
        len = si + 1;
        pos = (bitsize - ri) & (bitsize - 1);
        tcg_gen_deposit_z_i64(tcg_rd, tcg_tmp, pos, len);
    }
    return true;
}

static bool trans_BFM(DisasContext *s, arg_BFM *a)
{
    TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
    TCGv_i64 tcg_tmp = read_cpu_reg(s, a->rn, 1);
    unsigned int bitsize = a->sf ? 64 : 32;
    unsigned int ri = a->immr;
    unsigned int si = a->imms;
    unsigned int pos, len;

    tcg_rd = cpu_reg(s, a->rd);
    tcg_tmp = read_cpu_reg(s, a->rn, 1);

    if (si >= ri) {
        /* Wd<s-r:0> = Wn<s:r> */
        tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri);
        len = (si - ri) + 1;
        pos = 0;
    } else {
        /* Wd<32+s-r,32-r> = Wn<s:0> */
        len = si + 1;
        pos = (bitsize - ri) & (bitsize - 1);
    }

    tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
    if (!a->sf) {
        tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
    }
    return true;
}

static bool trans_EXTR(DisasContext *s, arg_extract *a)
{
    TCGv_i64 tcg_rd, tcg_rm, tcg_rn;

    tcg_rd = cpu_reg(s, a->rd);

    if (unlikely(a->imm == 0)) {
        /*
         * tcg shl_i32/shl_i64 is undefined for 32/64 bit shifts,
         * so an extract from bit 0 is a special case.
         */
        if (a->sf) {
            tcg_gen_mov_i64(tcg_rd, cpu_reg(s, a->rm));
        } else {
            tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, a->rm));
        }
    } else {
        tcg_rm = cpu_reg(s, a->rm);
        tcg_rn = cpu_reg(s, a->rn);

        if (a->sf) {
            /* Specialization to ROR happens in EXTRACT2.  */
            tcg_gen_extract2_i64(tcg_rd, tcg_rm, tcg_rn, a->imm);
        } else {
            TCGv_i32 t0 = tcg_temp_new_i32();

            tcg_gen_extrl_i64_i32(t0, tcg_rm);
            if (a->rm == a->rn) {
                tcg_gen_rotri_i32(t0, t0, a->imm);
            } else {
                TCGv_i32 t1 = tcg_temp_new_i32();
                tcg_gen_extrl_i64_i32(t1, tcg_rn);
                tcg_gen_extract2_i32(t0, t0, t1, a->imm);
            }
            tcg_gen_extu_i32_i64(tcg_rd, t0);
        }
    }
    return true;
}

/*
 * Cryptographic AES, SHA, SHA512
 */

TRANS_FEAT(AESE, aa64_aes, do_gvec_op3_ool, a, 0, gen_helper_crypto_aese)
TRANS_FEAT(AESD, aa64_aes, do_gvec_op3_ool, a, 0, gen_helper_crypto_aesd)
TRANS_FEAT(AESMC, aa64_aes, do_gvec_op2_ool, a, 0, gen_helper_crypto_aesmc)
TRANS_FEAT(AESIMC, aa64_aes, do_gvec_op2_ool, a, 0, gen_helper_crypto_aesimc)

TRANS_FEAT(SHA1C, aa64_sha1, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha1c)
TRANS_FEAT(SHA1P, aa64_sha1, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha1p)
TRANS_FEAT(SHA1M, aa64_sha1, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha1m)
TRANS_FEAT(SHA1SU0, aa64_sha1, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha1su0)

TRANS_FEAT(SHA256H, aa64_sha256, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha256h)
TRANS_FEAT(SHA256H2, aa64_sha256, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha256h2)
TRANS_FEAT(SHA256SU1, aa64_sha256, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha256su1)

TRANS_FEAT(SHA1H, aa64_sha1, do_gvec_op2_ool, a, 0, gen_helper_crypto_sha1h)
TRANS_FEAT(SHA1SU1, aa64_sha1, do_gvec_op2_ool, a, 0, gen_helper_crypto_sha1su1)
TRANS_FEAT(SHA256SU0, aa64_sha256, do_gvec_op2_ool, a, 0, gen_helper_crypto_sha256su0)

TRANS_FEAT(SHA512H, aa64_sha512, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha512h)
TRANS_FEAT(SHA512H2, aa64_sha512, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha512h2)
TRANS_FEAT(SHA512SU1, aa64_sha512, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha512su1)
TRANS_FEAT(RAX1, aa64_sha3, do_gvec_fn3, a, gen_gvec_rax1)
TRANS_FEAT(SM3PARTW1, aa64_sm3, do_gvec_op3_ool, a, 0, gen_helper_crypto_sm3partw1)
TRANS_FEAT(SM3PARTW2, aa64_sm3, do_gvec_op3_ool, a, 0, gen_helper_crypto_sm3partw2)
TRANS_FEAT(SM4EKEY, aa64_sm4, do_gvec_op3_ool, a, 0, gen_helper_crypto_sm4ekey)

TRANS_FEAT(SHA512SU0, aa64_sha512, do_gvec_op2_ool, a, 0, gen_helper_crypto_sha512su0)
TRANS_FEAT(SM4E, aa64_sm4, do_gvec_op3_ool, a, 0, gen_helper_crypto_sm4e)

TRANS_FEAT(EOR3, aa64_sha3, do_gvec_fn4, a, gen_gvec_eor3)
TRANS_FEAT(BCAX, aa64_sha3, do_gvec_fn4, a, gen_gvec_bcax)

static bool trans_SM3SS1(DisasContext *s, arg_SM3SS1 *a)
{
    if (!dc_isar_feature(aa64_sm3, s)) {
        return false;
    }
    if (fp_access_check(s)) {
        TCGv_i32 tcg_op1 = tcg_temp_new_i32();
        TCGv_i32 tcg_op2 = tcg_temp_new_i32();
        TCGv_i32 tcg_op3 = tcg_temp_new_i32();
        TCGv_i32 tcg_res = tcg_temp_new_i32();
        unsigned vsz, dofs;

        read_vec_element_i32(s, tcg_op1, a->rn, 3, MO_32);
        read_vec_element_i32(s, tcg_op2, a->rm, 3, MO_32);
        read_vec_element_i32(s, tcg_op3, a->ra, 3, MO_32);

        tcg_gen_rotri_i32(tcg_res, tcg_op1, 20);
        tcg_gen_add_i32(tcg_res, tcg_res, tcg_op2);
        tcg_gen_add_i32(tcg_res, tcg_res, tcg_op3);
        tcg_gen_rotri_i32(tcg_res, tcg_res, 25);

        /* Clear the whole register first, then store bits [127:96]. */
        vsz = vec_full_reg_size(s);
        dofs = vec_full_reg_offset(s, a->rd);
        tcg_gen_gvec_dup_imm(MO_64, dofs, vsz, vsz, 0);
        write_vec_element_i32(s, tcg_res, a->rd, 3, MO_32);
    }
    return true;
}

static bool do_crypto3i(DisasContext *s, arg_crypto3i *a, gen_helper_gvec_3 *fn)
{
    if (fp_access_check(s)) {
        gen_gvec_op3_ool(s, true, a->rd, a->rn, a->rm, a->imm, fn);
    }
    return true;
}
TRANS_FEAT(SM3TT1A, aa64_sm3, do_crypto3i, a, gen_helper_crypto_sm3tt1a)
TRANS_FEAT(SM3TT1B, aa64_sm3, do_crypto3i, a, gen_helper_crypto_sm3tt1b)
TRANS_FEAT(SM3TT2A, aa64_sm3, do_crypto3i, a, gen_helper_crypto_sm3tt2a)
TRANS_FEAT(SM3TT2B, aa64_sm3, do_crypto3i, a, gen_helper_crypto_sm3tt2b)

static bool trans_XAR(DisasContext *s, arg_XAR *a)
{
    if (!dc_isar_feature(aa64_sha3, s)) {
        return false;
    }
    if (fp_access_check(s)) {
        gen_gvec_xar(MO_64, vec_full_reg_offset(s, a->rd),
                     vec_full_reg_offset(s, a->rn),
                     vec_full_reg_offset(s, a->rm), a->imm, 16,
                     vec_full_reg_size(s));
    }
    return true;
}

/*
 * Advanced SIMD copy
 */

static bool decode_esz_idx(int imm, MemOp *pesz, unsigned *pidx)
{
    unsigned esz = ctz32(imm);
    if (esz <= MO_64) {
        *pesz = esz;
        *pidx = imm >> (esz + 1);
        return true;
    }
    return false;
}

static bool trans_DUP_element_s(DisasContext *s, arg_DUP_element_s *a)
{
    MemOp esz;
    unsigned idx;

    if (!decode_esz_idx(a->imm, &esz, &idx)) {
        return false;
    }
    if (fp_access_check(s)) {
        /*
         * This instruction just extracts the specified element and
         * zero-extends it into the bottom of the destination register.
         */
        TCGv_i64 tmp = tcg_temp_new_i64();
        read_vec_element(s, tmp, a->rn, idx, esz);
        write_fp_dreg(s, a->rd, tmp);
    }
    return true;
}

static bool trans_DUP_element_v(DisasContext *s, arg_DUP_element_v *a)
{
    MemOp esz;
    unsigned idx;

    if (!decode_esz_idx(a->imm, &esz, &idx)) {
        return false;
    }
    if (esz == MO_64 && !a->q) {
        return false;
    }
    if (fp_access_check(s)) {
        tcg_gen_gvec_dup_mem(esz, vec_full_reg_offset(s, a->rd),
                             vec_reg_offset(s, a->rn, idx, esz),
                             a->q ? 16 : 8, vec_full_reg_size(s));
    }
    return true;
}

static bool trans_DUP_general(DisasContext *s, arg_DUP_general *a)
{
    MemOp esz;
    unsigned idx;

    if (!decode_esz_idx(a->imm, &esz, &idx)) {
        return false;
    }
    if (esz == MO_64 && !a->q) {
        return false;
    }
    if (fp_access_check(s)) {
        tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd),
                             a->q ? 16 : 8, vec_full_reg_size(s),
                             cpu_reg(s, a->rn));
    }
    return true;
}

static bool do_smov_umov(DisasContext *s, arg_SMOV *a, MemOp is_signed)
{
    MemOp esz;
    unsigned idx;

    if (!decode_esz_idx(a->imm, &esz, &idx)) {
        return false;
    }
    if (is_signed) {
        if (esz == MO_64 || (esz == MO_32 && !a->q)) {
            return false;
        }
    } else {
        if (esz == MO_64 ? !a->q : a->q) {
            return false;
        }
    }
    if (fp_access_check(s)) {
        TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
        read_vec_element(s, tcg_rd, a->rn, idx, esz | is_signed);
        if (is_signed && !a->q) {
            tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
        }
    }
    return true;
}

TRANS(SMOV, do_smov_umov, a, MO_SIGN)
TRANS(UMOV, do_smov_umov, a, 0)

static bool trans_INS_general(DisasContext *s, arg_INS_general *a)
{
    MemOp esz;
    unsigned idx;

    if (!decode_esz_idx(a->imm, &esz, &idx)) {
        return false;
    }
    if (fp_access_check(s)) {
        write_vec_element(s, cpu_reg(s, a->rn), a->rd, idx, esz);
        clear_vec_high(s, true, a->rd);
    }
    return true;
}

static bool trans_INS_element(DisasContext *s, arg_INS_element *a)
{
    MemOp esz;
    unsigned didx, sidx;

    if (!decode_esz_idx(a->di, &esz, &didx)) {
        return false;
    }
    sidx = a->si >> esz;
    if (fp_access_check(s)) {
        TCGv_i64 tmp = tcg_temp_new_i64();

        read_vec_element(s, tmp, a->rn, sidx, esz);
        write_vec_element(s, tmp, a->rd, didx, esz);

        /* INS is considered a 128-bit write for SVE. */
        clear_vec_high(s, true, a->rd);
    }
    return true;
}

/*
 * Advanced SIMD three same
 */

typedef struct FPScalar {
    void (*gen_h)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
    void (*gen_s)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
    void (*gen_d)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
} FPScalar;

static bool do_fp3_scalar(DisasContext *s, arg_rrr_e *a, const FPScalar *f)
{
    switch (a->esz) {
    case MO_64:
        if (fp_access_check(s)) {
            TCGv_i64 t0 = read_fp_dreg(s, a->rn);
            TCGv_i64 t1 = read_fp_dreg(s, a->rm);
            f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR));
            write_fp_dreg(s, a->rd, t0);
        }
        break;
    case MO_32:
        if (fp_access_check(s)) {
            TCGv_i32 t0 = read_fp_sreg(s, a->rn);
            TCGv_i32 t1 = read_fp_sreg(s, a->rm);
            f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR));
            write_fp_sreg(s, a->rd, t0);
        }
        break;
    case MO_16:
        if (!dc_isar_feature(aa64_fp16, s)) {
            return false;
        }
        if (fp_access_check(s)) {
            TCGv_i32 t0 = read_fp_hreg(s, a->rn);
            TCGv_i32 t1 = read_fp_hreg(s, a->rm);
            f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16));
            write_fp_sreg(s, a->rd, t0);
        }
        break;
    default:
        return false;
    }
    return true;
}

static const FPScalar f_scalar_fadd = {
    gen_helper_vfp_addh,
    gen_helper_vfp_adds,
    gen_helper_vfp_addd,
};
TRANS(FADD_s, do_fp3_scalar, a, &f_scalar_fadd)

static const FPScalar f_scalar_fsub = {
    gen_helper_vfp_subh,
    gen_helper_vfp_subs,
    gen_helper_vfp_subd,
};
TRANS(FSUB_s, do_fp3_scalar, a, &f_scalar_fsub)

static const FPScalar f_scalar_fdiv = {
    gen_helper_vfp_divh,
    gen_helper_vfp_divs,
    gen_helper_vfp_divd,
};
TRANS(FDIV_s, do_fp3_scalar, a, &f_scalar_fdiv)

static const FPScalar f_scalar_fmul = {
    gen_helper_vfp_mulh,
    gen_helper_vfp_muls,
    gen_helper_vfp_muld,
};
TRANS(FMUL_s, do_fp3_scalar, a, &f_scalar_fmul)

static const FPScalar f_scalar_fmax = {
    gen_helper_advsimd_maxh,
    gen_helper_vfp_maxs,
    gen_helper_vfp_maxd,
};
TRANS(FMAX_s, do_fp3_scalar, a, &f_scalar_fmax)

static const FPScalar f_scalar_fmin = {
    gen_helper_advsimd_minh,
    gen_helper_vfp_mins,
    gen_helper_vfp_mind,
};
TRANS(FMIN_s, do_fp3_scalar, a, &f_scalar_fmin)

static const FPScalar f_scalar_fmaxnm = {
    gen_helper_advsimd_maxnumh,
    gen_helper_vfp_maxnums,
    gen_helper_vfp_maxnumd,
};
TRANS(FMAXNM_s, do_fp3_scalar, a, &f_scalar_fmaxnm)

static const FPScalar f_scalar_fminnm = {
    gen_helper_advsimd_minnumh,
    gen_helper_vfp_minnums,
    gen_helper_vfp_minnumd,
};
TRANS(FMINNM_s, do_fp3_scalar, a, &f_scalar_fminnm)

static const FPScalar f_scalar_fmulx = {
    gen_helper_advsimd_mulxh,
    gen_helper_vfp_mulxs,
    gen_helper_vfp_mulxd,
};
TRANS(FMULX_s, do_fp3_scalar, a, &f_scalar_fmulx)

static void gen_fnmul_h(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_ptr s)
{
    gen_helper_vfp_mulh(d, n, m, s);
    gen_vfp_negh(d, d);
}

static void gen_fnmul_s(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_ptr s)
{
    gen_helper_vfp_muls(d, n, m, s);
    gen_vfp_negs(d, d);
}

static void gen_fnmul_d(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_ptr s)
{
    gen_helper_vfp_muld(d, n, m, s);
    gen_vfp_negd(d, d);
}

static const FPScalar f_scalar_fnmul = {
    gen_fnmul_h,
    gen_fnmul_s,
    gen_fnmul_d,
};
TRANS(FNMUL_s, do_fp3_scalar, a, &f_scalar_fnmul)

static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
                          gen_helper_gvec_3_ptr * const fns[3])
{
    MemOp esz = a->esz;

    switch (esz) {
    case MO_64:
        if (!a->q) {
            return false;
        }
        break;
    case MO_32:
        break;
    case MO_16:
        if (!dc_isar_feature(aa64_fp16, s)) {
            return false;
        }
        break;
    default:
        return false;
    }
    if (fp_access_check(s)) {
        gen_gvec_op3_fpst(s, a->q, a->rd, a->rn, a->rm,
                          esz == MO_16, 0, fns[esz - 1]);
    }
    return true;
}

static gen_helper_gvec_3_ptr * const f_vector_fadd[3] = {
    gen_helper_gvec_fadd_h,
    gen_helper_gvec_fadd_s,
    gen_helper_gvec_fadd_d,
};
TRANS(FADD_v, do_fp3_vector, a, f_vector_fadd)

static gen_helper_gvec_3_ptr * const f_vector_fsub[3] = {
    gen_helper_gvec_fsub_h,
    gen_helper_gvec_fsub_s,
    gen_helper_gvec_fsub_d,
};
TRANS(FSUB_v, do_fp3_vector, a, f_vector_fsub)

static gen_helper_gvec_3_ptr * const f_vector_fdiv[3] = {
    gen_helper_gvec_fdiv_h,
    gen_helper_gvec_fdiv_s,
    gen_helper_gvec_fdiv_d,
};
TRANS(FDIV_v, do_fp3_vector, a, f_vector_fdiv)

static gen_helper_gvec_3_ptr * const f_vector_fmul[3] = {
    gen_helper_gvec_fmul_h,
    gen_helper_gvec_fmul_s,
    gen_helper_gvec_fmul_d,
};
TRANS(FMUL_v, do_fp3_vector, a, f_vector_fmul)

static gen_helper_gvec_3_ptr * const f_vector_fmax[3] = {
    gen_helper_gvec_fmax_h,
    gen_helper_gvec_fmax_s,
    gen_helper_gvec_fmax_d,
};
TRANS(FMAX_v, do_fp3_vector, a, f_vector_fmax)

static gen_helper_gvec_3_ptr * const f_vector_fmin[3] = {
    gen_helper_gvec_fmin_h,
    gen_helper_gvec_fmin_s,
    gen_helper_gvec_fmin_d,
};
TRANS(FMIN_v, do_fp3_vector, a, f_vector_fmin)

static gen_helper_gvec_3_ptr * const f_vector_fmaxnm[3] = {
    gen_helper_gvec_fmaxnum_h,
    gen_helper_gvec_fmaxnum_s,
    gen_helper_gvec_fmaxnum_d,
};
TRANS(FMAXNM_v, do_fp3_vector, a, f_vector_fmaxnm)

static gen_helper_gvec_3_ptr * const f_vector_fminnm[3] = {
    gen_helper_gvec_fminnum_h,
    gen_helper_gvec_fminnum_s,
    gen_helper_gvec_fminnum_d,
};
TRANS(FMINNM_v, do_fp3_vector, a, f_vector_fminnm)

static gen_helper_gvec_3_ptr * const f_vector_fmulx[3] = {
    gen_helper_gvec_fmulx_h,
    gen_helper_gvec_fmulx_s,
    gen_helper_gvec_fmulx_d,
};
TRANS(FMULX_v, do_fp3_vector, a, f_vector_fmulx)

static gen_helper_gvec_3_ptr * const f_vector_fmla[3] = {
    gen_helper_gvec_vfma_h,
    gen_helper_gvec_vfma_s,
    gen_helper_gvec_vfma_d,
};
TRANS(FMLA_v, do_fp3_vector, a, f_vector_fmla)

static gen_helper_gvec_3_ptr * const f_vector_fmls[3] = {
    gen_helper_gvec_vfms_h,
    gen_helper_gvec_vfms_s,
    gen_helper_gvec_vfms_d,
};
TRANS(FMLS_v, do_fp3_vector, a, f_vector_fmls)

/*
 * Advanced SIMD scalar/vector x indexed element
 */

static bool do_fp3_scalar_idx(DisasContext *s, arg_rrx_e *a, const FPScalar *f)
{
    switch (a->esz) {
    case MO_64:
        if (fp_access_check(s)) {
            TCGv_i64 t0 = read_fp_dreg(s, a->rn);
            TCGv_i64 t1 = tcg_temp_new_i64();

            read_vec_element(s, t1, a->rm, a->idx, MO_64);
            f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR));
            write_fp_dreg(s, a->rd, t0);
        }
        break;
    case MO_32:
        if (fp_access_check(s)) {
            TCGv_i32 t0 = read_fp_sreg(s, a->rn);
            TCGv_i32 t1 = tcg_temp_new_i32();

            read_vec_element_i32(s, t1, a->rm, a->idx, MO_32);
            f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR));
            write_fp_sreg(s, a->rd, t0);
        }
        break;
    case MO_16:
        if (!dc_isar_feature(aa64_fp16, s)) {
            return false;
        }
        if (fp_access_check(s)) {
            TCGv_i32 t0 = read_fp_hreg(s, a->rn);
            TCGv_i32 t1 = tcg_temp_new_i32();

            read_vec_element_i32(s, t1, a->rm, a->idx, MO_16);
            f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16));
            write_fp_sreg(s, a->rd, t0);
        }
        break;
    default:
        g_assert_not_reached();
    }
    return true;
}

TRANS(FMUL_si, do_fp3_scalar_idx, a, &f_scalar_fmul)
TRANS(FMULX_si, do_fp3_scalar_idx, a, &f_scalar_fmulx)

static bool do_fmla_scalar_idx(DisasContext *s, arg_rrx_e *a, bool neg)
{
    switch (a->esz) {
    case MO_64:
        if (fp_access_check(s)) {
            TCGv_i64 t0 = read_fp_dreg(s, a->rd);
            TCGv_i64 t1 = read_fp_dreg(s, a->rn);
            TCGv_i64 t2 = tcg_temp_new_i64();

            read_vec_element(s, t2, a->rm, a->idx, MO_64);
            if (neg) {
                gen_vfp_negd(t1, t1);
            }
            gen_helper_vfp_muladdd(t0, t1, t2, t0, fpstatus_ptr(FPST_FPCR));
            write_fp_dreg(s, a->rd, t0);
        }
        break;
    case MO_32:
        if (fp_access_check(s)) {
            TCGv_i32 t0 = read_fp_sreg(s, a->rd);
            TCGv_i32 t1 = read_fp_sreg(s, a->rn);
            TCGv_i32 t2 = tcg_temp_new_i32();

            read_vec_element_i32(s, t2, a->rm, a->idx, MO_32);
            if (neg) {
                gen_vfp_negs(t1, t1);
            }
            gen_helper_vfp_muladds(t0, t1, t2, t0, fpstatus_ptr(FPST_FPCR));
            write_fp_sreg(s, a->rd, t0);
        }
        break;
    case MO_16:
        if (!dc_isar_feature(aa64_fp16, s)) {
            return false;
        }
        if (fp_access_check(s)) {
            TCGv_i32 t0 = read_fp_hreg(s, a->rd);
            TCGv_i32 t1 = read_fp_hreg(s, a->rn);
            TCGv_i32 t2 = tcg_temp_new_i32();

            read_vec_element_i32(s, t2, a->rm, a->idx, MO_16);
            if (neg) {
                gen_vfp_negh(t1, t1);
            }
            gen_helper_advsimd_muladdh(t0, t1, t2, t0,
                                       fpstatus_ptr(FPST_FPCR_F16));
            write_fp_sreg(s, a->rd, t0);
        }
        break;
    default:
        g_assert_not_reached();
    }
    return true;
}

TRANS(FMLA_si, do_fmla_scalar_idx, a, false)
TRANS(FMLS_si, do_fmla_scalar_idx, a, true)

static bool do_fp3_vector_idx(DisasContext *s, arg_qrrx_e *a,
                              gen_helper_gvec_3_ptr * const fns[3])
{
    MemOp esz = a->esz;

    switch (esz) {
    case MO_64:
        if (!a->q) {
            return false;
        }
        break;
    case MO_32:
        break;
    case MO_16:
        if (!dc_isar_feature(aa64_fp16, s)) {
            return false;
        }
        break;
    default:
        g_assert_not_reached();
    }
    if (fp_access_check(s)) {
        gen_gvec_op3_fpst(s, a->q, a->rd, a->rn, a->rm,
                          esz == MO_16, a->idx, fns[esz - 1]);
    }
    return true;
}

static gen_helper_gvec_3_ptr * const f_vector_idx_fmul[3] = {
    gen_helper_gvec_fmul_idx_h,
    gen_helper_gvec_fmul_idx_s,
    gen_helper_gvec_fmul_idx_d,
};
TRANS(FMUL_vi, do_fp3_vector_idx, a, f_vector_idx_fmul)

static gen_helper_gvec_3_ptr * const f_vector_idx_fmulx[3] = {
    gen_helper_gvec_fmulx_idx_h,
    gen_helper_gvec_fmulx_idx_s,
    gen_helper_gvec_fmulx_idx_d,
};
TRANS(FMULX_vi, do_fp3_vector_idx, a, f_vector_idx_fmulx)

static bool do_fmla_vector_idx(DisasContext *s, arg_qrrx_e *a, bool neg)
{
    static gen_helper_gvec_4_ptr * const fns[3] = {
        gen_helper_gvec_fmla_idx_h,
        gen_helper_gvec_fmla_idx_s,
        gen_helper_gvec_fmla_idx_d,
    };
    MemOp esz = a->esz;

    switch (esz) {
    case MO_64:
        if (!a->q) {
            return false;
        }
        break;
    case MO_32:
        break;
    case MO_16:
        if (!dc_isar_feature(aa64_fp16, s)) {
            return false;
        }
        break;
    default:
        g_assert_not_reached();
    }
    if (fp_access_check(s)) {
        gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd,
                          esz == MO_16, (a->idx << 1) | neg,
                          fns[esz - 1]);
    }
    return true;
}

TRANS(FMLA_vi, do_fmla_vector_idx, a, false)
TRANS(FMLS_vi, do_fmla_vector_idx, a, true)


/* Shift a TCGv src by TCGv shift_amount, put result in dst.
 * Note that it is the caller's responsibility to ensure that the
 * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
 * mandated semantics for out of range shifts.
 */
static void shift_reg(TCGv_i64 dst, TCGv_i64 src, int sf,
                      enum a64_shift_type shift_type, TCGv_i64 shift_amount)
{
    switch (shift_type) {
    case A64_SHIFT_TYPE_LSL:
        tcg_gen_shl_i64(dst, src, shift_amount);
        break;
    case A64_SHIFT_TYPE_LSR:
        tcg_gen_shr_i64(dst, src, shift_amount);
        break;
    case A64_SHIFT_TYPE_ASR:
        if (!sf) {
            tcg_gen_ext32s_i64(dst, src);
        }
        tcg_gen_sar_i64(dst, sf ? src : dst, shift_amount);
        break;
    case A64_SHIFT_TYPE_ROR:
        if (sf) {
            tcg_gen_rotr_i64(dst, src, shift_amount);
        } else {
            TCGv_i32 t0, t1;
            t0 = tcg_temp_new_i32();
            t1 = tcg_temp_new_i32();
            tcg_gen_extrl_i64_i32(t0, src);
            tcg_gen_extrl_i64_i32(t1, shift_amount);
            tcg_gen_rotr_i32(t0, t0, t1);
            tcg_gen_extu_i32_i64(dst, t0);
        }
        break;
    default:
        assert(FALSE); /* all shift types should be handled */
        break;
    }

    if (!sf) { /* zero extend final result */
        tcg_gen_ext32u_i64(dst, dst);
    }
}

/* Shift a TCGv src by immediate, put result in dst.
 * The shift amount must be in range (this should always be true as the
 * relevant instructions will UNDEF on bad shift immediates).
 */
static void shift_reg_imm(TCGv_i64 dst, TCGv_i64 src, int sf,
                          enum a64_shift_type shift_type, unsigned int shift_i)
{
    assert(shift_i < (sf ? 64 : 32));

    if (shift_i == 0) {
        tcg_gen_mov_i64(dst, src);
    } else {
        shift_reg(dst, src, sf, shift_type, tcg_constant_i64(shift_i));
    }
}

/* Logical (shifted register)
 *   31  30 29 28       24 23   22 21  20  16 15    10 9    5 4    0
 * +----+-----+-----------+-------+---+------+--------+------+------+
 * | sf | opc | 0 1 0 1 0 | shift | N |  Rm  |  imm6  |  Rn  |  Rd  |
 * +----+-----+-----------+-------+---+------+--------+------+------+
 */
static void disas_logic_reg(DisasContext *s, uint32_t insn)
{
    TCGv_i64 tcg_rd, tcg_rn, tcg_rm;
    unsigned int sf, opc, shift_type, invert, rm, shift_amount, rn, rd;

    sf = extract32(insn, 31, 1);
    opc = extract32(insn, 29, 2);
    shift_type = extract32(insn, 22, 2);
    invert = extract32(insn, 21, 1);
    rm = extract32(insn, 16, 5);
    shift_amount = extract32(insn, 10, 6);
    rn = extract32(insn, 5, 5);
    rd = extract32(insn, 0, 5);

    if (!sf && (shift_amount & (1 << 5))) {
        unallocated_encoding(s);
        return;
    }

    tcg_rd = cpu_reg(s, rd);

    if (opc == 1 && shift_amount == 0 && shift_type == 0 && rn == 31) {
        /* Unshifted ORR and ORN with WZR/XZR is the standard encoding for
         * register-register MOV and MVN, so it is worth special casing.
         */
        tcg_rm = cpu_reg(s, rm);
        if (invert) {
            tcg_gen_not_i64(tcg_rd, tcg_rm);
            if (!sf) {
                tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
            }
        } else {
            if (sf) {
                tcg_gen_mov_i64(tcg_rd, tcg_rm);
            } else {
                tcg_gen_ext32u_i64(tcg_rd, tcg_rm);
            }
        }
        return;
    }

    tcg_rm = read_cpu_reg(s, rm, sf);

    if (shift_amount) {
        shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, shift_amount);
    }

    tcg_rn = cpu_reg(s, rn);

    switch (opc | (invert << 2)) {
    case 0: /* AND */
    case 3: /* ANDS */
        tcg_gen_and_i64(tcg_rd, tcg_rn, tcg_rm);
        break;
    case 1: /* ORR */
        tcg_gen_or_i64(tcg_rd, tcg_rn, tcg_rm);
        break;
    case 2: /* EOR */
        tcg_gen_xor_i64(tcg_rd, tcg_rn, tcg_rm);
        break;
    case 4: /* BIC */
    case 7: /* BICS */
        tcg_gen_andc_i64(tcg_rd, tcg_rn, tcg_rm);
        break;
    case 5: /* ORN */
        tcg_gen_orc_i64(tcg_rd, tcg_rn, tcg_rm);
        break;
    case 6: /* EON */
        tcg_gen_eqv_i64(tcg_rd, tcg_rn, tcg_rm);
        break;
    default:
        assert(FALSE);
        break;
    }

    if (!sf) {
        tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
    }

    if (opc == 3) {
        gen_logic_CC(sf, tcg_rd);
    }
}

/*
 * Add/subtract (extended register)
 *
 *  31|30|29|28       24|23 22|21|20   16|15  13|12  10|9  5|4  0|
 * +--+--+--+-----------+-----+--+-------+------+------+----+----+
 * |sf|op| S| 0 1 0 1 1 | opt | 1|  Rm   |option| imm3 | Rn | Rd |
 * +--+--+--+-----------+-----+--+-------+------+------+----+----+
 *
 *  sf: 0 -> 32bit, 1 -> 64bit
 *  op: 0 -> add  , 1 -> sub
 *   S: 1 -> set flags
 * opt: 00
 * option: extension type (see DecodeRegExtend)
 * imm3: optional shift to Rm
 *
 * Rd = Rn + LSL(extend(Rm), amount)
 */
static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int imm3 = extract32(insn, 10, 3);
    int option = extract32(insn, 13, 3);
    int rm = extract32(insn, 16, 5);
    int opt = extract32(insn, 22, 2);
    bool setflags = extract32(insn, 29, 1);
    bool sub_op = extract32(insn, 30, 1);
    bool sf = extract32(insn, 31, 1);

    TCGv_i64 tcg_rm, tcg_rn; /* temps */
    TCGv_i64 tcg_rd;
    TCGv_i64 tcg_result;

    if (imm3 > 4 || opt != 0) {
        unallocated_encoding(s);
        return;
    }

    /* non-flag setting ops may use SP */
    if (!setflags) {
        tcg_rd = cpu_reg_sp(s, rd);
    } else {
        tcg_rd = cpu_reg(s, rd);
    }
    tcg_rn = read_cpu_reg_sp(s, rn, sf);

    tcg_rm = read_cpu_reg(s, rm, sf);
    ext_and_shift_reg(tcg_rm, tcg_rm, option, imm3);

    tcg_result = tcg_temp_new_i64();

    if (!setflags) {
        if (sub_op) {
            tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm);
        } else {
            tcg_gen_add_i64(tcg_result, tcg_rn, tcg_rm);
        }
    } else {
        if (sub_op) {
            gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm);
        } else {
            gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm);
        }
    }

    if (sf) {
        tcg_gen_mov_i64(tcg_rd, tcg_result);
    } else {
        tcg_gen_ext32u_i64(tcg_rd, tcg_result);
    }
}

/*
 * Add/subtract (shifted register)
 *
 *  31 30 29 28       24 23 22 21 20   16 15     10 9    5 4    0
 * +--+--+--+-----------+-----+--+-------+---------+------+------+
 * |sf|op| S| 0 1 0 1 1 |shift| 0|  Rm   |  imm6   |  Rn  |  Rd  |
 * +--+--+--+-----------+-----+--+-------+---------+------+------+
 *
 *    sf: 0 -> 32bit, 1 -> 64bit
 *    op: 0 -> add  , 1 -> sub
 *     S: 1 -> set flags
 * shift: 00 -> LSL, 01 -> LSR, 10 -> ASR, 11 -> RESERVED
 *  imm6: Shift amount to apply to Rm before the add/sub
 */
static void disas_add_sub_reg(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int imm6 = extract32(insn, 10, 6);
    int rm = extract32(insn, 16, 5);
    int shift_type = extract32(insn, 22, 2);
    bool setflags = extract32(insn, 29, 1);
    bool sub_op = extract32(insn, 30, 1);
    bool sf = extract32(insn, 31, 1);

    TCGv_i64 tcg_rd = cpu_reg(s, rd);
    TCGv_i64 tcg_rn, tcg_rm;
    TCGv_i64 tcg_result;

    if ((shift_type == 3) || (!sf && (imm6 > 31))) {
        unallocated_encoding(s);
        return;
    }

    tcg_rn = read_cpu_reg(s, rn, sf);
    tcg_rm = read_cpu_reg(s, rm, sf);

    shift_reg_imm(tcg_rm, tcg_rm, sf, shift_type, imm6);

    tcg_result = tcg_temp_new_i64();

    if (!setflags) {
        if (sub_op) {
            tcg_gen_sub_i64(tcg_result, tcg_rn, tcg_rm);
        } else {
            tcg_gen_add_i64(tcg_result, tcg_rn, tcg_rm);
        }
    } else {
        if (sub_op) {
            gen_sub_CC(sf, tcg_result, tcg_rn, tcg_rm);
        } else {
            gen_add_CC(sf, tcg_result, tcg_rn, tcg_rm);
        }
    }

    if (sf) {
        tcg_gen_mov_i64(tcg_rd, tcg_result);
    } else {
        tcg_gen_ext32u_i64(tcg_rd, tcg_result);
    }
}

/* Data-processing (3 source)
 *
 *    31 30  29 28       24 23 21  20  16  15  14  10 9    5 4    0
 *  +--+------+-----------+------+------+----+------+------+------+
 *  |sf| op54 | 1 1 0 1 1 | op31 |  Rm  | o0 |  Ra  |  Rn  |  Rd  |
 *  +--+------+-----------+------+------+----+------+------+------+
 */
static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int ra = extract32(insn, 10, 5);
    int rm = extract32(insn, 16, 5);
    int op_id = (extract32(insn, 29, 3) << 4) |
        (extract32(insn, 21, 3) << 1) |
        extract32(insn, 15, 1);
    bool sf = extract32(insn, 31, 1);
    bool is_sub = extract32(op_id, 0, 1);
    bool is_high = extract32(op_id, 2, 1);
    bool is_signed = false;
    TCGv_i64 tcg_op1;
    TCGv_i64 tcg_op2;
    TCGv_i64 tcg_tmp;

    /* Note that op_id is sf:op54:op31:o0 so it includes the 32/64 size flag */
    switch (op_id) {
    case 0x42: /* SMADDL */
    case 0x43: /* SMSUBL */
    case 0x44: /* SMULH */
        is_signed = true;
        break;
    case 0x0: /* MADD (32bit) */
    case 0x1: /* MSUB (32bit) */
    case 0x40: /* MADD (64bit) */
    case 0x41: /* MSUB (64bit) */
    case 0x4a: /* UMADDL */
    case 0x4b: /* UMSUBL */
    case 0x4c: /* UMULH */
        break;
    default:
        unallocated_encoding(s);
        return;
    }

    if (is_high) {
        TCGv_i64 low_bits = tcg_temp_new_i64(); /* low bits discarded */
        TCGv_i64 tcg_rd = cpu_reg(s, rd);
        TCGv_i64 tcg_rn = cpu_reg(s, rn);
        TCGv_i64 tcg_rm = cpu_reg(s, rm);

        if (is_signed) {
            tcg_gen_muls2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm);
        } else {
            tcg_gen_mulu2_i64(low_bits, tcg_rd, tcg_rn, tcg_rm);
        }
        return;
    }

    tcg_op1 = tcg_temp_new_i64();
    tcg_op2 = tcg_temp_new_i64();
    tcg_tmp = tcg_temp_new_i64();

    if (op_id < 0x42) {
        tcg_gen_mov_i64(tcg_op1, cpu_reg(s, rn));
        tcg_gen_mov_i64(tcg_op2, cpu_reg(s, rm));
    } else {
        if (is_signed) {
            tcg_gen_ext32s_i64(tcg_op1, cpu_reg(s, rn));
            tcg_gen_ext32s_i64(tcg_op2, cpu_reg(s, rm));
        } else {
            tcg_gen_ext32u_i64(tcg_op1, cpu_reg(s, rn));
            tcg_gen_ext32u_i64(tcg_op2, cpu_reg(s, rm));
        }
    }

    if (ra == 31 && !is_sub) {
        /* Special-case MADD with rA == XZR; it is the standard MUL alias */
        tcg_gen_mul_i64(cpu_reg(s, rd), tcg_op1, tcg_op2);
    } else {
        tcg_gen_mul_i64(tcg_tmp, tcg_op1, tcg_op2);
        if (is_sub) {
            tcg_gen_sub_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp);
        } else {
            tcg_gen_add_i64(cpu_reg(s, rd), cpu_reg(s, ra), tcg_tmp);
        }
    }

    if (!sf) {
        tcg_gen_ext32u_i64(cpu_reg(s, rd), cpu_reg(s, rd));
    }
}

/* Add/subtract (with carry)
 *  31 30 29 28 27 26 25 24 23 22 21  20  16  15       10  9    5 4   0
 * +--+--+--+------------------------+------+-------------+------+-----+
 * |sf|op| S| 1  1  0  1  0  0  0  0 |  rm  | 0 0 0 0 0 0 |  Rn  |  Rd |
 * +--+--+--+------------------------+------+-------------+------+-----+
 */

static void disas_adc_sbc(DisasContext *s, uint32_t insn)
{
    unsigned int sf, op, setflags, rm, rn, rd;
    TCGv_i64 tcg_y, tcg_rn, tcg_rd;

    sf = extract32(insn, 31, 1);
    op = extract32(insn, 30, 1);
    setflags = extract32(insn, 29, 1);
    rm = extract32(insn, 16, 5);
    rn = extract32(insn, 5, 5);
    rd = extract32(insn, 0, 5);

    tcg_rd = cpu_reg(s, rd);
    tcg_rn = cpu_reg(s, rn);

    if (op) {
        tcg_y = tcg_temp_new_i64();
        tcg_gen_not_i64(tcg_y, cpu_reg(s, rm));
    } else {
        tcg_y = cpu_reg(s, rm);
    }

    if (setflags) {
        gen_adc_CC(sf, tcg_rd, tcg_rn, tcg_y);
    } else {
        gen_adc(sf, tcg_rd, tcg_rn, tcg_y);
    }
}

/*
 * Rotate right into flags
 *  31 30 29                21       15          10      5  4      0
 * +--+--+--+-----------------+--------+-----------+------+--+------+
 * |sf|op| S| 1 1 0 1 0 0 0 0 |  imm6  | 0 0 0 0 1 |  Rn  |o2| mask |
 * +--+--+--+-----------------+--------+-----------+------+--+------+
 */
static void disas_rotate_right_into_flags(DisasContext *s, uint32_t insn)
{
    int mask = extract32(insn, 0, 4);
    int o2 = extract32(insn, 4, 1);
    int rn = extract32(insn, 5, 5);
    int imm6 = extract32(insn, 15, 6);
    int sf_op_s = extract32(insn, 29, 3);
    TCGv_i64 tcg_rn;
    TCGv_i32 nzcv;

    if (sf_op_s != 5 || o2 != 0 || !dc_isar_feature(aa64_condm_4, s)) {
        unallocated_encoding(s);
        return;
    }

    tcg_rn = read_cpu_reg(s, rn, 1);
    tcg_gen_rotri_i64(tcg_rn, tcg_rn, imm6);

    nzcv = tcg_temp_new_i32();
    tcg_gen_extrl_i64_i32(nzcv, tcg_rn);

    if (mask & 8) { /* N */
        tcg_gen_shli_i32(cpu_NF, nzcv, 31 - 3);
    }
    if (mask & 4) { /* Z */
        tcg_gen_not_i32(cpu_ZF, nzcv);
        tcg_gen_andi_i32(cpu_ZF, cpu_ZF, 4);
    }
    if (mask & 2) { /* C */
        tcg_gen_extract_i32(cpu_CF, nzcv, 1, 1);
    }
    if (mask & 1) { /* V */
        tcg_gen_shli_i32(cpu_VF, nzcv, 31 - 0);
    }
}

/*
 * Evaluate into flags
 *  31 30 29                21        15   14        10      5  4      0
 * +--+--+--+-----------------+---------+----+---------+------+--+------+
 * |sf|op| S| 1 1 0 1 0 0 0 0 | opcode2 | sz | 0 0 1 0 |  Rn  |o3| mask |
 * +--+--+--+-----------------+---------+----+---------+------+--+------+
 */
static void disas_evaluate_into_flags(DisasContext *s, uint32_t insn)
{
    int o3_mask = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int o2 = extract32(insn, 15, 6);
    int sz = extract32(insn, 14, 1);
    int sf_op_s = extract32(insn, 29, 3);
    TCGv_i32 tmp;
    int shift;

    if (sf_op_s != 1 || o2 != 0 || o3_mask != 0xd ||
        !dc_isar_feature(aa64_condm_4, s)) {
        unallocated_encoding(s);
        return;
    }
    shift = sz ? 16 : 24;  /* SETF16 or SETF8 */

    tmp = tcg_temp_new_i32();
    tcg_gen_extrl_i64_i32(tmp, cpu_reg(s, rn));
    tcg_gen_shli_i32(cpu_NF, tmp, shift);
    tcg_gen_shli_i32(cpu_VF, tmp, shift - 1);
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
    tcg_gen_xor_i32(cpu_VF, cpu_VF, cpu_NF);
}

/* Conditional compare (immediate / register)
 *  31 30 29 28 27 26 25 24 23 22 21  20    16 15  12  11  10  9   5  4 3   0
 * +--+--+--+------------------------+--------+------+----+--+------+--+-----+
 * |sf|op| S| 1  1  0  1  0  0  1  0 |imm5/rm | cond |i/r |o2|  Rn  |o3|nzcv |
 * +--+--+--+------------------------+--------+------+----+--+------+--+-----+
 *        [1]                             y                [0]       [0]
 */
static void disas_cc(DisasContext *s, uint32_t insn)
{
    unsigned int sf, op, y, cond, rn, nzcv, is_imm;
    TCGv_i32 tcg_t0, tcg_t1, tcg_t2;
    TCGv_i64 tcg_tmp, tcg_y, tcg_rn;
    DisasCompare c;

    if (!extract32(insn, 29, 1)) {
        unallocated_encoding(s);
        return;
    }
    if (insn & (1 << 10 | 1 << 4)) {
        unallocated_encoding(s);
        return;
    }
    sf = extract32(insn, 31, 1);
    op = extract32(insn, 30, 1);
    is_imm = extract32(insn, 11, 1);
    y = extract32(insn, 16, 5); /* y = rm (reg) or imm5 (imm) */
    cond = extract32(insn, 12, 4);
    rn = extract32(insn, 5, 5);
    nzcv = extract32(insn, 0, 4);

    /* Set T0 = !COND.  */
    tcg_t0 = tcg_temp_new_i32();
    arm_test_cc(&c, cond);
    tcg_gen_setcondi_i32(tcg_invert_cond(c.cond), tcg_t0, c.value, 0);

    /* Load the arguments for the new comparison.  */
    if (is_imm) {
        tcg_y = tcg_temp_new_i64();
        tcg_gen_movi_i64(tcg_y, y);
    } else {
        tcg_y = cpu_reg(s, y);
    }
    tcg_rn = cpu_reg(s, rn);

    /* Set the flags for the new comparison.  */
    tcg_tmp = tcg_temp_new_i64();
    if (op) {
        gen_sub_CC(sf, tcg_tmp, tcg_rn, tcg_y);
    } else {
        gen_add_CC(sf, tcg_tmp, tcg_rn, tcg_y);
    }

    /* If COND was false, force the flags to #nzcv.  Compute two masks
     * to help with this: T1 = (COND ? 0 : -1), T2 = (COND ? -1 : 0).
     * For tcg hosts that support ANDC, we can make do with just T1.
     * In either case, allow the tcg optimizer to delete any unused mask.
     */
    tcg_t1 = tcg_temp_new_i32();
    tcg_t2 = tcg_temp_new_i32();
    tcg_gen_neg_i32(tcg_t1, tcg_t0);
    tcg_gen_subi_i32(tcg_t2, tcg_t0, 1);

    if (nzcv & 8) { /* N */
        tcg_gen_or_i32(cpu_NF, cpu_NF, tcg_t1);
    } else {
        if (TCG_TARGET_HAS_andc_i32) {
            tcg_gen_andc_i32(cpu_NF, cpu_NF, tcg_t1);
        } else {
            tcg_gen_and_i32(cpu_NF, cpu_NF, tcg_t2);
        }
    }
    if (nzcv & 4) { /* Z */
        if (TCG_TARGET_HAS_andc_i32) {
            tcg_gen_andc_i32(cpu_ZF, cpu_ZF, tcg_t1);
        } else {
            tcg_gen_and_i32(cpu_ZF, cpu_ZF, tcg_t2);
        }
    } else {
        tcg_gen_or_i32(cpu_ZF, cpu_ZF, tcg_t0);
    }
    if (nzcv & 2) { /* C */
        tcg_gen_or_i32(cpu_CF, cpu_CF, tcg_t0);
    } else {
        if (TCG_TARGET_HAS_andc_i32) {
            tcg_gen_andc_i32(cpu_CF, cpu_CF, tcg_t1);
        } else {
            tcg_gen_and_i32(cpu_CF, cpu_CF, tcg_t2);
        }
    }
    if (nzcv & 1) { /* V */
        tcg_gen_or_i32(cpu_VF, cpu_VF, tcg_t1);
    } else {
        if (TCG_TARGET_HAS_andc_i32) {
            tcg_gen_andc_i32(cpu_VF, cpu_VF, tcg_t1);
        } else {
            tcg_gen_and_i32(cpu_VF, cpu_VF, tcg_t2);
        }
    }
}

/* Conditional select
 *   31   30  29  28             21 20  16 15  12 11 10 9    5 4    0
 * +----+----+---+-----------------+------+------+-----+------+------+
 * | sf | op | S | 1 1 0 1 0 1 0 0 |  Rm  | cond | op2 |  Rn  |  Rd  |
 * +----+----+---+-----------------+------+------+-----+------+------+
 */
static void disas_cond_select(DisasContext *s, uint32_t insn)
{
    unsigned int sf, else_inv, rm, cond, else_inc, rn, rd;
    TCGv_i64 tcg_rd, zero;
    DisasCompare64 c;

    if (extract32(insn, 29, 1) || extract32(insn, 11, 1)) {
        /* S == 1 or op2<1> == 1 */
        unallocated_encoding(s);
        return;
    }
    sf = extract32(insn, 31, 1);
    else_inv = extract32(insn, 30, 1);
    rm = extract32(insn, 16, 5);
    cond = extract32(insn, 12, 4);
    else_inc = extract32(insn, 10, 1);
    rn = extract32(insn, 5, 5);
    rd = extract32(insn, 0, 5);

    tcg_rd = cpu_reg(s, rd);

    a64_test_cc(&c, cond);
    zero = tcg_constant_i64(0);

    if (rn == 31 && rm == 31 && (else_inc ^ else_inv)) {
        /* CSET & CSETM.  */
        if (else_inv) {
            tcg_gen_negsetcond_i64(tcg_invert_cond(c.cond),
                                   tcg_rd, c.value, zero);
        } else {
            tcg_gen_setcond_i64(tcg_invert_cond(c.cond),
                                tcg_rd, c.value, zero);
        }
    } else {
        TCGv_i64 t_true = cpu_reg(s, rn);
        TCGv_i64 t_false = read_cpu_reg(s, rm, 1);
        if (else_inv && else_inc) {
            tcg_gen_neg_i64(t_false, t_false);
        } else if (else_inv) {
            tcg_gen_not_i64(t_false, t_false);
        } else if (else_inc) {
            tcg_gen_addi_i64(t_false, t_false, 1);
        }
        tcg_gen_movcond_i64(c.cond, tcg_rd, c.value, zero, t_true, t_false);
    }

    if (!sf) {
        tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
    }
}

static void handle_clz(DisasContext *s, unsigned int sf,
                       unsigned int rn, unsigned int rd)
{
    TCGv_i64 tcg_rd, tcg_rn;
    tcg_rd = cpu_reg(s, rd);
    tcg_rn = cpu_reg(s, rn);

    if (sf) {
        tcg_gen_clzi_i64(tcg_rd, tcg_rn, 64);
    } else {
        TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
        tcg_gen_extrl_i64_i32(tcg_tmp32, tcg_rn);
        tcg_gen_clzi_i32(tcg_tmp32, tcg_tmp32, 32);
        tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
    }
}

static void handle_cls(DisasContext *s, unsigned int sf,
                       unsigned int rn, unsigned int rd)
{
    TCGv_i64 tcg_rd, tcg_rn;
    tcg_rd = cpu_reg(s, rd);
    tcg_rn = cpu_reg(s, rn);

    if (sf) {
        tcg_gen_clrsb_i64(tcg_rd, tcg_rn);
    } else {
        TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
        tcg_gen_extrl_i64_i32(tcg_tmp32, tcg_rn);
        tcg_gen_clrsb_i32(tcg_tmp32, tcg_tmp32);
        tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
    }
}

static void handle_rbit(DisasContext *s, unsigned int sf,
                        unsigned int rn, unsigned int rd)
{
    TCGv_i64 tcg_rd, tcg_rn;
    tcg_rd = cpu_reg(s, rd);
    tcg_rn = cpu_reg(s, rn);

    if (sf) {
        gen_helper_rbit64(tcg_rd, tcg_rn);
    } else {
        TCGv_i32 tcg_tmp32 = tcg_temp_new_i32();
        tcg_gen_extrl_i64_i32(tcg_tmp32, tcg_rn);
        gen_helper_rbit(tcg_tmp32, tcg_tmp32);
        tcg_gen_extu_i32_i64(tcg_rd, tcg_tmp32);
    }
}

/* REV with sf==1, opcode==3 ("REV64") */
static void handle_rev64(DisasContext *s, unsigned int sf,
                         unsigned int rn, unsigned int rd)
{
    if (!sf) {
        unallocated_encoding(s);
        return;
    }
    tcg_gen_bswap64_i64(cpu_reg(s, rd), cpu_reg(s, rn));
}

/* REV with sf==0, opcode==2
 * REV32 (sf==1, opcode==2)
 */
static void handle_rev32(DisasContext *s, unsigned int sf,
                         unsigned int rn, unsigned int rd)
{
    TCGv_i64 tcg_rd = cpu_reg(s, rd);
    TCGv_i64 tcg_rn = cpu_reg(s, rn);

    if (sf) {
        tcg_gen_bswap64_i64(tcg_rd, tcg_rn);
        tcg_gen_rotri_i64(tcg_rd, tcg_rd, 32);
    } else {
        tcg_gen_bswap32_i64(tcg_rd, tcg_rn, TCG_BSWAP_OZ);
    }
}

/* REV16 (opcode==1) */
static void handle_rev16(DisasContext *s, unsigned int sf,
                         unsigned int rn, unsigned int rd)
{
    TCGv_i64 tcg_rd = cpu_reg(s, rd);
    TCGv_i64 tcg_tmp = tcg_temp_new_i64();
    TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);
    TCGv_i64 mask = tcg_constant_i64(sf ? 0x00ff00ff00ff00ffull : 0x00ff00ff);

    tcg_gen_shri_i64(tcg_tmp, tcg_rn, 8);
    tcg_gen_and_i64(tcg_rd, tcg_rn, mask);
    tcg_gen_and_i64(tcg_tmp, tcg_tmp, mask);
    tcg_gen_shli_i64(tcg_rd, tcg_rd, 8);
    tcg_gen_or_i64(tcg_rd, tcg_rd, tcg_tmp);
}

/* Data-processing (1 source)
 *   31  30  29  28             21 20     16 15    10 9    5 4    0
 * +----+---+---+-----------------+---------+--------+------+------+
 * | sf | 1 | S | 1 1 0 1 0 1 1 0 | opcode2 | opcode |  Rn  |  Rd  |
 * +----+---+---+-----------------+---------+--------+------+------+
 */
static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
{
    unsigned int sf, opcode, opcode2, rn, rd;
    TCGv_i64 tcg_rd;

    if (extract32(insn, 29, 1)) {
        unallocated_encoding(s);
        return;
    }

    sf = extract32(insn, 31, 1);
    opcode = extract32(insn, 10, 6);
    opcode2 = extract32(insn, 16, 5);
    rn = extract32(insn, 5, 5);
    rd = extract32(insn, 0, 5);

#define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7))

    switch (MAP(sf, opcode2, opcode)) {
    case MAP(0, 0x00, 0x00): /* RBIT */
    case MAP(1, 0x00, 0x00):
        handle_rbit(s, sf, rn, rd);
        break;
    case MAP(0, 0x00, 0x01): /* REV16 */
    case MAP(1, 0x00, 0x01):
        handle_rev16(s, sf, rn, rd);
        break;
    case MAP(0, 0x00, 0x02): /* REV/REV32 */
    case MAP(1, 0x00, 0x02):
        handle_rev32(s, sf, rn, rd);
        break;
    case MAP(1, 0x00, 0x03): /* REV64 */
        handle_rev64(s, sf, rn, rd);
        break;
    case MAP(0, 0x00, 0x04): /* CLZ */
    case MAP(1, 0x00, 0x04):
        handle_clz(s, sf, rn, rd);
        break;
    case MAP(0, 0x00, 0x05): /* CLS */
    case MAP(1, 0x00, 0x05):
        handle_cls(s, sf, rn, rd);
        break;
    case MAP(1, 0x01, 0x00): /* PACIA */
        if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_pacia(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn));
        } else if (!dc_isar_feature(aa64_pauth, s)) {
            goto do_unallocated;
        }
        break;
    case MAP(1, 0x01, 0x01): /* PACIB */
        if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_pacib(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn));
        } else if (!dc_isar_feature(aa64_pauth, s)) {
            goto do_unallocated;
        }
        break;
    case MAP(1, 0x01, 0x02): /* PACDA */
        if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_pacda(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn));
        } else if (!dc_isar_feature(aa64_pauth, s)) {
            goto do_unallocated;
        }
        break;
    case MAP(1, 0x01, 0x03): /* PACDB */
        if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_pacdb(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn));
        } else if (!dc_isar_feature(aa64_pauth, s)) {
            goto do_unallocated;
        }
        break;
    case MAP(1, 0x01, 0x04): /* AUTIA */
        if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_autia(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn));
        } else if (!dc_isar_feature(aa64_pauth, s)) {
            goto do_unallocated;
        }
        break;
    case MAP(1, 0x01, 0x05): /* AUTIB */
        if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_autib(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn));
        } else if (!dc_isar_feature(aa64_pauth, s)) {
            goto do_unallocated;
        }
        break;
    case MAP(1, 0x01, 0x06): /* AUTDA */
        if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_autda(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn));
        } else if (!dc_isar_feature(aa64_pauth, s)) {
            goto do_unallocated;
        }
        break;
    case MAP(1, 0x01, 0x07): /* AUTDB */
        if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_autdb(tcg_rd, tcg_env, tcg_rd, cpu_reg_sp(s, rn));
        } else if (!dc_isar_feature(aa64_pauth, s)) {
            goto do_unallocated;
        }
        break;
    case MAP(1, 0x01, 0x08): /* PACIZA */
        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
            goto do_unallocated;
        } else if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_pacia(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0));
        }
        break;
    case MAP(1, 0x01, 0x09): /* PACIZB */
        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
            goto do_unallocated;
        } else if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_pacib(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0));
        }
        break;
    case MAP(1, 0x01, 0x0a): /* PACDZA */
        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
            goto do_unallocated;
        } else if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_pacda(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0));
        }
        break;
    case MAP(1, 0x01, 0x0b): /* PACDZB */
        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
            goto do_unallocated;
        } else if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_pacdb(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0));
        }
        break;
    case MAP(1, 0x01, 0x0c): /* AUTIZA */
        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
            goto do_unallocated;
        } else if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_autia(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0));
        }
        break;
    case MAP(1, 0x01, 0x0d): /* AUTIZB */
        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
            goto do_unallocated;
        } else if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_autib(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0));
        }
        break;
    case MAP(1, 0x01, 0x0e): /* AUTDZA */
        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
            goto do_unallocated;
        } else if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_autda(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0));
        }
        break;
    case MAP(1, 0x01, 0x0f): /* AUTDZB */
        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
            goto do_unallocated;
        } else if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_autdb(tcg_rd, tcg_env, tcg_rd, tcg_constant_i64(0));
        }
        break;
    case MAP(1, 0x01, 0x10): /* XPACI */
        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
            goto do_unallocated;
        } else if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_xpaci(tcg_rd, tcg_env, tcg_rd);
        }
        break;
    case MAP(1, 0x01, 0x11): /* XPACD */
        if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
            goto do_unallocated;
        } else if (s->pauth_active) {
            tcg_rd = cpu_reg(s, rd);
            gen_helper_xpacd(tcg_rd, tcg_env, tcg_rd);
        }
        break;
    default:
    do_unallocated:
        unallocated_encoding(s);
        break;
    }

#undef MAP
}

static void handle_div(DisasContext *s, bool is_signed, unsigned int sf,
                       unsigned int rm, unsigned int rn, unsigned int rd)
{
    TCGv_i64 tcg_n, tcg_m, tcg_rd;
    tcg_rd = cpu_reg(s, rd);

    if (!sf && is_signed) {
        tcg_n = tcg_temp_new_i64();
        tcg_m = tcg_temp_new_i64();
        tcg_gen_ext32s_i64(tcg_n, cpu_reg(s, rn));
        tcg_gen_ext32s_i64(tcg_m, cpu_reg(s, rm));
    } else {
        tcg_n = read_cpu_reg(s, rn, sf);
        tcg_m = read_cpu_reg(s, rm, sf);
    }

    if (is_signed) {
        gen_helper_sdiv64(tcg_rd, tcg_n, tcg_m);
    } else {
        gen_helper_udiv64(tcg_rd, tcg_n, tcg_m);
    }

    if (!sf) { /* zero extend final result */
        tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
    }
}

/* LSLV, LSRV, ASRV, RORV */
static void handle_shift_reg(DisasContext *s,
                             enum a64_shift_type shift_type, unsigned int sf,
                             unsigned int rm, unsigned int rn, unsigned int rd)
{
    TCGv_i64 tcg_shift = tcg_temp_new_i64();
    TCGv_i64 tcg_rd = cpu_reg(s, rd);
    TCGv_i64 tcg_rn = read_cpu_reg(s, rn, sf);

    tcg_gen_andi_i64(tcg_shift, cpu_reg(s, rm), sf ? 63 : 31);
    shift_reg(tcg_rd, tcg_rn, sf, shift_type, tcg_shift);
}

/* CRC32[BHWX], CRC32C[BHWX] */
static void handle_crc32(DisasContext *s,
                         unsigned int sf, unsigned int sz, bool crc32c,
                         unsigned int rm, unsigned int rn, unsigned int rd)
{
    TCGv_i64 tcg_acc, tcg_val;
    TCGv_i32 tcg_bytes;

    if (!dc_isar_feature(aa64_crc32, s)
        || (sf == 1 && sz != 3)
        || (sf == 0 && sz == 3)) {
        unallocated_encoding(s);
        return;
    }

    if (sz == 3) {
        tcg_val = cpu_reg(s, rm);
    } else {
        uint64_t mask;
        switch (sz) {
        case 0:
            mask = 0xFF;
            break;
        case 1:
            mask = 0xFFFF;
            break;
        case 2:
            mask = 0xFFFFFFFF;
            break;
        default:
            g_assert_not_reached();
        }
        tcg_val = tcg_temp_new_i64();
        tcg_gen_andi_i64(tcg_val, cpu_reg(s, rm), mask);
    }

    tcg_acc = cpu_reg(s, rn);
    tcg_bytes = tcg_constant_i32(1 << sz);

    if (crc32c) {
        gen_helper_crc32c_64(cpu_reg(s, rd), tcg_acc, tcg_val, tcg_bytes);
    } else {
        gen_helper_crc32_64(cpu_reg(s, rd), tcg_acc, tcg_val, tcg_bytes);
    }
}

/* Data-processing (2 source)
 *   31   30  29 28             21 20  16 15    10 9    5 4    0
 * +----+---+---+-----------------+------+--------+------+------+
 * | sf | 0 | S | 1 1 0 1 0 1 1 0 |  Rm  | opcode |  Rn  |  Rd  |
 * +----+---+---+-----------------+------+--------+------+------+
 */
static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
{
    unsigned int sf, rm, opcode, rn, rd, setflag;
    sf = extract32(insn, 31, 1);
    setflag = extract32(insn, 29, 1);
    rm = extract32(insn, 16, 5);
    opcode = extract32(insn, 10, 6);
    rn = extract32(insn, 5, 5);
    rd = extract32(insn, 0, 5);

    if (setflag && opcode != 0) {
        unallocated_encoding(s);
        return;
    }

    switch (opcode) {
    case 0: /* SUBP(S) */
        if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) {
            goto do_unallocated;
        } else {
            TCGv_i64 tcg_n, tcg_m, tcg_d;

            tcg_n = read_cpu_reg_sp(s, rn, true);
            tcg_m = read_cpu_reg_sp(s, rm, true);
            tcg_gen_sextract_i64(tcg_n, tcg_n, 0, 56);
            tcg_gen_sextract_i64(tcg_m, tcg_m, 0, 56);
            tcg_d = cpu_reg(s, rd);

            if (setflag) {
                gen_sub_CC(true, tcg_d, tcg_n, tcg_m);
            } else {
                tcg_gen_sub_i64(tcg_d, tcg_n, tcg_m);
            }
        }
        break;
    case 2: /* UDIV */
        handle_div(s, false, sf, rm, rn, rd);
        break;
    case 3: /* SDIV */
        handle_div(s, true, sf, rm, rn, rd);
        break;
    case 4: /* IRG */
        if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) {
            goto do_unallocated;
        }
        if (s->ata[0]) {
            gen_helper_irg(cpu_reg_sp(s, rd), tcg_env,
                           cpu_reg_sp(s, rn), cpu_reg(s, rm));
        } else {
            gen_address_with_allocation_tag0(cpu_reg_sp(s, rd),
                                             cpu_reg_sp(s, rn));
        }
        break;
    case 5: /* GMI */
        if (sf == 0 || !dc_isar_feature(aa64_mte_insn_reg, s)) {
            goto do_unallocated;
        } else {
            TCGv_i64 t = tcg_temp_new_i64();

            tcg_gen_extract_i64(t, cpu_reg_sp(s, rn), 56, 4);
            tcg_gen_shl_i64(t, tcg_constant_i64(1), t);
            tcg_gen_or_i64(cpu_reg(s, rd), cpu_reg(s, rm), t);
        }
        break;
    case 8: /* LSLV */
        handle_shift_reg(s, A64_SHIFT_TYPE_LSL, sf, rm, rn, rd);
        break;
    case 9: /* LSRV */
        handle_shift_reg(s, A64_SHIFT_TYPE_LSR, sf, rm, rn, rd);
        break;
    case 10: /* ASRV */
        handle_shift_reg(s, A64_SHIFT_TYPE_ASR, sf, rm, rn, rd);
        break;
    case 11: /* RORV */
        handle_shift_reg(s, A64_SHIFT_TYPE_ROR, sf, rm, rn, rd);
        break;
    case 12: /* PACGA */
        if (sf == 0 || !dc_isar_feature(aa64_pauth, s)) {
            goto do_unallocated;
        }
        gen_helper_pacga(cpu_reg(s, rd), tcg_env,
                         cpu_reg(s, rn), cpu_reg_sp(s, rm));
        break;
    case 16:
    case 17:
    case 18:
    case 19:
    case 20:
    case 21:
    case 22:
    case 23: /* CRC32 */
    {
        int sz = extract32(opcode, 0, 2);
        bool crc32c = extract32(opcode, 2, 1);
        handle_crc32(s, sf, sz, crc32c, rm, rn, rd);
        break;
    }
    default:
    do_unallocated:
        unallocated_encoding(s);
        break;
    }
}

/*
 * Data processing - register
 *  31  30 29  28      25    21  20  16      10         0
 * +--+---+--+---+-------+-----+-------+-------+---------+
 * |  |op0|  |op1| 1 0 1 | op2 |       |  op3  |         |
 * +--+---+--+---+-------+-----+-------+-------+---------+
 */
static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
{
    int op0 = extract32(insn, 30, 1);
    int op1 = extract32(insn, 28, 1);
    int op2 = extract32(insn, 21, 4);
    int op3 = extract32(insn, 10, 6);

    if (!op1) {
        if (op2 & 8) {
            if (op2 & 1) {
                /* Add/sub (extended register) */
                disas_add_sub_ext_reg(s, insn);
            } else {
                /* Add/sub (shifted register) */
                disas_add_sub_reg(s, insn);
            }
        } else {
            /* Logical (shifted register) */
            disas_logic_reg(s, insn);
        }
        return;
    }

    switch (op2) {
    case 0x0:
        switch (op3) {
        case 0x00: /* Add/subtract (with carry) */
            disas_adc_sbc(s, insn);
            break;

        case 0x01: /* Rotate right into flags */
        case 0x21:
            disas_rotate_right_into_flags(s, insn);
            break;

        case 0x02: /* Evaluate into flags */
        case 0x12:
        case 0x22:
        case 0x32:
            disas_evaluate_into_flags(s, insn);
            break;

        default:
            goto do_unallocated;
        }
        break;

    case 0x2: /* Conditional compare */
        disas_cc(s, insn); /* both imm and reg forms */
        break;

    case 0x4: /* Conditional select */
        disas_cond_select(s, insn);
        break;

    case 0x6: /* Data-processing */
        if (op0) {    /* (1 source) */
            disas_data_proc_1src(s, insn);
        } else {      /* (2 source) */
            disas_data_proc_2src(s, insn);
        }
        break;
    case 0x8 ... 0xf: /* (3 source) */
        disas_data_proc_3src(s, insn);
        break;

    default:
    do_unallocated:
        unallocated_encoding(s);
        break;
    }
}

static void handle_fp_compare(DisasContext *s, int size,
                              unsigned int rn, unsigned int rm,
                              bool cmp_with_zero, bool signal_all_nans)
{
    TCGv_i64 tcg_flags = tcg_temp_new_i64();
    TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);

    if (size == MO_64) {
        TCGv_i64 tcg_vn, tcg_vm;

        tcg_vn = read_fp_dreg(s, rn);
        if (cmp_with_zero) {
            tcg_vm = tcg_constant_i64(0);
        } else {
            tcg_vm = read_fp_dreg(s, rm);
        }
        if (signal_all_nans) {
            gen_helper_vfp_cmped_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
        } else {
            gen_helper_vfp_cmpd_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
        }
    } else {
        TCGv_i32 tcg_vn = tcg_temp_new_i32();
        TCGv_i32 tcg_vm = tcg_temp_new_i32();

        read_vec_element_i32(s, tcg_vn, rn, 0, size);
        if (cmp_with_zero) {
            tcg_gen_movi_i32(tcg_vm, 0);
        } else {
            read_vec_element_i32(s, tcg_vm, rm, 0, size);
        }

        switch (size) {
        case MO_32:
            if (signal_all_nans) {
                gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
            } else {
                gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
            }
            break;
        case MO_16:
            if (signal_all_nans) {
                gen_helper_vfp_cmpeh_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
            } else {
                gen_helper_vfp_cmph_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
            }
            break;
        default:
            g_assert_not_reached();
        }
    }

    gen_set_nzcv(tcg_flags);
}

/* Floating point compare
 *   31  30  29 28       24 23  22  21 20  16 15 14 13  10    9    5 4     0
 * +---+---+---+-----------+------+---+------+-----+---------+------+-------+
 * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | op  | 1 0 0 0 |  Rn  |  op2  |
 * +---+---+---+-----------+------+---+------+-----+---------+------+-------+
 */
static void disas_fp_compare(DisasContext *s, uint32_t insn)
{
    unsigned int mos, type, rm, op, rn, opc, op2r;
    int size;

    mos = extract32(insn, 29, 3);
    type = extract32(insn, 22, 2);
    rm = extract32(insn, 16, 5);
    op = extract32(insn, 14, 2);
    rn = extract32(insn, 5, 5);
    opc = extract32(insn, 3, 2);
    op2r = extract32(insn, 0, 3);

    if (mos || op || op2r) {
        unallocated_encoding(s);
        return;
    }

    switch (type) {
    case 0:
        size = MO_32;
        break;
    case 1:
        size = MO_64;
        break;
    case 3:
        size = MO_16;
        if (dc_isar_feature(aa64_fp16, s)) {
            break;
        }
        /* fallthru */
    default:
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    handle_fp_compare(s, size, rn, rm, opc & 1, opc & 2);
}

/* Floating point conditional compare
 *   31  30  29 28       24 23  22  21 20  16 15  12 11 10 9    5  4   3    0
 * +---+---+---+-----------+------+---+------+------+-----+------+----+------+
 * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | cond | 0 1 |  Rn  | op | nzcv |
 * +---+---+---+-----------+------+---+------+------+-----+------+----+------+
 */
static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
{
    unsigned int mos, type, rm, cond, rn, op, nzcv;
    TCGLabel *label_continue = NULL;
    int size;

    mos = extract32(insn, 29, 3);
    type = extract32(insn, 22, 2);
    rm = extract32(insn, 16, 5);
    cond = extract32(insn, 12, 4);
    rn = extract32(insn, 5, 5);
    op = extract32(insn, 4, 1);
    nzcv = extract32(insn, 0, 4);

    if (mos) {
        unallocated_encoding(s);
        return;
    }

    switch (type) {
    case 0:
        size = MO_32;
        break;
    case 1:
        size = MO_64;
        break;
    case 3:
        size = MO_16;
        if (dc_isar_feature(aa64_fp16, s)) {
            break;
        }
        /* fallthru */
    default:
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    if (cond < 0x0e) { /* not always */
        TCGLabel *label_match = gen_new_label();
        label_continue = gen_new_label();
        arm_gen_test_cc(cond, label_match);
        /* nomatch: */
        gen_set_nzcv(tcg_constant_i64(nzcv << 28));
        tcg_gen_br(label_continue);
        gen_set_label(label_match);
    }

    handle_fp_compare(s, size, rn, rm, false, op);

    if (cond < 0x0e) {
        gen_set_label(label_continue);
    }
}

/* Floating point conditional select
 *   31  30  29 28       24 23  22  21 20  16 15  12 11 10 9    5 4    0
 * +---+---+---+-----------+------+---+------+------+-----+------+------+
 * | M | 0 | S | 1 1 1 1 0 | type | 1 |  Rm  | cond | 1 1 |  Rn  |  Rd  |
 * +---+---+---+-----------+------+---+------+------+-----+------+------+
 */
static void disas_fp_csel(DisasContext *s, uint32_t insn)
{
    unsigned int mos, type, rm, cond, rn, rd;
    TCGv_i64 t_true, t_false;
    DisasCompare64 c;
    MemOp sz;

    mos = extract32(insn, 29, 3);
    type = extract32(insn, 22, 2);
    rm = extract32(insn, 16, 5);
    cond = extract32(insn, 12, 4);
    rn = extract32(insn, 5, 5);
    rd = extract32(insn, 0, 5);

    if (mos) {
        unallocated_encoding(s);
        return;
    }

    switch (type) {
    case 0:
        sz = MO_32;
        break;
    case 1:
        sz = MO_64;
        break;
    case 3:
        sz = MO_16;
        if (dc_isar_feature(aa64_fp16, s)) {
            break;
        }
        /* fallthru */
    default:
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    /* Zero extend sreg & hreg inputs to 64 bits now.  */
    t_true = tcg_temp_new_i64();
    t_false = tcg_temp_new_i64();
    read_vec_element(s, t_true, rn, 0, sz);
    read_vec_element(s, t_false, rm, 0, sz);

    a64_test_cc(&c, cond);
    tcg_gen_movcond_i64(c.cond, t_true, c.value, tcg_constant_i64(0),
                        t_true, t_false);

    /* Note that sregs & hregs write back zeros to the high bits,
       and we've already done the zero-extension.  */
    write_fp_dreg(s, rd, t_true);
}

/* Floating-point data-processing (1 source) - half precision */
static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
{
    TCGv_ptr fpst = NULL;
    TCGv_i32 tcg_op = read_fp_hreg(s, rn);
    TCGv_i32 tcg_res = tcg_temp_new_i32();

    switch (opcode) {
    case 0x0: /* FMOV */
        tcg_gen_mov_i32(tcg_res, tcg_op);
        break;
    case 0x1: /* FABS */
        gen_vfp_absh(tcg_res, tcg_op);
        break;
    case 0x2: /* FNEG */
        gen_vfp_negh(tcg_res, tcg_op);
        break;
    case 0x3: /* FSQRT */
        fpst = fpstatus_ptr(FPST_FPCR_F16);
        gen_helper_sqrt_f16(tcg_res, tcg_op, fpst);
        break;
    case 0x8: /* FRINTN */
    case 0x9: /* FRINTP */
    case 0xa: /* FRINTM */
    case 0xb: /* FRINTZ */
    case 0xc: /* FRINTA */
    {
        TCGv_i32 tcg_rmode;

        fpst = fpstatus_ptr(FPST_FPCR_F16);
        tcg_rmode = gen_set_rmode(opcode & 7, fpst);
        gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst);
        gen_restore_rmode(tcg_rmode, fpst);
        break;
    }
    case 0xe: /* FRINTX */
        fpst = fpstatus_ptr(FPST_FPCR_F16);
        gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, fpst);
        break;
    case 0xf: /* FRINTI */
        fpst = fpstatus_ptr(FPST_FPCR_F16);
        gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst);
        break;
    default:
        g_assert_not_reached();
    }

    write_fp_sreg(s, rd, tcg_res);
}

/* Floating-point data-processing (1 source) - single precision */
static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
{
    void (*gen_fpst)(TCGv_i32, TCGv_i32, TCGv_ptr);
    TCGv_i32 tcg_op, tcg_res;
    TCGv_ptr fpst;
    int rmode = -1;

    tcg_op = read_fp_sreg(s, rn);
    tcg_res = tcg_temp_new_i32();

    switch (opcode) {
    case 0x0: /* FMOV */
        tcg_gen_mov_i32(tcg_res, tcg_op);
        goto done;
    case 0x1: /* FABS */
        gen_vfp_abss(tcg_res, tcg_op);
        goto done;
    case 0x2: /* FNEG */
        gen_vfp_negs(tcg_res, tcg_op);
        goto done;
    case 0x3: /* FSQRT */
        gen_helper_vfp_sqrts(tcg_res, tcg_op, tcg_env);
        goto done;
    case 0x6: /* BFCVT */
        gen_fpst = gen_helper_bfcvt;
        break;
    case 0x8: /* FRINTN */
    case 0x9: /* FRINTP */
    case 0xa: /* FRINTM */
    case 0xb: /* FRINTZ */
    case 0xc: /* FRINTA */
        rmode = opcode & 7;
        gen_fpst = gen_helper_rints;
        break;
    case 0xe: /* FRINTX */
        gen_fpst = gen_helper_rints_exact;
        break;
    case 0xf: /* FRINTI */
        gen_fpst = gen_helper_rints;
        break;
    case 0x10: /* FRINT32Z */
        rmode = FPROUNDING_ZERO;
        gen_fpst = gen_helper_frint32_s;
        break;
    case 0x11: /* FRINT32X */
        gen_fpst = gen_helper_frint32_s;
        break;
    case 0x12: /* FRINT64Z */
        rmode = FPROUNDING_ZERO;
        gen_fpst = gen_helper_frint64_s;
        break;
    case 0x13: /* FRINT64X */
        gen_fpst = gen_helper_frint64_s;
        break;
    default:
        g_assert_not_reached();
    }

    fpst = fpstatus_ptr(FPST_FPCR);
    if (rmode >= 0) {
        TCGv_i32 tcg_rmode = gen_set_rmode(rmode, fpst);
        gen_fpst(tcg_res, tcg_op, fpst);
        gen_restore_rmode(tcg_rmode, fpst);
    } else {
        gen_fpst(tcg_res, tcg_op, fpst);
    }

 done:
    write_fp_sreg(s, rd, tcg_res);
}

/* Floating-point data-processing (1 source) - double precision */
static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
{
    void (*gen_fpst)(TCGv_i64, TCGv_i64, TCGv_ptr);
    TCGv_i64 tcg_op, tcg_res;
    TCGv_ptr fpst;
    int rmode = -1;

    switch (opcode) {
    case 0x0: /* FMOV */
        gen_gvec_fn2(s, false, rd, rn, tcg_gen_gvec_mov, 0);
        return;
    }

    tcg_op = read_fp_dreg(s, rn);
    tcg_res = tcg_temp_new_i64();

    switch (opcode) {
    case 0x1: /* FABS */
        gen_vfp_absd(tcg_res, tcg_op);
        goto done;
    case 0x2: /* FNEG */
        gen_vfp_negd(tcg_res, tcg_op);
        goto done;
    case 0x3: /* FSQRT */
        gen_helper_vfp_sqrtd(tcg_res, tcg_op, tcg_env);
        goto done;
    case 0x8: /* FRINTN */
    case 0x9: /* FRINTP */
    case 0xa: /* FRINTM */
    case 0xb: /* FRINTZ */
    case 0xc: /* FRINTA */
        rmode = opcode & 7;
        gen_fpst = gen_helper_rintd;
        break;
    case 0xe: /* FRINTX */
        gen_fpst = gen_helper_rintd_exact;
        break;
    case 0xf: /* FRINTI */
        gen_fpst = gen_helper_rintd;
        break;
    case 0x10: /* FRINT32Z */
        rmode = FPROUNDING_ZERO;
        gen_fpst = gen_helper_frint32_d;
        break;
    case 0x11: /* FRINT32X */
        gen_fpst = gen_helper_frint32_d;
        break;
    case 0x12: /* FRINT64Z */
        rmode = FPROUNDING_ZERO;
        gen_fpst = gen_helper_frint64_d;
        break;
    case 0x13: /* FRINT64X */
        gen_fpst = gen_helper_frint64_d;
        break;
    default:
        g_assert_not_reached();
    }

    fpst = fpstatus_ptr(FPST_FPCR);
    if (rmode >= 0) {
        TCGv_i32 tcg_rmode = gen_set_rmode(rmode, fpst);
        gen_fpst(tcg_res, tcg_op, fpst);
        gen_restore_rmode(tcg_rmode, fpst);
    } else {
        gen_fpst(tcg_res, tcg_op, fpst);
    }

 done:
    write_fp_dreg(s, rd, tcg_res);
}

static void handle_fp_fcvt(DisasContext *s, int opcode,
                           int rd, int rn, int dtype, int ntype)
{
    switch (ntype) {
    case 0x0:
    {
        TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
        if (dtype == 1) {
            /* Single to double */
            TCGv_i64 tcg_rd = tcg_temp_new_i64();
            gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, tcg_env);
            write_fp_dreg(s, rd, tcg_rd);
        } else {
            /* Single to half */
            TCGv_i32 tcg_rd = tcg_temp_new_i32();
            TCGv_i32 ahp = get_ahp_flag();
            TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);

            gen_helper_vfp_fcvt_f32_to_f16(tcg_rd, tcg_rn, fpst, ahp);
            /* write_fp_sreg is OK here because top half of tcg_rd is zero */
            write_fp_sreg(s, rd, tcg_rd);
        }
        break;
    }
    case 0x1:
    {
        TCGv_i64 tcg_rn = read_fp_dreg(s, rn);
        TCGv_i32 tcg_rd = tcg_temp_new_i32();
        if (dtype == 0) {
            /* Double to single */
            gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, tcg_env);
        } else {
            TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);
            TCGv_i32 ahp = get_ahp_flag();
            /* Double to half */
            gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, fpst, ahp);
            /* write_fp_sreg is OK here because top half of tcg_rd is zero */
        }
        write_fp_sreg(s, rd, tcg_rd);
        break;
    }
    case 0x3:
    {
        TCGv_i32 tcg_rn = read_fp_sreg(s, rn);
        TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR);
        TCGv_i32 tcg_ahp = get_ahp_flag();
        tcg_gen_ext16u_i32(tcg_rn, tcg_rn);
        if (dtype == 0) {
            /* Half to single */
            TCGv_i32 tcg_rd = tcg_temp_new_i32();
            gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp);
            write_fp_sreg(s, rd, tcg_rd);
        } else {
            /* Half to double */
            TCGv_i64 tcg_rd = tcg_temp_new_i64();
            gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp);
            write_fp_dreg(s, rd, tcg_rd);
        }
        break;
    }
    default:
        g_assert_not_reached();
    }
}

/* Floating point data-processing (1 source)
 *   31  30  29 28       24 23  22  21 20    15 14       10 9    5 4    0
 * +---+---+---+-----------+------+---+--------+-----------+------+------+
 * | M | 0 | S | 1 1 1 1 0 | type | 1 | opcode | 1 0 0 0 0 |  Rn  |  Rd  |
 * +---+---+---+-----------+------+---+--------+-----------+------+------+
 */
static void disas_fp_1src(DisasContext *s, uint32_t insn)
{
    int mos = extract32(insn, 29, 3);
    int type = extract32(insn, 22, 2);
    int opcode = extract32(insn, 15, 6);
    int rn = extract32(insn, 5, 5);
    int rd = extract32(insn, 0, 5);

    if (mos) {
        goto do_unallocated;
    }

    switch (opcode) {
    case 0x4: case 0x5: case 0x7:
    {
        /* FCVT between half, single and double precision */
        int dtype = extract32(opcode, 0, 2);
        if (type == 2 || dtype == type) {
            goto do_unallocated;
        }
        if (!fp_access_check(s)) {
            return;
        }

        handle_fp_fcvt(s, opcode, rd, rn, dtype, type);
        break;
    }

    case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */
        if (type > 1 || !dc_isar_feature(aa64_frint, s)) {
            goto do_unallocated;
        }
        /* fall through */
    case 0x0 ... 0x3:
    case 0x8 ... 0xc:
    case 0xe ... 0xf:
        /* 32-to-32 and 64-to-64 ops */
        switch (type) {
        case 0:
            if (!fp_access_check(s)) {
                return;
            }
            handle_fp_1src_single(s, opcode, rd, rn);
            break;
        case 1:
            if (!fp_access_check(s)) {
                return;
            }
            handle_fp_1src_double(s, opcode, rd, rn);
            break;
        case 3:
            if (!dc_isar_feature(aa64_fp16, s)) {
                goto do_unallocated;
            }

            if (!fp_access_check(s)) {
                return;
            }
            handle_fp_1src_half(s, opcode, rd, rn);
            break;
        default:
            goto do_unallocated;
        }
        break;

    case 0x6:
        switch (type) {
        case 1: /* BFCVT */
            if (!dc_isar_feature(aa64_bf16, s)) {
                goto do_unallocated;
            }
            if (!fp_access_check(s)) {
                return;
            }
            handle_fp_1src_single(s, opcode, rd, rn);
            break;
        default:
            goto do_unallocated;
        }
        break;

    default:
    do_unallocated:
        unallocated_encoding(s);
        break;
    }
}

/* Floating-point data-processing (3 source) - single precision */
static void handle_fp_3src_single(DisasContext *s, bool o0, bool o1,
                                  int rd, int rn, int rm, int ra)
{
    TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
    TCGv_i32 tcg_res = tcg_temp_new_i32();
    TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);

    tcg_op1 = read_fp_sreg(s, rn);
    tcg_op2 = read_fp_sreg(s, rm);
    tcg_op3 = read_fp_sreg(s, ra);

    /* These are fused multiply-add, and must be done as one
     * floating point operation with no rounding between the
     * multiplication and addition steps.
     * NB that doing the negations here as separate steps is
     * correct : an input NaN should come out with its sign bit
     * flipped if it is a negated-input.
     */
    if (o1 == true) {
        gen_vfp_negs(tcg_op3, tcg_op3);
    }

    if (o0 != o1) {
        gen_vfp_negs(tcg_op1, tcg_op1);
    }

    gen_helper_vfp_muladds(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);

    write_fp_sreg(s, rd, tcg_res);
}

/* Floating-point data-processing (3 source) - double precision */
static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
                                  int rd, int rn, int rm, int ra)
{
    TCGv_i64 tcg_op1, tcg_op2, tcg_op3;
    TCGv_i64 tcg_res = tcg_temp_new_i64();
    TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);

    tcg_op1 = read_fp_dreg(s, rn);
    tcg_op2 = read_fp_dreg(s, rm);
    tcg_op3 = read_fp_dreg(s, ra);

    /* These are fused multiply-add, and must be done as one
     * floating point operation with no rounding between the
     * multiplication and addition steps.
     * NB that doing the negations here as separate steps is
     * correct : an input NaN should come out with its sign bit
     * flipped if it is a negated-input.
     */
    if (o1 == true) {
        gen_vfp_negd(tcg_op3, tcg_op3);
    }

    if (o0 != o1) {
        gen_vfp_negd(tcg_op1, tcg_op1);
    }

    gen_helper_vfp_muladdd(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);

    write_fp_dreg(s, rd, tcg_res);
}

/* Floating-point data-processing (3 source) - half precision */
static void handle_fp_3src_half(DisasContext *s, bool o0, bool o1,
                                int rd, int rn, int rm, int ra)
{
    TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
    TCGv_i32 tcg_res = tcg_temp_new_i32();
    TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR_F16);

    tcg_op1 = read_fp_hreg(s, rn);
    tcg_op2 = read_fp_hreg(s, rm);
    tcg_op3 = read_fp_hreg(s, ra);

    /* These are fused multiply-add, and must be done as one
     * floating point operation with no rounding between the
     * multiplication and addition steps.
     * NB that doing the negations here as separate steps is
     * correct : an input NaN should come out with its sign bit
     * flipped if it is a negated-input.
     */
    if (o1 == true) {
        tcg_gen_xori_i32(tcg_op3, tcg_op3, 0x8000);
    }

    if (o0 != o1) {
        tcg_gen_xori_i32(tcg_op1, tcg_op1, 0x8000);
    }

    gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);

    write_fp_sreg(s, rd, tcg_res);
}

/* Floating point data-processing (3 source)
 *   31  30  29 28       24 23  22  21  20  16  15  14  10 9    5 4    0
 * +---+---+---+-----------+------+----+------+----+------+------+------+
 * | M | 0 | S | 1 1 1 1 1 | type | o1 |  Rm  | o0 |  Ra  |  Rn  |  Rd  |
 * +---+---+---+-----------+------+----+------+----+------+------+------+
 */
static void disas_fp_3src(DisasContext *s, uint32_t insn)
{
    int mos = extract32(insn, 29, 3);
    int type = extract32(insn, 22, 2);
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int ra = extract32(insn, 10, 5);
    int rm = extract32(insn, 16, 5);
    bool o0 = extract32(insn, 15, 1);
    bool o1 = extract32(insn, 21, 1);

    if (mos) {
        unallocated_encoding(s);
        return;
    }

    switch (type) {
    case 0:
        if (!fp_access_check(s)) {
            return;
        }
        handle_fp_3src_single(s, o0, o1, rd, rn, rm, ra);
        break;
    case 1:
        if (!fp_access_check(s)) {
            return;
        }
        handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
        break;
    case 3:
        if (!dc_isar_feature(aa64_fp16, s)) {
            unallocated_encoding(s);
            return;
        }
        if (!fp_access_check(s)) {
            return;
        }
        handle_fp_3src_half(s, o0, o1, rd, rn, rm, ra);
        break;
    default:
        unallocated_encoding(s);
    }
}

/* Floating point immediate
 *   31  30  29 28       24 23  22  21 20        13 12   10 9    5 4    0
 * +---+---+---+-----------+------+---+------------+-------+------+------+
 * | M | 0 | S | 1 1 1 1 0 | type | 1 |    imm8    | 1 0 0 | imm5 |  Rd  |
 * +---+---+---+-----------+------+---+------------+-------+------+------+
 */
static void disas_fp_imm(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int imm5 = extract32(insn, 5, 5);
    int imm8 = extract32(insn, 13, 8);
    int type = extract32(insn, 22, 2);
    int mos = extract32(insn, 29, 3);
    uint64_t imm;
    MemOp sz;

    if (mos || imm5) {
        unallocated_encoding(s);
        return;
    }

    switch (type) {
    case 0:
        sz = MO_32;
        break;
    case 1:
        sz = MO_64;
        break;
    case 3:
        sz = MO_16;
        if (dc_isar_feature(aa64_fp16, s)) {
            break;
        }
        /* fallthru */
    default:
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    imm = vfp_expand_imm(sz, imm8);
    write_fp_dreg(s, rd, tcg_constant_i64(imm));
}

/* Handle floating point <=> fixed point conversions. Note that we can
 * also deal with fp <=> integer conversions as a special case (scale == 64)
 * OPTME: consider handling that special case specially or at least skipping
 * the call to scalbn in the helpers for zero shifts.
 */
static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
                           bool itof, int rmode, int scale, int sf, int type)
{
    bool is_signed = !(opcode & 1);
    TCGv_ptr tcg_fpstatus;
    TCGv_i32 tcg_shift, tcg_single;
    TCGv_i64 tcg_double;

    tcg_fpstatus = fpstatus_ptr(type == 3 ? FPST_FPCR_F16 : FPST_FPCR);

    tcg_shift = tcg_constant_i32(64 - scale);

    if (itof) {
        TCGv_i64 tcg_int = cpu_reg(s, rn);
        if (!sf) {
            TCGv_i64 tcg_extend = tcg_temp_new_i64();

            if (is_signed) {
                tcg_gen_ext32s_i64(tcg_extend, tcg_int);
            } else {
                tcg_gen_ext32u_i64(tcg_extend, tcg_int);
            }

            tcg_int = tcg_extend;
        }

        switch (type) {
        case 1: /* float64 */
            tcg_double = tcg_temp_new_i64();
            if (is_signed) {
                gen_helper_vfp_sqtod(tcg_double, tcg_int,
                                     tcg_shift, tcg_fpstatus);
            } else {
                gen_helper_vfp_uqtod(tcg_double, tcg_int,
                                     tcg_shift, tcg_fpstatus);
            }
            write_fp_dreg(s, rd, tcg_double);
            break;

        case 0: /* float32 */
            tcg_single = tcg_temp_new_i32();
            if (is_signed) {
                gen_helper_vfp_sqtos(tcg_single, tcg_int,
                                     tcg_shift, tcg_fpstatus);
            } else {
                gen_helper_vfp_uqtos(tcg_single, tcg_int,
                                     tcg_shift, tcg_fpstatus);
            }
            write_fp_sreg(s, rd, tcg_single);
            break;

        case 3: /* float16 */
            tcg_single = tcg_temp_new_i32();
            if (is_signed) {
                gen_helper_vfp_sqtoh(tcg_single, tcg_int,
                                     tcg_shift, tcg_fpstatus);
            } else {
                gen_helper_vfp_uqtoh(tcg_single, tcg_int,
                                     tcg_shift, tcg_fpstatus);
            }
            write_fp_sreg(s, rd, tcg_single);
            break;

        default:
            g_assert_not_reached();
        }
    } else {
        TCGv_i64 tcg_int = cpu_reg(s, rd);
        TCGv_i32 tcg_rmode;

        if (extract32(opcode, 2, 1)) {
            /* There are too many rounding modes to all fit into rmode,
             * so FCVTA[US] is a special case.
             */
            rmode = FPROUNDING_TIEAWAY;
        }

        tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus);

        switch (type) {
        case 1: /* float64 */
            tcg_double = read_fp_dreg(s, rn);
            if (is_signed) {
                if (!sf) {
                    gen_helper_vfp_tosld(tcg_int, tcg_double,
                                         tcg_shift, tcg_fpstatus);
                } else {
                    gen_helper_vfp_tosqd(tcg_int, tcg_double,
                                         tcg_shift, tcg_fpstatus);
                }
            } else {
                if (!sf) {
                    gen_helper_vfp_tould(tcg_int, tcg_double,
                                         tcg_shift, tcg_fpstatus);
                } else {
                    gen_helper_vfp_touqd(tcg_int, tcg_double,
                                         tcg_shift, tcg_fpstatus);
                }
            }
            if (!sf) {
                tcg_gen_ext32u_i64(tcg_int, tcg_int);
            }
            break;

        case 0: /* float32 */
            tcg_single = read_fp_sreg(s, rn);
            if (sf) {
                if (is_signed) {
                    gen_helper_vfp_tosqs(tcg_int, tcg_single,
                                         tcg_shift, tcg_fpstatus);
                } else {
                    gen_helper_vfp_touqs(tcg_int, tcg_single,
                                         tcg_shift, tcg_fpstatus);
                }
            } else {
                TCGv_i32 tcg_dest = tcg_temp_new_i32();
                if (is_signed) {
                    gen_helper_vfp_tosls(tcg_dest, tcg_single,
                                         tcg_shift, tcg_fpstatus);
                } else {
                    gen_helper_vfp_touls(tcg_dest, tcg_single,
                                         tcg_shift, tcg_fpstatus);
                }
                tcg_gen_extu_i32_i64(tcg_int, tcg_dest);
            }
            break;

        case 3: /* float16 */
            tcg_single = read_fp_sreg(s, rn);
            if (sf) {
                if (is_signed) {
                    gen_helper_vfp_tosqh(tcg_int, tcg_single,
                                         tcg_shift, tcg_fpstatus);
                } else {
                    gen_helper_vfp_touqh(tcg_int, tcg_single,
                                         tcg_shift, tcg_fpstatus);
                }
            } else {
                TCGv_i32 tcg_dest = tcg_temp_new_i32();
                if (is_signed) {
                    gen_helper_vfp_toslh(tcg_dest, tcg_single,
                                         tcg_shift, tcg_fpstatus);
                } else {
                    gen_helper_vfp_toulh(tcg_dest, tcg_single,
                                         tcg_shift, tcg_fpstatus);
                }
                tcg_gen_extu_i32_i64(tcg_int, tcg_dest);
            }
            break;

        default:
            g_assert_not_reached();
        }

        gen_restore_rmode(tcg_rmode, tcg_fpstatus);
    }
}

/* Floating point <-> fixed point conversions
 *   31   30  29 28       24 23  22  21 20   19 18    16 15   10 9    5 4    0
 * +----+---+---+-----------+------+---+-------+--------+-------+------+------+
 * | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opcode | scale |  Rn  |  Rd  |
 * +----+---+---+-----------+------+---+-------+--------+-------+------+------+
 */
static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int scale = extract32(insn, 10, 6);
    int opcode = extract32(insn, 16, 3);
    int rmode = extract32(insn, 19, 2);
    int type = extract32(insn, 22, 2);
    bool sbit = extract32(insn, 29, 1);
    bool sf = extract32(insn, 31, 1);
    bool itof;

    if (sbit || (!sf && scale < 32)) {
        unallocated_encoding(s);
        return;
    }

    switch (type) {
    case 0: /* float32 */
    case 1: /* float64 */
        break;
    case 3: /* float16 */
        if (dc_isar_feature(aa64_fp16, s)) {
            break;
        }
        /* fallthru */
    default:
        unallocated_encoding(s);
        return;
    }

    switch ((rmode << 3) | opcode) {
    case 0x2: /* SCVTF */
    case 0x3: /* UCVTF */
        itof = true;
        break;
    case 0x18: /* FCVTZS */
    case 0x19: /* FCVTZU */
        itof = false;
        break;
    default:
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    handle_fpfpcvt(s, rd, rn, opcode, itof, FPROUNDING_ZERO, scale, sf, type);
}

static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
{
    /* FMOV: gpr to or from float, double, or top half of quad fp reg,
     * without conversion.
     */

    if (itof) {
        TCGv_i64 tcg_rn = cpu_reg(s, rn);
        TCGv_i64 tmp;

        switch (type) {
        case 0:
            /* 32 bit */
            tmp = tcg_temp_new_i64();
            tcg_gen_ext32u_i64(tmp, tcg_rn);
            write_fp_dreg(s, rd, tmp);
            break;
        case 1:
            /* 64 bit */
            write_fp_dreg(s, rd, tcg_rn);
            break;
        case 2:
            /* 64 bit to top half. */
            tcg_gen_st_i64(tcg_rn, tcg_env, fp_reg_hi_offset(s, rd));
            clear_vec_high(s, true, rd);
            break;
        case 3:
            /* 16 bit */
            tmp = tcg_temp_new_i64();
            tcg_gen_ext16u_i64(tmp, tcg_rn);
            write_fp_dreg(s, rd, tmp);
            break;
        default:
            g_assert_not_reached();
        }
    } else {
        TCGv_i64 tcg_rd = cpu_reg(s, rd);

        switch (type) {
        case 0:
            /* 32 bit */
            tcg_gen_ld32u_i64(tcg_rd, tcg_env, fp_reg_offset(s, rn, MO_32));
            break;
        case 1:
            /* 64 bit */
            tcg_gen_ld_i64(tcg_rd, tcg_env, fp_reg_offset(s, rn, MO_64));
            break;
        case 2:
            /* 64 bits from top half */
            tcg_gen_ld_i64(tcg_rd, tcg_env, fp_reg_hi_offset(s, rn));
            break;
        case 3:
            /* 16 bit */
            tcg_gen_ld16u_i64(tcg_rd, tcg_env, fp_reg_offset(s, rn, MO_16));
            break;
        default:
            g_assert_not_reached();
        }
    }
}

static void handle_fjcvtzs(DisasContext *s, int rd, int rn)
{
    TCGv_i64 t = read_fp_dreg(s, rn);
    TCGv_ptr fpstatus = fpstatus_ptr(FPST_FPCR);

    gen_helper_fjcvtzs(t, t, fpstatus);

    tcg_gen_ext32u_i64(cpu_reg(s, rd), t);
    tcg_gen_extrh_i64_i32(cpu_ZF, t);
    tcg_gen_movi_i32(cpu_CF, 0);
    tcg_gen_movi_i32(cpu_NF, 0);
    tcg_gen_movi_i32(cpu_VF, 0);
}

/* Floating point <-> integer conversions
 *   31   30  29 28       24 23  22  21 20   19 18 16 15         10 9  5 4  0
 * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
 * | sf | 0 | S | 1 1 1 1 0 | type | 1 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd |
 * +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
 */
static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int opcode = extract32(insn, 16, 3);
    int rmode = extract32(insn, 19, 2);
    int type = extract32(insn, 22, 2);
    bool sbit = extract32(insn, 29, 1);
    bool sf = extract32(insn, 31, 1);
    bool itof = false;

    if (sbit) {
        goto do_unallocated;
    }

    switch (opcode) {
    case 2: /* SCVTF */
    case 3: /* UCVTF */
        itof = true;
        /* fallthru */
    case 4: /* FCVTAS */
    case 5: /* FCVTAU */
        if (rmode != 0) {
            goto do_unallocated;
        }
        /* fallthru */
    case 0: /* FCVT[NPMZ]S */
    case 1: /* FCVT[NPMZ]U */
        switch (type) {
        case 0: /* float32 */
        case 1: /* float64 */
            break;
        case 3: /* float16 */
            if (!dc_isar_feature(aa64_fp16, s)) {
                goto do_unallocated;
            }
            break;
        default:
            goto do_unallocated;
        }
        if (!fp_access_check(s)) {
            return;
        }
        handle_fpfpcvt(s, rd, rn, opcode, itof, rmode, 64, sf, type);
        break;

    default:
        switch (sf << 7 | type << 5 | rmode << 3 | opcode) {
        case 0b01100110: /* FMOV half <-> 32-bit int */
        case 0b01100111:
        case 0b11100110: /* FMOV half <-> 64-bit int */
        case 0b11100111:
            if (!dc_isar_feature(aa64_fp16, s)) {
                goto do_unallocated;
            }
            /* fallthru */
        case 0b00000110: /* FMOV 32-bit */
        case 0b00000111:
        case 0b10100110: /* FMOV 64-bit */
        case 0b10100111:
        case 0b11001110: /* FMOV top half of 128-bit */
        case 0b11001111:
            if (!fp_access_check(s)) {
                return;
            }
            itof = opcode & 1;
            handle_fmov(s, rd, rn, type, itof);
            break;

        case 0b00111110: /* FJCVTZS */
            if (!dc_isar_feature(aa64_jscvt, s)) {
                goto do_unallocated;
            } else if (fp_access_check(s)) {
                handle_fjcvtzs(s, rd, rn);
            }
            break;

        default:
        do_unallocated:
            unallocated_encoding(s);
            return;
        }
        break;
    }
}

/* FP-specific subcases of table C3-6 (SIMD and FP data processing)
 *   31  30  29 28     25 24                          0
 * +---+---+---+---------+-----------------------------+
 * |   | 0 |   | 1 1 1 1 |                             |
 * +---+---+---+---------+-----------------------------+
 */
static void disas_data_proc_fp(DisasContext *s, uint32_t insn)
{
    if (extract32(insn, 24, 1)) {
        /* Floating point data-processing (3 source) */
        disas_fp_3src(s, insn);
    } else if (extract32(insn, 21, 1) == 0) {
        /* Floating point to fixed point conversions */
        disas_fp_fixed_conv(s, insn);
    } else {
        switch (extract32(insn, 10, 2)) {
        case 1:
            /* Floating point conditional compare */
            disas_fp_ccomp(s, insn);
            break;
        case 2:
            /* Floating point data-processing (2 source) */
            unallocated_encoding(s); /* in decodetree */
            break;
        case 3:
            /* Floating point conditional select */
            disas_fp_csel(s, insn);
            break;
        case 0:
            switch (ctz32(extract32(insn, 12, 4))) {
            case 0: /* [15:12] == xxx1 */
                /* Floating point immediate */
                disas_fp_imm(s, insn);
                break;
            case 1: /* [15:12] == xx10 */
                /* Floating point compare */
                disas_fp_compare(s, insn);
                break;
            case 2: /* [15:12] == x100 */
                /* Floating point data-processing (1 source) */
                disas_fp_1src(s, insn);
                break;
            case 3: /* [15:12] == 1000 */
                unallocated_encoding(s);
                break;
            default: /* [15:12] == 0000 */
                /* Floating point <-> integer conversions */
                disas_fp_int_conv(s, insn);
                break;
            }
            break;
        }
    }
}

static void do_ext64(DisasContext *s, TCGv_i64 tcg_left, TCGv_i64 tcg_right,
                     int pos)
{
    /* Extract 64 bits from the middle of two concatenated 64 bit
     * vector register slices left:right. The extracted bits start
     * at 'pos' bits into the right (least significant) side.
     * We return the result in tcg_right, and guarantee not to
     * trash tcg_left.
     */
    TCGv_i64 tcg_tmp = tcg_temp_new_i64();
    assert(pos > 0 && pos < 64);

    tcg_gen_shri_i64(tcg_right, tcg_right, pos);
    tcg_gen_shli_i64(tcg_tmp, tcg_left, 64 - pos);
    tcg_gen_or_i64(tcg_right, tcg_right, tcg_tmp);
}

/* EXT
 *   31  30 29         24 23 22  21 20  16 15  14  11 10  9    5 4    0
 * +---+---+-------------+-----+---+------+---+------+---+------+------+
 * | 0 | Q | 1 0 1 1 1 0 | op2 | 0 |  Rm  | 0 | imm4 | 0 |  Rn  |  Rd  |
 * +---+---+-------------+-----+---+------+---+------+---+------+------+
 */
static void disas_simd_ext(DisasContext *s, uint32_t insn)
{
    int is_q = extract32(insn, 30, 1);
    int op2 = extract32(insn, 22, 2);
    int imm4 = extract32(insn, 11, 4);
    int rm = extract32(insn, 16, 5);
    int rn = extract32(insn, 5, 5);
    int rd = extract32(insn, 0, 5);
    int pos = imm4 << 3;
    TCGv_i64 tcg_resl, tcg_resh;

    if (op2 != 0 || (!is_q && extract32(imm4, 3, 1))) {
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    tcg_resh = tcg_temp_new_i64();
    tcg_resl = tcg_temp_new_i64();

    /* Vd gets bits starting at pos bits into Vm:Vn. This is
     * either extracting 128 bits from a 128:128 concatenation, or
     * extracting 64 bits from a 64:64 concatenation.
     */
    if (!is_q) {
        read_vec_element(s, tcg_resl, rn, 0, MO_64);
        if (pos != 0) {
            read_vec_element(s, tcg_resh, rm, 0, MO_64);
            do_ext64(s, tcg_resh, tcg_resl, pos);
        }
    } else {
        TCGv_i64 tcg_hh;
        typedef struct {
            int reg;
            int elt;
        } EltPosns;
        EltPosns eltposns[] = { {rn, 0}, {rn, 1}, {rm, 0}, {rm, 1} };
        EltPosns *elt = eltposns;

        if (pos >= 64) {
            elt++;
            pos -= 64;
        }

        read_vec_element(s, tcg_resl, elt->reg, elt->elt, MO_64);
        elt++;
        read_vec_element(s, tcg_resh, elt->reg, elt->elt, MO_64);
        elt++;
        if (pos != 0) {
            do_ext64(s, tcg_resh, tcg_resl, pos);
            tcg_hh = tcg_temp_new_i64();
            read_vec_element(s, tcg_hh, elt->reg, elt->elt, MO_64);
            do_ext64(s, tcg_hh, tcg_resh, pos);
        }
    }

    write_vec_element(s, tcg_resl, rd, 0, MO_64);
    if (is_q) {
        write_vec_element(s, tcg_resh, rd, 1, MO_64);
    }
    clear_vec_high(s, is_q, rd);
}

/* TBL/TBX
 *   31  30 29         24 23 22  21 20  16 15  14 13  12  11 10 9    5 4    0
 * +---+---+-------------+-----+---+------+---+-----+----+-----+------+------+
 * | 0 | Q | 0 0 1 1 1 0 | op2 | 0 |  Rm  | 0 | len | op | 0 0 |  Rn  |  Rd  |
 * +---+---+-------------+-----+---+------+---+-----+----+-----+------+------+
 */
static void disas_simd_tb(DisasContext *s, uint32_t insn)
{
    int op2 = extract32(insn, 22, 2);
    int is_q = extract32(insn, 30, 1);
    int rm = extract32(insn, 16, 5);
    int rn = extract32(insn, 5, 5);
    int rd = extract32(insn, 0, 5);
    int is_tbx = extract32(insn, 12, 1);
    int len = (extract32(insn, 13, 2) + 1) * 16;

    if (op2 != 0) {
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd),
                       vec_full_reg_offset(s, rm), tcg_env,
                       is_q ? 16 : 8, vec_full_reg_size(s),
                       (len << 6) | (is_tbx << 5) | rn,
                       gen_helper_simd_tblx);
}

/* ZIP/UZP/TRN
 *   31  30 29         24 23  22  21 20   16 15 14 12 11 10 9    5 4    0
 * +---+---+-------------+------+---+------+---+------------------+------+
 * | 0 | Q | 0 0 1 1 1 0 | size | 0 |  Rm  | 0 | opc | 1 0 |  Rn  |  Rd  |
 * +---+---+-------------+------+---+------+---+------------------+------+
 */
static void disas_simd_zip_trn(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int rm = extract32(insn, 16, 5);
    int size = extract32(insn, 22, 2);
    /* opc field bits [1:0] indicate ZIP/UZP/TRN;
     * bit 2 indicates 1 vs 2 variant of the insn.
     */
    int opcode = extract32(insn, 12, 2);
    bool part = extract32(insn, 14, 1);
    bool is_q = extract32(insn, 30, 1);
    int esize = 8 << size;
    int i;
    int datasize = is_q ? 128 : 64;
    int elements = datasize / esize;
    TCGv_i64 tcg_res[2], tcg_ele;

    if (opcode == 0 || (size == 3 && !is_q)) {
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    tcg_res[0] = tcg_temp_new_i64();
    tcg_res[1] = is_q ? tcg_temp_new_i64() : NULL;
    tcg_ele = tcg_temp_new_i64();

    for (i = 0; i < elements; i++) {
        int o, w;

        switch (opcode) {
        case 1: /* UZP1/2 */
        {
            int midpoint = elements / 2;
            if (i < midpoint) {
                read_vec_element(s, tcg_ele, rn, 2 * i + part, size);
            } else {
                read_vec_element(s, tcg_ele, rm,
                                 2 * (i - midpoint) + part, size);
            }
            break;
        }
        case 2: /* TRN1/2 */
            if (i & 1) {
                read_vec_element(s, tcg_ele, rm, (i & ~1) + part, size);
            } else {
                read_vec_element(s, tcg_ele, rn, (i & ~1) + part, size);
            }
            break;
        case 3: /* ZIP1/2 */
        {
            int base = part * elements / 2;
            if (i & 1) {
                read_vec_element(s, tcg_ele, rm, base + (i >> 1), size);
            } else {
                read_vec_element(s, tcg_ele, rn, base + (i >> 1), size);
            }
            break;
        }
        default:
            g_assert_not_reached();
        }

        w = (i * esize) / 64;
        o = (i * esize) % 64;
        if (o == 0) {
            tcg_gen_mov_i64(tcg_res[w], tcg_ele);
        } else {
            tcg_gen_shli_i64(tcg_ele, tcg_ele, o);
            tcg_gen_or_i64(tcg_res[w], tcg_res[w], tcg_ele);
        }
    }

    for (i = 0; i <= is_q; ++i) {
        write_vec_element(s, tcg_res[i], rd, i, MO_64);
    }
    clear_vec_high(s, is_q, rd);
}

/*
 * do_reduction_op helper
 *
 * This mirrors the Reduce() pseudocode in the ARM ARM. It is
 * important for correct NaN propagation that we do these
 * operations in exactly the order specified by the pseudocode.
 *
 * This is a recursive function, TCG temps should be freed by the
 * calling function once it is done with the values.
 */
static TCGv_i32 do_reduction_op(DisasContext *s, int fpopcode, int rn,
                                int esize, int size, int vmap, TCGv_ptr fpst)
{
    if (esize == size) {
        int element;
        MemOp msize = esize == 16 ? MO_16 : MO_32;
        TCGv_i32 tcg_elem;

        /* We should have one register left here */
        assert(ctpop8(vmap) == 1);
        element = ctz32(vmap);
        assert(element < 8);

        tcg_elem = tcg_temp_new_i32();
        read_vec_element_i32(s, tcg_elem, rn, element, msize);
        return tcg_elem;
    } else {
        int bits = size / 2;
        int shift = ctpop8(vmap) / 2;
        int vmap_lo = (vmap >> shift) & vmap;
        int vmap_hi = (vmap & ~vmap_lo);
        TCGv_i32 tcg_hi, tcg_lo, tcg_res;

        tcg_hi = do_reduction_op(s, fpopcode, rn, esize, bits, vmap_hi, fpst);
        tcg_lo = do_reduction_op(s, fpopcode, rn, esize, bits, vmap_lo, fpst);
        tcg_res = tcg_temp_new_i32();

        switch (fpopcode) {
        case 0x0c: /* fmaxnmv half-precision */
            gen_helper_advsimd_maxnumh(tcg_res, tcg_lo, tcg_hi, fpst);
            break;
        case 0x0f: /* fmaxv half-precision */
            gen_helper_advsimd_maxh(tcg_res, tcg_lo, tcg_hi, fpst);
            break;
        case 0x1c: /* fminnmv half-precision */
            gen_helper_advsimd_minnumh(tcg_res, tcg_lo, tcg_hi, fpst);
            break;
        case 0x1f: /* fminv half-precision */
            gen_helper_advsimd_minh(tcg_res, tcg_lo, tcg_hi, fpst);
            break;
        case 0x2c: /* fmaxnmv */
            gen_helper_vfp_maxnums(tcg_res, tcg_lo, tcg_hi, fpst);
            break;
        case 0x2f: /* fmaxv */
            gen_helper_vfp_maxs(tcg_res, tcg_lo, tcg_hi, fpst);
            break;
        case 0x3c: /* fminnmv */
            gen_helper_vfp_minnums(tcg_res, tcg_lo, tcg_hi, fpst);
            break;
        case 0x3f: /* fminv */
            gen_helper_vfp_mins(tcg_res, tcg_lo, tcg_hi, fpst);
            break;
        default:
            g_assert_not_reached();
        }
        return tcg_res;
    }
}

/* AdvSIMD across lanes
 *   31  30  29 28       24 23  22 21       17 16    12 11 10 9    5 4    0
 * +---+---+---+-----------+------+-----------+--------+-----+------+------+
 * | 0 | Q | U | 0 1 1 1 0 | size | 1 1 0 0 0 | opcode | 1 0 |  Rn  |  Rd  |
 * +---+---+---+-----------+------+-----------+--------+-----+------+------+
 */
static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int size = extract32(insn, 22, 2);
    int opcode = extract32(insn, 12, 5);
    bool is_q = extract32(insn, 30, 1);
    bool is_u = extract32(insn, 29, 1);
    bool is_fp = false;
    bool is_min = false;
    int esize;
    int elements;
    int i;
    TCGv_i64 tcg_res, tcg_elt;

    switch (opcode) {
    case 0x1b: /* ADDV */
        if (is_u) {
            unallocated_encoding(s);
            return;
        }
        /* fall through */
    case 0x3: /* SADDLV, UADDLV */
    case 0xa: /* SMAXV, UMAXV */
    case 0x1a: /* SMINV, UMINV */
        if (size == 3 || (size == 2 && !is_q)) {
            unallocated_encoding(s);
            return;
        }
        break;
    case 0xc: /* FMAXNMV, FMINNMV */
    case 0xf: /* FMAXV, FMINV */
        /* Bit 1 of size field encodes min vs max and the actual size
         * depends on the encoding of the U bit. If not set (and FP16
         * enabled) then we do half-precision float instead of single
         * precision.
         */
        is_min = extract32(size, 1, 1);
        is_fp = true;
        if (!is_u && dc_isar_feature(aa64_fp16, s)) {
            size = 1;
        } else if (!is_u || !is_q || extract32(size, 0, 1)) {
            unallocated_encoding(s);
            return;
        } else {
            size = 2;
        }
        break;
    default:
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    esize = 8 << size;
    elements = (is_q ? 128 : 64) / esize;

    tcg_res = tcg_temp_new_i64();
    tcg_elt = tcg_temp_new_i64();

    /* These instructions operate across all lanes of a vector
     * to produce a single result. We can guarantee that a 64
     * bit intermediate is sufficient:
     *  + for [US]ADDLV the maximum element size is 32 bits, and
     *    the result type is 64 bits
     *  + for FMAX*V, FMIN*V, ADDV the intermediate type is the
     *    same as the element size, which is 32 bits at most
     * For the integer operations we can choose to work at 64
     * or 32 bits and truncate at the end; for simplicity
     * we use 64 bits always. The floating point
     * ops do require 32 bit intermediates, though.
     */
    if (!is_fp) {
        read_vec_element(s, tcg_res, rn, 0, size | (is_u ? 0 : MO_SIGN));

        for (i = 1; i < elements; i++) {
            read_vec_element(s, tcg_elt, rn, i, size | (is_u ? 0 : MO_SIGN));

            switch (opcode) {
            case 0x03: /* SADDLV / UADDLV */
            case 0x1b: /* ADDV */
                tcg_gen_add_i64(tcg_res, tcg_res, tcg_elt);
                break;
            case 0x0a: /* SMAXV / UMAXV */
                if (is_u) {
                    tcg_gen_umax_i64(tcg_res, tcg_res, tcg_elt);
                } else {
                    tcg_gen_smax_i64(tcg_res, tcg_res, tcg_elt);
                }
                break;
            case 0x1a: /* SMINV / UMINV */
                if (is_u) {
                    tcg_gen_umin_i64(tcg_res, tcg_res, tcg_elt);
                } else {
                    tcg_gen_smin_i64(tcg_res, tcg_res, tcg_elt);
                }
                break;
            default:
                g_assert_not_reached();
            }

        }
    } else {
        /* Floating point vector reduction ops which work across 32
         * bit (single) or 16 bit (half-precision) intermediates.
         * Note that correct NaN propagation requires that we do these
         * operations in exactly the order specified by the pseudocode.
         */
        TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
        int fpopcode = opcode | is_min << 4 | is_u << 5;
        int vmap = (1 << elements) - 1;
        TCGv_i32 tcg_res32 = do_reduction_op(s, fpopcode, rn, esize,
                                             (is_q ? 128 : 64), vmap, fpst);
        tcg_gen_extu_i32_i64(tcg_res, tcg_res32);
    }

    /* Now truncate the result to the width required for the final output */
    if (opcode == 0x03) {
        /* SADDLV, UADDLV: result is 2*esize */
        size++;
    }

    switch (size) {
    case 0:
        tcg_gen_ext8u_i64(tcg_res, tcg_res);
        break;
    case 1:
        tcg_gen_ext16u_i64(tcg_res, tcg_res);
        break;
    case 2:
        tcg_gen_ext32u_i64(tcg_res, tcg_res);
        break;
    case 3:
        break;
    default:
        g_assert_not_reached();
    }

    write_fp_dreg(s, rd, tcg_res);
}

/* AdvSIMD modified immediate
 *  31  30   29  28                 19 18 16 15   12  11  10  9     5 4    0
 * +---+---+----+---------------------+-----+-------+----+---+-------+------+
 * | 0 | Q | op | 0 1 1 1 1 0 0 0 0 0 | abc | cmode | o2 | 1 | defgh |  Rd  |
 * +---+---+----+---------------------+-----+-------+----+---+-------+------+
 *
 * There are a number of operations that can be carried out here:
 *   MOVI - move (shifted) imm into register
 *   MVNI - move inverted (shifted) imm into register
 *   ORR  - bitwise OR of (shifted) imm with register
 *   BIC  - bitwise clear of (shifted) imm with register
 * With ARMv8.2 we also have:
 *   FMOV half-precision
 */
static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int cmode = extract32(insn, 12, 4);
    int o2 = extract32(insn, 11, 1);
    uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
    bool is_neg = extract32(insn, 29, 1);
    bool is_q = extract32(insn, 30, 1);
    uint64_t imm = 0;

    if (o2) {
        if (cmode != 0xf || is_neg) {
            unallocated_encoding(s);
            return;
        }
        /* FMOV (vector, immediate) - half-precision */
        if (!dc_isar_feature(aa64_fp16, s)) {
            unallocated_encoding(s);
            return;
        }
        imm = vfp_expand_imm(MO_16, abcdefgh);
        /* now duplicate across the lanes */
        imm = dup_const(MO_16, imm);
    } else {
        if (cmode == 0xf && is_neg && !is_q) {
            unallocated_encoding(s);
            return;
        }
        imm = asimd_imm_const(abcdefgh, cmode, is_neg);
    }

    if (!fp_access_check(s)) {
        return;
    }

    if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
        /* MOVI or MVNI, with MVNI negation handled above.  */
        tcg_gen_gvec_dup_imm(MO_64, vec_full_reg_offset(s, rd), is_q ? 16 : 8,
                             vec_full_reg_size(s), imm);
    } else {
        /* ORR or BIC, with BIC negation to AND handled above.  */
        if (is_neg) {
            gen_gvec_fn2i(s, is_q, rd, rd, imm, tcg_gen_gvec_andi, MO_64);
        } else {
            gen_gvec_fn2i(s, is_q, rd, rd, imm, tcg_gen_gvec_ori, MO_64);
        }
    }
}

/* AdvSIMD scalar pairwise
 *  31 30  29 28       24 23  22 21       17 16    12 11 10 9    5 4    0
 * +-----+---+-----------+------+-----------+--------+-----+------+------+
 * | 0 1 | U | 1 1 1 1 0 | size | 1 1 0 0 0 | opcode | 1 0 |  Rn  |  Rd  |
 * +-----+---+-----------+------+-----------+--------+-----+------+------+
 */
static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
{
    int u = extract32(insn, 29, 1);
    int size = extract32(insn, 22, 2);
    int opcode = extract32(insn, 12, 5);
    int rn = extract32(insn, 5, 5);
    int rd = extract32(insn, 0, 5);
    TCGv_ptr fpst;

    /* For some ops (the FP ones), size[1] is part of the encoding.
     * For ADDP strictly it is not but size[1] is always 1 for valid
     * encodings.
     */
    opcode |= (extract32(size, 1, 1) << 5);

    switch (opcode) {
    case 0x3b: /* ADDP */
        if (u || size != 3) {
            unallocated_encoding(s);
            return;
        }
        if (!fp_access_check(s)) {
            return;
        }

        fpst = NULL;
        break;
    case 0xc: /* FMAXNMP */
    case 0xd: /* FADDP */
    case 0xf: /* FMAXP */
    case 0x2c: /* FMINNMP */
    case 0x2f: /* FMINP */
        /* FP op, size[0] is 32 or 64 bit*/
        if (!u) {
            if ((size & 1) || !dc_isar_feature(aa64_fp16, s)) {
                unallocated_encoding(s);
                return;
            } else {
                size = MO_16;
            }
        } else {
            size = extract32(size, 0, 1) ? MO_64 : MO_32;
        }

        if (!fp_access_check(s)) {
            return;
        }

        fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
        break;
    default:
        unallocated_encoding(s);
        return;
    }

    if (size == MO_64) {
        TCGv_i64 tcg_op1 = tcg_temp_new_i64();
        TCGv_i64 tcg_op2 = tcg_temp_new_i64();
        TCGv_i64 tcg_res = tcg_temp_new_i64();

        read_vec_element(s, tcg_op1, rn, 0, MO_64);
        read_vec_element(s, tcg_op2, rn, 1, MO_64);

        switch (opcode) {
        case 0x3b: /* ADDP */
            tcg_gen_add_i64(tcg_res, tcg_op1, tcg_op2);
            break;
        case 0xc: /* FMAXNMP */
            gen_helper_vfp_maxnumd(tcg_res, tcg_op1, tcg_op2, fpst);
            break;
        case 0xd: /* FADDP */
            gen_helper_vfp_addd(tcg_res, tcg_op1, tcg_op2, fpst);
            break;
        case 0xf: /* FMAXP */
            gen_helper_vfp_maxd(tcg_res, tcg_op1, tcg_op2, fpst);
            break;
        case 0x2c: /* FMINNMP */
            gen_helper_vfp_minnumd(tcg_res, tcg_op1, tcg_op2, fpst);
            break;
        case 0x2f: /* FMINP */
            gen_helper_vfp_mind(tcg_res, tcg_op1, tcg_op2, fpst);
            break;
        default:
            g_assert_not_reached();
        }

        write_fp_dreg(s, rd, tcg_res);
    } else {
        TCGv_i32 tcg_op1 = tcg_temp_new_i32();
        TCGv_i32 tcg_op2 = tcg_temp_new_i32();
        TCGv_i32 tcg_res = tcg_temp_new_i32();

        read_vec_element_i32(s, tcg_op1, rn, 0, size);
        read_vec_element_i32(s, tcg_op2, rn, 1, size);

        if (size == MO_16) {
            switch (opcode) {
            case 0xc: /* FMAXNMP */
                gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0xd: /* FADDP */
                gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0xf: /* FMAXP */
                gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x2c: /* FMINNMP */
                gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x2f: /* FMINP */
                gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            default:
                g_assert_not_reached();
            }
        } else {
            switch (opcode) {
            case 0xc: /* FMAXNMP */
                gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0xd: /* FADDP */
                gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0xf: /* FMAXP */
                gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x2c: /* FMINNMP */
                gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x2f: /* FMINP */
                gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            default:
                g_assert_not_reached();
            }
        }

        write_fp_sreg(s, rd, tcg_res);
    }
}

/*
 * Common SSHR[RA]/USHR[RA] - Shift right (optional rounding/accumulate)
 *
 * This code is handles the common shifting code and is used by both
 * the vector and scalar code.
 */
static void handle_shri_with_rndacc(TCGv_i64 tcg_res, TCGv_i64 tcg_src,
                                    TCGv_i64 tcg_rnd, bool accumulate,
                                    bool is_u, int size, int shift)
{
    bool extended_result = false;
    bool round = tcg_rnd != NULL;
    int ext_lshift = 0;
    TCGv_i64 tcg_src_hi;

    if (round && size == 3) {
        extended_result = true;
        ext_lshift = 64 - shift;
        tcg_src_hi = tcg_temp_new_i64();
    } else if (shift == 64) {
        if (!accumulate && is_u) {
            /* result is zero */
            tcg_gen_movi_i64(tcg_res, 0);
            return;
        }
    }

    /* Deal with the rounding step */
    if (round) {
        if (extended_result) {
            TCGv_i64 tcg_zero = tcg_constant_i64(0);
            if (!is_u) {
                /* take care of sign extending tcg_res */
                tcg_gen_sari_i64(tcg_src_hi, tcg_src, 63);
                tcg_gen_add2_i64(tcg_src, tcg_src_hi,
                                 tcg_src, tcg_src_hi,
                                 tcg_rnd, tcg_zero);
            } else {
                tcg_gen_add2_i64(tcg_src, tcg_src_hi,
                                 tcg_src, tcg_zero,
                                 tcg_rnd, tcg_zero);
            }
        } else {
            tcg_gen_add_i64(tcg_src, tcg_src, tcg_rnd);
        }
    }

    /* Now do the shift right */
    if (round && extended_result) {
        /* extended case, >64 bit precision required */
        if (ext_lshift == 0) {
            /* special case, only high bits matter */
            tcg_gen_mov_i64(tcg_src, tcg_src_hi);
        } else {
            tcg_gen_shri_i64(tcg_src, tcg_src, shift);
            tcg_gen_shli_i64(tcg_src_hi, tcg_src_hi, ext_lshift);
            tcg_gen_or_i64(tcg_src, tcg_src, tcg_src_hi);
        }
    } else {
        if (is_u) {
            if (shift == 64) {
                /* essentially shifting in 64 zeros */
                tcg_gen_movi_i64(tcg_src, 0);
            } else {
                tcg_gen_shri_i64(tcg_src, tcg_src, shift);
            }
        } else {
            if (shift == 64) {
                /* effectively extending the sign-bit */
                tcg_gen_sari_i64(tcg_src, tcg_src, 63);
            } else {
                tcg_gen_sari_i64(tcg_src, tcg_src, shift);
            }
        }
    }

    if (accumulate) {
        tcg_gen_add_i64(tcg_res, tcg_res, tcg_src);
    } else {
        tcg_gen_mov_i64(tcg_res, tcg_src);
    }
}

/* SSHR[RA]/USHR[RA] - Scalar shift right (optional rounding/accumulate) */
static void handle_scalar_simd_shri(DisasContext *s,
                                    bool is_u, int immh, int immb,
                                    int opcode, int rn, int rd)
{
    const int size = 3;
    int immhb = immh << 3 | immb;
    int shift = 2 * (8 << size) - immhb;
    bool accumulate = false;
    bool round = false;
    bool insert = false;
    TCGv_i64 tcg_rn;
    TCGv_i64 tcg_rd;
    TCGv_i64 tcg_round;

    if (!extract32(immh, 3, 1)) {
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    switch (opcode) {
    case 0x02: /* SSRA / USRA (accumulate) */
        accumulate = true;
        break;
    case 0x04: /* SRSHR / URSHR (rounding) */
        round = true;
        break;
    case 0x06: /* SRSRA / URSRA (accum + rounding) */
        accumulate = round = true;
        break;
    case 0x08: /* SRI */
        insert = true;
        break;
    }

    if (round) {
        tcg_round = tcg_constant_i64(1ULL << (shift - 1));
    } else {
        tcg_round = NULL;
    }

    tcg_rn = read_fp_dreg(s, rn);
    tcg_rd = (accumulate || insert) ? read_fp_dreg(s, rd) : tcg_temp_new_i64();

    if (insert) {
        /* shift count same as element size is valid but does nothing;
         * special case to avoid potential shift by 64.
         */
        int esize = 8 << size;
        if (shift != esize) {
            tcg_gen_shri_i64(tcg_rn, tcg_rn, shift);
            tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_rn, 0, esize - shift);
        }
    } else {
        handle_shri_with_rndacc(tcg_rd, tcg_rn, tcg_round,
                                accumulate, is_u, size, shift);
    }

    write_fp_dreg(s, rd, tcg_rd);
}

/* SHL/SLI - Scalar shift left */
static void handle_scalar_simd_shli(DisasContext *s, bool insert,
                                    int immh, int immb, int opcode,
                                    int rn, int rd)
{
    int size = 32 - clz32(immh) - 1;
    int immhb = immh << 3 | immb;
    int shift = immhb - (8 << size);
    TCGv_i64 tcg_rn;
    TCGv_i64 tcg_rd;

    if (!extract32(immh, 3, 1)) {
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    tcg_rn = read_fp_dreg(s, rn);
    tcg_rd = insert ? read_fp_dreg(s, rd) : tcg_temp_new_i64();

    if (insert) {
        tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_rn, shift, 64 - shift);
    } else {
        tcg_gen_shli_i64(tcg_rd, tcg_rn, shift);
    }

    write_fp_dreg(s, rd, tcg_rd);
}

/* SQSHRN/SQSHRUN - Saturating (signed/unsigned) shift right with
 * (signed/unsigned) narrowing */
static void handle_vec_simd_sqshrn(DisasContext *s, bool is_scalar, bool is_q,
                                   bool is_u_shift, bool is_u_narrow,
                                   int immh, int immb, int opcode,
                                   int rn, int rd)
{
    int immhb = immh << 3 | immb;
    int size = 32 - clz32(immh) - 1;
    int esize = 8 << size;
    int shift = (2 * esize) - immhb;
    int elements = is_scalar ? 1 : (64 / esize);
    bool round = extract32(opcode, 0, 1);
    MemOp ldop = (size + 1) | (is_u_shift ? 0 : MO_SIGN);
    TCGv_i64 tcg_rn, tcg_rd, tcg_round;
    TCGv_i32 tcg_rd_narrowed;
    TCGv_i64 tcg_final;

    static NeonGenNarrowEnvFn * const signed_narrow_fns[4][2] = {
        { gen_helper_neon_narrow_sat_s8,
          gen_helper_neon_unarrow_sat8 },
        { gen_helper_neon_narrow_sat_s16,
          gen_helper_neon_unarrow_sat16 },
        { gen_helper_neon_narrow_sat_s32,
          gen_helper_neon_unarrow_sat32 },
        { NULL, NULL },
    };
    static NeonGenNarrowEnvFn * const unsigned_narrow_fns[4] = {
        gen_helper_neon_narrow_sat_u8,
        gen_helper_neon_narrow_sat_u16,
        gen_helper_neon_narrow_sat_u32,
        NULL
    };
    NeonGenNarrowEnvFn *narrowfn;

    int i;

    assert(size < 4);

    if (extract32(immh, 3, 1)) {
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    if (is_u_shift) {
        narrowfn = unsigned_narrow_fns[size];
    } else {
        narrowfn = signed_narrow_fns[size][is_u_narrow ? 1 : 0];
    }

    tcg_rn = tcg_temp_new_i64();
    tcg_rd = tcg_temp_new_i64();
    tcg_rd_narrowed = tcg_temp_new_i32();
    tcg_final = tcg_temp_new_i64();

    if (round) {
        tcg_round = tcg_constant_i64(1ULL << (shift - 1));
    } else {
        tcg_round = NULL;
    }

    for (i = 0; i < elements; i++) {
        read_vec_element(s, tcg_rn, rn, i, ldop);
        handle_shri_with_rndacc(tcg_rd, tcg_rn, tcg_round,
                                false, is_u_shift, size+1, shift);
        narrowfn(tcg_rd_narrowed, tcg_env, tcg_rd);
        tcg_gen_extu_i32_i64(tcg_rd, tcg_rd_narrowed);
        if (i == 0) {
            tcg_gen_extract_i64(tcg_final, tcg_rd, 0, esize);
        } else {
            tcg_gen_deposit_i64(tcg_final, tcg_final, tcg_rd, esize * i, esize);
        }
    }

    if (!is_q) {
        write_vec_element(s, tcg_final, rd, 0, MO_64);
    } else {
        write_vec_element(s, tcg_final, rd, 1, MO_64);
    }
    clear_vec_high(s, is_q, rd);
}

/* SQSHLU, UQSHL, SQSHL: saturating left shifts */
static void handle_simd_qshl(DisasContext *s, bool scalar, bool is_q,
                             bool src_unsigned, bool dst_unsigned,
                             int immh, int immb, int rn, int rd)
{
    int immhb = immh << 3 | immb;
    int size = 32 - clz32(immh) - 1;
    int shift = immhb - (8 << size);
    int pass;

    assert(immh != 0);
    assert(!(scalar && is_q));

    if (!scalar) {
        if (!is_q && extract32(immh, 3, 1)) {
            unallocated_encoding(s);
            return;
        }

        /* Since we use the variable-shift helpers we must
         * replicate the shift count into each element of
         * the tcg_shift value.
         */
        switch (size) {
        case 0:
            shift |= shift << 8;
            /* fall through */
        case 1:
            shift |= shift << 16;
            break;
        case 2:
        case 3:
            break;
        default:
            g_assert_not_reached();
        }
    }

    if (!fp_access_check(s)) {
        return;
    }

    if (size == 3) {
        TCGv_i64 tcg_shift = tcg_constant_i64(shift);
        static NeonGenTwo64OpEnvFn * const fns[2][2] = {
            { gen_helper_neon_qshl_s64, gen_helper_neon_qshlu_s64 },
            { NULL, gen_helper_neon_qshl_u64 },
        };
        NeonGenTwo64OpEnvFn *genfn = fns[src_unsigned][dst_unsigned];
        int maxpass = is_q ? 2 : 1;

        for (pass = 0; pass < maxpass; pass++) {
            TCGv_i64 tcg_op = tcg_temp_new_i64();

            read_vec_element(s, tcg_op, rn, pass, MO_64);
            genfn(tcg_op, tcg_env, tcg_op, tcg_shift);
            write_vec_element(s, tcg_op, rd, pass, MO_64);
        }
        clear_vec_high(s, is_q, rd);
    } else {
        TCGv_i32 tcg_shift = tcg_constant_i32(shift);
        static NeonGenTwoOpEnvFn * const fns[2][2][3] = {
            {
                { gen_helper_neon_qshl_s8,
                  gen_helper_neon_qshl_s16,
                  gen_helper_neon_qshl_s32 },
                { gen_helper_neon_qshlu_s8,
                  gen_helper_neon_qshlu_s16,
                  gen_helper_neon_qshlu_s32 }
            }, {
                { NULL, NULL, NULL },
                { gen_helper_neon_qshl_u8,
                  gen_helper_neon_qshl_u16,
                  gen_helper_neon_qshl_u32 }
            }
        };
        NeonGenTwoOpEnvFn *genfn = fns[src_unsigned][dst_unsigned][size];
        MemOp memop = scalar ? size : MO_32;
        int maxpass = scalar ? 1 : is_q ? 4 : 2;

        for (pass = 0; pass < maxpass; pass++) {
            TCGv_i32 tcg_op = tcg_temp_new_i32();

            read_vec_element_i32(s, tcg_op, rn, pass, memop);
            genfn(tcg_op, tcg_env, tcg_op, tcg_shift);
            if (scalar) {
                switch (size) {
                case 0:
                    tcg_gen_ext8u_i32(tcg_op, tcg_op);
                    break;
                case 1:
                    tcg_gen_ext16u_i32(tcg_op, tcg_op);
                    break;
                case 2:
                    break;
                default:
                    g_assert_not_reached();
                }
                write_fp_sreg(s, rd, tcg_op);
            } else {
                write_vec_element_i32(s, tcg_op, rd, pass, MO_32);
            }
        }

        if (!scalar) {
            clear_vec_high(s, is_q, rd);
        }
    }
}

/* Common vector code for handling integer to FP conversion */
static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn,
                                   int elements, int is_signed,
                                   int fracbits, int size)
{
    TCGv_ptr tcg_fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
    TCGv_i32 tcg_shift = NULL;

    MemOp mop = size | (is_signed ? MO_SIGN : 0);
    int pass;

    if (fracbits || size == MO_64) {
        tcg_shift = tcg_constant_i32(fracbits);
    }

    if (size == MO_64) {
        TCGv_i64 tcg_int64 = tcg_temp_new_i64();
        TCGv_i64 tcg_double = tcg_temp_new_i64();

        for (pass = 0; pass < elements; pass++) {
            read_vec_element(s, tcg_int64, rn, pass, mop);

            if (is_signed) {
                gen_helper_vfp_sqtod(tcg_double, tcg_int64,
                                     tcg_shift, tcg_fpst);
            } else {
                gen_helper_vfp_uqtod(tcg_double, tcg_int64,
                                     tcg_shift, tcg_fpst);
            }
            if (elements == 1) {
                write_fp_dreg(s, rd, tcg_double);
            } else {
                write_vec_element(s, tcg_double, rd, pass, MO_64);
            }
        }
    } else {
        TCGv_i32 tcg_int32 = tcg_temp_new_i32();
        TCGv_i32 tcg_float = tcg_temp_new_i32();

        for (pass = 0; pass < elements; pass++) {
            read_vec_element_i32(s, tcg_int32, rn, pass, mop);

            switch (size) {
            case MO_32:
                if (fracbits) {
                    if (is_signed) {
                        gen_helper_vfp_sltos(tcg_float, tcg_int32,
                                             tcg_shift, tcg_fpst);
                    } else {
                        gen_helper_vfp_ultos(tcg_float, tcg_int32,
                                             tcg_shift, tcg_fpst);
                    }
                } else {
                    if (is_signed) {
                        gen_helper_vfp_sitos(tcg_float, tcg_int32, tcg_fpst);
                    } else {
                        gen_helper_vfp_uitos(tcg_float, tcg_int32, tcg_fpst);
                    }
                }
                break;
            case MO_16:
                if (fracbits) {
                    if (is_signed) {
                        gen_helper_vfp_sltoh(tcg_float, tcg_int32,
                                             tcg_shift, tcg_fpst);
                    } else {
                        gen_helper_vfp_ultoh(tcg_float, tcg_int32,
                                             tcg_shift, tcg_fpst);
                    }
                } else {
                    if (is_signed) {
                        gen_helper_vfp_sitoh(tcg_float, tcg_int32, tcg_fpst);
                    } else {
                        gen_helper_vfp_uitoh(tcg_float, tcg_int32, tcg_fpst);
                    }
                }
                break;
            default:
                g_assert_not_reached();
            }

            if (elements == 1) {
                write_fp_sreg(s, rd, tcg_float);
            } else {
                write_vec_element_i32(s, tcg_float, rd, pass, size);
            }
        }
    }

    clear_vec_high(s, elements << size == 16, rd);
}

/* UCVTF/SCVTF - Integer to FP conversion */
static void handle_simd_shift_intfp_conv(DisasContext *s, bool is_scalar,
                                         bool is_q, bool is_u,
                                         int immh, int immb, int opcode,
                                         int rn, int rd)
{
    int size, elements, fracbits;
    int immhb = immh << 3 | immb;

    if (immh & 8) {
        size = MO_64;
        if (!is_scalar && !is_q) {
            unallocated_encoding(s);
            return;
        }
    } else if (immh & 4) {
        size = MO_32;
    } else if (immh & 2) {
        size = MO_16;
        if (!dc_isar_feature(aa64_fp16, s)) {
            unallocated_encoding(s);
            return;
        }
    } else {
        /* immh == 0 would be a failure of the decode logic */
        g_assert(immh == 1);
        unallocated_encoding(s);
        return;
    }

    if (is_scalar) {
        elements = 1;
    } else {
        elements = (8 << is_q) >> size;
    }
    fracbits = (16 << size) - immhb;

    if (!fp_access_check(s)) {
        return;
    }

    handle_simd_intfp_conv(s, rd, rn, elements, !is_u, fracbits, size);
}

/* FCVTZS, FVCVTZU - FP to fixedpoint conversion */
static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
                                         bool is_q, bool is_u,
                                         int immh, int immb, int rn, int rd)
{
    int immhb = immh << 3 | immb;
    int pass, size, fracbits;
    TCGv_ptr tcg_fpstatus;
    TCGv_i32 tcg_rmode, tcg_shift;

    if (immh & 0x8) {
        size = MO_64;
        if (!is_scalar && !is_q) {
            unallocated_encoding(s);
            return;
        }
    } else if (immh & 0x4) {
        size = MO_32;
    } else if (immh & 0x2) {
        size = MO_16;
        if (!dc_isar_feature(aa64_fp16, s)) {
            unallocated_encoding(s);
            return;
        }
    } else {
        /* Should have split out AdvSIMD modified immediate earlier.  */
        assert(immh == 1);
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    assert(!(is_scalar && is_q));

    tcg_fpstatus = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
    tcg_rmode = gen_set_rmode(FPROUNDING_ZERO, tcg_fpstatus);
    fracbits = (16 << size) - immhb;
    tcg_shift = tcg_constant_i32(fracbits);

    if (size == MO_64) {
        int maxpass = is_scalar ? 1 : 2;

        for (pass = 0; pass < maxpass; pass++) {
            TCGv_i64 tcg_op = tcg_temp_new_i64();

            read_vec_element(s, tcg_op, rn, pass, MO_64);
            if (is_u) {
                gen_helper_vfp_touqd(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
            } else {
                gen_helper_vfp_tosqd(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
            }
            write_vec_element(s, tcg_op, rd, pass, MO_64);
        }
        clear_vec_high(s, is_q, rd);
    } else {
        void (*fn)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
        int maxpass = is_scalar ? 1 : ((8 << is_q) >> size);

        switch (size) {
        case MO_16:
            if (is_u) {
                fn = gen_helper_vfp_touhh;
            } else {
                fn = gen_helper_vfp_toshh;
            }
            break;
        case MO_32:
            if (is_u) {
                fn = gen_helper_vfp_touls;
            } else {
                fn = gen_helper_vfp_tosls;
            }
            break;
        default:
            g_assert_not_reached();
        }

        for (pass = 0; pass < maxpass; pass++) {
            TCGv_i32 tcg_op = tcg_temp_new_i32();

            read_vec_element_i32(s, tcg_op, rn, pass, size);
            fn(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
            if (is_scalar) {
                if (size == MO_16 && !is_u) {
                    tcg_gen_ext16u_i32(tcg_op, tcg_op);
                }
                write_fp_sreg(s, rd, tcg_op);
            } else {
                write_vec_element_i32(s, tcg_op, rd, pass, size);
            }
        }
        if (!is_scalar) {
            clear_vec_high(s, is_q, rd);
        }
    }

    gen_restore_rmode(tcg_rmode, tcg_fpstatus);
}

/* AdvSIMD scalar shift by immediate
 *  31 30  29 28         23 22  19 18  16 15    11  10 9    5 4    0
 * +-----+---+-------------+------+------+--------+---+------+------+
 * | 0 1 | U | 1 1 1 1 1 0 | immh | immb | opcode | 1 |  Rn  |  Rd  |
 * +-----+---+-------------+------+------+--------+---+------+------+
 *
 * This is the scalar version so it works on a fixed sized registers
 */
static void disas_simd_scalar_shift_imm(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int opcode = extract32(insn, 11, 5);
    int immb = extract32(insn, 16, 3);
    int immh = extract32(insn, 19, 4);
    bool is_u = extract32(insn, 29, 1);

    if (immh == 0) {
        unallocated_encoding(s);
        return;
    }

    switch (opcode) {
    case 0x08: /* SRI */
        if (!is_u) {
            unallocated_encoding(s);
            return;
        }
        /* fall through */
    case 0x00: /* SSHR / USHR */
    case 0x02: /* SSRA / USRA */
    case 0x04: /* SRSHR / URSHR */
    case 0x06: /* SRSRA / URSRA */
        handle_scalar_simd_shri(s, is_u, immh, immb, opcode, rn, rd);
        break;
    case 0x0a: /* SHL / SLI */
        handle_scalar_simd_shli(s, is_u, immh, immb, opcode, rn, rd);
        break;
    case 0x1c: /* SCVTF, UCVTF */
        handle_simd_shift_intfp_conv(s, true, false, is_u, immh, immb,
                                     opcode, rn, rd);
        break;
    case 0x10: /* SQSHRUN, SQSHRUN2 */
    case 0x11: /* SQRSHRUN, SQRSHRUN2 */
        if (!is_u) {
            unallocated_encoding(s);
            return;
        }
        handle_vec_simd_sqshrn(s, true, false, false, true,
                               immh, immb, opcode, rn, rd);
        break;
    case 0x12: /* SQSHRN, SQSHRN2, UQSHRN */
    case 0x13: /* SQRSHRN, SQRSHRN2, UQRSHRN, UQRSHRN2 */
        handle_vec_simd_sqshrn(s, true, false, is_u, is_u,
                               immh, immb, opcode, rn, rd);
        break;
    case 0xc: /* SQSHLU */
        if (!is_u) {
            unallocated_encoding(s);
            return;
        }
        handle_simd_qshl(s, true, false, false, true, immh, immb, rn, rd);
        break;
    case 0xe: /* SQSHL, UQSHL */
        handle_simd_qshl(s, true, false, is_u, is_u, immh, immb, rn, rd);
        break;
    case 0x1f: /* FCVTZS, FCVTZU */
        handle_simd_shift_fpint_conv(s, true, false, is_u, immh, immb, rn, rd);
        break;
    default:
        unallocated_encoding(s);
        break;
    }
}

/* AdvSIMD scalar three different
 *  31 30  29 28       24 23  22  21 20  16 15    12 11 10 9    5 4    0
 * +-----+---+-----------+------+---+------+--------+-----+------+------+
 * | 0 1 | U | 1 1 1 1 0 | size | 1 |  Rm  | opcode | 0 0 |  Rn  |  Rd  |
 * +-----+---+-----------+------+---+------+--------+-----+------+------+
 */
static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
{
    bool is_u = extract32(insn, 29, 1);
    int size = extract32(insn, 22, 2);
    int opcode = extract32(insn, 12, 4);
    int rm = extract32(insn, 16, 5);
    int rn = extract32(insn, 5, 5);
    int rd = extract32(insn, 0, 5);

    if (is_u) {
        unallocated_encoding(s);
        return;
    }

    switch (opcode) {
    case 0x9: /* SQDMLAL, SQDMLAL2 */
    case 0xb: /* SQDMLSL, SQDMLSL2 */
    case 0xd: /* SQDMULL, SQDMULL2 */
        if (size == 0 || size == 3) {
            unallocated_encoding(s);
            return;
        }
        break;
    default:
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    if (size == 2) {
        TCGv_i64 tcg_op1 = tcg_temp_new_i64();
        TCGv_i64 tcg_op2 = tcg_temp_new_i64();
        TCGv_i64 tcg_res = tcg_temp_new_i64();

        read_vec_element(s, tcg_op1, rn, 0, MO_32 | MO_SIGN);
        read_vec_element(s, tcg_op2, rm, 0, MO_32 | MO_SIGN);

        tcg_gen_mul_i64(tcg_res, tcg_op1, tcg_op2);
        gen_helper_neon_addl_saturate_s64(tcg_res, tcg_env, tcg_res, tcg_res);

        switch (opcode) {
        case 0xd: /* SQDMULL, SQDMULL2 */
            break;
        case 0xb: /* SQDMLSL, SQDMLSL2 */
            tcg_gen_neg_i64(tcg_res, tcg_res);
            /* fall through */
        case 0x9: /* SQDMLAL, SQDMLAL2 */
            read_vec_element(s, tcg_op1, rd, 0, MO_64);
            gen_helper_neon_addl_saturate_s64(tcg_res, tcg_env,
                                              tcg_res, tcg_op1);
            break;
        default:
            g_assert_not_reached();
        }

        write_fp_dreg(s, rd, tcg_res);
    } else {
        TCGv_i32 tcg_op1 = read_fp_hreg(s, rn);
        TCGv_i32 tcg_op2 = read_fp_hreg(s, rm);
        TCGv_i64 tcg_res = tcg_temp_new_i64();

        gen_helper_neon_mull_s16(tcg_res, tcg_op1, tcg_op2);
        gen_helper_neon_addl_saturate_s32(tcg_res, tcg_env, tcg_res, tcg_res);

        switch (opcode) {
        case 0xd: /* SQDMULL, SQDMULL2 */
            break;
        case 0xb: /* SQDMLSL, SQDMLSL2 */
            gen_helper_neon_negl_u32(tcg_res, tcg_res);
            /* fall through */
        case 0x9: /* SQDMLAL, SQDMLAL2 */
        {
            TCGv_i64 tcg_op3 = tcg_temp_new_i64();
            read_vec_element(s, tcg_op3, rd, 0, MO_32);
            gen_helper_neon_addl_saturate_s32(tcg_res, tcg_env,
                                              tcg_res, tcg_op3);
            break;
        }
        default:
            g_assert_not_reached();
        }

        tcg_gen_ext32u_i64(tcg_res, tcg_res);
        write_fp_dreg(s, rd, tcg_res);
    }
}

static void handle_3same_64(DisasContext *s, int opcode, bool u,
                            TCGv_i64 tcg_rd, TCGv_i64 tcg_rn, TCGv_i64 tcg_rm)
{
    /* Handle 64x64->64 opcodes which are shared between the scalar
     * and vector 3-same groups. We cover every opcode where size == 3
     * is valid in either the three-reg-same (integer, not pairwise)
     * or scalar-three-reg-same groups.
     */
    TCGCond cond;

    switch (opcode) {
    case 0x1: /* SQADD */
        if (u) {
            gen_helper_neon_qadd_u64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
        } else {
            gen_helper_neon_qadd_s64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
        }
        break;
    case 0x5: /* SQSUB */
        if (u) {
            gen_helper_neon_qsub_u64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
        } else {
            gen_helper_neon_qsub_s64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
        }
        break;
    case 0x6: /* CMGT, CMHI */
        cond = u ? TCG_COND_GTU : TCG_COND_GT;
    do_cmop:
        /* 64 bit integer comparison, result = test ? -1 : 0. */
        tcg_gen_negsetcond_i64(cond, tcg_rd, tcg_rn, tcg_rm);
        break;
    case 0x7: /* CMGE, CMHS */
        cond = u ? TCG_COND_GEU : TCG_COND_GE;
        goto do_cmop;
    case 0x11: /* CMTST, CMEQ */
        if (u) {
            cond = TCG_COND_EQ;
            goto do_cmop;
        }
        gen_cmtst_i64(tcg_rd, tcg_rn, tcg_rm);
        break;
    case 0x8: /* SSHL, USHL */
        if (u) {
            gen_ushl_i64(tcg_rd, tcg_rn, tcg_rm);
        } else {
            gen_sshl_i64(tcg_rd, tcg_rn, tcg_rm);
        }
        break;
    case 0x9: /* SQSHL, UQSHL */
        if (u) {
            gen_helper_neon_qshl_u64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
        } else {
            gen_helper_neon_qshl_s64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
        }
        break;
    case 0xa: /* SRSHL, URSHL */
        if (u) {
            gen_helper_neon_rshl_u64(tcg_rd, tcg_rn, tcg_rm);
        } else {
            gen_helper_neon_rshl_s64(tcg_rd, tcg_rn, tcg_rm);
        }
        break;
    case 0xb: /* SQRSHL, UQRSHL */
        if (u) {
            gen_helper_neon_qrshl_u64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
        } else {
            gen_helper_neon_qrshl_s64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
        }
        break;
    case 0x10: /* ADD, SUB */
        if (u) {
            tcg_gen_sub_i64(tcg_rd, tcg_rn, tcg_rm);
        } else {
            tcg_gen_add_i64(tcg_rd, tcg_rn, tcg_rm);
        }
        break;
    default:
        g_assert_not_reached();
    }
}

/* Handle the 3-same-operands float operations; shared by the scalar
 * and vector encodings. The caller must filter out any encodings
 * not allocated for the encoding it is dealing with.
 */
static void handle_3same_float(DisasContext *s, int size, int elements,
                               int fpopcode, int rd, int rn, int rm)
{
    int pass;
    TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);

    for (pass = 0; pass < elements; pass++) {
        if (size) {
            /* Double */
            TCGv_i64 tcg_op1 = tcg_temp_new_i64();
            TCGv_i64 tcg_op2 = tcg_temp_new_i64();
            TCGv_i64 tcg_res = tcg_temp_new_i64();

            read_vec_element(s, tcg_op1, rn, pass, MO_64);
            read_vec_element(s, tcg_op2, rm, pass, MO_64);

            switch (fpopcode) {
            case 0x1c: /* FCMEQ */
                gen_helper_neon_ceq_f64(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x1f: /* FRECPS */
                gen_helper_recpsf_f64(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x3f: /* FRSQRTS */
                gen_helper_rsqrtsf_f64(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x5c: /* FCMGE */
                gen_helper_neon_cge_f64(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x5d: /* FACGE */
                gen_helper_neon_acge_f64(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x7a: /* FABD */
                gen_helper_vfp_subd(tcg_res, tcg_op1, tcg_op2, fpst);
                gen_vfp_absd(tcg_res, tcg_res);
                break;
            case 0x7c: /* FCMGT */
                gen_helper_neon_cgt_f64(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x7d: /* FACGT */
                gen_helper_neon_acgt_f64(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            default:
            case 0x18: /* FMAXNM */
            case 0x19: /* FMLA */
            case 0x1a: /* FADD */
            case 0x1b: /* FMULX */
            case 0x1e: /* FMAX */
            case 0x38: /* FMINNM */
            case 0x39: /* FMLS */
            case 0x3a: /* FSUB */
            case 0x3e: /* FMIN */
            case 0x5b: /* FMUL */
            case 0x5f: /* FDIV */
                g_assert_not_reached();
            }

            write_vec_element(s, tcg_res, rd, pass, MO_64);
        } else {
            /* Single */
            TCGv_i32 tcg_op1 = tcg_temp_new_i32();
            TCGv_i32 tcg_op2 = tcg_temp_new_i32();
            TCGv_i32 tcg_res = tcg_temp_new_i32();

            read_vec_element_i32(s, tcg_op1, rn, pass, MO_32);
            read_vec_element_i32(s, tcg_op2, rm, pass, MO_32);

            switch (fpopcode) {
            case 0x1c: /* FCMEQ */
                gen_helper_neon_ceq_f32(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x1f: /* FRECPS */
                gen_helper_recpsf_f32(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x3f: /* FRSQRTS */
                gen_helper_rsqrtsf_f32(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x5c: /* FCMGE */
                gen_helper_neon_cge_f32(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x5d: /* FACGE */
                gen_helper_neon_acge_f32(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x7a: /* FABD */
                gen_helper_vfp_subs(tcg_res, tcg_op1, tcg_op2, fpst);
                gen_vfp_abss(tcg_res, tcg_res);
                break;
            case 0x7c: /* FCMGT */
                gen_helper_neon_cgt_f32(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x7d: /* FACGT */
                gen_helper_neon_acgt_f32(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            default:
            case 0x18: /* FMAXNM */
            case 0x19: /* FMLA */
            case 0x1a: /* FADD */
            case 0x1b: /* FMULX */
            case 0x1e: /* FMAX */
            case 0x38: /* FMINNM */
            case 0x39: /* FMLS */
            case 0x3a: /* FSUB */
            case 0x3e: /* FMIN */
            case 0x5b: /* FMUL */
            case 0x5f: /* FDIV */
                g_assert_not_reached();
            }

            if (elements == 1) {
                /* scalar single so clear high part */
                TCGv_i64 tcg_tmp = tcg_temp_new_i64();

                tcg_gen_extu_i32_i64(tcg_tmp, tcg_res);
                write_vec_element(s, tcg_tmp, rd, pass, MO_64);
            } else {
                write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
            }
        }
    }

    clear_vec_high(s, elements * (size ? 8 : 4) > 8, rd);
}

/* AdvSIMD scalar three same
 *  31 30  29 28       24 23  22  21 20  16 15    11  10 9    5 4    0
 * +-----+---+-----------+------+---+------+--------+---+------+------+
 * | 0 1 | U | 1 1 1 1 0 | size | 1 |  Rm  | opcode | 1 |  Rn  |  Rd  |
 * +-----+---+-----------+------+---+------+--------+---+------+------+
 */
static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int opcode = extract32(insn, 11, 5);
    int rm = extract32(insn, 16, 5);
    int size = extract32(insn, 22, 2);
    bool u = extract32(insn, 29, 1);
    TCGv_i64 tcg_rd;

    if (opcode >= 0x18) {
        /* Floating point: U, size[1] and opcode indicate operation */
        int fpopcode = opcode | (extract32(size, 1, 1) << 5) | (u << 6);
        switch (fpopcode) {
        case 0x1f: /* FRECPS */
        case 0x3f: /* FRSQRTS */
        case 0x5d: /* FACGE */
        case 0x7d: /* FACGT */
        case 0x1c: /* FCMEQ */
        case 0x5c: /* FCMGE */
        case 0x7c: /* FCMGT */
        case 0x7a: /* FABD */
            break;
        default:
        case 0x1b: /* FMULX */
            unallocated_encoding(s);
            return;
        }

        if (!fp_access_check(s)) {
            return;
        }

        handle_3same_float(s, extract32(size, 0, 1), 1, fpopcode, rd, rn, rm);
        return;
    }

    switch (opcode) {
    case 0x1: /* SQADD, UQADD */
    case 0x5: /* SQSUB, UQSUB */
    case 0x9: /* SQSHL, UQSHL */
    case 0xb: /* SQRSHL, UQRSHL */
        break;
    case 0x8: /* SSHL, USHL */
    case 0xa: /* SRSHL, URSHL */
    case 0x6: /* CMGT, CMHI */
    case 0x7: /* CMGE, CMHS */
    case 0x11: /* CMTST, CMEQ */
    case 0x10: /* ADD, SUB (vector) */
        if (size != 3) {
            unallocated_encoding(s);
            return;
        }
        break;
    case 0x16: /* SQDMULH, SQRDMULH (vector) */
        if (size != 1 && size != 2) {
            unallocated_encoding(s);
            return;
        }
        break;
    default:
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    tcg_rd = tcg_temp_new_i64();

    if (size == 3) {
        TCGv_i64 tcg_rn = read_fp_dreg(s, rn);
        TCGv_i64 tcg_rm = read_fp_dreg(s, rm);

        handle_3same_64(s, opcode, u, tcg_rd, tcg_rn, tcg_rm);
    } else {
        /* Do a single operation on the lowest element in the vector.
         * We use the standard Neon helpers and rely on 0 OP 0 == 0 with
         * no side effects for all these operations.
         * OPTME: special-purpose helpers would avoid doing some
         * unnecessary work in the helper for the 8 and 16 bit cases.
         */
        NeonGenTwoOpEnvFn *genenvfn;
        TCGv_i32 tcg_rn = tcg_temp_new_i32();
        TCGv_i32 tcg_rm = tcg_temp_new_i32();
        TCGv_i32 tcg_rd32 = tcg_temp_new_i32();

        read_vec_element_i32(s, tcg_rn, rn, 0, size);
        read_vec_element_i32(s, tcg_rm, rm, 0, size);

        switch (opcode) {
        case 0x1: /* SQADD, UQADD */
        {
            static NeonGenTwoOpEnvFn * const fns[3][2] = {
                { gen_helper_neon_qadd_s8, gen_helper_neon_qadd_u8 },
                { gen_helper_neon_qadd_s16, gen_helper_neon_qadd_u16 },
                { gen_helper_neon_qadd_s32, gen_helper_neon_qadd_u32 },
            };
            genenvfn = fns[size][u];
            break;
        }
        case 0x5: /* SQSUB, UQSUB */
        {
            static NeonGenTwoOpEnvFn * const fns[3][2] = {
                { gen_helper_neon_qsub_s8, gen_helper_neon_qsub_u8 },
                { gen_helper_neon_qsub_s16, gen_helper_neon_qsub_u16 },
                { gen_helper_neon_qsub_s32, gen_helper_neon_qsub_u32 },
            };
            genenvfn = fns[size][u];
            break;
        }
        case 0x9: /* SQSHL, UQSHL */
        {
            static NeonGenTwoOpEnvFn * const fns[3][2] = {
                { gen_helper_neon_qshl_s8, gen_helper_neon_qshl_u8 },
                { gen_helper_neon_qshl_s16, gen_helper_neon_qshl_u16 },
                { gen_helper_neon_qshl_s32, gen_helper_neon_qshl_u32 },
            };
            genenvfn = fns[size][u];
            break;
        }
        case 0xb: /* SQRSHL, UQRSHL */
        {
            static NeonGenTwoOpEnvFn * const fns[3][2] = {
                { gen_helper_neon_qrshl_s8, gen_helper_neon_qrshl_u8 },
                { gen_helper_neon_qrshl_s16, gen_helper_neon_qrshl_u16 },
                { gen_helper_neon_qrshl_s32, gen_helper_neon_qrshl_u32 },
            };
            genenvfn = fns[size][u];
            break;
        }
        case 0x16: /* SQDMULH, SQRDMULH */
        {
            static NeonGenTwoOpEnvFn * const fns[2][2] = {
                { gen_helper_neon_qdmulh_s16, gen_helper_neon_qrdmulh_s16 },
                { gen_helper_neon_qdmulh_s32, gen_helper_neon_qrdmulh_s32 },
            };
            assert(size == 1 || size == 2);
            genenvfn = fns[size - 1][u];
            break;
        }
        default:
            g_assert_not_reached();
        }

        genenvfn(tcg_rd32, tcg_env, tcg_rn, tcg_rm);
        tcg_gen_extu_i32_i64(tcg_rd, tcg_rd32);
    }

    write_fp_dreg(s, rd, tcg_rd);
}

/* AdvSIMD scalar three same FP16
 *  31 30  29 28       24 23  22 21 20  16 15 14 13    11 10  9  5 4  0
 * +-----+---+-----------+---+-----+------+-----+--------+---+----+----+
 * | 0 1 | U | 1 1 1 1 0 | a | 1 0 |  Rm  | 0 0 | opcode | 1 | Rn | Rd |
 * +-----+---+-----------+---+-----+------+-----+--------+---+----+----+
 * v: 0101 1110 0100 0000 0000 0100 0000 0000 => 5e400400
 * m: 1101 1111 0110 0000 1100 0100 0000 0000 => df60c400
 */
static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
                                                  uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int opcode = extract32(insn, 11, 3);
    int rm = extract32(insn, 16, 5);
    bool u = extract32(insn, 29, 1);
    bool a = extract32(insn, 23, 1);
    int fpopcode = opcode | (a << 3) |  (u << 4);
    TCGv_ptr fpst;
    TCGv_i32 tcg_op1;
    TCGv_i32 tcg_op2;
    TCGv_i32 tcg_res;

    switch (fpopcode) {
    case 0x04: /* FCMEQ (reg) */
    case 0x07: /* FRECPS */
    case 0x0f: /* FRSQRTS */
    case 0x14: /* FCMGE (reg) */
    case 0x15: /* FACGE */
    case 0x1a: /* FABD */
    case 0x1c: /* FCMGT (reg) */
    case 0x1d: /* FACGT */
        break;
    default:
    case 0x03: /* FMULX */
        unallocated_encoding(s);
        return;
    }

    if (!dc_isar_feature(aa64_fp16, s)) {
        unallocated_encoding(s);
    }

    if (!fp_access_check(s)) {
        return;
    }

    fpst = fpstatus_ptr(FPST_FPCR_F16);

    tcg_op1 = read_fp_hreg(s, rn);
    tcg_op2 = read_fp_hreg(s, rm);
    tcg_res = tcg_temp_new_i32();

    switch (fpopcode) {
    case 0x04: /* FCMEQ (reg) */
        gen_helper_advsimd_ceq_f16(tcg_res, tcg_op1, tcg_op2, fpst);
        break;
    case 0x07: /* FRECPS */
        gen_helper_recpsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
        break;
    case 0x0f: /* FRSQRTS */
        gen_helper_rsqrtsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
        break;
    case 0x14: /* FCMGE (reg) */
        gen_helper_advsimd_cge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
        break;
    case 0x15: /* FACGE */
        gen_helper_advsimd_acge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
        break;
    case 0x1a: /* FABD */
        gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
        tcg_gen_andi_i32(tcg_res, tcg_res, 0x7fff);
        break;
    case 0x1c: /* FCMGT (reg) */
        gen_helper_advsimd_cgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
        break;
    case 0x1d: /* FACGT */
        gen_helper_advsimd_acgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
        break;
    default:
    case 0x03: /* FMULX */
        g_assert_not_reached();
    }

    write_fp_sreg(s, rd, tcg_res);
}

/* AdvSIMD scalar three same extra
 *  31 30  29 28       24 23  22  21 20  16  15 14    11  10 9  5 4  0
 * +-----+---+-----------+------+---+------+---+--------+---+----+----+
 * | 0 1 | U | 1 1 1 1 0 | size | 0 |  Rm  | 1 | opcode | 1 | Rn | Rd |
 * +-----+---+-----------+------+---+------+---+--------+---+----+----+
 */
static void disas_simd_scalar_three_reg_same_extra(DisasContext *s,
                                                   uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int opcode = extract32(insn, 11, 4);
    int rm = extract32(insn, 16, 5);
    int size = extract32(insn, 22, 2);
    bool u = extract32(insn, 29, 1);
    TCGv_i32 ele1, ele2, ele3;
    TCGv_i64 res;
    bool feature;

    switch (u * 16 + opcode) {
    case 0x10: /* SQRDMLAH (vector) */
    case 0x11: /* SQRDMLSH (vector) */
        if (size != 1 && size != 2) {
            unallocated_encoding(s);
            return;
        }
        feature = dc_isar_feature(aa64_rdm, s);
        break;
    default:
        unallocated_encoding(s);
        return;
    }
    if (!feature) {
        unallocated_encoding(s);
        return;
    }
    if (!fp_access_check(s)) {
        return;
    }

    /* Do a single operation on the lowest element in the vector.
     * We use the standard Neon helpers and rely on 0 OP 0 == 0
     * with no side effects for all these operations.
     * OPTME: special-purpose helpers would avoid doing some
     * unnecessary work in the helper for the 16 bit cases.
     */
    ele1 = tcg_temp_new_i32();
    ele2 = tcg_temp_new_i32();
    ele3 = tcg_temp_new_i32();

    read_vec_element_i32(s, ele1, rn, 0, size);
    read_vec_element_i32(s, ele2, rm, 0, size);
    read_vec_element_i32(s, ele3, rd, 0, size);

    switch (opcode) {
    case 0x0: /* SQRDMLAH */
        if (size == 1) {
            gen_helper_neon_qrdmlah_s16(ele3, tcg_env, ele1, ele2, ele3);
        } else {
            gen_helper_neon_qrdmlah_s32(ele3, tcg_env, ele1, ele2, ele3);
        }
        break;
    case 0x1: /* SQRDMLSH */
        if (size == 1) {
            gen_helper_neon_qrdmlsh_s16(ele3, tcg_env, ele1, ele2, ele3);
        } else {
            gen_helper_neon_qrdmlsh_s32(ele3, tcg_env, ele1, ele2, ele3);
        }
        break;
    default:
        g_assert_not_reached();
    }

    res = tcg_temp_new_i64();
    tcg_gen_extu_i32_i64(res, ele3);
    write_fp_dreg(s, rd, res);
}

static void handle_2misc_64(DisasContext *s, int opcode, bool u,
                            TCGv_i64 tcg_rd, TCGv_i64 tcg_rn,
                            TCGv_i32 tcg_rmode, TCGv_ptr tcg_fpstatus)
{
    /* Handle 64->64 opcodes which are shared between the scalar and
     * vector 2-reg-misc groups. We cover every integer opcode where size == 3
     * is valid in either group and also the double-precision fp ops.
     * The caller only need provide tcg_rmode and tcg_fpstatus if the op
     * requires them.
     */
    TCGCond cond;

    switch (opcode) {
    case 0x4: /* CLS, CLZ */
        if (u) {
            tcg_gen_clzi_i64(tcg_rd, tcg_rn, 64);
        } else {
            tcg_gen_clrsb_i64(tcg_rd, tcg_rn);
        }
        break;
    case 0x5: /* NOT */
        /* This opcode is shared with CNT and RBIT but we have earlier
         * enforced that size == 3 if and only if this is the NOT insn.
         */
        tcg_gen_not_i64(tcg_rd, tcg_rn);
        break;
    case 0x7: /* SQABS, SQNEG */
        if (u) {
            gen_helper_neon_qneg_s64(tcg_rd, tcg_env, tcg_rn);
        } else {
            gen_helper_neon_qabs_s64(tcg_rd, tcg_env, tcg_rn);
        }
        break;
    case 0xa: /* CMLT */
        cond = TCG_COND_LT;
    do_cmop:
        /* 64 bit integer comparison against zero, result is test ? -1 : 0. */
        tcg_gen_negsetcond_i64(cond, tcg_rd, tcg_rn, tcg_constant_i64(0));
        break;
    case 0x8: /* CMGT, CMGE */
        cond = u ? TCG_COND_GE : TCG_COND_GT;
        goto do_cmop;
    case 0x9: /* CMEQ, CMLE */
        cond = u ? TCG_COND_LE : TCG_COND_EQ;
        goto do_cmop;
    case 0xb: /* ABS, NEG */
        if (u) {
            tcg_gen_neg_i64(tcg_rd, tcg_rn);
        } else {
            tcg_gen_abs_i64(tcg_rd, tcg_rn);
        }
        break;
    case 0x2f: /* FABS */
        gen_vfp_absd(tcg_rd, tcg_rn);
        break;
    case 0x6f: /* FNEG */
        gen_vfp_negd(tcg_rd, tcg_rn);
        break;
    case 0x7f: /* FSQRT */
        gen_helper_vfp_sqrtd(tcg_rd, tcg_rn, tcg_env);
        break;
    case 0x1a: /* FCVTNS */
    case 0x1b: /* FCVTMS */
    case 0x1c: /* FCVTAS */
    case 0x3a: /* FCVTPS */
    case 0x3b: /* FCVTZS */
        gen_helper_vfp_tosqd(tcg_rd, tcg_rn, tcg_constant_i32(0), tcg_fpstatus);
        break;
    case 0x5a: /* FCVTNU */
    case 0x5b: /* FCVTMU */
    case 0x5c: /* FCVTAU */
    case 0x7a: /* FCVTPU */
    case 0x7b: /* FCVTZU */
        gen_helper_vfp_touqd(tcg_rd, tcg_rn, tcg_constant_i32(0), tcg_fpstatus);
        break;
    case 0x18: /* FRINTN */
    case 0x19: /* FRINTM */
    case 0x38: /* FRINTP */
    case 0x39: /* FRINTZ */
    case 0x58: /* FRINTA */
    case 0x79: /* FRINTI */
        gen_helper_rintd(tcg_rd, tcg_rn, tcg_fpstatus);
        break;
    case 0x59: /* FRINTX */
        gen_helper_rintd_exact(tcg_rd, tcg_rn, tcg_fpstatus);
        break;
    case 0x1e: /* FRINT32Z */
    case 0x5e: /* FRINT32X */
        gen_helper_frint32_d(tcg_rd, tcg_rn, tcg_fpstatus);
        break;
    case 0x1f: /* FRINT64Z */
    case 0x5f: /* FRINT64X */
        gen_helper_frint64_d(tcg_rd, tcg_rn, tcg_fpstatus);
        break;
    default:
        g_assert_not_reached();
    }
}

static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
                                   bool is_scalar, bool is_u, bool is_q,
                                   int size, int rn, int rd)
{
    bool is_double = (size == MO_64);
    TCGv_ptr fpst;

    if (!fp_access_check(s)) {
        return;
    }

    fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);

    if (is_double) {
        TCGv_i64 tcg_op = tcg_temp_new_i64();
        TCGv_i64 tcg_zero = tcg_constant_i64(0);
        TCGv_i64 tcg_res = tcg_temp_new_i64();
        NeonGenTwoDoubleOpFn *genfn;
        bool swap = false;
        int pass;

        switch (opcode) {
        case 0x2e: /* FCMLT (zero) */
            swap = true;
            /* fallthrough */
        case 0x2c: /* FCMGT (zero) */
            genfn = gen_helper_neon_cgt_f64;
            break;
        case 0x2d: /* FCMEQ (zero) */
            genfn = gen_helper_neon_ceq_f64;
            break;
        case 0x6d: /* FCMLE (zero) */
            swap = true;
            /* fall through */
        case 0x6c: /* FCMGE (zero) */
            genfn = gen_helper_neon_cge_f64;
            break;
        default:
            g_assert_not_reached();
        }

        for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
            read_vec_element(s, tcg_op, rn, pass, MO_64);
            if (swap) {
                genfn(tcg_res, tcg_zero, tcg_op, fpst);
            } else {
                genfn(tcg_res, tcg_op, tcg_zero, fpst);
            }
            write_vec_element(s, tcg_res, rd, pass, MO_64);
        }

        clear_vec_high(s, !is_scalar, rd);
    } else {
        TCGv_i32 tcg_op = tcg_temp_new_i32();
        TCGv_i32 tcg_zero = tcg_constant_i32(0);
        TCGv_i32 tcg_res = tcg_temp_new_i32();
        NeonGenTwoSingleOpFn *genfn;
        bool swap = false;
        int pass, maxpasses;

        if (size == MO_16) {
            switch (opcode) {
            case 0x2e: /* FCMLT (zero) */
                swap = true;
                /* fall through */
            case 0x2c: /* FCMGT (zero) */
                genfn = gen_helper_advsimd_cgt_f16;
                break;
            case 0x2d: /* FCMEQ (zero) */
                genfn = gen_helper_advsimd_ceq_f16;
                break;
            case 0x6d: /* FCMLE (zero) */
                swap = true;
                /* fall through */
            case 0x6c: /* FCMGE (zero) */
                genfn = gen_helper_advsimd_cge_f16;
                break;
            default:
                g_assert_not_reached();
            }
        } else {
            switch (opcode) {
            case 0x2e: /* FCMLT (zero) */
                swap = true;
                /* fall through */
            case 0x2c: /* FCMGT (zero) */
                genfn = gen_helper_neon_cgt_f32;
                break;
            case 0x2d: /* FCMEQ (zero) */
                genfn = gen_helper_neon_ceq_f32;
                break;
            case 0x6d: /* FCMLE (zero) */
                swap = true;
                /* fall through */
            case 0x6c: /* FCMGE (zero) */
                genfn = gen_helper_neon_cge_f32;
                break;
            default:
                g_assert_not_reached();
            }
        }

        if (is_scalar) {
            maxpasses = 1;
        } else {
            int vector_size = 8 << is_q;
            maxpasses = vector_size >> size;
        }

        for (pass = 0; pass < maxpasses; pass++) {
            read_vec_element_i32(s, tcg_op, rn, pass, size);
            if (swap) {
                genfn(tcg_res, tcg_zero, tcg_op, fpst);
            } else {
                genfn(tcg_res, tcg_op, tcg_zero, fpst);
            }
            if (is_scalar) {
                write_fp_sreg(s, rd, tcg_res);
            } else {
                write_vec_element_i32(s, tcg_res, rd, pass, size);
            }
        }

        if (!is_scalar) {
            clear_vec_high(s, is_q, rd);
        }
    }
}

static void handle_2misc_reciprocal(DisasContext *s, int opcode,
                                    bool is_scalar, bool is_u, bool is_q,
                                    int size, int rn, int rd)
{
    bool is_double = (size == 3);
    TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);

    if (is_double) {
        TCGv_i64 tcg_op = tcg_temp_new_i64();
        TCGv_i64 tcg_res = tcg_temp_new_i64();
        int pass;

        for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
            read_vec_element(s, tcg_op, rn, pass, MO_64);
            switch (opcode) {
            case 0x3d: /* FRECPE */
                gen_helper_recpe_f64(tcg_res, tcg_op, fpst);
                break;
            case 0x3f: /* FRECPX */
                gen_helper_frecpx_f64(tcg_res, tcg_op, fpst);
                break;
            case 0x7d: /* FRSQRTE */
                gen_helper_rsqrte_f64(tcg_res, tcg_op, fpst);
                break;
            default:
                g_assert_not_reached();
            }
            write_vec_element(s, tcg_res, rd, pass, MO_64);
        }
        clear_vec_high(s, !is_scalar, rd);
    } else {
        TCGv_i32 tcg_op = tcg_temp_new_i32();
        TCGv_i32 tcg_res = tcg_temp_new_i32();
        int pass, maxpasses;

        if (is_scalar) {
            maxpasses = 1;
        } else {
            maxpasses = is_q ? 4 : 2;
        }

        for (pass = 0; pass < maxpasses; pass++) {
            read_vec_element_i32(s, tcg_op, rn, pass, MO_32);

            switch (opcode) {
            case 0x3c: /* URECPE */
                gen_helper_recpe_u32(tcg_res, tcg_op);
                break;
            case 0x3d: /* FRECPE */
                gen_helper_recpe_f32(tcg_res, tcg_op, fpst);
                break;
            case 0x3f: /* FRECPX */
                gen_helper_frecpx_f32(tcg_res, tcg_op, fpst);
                break;
            case 0x7d: /* FRSQRTE */
                gen_helper_rsqrte_f32(tcg_res, tcg_op, fpst);
                break;
            default:
                g_assert_not_reached();
            }

            if (is_scalar) {
                write_fp_sreg(s, rd, tcg_res);
            } else {
                write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
            }
        }
        if (!is_scalar) {
            clear_vec_high(s, is_q, rd);
        }
    }
}

static void handle_2misc_narrow(DisasContext *s, bool scalar,
                                int opcode, bool u, bool is_q,
                                int size, int rn, int rd)
{
    /* Handle 2-reg-misc ops which are narrowing (so each 2*size element
     * in the source becomes a size element in the destination).
     */
    int pass;
    TCGv_i32 tcg_res[2];
    int destelt = is_q ? 2 : 0;
    int passes = scalar ? 1 : 2;

    if (scalar) {
        tcg_res[1] = tcg_constant_i32(0);
    }

    for (pass = 0; pass < passes; pass++) {
        TCGv_i64 tcg_op = tcg_temp_new_i64();
        NeonGenNarrowFn *genfn = NULL;
        NeonGenNarrowEnvFn *genenvfn = NULL;

        if (scalar) {
            read_vec_element(s, tcg_op, rn, pass, size + 1);
        } else {
            read_vec_element(s, tcg_op, rn, pass, MO_64);
        }
        tcg_res[pass] = tcg_temp_new_i32();

        switch (opcode) {
        case 0x12: /* XTN, SQXTUN */
        {
            static NeonGenNarrowFn * const xtnfns[3] = {
                gen_helper_neon_narrow_u8,
                gen_helper_neon_narrow_u16,
                tcg_gen_extrl_i64_i32,
            };
            static NeonGenNarrowEnvFn * const sqxtunfns[3] = {
                gen_helper_neon_unarrow_sat8,
                gen_helper_neon_unarrow_sat16,
                gen_helper_neon_unarrow_sat32,
            };
            if (u) {
                genenvfn = sqxtunfns[size];
            } else {
                genfn = xtnfns[size];
            }
            break;
        }
        case 0x14: /* SQXTN, UQXTN */
        {
            static NeonGenNarrowEnvFn * const fns[3][2] = {
                { gen_helper_neon_narrow_sat_s8,
                  gen_helper_neon_narrow_sat_u8 },
                { gen_helper_neon_narrow_sat_s16,
                  gen_helper_neon_narrow_sat_u16 },
                { gen_helper_neon_narrow_sat_s32,
                  gen_helper_neon_narrow_sat_u32 },
            };
            genenvfn = fns[size][u];
            break;
        }
        case 0x16: /* FCVTN, FCVTN2 */
            /* 32 bit to 16 bit or 64 bit to 32 bit float conversion */
            if (size == 2) {
                gen_helper_vfp_fcvtsd(tcg_res[pass], tcg_op, tcg_env);
            } else {
                TCGv_i32 tcg_lo = tcg_temp_new_i32();
                TCGv_i32 tcg_hi = tcg_temp_new_i32();
                TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);
                TCGv_i32 ahp = get_ahp_flag();

                tcg_gen_extr_i64_i32(tcg_lo, tcg_hi, tcg_op);
                gen_helper_vfp_fcvt_f32_to_f16(tcg_lo, tcg_lo, fpst, ahp);
                gen_helper_vfp_fcvt_f32_to_f16(tcg_hi, tcg_hi, fpst, ahp);
                tcg_gen_deposit_i32(tcg_res[pass], tcg_lo, tcg_hi, 16, 16);
            }
            break;
        case 0x36: /* BFCVTN, BFCVTN2 */
            {
                TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);
                gen_helper_bfcvt_pair(tcg_res[pass], tcg_op, fpst);
            }
            break;
        case 0x56:  /* FCVTXN, FCVTXN2 */
            /* 64 bit to 32 bit float conversion
             * with von Neumann rounding (round to odd)
             */
            assert(size == 2);
            gen_helper_fcvtx_f64_to_f32(tcg_res[pass], tcg_op, tcg_env);
            break;
        default:
            g_assert_not_reached();
        }

        if (genfn) {
            genfn(tcg_res[pass], tcg_op);
        } else if (genenvfn) {
            genenvfn(tcg_res[pass], tcg_env, tcg_op);
        }
    }

    for (pass = 0; pass < 2; pass++) {
        write_vec_element_i32(s, tcg_res[pass], rd, destelt + pass, MO_32);
    }
    clear_vec_high(s, is_q, rd);
}

/* Remaining saturating accumulating ops */
static void handle_2misc_satacc(DisasContext *s, bool is_scalar, bool is_u,
                                bool is_q, int size, int rn, int rd)
{
    bool is_double = (size == 3);

    if (is_double) {
        TCGv_i64 tcg_rn = tcg_temp_new_i64();
        TCGv_i64 tcg_rd = tcg_temp_new_i64();
        int pass;

        for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
            read_vec_element(s, tcg_rn, rn, pass, MO_64);
            read_vec_element(s, tcg_rd, rd, pass, MO_64);

            if (is_u) { /* USQADD */
                gen_helper_neon_uqadd_s64(tcg_rd, tcg_env, tcg_rn, tcg_rd);
            } else { /* SUQADD */
                gen_helper_neon_sqadd_u64(tcg_rd, tcg_env, tcg_rn, tcg_rd);
            }
            write_vec_element(s, tcg_rd, rd, pass, MO_64);
        }
        clear_vec_high(s, !is_scalar, rd);
    } else {
        TCGv_i32 tcg_rn = tcg_temp_new_i32();
        TCGv_i32 tcg_rd = tcg_temp_new_i32();
        int pass, maxpasses;

        if (is_scalar) {
            maxpasses = 1;
        } else {
            maxpasses = is_q ? 4 : 2;
        }

        for (pass = 0; pass < maxpasses; pass++) {
            if (is_scalar) {
                read_vec_element_i32(s, tcg_rn, rn, pass, size);
                read_vec_element_i32(s, tcg_rd, rd, pass, size);
            } else {
                read_vec_element_i32(s, tcg_rn, rn, pass, MO_32);
                read_vec_element_i32(s, tcg_rd, rd, pass, MO_32);
            }

            if (is_u) { /* USQADD */
                switch (size) {
                case 0:
                    gen_helper_neon_uqadd_s8(tcg_rd, tcg_env, tcg_rn, tcg_rd);
                    break;
                case 1:
                    gen_helper_neon_uqadd_s16(tcg_rd, tcg_env, tcg_rn, tcg_rd);
                    break;
                case 2:
                    gen_helper_neon_uqadd_s32(tcg_rd, tcg_env, tcg_rn, tcg_rd);
                    break;
                default:
                    g_assert_not_reached();
                }
            } else { /* SUQADD */
                switch (size) {
                case 0:
                    gen_helper_neon_sqadd_u8(tcg_rd, tcg_env, tcg_rn, tcg_rd);
                    break;
                case 1:
                    gen_helper_neon_sqadd_u16(tcg_rd, tcg_env, tcg_rn, tcg_rd);
                    break;
                case 2:
                    gen_helper_neon_sqadd_u32(tcg_rd, tcg_env, tcg_rn, tcg_rd);
                    break;
                default:
                    g_assert_not_reached();
                }
            }

            if (is_scalar) {
                write_vec_element(s, tcg_constant_i64(0), rd, 0, MO_64);
            }
            write_vec_element_i32(s, tcg_rd, rd, pass, MO_32);
        }
        clear_vec_high(s, is_q, rd);
    }
}

/* AdvSIMD scalar two reg misc
 *  31 30  29 28       24 23  22 21       17 16    12 11 10 9    5 4    0
 * +-----+---+-----------+------+-----------+--------+-----+------+------+
 * | 0 1 | U | 1 1 1 1 0 | size | 1 0 0 0 0 | opcode | 1 0 |  Rn  |  Rd  |
 * +-----+---+-----------+------+-----------+--------+-----+------+------+
 */
static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int opcode = extract32(insn, 12, 5);
    int size = extract32(insn, 22, 2);
    bool u = extract32(insn, 29, 1);
    bool is_fcvt = false;
    int rmode;
    TCGv_i32 tcg_rmode;
    TCGv_ptr tcg_fpstatus;

    switch (opcode) {
    case 0x3: /* USQADD / SUQADD*/
        if (!fp_access_check(s)) {
            return;
        }
        handle_2misc_satacc(s, true, u, false, size, rn, rd);
        return;
    case 0x7: /* SQABS / SQNEG */
        break;
    case 0xa: /* CMLT */
        if (u) {
            unallocated_encoding(s);
            return;
        }
        /* fall through */
    case 0x8: /* CMGT, CMGE */
    case 0x9: /* CMEQ, CMLE */
    case 0xb: /* ABS, NEG */
        if (size != 3) {
            unallocated_encoding(s);
            return;
        }
        break;
    case 0x12: /* SQXTUN */
        if (!u) {
            unallocated_encoding(s);
            return;
        }
        /* fall through */
    case 0x14: /* SQXTN, UQXTN */
        if (size == 3) {
            unallocated_encoding(s);
            return;
        }
        if (!fp_access_check(s)) {
            return;
        }
        handle_2misc_narrow(s, true, opcode, u, false, size, rn, rd);
        return;
    case 0xc ... 0xf:
    case 0x16 ... 0x1d:
    case 0x1f:
        /* Floating point: U, size[1] and opcode indicate operation;
         * size[0] indicates single or double precision.
         */
        opcode |= (extract32(size, 1, 1) << 5) | (u << 6);
        size = extract32(size, 0, 1) ? 3 : 2;
        switch (opcode) {
        case 0x2c: /* FCMGT (zero) */
        case 0x2d: /* FCMEQ (zero) */
        case 0x2e: /* FCMLT (zero) */
        case 0x6c: /* FCMGE (zero) */
        case 0x6d: /* FCMLE (zero) */
            handle_2misc_fcmp_zero(s, opcode, true, u, true, size, rn, rd);
            return;
        case 0x1d: /* SCVTF */
        case 0x5d: /* UCVTF */
        {
            bool is_signed = (opcode == 0x1d);
            if (!fp_access_check(s)) {
                return;
            }
            handle_simd_intfp_conv(s, rd, rn, 1, is_signed, 0, size);
            return;
        }
        case 0x3d: /* FRECPE */
        case 0x3f: /* FRECPX */
        case 0x7d: /* FRSQRTE */
            if (!fp_access_check(s)) {
                return;
            }
            handle_2misc_reciprocal(s, opcode, true, u, true, size, rn, rd);
            return;
        case 0x1a: /* FCVTNS */
        case 0x1b: /* FCVTMS */
        case 0x3a: /* FCVTPS */
        case 0x3b: /* FCVTZS */
        case 0x5a: /* FCVTNU */
        case 0x5b: /* FCVTMU */
        case 0x7a: /* FCVTPU */
        case 0x7b: /* FCVTZU */
            is_fcvt = true;
            rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1);
            break;
        case 0x1c: /* FCVTAS */
        case 0x5c: /* FCVTAU */
            /* TIEAWAY doesn't fit in the usual rounding mode encoding */
            is_fcvt = true;
            rmode = FPROUNDING_TIEAWAY;
            break;
        case 0x56: /* FCVTXN, FCVTXN2 */
            if (size == 2) {
                unallocated_encoding(s);
                return;
            }
            if (!fp_access_check(s)) {
                return;
            }
            handle_2misc_narrow(s, true, opcode, u, false, size - 1, rn, rd);
            return;
        default:
            unallocated_encoding(s);
            return;
        }
        break;
    default:
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    if (is_fcvt) {
        tcg_fpstatus = fpstatus_ptr(FPST_FPCR);
        tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus);
    } else {
        tcg_fpstatus = NULL;
        tcg_rmode = NULL;
    }

    if (size == 3) {
        TCGv_i64 tcg_rn = read_fp_dreg(s, rn);
        TCGv_i64 tcg_rd = tcg_temp_new_i64();

        handle_2misc_64(s, opcode, u, tcg_rd, tcg_rn, tcg_rmode, tcg_fpstatus);
        write_fp_dreg(s, rd, tcg_rd);
    } else {
        TCGv_i32 tcg_rn = tcg_temp_new_i32();
        TCGv_i32 tcg_rd = tcg_temp_new_i32();

        read_vec_element_i32(s, tcg_rn, rn, 0, size);

        switch (opcode) {
        case 0x7: /* SQABS, SQNEG */
        {
            NeonGenOneOpEnvFn *genfn;
            static NeonGenOneOpEnvFn * const fns[3][2] = {
                { gen_helper_neon_qabs_s8, gen_helper_neon_qneg_s8 },
                { gen_helper_neon_qabs_s16, gen_helper_neon_qneg_s16 },
                { gen_helper_neon_qabs_s32, gen_helper_neon_qneg_s32 },
            };
            genfn = fns[size][u];
            genfn(tcg_rd, tcg_env, tcg_rn);
            break;
        }
        case 0x1a: /* FCVTNS */
        case 0x1b: /* FCVTMS */
        case 0x1c: /* FCVTAS */
        case 0x3a: /* FCVTPS */
        case 0x3b: /* FCVTZS */
            gen_helper_vfp_tosls(tcg_rd, tcg_rn, tcg_constant_i32(0),
                                 tcg_fpstatus);
            break;
        case 0x5a: /* FCVTNU */
        case 0x5b: /* FCVTMU */
        case 0x5c: /* FCVTAU */
        case 0x7a: /* FCVTPU */
        case 0x7b: /* FCVTZU */
            gen_helper_vfp_touls(tcg_rd, tcg_rn, tcg_constant_i32(0),
                                 tcg_fpstatus);
            break;
        default:
            g_assert_not_reached();
        }

        write_fp_sreg(s, rd, tcg_rd);
    }

    if (is_fcvt) {
        gen_restore_rmode(tcg_rmode, tcg_fpstatus);
    }
}

/* SSHR[RA]/USHR[RA] - Vector shift right (optional rounding/accumulate) */
static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
                                 int immh, int immb, int opcode, int rn, int rd)
{
    int size = 32 - clz32(immh) - 1;
    int immhb = immh << 3 | immb;
    int shift = 2 * (8 << size) - immhb;
    GVecGen2iFn *gvec_fn;

    if (extract32(immh, 3, 1) && !is_q) {
        unallocated_encoding(s);
        return;
    }
    tcg_debug_assert(size <= 3);

    if (!fp_access_check(s)) {
        return;
    }

    switch (opcode) {
    case 0x02: /* SSRA / USRA (accumulate) */
        gvec_fn = is_u ? gen_gvec_usra : gen_gvec_ssra;
        break;

    case 0x08: /* SRI */
        gvec_fn = gen_gvec_sri;
        break;

    case 0x00: /* SSHR / USHR */
        if (is_u) {
            if (shift == 8 << size) {
                /* Shift count the same size as element size produces zero.  */
                tcg_gen_gvec_dup_imm(size, vec_full_reg_offset(s, rd),
                                     is_q ? 16 : 8, vec_full_reg_size(s), 0);
                return;
            }
            gvec_fn = tcg_gen_gvec_shri;
        } else {
            /* Shift count the same size as element size produces all sign.  */
            if (shift == 8 << size) {
                shift -= 1;
            }
            gvec_fn = tcg_gen_gvec_sari;
        }
        break;

    case 0x04: /* SRSHR / URSHR (rounding) */
        gvec_fn = is_u ? gen_gvec_urshr : gen_gvec_srshr;
        break;

    case 0x06: /* SRSRA / URSRA (accum + rounding) */
        gvec_fn = is_u ? gen_gvec_ursra : gen_gvec_srsra;
        break;

    default:
        g_assert_not_reached();
    }

    gen_gvec_fn2i(s, is_q, rd, rn, shift, gvec_fn, size);
}

/* SHL/SLI - Vector shift left */
static void handle_vec_simd_shli(DisasContext *s, bool is_q, bool insert,
                                 int immh, int immb, int opcode, int rn, int rd)
{
    int size = 32 - clz32(immh) - 1;
    int immhb = immh << 3 | immb;
    int shift = immhb - (8 << size);

    /* Range of size is limited by decode: immh is a non-zero 4 bit field */
    assert(size >= 0 && size <= 3);

    if (extract32(immh, 3, 1) && !is_q) {
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    if (insert) {
        gen_gvec_fn2i(s, is_q, rd, rn, shift, gen_gvec_sli, size);
    } else {
        gen_gvec_fn2i(s, is_q, rd, rn, shift, tcg_gen_gvec_shli, size);
    }
}

/* USHLL/SHLL - Vector shift left with widening */
static void handle_vec_simd_wshli(DisasContext *s, bool is_q, bool is_u,
                                 int immh, int immb, int opcode, int rn, int rd)
{
    int size = 32 - clz32(immh) - 1;
    int immhb = immh << 3 | immb;
    int shift = immhb - (8 << size);
    int dsize = 64;
    int esize = 8 << size;
    int elements = dsize/esize;
    TCGv_i64 tcg_rn = tcg_temp_new_i64();
    TCGv_i64 tcg_rd = tcg_temp_new_i64();
    int i;

    if (size >= 3) {
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    /* For the LL variants the store is larger than the load,
     * so if rd == rn we would overwrite parts of our input.
     * So load everything right now and use shifts in the main loop.
     */
    read_vec_element(s, tcg_rn, rn, is_q ? 1 : 0, MO_64);

    for (i = 0; i < elements; i++) {
        tcg_gen_shri_i64(tcg_rd, tcg_rn, i * esize);
        ext_and_shift_reg(tcg_rd, tcg_rd, size | (!is_u << 2), 0);
        tcg_gen_shli_i64(tcg_rd, tcg_rd, shift);
        write_vec_element(s, tcg_rd, rd, i, size + 1);
    }
}

/* SHRN/RSHRN - Shift right with narrowing (and potential rounding) */
static void handle_vec_simd_shrn(DisasContext *s, bool is_q,
                                 int immh, int immb, int opcode, int rn, int rd)
{
    int immhb = immh << 3 | immb;
    int size = 32 - clz32(immh) - 1;
    int dsize = 64;
    int esize = 8 << size;
    int elements = dsize/esize;
    int shift = (2 * esize) - immhb;
    bool round = extract32(opcode, 0, 1);
    TCGv_i64 tcg_rn, tcg_rd, tcg_final;
    TCGv_i64 tcg_round;
    int i;

    if (extract32(immh, 3, 1)) {
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    tcg_rn = tcg_temp_new_i64();
    tcg_rd = tcg_temp_new_i64();
    tcg_final = tcg_temp_new_i64();
    read_vec_element(s, tcg_final, rd, is_q ? 1 : 0, MO_64);

    if (round) {
        tcg_round = tcg_constant_i64(1ULL << (shift - 1));
    } else {
        tcg_round = NULL;
    }

    for (i = 0; i < elements; i++) {
        read_vec_element(s, tcg_rn, rn, i, size+1);
        handle_shri_with_rndacc(tcg_rd, tcg_rn, tcg_round,
                                false, true, size+1, shift);

        tcg_gen_deposit_i64(tcg_final, tcg_final, tcg_rd, esize * i, esize);
    }

    if (!is_q) {
        write_vec_element(s, tcg_final, rd, 0, MO_64);
    } else {
        write_vec_element(s, tcg_final, rd, 1, MO_64);
    }

    clear_vec_high(s, is_q, rd);
}


/* AdvSIMD shift by immediate
 *  31  30   29 28         23 22  19 18  16 15    11  10 9    5 4    0
 * +---+---+---+-------------+------+------+--------+---+------+------+
 * | 0 | Q | U | 0 1 1 1 1 0 | immh | immb | opcode | 1 |  Rn  |  Rd  |
 * +---+---+---+-------------+------+------+--------+---+------+------+
 */
static void disas_simd_shift_imm(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int opcode = extract32(insn, 11, 5);
    int immb = extract32(insn, 16, 3);
    int immh = extract32(insn, 19, 4);
    bool is_u = extract32(insn, 29, 1);
    bool is_q = extract32(insn, 30, 1);

    /* data_proc_simd[] has sent immh == 0 to disas_simd_mod_imm. */
    assert(immh != 0);

    switch (opcode) {
    case 0x08: /* SRI */
        if (!is_u) {
            unallocated_encoding(s);
            return;
        }
        /* fall through */
    case 0x00: /* SSHR / USHR */
    case 0x02: /* SSRA / USRA (accumulate) */
    case 0x04: /* SRSHR / URSHR (rounding) */
    case 0x06: /* SRSRA / URSRA (accum + rounding) */
        handle_vec_simd_shri(s, is_q, is_u, immh, immb, opcode, rn, rd);
        break;
    case 0x0a: /* SHL / SLI */
        handle_vec_simd_shli(s, is_q, is_u, immh, immb, opcode, rn, rd);
        break;
    case 0x10: /* SHRN */
    case 0x11: /* RSHRN / SQRSHRUN */
        if (is_u) {
            handle_vec_simd_sqshrn(s, false, is_q, false, true, immh, immb,
                                   opcode, rn, rd);
        } else {
            handle_vec_simd_shrn(s, is_q, immh, immb, opcode, rn, rd);
        }
        break;
    case 0x12: /* SQSHRN / UQSHRN */
    case 0x13: /* SQRSHRN / UQRSHRN */
        handle_vec_simd_sqshrn(s, false, is_q, is_u, is_u, immh, immb,
                               opcode, rn, rd);
        break;
    case 0x14: /* SSHLL / USHLL */
        handle_vec_simd_wshli(s, is_q, is_u, immh, immb, opcode, rn, rd);
        break;
    case 0x1c: /* SCVTF / UCVTF */
        handle_simd_shift_intfp_conv(s, false, is_q, is_u, immh, immb,
                                     opcode, rn, rd);
        break;
    case 0xc: /* SQSHLU */
        if (!is_u) {
            unallocated_encoding(s);
            return;
        }
        handle_simd_qshl(s, false, is_q, false, true, immh, immb, rn, rd);
        break;
    case 0xe: /* SQSHL, UQSHL */
        handle_simd_qshl(s, false, is_q, is_u, is_u, immh, immb, rn, rd);
        break;
    case 0x1f: /* FCVTZS/ FCVTZU */
        handle_simd_shift_fpint_conv(s, false, is_q, is_u, immh, immb, rn, rd);
        return;
    default:
        unallocated_encoding(s);
        return;
    }
}

/* Generate code to do a "long" addition or subtraction, ie one done in
 * TCGv_i64 on vector lanes twice the width specified by size.
 */
static void gen_neon_addl(int size, bool is_sub, TCGv_i64 tcg_res,
                          TCGv_i64 tcg_op1, TCGv_i64 tcg_op2)
{
    static NeonGenTwo64OpFn * const fns[3][2] = {
        { gen_helper_neon_addl_u16, gen_helper_neon_subl_u16 },
        { gen_helper_neon_addl_u32, gen_helper_neon_subl_u32 },
        { tcg_gen_add_i64, tcg_gen_sub_i64 },
    };
    NeonGenTwo64OpFn *genfn;
    assert(size < 3);

    genfn = fns[size][is_sub];
    genfn(tcg_res, tcg_op1, tcg_op2);
}

static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size,
                                int opcode, int rd, int rn, int rm)
{
    /* 3-reg-different widening insns: 64 x 64 -> 128 */
    TCGv_i64 tcg_res[2];
    int pass, accop;

    tcg_res[0] = tcg_temp_new_i64();
    tcg_res[1] = tcg_temp_new_i64();

    /* Does this op do an adding accumulate, a subtracting accumulate,
     * or no accumulate at all?
     */
    switch (opcode) {
    case 5:
    case 8:
    case 9:
        accop = 1;
        break;
    case 10:
    case 11:
        accop = -1;
        break;
    default:
        accop = 0;
        break;
    }

    if (accop != 0) {
        read_vec_element(s, tcg_res[0], rd, 0, MO_64);
        read_vec_element(s, tcg_res[1], rd, 1, MO_64);
    }

    /* size == 2 means two 32x32->64 operations; this is worth special
     * casing because we can generally handle it inline.
     */
    if (size == 2) {
        for (pass = 0; pass < 2; pass++) {
            TCGv_i64 tcg_op1 = tcg_temp_new_i64();
            TCGv_i64 tcg_op2 = tcg_temp_new_i64();
            TCGv_i64 tcg_passres;
            MemOp memop = MO_32 | (is_u ? 0 : MO_SIGN);

            int elt = pass + is_q * 2;

            read_vec_element(s, tcg_op1, rn, elt, memop);
            read_vec_element(s, tcg_op2, rm, elt, memop);

            if (accop == 0) {
                tcg_passres = tcg_res[pass];
            } else {
                tcg_passres = tcg_temp_new_i64();
            }

            switch (opcode) {
            case 0: /* SADDL, SADDL2, UADDL, UADDL2 */
                tcg_gen_add_i64(tcg_passres, tcg_op1, tcg_op2);
                break;
            case 2: /* SSUBL, SSUBL2, USUBL, USUBL2 */
                tcg_gen_sub_i64(tcg_passres, tcg_op1, tcg_op2);
                break;
            case 5: /* SABAL, SABAL2, UABAL, UABAL2 */
            case 7: /* SABDL, SABDL2, UABDL, UABDL2 */
            {
                TCGv_i64 tcg_tmp1 = tcg_temp_new_i64();
                TCGv_i64 tcg_tmp2 = tcg_temp_new_i64();

                tcg_gen_sub_i64(tcg_tmp1, tcg_op1, tcg_op2);
                tcg_gen_sub_i64(tcg_tmp2, tcg_op2, tcg_op1);
                tcg_gen_movcond_i64(is_u ? TCG_COND_GEU : TCG_COND_GE,
                                    tcg_passres,
                                    tcg_op1, tcg_op2, tcg_tmp1, tcg_tmp2);
                break;
            }
            case 8: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
            case 10: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
            case 12: /* UMULL, UMULL2, SMULL, SMULL2 */
                tcg_gen_mul_i64(tcg_passres, tcg_op1, tcg_op2);
                break;
            case 9: /* SQDMLAL, SQDMLAL2 */
            case 11: /* SQDMLSL, SQDMLSL2 */
            case 13: /* SQDMULL, SQDMULL2 */
                tcg_gen_mul_i64(tcg_passres, tcg_op1, tcg_op2);
                gen_helper_neon_addl_saturate_s64(tcg_passres, tcg_env,
                                                  tcg_passres, tcg_passres);
                break;
            default:
                g_assert_not_reached();
            }

            if (opcode == 9 || opcode == 11) {
                /* saturating accumulate ops */
                if (accop < 0) {
                    tcg_gen_neg_i64(tcg_passres, tcg_passres);
                }
                gen_helper_neon_addl_saturate_s64(tcg_res[pass], tcg_env,
                                                  tcg_res[pass], tcg_passres);
            } else if (accop > 0) {
                tcg_gen_add_i64(tcg_res[pass], tcg_res[pass], tcg_passres);
            } else if (accop < 0) {
                tcg_gen_sub_i64(tcg_res[pass], tcg_res[pass], tcg_passres);
            }
        }
    } else {
        /* size 0 or 1, generally helper functions */
        for (pass = 0; pass < 2; pass++) {
            TCGv_i32 tcg_op1 = tcg_temp_new_i32();
            TCGv_i32 tcg_op2 = tcg_temp_new_i32();
            TCGv_i64 tcg_passres;
            int elt = pass + is_q * 2;

            read_vec_element_i32(s, tcg_op1, rn, elt, MO_32);
            read_vec_element_i32(s, tcg_op2, rm, elt, MO_32);

            if (accop == 0) {
                tcg_passres = tcg_res[pass];
            } else {
                tcg_passres = tcg_temp_new_i64();
            }

            switch (opcode) {
            case 0: /* SADDL, SADDL2, UADDL, UADDL2 */
            case 2: /* SSUBL, SSUBL2, USUBL, USUBL2 */
            {
                TCGv_i64 tcg_op2_64 = tcg_temp_new_i64();
                static NeonGenWidenFn * const widenfns[2][2] = {
                    { gen_helper_neon_widen_s8, gen_helper_neon_widen_u8 },
                    { gen_helper_neon_widen_s16, gen_helper_neon_widen_u16 },
                };
                NeonGenWidenFn *widenfn = widenfns[size][is_u];

                widenfn(tcg_op2_64, tcg_op2);
                widenfn(tcg_passres, tcg_op1);
                gen_neon_addl(size, (opcode == 2), tcg_passres,
                              tcg_passres, tcg_op2_64);
                break;
            }
            case 5: /* SABAL, SABAL2, UABAL, UABAL2 */
            case 7: /* SABDL, SABDL2, UABDL, UABDL2 */
                if (size == 0) {
                    if (is_u) {
                        gen_helper_neon_abdl_u16(tcg_passres, tcg_op1, tcg_op2);
                    } else {
                        gen_helper_neon_abdl_s16(tcg_passres, tcg_op1, tcg_op2);
                    }
                } else {
                    if (is_u) {
                        gen_helper_neon_abdl_u32(tcg_passres, tcg_op1, tcg_op2);
                    } else {
                        gen_helper_neon_abdl_s32(tcg_passres, tcg_op1, tcg_op2);
                    }
                }
                break;
            case 8: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
            case 10: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
            case 12: /* UMULL, UMULL2, SMULL, SMULL2 */
                if (size == 0) {
                    if (is_u) {
                        gen_helper_neon_mull_u8(tcg_passres, tcg_op1, tcg_op2);
                    } else {
                        gen_helper_neon_mull_s8(tcg_passres, tcg_op1, tcg_op2);
                    }
                } else {
                    if (is_u) {
                        gen_helper_neon_mull_u16(tcg_passres, tcg_op1, tcg_op2);
                    } else {
                        gen_helper_neon_mull_s16(tcg_passres, tcg_op1, tcg_op2);
                    }
                }
                break;
            case 9: /* SQDMLAL, SQDMLAL2 */
            case 11: /* SQDMLSL, SQDMLSL2 */
            case 13: /* SQDMULL, SQDMULL2 */
                assert(size == 1);
                gen_helper_neon_mull_s16(tcg_passres, tcg_op1, tcg_op2);
                gen_helper_neon_addl_saturate_s32(tcg_passres, tcg_env,
                                                  tcg_passres, tcg_passres);
                break;
            default:
                g_assert_not_reached();
            }

            if (accop != 0) {
                if (opcode == 9 || opcode == 11) {
                    /* saturating accumulate ops */
                    if (accop < 0) {
                        gen_helper_neon_negl_u32(tcg_passres, tcg_passres);
                    }
                    gen_helper_neon_addl_saturate_s32(tcg_res[pass], tcg_env,
                                                      tcg_res[pass],
                                                      tcg_passres);
                } else {
                    gen_neon_addl(size, (accop < 0), tcg_res[pass],
                                  tcg_res[pass], tcg_passres);
                }
            }
        }
    }

    write_vec_element(s, tcg_res[0], rd, 0, MO_64);
    write_vec_element(s, tcg_res[1], rd, 1, MO_64);
}

static void handle_3rd_wide(DisasContext *s, int is_q, int is_u, int size,
                            int opcode, int rd, int rn, int rm)
{
    TCGv_i64 tcg_res[2];
    int part = is_q ? 2 : 0;
    int pass;

    for (pass = 0; pass < 2; pass++) {
        TCGv_i64 tcg_op1 = tcg_temp_new_i64();
        TCGv_i32 tcg_op2 = tcg_temp_new_i32();
        TCGv_i64 tcg_op2_wide = tcg_temp_new_i64();
        static NeonGenWidenFn * const widenfns[3][2] = {
            { gen_helper_neon_widen_s8, gen_helper_neon_widen_u8 },
            { gen_helper_neon_widen_s16, gen_helper_neon_widen_u16 },
            { tcg_gen_ext_i32_i64, tcg_gen_extu_i32_i64 },
        };
        NeonGenWidenFn *widenfn = widenfns[size][is_u];

        read_vec_element(s, tcg_op1, rn, pass, MO_64);
        read_vec_element_i32(s, tcg_op2, rm, part + pass, MO_32);
        widenfn(tcg_op2_wide, tcg_op2);
        tcg_res[pass] = tcg_temp_new_i64();
        gen_neon_addl(size, (opcode == 3),
                      tcg_res[pass], tcg_op1, tcg_op2_wide);
    }

    for (pass = 0; pass < 2; pass++) {
        write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
    }
}

static void do_narrow_round_high_u32(TCGv_i32 res, TCGv_i64 in)
{
    tcg_gen_addi_i64(in, in, 1U << 31);
    tcg_gen_extrh_i64_i32(res, in);
}

static void handle_3rd_narrowing(DisasContext *s, int is_q, int is_u, int size,
                                 int opcode, int rd, int rn, int rm)
{
    TCGv_i32 tcg_res[2];
    int part = is_q ? 2 : 0;
    int pass;

    for (pass = 0; pass < 2; pass++) {
        TCGv_i64 tcg_op1 = tcg_temp_new_i64();
        TCGv_i64 tcg_op2 = tcg_temp_new_i64();
        TCGv_i64 tcg_wideres = tcg_temp_new_i64();
        static NeonGenNarrowFn * const narrowfns[3][2] = {
            { gen_helper_neon_narrow_high_u8,
              gen_helper_neon_narrow_round_high_u8 },
            { gen_helper_neon_narrow_high_u16,
              gen_helper_neon_narrow_round_high_u16 },
            { tcg_gen_extrh_i64_i32, do_narrow_round_high_u32 },
        };
        NeonGenNarrowFn *gennarrow = narrowfns[size][is_u];

        read_vec_element(s, tcg_op1, rn, pass, MO_64);
        read_vec_element(s, tcg_op2, rm, pass, MO_64);

        gen_neon_addl(size, (opcode == 6), tcg_wideres, tcg_op1, tcg_op2);

        tcg_res[pass] = tcg_temp_new_i32();
        gennarrow(tcg_res[pass], tcg_wideres);
    }

    for (pass = 0; pass < 2; pass++) {
        write_vec_element_i32(s, tcg_res[pass], rd, pass + part, MO_32);
    }
    clear_vec_high(s, is_q, rd);
}

/* AdvSIMD three different
 *   31  30  29 28       24 23  22  21 20  16 15    12 11 10 9    5 4    0
 * +---+---+---+-----------+------+---+------+--------+-----+------+------+
 * | 0 | Q | U | 0 1 1 1 0 | size | 1 |  Rm  | opcode | 0 0 |  Rn  |  Rd  |
 * +---+---+---+-----------+------+---+------+--------+-----+------+------+
 */
static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
{
    /* Instructions in this group fall into three basic classes
     * (in each case with the operation working on each element in
     * the input vectors):
     * (1) widening 64 x 64 -> 128 (with possibly Vd as an extra
     *     128 bit input)
     * (2) wide 64 x 128 -> 128
     * (3) narrowing 128 x 128 -> 64
     * Here we do initial decode, catch unallocated cases and
     * dispatch to separate functions for each class.
     */
    int is_q = extract32(insn, 30, 1);
    int is_u = extract32(insn, 29, 1);
    int size = extract32(insn, 22, 2);
    int opcode = extract32(insn, 12, 4);
    int rm = extract32(insn, 16, 5);
    int rn = extract32(insn, 5, 5);
    int rd = extract32(insn, 0, 5);

    switch (opcode) {
    case 1: /* SADDW, SADDW2, UADDW, UADDW2 */
    case 3: /* SSUBW, SSUBW2, USUBW, USUBW2 */
        /* 64 x 128 -> 128 */
        if (size == 3) {
            unallocated_encoding(s);
            return;
        }
        if (!fp_access_check(s)) {
            return;
        }
        handle_3rd_wide(s, is_q, is_u, size, opcode, rd, rn, rm);
        break;
    case 4: /* ADDHN, ADDHN2, RADDHN, RADDHN2 */
    case 6: /* SUBHN, SUBHN2, RSUBHN, RSUBHN2 */
        /* 128 x 128 -> 64 */
        if (size == 3) {
            unallocated_encoding(s);
            return;
        }
        if (!fp_access_check(s)) {
            return;
        }
        handle_3rd_narrowing(s, is_q, is_u, size, opcode, rd, rn, rm);
        break;
    case 14: /* PMULL, PMULL2 */
        if (is_u) {
            unallocated_encoding(s);
            return;
        }
        switch (size) {
        case 0: /* PMULL.P8 */
            if (!fp_access_check(s)) {
                return;
            }
            /* The Q field specifies lo/hi half input for this insn.  */
            gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
                             gen_helper_neon_pmull_h);
            break;

        case 3: /* PMULL.P64 */
            if (!dc_isar_feature(aa64_pmull, s)) {
                unallocated_encoding(s);
                return;
            }
            if (!fp_access_check(s)) {
                return;
            }
            /* The Q field specifies lo/hi half input for this insn.  */
            gen_gvec_op3_ool(s, true, rd, rn, rm, is_q,
                             gen_helper_gvec_pmull_q);
            break;

        default:
            unallocated_encoding(s);
            break;
        }
        return;
    case 9: /* SQDMLAL, SQDMLAL2 */
    case 11: /* SQDMLSL, SQDMLSL2 */
    case 13: /* SQDMULL, SQDMULL2 */
        if (is_u || size == 0) {
            unallocated_encoding(s);
            return;
        }
        /* fall through */
    case 0: /* SADDL, SADDL2, UADDL, UADDL2 */
    case 2: /* SSUBL, SSUBL2, USUBL, USUBL2 */
    case 5: /* SABAL, SABAL2, UABAL, UABAL2 */
    case 7: /* SABDL, SABDL2, UABDL, UABDL2 */
    case 8: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
    case 10: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
    case 12: /* SMULL, SMULL2, UMULL, UMULL2 */
        /* 64 x 64 -> 128 */
        if (size == 3) {
            unallocated_encoding(s);
            return;
        }
        if (!fp_access_check(s)) {
            return;
        }

        handle_3rd_widening(s, is_q, is_u, size, opcode, rd, rn, rm);
        break;
    default:
        /* opcode 15 not allocated */
        unallocated_encoding(s);
        break;
    }
}

/* Logic op (opcode == 3) subgroup of C3.6.16. */
static void disas_simd_3same_logic(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int rm = extract32(insn, 16, 5);
    int size = extract32(insn, 22, 2);
    bool is_u = extract32(insn, 29, 1);
    bool is_q = extract32(insn, 30, 1);

    if (!fp_access_check(s)) {
        return;
    }

    switch (size + 4 * is_u) {
    case 0: /* AND */
        gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_and, 0);
        return;
    case 1: /* BIC */
        gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_andc, 0);
        return;
    case 2: /* ORR */
        gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_or, 0);
        return;
    case 3: /* ORN */
        gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_orc, 0);
        return;
    case 4: /* EOR */
        gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_xor, 0);
        return;

    case 5: /* BSL bitwise select */
        gen_gvec_fn4(s, is_q, rd, rd, rn, rm, tcg_gen_gvec_bitsel, 0);
        return;
    case 6: /* BIT, bitwise insert if true */
        gen_gvec_fn4(s, is_q, rd, rm, rn, rd, tcg_gen_gvec_bitsel, 0);
        return;
    case 7: /* BIF, bitwise insert if false */
        gen_gvec_fn4(s, is_q, rd, rm, rd, rn, tcg_gen_gvec_bitsel, 0);
        return;

    default:
        g_assert_not_reached();
    }
}

/* Pairwise op subgroup of C3.6.16.
 *
 * This is called directly or via the handle_3same_float for float pairwise
 * operations where the opcode and size are calculated differently.
 */
static void handle_simd_3same_pair(DisasContext *s, int is_q, int u, int opcode,
                                   int size, int rn, int rm, int rd)
{
    TCGv_ptr fpst;
    int pass;

    /* Floating point operations need fpst */
    if (opcode >= 0x58) {
        fpst = fpstatus_ptr(FPST_FPCR);
    } else {
        fpst = NULL;
    }

    if (!fp_access_check(s)) {
        return;
    }

    /* These operations work on the concatenated rm:rn, with each pair of
     * adjacent elements being operated on to produce an element in the result.
     */
    if (size == 3) {
        TCGv_i64 tcg_res[2];

        for (pass = 0; pass < 2; pass++) {
            TCGv_i64 tcg_op1 = tcg_temp_new_i64();
            TCGv_i64 tcg_op2 = tcg_temp_new_i64();
            int passreg = (pass == 0) ? rn : rm;

            read_vec_element(s, tcg_op1, passreg, 0, MO_64);
            read_vec_element(s, tcg_op2, passreg, 1, MO_64);
            tcg_res[pass] = tcg_temp_new_i64();

            switch (opcode) {
            case 0x17: /* ADDP */
                tcg_gen_add_i64(tcg_res[pass], tcg_op1, tcg_op2);
                break;
            case 0x58: /* FMAXNMP */
                gen_helper_vfp_maxnumd(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            case 0x5a: /* FADDP */
                gen_helper_vfp_addd(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            case 0x5e: /* FMAXP */
                gen_helper_vfp_maxd(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            case 0x78: /* FMINNMP */
                gen_helper_vfp_minnumd(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            case 0x7e: /* FMINP */
                gen_helper_vfp_mind(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            default:
                g_assert_not_reached();
            }
        }

        for (pass = 0; pass < 2; pass++) {
            write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
        }
    } else {
        int maxpass = is_q ? 4 : 2;
        TCGv_i32 tcg_res[4];

        for (pass = 0; pass < maxpass; pass++) {
            TCGv_i32 tcg_op1 = tcg_temp_new_i32();
            TCGv_i32 tcg_op2 = tcg_temp_new_i32();
            NeonGenTwoOpFn *genfn = NULL;
            int passreg = pass < (maxpass / 2) ? rn : rm;
            int passelt = (is_q && (pass & 1)) ? 2 : 0;

            read_vec_element_i32(s, tcg_op1, passreg, passelt, MO_32);
            read_vec_element_i32(s, tcg_op2, passreg, passelt + 1, MO_32);
            tcg_res[pass] = tcg_temp_new_i32();

            switch (opcode) {
            case 0x17: /* ADDP */
            {
                static NeonGenTwoOpFn * const fns[3] = {
                    gen_helper_neon_padd_u8,
                    gen_helper_neon_padd_u16,
                    tcg_gen_add_i32,
                };
                genfn = fns[size];
                break;
            }
            case 0x14: /* SMAXP, UMAXP */
            {
                static NeonGenTwoOpFn * const fns[3][2] = {
                    { gen_helper_neon_pmax_s8, gen_helper_neon_pmax_u8 },
                    { gen_helper_neon_pmax_s16, gen_helper_neon_pmax_u16 },
                    { tcg_gen_smax_i32, tcg_gen_umax_i32 },
                };
                genfn = fns[size][u];
                break;
            }
            case 0x15: /* SMINP, UMINP */
            {
                static NeonGenTwoOpFn * const fns[3][2] = {
                    { gen_helper_neon_pmin_s8, gen_helper_neon_pmin_u8 },
                    { gen_helper_neon_pmin_s16, gen_helper_neon_pmin_u16 },
                    { tcg_gen_smin_i32, tcg_gen_umin_i32 },
                };
                genfn = fns[size][u];
                break;
            }
            /* The FP operations are all on single floats (32 bit) */
            case 0x58: /* FMAXNMP */
                gen_helper_vfp_maxnums(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            case 0x5a: /* FADDP */
                gen_helper_vfp_adds(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            case 0x5e: /* FMAXP */
                gen_helper_vfp_maxs(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            case 0x78: /* FMINNMP */
                gen_helper_vfp_minnums(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            case 0x7e: /* FMINP */
                gen_helper_vfp_mins(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            default:
                g_assert_not_reached();
            }

            /* FP ops called directly, otherwise call now */
            if (genfn) {
                genfn(tcg_res[pass], tcg_op1, tcg_op2);
            }
        }

        for (pass = 0; pass < maxpass; pass++) {
            write_vec_element_i32(s, tcg_res[pass], rd, pass, MO_32);
        }
        clear_vec_high(s, is_q, rd);
    }
}

/* Floating point op subgroup of C3.6.16. */
static void disas_simd_3same_float(DisasContext *s, uint32_t insn)
{
    /* For floating point ops, the U, size[1] and opcode bits
     * together indicate the operation. size[0] indicates single
     * or double.
     */
    int fpopcode = extract32(insn, 11, 5)
        | (extract32(insn, 23, 1) << 5)
        | (extract32(insn, 29, 1) << 6);
    int is_q = extract32(insn, 30, 1);
    int size = extract32(insn, 22, 1);
    int rm = extract32(insn, 16, 5);
    int rn = extract32(insn, 5, 5);
    int rd = extract32(insn, 0, 5);

    int datasize = is_q ? 128 : 64;
    int esize = 32 << size;
    int elements = datasize / esize;

    if (size == 1 && !is_q) {
        unallocated_encoding(s);
        return;
    }

    switch (fpopcode) {
    case 0x58: /* FMAXNMP */
    case 0x5a: /* FADDP */
    case 0x5e: /* FMAXP */
    case 0x78: /* FMINNMP */
    case 0x7e: /* FMINP */
        if (size && !is_q) {
            unallocated_encoding(s);
            return;
        }
        handle_simd_3same_pair(s, is_q, 0, fpopcode, size ? MO_64 : MO_32,
                               rn, rm, rd);
        return;
    case 0x1f: /* FRECPS */
    case 0x3f: /* FRSQRTS */
    case 0x5d: /* FACGE */
    case 0x7d: /* FACGT */
    case 0x1c: /* FCMEQ */
    case 0x5c: /* FCMGE */
    case 0x7a: /* FABD */
    case 0x7c: /* FCMGT */
        if (!fp_access_check(s)) {
            return;
        }
        handle_3same_float(s, size, elements, fpopcode, rd, rn, rm);
        return;

    case 0x1d: /* FMLAL  */
    case 0x3d: /* FMLSL  */
    case 0x59: /* FMLAL2 */
    case 0x79: /* FMLSL2 */
        if (size & 1 || !dc_isar_feature(aa64_fhm, s)) {
            unallocated_encoding(s);
            return;
        }
        if (fp_access_check(s)) {
            int is_s = extract32(insn, 23, 1);
            int is_2 = extract32(insn, 29, 1);
            int data = (is_2 << 1) | is_s;
            tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
                               vec_full_reg_offset(s, rn),
                               vec_full_reg_offset(s, rm), tcg_env,
                               is_q ? 16 : 8, vec_full_reg_size(s),
                               data, gen_helper_gvec_fmlal_a64);
        }
        return;

    default:
    case 0x18: /* FMAXNM */
    case 0x19: /* FMLA */
    case 0x1a: /* FADD */
    case 0x1b: /* FMULX */
    case 0x1e: /* FMAX */
    case 0x38: /* FMINNM */
    case 0x39: /* FMLS */
    case 0x3a: /* FSUB */
    case 0x3e: /* FMIN */
    case 0x5b: /* FMUL */
    case 0x5f: /* FDIV */
        unallocated_encoding(s);
        return;
    }
}

/* Integer op subgroup of C3.6.16. */
static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
{
    int is_q = extract32(insn, 30, 1);
    int u = extract32(insn, 29, 1);
    int size = extract32(insn, 22, 2);
    int opcode = extract32(insn, 11, 5);
    int rm = extract32(insn, 16, 5);
    int rn = extract32(insn, 5, 5);
    int rd = extract32(insn, 0, 5);
    int pass;
    TCGCond cond;

    switch (opcode) {
    case 0x13: /* MUL, PMUL */
        if (u && size != 0) {
            unallocated_encoding(s);
            return;
        }
        /* fall through */
    case 0x0: /* SHADD, UHADD */
    case 0x2: /* SRHADD, URHADD */
    case 0x4: /* SHSUB, UHSUB */
    case 0xc: /* SMAX, UMAX */
    case 0xd: /* SMIN, UMIN */
    case 0xe: /* SABD, UABD */
    case 0xf: /* SABA, UABA */
    case 0x12: /* MLA, MLS */
        if (size == 3) {
            unallocated_encoding(s);
            return;
        }
        break;
    case 0x16: /* SQDMULH, SQRDMULH */
        if (size == 0 || size == 3) {
            unallocated_encoding(s);
            return;
        }
        break;
    default:
        if (size == 3 && !is_q) {
            unallocated_encoding(s);
            return;
        }
        break;
    }

    if (!fp_access_check(s)) {
        return;
    }

    switch (opcode) {
    case 0x01: /* SQADD, UQADD */
        if (u) {
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uqadd_qc, size);
        } else {
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqadd_qc, size);
        }
        return;
    case 0x05: /* SQSUB, UQSUB */
        if (u) {
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uqsub_qc, size);
        } else {
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqsub_qc, size);
        }
        return;
    case 0x08: /* SSHL, USHL */
        if (u) {
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_ushl, size);
        } else {
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sshl, size);
        }
        return;
    case 0x0c: /* SMAX, UMAX */
        if (u) {
            gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
        } else {
            gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smax, size);
        }
        return;
    case 0x0d: /* SMIN, UMIN */
        if (u) {
            gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umin, size);
        } else {
            gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smin, size);
        }
        return;
    case 0xe: /* SABD, UABD */
        if (u) {
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uabd, size);
        } else {
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sabd, size);
        }
        return;
    case 0xf: /* SABA, UABA */
        if (u) {
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uaba, size);
        } else {
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_saba, size);
        }
        return;
    case 0x10: /* ADD, SUB */
        if (u) {
            gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_sub, size);
        } else {
            gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_add, size);
        }
        return;
    case 0x13: /* MUL, PMUL */
        if (!u) { /* MUL */
            gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_mul, size);
        } else {  /* PMUL */
            gen_gvec_op3_ool(s, is_q, rd, rn, rm, 0, gen_helper_gvec_pmul_b);
        }
        return;
    case 0x12: /* MLA, MLS */
        if (u) {
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mls, size);
        } else {
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mla, size);
        }
        return;
    case 0x16: /* SQDMULH, SQRDMULH */
        {
            static gen_helper_gvec_3_ptr * const fns[2][2] = {
                { gen_helper_neon_sqdmulh_h, gen_helper_neon_sqrdmulh_h },
                { gen_helper_neon_sqdmulh_s, gen_helper_neon_sqrdmulh_s },
            };
            gen_gvec_op3_qc(s, is_q, rd, rn, rm, fns[size - 1][u]);
        }
        return;
    case 0x11:
        if (!u) { /* CMTST */
            gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_cmtst, size);
            return;
        }
        /* else CMEQ */
        cond = TCG_COND_EQ;
        goto do_gvec_cmp;
    case 0x06: /* CMGT, CMHI */
        cond = u ? TCG_COND_GTU : TCG_COND_GT;
        goto do_gvec_cmp;
    case 0x07: /* CMGE, CMHS */
        cond = u ? TCG_COND_GEU : TCG_COND_GE;
    do_gvec_cmp:
        tcg_gen_gvec_cmp(cond, size, vec_full_reg_offset(s, rd),
                         vec_full_reg_offset(s, rn),
                         vec_full_reg_offset(s, rm),
                         is_q ? 16 : 8, vec_full_reg_size(s));
        return;
    }

    if (size == 3) {
        assert(is_q);
        for (pass = 0; pass < 2; pass++) {
            TCGv_i64 tcg_op1 = tcg_temp_new_i64();
            TCGv_i64 tcg_op2 = tcg_temp_new_i64();
            TCGv_i64 tcg_res = tcg_temp_new_i64();

            read_vec_element(s, tcg_op1, rn, pass, MO_64);
            read_vec_element(s, tcg_op2, rm, pass, MO_64);

            handle_3same_64(s, opcode, u, tcg_res, tcg_op1, tcg_op2);

            write_vec_element(s, tcg_res, rd, pass, MO_64);
        }
    } else {
        for (pass = 0; pass < (is_q ? 4 : 2); pass++) {
            TCGv_i32 tcg_op1 = tcg_temp_new_i32();
            TCGv_i32 tcg_op2 = tcg_temp_new_i32();
            TCGv_i32 tcg_res = tcg_temp_new_i32();
            NeonGenTwoOpFn *genfn = NULL;
            NeonGenTwoOpEnvFn *genenvfn = NULL;

            read_vec_element_i32(s, tcg_op1, rn, pass, MO_32);
            read_vec_element_i32(s, tcg_op2, rm, pass, MO_32);

            switch (opcode) {
            case 0x0: /* SHADD, UHADD */
            {
                static NeonGenTwoOpFn * const fns[3][2] = {
                    { gen_helper_neon_hadd_s8, gen_helper_neon_hadd_u8 },
                    { gen_helper_neon_hadd_s16, gen_helper_neon_hadd_u16 },
                    { gen_helper_neon_hadd_s32, gen_helper_neon_hadd_u32 },
                };
                genfn = fns[size][u];
                break;
            }
            case 0x2: /* SRHADD, URHADD */
            {
                static NeonGenTwoOpFn * const fns[3][2] = {
                    { gen_helper_neon_rhadd_s8, gen_helper_neon_rhadd_u8 },
                    { gen_helper_neon_rhadd_s16, gen_helper_neon_rhadd_u16 },
                    { gen_helper_neon_rhadd_s32, gen_helper_neon_rhadd_u32 },
                };
                genfn = fns[size][u];
                break;
            }
            case 0x4: /* SHSUB, UHSUB */
            {
                static NeonGenTwoOpFn * const fns[3][2] = {
                    { gen_helper_neon_hsub_s8, gen_helper_neon_hsub_u8 },
                    { gen_helper_neon_hsub_s16, gen_helper_neon_hsub_u16 },
                    { gen_helper_neon_hsub_s32, gen_helper_neon_hsub_u32 },
                };
                genfn = fns[size][u];
                break;
            }
            case 0x9: /* SQSHL, UQSHL */
            {
                static NeonGenTwoOpEnvFn * const fns[3][2] = {
                    { gen_helper_neon_qshl_s8, gen_helper_neon_qshl_u8 },
                    { gen_helper_neon_qshl_s16, gen_helper_neon_qshl_u16 },
                    { gen_helper_neon_qshl_s32, gen_helper_neon_qshl_u32 },
                };
                genenvfn = fns[size][u];
                break;
            }
            case 0xa: /* SRSHL, URSHL */
            {
                static NeonGenTwoOpFn * const fns[3][2] = {
                    { gen_helper_neon_rshl_s8, gen_helper_neon_rshl_u8 },
                    { gen_helper_neon_rshl_s16, gen_helper_neon_rshl_u16 },
                    { gen_helper_neon_rshl_s32, gen_helper_neon_rshl_u32 },
                };
                genfn = fns[size][u];
                break;
            }
            case 0xb: /* SQRSHL, UQRSHL */
            {
                static NeonGenTwoOpEnvFn * const fns[3][2] = {
                    { gen_helper_neon_qrshl_s8, gen_helper_neon_qrshl_u8 },
                    { gen_helper_neon_qrshl_s16, gen_helper_neon_qrshl_u16 },
                    { gen_helper_neon_qrshl_s32, gen_helper_neon_qrshl_u32 },
                };
                genenvfn = fns[size][u];
                break;
            }
            default:
                g_assert_not_reached();
            }

            if (genenvfn) {
                genenvfn(tcg_res, tcg_env, tcg_op1, tcg_op2);
            } else {
                genfn(tcg_res, tcg_op1, tcg_op2);
            }

            write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
        }
    }
    clear_vec_high(s, is_q, rd);
}

/* AdvSIMD three same
 *  31  30  29  28       24 23  22  21 20  16 15    11  10 9    5 4    0
 * +---+---+---+-----------+------+---+------+--------+---+------+------+
 * | 0 | Q | U | 0 1 1 1 0 | size | 1 |  Rm  | opcode | 1 |  Rn  |  Rd  |
 * +---+---+---+-----------+------+---+------+--------+---+------+------+
 */
static void disas_simd_three_reg_same(DisasContext *s, uint32_t insn)
{
    int opcode = extract32(insn, 11, 5);

    switch (opcode) {
    case 0x3: /* logic ops */
        disas_simd_3same_logic(s, insn);
        break;
    case 0x17: /* ADDP */
    case 0x14: /* SMAXP, UMAXP */
    case 0x15: /* SMINP, UMINP */
    {
        /* Pairwise operations */
        int is_q = extract32(insn, 30, 1);
        int u = extract32(insn, 29, 1);
        int size = extract32(insn, 22, 2);
        int rm = extract32(insn, 16, 5);
        int rn = extract32(insn, 5, 5);
        int rd = extract32(insn, 0, 5);
        if (opcode == 0x17) {
            if (u || (size == 3 && !is_q)) {
                unallocated_encoding(s);
                return;
            }
        } else {
            if (size == 3) {
                unallocated_encoding(s);
                return;
            }
        }
        handle_simd_3same_pair(s, is_q, u, opcode, size, rn, rm, rd);
        break;
    }
    case 0x18 ... 0x31:
        /* floating point ops, sz[1] and U are part of opcode */
        disas_simd_3same_float(s, insn);
        break;
    default:
        disas_simd_3same_int(s, insn);
        break;
    }
}

/*
 * Advanced SIMD three same (ARMv8.2 FP16 variants)
 *
 *  31  30  29  28       24 23  22 21 20  16 15 14 13    11 10  9    5 4    0
 * +---+---+---+-----------+---------+------+-----+--------+---+------+------+
 * | 0 | Q | U | 0 1 1 1 0 | a | 1 0 |  Rm  | 0 0 | opcode | 1 |  Rn  |  Rd  |
 * +---+---+---+-----------+---------+------+-----+--------+---+------+------+
 *
 * This includes FMULX, FCMEQ (register), FRECPS, FRSQRTS, FCMGE
 * (register), FACGE, FABD, FCMGT (register) and FACGT.
 *
 */
static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
{
    int opcode = extract32(insn, 11, 3);
    int u = extract32(insn, 29, 1);
    int a = extract32(insn, 23, 1);
    int is_q = extract32(insn, 30, 1);
    int rm = extract32(insn, 16, 5);
    int rn = extract32(insn, 5, 5);
    int rd = extract32(insn, 0, 5);
    /*
     * For these floating point ops, the U, a and opcode bits
     * together indicate the operation.
     */
    int fpopcode = opcode | (a << 3) | (u << 4);
    int datasize = is_q ? 128 : 64;
    int elements = datasize / 16;
    bool pairwise;
    TCGv_ptr fpst;
    int pass;

    switch (fpopcode) {
    case 0x4: /* FCMEQ */
    case 0x7: /* FRECPS */
    case 0xf: /* FRSQRTS */
    case 0x14: /* FCMGE */
    case 0x15: /* FACGE */
    case 0x1a: /* FABD */
    case 0x1c: /* FCMGT */
    case 0x1d: /* FACGT */
        pairwise = false;
        break;
    case 0x10: /* FMAXNMP */
    case 0x12: /* FADDP */
    case 0x16: /* FMAXP */
    case 0x18: /* FMINNMP */
    case 0x1e: /* FMINP */
        pairwise = true;
        break;
    default:
    case 0x0: /* FMAXNM */
    case 0x1: /* FMLA */
    case 0x2: /* FADD */
    case 0x3: /* FMULX */
    case 0x6: /* FMAX */
    case 0x8: /* FMINNM */
    case 0x9: /* FMLS */
    case 0xa: /* FSUB */
    case 0xe: /* FMIN */
    case 0x13: /* FMUL */
    case 0x17: /* FDIV */
        unallocated_encoding(s);
        return;
    }

    if (!dc_isar_feature(aa64_fp16, s)) {
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    fpst = fpstatus_ptr(FPST_FPCR_F16);

    if (pairwise) {
        int maxpass = is_q ? 8 : 4;
        TCGv_i32 tcg_op1 = tcg_temp_new_i32();
        TCGv_i32 tcg_op2 = tcg_temp_new_i32();
        TCGv_i32 tcg_res[8];

        for (pass = 0; pass < maxpass; pass++) {
            int passreg = pass < (maxpass / 2) ? rn : rm;
            int passelt = (pass << 1) & (maxpass - 1);

            read_vec_element_i32(s, tcg_op1, passreg, passelt, MO_16);
            read_vec_element_i32(s, tcg_op2, passreg, passelt + 1, MO_16);
            tcg_res[pass] = tcg_temp_new_i32();

            switch (fpopcode) {
            case 0x10: /* FMAXNMP */
                gen_helper_advsimd_maxnumh(tcg_res[pass], tcg_op1, tcg_op2,
                                           fpst);
                break;
            case 0x12: /* FADDP */
                gen_helper_advsimd_addh(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            case 0x16: /* FMAXP */
                gen_helper_advsimd_maxh(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            case 0x18: /* FMINNMP */
                gen_helper_advsimd_minnumh(tcg_res[pass], tcg_op1, tcg_op2,
                                           fpst);
                break;
            case 0x1e: /* FMINP */
                gen_helper_advsimd_minh(tcg_res[pass], tcg_op1, tcg_op2, fpst);
                break;
            default:
                g_assert_not_reached();
            }
        }

        for (pass = 0; pass < maxpass; pass++) {
            write_vec_element_i32(s, tcg_res[pass], rd, pass, MO_16);
        }
    } else {
        for (pass = 0; pass < elements; pass++) {
            TCGv_i32 tcg_op1 = tcg_temp_new_i32();
            TCGv_i32 tcg_op2 = tcg_temp_new_i32();
            TCGv_i32 tcg_res = tcg_temp_new_i32();

            read_vec_element_i32(s, tcg_op1, rn, pass, MO_16);
            read_vec_element_i32(s, tcg_op2, rm, pass, MO_16);

            switch (fpopcode) {
            case 0x4: /* FCMEQ */
                gen_helper_advsimd_ceq_f16(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x7: /* FRECPS */
                gen_helper_recpsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0xf: /* FRSQRTS */
                gen_helper_rsqrtsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x14: /* FCMGE */
                gen_helper_advsimd_cge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x15: /* FACGE */
                gen_helper_advsimd_acge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x1a: /* FABD */
                gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
                tcg_gen_andi_i32(tcg_res, tcg_res, 0x7fff);
                break;
            case 0x1c: /* FCMGT */
                gen_helper_advsimd_cgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            case 0x1d: /* FACGT */
                gen_helper_advsimd_acgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
                break;
            default:
            case 0x0: /* FMAXNM */
            case 0x1: /* FMLA */
            case 0x2: /* FADD */
            case 0x3: /* FMULX */
            case 0x6: /* FMAX */
            case 0x8: /* FMINNM */
            case 0x9: /* FMLS */
            case 0xa: /* FSUB */
            case 0xe: /* FMIN */
            case 0x13: /* FMUL */
            case 0x17: /* FDIV */
                g_assert_not_reached();
            }

            write_vec_element_i32(s, tcg_res, rd, pass, MO_16);
        }
    }

    clear_vec_high(s, is_q, rd);
}

/* AdvSIMD three same extra
 *  31   30  29 28       24 23  22  21 20  16  15 14    11  10 9  5 4  0
 * +---+---+---+-----------+------+---+------+---+--------+---+----+----+
 * | 0 | Q | U | 0 1 1 1 0 | size | 0 |  Rm  | 1 | opcode | 1 | Rn | Rd |
 * +---+---+---+-----------+------+---+------+---+--------+---+----+----+
 */
static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
{
    int rd = extract32(insn, 0, 5);
    int rn = extract32(insn, 5, 5);
    int opcode = extract32(insn, 11, 4);
    int rm = extract32(insn, 16, 5);
    int size = extract32(insn, 22, 2);
    bool u = extract32(insn, 29, 1);
    bool is_q = extract32(insn, 30, 1);
    bool feature;
    int rot;

    switch (u * 16 + opcode) {
    case 0x10: /* SQRDMLAH (vector) */
    case 0x11: /* SQRDMLSH (vector) */
        if (size != 1 && size != 2) {
            unallocated_encoding(s);
            return;
        }
        feature = dc_isar_feature(aa64_rdm, s);
        break;
    case 0x02: /* SDOT (vector) */
    case 0x12: /* UDOT (vector) */
        if (size != MO_32) {
            unallocated_encoding(s);
            return;
        }
        feature = dc_isar_feature(aa64_dp, s);
        break;
    case 0x03: /* USDOT */
        if (size != MO_32) {
            unallocated_encoding(s);
            return;
        }
        feature = dc_isar_feature(aa64_i8mm, s);
        break;
    case 0x04: /* SMMLA */
    case 0x14: /* UMMLA */
    case 0x05: /* USMMLA */
        if (!is_q || size != MO_32) {
            unallocated_encoding(s);
            return;
        }
        feature = dc_isar_feature(aa64_i8mm, s);
        break;
    case 0x18: /* FCMLA, #0 */
    case 0x19: /* FCMLA, #90 */
    case 0x1a: /* FCMLA, #180 */
    case 0x1b: /* FCMLA, #270 */
    case 0x1c: /* FCADD, #90 */
    case 0x1e: /* FCADD, #270 */
        if (size == 0
            || (size == 1 && !dc_isar_feature(aa64_fp16, s))
            || (size == 3 && !is_q)) {
            unallocated_encoding(s);
            return;
        }
        feature = dc_isar_feature(aa64_fcma, s);
        break;
    case 0x1d: /* BFMMLA */
        if (size != MO_16 || !is_q) {
            unallocated_encoding(s);
            return;
        }
        feature = dc_isar_feature(aa64_bf16, s);
        break;
    case 0x1f:
        switch (size) {
        case 1: /* BFDOT */
        case 3: /* BFMLAL{B,T} */
            feature = dc_isar_feature(aa64_bf16, s);
            break;
        default:
            unallocated_encoding(s);
            return;
        }
        break;
    default:
        unallocated_encoding(s);
        return;
    }
    if (!feature) {
        unallocated_encoding(s);
        return;
    }
    if (!fp_access_check(s)) {
        return;
    }

    switch (opcode) {
    case 0x0: /* SQRDMLAH (vector) */
        gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqrdmlah_qc, size);
        return;

    case 0x1: /* SQRDMLSH (vector) */
        gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqrdmlsh_qc, size);
        return;

    case 0x2: /* SDOT / UDOT */
        gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0,
                         u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b);
        return;

    case 0x3: /* USDOT */
        gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_usdot_b);
        return;

    case 0x04: /* SMMLA, UMMLA */
        gen_gvec_op4_ool(s, 1, rd, rn, rm, rd, 0,
                         u ? gen_helper_gvec_ummla_b
                         : gen_helper_gvec_smmla_b);
        return;
    case 0x05: /* USMMLA */
        gen_gvec_op4_ool(s, 1, rd, rn, rm, rd, 0, gen_helper_gvec_usmmla_b);
        return;

    case 0x8: /* FCMLA, #0 */
    case 0x9: /* FCMLA, #90 */
    case 0xa: /* FCMLA, #180 */
    case 0xb: /* FCMLA, #270 */
        rot = extract32(opcode, 0, 2);
        switch (size) {
        case 1:
            gen_gvec_op4_fpst(s, is_q, rd, rn, rm, rd, true, rot,
                              gen_helper_gvec_fcmlah);
            break;
        case 2:
            gen_gvec_op4_fpst(s, is_q, rd, rn, rm, rd, false, rot,
                              gen_helper_gvec_fcmlas);
            break;
        case 3:
            gen_gvec_op4_fpst(s, is_q, rd, rn, rm, rd, false, rot,
                              gen_helper_gvec_fcmlad);
            break;
        default:
            g_assert_not_reached();
        }
        return;

    case 0xc: /* FCADD, #90 */
    case 0xe: /* FCADD, #270 */
        rot = extract32(opcode, 1, 1);
        switch (size) {
        case 1:
            gen_gvec_op3_fpst(s, is_q, rd, rn, rm, size == 1, rot,
                              gen_helper_gvec_fcaddh);
            break;
        case 2:
            gen_gvec_op3_fpst(s, is_q, rd, rn, rm, size == 1, rot,
                              gen_helper_gvec_fcadds);
            break;
        case 3:
            gen_gvec_op3_fpst(s, is_q, rd, rn, rm, size == 1, rot,
                              gen_helper_gvec_fcaddd);
            break;
        default:
            g_assert_not_reached();
        }
        return;

    case 0xd: /* BFMMLA */
        gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfmmla);
        return;
    case 0xf:
        switch (size) {
        case 1: /* BFDOT */
            gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfdot);
            break;
        case 3: /* BFMLAL{B,T} */
            gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, false, is_q,
                              gen_helper_gvec_bfmlal);
            break;
        default:
            g_assert_not_reached();
        }
        return;

    default:
        g_assert_not_reached();
    }
}

static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q,
                                  int size, int rn, int rd)
{
    /* Handle 2-reg-misc ops which are widening (so each size element
     * in the source becomes a 2*size element in the destination.
     * The only instruction like this is FCVTL.
     */
    int pass;

    if (size == 3) {
        /* 32 -> 64 bit fp conversion */
        TCGv_i64 tcg_res[2];
        int srcelt = is_q ? 2 : 0;

        for (pass = 0; pass < 2; pass++) {
            TCGv_i32 tcg_op = tcg_temp_new_i32();
            tcg_res[pass] = tcg_temp_new_i64();

            read_vec_element_i32(s, tcg_op, rn, srcelt + pass, MO_32);
            gen_helper_vfp_fcvtds(tcg_res[pass], tcg_op, tcg_env);
        }
        for (pass = 0; pass < 2; pass++) {
            write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
        }
    } else {
        /* 16 -> 32 bit fp conversion */
        int srcelt = is_q ? 4 : 0;
        TCGv_i32 tcg_res[4];
        TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);
        TCGv_i32 ahp = get_ahp_flag();

        for (pass = 0; pass < 4; pass++) {
            tcg_res[pass] = tcg_temp_new_i32();

            read_vec_element_i32(s, tcg_res[pass], rn, srcelt + pass, MO_16);
            gen_helper_vfp_fcvt_f16_to_f32(tcg_res[pass], tcg_res[pass],
                                           fpst, ahp);
        }
        for (pass = 0; pass < 4; pass++) {
            write_vec_element_i32(s, tcg_res[pass], rd, pass, MO_32);
        }
    }
}

static void handle_rev(DisasContext *s, int opcode, bool u,
                       bool is_q, int size, int rn, int rd)
{
    int op = (opcode << 1) | u;
    int opsz = op + size;
    int grp_size = 3 - opsz;
    int dsize = is_q ? 128 : 64;
    int i;

    if (opsz >= 3) {
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    if (size == 0) {
        /* Special case bytes, use bswap op on each group of elements */
        int groups = dsize / (8 << grp_size);

        for (i = 0; i < groups; i++) {
            TCGv_i64 tcg_tmp = tcg_temp_new_i64();

            read_vec_element(s, tcg_tmp, rn, i, grp_size);
            switch (grp_size) {
            case MO_16:
                tcg_gen_bswap16_i64(tcg_tmp, tcg_tmp, TCG_BSWAP_IZ);
                break;
            case MO_32:
                tcg_gen_bswap32_i64(tcg_tmp, tcg_tmp, TCG_BSWAP_IZ);
                break;
            case MO_64:
                tcg_gen_bswap64_i64(tcg_tmp, tcg_tmp);
                break;
            default:
                g_assert_not_reached();
            }
            write_vec_element(s, tcg_tmp, rd, i, grp_size);
        }
        clear_vec_high(s, is_q, rd);
    } else {
        int revmask = (1 << grp_size) - 1;
        int esize = 8 << size;
        int elements = dsize / esize;
        TCGv_i64 tcg_rn = tcg_temp_new_i64();
        TCGv_i64 tcg_rd[2];

        for (i = 0; i < 2; i++) {
            tcg_rd[i] = tcg_temp_new_i64();
            tcg_gen_movi_i64(tcg_rd[i], 0);
        }

        for (i = 0; i < elements; i++) {
            int e_rev = (i & 0xf) ^ revmask;
            int w = (e_rev * esize) / 64;
            int o = (e_rev * esize) % 64;

            read_vec_element(s, tcg_rn, rn, i, size);
            tcg_gen_deposit_i64(tcg_rd[w], tcg_rd[w], tcg_rn, o, esize);
        }

        for (i = 0; i < 2; i++) {
            write_vec_element(s, tcg_rd[i], rd, i, MO_64);
        }
        clear_vec_high(s, true, rd);
    }
}

static void handle_2misc_pairwise(DisasContext *s, int opcode, bool u,
                                  bool is_q, int size, int rn, int rd)
{
    /* Implement the pairwise operations from 2-misc:
     * SADDLP, UADDLP, SADALP, UADALP.
     * These all add pairs of elements in the input to produce a
     * double-width result element in the output (possibly accumulating).
     */
    bool accum = (opcode == 0x6);
    int maxpass = is_q ? 2 : 1;
    int pass;
    TCGv_i64 tcg_res[2];

    if (size == 2) {
        /* 32 + 32 -> 64 op */
        MemOp memop = size + (u ? 0 : MO_SIGN);

        for (pass = 0; pass < maxpass; pass++) {
            TCGv_i64 tcg_op1 = tcg_temp_new_i64();
            TCGv_i64 tcg_op2 = tcg_temp_new_i64();

            tcg_res[pass] = tcg_temp_new_i64();

            read_vec_element(s, tcg_op1, rn, pass * 2, memop);
            read_vec_element(s, tcg_op2, rn, pass * 2 + 1, memop);
            tcg_gen_add_i64(tcg_res[pass], tcg_op1, tcg_op2);
            if (accum) {
                read_vec_element(s, tcg_op1, rd, pass, MO_64);
                tcg_gen_add_i64(tcg_res[pass], tcg_res[pass], tcg_op1);
            }
        }
    } else {
        for (pass = 0; pass < maxpass; pass++) {
            TCGv_i64 tcg_op = tcg_temp_new_i64();
            NeonGenOne64OpFn *genfn;
            static NeonGenOne64OpFn * const fns[2][2] = {
                { gen_helper_neon_addlp_s8,  gen_helper_neon_addlp_u8 },
                { gen_helper_neon_addlp_s16,  gen_helper_neon_addlp_u16 },
            };

            genfn = fns[size][u];

            tcg_res[pass] = tcg_temp_new_i64();

            read_vec_element(s, tcg_op, rn, pass, MO_64);
            genfn(tcg_res[pass], tcg_op);

            if (accum) {
                read_vec_element(s, tcg_op, rd, pass, MO_64);
                if (size == 0) {
                    gen_helper_neon_addl_u16(tcg_res[pass],
                                             tcg_res[pass], tcg_op);
                } else {
                    gen_helper_neon_addl_u32(tcg_res[pass],
                                             tcg_res[pass], tcg_op);
                }
            }
        }
    }
    if (!is_q) {
        tcg_res[1] = tcg_constant_i64(0);
    }
    for (pass = 0; pass < 2; pass++) {
        write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
    }
}

static void handle_shll(DisasContext *s, bool is_q, int size, int rn, int rd)
{
    /* Implement SHLL and SHLL2 */
    int pass;
    int part = is_q ? 2 : 0;
    TCGv_i64 tcg_res[2];

    for (pass = 0; pass < 2; pass++) {
        static NeonGenWidenFn * const widenfns[3] = {
            gen_helper_neon_widen_u8,
            gen_helper_neon_widen_u16,
            tcg_gen_extu_i32_i64,
        };
        NeonGenWidenFn *widenfn = widenfns[size];
        TCGv_i32 tcg_op = tcg_temp_new_i32();

        read_vec_element_i32(s, tcg_op, rn, part + pass, MO_32);
        tcg_res[pass] = tcg_temp_new_i64();
        widenfn(tcg_res[pass], tcg_op);
        tcg_gen_shli_i64(tcg_res[pass], tcg_res[pass], 8 << size);
    }

    for (pass = 0; pass < 2; pass++) {
        write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
    }
}

/* AdvSIMD two reg misc
 *   31  30  29 28       24 23  22 21       17 16    12 11 10 9    5 4    0
 * +---+---+---+-----------+------+-----------+--------+-----+------+------+
 * | 0 | Q | U | 0 1 1 1 0 | size | 1 0 0 0 0 | opcode | 1 0 |  Rn  |  Rd  |
 * +---+---+---+-----------+------+-----------+--------+-----+------+------+
 */
static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
{
    int size = extract32(insn, 22, 2);
    int opcode = extract32(insn, 12, 5);
    bool u = extract32(insn, 29, 1);
    bool is_q = extract32(insn, 30, 1);
    int rn = extract32(insn, 5, 5);
    int rd = extract32(insn, 0, 5);
    bool need_fpstatus = false;
    int rmode = -1;
    TCGv_i32 tcg_rmode;
    TCGv_ptr tcg_fpstatus;

    switch (opcode) {
    case 0x0: /* REV64, REV32 */
    case 0x1: /* REV16 */
        handle_rev(s, opcode, u, is_q, size, rn, rd);
        return;
    case 0x5: /* CNT, NOT, RBIT */
        if (u && size == 0) {
            /* NOT */
            break;
        } else if (u && size == 1) {
            /* RBIT */
            break;
        } else if (!u && size == 0) {
            /* CNT */
            break;
        }
        unallocated_encoding(s);
        return;
    case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */
    case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */
        if (size == 3) {
            unallocated_encoding(s);
            return;
        }
        if (!fp_access_check(s)) {
            return;
        }

        handle_2misc_narrow(s, false, opcode, u, is_q, size, rn, rd);
        return;
    case 0x4: /* CLS, CLZ */
        if (size == 3) {
            unallocated_encoding(s);
            return;
        }
        break;
    case 0x2: /* SADDLP, UADDLP */
    case 0x6: /* SADALP, UADALP */
        if (size == 3) {
            unallocated_encoding(s);
            return;
        }
        if (!fp_access_check(s)) {
            return;
        }
        handle_2misc_pairwise(s, opcode, u, is_q, size, rn, rd);
        return;
    case 0x13: /* SHLL, SHLL2 */
        if (u == 0 || size == 3) {
            unallocated_encoding(s);
            return;
        }
        if (!fp_access_check(s)) {
            return;
        }
        handle_shll(s, is_q, size, rn, rd);
        return;
    case 0xa: /* CMLT */
        if (u == 1) {
            unallocated_encoding(s);
            return;
        }
        /* fall through */
    case 0x8: /* CMGT, CMGE */
    case 0x9: /* CMEQ, CMLE */
    case 0xb: /* ABS, NEG */
        if (size == 3 && !is_q) {
            unallocated_encoding(s);
            return;
        }
        break;
    case 0x3: /* SUQADD, USQADD */
        if (size == 3 && !is_q) {
            unallocated_encoding(s);
            return;
        }
        if (!fp_access_check(s)) {
            return;
        }
        handle_2misc_satacc(s, false, u, is_q, size, rn, rd);
        return;
    case 0x7: /* SQABS, SQNEG */
        if (size == 3 && !is_q) {
            unallocated_encoding(s);
            return;
        }
        break;
    case 0xc ... 0xf:
    case 0x16 ... 0x1f:
    {
        /* Floating point: U, size[1] and opcode indicate operation;
         * size[0] indicates single or double precision.
         */
        int is_double = extract32(size, 0, 1);
        opcode |= (extract32(size, 1, 1) << 5) | (u << 6);
        size = is_double ? 3 : 2;
        switch (opcode) {
        case 0x2f: /* FABS */
        case 0x6f: /* FNEG */
            if (size == 3 && !is_q) {
                unallocated_encoding(s);
                return;
            }
            break;
        case 0x1d: /* SCVTF */
        case 0x5d: /* UCVTF */
        {
            bool is_signed = (opcode == 0x1d) ? true : false;
            int elements = is_double ? 2 : is_q ? 4 : 2;
            if (is_double && !is_q) {
                unallocated_encoding(s);
                return;
            }
            if (!fp_access_check(s)) {
                return;
            }
            handle_simd_intfp_conv(s, rd, rn, elements, is_signed, 0, size);
            return;
        }
        case 0x2c: /* FCMGT (zero) */
        case 0x2d: /* FCMEQ (zero) */
        case 0x2e: /* FCMLT (zero) */
        case 0x6c: /* FCMGE (zero) */
        case 0x6d: /* FCMLE (zero) */
            if (size == 3 && !is_q) {
                unallocated_encoding(s);
                return;
            }
            handle_2misc_fcmp_zero(s, opcode, false, u, is_q, size, rn, rd);
            return;
        case 0x7f: /* FSQRT */
            if (size == 3 && !is_q) {
                unallocated_encoding(s);
                return;
            }
            break;
        case 0x1a: /* FCVTNS */
        case 0x1b: /* FCVTMS */
        case 0x3a: /* FCVTPS */
        case 0x3b: /* FCVTZS */
        case 0x5a: /* FCVTNU */
        case 0x5b: /* FCVTMU */
        case 0x7a: /* FCVTPU */
        case 0x7b: /* FCVTZU */
            need_fpstatus = true;
            rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1);
            if (size == 3 && !is_q) {
                unallocated_encoding(s);
                return;
            }
            break;
        case 0x5c: /* FCVTAU */
        case 0x1c: /* FCVTAS */
            need_fpstatus = true;
            rmode = FPROUNDING_TIEAWAY;
            if (size == 3 && !is_q) {
                unallocated_encoding(s);
                return;
            }
            break;
        case 0x3c: /* URECPE */
            if (size == 3) {
                unallocated_encoding(s);
                return;
            }
            /* fall through */
        case 0x3d: /* FRECPE */
        case 0x7d: /* FRSQRTE */
            if (size == 3 && !is_q) {
                unallocated_encoding(s);
                return;
            }
            if (!fp_access_check(s)) {
                return;
            }
            handle_2misc_reciprocal(s, opcode, false, u, is_q, size, rn, rd);
            return;
        case 0x56: /* FCVTXN, FCVTXN2 */
            if (size == 2) {
                unallocated_encoding(s);
                return;
            }
            /* fall through */
        case 0x16: /* FCVTN, FCVTN2 */
            /* handle_2misc_narrow does a 2*size -> size operation, but these
             * instructions encode the source size rather than dest size.
             */
            if (!fp_access_check(s)) {
                return;
            }
            handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd);
            return;
        case 0x36: /* BFCVTN, BFCVTN2 */
            if (!dc_isar_feature(aa64_bf16, s) || size != 2) {
                unallocated_encoding(s);
                return;
            }
            if (!fp_access_check(s)) {
                return;
            }
            handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd);
            return;
        case 0x17: /* FCVTL, FCVTL2 */
            if (!fp_access_check(s)) {
                return;
            }
            handle_2misc_widening(s, opcode, is_q, size, rn, rd);
            return;
        case 0x18: /* FRINTN */
        case 0x19: /* FRINTM */
        case 0x38: /* FRINTP */
        case 0x39: /* FRINTZ */
            rmode = extract32(opcode, 5, 1) | (extract32(opcode, 0, 1) << 1);
            /* fall through */
        case 0x59: /* FRINTX */
        case 0x79: /* FRINTI */
            need_fpstatus = true;
            if (size == 3 && !is_q) {
                unallocated_encoding(s);
                return;
            }
            break;
        case 0x58: /* FRINTA */
            rmode = FPROUNDING_TIEAWAY;
            need_fpstatus = true;
            if (size == 3 && !is_q) {
                unallocated_encoding(s);
                return;
            }
            break;
        case 0x7c: /* URSQRTE */
            if (size == 3) {
                unallocated_encoding(s);
                return;
            }
            break;
        case 0x1e: /* FRINT32Z */
        case 0x1f: /* FRINT64Z */
            rmode = FPROUNDING_ZERO;
            /* fall through */
        case 0x5e: /* FRINT32X */
        case 0x5f: /* FRINT64X */
            need_fpstatus = true;
            if ((size == 3 && !is_q) || !dc_isar_feature(aa64_frint, s)) {
                unallocated_encoding(s);
                return;
            }
            break;
        default:
            unallocated_encoding(s);
            return;
        }
        break;
    }
    default:
        unallocated_encoding(s);
        return;
    }

    if (!fp_access_check(s)) {
        return;
    }

    if (need_fpstatus || rmode >= 0) {
        tcg_fpstatus = fpstatus_ptr(FPST_FPCR);
    } else {
        tcg_fpstatus = NULL;
    }
    if (rmode >= 0) {
        tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus);
    } else {
        tcg_rmode = NULL;
    }

    switch (opcode) {
    case 0x5:
        if (u && size == 0) { /* NOT */
            gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_not, 0);
            return;
        }
        break;
    case 0x8: /* CMGT, CMGE */
        if (u) {
            gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cge0, size);
        } else {
            gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cgt0, size);
        }
        return;
    case 0x9: /* CMEQ, CMLE */
        if (u) {
            gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cle0, size);
        } else {
            gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_ceq0, size);
        }
        return;
    case 0xa: /* CMLT */
        gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clt0, size);
        return;
    case 0xb:
        if (u) { /* ABS, NEG */
            gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_neg, size);
        } else {
            gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_abs, size);
        }
        return;
    }

    if (size == 3) {
        /* All 64-bit element operations can be shared with scalar 2misc */
        int pass;

        /* Coverity claims (size == 3 && !is_q) has been eliminated
         * from all paths leading to here.
         */
        tcg_debug_assert(is_q);
        for (pass = 0; pass < 2; pass++) {
            TCGv_i64 tcg_op = tcg_temp_new_i64();
            TCGv_i64 tcg_res = tcg_temp_new_i64();

            read_vec_element(s, tcg_op, rn, pass, MO_64);

            handle_2misc_64(s, opcode, u, tcg_res, tcg_op,
                            tcg_rmode, tcg_fpstatus);

            write_vec_element(s, tcg_res, rd, pass, MO_64);
        }
    } else {
        int pass;

        for (pass = 0; pass < (is_q ? 4 : 2); pass++) {
            TCGv_i32 tcg_op = tcg_temp_new_i32();
            TCGv_i32 tcg_res = tcg_temp_new_i32();

            read_vec_element_i32(s, tcg_op, rn, pass, MO_32);

            if (size == 2) {
                /* Special cases for 32 bit elements */
                switch (opcode) {
                case 0x4: /* CLS */
                    if (u) {
                        tcg_gen_clzi_i32(tcg_res, tcg_op, 32);
                    } else {
                        tcg_gen_clrsb_i32(tcg_res, tcg_op);
                    }
                    break;
                case 0x7: /* SQABS, SQNEG */
                    if (u) {
                        gen_helper_neon_qneg_s32(tcg_res, tcg_env, tcg_op);
                    } else {
                        gen_helper_neon_qabs_s32(tcg_res, tcg_env, tcg_op);
                    }
                    break;
                case 0x2f: /* FABS */
                    gen_vfp_abss(tcg_res, tcg_op);
                    break;
                case 0x6f: /* FNEG */
                    gen_vfp_negs(tcg_res, tcg_op);
                    break;
                case 0x7f: /* FSQRT */
                    gen_helper_vfp_sqrts(tcg_res, tcg_op, tcg_env);
                    break;
                case 0x1a: /* FCVTNS */
                case 0x1b: /* FCVTMS */
                case 0x1c: /* FCVTAS */
                case 0x3a: /* FCVTPS */
                case 0x3b: /* FCVTZS */
                    gen_helper_vfp_tosls(tcg_res, tcg_op,
                                         tcg_constant_i32(0), tcg_fpstatus);
                    break;
                case 0x5a: /* FCVTNU */
                case 0x5b: /* FCVTMU */
                case 0x5c: /* FCVTAU */
                case 0x7a: /* FCVTPU */
                case 0x7b: /* FCVTZU */
                    gen_helper_vfp_touls(tcg_res, tcg_op,
                                         tcg_constant_i32(0), tcg_fpstatus);
                    break;
                case 0x18: /* FRINTN */
                case 0x19: /* FRINTM */
                case 0x38: /* FRINTP */
                case 0x39: /* FRINTZ */
                case 0x58: /* FRINTA */
                case 0x79: /* FRINTI */
                    gen_helper_rints(tcg_res, tcg_op, tcg_fpstatus);
                    break;
                case 0x59: /* FRINTX */
                    gen_helper_rints_exact(tcg_res, tcg_op, tcg_fpstatus);
                    break;
                case 0x7c: /* URSQRTE */
                    gen_helper_rsqrte_u32(tcg_res, tcg_op);
                    break;
                case 0x1e: /* FRINT32Z */
                case 0x5e: /* FRINT32X */
                    gen_helper_frint32_s(tcg_res, tcg_op, tcg_fpstatus);
                    break;
                case 0x1f: /* FRINT64Z */
                case 0x5f: /* FRINT64X */
                    gen_helper_frint64_s(tcg_res, tcg_op, tcg_fpstatus);
                    break;
                default:
                    g_assert_not_reached();
                }
            } else {
                /* Use helpers for 8 and 16 bit elements */
                switch (opcode) {
                case 0x5: /* CNT, RBIT */
                    /* For these two insns size is part of the opcode specifier
                     * (handled earlier); they always operate on byte elements.
                     */
                    if (u) {
                        gen_helper_neon_rbit_u8(tcg_res, tcg_op);
                    } else {
                        gen_helper_neon_cnt_u8(tcg_res, tcg_op);
                    }
                    break;
                case 0x7: /* SQABS, SQNEG */
                {
                    NeonGenOneOpEnvFn *genfn;
                    static NeonGenOneOpEnvFn * const fns[2][2] = {
                        { gen_helper_neon_qabs_s8, gen_helper_neon_qneg_s8 },
                        { gen_helper_neon_qabs_s16, gen_helper_neon_qneg_s16 },
                    };
                    genfn = fns[size][u];
                    genfn(tcg_res, tcg_env, tcg_op);
                    break;
                }
                case 0x4: /* CLS, CLZ */
                    if (u) {
                        if (size == 0) {
                            gen_helper_neon_clz_u8(tcg_res, tcg_op);
                        } else {
                            gen_helper_neon_clz_u16(tcg_res, tcg_op);
                        }
                    } else {
                        if (size == 0) {
                            gen_helper_neon_cls_s8(tcg_res, tcg_op);
                        } else {
                            gen_helper_neon_cls_s16(tcg_res, tcg_op);
                        }
                    }
                    break;
                default:
                    g_assert_not_reached();
                }
            }

            write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
        }
    }
    clear_vec_high(s, is_q, rd);

    if (tcg_rmode) {
        gen_restore_rmode(tcg_rmode, tcg_fpstatus);
    }
}

/* AdvSIMD [scalar] two register miscellaneous (FP16)
 *
 *   31  30  29 28  27     24  23 22 21       17 16    12 11 10 9    5 4    0
 * +---+---+---+---+---------+---+-------------+--------+-----+------+------+
 * | 0 | Q | U | S | 1 1 1 0 | a | 1 1 1 1 0 0 | opcode | 1 0 |  Rn  |  Rd  |
 * +---+---+---+---+---------+---+-------------+--------+-----+------+------+
 *   mask: 1000 1111 0111 1110 0000 1100 0000 0000 0x8f7e 0c00
 *   val:  0000 1110 0111 1000 0000 1000 0000 0000 0x0e78 0800
 *
 * This actually covers two groups where scalar access is governed by
 * bit 28. A bunch of the instructions (float to integral) only exist
 * in the vector form and are un-allocated for the scalar decode. Also
 * in the scalar decode Q is always 1.
 */
static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
{
    int fpop, opcode, a, u;
    int rn, rd;
    bool is_q;
    bool is_scalar;
    bool only_in_vector = false;

    int pass;
    TCGv_i32 tcg_rmode = NULL;
    TCGv_ptr tcg_fpstatus = NULL;
    bool need_fpst = true;
    int rmode = -1;

    if (!dc_isar_feature(aa64_fp16, s)) {
        unallocated_encoding(s);
        return;
    }

    rd = extract32(insn, 0, 5);
    rn = extract32(insn, 5, 5);

    a = extract32(insn, 23, 1);
    u = extract32(insn, 29, 1);
    is_scalar = extract32(insn, 28, 1);
    is_q = extract32(insn, 30, 1);

    opcode = extract32(insn, 12, 5);
    fpop = deposit32(opcode, 5, 1, a);
    fpop = deposit32(fpop, 6, 1, u);

    switch (fpop) {
    case 0x1d: /* SCVTF */
    case 0x5d: /* UCVTF */
    {
        int elements;

        if (is_scalar) {
            elements = 1;
        } else {
            elements = (is_q ? 8 : 4);
        }

        if (!fp_access_check(s)) {
            return;
        }
        handle_simd_intfp_conv(s, rd, rn, elements, !u, 0, MO_16);
        return;
    }
    break;
    case 0x2c: /* FCMGT (zero) */
    case 0x2d: /* FCMEQ (zero) */
    case 0x2e: /* FCMLT (zero) */
    case 0x6c: /* FCMGE (zero) */
    case 0x6d: /* FCMLE (zero) */
        handle_2misc_fcmp_zero(s, fpop, is_scalar, 0, is_q, MO_16, rn, rd);
        return;
    case 0x3d: /* FRECPE */
    case 0x3f: /* FRECPX */
        break;
    case 0x18: /* FRINTN */
        only_in_vector = true;
        rmode = FPROUNDING_TIEEVEN;
        break;
    case 0x19: /* FRINTM */
        only_in_vector = true;
        rmode = FPROUNDING_NEGINF;
        break;
    case 0x38: /* FRINTP */
        only_in_vector = true;
        rmode = FPROUNDING_POSINF;
        break;
    case 0x39: /* FRINTZ */
        only_in_vector = true;
        rmode = FPROUNDING_ZERO;
        break;
    case 0x58: /* FRINTA */
        only_in_vector = true;
        rmode = FPROUNDING_TIEAWAY;
        break;
    case 0x59: /* FRINTX */
    case 0x79: /* FRINTI */
        only_in_vector = true;
        /* current rounding mode */
        break;
    case 0x1a: /* FCVTNS */
        rmode = FPROUNDING_TIEEVEN;
        break;
    case 0x1b: /* FCVTMS */
        rmode = FPROUNDING_NEGINF;
        break;
    case 0x1c: /* FCVTAS */
        rmode = FPROUNDING_TIEAWAY;
        break;
    case 0x3a: /* FCVTPS */
        rmode = FPROUNDING_POSINF;
        break;
    case 0x3b: /* FCVTZS */
        rmode = FPROUNDING_ZERO;
        break;
    case 0x5a: /* FCVTNU */
        rmode = FPROUNDING_TIEEVEN;
        break;
    case 0x5b: /* FCVTMU */
        rmode = FPROUNDING_NEGINF;
        break;
    case 0x5c: /* FCVTAU */
        rmode = FPROUNDING_TIEAWAY;
        break;
    case 0x7a: /* FCVTPU */
        rmode = FPROUNDING_POSINF;
        break;
    case 0x7b: /* FCVTZU */
        rmode = FPROUNDING_ZERO;
        break;
    case 0x2f: /* FABS */
    case 0x6f: /* FNEG */
        need_fpst = false;
        break;
    case 0x7d: /* FRSQRTE */
    case 0x7f: /* FSQRT (vector) */
        break;
    default:
        unallocated_encoding(s);
        return;
    }


    /* Check additional constraints for the scalar encoding */
    if (is_scalar) {
        if (!is_q) {
            unallocated_encoding(s);
            return;
        }
        /* FRINTxx is only in the vector form */
        if (only_in_vector) {
            unallocated_encoding(s);
            return;
        }
    }

    if (!fp_access_check(s)) {
        return;
    }

    if (rmode >= 0 || need_fpst) {
        tcg_fpstatus = fpstatus_ptr(FPST_FPCR_F16);
    }

    if (rmode >= 0) {
        tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus);
    }

    if (is_scalar) {
        TCGv_i32 tcg_op = read_fp_hreg(s, rn);
        TCGv_i32 tcg_res = tcg_temp_new_i32();

        switch (fpop) {
        case 0x1a: /* FCVTNS */
        case 0x1b: /* FCVTMS */
        case 0x1c: /* FCVTAS */
        case 0x3a: /* FCVTPS */
        case 0x3b: /* FCVTZS */
            gen_helper_advsimd_f16tosinth(tcg_res, tcg_op, tcg_fpstatus);
            break;
        case 0x3d: /* FRECPE */
            gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus);
            break;
        case 0x3f: /* FRECPX */
            gen_helper_frecpx_f16(tcg_res, tcg_op, tcg_fpstatus);
            break;
        case 0x5a: /* FCVTNU */
        case 0x5b: /* FCVTMU */
        case 0x5c: /* FCVTAU */
        case 0x7a: /* FCVTPU */
        case 0x7b: /* FCVTZU */
            gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus);
            break;
        case 0x6f: /* FNEG */
            tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
            break;
        case 0x7d: /* FRSQRTE */
            gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus);
            break;
        default:
            g_assert_not_reached();
        }

        /* limit any sign extension going on */
        tcg_gen_andi_i32(tcg_res, tcg_res, 0xffff);
        write_fp_sreg(s, rd, tcg_res);
    } else {
        for (pass = 0; pass < (is_q ? 8 : 4); pass++) {
            TCGv_i32 tcg_op = tcg_temp_new_i32();
            TCGv_i32 tcg_res = tcg_temp_new_i32();

            read_vec_element_i32(s, tcg_op, rn, pass, MO_16);

            switch (fpop) {
            case 0x1a: /* FCVTNS */
            case 0x1b: /* FCVTMS */
            case 0x1c: /* FCVTAS */
            case 0x3a: /* FCVTPS */
            case 0x3b: /* FCVTZS */
                gen_helper_advsimd_f16tosinth(tcg_res, tcg_op, tcg_fpstatus);
                break;
            case 0x3d: /* FRECPE */
                gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus);
                break;
            case 0x5a: /* FCVTNU */
            case 0x5b: /* FCVTMU */
            case 0x5c: /* FCVTAU */
            case 0x7a: /* FCVTPU */
            case 0x7b: /* FCVTZU */
                gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus);
                break;
            case 0x18: /* FRINTN */
            case 0x19: /* FRINTM */
            case 0x38: /* FRINTP */
            case 0x39: /* FRINTZ */
            case 0x58: /* FRINTA */
            case 0x79: /* FRINTI */
                gen_helper_advsimd_rinth(tcg_res, tcg_op, tcg_fpstatus);
                break;
            case 0x59: /* FRINTX */
                gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, tcg_fpstatus);
                break;
            case 0x2f: /* FABS */
                tcg_gen_andi_i32(tcg_res, tcg_op, 0x7fff);
                break;
            case 0x6f: /* FNEG */
                tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
                break;
            case 0x7d: /* FRSQRTE */
                gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus);
                break;
            case 0x7f: /* FSQRT */
                gen_helper_sqrt_f16(tcg_res, tcg_op, tcg_fpstatus);
                break;
            default:
                g_assert_not_reached();
            }

            write_vec_element_i32(s, tcg_res, rd, pass, MO_16);
        }

        clear_vec_high(s, is_q, rd);
    }

    if (tcg_rmode) {
        gen_restore_rmode(tcg_rmode, tcg_fpstatus);
    }
}

/* AdvSIMD scalar x indexed element
 *  31 30  29 28       24 23  22 21  20  19  16 15 12  11  10 9    5 4    0
 * +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
 * | 0 1 | U | 1 1 1 1 1 | size | L | M |  Rm  | opc | H | 0 |  Rn  |  Rd  |
 * +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
 * AdvSIMD vector x indexed element
 *   31  30  29 28       24 23  22 21  20  19  16 15 12  11  10 9    5 4    0
 * +---+---+---+-----------+------+---+---+------+-----+---+---+------+------+
 * | 0 | Q | U | 0 1 1 1 1 | size | L | M |  Rm  | opc | H | 0 |  Rn  |  Rd  |
 * +---+---+---+-----------+------+---+---+------+-----+---+---+------+------+
 */
static void disas_simd_indexed(DisasContext *s, uint32_t insn)
{
    /* This encoding has two kinds of instruction:
     *  normal, where we perform elt x idxelt => elt for each
     *     element in the vector
     *  long, where we perform elt x idxelt and generate a result of
     *     double the width of the input element
     * The long ops have a 'part' specifier (ie come in INSN, INSN2 pairs).
     */
    bool is_scalar = extract32(insn, 28, 1);
    bool is_q = extract32(insn, 30, 1);
    bool u = extract32(insn, 29, 1);
    int size = extract32(insn, 22, 2);
    int l = extract32(insn, 21, 1);
    int m = extract32(insn, 20, 1);
    /* Note that the Rm field here is only 4 bits, not 5 as it usually is */
    int rm = extract32(insn, 16, 4);
    int opcode = extract32(insn, 12, 4);
    int h = extract32(insn, 11, 1);
    int rn = extract32(insn, 5, 5);
    int rd = extract32(insn, 0, 5);
    bool is_long = false;
    int is_fp = 0;
    bool is_fp16 = false;
    int index;
    TCGv_ptr fpst;

    switch (16 * u + opcode) {
    case 0x08: /* MUL */
    case 0x10: /* MLA */
    case 0x14: /* MLS */
        if (is_scalar) {
            unallocated_encoding(s);
            return;
        }
        break;
    case 0x02: /* SMLAL, SMLAL2 */
    case 0x12: /* UMLAL, UMLAL2 */
    case 0x06: /* SMLSL, SMLSL2 */
    case 0x16: /* UMLSL, UMLSL2 */
    case 0x0a: /* SMULL, SMULL2 */
    case 0x1a: /* UMULL, UMULL2 */
        if (is_scalar) {
            unallocated_encoding(s);
            return;
        }
        is_long = true;
        break;
    case 0x03: /* SQDMLAL, SQDMLAL2 */
    case 0x07: /* SQDMLSL, SQDMLSL2 */
    case 0x0b: /* SQDMULL, SQDMULL2 */
        is_long = true;
        break;
    case 0x0c: /* SQDMULH */
    case 0x0d: /* SQRDMULH */
        break;
    case 0x1d: /* SQRDMLAH */
    case 0x1f: /* SQRDMLSH */
        if (!dc_isar_feature(aa64_rdm, s)) {
            unallocated_encoding(s);
            return;
        }
        break;
    case 0x0e: /* SDOT */
    case 0x1e: /* UDOT */
        if (is_scalar || size != MO_32 || !dc_isar_feature(aa64_dp, s)) {
            unallocated_encoding(s);
            return;
        }
        break;
    case 0x0f:
        switch (size) {
        case 0: /* SUDOT */
        case 2: /* USDOT */
            if (is_scalar || !dc_isar_feature(aa64_i8mm, s)) {
                unallocated_encoding(s);
                return;
            }
            size = MO_32;
            break;
        case 1: /* BFDOT */
            if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
                unallocated_encoding(s);
                return;
            }
            size = MO_32;
            break;
        case 3: /* BFMLAL{B,T} */
            if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
                unallocated_encoding(s);
                return;
            }
            /* can't set is_fp without other incorrect size checks */
            size = MO_16;
            break;
        default:
            unallocated_encoding(s);
            return;
        }
        break;
    case 0x11: /* FCMLA #0 */
    case 0x13: /* FCMLA #90 */
    case 0x15: /* FCMLA #180 */
    case 0x17: /* FCMLA #270 */
        if (is_scalar || !dc_isar_feature(aa64_fcma, s)) {
            unallocated_encoding(s);
            return;
        }
        is_fp = 2;
        break;
    case 0x00: /* FMLAL */
    case 0x04: /* FMLSL */
    case 0x18: /* FMLAL2 */
    case 0x1c: /* FMLSL2 */
        if (is_scalar || size != MO_32 || !dc_isar_feature(aa64_fhm, s)) {
            unallocated_encoding(s);
            return;
        }
        size = MO_16;
        /* is_fp, but we pass tcg_env not fp_status.  */
        break;
    default:
    case 0x01: /* FMLA */
    case 0x05: /* FMLS */
    case 0x09: /* FMUL */
    case 0x19: /* FMULX */
        unallocated_encoding(s);
        return;
    }

    switch (is_fp) {
    case 1: /* normal fp */
        unallocated_encoding(s); /* in decodetree */
        return;

    case 2: /* complex fp */
        /* Each indexable element is a complex pair.  */
        size += 1;
        switch (size) {
        case MO_32:
            if (h && !is_q) {
                unallocated_encoding(s);
                return;
            }
            is_fp16 = true;
            break;
        case MO_64:
            break;
        default:
            unallocated_encoding(s);
            return;
        }
        break;

    default: /* integer */
        switch (size) {
        case MO_8:
        case MO_64:
            unallocated_encoding(s);
            return;
        }
        break;
    }
    if (is_fp16 && !dc_isar_feature(aa64_fp16, s)) {
        unallocated_encoding(s);
        return;
    }

    /* Given MemOp size, adjust register and indexing.  */
    switch (size) {
    case MO_16:
        index = h << 2 | l << 1 | m;
        break;
    case MO_32:
        index = h << 1 | l;
        rm |= m << 4;
        break;
    case MO_64:
        if (l || !is_q) {
            unallocated_encoding(s);
            return;
        }
        index = h;
        rm |= m << 4;
        break;
    default:
        g_assert_not_reached();
    }

    if (!fp_access_check(s)) {
        return;
    }

    if (is_fp) {
        fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR);
    } else {
        fpst = NULL;
    }

    switch (16 * u + opcode) {
    case 0x0e: /* SDOT */
    case 0x1e: /* UDOT */
        gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
                         u ? gen_helper_gvec_udot_idx_b
                         : gen_helper_gvec_sdot_idx_b);
        return;
    case 0x0f:
        switch (extract32(insn, 22, 2)) {
        case 0: /* SUDOT */
            gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
                             gen_helper_gvec_sudot_idx_b);
            return;
        case 1: /* BFDOT */
            gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
                             gen_helper_gvec_bfdot_idx);
            return;
        case 2: /* USDOT */
            gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
                             gen_helper_gvec_usdot_idx_b);
            return;
        case 3: /* BFMLAL{B,T} */
            gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, 0, (index << 1) | is_q,
                              gen_helper_gvec_bfmlal_idx);
            return;
        }
        g_assert_not_reached();
    case 0x11: /* FCMLA #0 */
    case 0x13: /* FCMLA #90 */
    case 0x15: /* FCMLA #180 */
    case 0x17: /* FCMLA #270 */
        {
            int rot = extract32(insn, 13, 2);
            int data = (index << 2) | rot;
            tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd),
                               vec_full_reg_offset(s, rn),
                               vec_full_reg_offset(s, rm),
                               vec_full_reg_offset(s, rd), fpst,
                               is_q ? 16 : 8, vec_full_reg_size(s), data,
                               size == MO_64
                               ? gen_helper_gvec_fcmlas_idx
                               : gen_helper_gvec_fcmlah_idx);
        }
        return;

    case 0x00: /* FMLAL */
    case 0x04: /* FMLSL */
    case 0x18: /* FMLAL2 */
    case 0x1c: /* FMLSL2 */
        {
            int is_s = extract32(opcode, 2, 1);
            int is_2 = u;
            int data = (index << 2) | (is_2 << 1) | is_s;
            tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
                               vec_full_reg_offset(s, rn),
                               vec_full_reg_offset(s, rm), tcg_env,
                               is_q ? 16 : 8, vec_full_reg_size(s),
                               data, gen_helper_gvec_fmlal_idx_a64);
        }
        return;

    case 0x08: /* MUL */
        if (!is_long && !is_scalar) {
            static gen_helper_gvec_3 * const fns[3] = {
                gen_helper_gvec_mul_idx_h,
                gen_helper_gvec_mul_idx_s,
                gen_helper_gvec_mul_idx_d,
            };
            tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
                               vec_full_reg_offset(s, rn),
                               vec_full_reg_offset(s, rm),
                               is_q ? 16 : 8, vec_full_reg_size(s),
                               index, fns[size - 1]);
            return;
        }
        break;

    case 0x10: /* MLA */
        if (!is_long && !is_scalar) {
            static gen_helper_gvec_4 * const fns[3] = {
                gen_helper_gvec_mla_idx_h,
                gen_helper_gvec_mla_idx_s,
                gen_helper_gvec_mla_idx_d,
            };
            tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
                               vec_full_reg_offset(s, rn),
                               vec_full_reg_offset(s, rm),
                               vec_full_reg_offset(s, rd),
                               is_q ? 16 : 8, vec_full_reg_size(s),
                               index, fns[size - 1]);
            return;
        }
        break;

    case 0x14: /* MLS */
        if (!is_long && !is_scalar) {
            static gen_helper_gvec_4 * const fns[3] = {
                gen_helper_gvec_mls_idx_h,
                gen_helper_gvec_mls_idx_s,
                gen_helper_gvec_mls_idx_d,
            };
            tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
                               vec_full_reg_offset(s, rn),
                               vec_full_reg_offset(s, rm),
                               vec_full_reg_offset(s, rd),
                               is_q ? 16 : 8, vec_full_reg_size(s),
                               index, fns[size - 1]);
            return;
        }
        break;
    }

    if (size == 3) {
        g_assert_not_reached();
    } else if (!is_long) {
        /* 32 bit floating point, or 16 or 32 bit integer.
         * For the 16 bit scalar case we use the usual Neon helpers and
         * rely on the fact that 0 op 0 == 0 with no side effects.
         */
        TCGv_i32 tcg_idx = tcg_temp_new_i32();
        int pass, maxpasses;

        if (is_scalar) {
            maxpasses = 1;
        } else {
            maxpasses = is_q ? 4 : 2;
        }

        read_vec_element_i32(s, tcg_idx, rm, index, size);

        if (size == 1 && !is_scalar) {
            /* The simplest way to handle the 16x16 indexed ops is to duplicate
             * the index into both halves of the 32 bit tcg_idx and then use
             * the usual Neon helpers.
             */
            tcg_gen_deposit_i32(tcg_idx, tcg_idx, tcg_idx, 16, 16);
        }

        for (pass = 0; pass < maxpasses; pass++) {
            TCGv_i32 tcg_op = tcg_temp_new_i32();
            TCGv_i32 tcg_res = tcg_temp_new_i32();

            read_vec_element_i32(s, tcg_op, rn, pass, is_scalar ? size : MO_32);

            switch (16 * u + opcode) {
            case 0x08: /* MUL */
            case 0x10: /* MLA */
            case 0x14: /* MLS */
            {
                static NeonGenTwoOpFn * const fns[2][2] = {
                    { gen_helper_neon_add_u16, gen_helper_neon_sub_u16 },
                    { tcg_gen_add_i32, tcg_gen_sub_i32 },
                };
                NeonGenTwoOpFn *genfn;
                bool is_sub = opcode == 0x4;

                if (size == 1) {
                    gen_helper_neon_mul_u16(tcg_res, tcg_op, tcg_idx);
                } else {
                    tcg_gen_mul_i32(tcg_res, tcg_op, tcg_idx);
                }
                if (opcode == 0x8) {
                    break;
                }
                read_vec_element_i32(s, tcg_op, rd, pass, MO_32);
                genfn = fns[size - 1][is_sub];
                genfn(tcg_res, tcg_op, tcg_res);
                break;
            }
            case 0x0c: /* SQDMULH */
                if (size == 1) {
                    gen_helper_neon_qdmulh_s16(tcg_res, tcg_env,
                                               tcg_op, tcg_idx);
                } else {
                    gen_helper_neon_qdmulh_s32(tcg_res, tcg_env,
                                               tcg_op, tcg_idx);
                }
                break;
            case 0x0d: /* SQRDMULH */
                if (size == 1) {
                    gen_helper_neon_qrdmulh_s16(tcg_res, tcg_env,
                                                tcg_op, tcg_idx);
                } else {
                    gen_helper_neon_qrdmulh_s32(tcg_res, tcg_env,
                                                tcg_op, tcg_idx);
                }
                break;
            case 0x1d: /* SQRDMLAH */
                read_vec_element_i32(s, tcg_res, rd, pass,
                                     is_scalar ? size : MO_32);
                if (size == 1) {
                    gen_helper_neon_qrdmlah_s16(tcg_res, tcg_env,
                                                tcg_op, tcg_idx, tcg_res);
                } else {
                    gen_helper_neon_qrdmlah_s32(tcg_res, tcg_env,
                                                tcg_op, tcg_idx, tcg_res);
                }
                break;
            case 0x1f: /* SQRDMLSH */
                read_vec_element_i32(s, tcg_res, rd, pass,
                                     is_scalar ? size : MO_32);
                if (size == 1) {
                    gen_helper_neon_qrdmlsh_s16(tcg_res, tcg_env,
                                                tcg_op, tcg_idx, tcg_res);
                } else {
                    gen_helper_neon_qrdmlsh_s32(tcg_res, tcg_env,
                                                tcg_op, tcg_idx, tcg_res);
                }
                break;
            default:
            case 0x01: /* FMLA */
            case 0x05: /* FMLS */
            case 0x09: /* FMUL */
            case 0x19: /* FMULX */
                g_assert_not_reached();
            }

            if (is_scalar) {
                write_fp_sreg(s, rd, tcg_res);
            } else {
                write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
            }
        }

        clear_vec_high(s, is_q, rd);
    } else {
        /* long ops: 16x16->32 or 32x32->64 */
        TCGv_i64 tcg_res[2];
        int pass;
        bool satop = extract32(opcode, 0, 1);
        MemOp memop = MO_32;

        if (satop || !u) {
            memop |= MO_SIGN;
        }

        if (size == 2) {
            TCGv_i64 tcg_idx = tcg_temp_new_i64();

            read_vec_element(s, tcg_idx, rm, index, memop);

            for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
                TCGv_i64 tcg_op = tcg_temp_new_i64();
                TCGv_i64 tcg_passres;
                int passelt;

                if (is_scalar) {
                    passelt = 0;
                } else {
                    passelt = pass + (is_q * 2);
                }

                read_vec_element(s, tcg_op, rn, passelt, memop);

                tcg_res[pass] = tcg_temp_new_i64();

                if (opcode == 0xa || opcode == 0xb) {
                    /* Non-accumulating ops */
                    tcg_passres = tcg_res[pass];
                } else {
                    tcg_passres = tcg_temp_new_i64();
                }

                tcg_gen_mul_i64(tcg_passres, tcg_op, tcg_idx);

                if (satop) {
                    /* saturating, doubling */
                    gen_helper_neon_addl_saturate_s64(tcg_passres, tcg_env,
                                                      tcg_passres, tcg_passres);
                }

                if (opcode == 0xa || opcode == 0xb) {
                    continue;
                }

                /* Accumulating op: handle accumulate step */
                read_vec_element(s, tcg_res[pass], rd, pass, MO_64);

                switch (opcode) {
                case 0x2: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
                    tcg_gen_add_i64(tcg_res[pass], tcg_res[pass], tcg_passres);
                    break;
                case 0x6: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
                    tcg_gen_sub_i64(tcg_res[pass], tcg_res[pass], tcg_passres);
                    break;
                case 0x7: /* SQDMLSL, SQDMLSL2 */
                    tcg_gen_neg_i64(tcg_passres, tcg_passres);
                    /* fall through */
                case 0x3: /* SQDMLAL, SQDMLAL2 */
                    gen_helper_neon_addl_saturate_s64(tcg_res[pass], tcg_env,
                                                      tcg_res[pass],
                                                      tcg_passres);
                    break;
                default:
                    g_assert_not_reached();
                }
            }

            clear_vec_high(s, !is_scalar, rd);
        } else {
            TCGv_i32 tcg_idx = tcg_temp_new_i32();

            assert(size == 1);
            read_vec_element_i32(s, tcg_idx, rm, index, size);

            if (!is_scalar) {
                /* The simplest way to handle the 16x16 indexed ops is to
                 * duplicate the index into both halves of the 32 bit tcg_idx
                 * and then use the usual Neon helpers.
                 */
                tcg_gen_deposit_i32(tcg_idx, tcg_idx, tcg_idx, 16, 16);
            }

            for (pass = 0; pass < (is_scalar ? 1 : 2); pass++) {
                TCGv_i32 tcg_op = tcg_temp_new_i32();
                TCGv_i64 tcg_passres;

                if (is_scalar) {
                    read_vec_element_i32(s, tcg_op, rn, pass, size);
                } else {
                    read_vec_element_i32(s, tcg_op, rn,
                                         pass + (is_q * 2), MO_32);
                }

                tcg_res[pass] = tcg_temp_new_i64();

                if (opcode == 0xa || opcode == 0xb) {
                    /* Non-accumulating ops */
                    tcg_passres = tcg_res[pass];
                } else {
                    tcg_passres = tcg_temp_new_i64();
                }

                if (memop & MO_SIGN) {
                    gen_helper_neon_mull_s16(tcg_passres, tcg_op, tcg_idx);
                } else {
                    gen_helper_neon_mull_u16(tcg_passres, tcg_op, tcg_idx);
                }
                if (satop) {
                    gen_helper_neon_addl_saturate_s32(tcg_passres, tcg_env,
                                                      tcg_passres, tcg_passres);
                }

                if (opcode == 0xa || opcode == 0xb) {
                    continue;
                }

                /* Accumulating op: handle accumulate step */
                read_vec_element(s, tcg_res[pass], rd, pass, MO_64);

                switch (opcode) {
                case 0x2: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */
                    gen_helper_neon_addl_u32(tcg_res[pass], tcg_res[pass],
                                             tcg_passres);
                    break;
                case 0x6: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */
                    gen_helper_neon_subl_u32(tcg_res[pass], tcg_res[pass],
                                             tcg_passres);
                    break;
                case 0x7: /* SQDMLSL, SQDMLSL2 */
                    gen_helper_neon_negl_u32(tcg_passres, tcg_passres);
                    /* fall through */
                case 0x3: /* SQDMLAL, SQDMLAL2 */
                    gen_helper_neon_addl_saturate_s32(tcg_res[pass], tcg_env,
                                                      tcg_res[pass],
                                                      tcg_passres);
                    break;
                default:
                    g_assert_not_reached();
                }
            }

            if (is_scalar) {
                tcg_gen_ext32u_i64(tcg_res[0], tcg_res[0]);
            }
        }

        if (is_scalar) {
            tcg_res[1] = tcg_constant_i64(0);
        }

        for (pass = 0; pass < 2; pass++) {
            write_vec_element(s, tcg_res[pass], rd, pass, MO_64);
        }
    }
}

/* C3.6 Data processing - SIMD, inc Crypto
 *
 * As the decode gets a little complex we are using a table based
 * approach for this part of the decode.
 */
static const AArch64DecodeTable data_proc_simd[] = {
    /* pattern  ,  mask     ,  fn                        */
    { 0x0e200400, 0x9f200400, disas_simd_three_reg_same },
    { 0x0e008400, 0x9f208400, disas_simd_three_reg_same_extra },
    { 0x0e200000, 0x9f200c00, disas_simd_three_reg_diff },
    { 0x0e200800, 0x9f3e0c00, disas_simd_two_reg_misc },
    { 0x0e300800, 0x9f3e0c00, disas_simd_across_lanes },
    { 0x0f000000, 0x9f000400, disas_simd_indexed }, /* vector indexed */
    /* simd_mod_imm decode is a subset of simd_shift_imm, so must precede it */
    { 0x0f000400, 0x9ff80400, disas_simd_mod_imm },
    { 0x0f000400, 0x9f800400, disas_simd_shift_imm },
    { 0x0e000000, 0xbf208c00, disas_simd_tb },
    { 0x0e000800, 0xbf208c00, disas_simd_zip_trn },
    { 0x2e000000, 0xbf208400, disas_simd_ext },
    { 0x5e200400, 0xdf200400, disas_simd_scalar_three_reg_same },
    { 0x5e008400, 0xdf208400, disas_simd_scalar_three_reg_same_extra },
    { 0x5e200000, 0xdf200c00, disas_simd_scalar_three_reg_diff },
    { 0x5e200800, 0xdf3e0c00, disas_simd_scalar_two_reg_misc },
    { 0x5e300800, 0xdf3e0c00, disas_simd_scalar_pairwise },
    { 0x5f000000, 0xdf000400, disas_simd_indexed }, /* scalar indexed */
    { 0x5f000400, 0xdf800400, disas_simd_scalar_shift_imm },
    { 0x0e400400, 0x9f60c400, disas_simd_three_reg_same_fp16 },
    { 0x0e780800, 0x8f7e0c00, disas_simd_two_reg_misc_fp16 },
    { 0x5e400400, 0xdf60c400, disas_simd_scalar_three_reg_same_fp16 },
    { 0x00000000, 0x00000000, NULL }
};

static void disas_data_proc_simd(DisasContext *s, uint32_t insn)
{
    /* Note that this is called with all non-FP cases from
     * table C3-6 so it must UNDEF for entries not specifically
     * allocated to instructions in that table.
     */
    AArch64DecodeFn *fn = lookup_disas_fn(&data_proc_simd[0], insn);
    if (fn) {
        fn(s, insn);
    } else {
        unallocated_encoding(s);
    }
}

/* C3.6 Data processing - SIMD and floating point */
static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
{
    if (extract32(insn, 28, 1) == 1 && extract32(insn, 30, 1) == 0) {
        disas_data_proc_fp(s, insn);
    } else {
        /* SIMD, including crypto */
        disas_data_proc_simd(s, insn);
    }
}

static bool trans_OK(DisasContext *s, arg_OK *a)
{
    return true;
}

static bool trans_FAIL(DisasContext *s, arg_OK *a)
{
    s->is_nonstreaming = true;
    return true;
}

/**
 * is_guarded_page:
 * @env: The cpu environment
 * @s: The DisasContext
 *
 * Return true if the page is guarded.
 */
static bool is_guarded_page(CPUARMState *env, DisasContext *s)
{
    uint64_t addr = s->base.pc_first;
#ifdef CONFIG_USER_ONLY
    return page_get_flags(addr) & PAGE_BTI;
#else
    CPUTLBEntryFull *full;
    void *host;
    int mmu_idx = arm_to_core_mmu_idx(s->mmu_idx);
    int flags;

    /*
     * We test this immediately after reading an insn, which means
     * that the TLB entry must be present and valid, and thus this
     * access will never raise an exception.
     */
    flags = probe_access_full(env, addr, 0, MMU_INST_FETCH, mmu_idx,
                              false, &host, &full, 0);
    assert(!(flags & TLB_INVALID_MASK));

    return full->extra.arm.guarded;
#endif
}

/**
 * btype_destination_ok:
 * @insn: The instruction at the branch destination
 * @bt: SCTLR_ELx.BT
 * @btype: PSTATE.BTYPE, and is non-zero
 *
 * On a guarded page, there are a limited number of insns
 * that may be present at the branch target:
 *   - branch target identifiers,
 *   - paciasp, pacibsp,
 *   - BRK insn
 *   - HLT insn
 * Anything else causes a Branch Target Exception.
 *
 * Return true if the branch is compatible, false to raise BTITRAP.
 */
static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
{
    if ((insn & 0xfffff01fu) == 0xd503201fu) {
        /* HINT space */
        switch (extract32(insn, 5, 7)) {
        case 0b011001: /* PACIASP */
        case 0b011011: /* PACIBSP */
            /*
             * If SCTLR_ELx.BT, then PACI*SP are not compatible
             * with btype == 3.  Otherwise all btype are ok.
             */
            return !bt || btype != 3;
        case 0b100000: /* BTI */
            /* Not compatible with any btype.  */
            return false;
        case 0b100010: /* BTI c */
            /* Not compatible with btype == 3 */
            return btype != 3;
        case 0b100100: /* BTI j */
            /* Not compatible with btype == 2 */
            return btype != 2;
        case 0b100110: /* BTI jc */
            /* Compatible with any btype.  */
            return true;
        }
    } else {
        switch (insn & 0xffe0001fu) {
        case 0xd4200000u: /* BRK */
        case 0xd4400000u: /* HLT */
            /* Give priority to the breakpoint exception.  */
            return true;
        }
    }
    return false;
}

/* C3.1 A64 instruction index by encoding */
static void disas_a64_legacy(DisasContext *s, uint32_t insn)
{
    switch (extract32(insn, 25, 4)) {
    case 0x5:
    case 0xd:      /* Data processing - register */
        disas_data_proc_reg(s, insn);
        break;
    case 0x7:
    case 0xf:      /* Data processing - SIMD and floating point */
        disas_data_proc_simd_fp(s, insn);
        break;
    default:
        unallocated_encoding(s);
        break;
    }
}

static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
                                          CPUState *cpu)
{
    DisasContext *dc = container_of(dcbase, DisasContext, base);
    CPUARMState *env = cpu_env(cpu);
    ARMCPU *arm_cpu = env_archcpu(env);
    CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
    int bound, core_mmu_idx;

    dc->isar = &arm_cpu->isar;
    dc->condjmp = 0;
    dc->pc_save = dc->base.pc_first;
    dc->aarch64 = true;
    dc->thumb = false;
    dc->sctlr_b = 0;
    dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
    dc->condexec_mask = 0;
    dc->condexec_cond = 0;
    core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
    dc->mmu_idx = core_to_aa64_mmu_idx(core_mmu_idx);
    dc->tbii = EX_TBFLAG_A64(tb_flags, TBII);
    dc->tbid = EX_TBFLAG_A64(tb_flags, TBID);
    dc->tcma = EX_TBFLAG_A64(tb_flags, TCMA);
    dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
#if !defined(CONFIG_USER_ONLY)
    dc->user = (dc->current_el == 0);
#endif
    dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
    dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
    dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
    dc->fgt_active = EX_TBFLAG_ANY(tb_flags, FGT_ACTIVE);
    dc->fgt_svc = EX_TBFLAG_ANY(tb_flags, FGT_SVC);
    dc->trap_eret = EX_TBFLAG_A64(tb_flags, TRAP_ERET);
    dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
    dc->sme_excp_el = EX_TBFLAG_A64(tb_flags, SMEEXC_EL);
    dc->vl = (EX_TBFLAG_A64(tb_flags, VL) + 1) * 16;
    dc->svl = (EX_TBFLAG_A64(tb_flags, SVL) + 1) * 16;
    dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
    dc->bt = EX_TBFLAG_A64(tb_flags, BT);
    dc->btype = EX_TBFLAG_A64(tb_flags, BTYPE);
    dc->unpriv = EX_TBFLAG_A64(tb_flags, UNPRIV);
    dc->ata[0] = EX_TBFLAG_A64(tb_flags, ATA);
    dc->ata[1] = EX_TBFLAG_A64(tb_flags, ATA0);
    dc->mte_active[0] = EX_TBFLAG_A64(tb_flags, MTE_ACTIVE);
    dc->mte_active[1] = EX_TBFLAG_A64(tb_flags, MTE0_ACTIVE);
    dc->pstate_sm = EX_TBFLAG_A64(tb_flags, PSTATE_SM);
    dc->pstate_za = EX_TBFLAG_A64(tb_flags, PSTATE_ZA);
    dc->sme_trap_nonstreaming = EX_TBFLAG_A64(tb_flags, SME_TRAP_NONSTREAMING);
    dc->naa = EX_TBFLAG_A64(tb_flags, NAA);
    dc->nv = EX_TBFLAG_A64(tb_flags, NV);
    dc->nv1 = EX_TBFLAG_A64(tb_flags, NV1);
    dc->nv2 = EX_TBFLAG_A64(tb_flags, NV2);
    dc->nv2_mem_e20 = EX_TBFLAG_A64(tb_flags, NV2_MEM_E20);
    dc->nv2_mem_be = EX_TBFLAG_A64(tb_flags, NV2_MEM_BE);
    dc->vec_len = 0;
    dc->vec_stride = 0;
    dc->cp_regs = arm_cpu->cp_regs;
    dc->features = env->features;
    dc->dcz_blocksize = arm_cpu->dcz_blocksize;
    dc->gm_blocksize = arm_cpu->gm_blocksize;

#ifdef CONFIG_USER_ONLY
    /* In sve_probe_page, we assume TBI is enabled. */
    tcg_debug_assert(dc->tbid & 1);
#endif

    dc->lse2 = dc_isar_feature(aa64_lse2, dc);

    /* Single step state. The code-generation logic here is:
     *  SS_ACTIVE == 0:
     *   generate code with no special handling for single-stepping (except
     *   that anything that can make us go to SS_ACTIVE == 1 must end the TB;
     *   this happens anyway because those changes are all system register or
     *   PSTATE writes).
     *  SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
     *   emit code for one insn
     *   emit code to clear PSTATE.SS
     *   emit code to generate software step exception for completed step
     *   end TB (as usual for having generated an exception)
     *  SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
     *   emit code to generate a software step exception
     *   end the TB
     */
    dc->ss_active = EX_TBFLAG_ANY(tb_flags, SS_ACTIVE);
    dc->pstate_ss = EX_TBFLAG_ANY(tb_flags, PSTATE__SS);
    dc->is_ldex = false;

    /* Bound the number of insns to execute to those left on the page.  */
    bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;

    /* If architectural single step active, limit to 1.  */
    if (dc->ss_active) {
        bound = 1;
    }
    dc->base.max_insns = MIN(dc->base.max_insns, bound);
}

static void aarch64_tr_tb_start(DisasContextBase *db, CPUState *cpu)
{
}

static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
{
    DisasContext *dc = container_of(dcbase, DisasContext, base);
    target_ulong pc_arg = dc->base.pc_next;

    if (tb_cflags(dcbase->tb) & CF_PCREL) {
        pc_arg &= ~TARGET_PAGE_MASK;
    }
    tcg_gen_insn_start(pc_arg, 0, 0);
    dc->insn_start_updated = false;
}

static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
{
    DisasContext *s = container_of(dcbase, DisasContext, base);
    CPUARMState *env = cpu_env(cpu);
    uint64_t pc = s->base.pc_next;
    uint32_t insn;

    /* Singlestep exceptions have the highest priority. */
    if (s->ss_active && !s->pstate_ss) {
        /* Singlestep state is Active-pending.
         * If we're in this state at the start of a TB then either
         *  a) we just took an exception to an EL which is being debugged
         *     and this is the first insn in the exception handler
         *  b) debug exceptions were masked and we just unmasked them
         *     without changing EL (eg by clearing PSTATE.D)
         * In either case we're going to take a swstep exception in the
         * "did not step an insn" case, and so the syndrome ISV and EX
         * bits should be zero.
         */
        assert(s->base.num_insns == 1);
        gen_swstep_exception(s, 0, 0);
        s->base.is_jmp = DISAS_NORETURN;
        s->base.pc_next = pc + 4;
        return;
    }

    if (pc & 3) {
        /*
         * PC alignment fault.  This has priority over the instruction abort
         * that we would receive from a translation fault via arm_ldl_code.
         * This should only be possible after an indirect branch, at the
         * start of the TB.
         */
        assert(s->base.num_insns == 1);
        gen_helper_exception_pc_alignment(tcg_env, tcg_constant_tl(pc));
        s->base.is_jmp = DISAS_NORETURN;
        s->base.pc_next = QEMU_ALIGN_UP(pc, 4);
        return;
    }

    s->pc_curr = pc;
    insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
    s->insn = insn;
    s->base.pc_next = pc + 4;

    s->fp_access_checked = false;
    s->sve_access_checked = false;

    if (s->pstate_il) {
        /*
         * Illegal execution state. This has priority over BTI
         * exceptions, but comes after instruction abort exceptions.
         */
        gen_exception_insn(s, 0, EXCP_UDEF, syn_illegalstate());
        return;
    }

    if (dc_isar_feature(aa64_bti, s)) {
        if (s->base.num_insns == 1) {
            /*
             * At the first insn of the TB, compute s->guarded_page.
             * We delayed computing this until successfully reading
             * the first insn of the TB, above.  This (mostly) ensures
             * that the softmmu tlb entry has been populated, and the
             * page table GP bit is available.
             *
             * Note that we need to compute this even if btype == 0,
             * because this value is used for BR instructions later
             * where ENV is not available.
             */
            s->guarded_page = is_guarded_page(env, s);

            /* First insn can have btype set to non-zero.  */
            tcg_debug_assert(s->btype >= 0);

            /*
             * Note that the Branch Target Exception has fairly high
             * priority -- below debugging exceptions but above most
             * everything else.  This allows us to handle this now
             * instead of waiting until the insn is otherwise decoded.
             */
            if (s->btype != 0
                && s->guarded_page
                && !btype_destination_ok(insn, s->bt, s->btype)) {
                gen_exception_insn(s, 0, EXCP_UDEF, syn_btitrap(s->btype));
                return;
            }
        } else {
            /* Not the first insn: btype must be 0.  */
            tcg_debug_assert(s->btype == 0);
        }
    }

    s->is_nonstreaming = false;
    if (s->sme_trap_nonstreaming) {
        disas_sme_fa64(s, insn);
    }

    if (!disas_a64(s, insn) &&
        !disas_sme(s, insn) &&
        !disas_sve(s, insn)) {
        disas_a64_legacy(s, insn);
    }

    /*
     * After execution of most insns, btype is reset to 0.
     * Note that we set btype == -1 when the insn sets btype.
     */
    if (s->btype > 0 && s->base.is_jmp != DISAS_NORETURN) {
        reset_btype(s);
    }
}

static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
{
    DisasContext *dc = container_of(dcbase, DisasContext, base);

    if (unlikely(dc->ss_active)) {
        /* Note that this means single stepping WFI doesn't halt the CPU.
         * For conditional branch insns this is harmless unreachable code as
         * gen_goto_tb() has already handled emitting the debug exception
         * (and thus a tb-jump is not possible when singlestepping).
         */
        switch (dc->base.is_jmp) {
        default:
            gen_a64_update_pc(dc, 4);
            /* fall through */
        case DISAS_EXIT:
        case DISAS_JUMP:
            gen_step_complete_exception(dc);
            break;
        case DISAS_NORETURN:
            break;
        }
    } else {
        switch (dc->base.is_jmp) {
        case DISAS_NEXT:
        case DISAS_TOO_MANY:
            gen_goto_tb(dc, 1, 4);
            break;
        default:
        case DISAS_UPDATE_EXIT:
            gen_a64_update_pc(dc, 4);
            /* fall through */
        case DISAS_EXIT:
            tcg_gen_exit_tb(NULL, 0);
            break;
        case DISAS_UPDATE_NOCHAIN:
            gen_a64_update_pc(dc, 4);
            /* fall through */
        case DISAS_JUMP:
            tcg_gen_lookup_and_goto_ptr();
            break;
        case DISAS_NORETURN:
        case DISAS_SWI:
            break;
        case DISAS_WFE:
            gen_a64_update_pc(dc, 4);
            gen_helper_wfe(tcg_env);
            break;
        case DISAS_YIELD:
            gen_a64_update_pc(dc, 4);
            gen_helper_yield(tcg_env);
            break;
        case DISAS_WFI:
            /*
             * This is a special case because we don't want to just halt
             * the CPU if trying to debug across a WFI.
             */
            gen_a64_update_pc(dc, 4);
            gen_helper_wfi(tcg_env, tcg_constant_i32(4));
            /*
             * The helper doesn't necessarily throw an exception, but we
             * must go back to the main loop to check for interrupts anyway.
             */
            tcg_gen_exit_tb(NULL, 0);
            break;
        }
    }
}

const TranslatorOps aarch64_translator_ops = {
    .init_disas_context = aarch64_tr_init_disas_context,
    .tb_start           = aarch64_tr_tb_start,
    .insn_start         = aarch64_tr_insn_start,
    .translate_insn     = aarch64_tr_translate_insn,
    .tb_stop            = aarch64_tr_tb_stop,
};
