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

#include "translate.h"
#include "translate-a32.h"
#include "qemu/log.h"
#include "arm_ldst.h"
#include "semihosting/semihost.h"
#include "cpregs.h"
#include "exec/helper-proto.h"
#include "exec/target_page.h"

#define HELPER_H "helper.h"
#include "exec/helper-info.c.inc"
#undef  HELPER_H

#define ENABLE_ARCH_4T    arm_dc_feature(s, ARM_FEATURE_V4T)
#define ENABLE_ARCH_5     arm_dc_feature(s, ARM_FEATURE_V5)
/* currently all emulated v5 cores are also v5TE, so don't bother */
#define ENABLE_ARCH_5TE   arm_dc_feature(s, ARM_FEATURE_V5)
#define ENABLE_ARCH_5J    dc_isar_feature(aa32_jazelle, s)
#define ENABLE_ARCH_6     arm_dc_feature(s, ARM_FEATURE_V6)
#define ENABLE_ARCH_6K    arm_dc_feature(s, ARM_FEATURE_V6K)
#define ENABLE_ARCH_6T2   arm_dc_feature(s, ARM_FEATURE_THUMB2)
#define ENABLE_ARCH_7     arm_dc_feature(s, ARM_FEATURE_V7)
#define ENABLE_ARCH_8     arm_dc_feature(s, ARM_FEATURE_V8)

/* These are TCG globals which alias CPUARMState fields */
static TCGv_i32 cpu_R[16];
TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
TCGv_i64 cpu_exclusive_addr;
TCGv_i64 cpu_exclusive_val;

static const char * const regnames[] =
    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };


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

    for (i = 0; i < 16; i++) {
        cpu_R[i] = tcg_global_mem_new_i32(tcg_env,
                                          offsetof(CPUARMState, regs[i]),
                                          regnames[i]);
    }
    cpu_CF = tcg_global_mem_new_i32(tcg_env, offsetof(CPUARMState, CF), "CF");
    cpu_NF = tcg_global_mem_new_i32(tcg_env, offsetof(CPUARMState, NF), "NF");
    cpu_VF = tcg_global_mem_new_i32(tcg_env, offsetof(CPUARMState, VF), "VF");
    cpu_ZF = tcg_global_mem_new_i32(tcg_env, offsetof(CPUARMState, ZF), "ZF");

    cpu_exclusive_addr = tcg_global_mem_new_i64(tcg_env,
        offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
    cpu_exclusive_val = tcg_global_mem_new_i64(tcg_env,
        offsetof(CPUARMState, exclusive_val), "exclusive_val");

    a64_translate_init();
}

uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
{
    /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
    switch (cmode) {
    case 0: case 1:
        /* no-op */
        break;
    case 2: case 3:
        imm <<= 8;
        break;
    case 4: case 5:
        imm <<= 16;
        break;
    case 6: case 7:
        imm <<= 24;
        break;
    case 8: case 9:
        imm |= imm << 16;
        break;
    case 10: case 11:
        imm = (imm << 8) | (imm << 24);
        break;
    case 12:
        imm = (imm << 8) | 0xff;
        break;
    case 13:
        imm = (imm << 16) | 0xffff;
        break;
    case 14:
        if (op) {
            /*
             * This and cmode == 15 op == 1 are the only cases where
             * the top and bottom 32 bits of the encoded constant differ.
             */
            uint64_t imm64 = 0;
            int n;

            for (n = 0; n < 8; n++) {
                if (imm & (1 << n)) {
                    imm64 |= (0xffULL << (n * 8));
                }
            }
            return imm64;
        }
        imm |= (imm << 8) | (imm << 16) | (imm << 24);
        break;
    case 15:
        if (op) {
            /* Reserved encoding for AArch32; valid for AArch64 */
            uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
            if (imm & 0x80) {
                imm64 |= 0x8000000000000000ULL;
            }
            if (imm & 0x40) {
                imm64 |= 0x3fc0000000000000ULL;
            } else {
                imm64 |= 0x4000000000000000ULL;
            }
            return imm64;
        }
        imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
            | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
        break;
    }
    if (op) {
        imm = ~imm;
    }
    return dup_const(MO_32, imm);
}

/* Generate a label used for skipping this instruction */
void arm_gen_condlabel(DisasContext *s)
{
    if (!s->condjmp) {
        s->condlabel = gen_disas_label(s);
        s->condjmp = 1;
    }
}

/* Flags for the disas_set_da_iss info argument:
 * lower bits hold the Rt register number, higher bits are flags.
 */
typedef enum ISSInfo {
    ISSNone = 0,
    ISSRegMask = 0x1f,
    ISSInvalid = (1 << 5),
    ISSIsAcqRel = (1 << 6),
    ISSIsWrite = (1 << 7),
    ISSIs16Bit = (1 << 8),
} ISSInfo;

/*
 * Store var into env + offset to a member with size bytes.
 * Free var after use.
 */
void store_cpu_offset(TCGv_i32 var, int offset, int size)
{
    switch (size) {
    case 1:
        tcg_gen_st8_i32(var, tcg_env, offset);
        break;
    case 4:
        tcg_gen_st_i32(var, tcg_env, offset);
        break;
    default:
        g_assert_not_reached();
    }
}

/* Save the syndrome information for a Data Abort */
static void disas_set_da_iss(DisasContext *s, MemOp memop, ISSInfo issinfo)
{
    uint32_t syn;
    int sas = memop & MO_SIZE;
    bool sse = memop & MO_SIGN;
    bool is_acqrel = issinfo & ISSIsAcqRel;
    bool is_write = issinfo & ISSIsWrite;
    bool is_16bit = issinfo & ISSIs16Bit;
    int srt = issinfo & ISSRegMask;

    if (issinfo & ISSInvalid) {
        /* Some callsites want to conditionally provide ISS info,
         * eg "only if this was not a writeback"
         */
        return;
    }

    if (srt == 15) {
        /* For AArch32, insns where the src/dest is R15 never generate
         * ISS information. Catching that here saves checking at all
         * the call sites.
         */
        return;
    }

    syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
                                  0, 0, 0, is_write, 0, is_16bit);
    disas_set_insn_syndrome(s, syn);
}

static inline int get_a32_user_mem_index(DisasContext *s)
{
    /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
     * insns:
     *  if PL2, UNPREDICTABLE (we choose to implement as if PL0)
     *  otherwise, access as if at PL0.
     */
    switch (s->mmu_idx) {
    case ARMMMUIdx_E3:
    case ARMMMUIdx_E30_0:
    case ARMMMUIdx_E30_3_PAN:
        return arm_to_core_mmu_idx(ARMMMUIdx_E30_0);
    case ARMMMUIdx_E2:        /* this one is UNPREDICTABLE */
    case ARMMMUIdx_E10_0:
    case ARMMMUIdx_E10_1:
    case ARMMMUIdx_E10_1_PAN:
        return arm_to_core_mmu_idx(ARMMMUIdx_E10_0);
    case ARMMMUIdx_MUser:
    case ARMMMUIdx_MPriv:
        return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
    case ARMMMUIdx_MUserNegPri:
    case ARMMMUIdx_MPrivNegPri:
        return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
    case ARMMMUIdx_MSUser:
    case ARMMMUIdx_MSPriv:
        return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
    case ARMMMUIdx_MSUserNegPri:
    case ARMMMUIdx_MSPrivNegPri:
        return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
    default:
        g_assert_not_reached();
    }
}

/* The pc_curr difference for an architectural jump. */
static target_long jmp_diff(DisasContext *s, target_long diff)
{
    return diff + (s->thumb ? 4 : 8);
}

static void gen_pc_plus_diff(DisasContext *s, TCGv_i32 var, target_long diff)
{
    assert(s->pc_save != -1);
    if (tb_cflags(s->base.tb) & CF_PCREL) {
        tcg_gen_addi_i32(var, cpu_R[15], (s->pc_curr - s->pc_save) + diff);
    } else {
        tcg_gen_movi_i32(var, s->pc_curr + diff);
    }
}

/* Set a variable to the value of a CPU register.  */
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
{
    if (reg == 15) {
        gen_pc_plus_diff(s, var, jmp_diff(s, 0));
    } else {
        tcg_gen_mov_i32(var, cpu_R[reg]);
    }
}

/*
 * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
 * This is used for load/store for which use of PC implies (literal),
 * or ADD that implies ADR.
 */
TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
{
    TCGv_i32 tmp = tcg_temp_new_i32();

    if (reg == 15) {
        /*
         * This address is computed from an aligned PC:
         * subtract off the low bits.
         */
        gen_pc_plus_diff(s, tmp, jmp_diff(s, ofs - (s->pc_curr & 3)));
    } else {
        tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
    }
    return tmp;
}

/* Set a CPU register.  The source must be a temporary and will be
   marked as dead.  */
void store_reg(DisasContext *s, int reg, TCGv_i32 var)
{
    if (reg == 15) {
        /* In Thumb mode, we must ignore bit 0.
         * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
         * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
         * We choose to ignore [1:0] in ARM mode for all architecture versions.
         */
        tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
        s->base.is_jmp = DISAS_JUMP;
        s->pc_save = -1;
    } else if (reg == 13 && arm_dc_feature(s, ARM_FEATURE_M)) {
        /* For M-profile SP bits [1:0] are always zero */
        tcg_gen_andi_i32(var, var, ~3);
    }
    tcg_gen_mov_i32(cpu_R[reg], var);
}

/*
 * Variant of store_reg which applies v8M stack-limit checks before updating
 * SP. If the check fails this will result in an exception being taken.
 * We disable the stack checks for CONFIG_USER_ONLY because we have
 * no idea what the stack limits should be in that case.
 * If stack checking is not being done this just acts like store_reg().
 */
static void store_sp_checked(DisasContext *s, TCGv_i32 var)
{
#ifndef CONFIG_USER_ONLY
    if (s->v8m_stackcheck) {
        gen_helper_v8m_stackcheck(tcg_env, var);
    }
#endif
    store_reg(s, 13, var);
}

/* Value extensions.  */
#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)

#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)

void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
{
    gen_helper_cpsr_write(tcg_env, var, tcg_constant_i32(mask));
}

static void gen_rebuild_hflags(DisasContext *s, bool new_el)
{
    bool m_profile = arm_dc_feature(s, ARM_FEATURE_M);

    if (new_el) {
        if (m_profile) {
            gen_helper_rebuild_hflags_m32_newel(tcg_env);
        } else {
            gen_helper_rebuild_hflags_a32_newel(tcg_env);
        }
    } else {
        TCGv_i32 tcg_el = tcg_constant_i32(s->current_el);
        if (m_profile) {
            gen_helper_rebuild_hflags_m32(tcg_env, tcg_el);
        } else {
            gen_helper_rebuild_hflags_a32(tcg_env, tcg_el);
        }
    }
}

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

static void gen_singlestep_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;
}

void clear_eci_state(DisasContext *s)
{
    /*
     * Clear any ECI/ICI state: used when a load multiple/store
     * multiple insn executes.
     */
    if (s->eci) {
        store_cpu_field_constant(0, condexec_bits);
        s->eci = 0;
    }
}

static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
{
    TCGv_i32 tmp1 = tcg_temp_new_i32();
    TCGv_i32 tmp2 = tcg_temp_new_i32();
    tcg_gen_ext16s_i32(tmp1, a);
    tcg_gen_ext16s_i32(tmp2, b);
    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
    tcg_gen_sari_i32(a, a, 16);
    tcg_gen_sari_i32(b, b, 16);
    tcg_gen_mul_i32(b, b, a);
    tcg_gen_mov_i32(a, tmp1);
}

/* Byteswap each halfword.  */
void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
{
    TCGv_i32 tmp = tcg_temp_new_i32();
    TCGv_i32 mask = tcg_constant_i32(0x00ff00ff);
    tcg_gen_shri_i32(tmp, var, 8);
    tcg_gen_and_i32(tmp, tmp, mask);
    tcg_gen_and_i32(var, var, mask);
    tcg_gen_shli_i32(var, var, 8);
    tcg_gen_or_i32(dest, var, tmp);
}

/* Byteswap low halfword and sign extend.  */
static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
{
    tcg_gen_bswap16_i32(var, var, TCG_BSWAP_OS);
}

/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
    tmp = (t0 ^ t1) & 0x8000;
    t0 &= ~0x8000;
    t1 &= ~0x8000;
    t0 = (t0 + t1) ^ tmp;
 */

static void gen_add16(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
    TCGv_i32 tmp = tcg_temp_new_i32();
    tcg_gen_xor_i32(tmp, t0, t1);
    tcg_gen_andi_i32(tmp, tmp, 0x8000);
    tcg_gen_andi_i32(t0, t0, ~0x8000);
    tcg_gen_andi_i32(t1, t1, ~0x8000);
    tcg_gen_add_i32(t0, t0, t1);
    tcg_gen_xor_i32(dest, t0, tmp);
}

/* Set N and Z flags from var.  */
static inline void gen_logic_CC(TCGv_i32 var)
{
    tcg_gen_mov_i32(cpu_NF, var);
    tcg_gen_mov_i32(cpu_ZF, var);
}

/* dest = T0 + T1 + CF. */
static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
    tcg_gen_add_i32(dest, t0, t1);
    tcg_gen_add_i32(dest, dest, cpu_CF);
}

/* dest = T0 - T1 + CF - 1.  */
static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
    tcg_gen_sub_i32(dest, t0, t1);
    tcg_gen_add_i32(dest, dest, cpu_CF);
    tcg_gen_subi_i32(dest, dest, 1);
}

/* dest = T0 + T1. Compute C, N, V and Z flags */
static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
    TCGv_i32 tmp = tcg_temp_new_i32();
    tcg_gen_movi_i32(tmp, 0);
    tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
    tcg_gen_xor_i32(tmp, t0, t1);
    tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
    tcg_gen_mov_i32(dest, cpu_NF);
}

/* dest = T0 + T1 + CF.  Compute C, N, V and Z flags */
static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
    TCGv_i32 tmp = tcg_temp_new_i32();

    tcg_gen_addcio_i32(cpu_NF, cpu_CF, t0, t1, cpu_CF);

    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
    tcg_gen_xor_i32(tmp, t0, t1);
    tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
    tcg_gen_mov_i32(dest, cpu_NF);
}

/* dest = T0 - T1. Compute C, N, V and Z flags */
static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
    TCGv_i32 tmp;
    tcg_gen_sub_i32(cpu_NF, t0, t1);
    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
    tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
    tmp = tcg_temp_new_i32();
    tcg_gen_xor_i32(tmp, t0, t1);
    tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
    tcg_gen_mov_i32(dest, cpu_NF);
}

/* dest = T0 + ~T1 + CF.  Compute C, N, V and Z flags */
static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
    TCGv_i32 tmp = tcg_temp_new_i32();
    tcg_gen_not_i32(tmp, t1);
    gen_adc_CC(dest, t0, tmp);
}

#define GEN_SHIFT(name)                                               \
static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)       \
{                                                                     \
    TCGv_i32 tmpd = tcg_temp_new_i32();                               \
    TCGv_i32 tmp1 = tcg_temp_new_i32();                               \
    TCGv_i32 zero = tcg_constant_i32(0);                              \
    tcg_gen_andi_i32(tmp1, t1, 0x1f);                                 \
    tcg_gen_##name##_i32(tmpd, t0, tmp1);                             \
    tcg_gen_andi_i32(tmp1, t1, 0xe0);                                 \
    tcg_gen_movcond_i32(TCG_COND_NE, dest, tmp1, zero, zero, tmpd);   \
}
GEN_SHIFT(shl)
GEN_SHIFT(shr)
#undef GEN_SHIFT

static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
{
    TCGv_i32 tmp1 = tcg_temp_new_i32();

    tcg_gen_andi_i32(tmp1, t1, 0xff);
    tcg_gen_umin_i32(tmp1, tmp1, tcg_constant_i32(31));
    tcg_gen_sar_i32(dest, t0, tmp1);
}

static void shifter_out_im(TCGv_i32 var, int shift)
{
    tcg_gen_extract_i32(cpu_CF, var, shift, 1);
}

/* Shift by immediate.  Includes special handling for shift == 0.  */
static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
                                    int shift, int flags)
{
    switch (shiftop) {
    case 0: /* LSL */
        if (shift != 0) {
            if (flags)
                shifter_out_im(var, 32 - shift);
            tcg_gen_shli_i32(var, var, shift);
        }
        break;
    case 1: /* LSR */
        if (shift == 0) {
            if (flags) {
                tcg_gen_shri_i32(cpu_CF, var, 31);
            }
            tcg_gen_movi_i32(var, 0);
        } else {
            if (flags)
                shifter_out_im(var, shift - 1);
            tcg_gen_shri_i32(var, var, shift);
        }
        break;
    case 2: /* ASR */
        if (shift == 0)
            shift = 32;
        if (flags)
            shifter_out_im(var, shift - 1);
        if (shift == 32)
          shift = 31;
        tcg_gen_sari_i32(var, var, shift);
        break;
    case 3: /* ROR/RRX */
        if (shift != 0) {
            if (flags)
                shifter_out_im(var, shift - 1);
            tcg_gen_rotri_i32(var, var, shift); break;
        } else {
            TCGv_i32 tmp = tcg_temp_new_i32();
            tcg_gen_shli_i32(tmp, cpu_CF, 31);
            if (flags)
                shifter_out_im(var, 0);
            tcg_gen_shri_i32(var, var, 1);
            tcg_gen_or_i32(var, var, tmp);
        }
    }
};

static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
                                     TCGv_i32 shift, int flags)
{
    if (flags) {
        switch (shiftop) {
        case 0: gen_helper_shl_cc(var, tcg_env, var, shift); break;
        case 1: gen_helper_shr_cc(var, tcg_env, var, shift); break;
        case 2: gen_helper_sar_cc(var, tcg_env, var, shift); break;
        case 3: gen_helper_ror_cc(var, tcg_env, var, shift); break;
        }
    } else {
        switch (shiftop) {
        case 0:
            gen_shl(var, var, shift);
            break;
        case 1:
            gen_shr(var, var, shift);
            break;
        case 2:
            gen_sar(var, var, shift);
            break;
        case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
                tcg_gen_rotr_i32(var, var, shift); break;
        }
    }
}

/*
 * Generate a conditional based on ARM condition code cc.
 * This is common between ARM and Aarch64 targets.
 */
void arm_test_cc(DisasCompare *cmp, int cc)
{
    TCGv_i32 value;
    TCGCond cond;

    switch (cc) {
    case 0: /* eq: Z */
    case 1: /* ne: !Z */
        cond = TCG_COND_EQ;
        value = cpu_ZF;
        break;

    case 2: /* cs: C */
    case 3: /* cc: !C */
        cond = TCG_COND_NE;
        value = cpu_CF;
        break;

    case 4: /* mi: N */
    case 5: /* pl: !N */
        cond = TCG_COND_LT;
        value = cpu_NF;
        break;

    case 6: /* vs: V */
    case 7: /* vc: !V */
        cond = TCG_COND_LT;
        value = cpu_VF;
        break;

    case 8: /* hi: C && !Z */
    case 9: /* ls: !C || Z -> !(C && !Z) */
        cond = TCG_COND_NE;
        value = tcg_temp_new_i32();
        /* CF is 1 for C, so -CF is an all-bits-set mask for C;
           ZF is non-zero for !Z; so AND the two subexpressions.  */
        tcg_gen_neg_i32(value, cpu_CF);
        tcg_gen_and_i32(value, value, cpu_ZF);
        break;

    case 10: /* ge: N == V -> N ^ V == 0 */
    case 11: /* lt: N != V -> N ^ V != 0 */
        /* Since we're only interested in the sign bit, == 0 is >= 0.  */
        cond = TCG_COND_GE;
        value = tcg_temp_new_i32();
        tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
        break;

    case 12: /* gt: !Z && N == V */
    case 13: /* le: Z || N != V */
        cond = TCG_COND_NE;
        value = tcg_temp_new_i32();
        /* (N == V) is equal to the sign bit of ~(NF ^ VF).  Propagate
         * the sign bit then AND with ZF to yield the result.  */
        tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
        tcg_gen_sari_i32(value, value, 31);
        tcg_gen_andc_i32(value, cpu_ZF, value);
        break;

    case 14: /* always */
    case 15: /* always */
        /* Use the ALWAYS condition, which will fold early.
         * It doesn't matter what we use for the value.  */
        cond = TCG_COND_ALWAYS;
        value = cpu_ZF;
        goto no_invert;

    default:
        fprintf(stderr, "Bad condition code 0x%x\n", cc);
        abort();
    }

    if (cc & 1) {
        cond = tcg_invert_cond(cond);
    }

 no_invert:
    cmp->cond = cond;
    cmp->value = value;
}

void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
{
    tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
}

void arm_gen_test_cc(int cc, TCGLabel *label)
{
    DisasCompare cmp;
    arm_test_cc(&cmp, cc);
    arm_jump_cc(&cmp, label);
}

void gen_set_condexec(DisasContext *s)
{
    if (s->condexec_mask) {
        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);

        store_cpu_field_constant(val, condexec_bits);
    }
}

void gen_update_pc(DisasContext *s, target_long diff)
{
    gen_pc_plus_diff(s, cpu_R[15], diff);
    s->pc_save = s->pc_curr + diff;
}

/* Set PC and Thumb state from var.  var is marked as dead.  */
static inline void gen_bx(DisasContext *s, TCGv_i32 var)
{
    s->base.is_jmp = DISAS_JUMP;
    tcg_gen_andi_i32(cpu_R[15], var, ~1);
    tcg_gen_andi_i32(var, var, 1);
    store_cpu_field(var, thumb);
    s->pc_save = -1;
}

/*
 * Set PC and Thumb state from var. var is marked as dead.
 * For M-profile CPUs, include logic to detect exception-return
 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
 * and BX reg, and no others, and happens only for code in Handler mode.
 * The Security Extension also requires us to check for the FNC_RETURN
 * which signals a function return from non-secure state; this can happen
 * in both Handler and Thread mode.
 * To avoid having to do multiple comparisons in inline generated code,
 * we make the check we do here loose, so it will match for EXC_RETURN
 * in Thread mode. For system emulation do_v7m_exception_exit() checks
 * for these spurious cases and returns without doing anything (giving
 * the same behaviour as for a branch to a non-magic address).
 *
 * In linux-user mode it is unclear what the right behaviour for an
 * attempted FNC_RETURN should be, because in real hardware this will go
 * directly to Secure code (ie not the Linux kernel) which will then treat
 * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
 * attempt behave the way it would on a CPU without the security extension,
 * which is to say "like a normal branch". That means we can simply treat
 * all branches as normal with no magic address behaviour.
 */
static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
{
    /* Generate the same code here as for a simple bx, but flag via
     * s->base.is_jmp that we need to do the rest of the work later.
     */
    gen_bx(s, var);
#ifndef CONFIG_USER_ONLY
    if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
        (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
        s->base.is_jmp = DISAS_BX_EXCRET;
    }
#endif
}

static inline void gen_bx_excret_final_code(DisasContext *s)
{
    /* Generate the code to finish possible exception return and end the TB */
    DisasLabel excret_label = gen_disas_label(s);
    uint32_t min_magic;

    if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
        /* Covers FNC_RETURN and EXC_RETURN magic */
        min_magic = FNC_RETURN_MIN_MAGIC;
    } else {
        /* EXC_RETURN magic only */
        min_magic = EXC_RETURN_MIN_MAGIC;
    }

    /* Is the new PC value in the magic range indicating exception return? */
    tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label.label);
    /* No: end the TB as we would for a DISAS_JMP */
    if (s->ss_active) {
        gen_singlestep_exception(s);
    } else {
        tcg_gen_exit_tb(NULL, 0);
    }
    set_disas_label(s, excret_label);
    /* Yes: this is an exception return.
     * At this point in runtime env->regs[15] and env->thumb will hold
     * the exception-return magic number, which do_v7m_exception_exit()
     * will read. Nothing else will be able to see those values because
     * the cpu-exec main loop guarantees that we will always go straight
     * from raising the exception to the exception-handling code.
     *
     * gen_ss_advance(s) does nothing on M profile currently but
     * calling it is conceptually the right thing as we have executed
     * this instruction (compare SWI, HVC, SMC handling).
     */
    gen_ss_advance(s);
    gen_exception_internal(EXCP_EXCEPTION_EXIT);
}

static inline void gen_bxns(DisasContext *s, int rm)
{
    TCGv_i32 var = load_reg(s, rm);

    /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
     * we need to sync state before calling it, but:
     *  - we don't need to do gen_update_pc() because the bxns helper will
     *    always set the PC itself
     *  - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
     *    unless it's outside an IT block or the last insn in an IT block,
     *    so we know that condexec == 0 (already set at the top of the TB)
     *    is correct in the non-UNPREDICTABLE cases, and we can choose
     *    "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
     */
    gen_helper_v7m_bxns(tcg_env, var);
    s->base.is_jmp = DISAS_EXIT;
}

static inline void gen_blxns(DisasContext *s, int rm)
{
    TCGv_i32 var = load_reg(s, rm);

    /* We don't need to sync condexec state, for the same reason as bxns.
     * We do however need to set the PC, because the blxns helper reads it.
     * The blxns helper may throw an exception.
     */
    gen_update_pc(s, curr_insn_len(s));
    gen_helper_v7m_blxns(tcg_env, var);
    s->base.is_jmp = DISAS_EXIT;
}

/* Variant of store_reg which uses branch&exchange logic when storing
   to r15 in ARM architecture v7 and above. The source must be a temporary
   and will be marked as dead. */
static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
{
    if (reg == 15 && ENABLE_ARCH_7) {
        gen_bx(s, var);
    } else {
        store_reg(s, reg, var);
    }
}

/* Variant of store_reg which uses branch&exchange logic when storing
 * to r15 in ARM architecture v5T and above. This is used for storing
 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
{
    if (reg == 15 && ENABLE_ARCH_5) {
        gen_bx_excret(s, var);
    } else {
        store_reg(s, reg, var);
    }
}

#ifdef CONFIG_USER_ONLY
#define IS_USER_ONLY 1
#else
#define IS_USER_ONLY 0
#endif

MemOp pow2_align(unsigned i)
{
    static const MemOp mop_align[] = {
        0, MO_ALIGN_2, MO_ALIGN_4, MO_ALIGN_8, MO_ALIGN_16, MO_ALIGN_32
    };
    g_assert(i < ARRAY_SIZE(mop_align));
    return mop_align[i];
}

/*
 * Abstractions of "generate code to do a guest load/store for
 * AArch32", where a vaddr is always 32 bits (and is zero
 * extended if we're a 64 bit core) and  data is also
 * 32 bits unless specifically doing a 64 bit access.
 * These functions work like tcg_gen_qemu_{ld,st}* except
 * that the address argument is TCGv_i32 rather than TCGv.
 */

static TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
{
    TCGv addr = tcg_temp_new();
    tcg_gen_extu_i32_tl(addr, a32);

    /* Not needed for user-mode BE32, where we use MO_BE instead.  */
    if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
        tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
    }
    return addr;
}

/*
 * Internal routines are used for NEON cases where the endianness
 * and/or alignment has already been taken into account and manipulated.
 */
void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
                              TCGv_i32 a32, int index, MemOp opc)
{
    TCGv addr = gen_aa32_addr(s, a32, opc);
    tcg_gen_qemu_ld_i32(val, addr, index, opc);
}

void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
                              TCGv_i32 a32, int index, MemOp opc)
{
    TCGv addr = gen_aa32_addr(s, a32, opc);
    tcg_gen_qemu_st_i32(val, addr, index, opc);
}

void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
                              TCGv_i32 a32, int index, MemOp opc)
{
    TCGv addr = gen_aa32_addr(s, a32, opc);

    tcg_gen_qemu_ld_i64(val, addr, index, opc);

    /* Not needed for user-mode BE32, where we use MO_BE instead.  */
    if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
        tcg_gen_rotri_i64(val, val, 32);
    }
}

void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
                              TCGv_i32 a32, int index, MemOp opc)
{
    TCGv addr = gen_aa32_addr(s, a32, opc);

    /* Not needed for user-mode BE32, where we use MO_BE instead.  */
    if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
        TCGv_i64 tmp = tcg_temp_new_i64();
        tcg_gen_rotri_i64(tmp, val, 32);
        tcg_gen_qemu_st_i64(tmp, addr, index, opc);
    } else {
        tcg_gen_qemu_st_i64(val, addr, index, opc);
    }
}

void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
                     int index, MemOp opc)
{
    gen_aa32_ld_internal_i32(s, val, a32, index, finalize_memop(s, opc));
}

void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
                     int index, MemOp opc)
{
    gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
}

void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
                     int index, MemOp opc)
{
    gen_aa32_ld_internal_i64(s, val, a32, index, finalize_memop(s, opc));
}

void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
                     int index, MemOp opc)
{
    gen_aa32_st_internal_i64(s, val, a32, index, finalize_memop(s, opc));
}

#define DO_GEN_LD(SUFF, OPC)                                            \
    static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
                                         TCGv_i32 a32, int index)       \
    {                                                                   \
        gen_aa32_ld_i32(s, val, a32, index, OPC);                       \
    }

#define DO_GEN_ST(SUFF, OPC)                                            \
    static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
                                         TCGv_i32 a32, int index)       \
    {                                                                   \
        gen_aa32_st_i32(s, val, a32, index, OPC);                       \
    }

static inline void gen_hvc(DisasContext *s, int imm16)
{
    /* The pre HVC helper handles cases when HVC gets trapped
     * as an undefined insn by runtime configuration (ie before
     * the insn really executes).
     */
    gen_update_pc(s, 0);
    gen_helper_pre_hvc(tcg_env);
    /* Otherwise we will treat this as a real exception which
     * happens after execution of the insn. (The distinction matters
     * for the PC value reported to the exception handler and also
     * for single stepping.)
     */
    s->svc_imm = imm16;
    gen_update_pc(s, curr_insn_len(s));
    s->base.is_jmp = DISAS_HVC;
}

static inline void gen_smc(DisasContext *s)
{
    /* As with HVC, we may take an exception either before or after
     * the insn executes.
     */
    gen_update_pc(s, 0);
    gen_helper_pre_smc(tcg_env, tcg_constant_i32(syn_aa32_smc()));
    gen_update_pc(s, curr_insn_len(s));
    s->base.is_jmp = DISAS_SMC;
}

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

static void gen_exception_el_v(int excp, uint32_t syndrome, TCGv_i32 tcg_el)
{
    gen_helper_exception_with_syndrome_el(tcg_env, tcg_constant_i32(excp),
                                          tcg_constant_i32(syndrome), tcg_el);
}

static void gen_exception_el(int excp, uint32_t syndrome, uint32_t target_el)
{
    gen_exception_el_v(excp, syndrome, tcg_constant_i32(target_el));
}

static void gen_exception(int excp, uint32_t syndrome)
{
    gen_helper_exception_with_syndrome(tcg_env, tcg_constant_i32(excp),
                                       tcg_constant_i32(syndrome));
}

static void gen_exception_insn_el_v(DisasContext *s, target_long pc_diff,
                                    int excp, uint32_t syn, TCGv_i32 tcg_el)
{
    if (s->aarch64) {
        gen_a64_update_pc(s, pc_diff);
    } else {
        gen_set_condexec(s);
        gen_update_pc(s, pc_diff);
    }
    gen_exception_el_v(excp, syn, tcg_el);
    s->base.is_jmp = DISAS_NORETURN;
}

void gen_exception_insn_el(DisasContext *s, target_long pc_diff, int excp,
                           uint32_t syn, uint32_t target_el)
{
    gen_exception_insn_el_v(s, pc_diff, excp, syn,
                            tcg_constant_i32(target_el));
}

void gen_exception_insn(DisasContext *s, target_long pc_diff,
                        int excp, uint32_t syn)
{
    if (s->aarch64) {
        gen_a64_update_pc(s, pc_diff);
    } else {
        gen_set_condexec(s);
        gen_update_pc(s, pc_diff);
    }
    gen_exception(excp, syn);
    s->base.is_jmp = DISAS_NORETURN;
}

TCGLabel *delay_exception_el(DisasContext *s, int excp,
                             uint32_t syn, uint32_t target_el)
{
    /* Use tcg_malloc for automatic release on longjmp out of translation. */
    DisasDelayException *e = tcg_malloc(sizeof(DisasDelayException));

    memset(e, 0, sizeof(*e));

    /* Save enough of the current state to satisfy gen_exception_insn. */
    e->pc_curr = s->pc_curr;
    e->pc_save = s->pc_save;
    if (!s->aarch64) {
        e->condexec_cond = s->condexec_cond;
        e->condexec_mask = s->condexec_mask;
    }

    e->excp = excp;
    e->syn = syn;
    e->target_el = target_el;

    e->next = s->delay_excp_list;
    s->delay_excp_list = e;

    e->lab = gen_new_label();
    return e->lab;
}

TCGLabel *delay_exception(DisasContext *s, int excp, uint32_t syn)
{
    return delay_exception_el(s, excp, syn, 0);
}

void emit_delayed_exceptions(DisasContext *s)
{
    for (DisasDelayException *e = s->delay_excp_list; e ; e = e->next) {
        gen_set_label(e->lab);

        /* Restore the insn state to satisfy gen_exception_insn. */
        s->pc_curr = e->pc_curr;
        s->pc_save = e->pc_save;
        s->condexec_cond = e->condexec_cond;
        s->condexec_mask = e->condexec_mask;

        if (e->target_el) {
            gen_exception_insn_el(s, 0, e->excp, e->syn, e->target_el);
        } else {
            gen_exception_insn(s, 0, e->excp, e->syn);
        }
    }
}

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

void unallocated_encoding(DisasContext *s)
{
    /* Unallocated and reserved encodings are uncategorized */
    gen_exception_insn(s, 0, EXCP_UDEF, syn_uncategorized());
}

/* Force a TB lookup after an instruction that changes the CPU state.  */
void gen_lookup_tb(DisasContext *s)
{
    gen_pc_plus_diff(s, cpu_R[15], curr_insn_len(s));
    s->base.is_jmp = DISAS_EXIT;
}

static inline void gen_hlt(DisasContext *s, int imm)
{
    /* 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 0x3C" is a T32 semihosting trap instruction,
     * and "HLT 0xF000" is an A32 semihosting syscall. These traps
     * must trigger semihosting even for ARMv7 and earlier, where
     * HLT was an undefined encoding.
     * In system mode, we don't allow userspace access to
     * semihosting, to provide some semblance of security
     * (and for consistency with our 32-bit semihosting).
     */
    if (semihosting_enabled(s->current_el == 0) &&
        (imm == (s->thumb ? 0x3c : 0xf000))) {
        gen_exception_internal_insn(s, EXCP_SEMIHOST);
        return;
    }

    unallocated_encoding(s);
}

/*
 * Return the offset of a "full" NEON Dreg.
 */
long neon_full_reg_offset(unsigned reg)
{
    return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
}

/*
 * Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
 * where 0 is the least significant end of the register.
 */
long neon_element_offset(int reg, int element, MemOp memop)
{
    int element_size = 1 << (memop & MO_SIZE);
    int ofs = element * element_size;
#if HOST_BIG_ENDIAN
    /*
     * Calculate the offset assuming fully little-endian,
     * then XOR to account for the order of the 8-byte units.
     */
    if (element_size < 8) {
        ofs ^= 8 - element_size;
    }
#endif
    return neon_full_reg_offset(reg) + ofs;
}

/* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
long vfp_reg_offset(bool dp, unsigned reg)
{
    if (dp) {
        return neon_element_offset(reg, 0, MO_64);
    } else {
        return neon_element_offset(reg >> 1, reg & 1, MO_32);
    }
}

void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
{
    long off = neon_element_offset(reg, ele, memop);

    switch (memop) {
    case MO_SB:
        tcg_gen_ld8s_i32(dest, tcg_env, off);
        break;
    case MO_UB:
        tcg_gen_ld8u_i32(dest, tcg_env, off);
        break;
    case MO_SW:
        tcg_gen_ld16s_i32(dest, tcg_env, off);
        break;
    case MO_UW:
        tcg_gen_ld16u_i32(dest, tcg_env, off);
        break;
    case MO_UL:
    case MO_SL:
        tcg_gen_ld_i32(dest, tcg_env, off);
        break;
    default:
        g_assert_not_reached();
    }
}

void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
{
    long off = neon_element_offset(reg, ele, memop);

    switch (memop) {
    case MO_SL:
        tcg_gen_ld32s_i64(dest, tcg_env, off);
        break;
    case MO_UL:
        tcg_gen_ld32u_i64(dest, tcg_env, off);
        break;
    case MO_UQ:
        tcg_gen_ld_i64(dest, tcg_env, off);
        break;
    default:
        g_assert_not_reached();
    }
}

void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
{
    long off = neon_element_offset(reg, ele, memop);

    switch (memop) {
    case MO_8:
        tcg_gen_st8_i32(src, tcg_env, off);
        break;
    case MO_16:
        tcg_gen_st16_i32(src, tcg_env, off);
        break;
    case MO_32:
        tcg_gen_st_i32(src, tcg_env, off);
        break;
    default:
        g_assert_not_reached();
    }
}

void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
{
    long off = neon_element_offset(reg, ele, memop);

    switch (memop) {
    case MO_32:
        tcg_gen_st32_i64(src, tcg_env, off);
        break;
    case MO_64:
        tcg_gen_st_i64(src, tcg_env, off);
        break;
    default:
        g_assert_not_reached();
    }
}

static void gen_goto_ptr(void)
{
    tcg_gen_lookup_and_goto_ptr();
}

/* This will end the TB but doesn't guarantee we'll return to
 * cpu_loop_exec. Any live exit_requests will be processed as we
 * enter the next TB.
 */
static void gen_goto_tb(DisasContext *s, int n, target_long diff)
{
    if (translator_use_goto_tb(&s->base, 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_update_pc(s, diff);
            tcg_gen_goto_tb(n);
        } else {
            tcg_gen_goto_tb(n);
            gen_update_pc(s, diff);
        }
        tcg_gen_exit_tb(s->base.tb, n);
    } else {
        gen_update_pc(s, diff);
        gen_goto_ptr();
    }
    s->base.is_jmp = DISAS_NORETURN;
}

/* Jump, specifying which TB number to use if we gen_goto_tb() */
static void gen_jmp_tb(DisasContext *s, target_long diff, int tbno)
{
    if (unlikely(s->ss_active)) {
        /* An indirect jump so that we still trigger the debug exception.  */
        gen_update_pc(s, diff);
        s->base.is_jmp = DISAS_JUMP;
        return;
    }
    switch (s->base.is_jmp) {
    case DISAS_NEXT:
    case DISAS_TOO_MANY:
    case DISAS_NORETURN:
        /*
         * The normal case: just go to the destination TB.
         * NB: NORETURN happens if we generate code like
         *    gen_brcondi(l);
         *    gen_jmp();
         *    gen_set_label(l);
         *    gen_jmp();
         * on the second call to gen_jmp().
         */
        gen_goto_tb(s, tbno, diff);
        break;
    case DISAS_UPDATE_NOCHAIN:
    case DISAS_UPDATE_EXIT:
        /*
         * We already decided we're leaving the TB for some other reason.
         * Avoid using goto_tb so we really do exit back to the main loop
         * and don't chain to another TB.
         */
        gen_update_pc(s, diff);
        gen_goto_ptr();
        s->base.is_jmp = DISAS_NORETURN;
        break;
    default:
        /*
         * We shouldn't be emitting code for a jump and also have
         * is_jmp set to one of the special cases like DISAS_SWI.
         */
        g_assert_not_reached();
    }
}

static inline void gen_jmp(DisasContext *s, target_long diff)
{
    gen_jmp_tb(s, diff, 0);
}

static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
{
    if (x)
        tcg_gen_sari_i32(t0, t0, 16);
    else
        gen_sxth(t0);
    if (y)
        tcg_gen_sari_i32(t1, t1, 16);
    else
        gen_sxth(t1);
    tcg_gen_mul_i32(t0, t0, t1);
}

/* Return the mask of PSR bits set by a MSR instruction.  */
static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
{
    uint32_t mask = 0;

    if (flags & (1 << 0)) {
        mask |= 0xff;
    }
    if (flags & (1 << 1)) {
        mask |= 0xff00;
    }
    if (flags & (1 << 2)) {
        mask |= 0xff0000;
    }
    if (flags & (1 << 3)) {
        mask |= 0xff000000;
    }

    /* Mask out undefined and reserved bits.  */
    mask &= aarch32_cpsr_valid_mask(s->features, s->isar);

    /* Mask out execution state.  */
    if (!spsr) {
        mask &= ~CPSR_EXEC;
    }

    /* Mask out privileged bits.  */
    if (IS_USER(s)) {
        mask &= CPSR_USER;
    }
    return mask;
}

/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
{
    TCGv_i32 tmp;
    if (spsr) {
        /* ??? This is also undefined in system mode.  */
        if (IS_USER(s))
            return 1;

        tmp = load_cpu_field(spsr);
        tcg_gen_andi_i32(tmp, tmp, ~mask);
        tcg_gen_andi_i32(t0, t0, mask);
        tcg_gen_or_i32(tmp, tmp, t0);
        store_cpu_field(tmp, spsr);
    } else {
        gen_set_cpsr(t0, mask);
    }
    gen_lookup_tb(s);
    return 0;
}

/* Returns nonzero if access to the PSR is not permitted.  */
static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
{
    TCGv_i32 tmp;
    tmp = tcg_temp_new_i32();
    tcg_gen_movi_i32(tmp, val);
    return gen_set_psr(s, mask, spsr, tmp);
}

static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
                                     int *tgtmode, int *regno)
{
    /* Decode the r and sysm fields of MSR/MRS banked accesses into
     * the target mode and register number, and identify the various
     * unpredictable cases.
     * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
     *  + executed in user mode
     *  + using R15 as the src/dest register
     *  + accessing an unimplemented register
     *  + accessing a register that's inaccessible at current PL/security state*
     *  + accessing a register that you could access with a different insn
     * We choose to UNDEF in all these cases.
     * Since we don't know which of the various AArch32 modes we are in
     * we have to defer some checks to runtime.
     * Accesses to Monitor mode registers from Secure EL1 (which implies
     * that EL3 is AArch64) must trap to EL3.
     *
     * If the access checks fail this function will emit code to take
     * an exception and return false. Otherwise it will return true,
     * and set *tgtmode and *regno appropriately.
     */
    /* These instructions are present only in ARMv8, or in ARMv7 with the
     * Virtualization Extensions.
     */
    if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
        !arm_dc_feature(s, ARM_FEATURE_EL2)) {
        goto undef;
    }

    if (IS_USER(s) || rn == 15) {
        goto undef;
    }

    /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
     * of registers into (r, sysm).
     */
    if (r) {
        /* SPSRs for other modes */
        switch (sysm) {
        case 0xe: /* SPSR_fiq */
            *tgtmode = ARM_CPU_MODE_FIQ;
            break;
        case 0x10: /* SPSR_irq */
            *tgtmode = ARM_CPU_MODE_IRQ;
            break;
        case 0x12: /* SPSR_svc */
            *tgtmode = ARM_CPU_MODE_SVC;
            break;
        case 0x14: /* SPSR_abt */
            *tgtmode = ARM_CPU_MODE_ABT;
            break;
        case 0x16: /* SPSR_und */
            *tgtmode = ARM_CPU_MODE_UND;
            break;
        case 0x1c: /* SPSR_mon */
            *tgtmode = ARM_CPU_MODE_MON;
            break;
        case 0x1e: /* SPSR_hyp */
            *tgtmode = ARM_CPU_MODE_HYP;
            break;
        default: /* unallocated */
            goto undef;
        }
        /* We arbitrarily assign SPSR a register number of 16. */
        *regno = 16;
    } else {
        /* general purpose registers for other modes */
        switch (sysm) {
        case 0x0 ... 0x6:   /* 0b00xxx : r8_usr ... r14_usr */
            *tgtmode = ARM_CPU_MODE_USR;
            *regno = sysm + 8;
            break;
        case 0x8 ... 0xe:   /* 0b01xxx : r8_fiq ... r14_fiq */
            *tgtmode = ARM_CPU_MODE_FIQ;
            *regno = sysm;
            break;
        case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
            *tgtmode = ARM_CPU_MODE_IRQ;
            *regno = sysm & 1 ? 13 : 14;
            break;
        case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
            *tgtmode = ARM_CPU_MODE_SVC;
            *regno = sysm & 1 ? 13 : 14;
            break;
        case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
            *tgtmode = ARM_CPU_MODE_ABT;
            *regno = sysm & 1 ? 13 : 14;
            break;
        case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
            *tgtmode = ARM_CPU_MODE_UND;
            *regno = sysm & 1 ? 13 : 14;
            break;
        case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
            *tgtmode = ARM_CPU_MODE_MON;
            *regno = sysm & 1 ? 13 : 14;
            break;
        case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
            *tgtmode = ARM_CPU_MODE_HYP;
            /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
            *regno = sysm & 1 ? 13 : 17;
            break;
        default: /* unallocated */
            goto undef;
        }
    }

    /* Catch the 'accessing inaccessible register' cases we can detect
     * at translate time.
     */
    switch (*tgtmode) {
    case ARM_CPU_MODE_MON:
        if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
            goto undef;
        }
        if (s->current_el == 1) {
            /* If we're in Secure EL1 (which implies that EL3 is AArch64)
             * then accesses to Mon registers trap to Secure EL2, if it exists,
             * otherwise EL3.
             */
            TCGv_i32 tcg_el;

            if (arm_dc_feature(s, ARM_FEATURE_AARCH64) &&
                dc_isar_feature(aa64_sel2, s)) {
                /* Target EL is EL<3 minus SCR_EL3.EEL2> */
                tcg_el = load_cpu_field_low32(cp15.scr_el3);
                tcg_gen_sextract_i32(tcg_el, tcg_el, ctz32(SCR_EEL2), 1);
                tcg_gen_addi_i32(tcg_el, tcg_el, 3);
            } else {
                tcg_el = tcg_constant_i32(3);
            }

            gen_exception_insn_el_v(s, 0, EXCP_UDEF,
                                    syn_uncategorized(), tcg_el);
            return false;
        }
        break;
    case ARM_CPU_MODE_HYP:
        /*
         * r13_hyp can only be accessed from Monitor mode, and so we
         * can forbid accesses from EL2 or below.
         * elr_hyp can be accessed also from Hyp mode, so forbid
         * accesses from EL0 or EL1.
         * SPSR_hyp is supposed to be in the same category as r13_hyp
         * and UNPREDICTABLE if accessed from anything except Monitor
         * mode. However there is some real-world code that will do
         * it because at least some hardware happens to permit the
         * access. (Notably a standard Cortex-R52 startup code fragment
         * does this.) So we permit SPSR_hyp from Hyp mode also, to allow
         * this (incorrect) guest code to run.
         */
        if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2
            || (s->current_el < 3 && *regno != 16 && *regno != 17)) {
            goto undef;
        }
        break;
    default:
        break;
    }

    return true;

undef:
    /* If we get here then some access check did not pass */
    gen_exception_insn(s, 0, EXCP_UDEF, syn_uncategorized());
    return false;
}

static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
{
    TCGv_i32 tcg_reg;
    int tgtmode = 0, regno = 0;

    if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
        return;
    }

    /* Sync state because msr_banked() can raise exceptions */
    gen_set_condexec(s);
    gen_update_pc(s, 0);
    tcg_reg = load_reg(s, rn);
    gen_helper_msr_banked(tcg_env, tcg_reg,
                          tcg_constant_i32(tgtmode),
                          tcg_constant_i32(regno));
    s->base.is_jmp = DISAS_UPDATE_EXIT;
}

static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
{
    TCGv_i32 tcg_reg;
    int tgtmode = 0, regno = 0;

    if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
        return;
    }

    /* Sync state because mrs_banked() can raise exceptions */
    gen_set_condexec(s);
    gen_update_pc(s, 0);
    tcg_reg = tcg_temp_new_i32();
    gen_helper_mrs_banked(tcg_reg, tcg_env,
                          tcg_constant_i32(tgtmode),
                          tcg_constant_i32(regno));
    store_reg(s, rn, tcg_reg);
    s->base.is_jmp = DISAS_UPDATE_EXIT;
}

/* Store value to PC as for an exception return (ie don't
 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
 * will do the masking based on the new value of the Thumb bit.
 */
static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
{
    tcg_gen_mov_i32(cpu_R[15], pc);
}

/* Generate a v6 exception return.  Marks both values as dead.  */
static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
{
    store_pc_exc_ret(s, pc);
    /* The cpsr_write_eret helper will mask the low bits of PC
     * appropriately depending on the new Thumb bit, so it must
     * be called after storing the new PC.
     */
    translator_io_start(&s->base);
    gen_helper_cpsr_write_eret(tcg_env, cpsr);
    /* Must exit loop to check un-masked IRQs */
    s->base.is_jmp = DISAS_EXIT;
}

/* Generate an old-style exception return. Marks pc as dead. */
static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
{
    gen_rfe(s, pc, load_cpu_field(spsr));
}

static bool aa32_cpreg_encoding_in_impdef_space(uint8_t crn, uint8_t crm)
{
    static const uint16_t mask[3] = {
        0b0000000111100111,  /* crn ==  9, crm == {c0-c2, c5-c8}   */
        0b0000000100010011,  /* crn == 10, crm == {c0, c1, c4, c8} */
        0b1000000111111111,  /* crn == 11, crm == {c0-c8, c15}     */
    };

    if (crn >= 9 && crn <= 11) {
        return (mask[crn - 9] >> crm) & 1;
    }
    return false;
}

static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
                           int opc1, int crn, int crm, int opc2,
                           bool isread, int rt, int rt2)
{
    uint32_t key = ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2);
    const ARMCPRegInfo *ri = get_arm_cp_reginfo(s->cp_regs, key);
    TCGv_ptr tcg_ri = NULL;
    bool need_exit_tb = false;
    uint32_t syndrome;

    /*
     * Note that since we are an implementation which takes an
     * exception on a trapped conditional instruction only if the
     * instruction passes its condition code check, we can take
     * advantage of the clause in the ARM ARM that allows us to set
     * the COND field in the instruction to 0xE in all cases.
     * We could fish the actual condition out of the insn (ARM)
     * or the condexec bits (Thumb) but it isn't necessary.
     */
    switch (cpnum) {
    case 14:
        if (is64) {
            syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
                                         isread, false);
        } else {
            syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
                                        rt, isread, false);
        }
        break;
    case 15:
        if (is64) {
            syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
                                         isread, false);
        } else {
            syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
                                        rt, isread, false);
        }
        break;
    default:
        /*
         * ARMv8 defines that only coprocessors 14 and 15 exist,
         * so this can only happen if this is an ARMv7 or earlier CPU,
         * in which case the syndrome information won't actually be
         * guest visible.
         */
        assert(!arm_dc_feature(s, ARM_FEATURE_V8));
        syndrome = syn_uncategorized();
        break;
    }

    if (s->hstr_active && cpnum == 15 && s->current_el == 1) {
        /*
         * At EL1, check for a HSTR_EL2 trap, which must take precedence
         * over the UNDEF for "no such register" or the UNDEF for "access
         * permissions forbid this EL1 access". HSTR_EL2 traps from EL0
         * only happen if the cpreg doesn't UNDEF at EL0, so we do those in
         * access_check_cp_reg(), after the checks for whether the access
         * configurably trapped to EL1.
         */
        uint32_t maskbit = is64 ? crm : crn;

        if (maskbit != 4 && maskbit != 14) {
            /* T4 and T14 are RES0 so never cause traps */
            TCGv_i32 t;
            DisasLabel over = gen_disas_label(s);

            t = load_cpu_offset(offsetoflow32(CPUARMState, cp15.hstr_el2));
            tcg_gen_andi_i32(t, t, 1u << maskbit);
            tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, over.label);

            gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
            /*
             * gen_exception_insn() will set is_jmp to DISAS_NORETURN,
             * but since we're conditionally branching over it, we want
             * to assume continue-to-next-instruction.
             */
            s->base.is_jmp = DISAS_NEXT;
            set_disas_label(s, over);
        }
    }

    if (cpnum == 15 && aa32_cpreg_encoding_in_impdef_space(crn, crm)) {
        /*
         * Check for TIDCP trap, which must take precedence over the UNDEF
         * for "no such register" etc.  It shares precedence with HSTR,
         * but raises the same exception, so order doesn't matter.
         */
        switch (s->current_el) {
        case 0:
            if (arm_dc_feature(s, ARM_FEATURE_AARCH64)
                && 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.
         */
        if (is64) {
            qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
                          "64 bit system register cp:%d opc1: %d crm:%d "
                          "(%s)\n",
                          isread ? "read" : "write", cpnum, opc1, crm,
                          s->ns ? "non-secure" : "secure");
        } else {
            qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
                          "system register cp:%d opc1:%d crn:%d crm:%d "
                          "opc2:%d (%s)\n",
                          isread ? "read" : "write", cpnum, opc1, crn,
                          crm, opc2, s->ns ? "non-secure" : "secure");
        }
        unallocated_encoding(s);
        return;
    }

    /* Check access permissions */
    if (!cp_access_ok(s->current_el, ri, isread)) {
        unallocated_encoding(s);
        return;
    }

    if ((s->hstr_active && s->current_el == 0) || ri->accessfn ||
        (ri->fgt && s->fgt_active)) {
        /*
         * Emit code to perform further access permissions checks at
         * runtime; this may result in an exception.
         */
        gen_set_condexec(s);
        gen_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_set_condexec(s);
        gen_update_pc(s, 0);
    }

    /* Handle special cases first */
    switch (ri->type & ARM_CP_SPECIAL_MASK) {
    case 0:
        break;
    case ARM_CP_NOP:
        return;
    case ARM_CP_WFI:
        if (isread) {
            unallocated_encoding(s);
        } else {
            gen_update_pc(s, curr_insn_len(s));
            s->base.is_jmp = DISAS_WFI;
        }
        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);
    }

    if (isread) {
        /* Read */
        if (is64) {
            TCGv_i64 tmp64;
            TCGv_i32 tmp;
            if (ri->type & ARM_CP_CONST) {
                tmp64 = tcg_constant_i64(ri->resetvalue);
            } else if (ri->readfn) {
                if (!tcg_ri) {
                    tcg_ri = gen_lookup_cp_reg(key);
                }
                tmp64 = tcg_temp_new_i64();
                gen_helper_get_cp_reg64(tmp64, tcg_env, tcg_ri);
            } else {
                tmp64 = tcg_temp_new_i64();
                tcg_gen_ld_i64(tmp64, tcg_env, ri->fieldoffset);
            }
            tmp = tcg_temp_new_i32();
            tcg_gen_extrl_i64_i32(tmp, tmp64);
            store_reg(s, rt, tmp);
            tmp = tcg_temp_new_i32();
            tcg_gen_extrh_i64_i32(tmp, tmp64);
            store_reg(s, rt2, tmp);
        } else {
            TCGv_i32 tmp;
            if (ri->type & ARM_CP_CONST) {
                tmp = tcg_constant_i32(ri->resetvalue);
            } else if (ri->readfn) {
                if (!tcg_ri) {
                    tcg_ri = gen_lookup_cp_reg(key);
                }
                tmp = tcg_temp_new_i32();
                gen_helper_get_cp_reg(tmp, tcg_env, tcg_ri);
            } else {
                tmp = load_cpu_offset(ri->fieldoffset);
            }
            if (rt == 15) {
                /* Destination register of r15 for 32 bit loads sets
                 * the condition codes from the high 4 bits of the value
                 */
                gen_set_nzcv(tmp);
            } else {
                store_reg(s, rt, tmp);
            }
        }
    } else {
        /* Write */
        if (ri->type & ARM_CP_CONST) {
            /* If not forbidden by access permissions, treat as WI */
            return;
        }

        if (is64) {
            TCGv_i32 tmplo, tmphi;
            TCGv_i64 tmp64 = tcg_temp_new_i64();
            tmplo = load_reg(s, rt);
            tmphi = load_reg(s, rt2);
            tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
            if (ri->writefn) {
                if (!tcg_ri) {
                    tcg_ri = gen_lookup_cp_reg(key);
                }
                gen_helper_set_cp_reg64(tcg_env, tcg_ri, tmp64);
            } else {
                tcg_gen_st_i64(tmp64, tcg_env, ri->fieldoffset);
            }
        } else {
            TCGv_i32 tmp = load_reg(s, rt);
            if (ri->writefn) {
                if (!tcg_ri) {
                    tcg_ri = gen_lookup_cp_reg(key);
                }
                gen_helper_set_cp_reg(tcg_env, tcg_ri, tmp);
            } else {
                store_cpu_offset(tmp, ri->fieldoffset, 4);
            }
        }
    }

    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, ri->type & ARM_CP_NEWEL);
        /*
         * 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) {
        gen_lookup_tb(s);
    }
}

/* Store a 64-bit value to a register pair.  Clobbers val.  */
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
{
    TCGv_i32 tmp;
    tmp = tcg_temp_new_i32();
    tcg_gen_extrl_i64_i32(tmp, val);
    store_reg(s, rlow, tmp);
    tmp = tcg_temp_new_i32();
    tcg_gen_extrh_i64_i32(tmp, val);
    store_reg(s, rhigh, tmp);
}

/* load and add a 64-bit value from a register pair.  */
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
{
    TCGv_i64 tmp;
    TCGv_i32 tmpl;
    TCGv_i32 tmph;

    /* Load 64-bit value rd:rn.  */
    tmpl = load_reg(s, rlow);
    tmph = load_reg(s, rhigh);
    tmp = tcg_temp_new_i64();
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
    tcg_gen_add_i64(val, val, tmp);
}

/* Set N and Z flags from hi|lo.  */
static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
{
    tcg_gen_mov_i32(cpu_NF, hi);
    tcg_gen_or_i32(cpu_ZF, lo, hi);
}

/* 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 should be sufficient to implement
   the architecturally mandated semantics, and avoids having to monitor
   regular stores.  The compare vs the remembered value is done during
   the cmpxchg operation, but we must compare the addresses manually.  */
static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
                               TCGv_i32 addr, int size)
{
    TCGv_i32 tmp = tcg_temp_new_i32();
    MemOp opc = size | MO_ALIGN | s->be_data;

    s->is_ldex = true;

    if (size == 3) {
        TCGv_i32 tmp2 = tcg_temp_new_i32();
        TCGv_i64 t64 = tcg_temp_new_i64();

        /*
         * For AArch32, architecturally the 32-bit word at the lowest
         * address is always Rt and the one at addr+4 is Rt2, even if
         * the CPU is big-endian. That means we don't want to do a
         * gen_aa32_ld_i64(), which checks SCTLR_B as if for an
         * architecturally 64-bit access, but instead do a 64-bit access
         * using MO_BE if appropriate and then split the two halves.
         */
        TCGv taddr = gen_aa32_addr(s, addr, opc);

        tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
        tcg_gen_mov_i64(cpu_exclusive_val, t64);
        if (s->be_data == MO_BE) {
            tcg_gen_extr_i64_i32(tmp2, tmp, t64);
        } else {
            tcg_gen_extr_i64_i32(tmp, tmp2, t64);
        }
        store_reg(s, rt2, tmp2);
    } else {
        gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
        tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
    }

    store_reg(s, rt, tmp);
    tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
}

static void gen_clrex(DisasContext *s)
{
    tcg_gen_movi_i64(cpu_exclusive_addr, -1);
}

static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
                                TCGv_i32 addr, int size)
{
    TCGv_i32 t0, t1, t2;
    TCGv_i64 extaddr;
    TCGv taddr;
    TCGLabel *done_label;
    TCGLabel *fail_label;
    MemOp opc = size | MO_ALIGN | s->be_data;

    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
         [addr] = {Rt};
         {Rd} = 0;
       } else {
         {Rd} = 1;
       } */
    fail_label = gen_new_label();
    done_label = gen_new_label();
    extaddr = tcg_temp_new_i64();
    tcg_gen_extu_i32_i64(extaddr, addr);
    tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);

    taddr = gen_aa32_addr(s, addr, opc);
    t0 = tcg_temp_new_i32();
    t1 = load_reg(s, rt);
    if (size == 3) {
        TCGv_i64 o64 = tcg_temp_new_i64();
        TCGv_i64 n64 = tcg_temp_new_i64();

        t2 = load_reg(s, rt2);

        /*
         * For AArch32, architecturally the 32-bit word at the lowest
         * address is always Rt and the one at addr+4 is Rt2, even if
         * the CPU is big-endian. Since we're going to treat this as a
         * single 64-bit BE store, we need to put the two halves in the
         * opposite order for BE to LE, so that they end up in the right
         * places.  We don't want gen_aa32_st_i64, because that checks
         * SCTLR_B as if for an architectural 64-bit access.
         */
        if (s->be_data == MO_BE) {
            tcg_gen_concat_i32_i64(n64, t2, t1);
        } else {
            tcg_gen_concat_i32_i64(n64, t1, t2);
        }

        tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
                                   get_mem_index(s), opc);

        tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
        tcg_gen_extrl_i64_i32(t0, o64);
    } else {
        t2 = tcg_temp_new_i32();
        tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
        tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
        tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
    }
    tcg_gen_mov_i32(cpu_R[rd], t0);
    tcg_gen_br(done_label);

    gen_set_label(fail_label);
    tcg_gen_movi_i32(cpu_R[rd], 1);
    gen_set_label(done_label);
    tcg_gen_movi_i64(cpu_exclusive_addr, -1);
}

/* gen_srs:
 * @env: CPUARMState
 * @s: DisasContext
 * @mode: mode field from insn (which stack to store to)
 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
 * @writeback: true if writeback bit set
 *
 * Generate code for the SRS (Store Return State) insn.
 */
static void gen_srs(DisasContext *s,
                    uint32_t mode, uint32_t amode, bool writeback)
{
    int32_t offset;
    TCGv_i32 addr, tmp;
    bool undef = false;

    /* SRS is:
     * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
     *   and specified mode is monitor mode
     * - UNDEFINED in Hyp mode
     * - UNPREDICTABLE in User or System mode
     * - UNPREDICTABLE if the specified mode is:
     * -- not implemented
     * -- not a valid mode number
     * -- a mode that's at a higher exception level
     * -- Monitor, if we are Non-secure
     * For the UNPREDICTABLE cases we choose to UNDEF.
     */
    if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
        gen_exception_insn_el(s, 0, EXCP_UDEF, syn_uncategorized(), 3);
        return;
    }

    if (s->current_el == 0 || s->current_el == 2) {
        undef = true;
    }

    switch (mode) {
    case ARM_CPU_MODE_USR:
    case ARM_CPU_MODE_FIQ:
    case ARM_CPU_MODE_IRQ:
    case ARM_CPU_MODE_SVC:
    case ARM_CPU_MODE_ABT:
    case ARM_CPU_MODE_UND:
    case ARM_CPU_MODE_SYS:
        break;
    case ARM_CPU_MODE_HYP:
        if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
            undef = true;
        }
        break;
    case ARM_CPU_MODE_MON:
        /* No need to check specifically for "are we non-secure" because
         * we've already made EL0 UNDEF and handled the trap for S-EL1;
         * so if this isn't EL3 then we must be non-secure.
         */
        if (s->current_el != 3) {
            undef = true;
        }
        break;
    default:
        undef = true;
    }

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

    addr = tcg_temp_new_i32();
    /* get_r13_banked() will raise an exception if called from System mode */
    gen_set_condexec(s);
    gen_update_pc(s, 0);
    gen_helper_get_r13_banked(addr, tcg_env, tcg_constant_i32(mode));
    switch (amode) {
    case 0: /* DA */
        offset = -4;
        break;
    case 1: /* IA */
        offset = 0;
        break;
    case 2: /* DB */
        offset = -8;
        break;
    case 3: /* IB */
        offset = 4;
        break;
    default:
        g_assert_not_reached();
    }
    tcg_gen_addi_i32(addr, addr, offset);
    tmp = load_reg(s, 14);
    gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
    tmp = load_cpu_field(spsr);
    tcg_gen_addi_i32(addr, addr, 4);
    gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
    if (writeback) {
        switch (amode) {
        case 0:
            offset = -8;
            break;
        case 1:
            offset = 4;
            break;
        case 2:
            offset = -4;
            break;
        case 3:
            offset = 0;
            break;
        default:
            g_assert_not_reached();
        }
        tcg_gen_addi_i32(addr, addr, offset);
        gen_helper_set_r13_banked(tcg_env, tcg_constant_i32(mode), addr);
    }
    s->base.is_jmp = DISAS_UPDATE_EXIT;
}

/* Skip this instruction if the ARM condition is false */
static void arm_skip_unless(DisasContext *s, uint32_t cond)
{
    arm_gen_condlabel(s);
    arm_gen_test_cc(cond ^ 1, s->condlabel.label);
}


/*
 * Constant expanders used by T16/T32 decode
 */

/* Return only the rotation part of T32ExpandImm.  */
static int t32_expandimm_rot(DisasContext *s, int x)
{
    return x & 0xc00 ? extract32(x, 7, 5) : 0;
}

/* Return the unrotated immediate from T32ExpandImm.  */
static int t32_expandimm_imm(DisasContext *s, int x)
{
    uint32_t imm = extract32(x, 0, 8);

    switch (extract32(x, 8, 4)) {
    case 0: /* XY */
        /* Nothing to do.  */
        break;
    case 1: /* 00XY00XY */
        imm *= 0x00010001;
        break;
    case 2: /* XY00XY00 */
        imm *= 0x01000100;
        break;
    case 3: /* XYXYXYXY */
        imm *= 0x01010101;
        break;
    default:
        /* Rotated constant.  */
        imm |= 0x80;
        break;
    }
    return imm;
}

static int t32_branch24(DisasContext *s, int x)
{
    /* Convert J1:J2 at x[22:21] to I2:I1, which involves I=J^~S.  */
    x ^= !(x < 0) * (3 << 21);
    /* Append the final zero.  */
    return x << 1;
}

static int t16_setflags(DisasContext *s)
{
    return s->condexec_mask == 0;
}

static int t16_push_list(DisasContext *s, int x)
{
    return (x & 0xff) | (x & 0x100) << (14 - 8);
}

static int t16_pop_list(DisasContext *s, int x)
{
    return (x & 0xff) | (x & 0x100) << (15 - 8);
}

/*
 * Include the generated decoders.
 */

#include "decode-a32.c.inc"
#include "decode-a32-uncond.c.inc"
#include "decode-t32.c.inc"
#include "decode-t16.c.inc"

static bool valid_cp(DisasContext *s, int cp)
{
    /*
     * Return true if this coprocessor field indicates something
     * that's really a possible coprocessor.
     * For v7 and earlier, coprocessors 8..15 were reserved for Arm use,
     * and of those only cp14 and cp15 were used for registers.
     * cp10 and cp11 were used for VFP and Neon, whose decode is
     * dealt with elsewhere. With the advent of fp16, cp9 is also
     * now part of VFP.
     * For v8A and later, the encoding has been tightened so that
     * only cp14 and cp15 are valid, and other values aren't considered
     * to be in the coprocessor-instruction space at all. v8M still
     * permits coprocessors 0..7.
     */
    if (arm_dc_feature(s, ARM_FEATURE_V8) &&
        !arm_dc_feature(s, ARM_FEATURE_M)) {
        return cp >= 14;
    }
    return cp < 8 || cp >= 14;
}

static bool trans_MCR(DisasContext *s, arg_MCR *a)
{
    if (!valid_cp(s, a->cp)) {
        return false;
    }
    do_coproc_insn(s, a->cp, false, a->opc1, a->crn, a->crm, a->opc2,
                   false, a->rt, 0);
    return true;
}

static bool trans_MRC(DisasContext *s, arg_MRC *a)
{
    if (!valid_cp(s, a->cp)) {
        return false;
    }
    do_coproc_insn(s, a->cp, false, a->opc1, a->crn, a->crm, a->opc2,
                   true, a->rt, 0);
    return true;
}

static bool trans_MCRR(DisasContext *s, arg_MCRR *a)
{
    if (!valid_cp(s, a->cp)) {
        return false;
    }
    do_coproc_insn(s, a->cp, true, a->opc1, 0, a->crm, 0,
                   false, a->rt, a->rt2);
    return true;
}

static bool trans_MRRC(DisasContext *s, arg_MRRC *a)
{
    if (!valid_cp(s, a->cp)) {
        return false;
    }
    do_coproc_insn(s, a->cp, true, a->opc1, 0, a->crm, 0,
                   true, a->rt, a->rt2);
    return true;
}

/* Helpers to swap operands for reverse-subtract.  */
static void gen_rsb(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
{
    tcg_gen_sub_i32(dst, b, a);
}

static void gen_rsb_CC(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
{
    gen_sub_CC(dst, b, a);
}

static void gen_rsc(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
{
    gen_sub_carry(dest, b, a);
}

static void gen_rsc_CC(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
{
    gen_sbc_CC(dest, b, a);
}

/*
 * Helpers for the data processing routines.
 *
 * After the computation store the results back.
 * This may be suppressed altogether (STREG_NONE), require a runtime
 * check against the stack limits (STREG_SP_CHECK), or generate an
 * exception return.  Oh, or store into a register.
 *
 * Always return true, indicating success for a trans_* function.
 */
typedef enum {
   STREG_NONE,
   STREG_NORMAL,
   STREG_SP_CHECK,
   STREG_EXC_RET,
} StoreRegKind;

static bool store_reg_kind(DisasContext *s, int rd,
                            TCGv_i32 val, StoreRegKind kind)
{
    switch (kind) {
    case STREG_NONE:
        return true;
    case STREG_NORMAL:
        /* See ALUWritePC: Interworking only from a32 mode. */
        if (s->thumb) {
            store_reg(s, rd, val);
        } else {
            store_reg_bx(s, rd, val);
        }
        return true;
    case STREG_SP_CHECK:
        store_sp_checked(s, val);
        return true;
    case STREG_EXC_RET:
        gen_exception_return(s, val);
        return true;
    }
    g_assert_not_reached();
}

/*
 * Data Processing (register)
 *
 * Operate, with set flags, one register source,
 * one immediate shifted register source, and a destination.
 */
static bool op_s_rrr_shi(DisasContext *s, arg_s_rrr_shi *a,
                         void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
                         int logic_cc, StoreRegKind kind)
{
    TCGv_i32 tmp1, tmp2;

    tmp2 = load_reg(s, a->rm);
    gen_arm_shift_im(tmp2, a->shty, a->shim, logic_cc);
    tmp1 = load_reg(s, a->rn);

    gen(tmp1, tmp1, tmp2);

    if (logic_cc) {
        gen_logic_CC(tmp1);
    }
    return store_reg_kind(s, a->rd, tmp1, kind);
}

static bool op_s_rxr_shi(DisasContext *s, arg_s_rrr_shi *a,
                         void (*gen)(TCGv_i32, TCGv_i32),
                         int logic_cc, StoreRegKind kind)
{
    TCGv_i32 tmp;

    tmp = load_reg(s, a->rm);
    gen_arm_shift_im(tmp, a->shty, a->shim, logic_cc);

    gen(tmp, tmp);
    if (logic_cc) {
        gen_logic_CC(tmp);
    }
    return store_reg_kind(s, a->rd, tmp, kind);
}

/*
 * Data-processing (register-shifted register)
 *
 * Operate, with set flags, one register source,
 * one register shifted register source, and a destination.
 */
static bool op_s_rrr_shr(DisasContext *s, arg_s_rrr_shr *a,
                         void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
                         int logic_cc, StoreRegKind kind)
{
    TCGv_i32 tmp1, tmp2;

    tmp1 = load_reg(s, a->rs);
    tmp2 = load_reg(s, a->rm);
    gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
    tmp1 = load_reg(s, a->rn);

    gen(tmp1, tmp1, tmp2);

    if (logic_cc) {
        gen_logic_CC(tmp1);
    }
    return store_reg_kind(s, a->rd, tmp1, kind);
}

static bool op_s_rxr_shr(DisasContext *s, arg_s_rrr_shr *a,
                         void (*gen)(TCGv_i32, TCGv_i32),
                         int logic_cc, StoreRegKind kind)
{
    TCGv_i32 tmp1, tmp2;

    tmp1 = load_reg(s, a->rs);
    tmp2 = load_reg(s, a->rm);
    gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);

    gen(tmp2, tmp2);
    if (logic_cc) {
        gen_logic_CC(tmp2);
    }
    return store_reg_kind(s, a->rd, tmp2, kind);
}

/*
 * Data-processing (immediate)
 *
 * Operate, with set flags, one register source,
 * one rotated immediate, and a destination.
 *
 * Note that logic_cc && a->rot setting CF based on the msb of the
 * immediate is the reason why we must pass in the unrotated form
 * of the immediate.
 */
static bool op_s_rri_rot(DisasContext *s, arg_s_rri_rot *a,
                         void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
                         int logic_cc, StoreRegKind kind)
{
    TCGv_i32 tmp1;
    uint32_t imm;

    imm = ror32(a->imm, a->rot);
    if (logic_cc && a->rot) {
        tcg_gen_movi_i32(cpu_CF, imm >> 31);
    }
    tmp1 = load_reg(s, a->rn);

    gen(tmp1, tmp1, tcg_constant_i32(imm));

    if (logic_cc) {
        gen_logic_CC(tmp1);
    }
    return store_reg_kind(s, a->rd, tmp1, kind);
}

static bool op_s_rxi_rot(DisasContext *s, arg_s_rri_rot *a,
                         void (*gen)(TCGv_i32, TCGv_i32),
                         int logic_cc, StoreRegKind kind)
{
    TCGv_i32 tmp;
    uint32_t imm;

    imm = ror32(a->imm, a->rot);
    if (logic_cc && a->rot) {
        tcg_gen_movi_i32(cpu_CF, imm >> 31);
    }

    tmp = tcg_temp_new_i32();
    gen(tmp, tcg_constant_i32(imm));

    if (logic_cc) {
        gen_logic_CC(tmp);
    }
    return store_reg_kind(s, a->rd, tmp, kind);
}

#define DO_ANY3(NAME, OP, L, K)                                         \
    static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a)  \
    { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); }      \
    static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a)  \
    { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); }      \
    static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a)   \
    { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }

#define DO_ANY2(NAME, OP, L, K)                                         \
    static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a)  \
    { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); }      \
    static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a)  \
    { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); }      \
    static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a)   \
    { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }

#define DO_CMP2(NAME, OP, L)                                            \
    static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a)  \
    { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); }                   \
    static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a)  \
    { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); }                   \
    static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a)   \
    { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }

DO_ANY3(AND, tcg_gen_and_i32, a->s, STREG_NORMAL)
DO_ANY3(EOR, tcg_gen_xor_i32, a->s, STREG_NORMAL)
DO_ANY3(ORR, tcg_gen_or_i32, a->s, STREG_NORMAL)
DO_ANY3(BIC, tcg_gen_andc_i32, a->s, STREG_NORMAL)

DO_ANY3(RSB, a->s ? gen_rsb_CC : gen_rsb, false, STREG_NORMAL)
DO_ANY3(ADC, a->s ? gen_adc_CC : gen_add_carry, false, STREG_NORMAL)
DO_ANY3(SBC, a->s ? gen_sbc_CC : gen_sub_carry, false, STREG_NORMAL)
DO_ANY3(RSC, a->s ? gen_rsc_CC : gen_rsc, false, STREG_NORMAL)

DO_CMP2(TST, tcg_gen_and_i32, true)
DO_CMP2(TEQ, tcg_gen_xor_i32, true)
DO_CMP2(CMN, gen_add_CC, false)
DO_CMP2(CMP, gen_sub_CC, false)

DO_ANY3(ADD, a->s ? gen_add_CC : tcg_gen_add_i32, false,
        a->rd == 13 && a->rn == 13 ? STREG_SP_CHECK : STREG_NORMAL)

/*
 * Note for the computation of StoreRegKind we return out of the
 * middle of the functions that are expanded by DO_ANY3, and that
 * we modify a->s via that parameter before it is used by OP.
 */
DO_ANY3(SUB, a->s ? gen_sub_CC : tcg_gen_sub_i32, false,
        ({
            StoreRegKind ret = STREG_NORMAL;
            if (a->rd == 15 && a->s) {
                /*
                 * See ALUExceptionReturn:
                 * In User mode, UNPREDICTABLE; we choose UNDEF.
                 * In Hyp mode, UNDEFINED.
                 */
                if (IS_USER(s) || s->current_el == 2) {
                    unallocated_encoding(s);
                    return true;
                }
                /* There is no writeback of nzcv to PSTATE.  */
                a->s = 0;
                ret = STREG_EXC_RET;
            } else if (a->rd == 13 && a->rn == 13) {
                ret = STREG_SP_CHECK;
            }
            ret;
        }))

DO_ANY2(MOV, tcg_gen_mov_i32, a->s,
        ({
            StoreRegKind ret = STREG_NORMAL;
            if (a->rd == 15 && a->s) {
                /*
                 * See ALUExceptionReturn:
                 * In User mode, UNPREDICTABLE; we choose UNDEF.
                 * In Hyp mode, UNDEFINED.
                 */
                if (IS_USER(s) || s->current_el == 2) {
                    unallocated_encoding(s);
                    return true;
                }
                /* There is no writeback of nzcv to PSTATE.  */
                a->s = 0;
                ret = STREG_EXC_RET;
            } else if (a->rd == 13) {
                ret = STREG_SP_CHECK;
            }
            ret;
        }))

DO_ANY2(MVN, tcg_gen_not_i32, a->s, STREG_NORMAL)

/*
 * ORN is only available with T32, so there is no register-shifted-register
 * form of the insn.  Using the DO_ANY3 macro would create an unused function.
 */
static bool trans_ORN_rrri(DisasContext *s, arg_s_rrr_shi *a)
{
    return op_s_rrr_shi(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
}

static bool trans_ORN_rri(DisasContext *s, arg_s_rri_rot *a)
{
    return op_s_rri_rot(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
}

#undef DO_ANY3
#undef DO_ANY2
#undef DO_CMP2

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

static bool trans_MOVW(DisasContext *s, arg_MOVW *a)
{
    if (!ENABLE_ARCH_6T2) {
        return false;
    }

    store_reg(s, a->rd, tcg_constant_i32(a->imm));
    return true;
}

static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
{
    TCGv_i32 tmp;

    if (!ENABLE_ARCH_6T2) {
        return false;
    }

    tmp = load_reg(s, a->rd);
    tcg_gen_ext16u_i32(tmp, tmp);
    tcg_gen_ori_i32(tmp, tmp, a->imm << 16);
    store_reg(s, a->rd, tmp);
    return true;
}

/*
 * v8.1M MVE wide-shifts
 */
static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
                          WideShiftImmFn *fn)
{
    TCGv_i64 rda;
    TCGv_i32 rdalo, rdahi;

    if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
        /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
        return false;
    }
    if (a->rdahi == 15) {
        /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
        return false;
    }
    if (!dc_isar_feature(aa32_mve, s) ||
        !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
        a->rdahi == 13) {
        /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
        unallocated_encoding(s);
        return true;
    }

    if (a->shim == 0) {
        a->shim = 32;
    }

    rda = tcg_temp_new_i64();
    rdalo = load_reg(s, a->rdalo);
    rdahi = load_reg(s, a->rdahi);
    tcg_gen_concat_i32_i64(rda, rdalo, rdahi);

    fn(rda, rda, a->shim);

    tcg_gen_extrl_i64_i32(rdalo, rda);
    tcg_gen_extrh_i64_i32(rdahi, rda);
    store_reg(s, a->rdalo, rdalo);
    store_reg(s, a->rdahi, rdahi);

    return true;
}

static bool trans_ASRL_ri(DisasContext *s, arg_mve_shl_ri *a)
{
    return do_mve_shl_ri(s, a, tcg_gen_sari_i64);
}

static bool trans_LSLL_ri(DisasContext *s, arg_mve_shl_ri *a)
{
    return do_mve_shl_ri(s, a, tcg_gen_shli_i64);
}

static bool trans_LSRL_ri(DisasContext *s, arg_mve_shl_ri *a)
{
    return do_mve_shl_ri(s, a, tcg_gen_shri_i64);
}

static void gen_mve_sqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
{
    gen_helper_mve_sqshll(r, tcg_env, n, tcg_constant_i32(shift));
}

static bool trans_SQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
{
    return do_mve_shl_ri(s, a, gen_mve_sqshll);
}

static void gen_mve_uqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
{
    gen_helper_mve_uqshll(r, tcg_env, n, tcg_constant_i32(shift));
}

static bool trans_UQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
{
    return do_mve_shl_ri(s, a, gen_mve_uqshll);
}

static bool trans_SRSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
{
    return do_mve_shl_ri(s, a, gen_srshr64_i64);
}

static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
{
    return do_mve_shl_ri(s, a, gen_urshr64_i64);
}

static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
{
    TCGv_i64 rda;
    TCGv_i32 rdalo, rdahi;

    if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
        /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
        return false;
    }
    if (a->rdahi == 15) {
        /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
        return false;
    }
    if (!dc_isar_feature(aa32_mve, s) ||
        !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
        a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
        a->rm == a->rdahi || a->rm == a->rdalo) {
        /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
        unallocated_encoding(s);
        return true;
    }

    rda = tcg_temp_new_i64();
    rdalo = load_reg(s, a->rdalo);
    rdahi = load_reg(s, a->rdahi);
    tcg_gen_concat_i32_i64(rda, rdalo, rdahi);

    /* The helper takes care of the sign-extension of the low 8 bits of Rm */
    fn(rda, tcg_env, rda, cpu_R[a->rm]);

    tcg_gen_extrl_i64_i32(rdalo, rda);
    tcg_gen_extrh_i64_i32(rdahi, rda);
    store_reg(s, a->rdalo, rdalo);
    store_reg(s, a->rdahi, rdahi);

    return true;
}

static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
{
    return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
}

static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
{
    return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
}

static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
{
    return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
}

static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
{
    return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
}

static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
{
    return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
}

static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
{
    return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
}

static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
{
    if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
        /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
        return false;
    }
    if (!dc_isar_feature(aa32_mve, s) ||
        !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
        a->rda == 13 || a->rda == 15) {
        /* These rda cases are UNPREDICTABLE; we choose to UNDEF */
        unallocated_encoding(s);
        return true;
    }

    if (a->shim == 0) {
        a->shim = 32;
    }
    fn(cpu_R[a->rda], cpu_R[a->rda], a->shim);

    return true;
}

static bool trans_URSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
{
    return do_mve_sh_ri(s, a, gen_urshr32_i32);
}

static bool trans_SRSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
{
    return do_mve_sh_ri(s, a, gen_srshr32_i32);
}

static void gen_mve_sqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
{
    gen_helper_mve_sqshl(r, tcg_env, n, tcg_constant_i32(shift));
}

static bool trans_SQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
{
    return do_mve_sh_ri(s, a, gen_mve_sqshl);
}

static void gen_mve_uqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
{
    gen_helper_mve_uqshl(r, tcg_env, n, tcg_constant_i32(shift));
}

static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
{
    return do_mve_sh_ri(s, a, gen_mve_uqshl);
}

static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
{
    if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
        /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
        return false;
    }
    if (!dc_isar_feature(aa32_mve, s) ||
        !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
        a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
        a->rm == a->rda) {
        /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
        unallocated_encoding(s);
        return true;
    }

    /* The helper takes care of the sign-extension of the low 8 bits of Rm */
    fn(cpu_R[a->rda], tcg_env, cpu_R[a->rda], cpu_R[a->rm]);
    return true;
}

static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
{
    return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
}

static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
{
    return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
}

/*
 * Multiply and multiply accumulate
 */

static bool op_mla(DisasContext *s, arg_s_rrrr *a, bool add)
{
    TCGv_i32 t1, t2;

    t1 = load_reg(s, a->rn);
    t2 = load_reg(s, a->rm);
    tcg_gen_mul_i32(t1, t1, t2);
    if (add) {
        t2 = load_reg(s, a->ra);
        tcg_gen_add_i32(t1, t1, t2);
    }
    if (a->s) {
        gen_logic_CC(t1);
    }
    store_reg(s, a->rd, t1);
    return true;
}

static bool trans_MUL(DisasContext *s, arg_MUL *a)
{
    return op_mla(s, a, false);
}

static bool trans_MLA(DisasContext *s, arg_MLA *a)
{
    return op_mla(s, a, true);
}

static bool trans_MLS(DisasContext *s, arg_MLS *a)
{
    TCGv_i32 t1, t2;

    if (!ENABLE_ARCH_6T2) {
        return false;
    }
    t1 = load_reg(s, a->rn);
    t2 = load_reg(s, a->rm);
    tcg_gen_mul_i32(t1, t1, t2);
    t2 = load_reg(s, a->ra);
    tcg_gen_sub_i32(t1, t2, t1);
    store_reg(s, a->rd, t1);
    return true;
}

static bool op_mlal(DisasContext *s, arg_s_rrrr *a, bool uns, bool add)
{
    TCGv_i32 t0, t1, t2, t3;

    t0 = load_reg(s, a->rm);
    t1 = load_reg(s, a->rn);
    if (uns) {
        tcg_gen_mulu2_i32(t0, t1, t0, t1);
    } else {
        tcg_gen_muls2_i32(t0, t1, t0, t1);
    }
    if (add) {
        t2 = load_reg(s, a->ra);
        t3 = load_reg(s, a->rd);
        tcg_gen_add2_i32(t0, t1, t0, t1, t2, t3);
    }
    if (a->s) {
        gen_logicq_cc(t0, t1);
    }
    store_reg(s, a->ra, t0);
    store_reg(s, a->rd, t1);
    return true;
}

static bool trans_UMULL(DisasContext *s, arg_UMULL *a)
{
    return op_mlal(s, a, true, false);
}

static bool trans_SMULL(DisasContext *s, arg_SMULL *a)
{
    return op_mlal(s, a, false, false);
}

static bool trans_UMLAL(DisasContext *s, arg_UMLAL *a)
{
    return op_mlal(s, a, true, true);
}

static bool trans_SMLAL(DisasContext *s, arg_SMLAL *a)
{
    return op_mlal(s, a, false, true);
}

static bool trans_UMAAL(DisasContext *s, arg_UMAAL *a)
{
    TCGv_i32 t0, t1, t2, zero;

    if (s->thumb
        ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
        : !ENABLE_ARCH_6) {
        return false;
    }

    t0 = load_reg(s, a->rm);
    t1 = load_reg(s, a->rn);
    tcg_gen_mulu2_i32(t0, t1, t0, t1);
    zero = tcg_constant_i32(0);
    t2 = load_reg(s, a->ra);
    tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
    t2 = load_reg(s, a->rd);
    tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
    store_reg(s, a->ra, t0);
    store_reg(s, a->rd, t1);
    return true;
}

/*
 * Saturating addition and subtraction
 */

static bool op_qaddsub(DisasContext *s, arg_rrr *a, bool add, bool doub)
{
    TCGv_i32 t0, t1;

    if (s->thumb
        ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
        : !ENABLE_ARCH_5TE) {
        return false;
    }

    t0 = load_reg(s, a->rm);
    t1 = load_reg(s, a->rn);
    if (doub) {
        gen_helper_add_saturate(t1, tcg_env, t1, t1);
    }
    if (add) {
        gen_helper_add_saturate(t0, tcg_env, t0, t1);
    } else {
        gen_helper_sub_saturate(t0, tcg_env, t0, t1);
    }
    store_reg(s, a->rd, t0);
    return true;
}

#define DO_QADDSUB(NAME, ADD, DOUB) \
static bool trans_##NAME(DisasContext *s, arg_rrr *a)    \
{                                                        \
    return op_qaddsub(s, a, ADD, DOUB);                  \
}

DO_QADDSUB(QADD, true, false)
DO_QADDSUB(QSUB, false, false)
DO_QADDSUB(QDADD, true, true)
DO_QADDSUB(QDSUB, false, true)

#undef DO_QADDSUB

/*
 * Halfword multiply and multiply accumulate
 */

static bool op_smlaxxx(DisasContext *s, arg_rrrr *a,
                       int add_long, bool nt, bool mt)
{
    TCGv_i32 t0, t1, tl, th;

    if (s->thumb
        ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
        : !ENABLE_ARCH_5TE) {
        return false;
    }

    t0 = load_reg(s, a->rn);
    t1 = load_reg(s, a->rm);
    gen_mulxy(t0, t1, nt, mt);

    switch (add_long) {
    case 0:
        store_reg(s, a->rd, t0);
        break;
    case 1:
        t1 = load_reg(s, a->ra);
        gen_helper_add_setq(t0, tcg_env, t0, t1);
        store_reg(s, a->rd, t0);
        break;
    case 2:
        tl = load_reg(s, a->ra);
        th = load_reg(s, a->rd);
        /* Sign-extend the 32-bit product to 64 bits.  */
        t1 = tcg_temp_new_i32();
        tcg_gen_sari_i32(t1, t0, 31);
        tcg_gen_add2_i32(tl, th, tl, th, t0, t1);
        store_reg(s, a->ra, tl);
        store_reg(s, a->rd, th);
        break;
    default:
        g_assert_not_reached();
    }
    return true;
}

#define DO_SMLAX(NAME, add, nt, mt) \
static bool trans_##NAME(DisasContext *s, arg_rrrr *a)     \
{                                                          \
    return op_smlaxxx(s, a, add, nt, mt);                  \
}

DO_SMLAX(SMULBB, 0, 0, 0)
DO_SMLAX(SMULBT, 0, 0, 1)
DO_SMLAX(SMULTB, 0, 1, 0)
DO_SMLAX(SMULTT, 0, 1, 1)

DO_SMLAX(SMLABB, 1, 0, 0)
DO_SMLAX(SMLABT, 1, 0, 1)
DO_SMLAX(SMLATB, 1, 1, 0)
DO_SMLAX(SMLATT, 1, 1, 1)

DO_SMLAX(SMLALBB, 2, 0, 0)
DO_SMLAX(SMLALBT, 2, 0, 1)
DO_SMLAX(SMLALTB, 2, 1, 0)
DO_SMLAX(SMLALTT, 2, 1, 1)

#undef DO_SMLAX

static bool op_smlawx(DisasContext *s, arg_rrrr *a, bool add, bool mt)
{
    TCGv_i32 t0, t1;

    if (!ENABLE_ARCH_5TE) {
        return false;
    }

    t0 = load_reg(s, a->rn);
    t1 = load_reg(s, a->rm);
    /*
     * Since the nominal result is product<47:16>, shift the 16-bit
     * input up by 16 bits, so that the result is at product<63:32>.
     */
    if (mt) {
        tcg_gen_andi_i32(t1, t1, 0xffff0000);
    } else {
        tcg_gen_shli_i32(t1, t1, 16);
    }
    tcg_gen_muls2_i32(t0, t1, t0, t1);
    if (add) {
        t0 = load_reg(s, a->ra);
        gen_helper_add_setq(t1, tcg_env, t1, t0);
    }
    store_reg(s, a->rd, t1);
    return true;
}

#define DO_SMLAWX(NAME, add, mt) \
static bool trans_##NAME(DisasContext *s, arg_rrrr *a)     \
{                                                          \
    return op_smlawx(s, a, add, mt);                       \
}

DO_SMLAWX(SMULWB, 0, 0)
DO_SMLAWX(SMULWT, 0, 1)
DO_SMLAWX(SMLAWB, 1, 0)
DO_SMLAWX(SMLAWT, 1, 1)

#undef DO_SMLAWX

/*
 * MSR (immediate) and hints
 */

static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
{
    /*
     * When running single-threaded TCG code, use the helper to ensure that
     * the next round-robin scheduled vCPU gets a crack.  When running in
     * MTTCG we don't generate jumps to the helper as it won't affect the
     * scheduling of other vCPUs.
     */
    if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
        gen_update_pc(s, curr_insn_len(s));
        s->base.is_jmp = DISAS_YIELD;
    }
    return true;
}

static bool trans_WFE(DisasContext *s, arg_WFE *a)
{
    /*
     * When running single-threaded TCG code, use the helper to ensure that
     * the next round-robin scheduled vCPU gets a crack.  In MTTCG mode we
     * just skip this instruction.  Currently the SEV/SEVL instructions,
     * which are *one* of many ways to wake the CPU from WFE, are not
     * implemented so we can't sleep like WFI does.
     */
    if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
        gen_update_pc(s, curr_insn_len(s));
        s->base.is_jmp = DISAS_WFE;
    }
    return true;
}

static bool trans_WFI(DisasContext *s, arg_WFI *a)
{
    /* For WFI, halt the vCPU until an IRQ. */
    gen_update_pc(s, curr_insn_len(s));
    s->base.is_jmp = DISAS_WFI;
    return true;
}

static bool trans_ESB(DisasContext *s, arg_ESB *a)
{
    /*
     * For M-profile, minimal-RAS ESB can be a NOP.
     * Without RAS, we must implement this as NOP.
     */
    if (!arm_dc_feature(s, ARM_FEATURE_M) && dc_isar_feature(aa32_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
         *      AArch32.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_NOP(DisasContext *s, arg_NOP *a)
{
    return true;
}

static bool trans_MSR_imm(DisasContext *s, arg_MSR_imm *a)
{
    uint32_t val = ror32(a->imm, a->rot * 2);
    uint32_t mask = msr_mask(s, a->mask, a->r);

    if (gen_set_psr_im(s, mask, a->r, val)) {
        unallocated_encoding(s);
    }
    return true;
}

/*
 * Cyclic Redundancy Check
 */

static bool op_crc32(DisasContext *s, arg_rrr *a, bool c, MemOp sz)
{
    TCGv_i32 t1, t2, t3;

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

    t1 = load_reg(s, a->rn);
    t2 = load_reg(s, a->rm);
    switch (sz) {
    case MO_8:
        gen_uxtb(t2);
        break;
    case MO_16:
        gen_uxth(t2);
        break;
    case MO_32:
        break;
    default:
        g_assert_not_reached();
    }
    t3 = tcg_constant_i32(1 << sz);
    if (c) {
        gen_helper_crc32c(t1, t1, t2, t3);
    } else {
        gen_helper_crc32(t1, t1, t2, t3);
    }
    store_reg(s, a->rd, t1);
    return true;
}

#define DO_CRC32(NAME, c, sz) \
static bool trans_##NAME(DisasContext *s, arg_rrr *a)  \
    { return op_crc32(s, a, c, sz); }

DO_CRC32(CRC32B, false, MO_8)
DO_CRC32(CRC32H, false, MO_16)
DO_CRC32(CRC32W, false, MO_32)
DO_CRC32(CRC32CB, true, MO_8)
DO_CRC32(CRC32CH, true, MO_16)
DO_CRC32(CRC32CW, true, MO_32)

#undef DO_CRC32

/*
 * Miscellaneous instructions
 */

static bool trans_MRS_bank(DisasContext *s, arg_MRS_bank *a)
{
    if (arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    gen_mrs_banked(s, a->r, a->sysm, a->rd);
    return true;
}

static bool trans_MSR_bank(DisasContext *s, arg_MSR_bank *a)
{
    if (arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    gen_msr_banked(s, a->r, a->sysm, a->rn);
    return true;
}

static bool trans_MRS_reg(DisasContext *s, arg_MRS_reg *a)
{
    TCGv_i32 tmp;

    if (arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    if (a->r) {
        if (IS_USER(s)) {
            unallocated_encoding(s);
            return true;
        }
        tmp = load_cpu_field(spsr);
    } else {
        tmp = tcg_temp_new_i32();
        gen_helper_cpsr_read(tmp, tcg_env);
    }
    store_reg(s, a->rd, tmp);
    return true;
}

static bool trans_MSR_reg(DisasContext *s, arg_MSR_reg *a)
{
    TCGv_i32 tmp;
    uint32_t mask = msr_mask(s, a->mask, a->r);

    if (arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    tmp = load_reg(s, a->rn);
    if (gen_set_psr(s, mask, a->r, tmp)) {
        unallocated_encoding(s);
    }
    return true;
}

static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
{
    TCGv_i32 tmp;

    if (!arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    tmp = tcg_temp_new_i32();
    gen_helper_v7m_mrs(tmp, tcg_env, tcg_constant_i32(a->sysm));
    store_reg(s, a->rd, tmp);
    return true;
}

static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
{
    TCGv_i32 addr, reg;

    if (!arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    addr = tcg_constant_i32((a->mask << 10) | a->sysm);
    reg = load_reg(s, a->rn);
    gen_helper_v7m_msr(tcg_env, addr, reg);
    /* If we wrote to CONTROL, the EL might have changed */
    gen_rebuild_hflags(s, true);
    gen_lookup_tb(s);
    return true;
}

static bool trans_BX(DisasContext *s, arg_BX *a)
{
    if (!ENABLE_ARCH_4T) {
        return false;
    }
    gen_bx_excret(s, load_reg(s, a->rm));
    return true;
}

static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
{
    if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    /*
     * v7A allows BXJ to be trapped via HSTR.TJDBX. We don't waste a
     * TBFLAGS bit on a basically-never-happens case, so call a helper
     * function to check for the trap and raise the exception if needed
     * (passing it the register number for the syndrome value).
     * v8A doesn't have this HSTR bit.
     */
    if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
        arm_dc_feature(s, ARM_FEATURE_EL2) &&
        s->current_el < 2 && s->ns) {
        gen_helper_check_bxj_trap(tcg_env, tcg_constant_i32(a->rm));
    }
    /* Trivial implementation equivalent to bx.  */
    gen_bx(s, load_reg(s, a->rm));
    return true;
}

static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
{
    TCGv_i32 tmp;

    if (!ENABLE_ARCH_5) {
        return false;
    }
    tmp = load_reg(s, a->rm);
    gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | s->thumb);
    gen_bx(s, tmp);
    return true;
}

/*
 * BXNS/BLXNS: only exist for v8M with the security extensions,
 * and always UNDEF if NonSecure.  We don't implement these in
 * the user-only mode either (in theory you can use them from
 * Secure User mode but they are too tied in to system emulation).
 */
static bool trans_BXNS(DisasContext *s, arg_BXNS *a)
{
    if (!s->v8m_secure || IS_USER_ONLY) {
        unallocated_encoding(s);
    } else {
        gen_bxns(s, a->rm);
    }
    return true;
}

static bool trans_BLXNS(DisasContext *s, arg_BLXNS *a)
{
    if (!s->v8m_secure || IS_USER_ONLY) {
        unallocated_encoding(s);
    } else {
        gen_blxns(s, a->rm);
    }
    return true;
}

static bool trans_CLZ(DisasContext *s, arg_CLZ *a)
{
    TCGv_i32 tmp;

    if (!ENABLE_ARCH_5) {
        return false;
    }
    tmp = load_reg(s, a->rm);
    tcg_gen_clzi_i32(tmp, tmp, 32);
    store_reg(s, a->rd, tmp);
    return true;
}

static bool trans_ERET(DisasContext *s, arg_ERET *a)
{
    TCGv_i32 tmp;

    if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
        return false;
    }
    if (IS_USER(s)) {
        unallocated_encoding(s);
        return true;
    }
    if (s->current_el == 2) {
        /* ERET from Hyp uses ELR_Hyp, not LR */
        tmp = load_cpu_field_low32(elr_el[2]);
    } else {
        tmp = load_reg(s, 14);
    }
    gen_exception_return(s, tmp);
    return true;
}

static bool trans_HLT(DisasContext *s, arg_HLT *a)
{
    gen_hlt(s, a->imm);
    return true;
}

static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
{
    if (!ENABLE_ARCH_5) {
        return false;
    }
    /* BKPT is OK with ECI set and leaves it untouched */
    s->eci_handled = true;
    if (arm_dc_feature(s, ARM_FEATURE_M) &&
        semihosting_enabled(s->current_el == 0) &&
        (a->imm == 0xab)) {
        gen_exception_internal_insn(s, EXCP_SEMIHOST);
    } else {
        gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
    }
    return true;
}

static bool trans_HVC(DisasContext *s, arg_HVC *a)
{
    if (!ENABLE_ARCH_7 || arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    if (IS_USER(s)) {
        unallocated_encoding(s);
    } else {
        gen_hvc(s, a->imm);
    }
    return true;
}

static bool trans_SMC(DisasContext *s, arg_SMC *a)
{
    if (!ENABLE_ARCH_6K || arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    if (IS_USER(s)) {
        unallocated_encoding(s);
    } else {
        gen_smc(s);
    }
    return true;
}

static bool trans_SG(DisasContext *s, arg_SG *a)
{
    if (!arm_dc_feature(s, ARM_FEATURE_M) ||
        !arm_dc_feature(s, ARM_FEATURE_V8)) {
        return false;
    }
    /*
     * SG (v8M only)
     * The bulk of the behaviour for this instruction is implemented
     * in v7m_handle_execute_nsc(), which deals with the insn when
     * it is executed by a CPU in non-secure state from memory
     * which is Secure & NonSecure-Callable.
     * Here we only need to handle the remaining cases:
     *  * in NS memory (including the "security extension not
     *    implemented" case) : NOP
     *  * in S memory but CPU already secure (clear IT bits)
     * We know that the attribute for the memory this insn is
     * in must match the current CPU state, because otherwise
     * get_phys_addr_pmsav8 would have generated an exception.
     */
    if (s->v8m_secure) {
        /* Like the IT insn, we don't need to generate any code */
        s->condexec_cond = 0;
        s->condexec_mask = 0;
    }
    return true;
}

static bool trans_TT(DisasContext *s, arg_TT *a)
{
    TCGv_i32 addr, tmp;

    if (!arm_dc_feature(s, ARM_FEATURE_M) ||
        !arm_dc_feature(s, ARM_FEATURE_V8)) {
        return false;
    }
    if (a->rd == 13 || a->rd == 15 || a->rn == 15) {
        /* We UNDEF for these UNPREDICTABLE cases */
        unallocated_encoding(s);
        return true;
    }
    if (a->A && !s->v8m_secure) {
        /* This case is UNDEFINED.  */
        unallocated_encoding(s);
        return true;
    }

    addr = load_reg(s, a->rn);
    tmp = tcg_temp_new_i32();
    gen_helper_v7m_tt(tmp, tcg_env, addr, tcg_constant_i32((a->A << 1) | a->T));
    store_reg(s, a->rd, tmp);
    return true;
}

/*
 * Load/store register index
 */

static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
{
    ISSInfo ret;

    /* ISS not valid if writeback */
    if (p && !w) {
        ret = rd;
        if (curr_insn_len(s) == 2) {
            ret |= ISSIs16Bit;
        }
    } else {
        ret = ISSInvalid;
    }
    return ret;
}

static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
{
    TCGv_i32 addr = load_reg(s, a->rn);

    if (s->v8m_stackcheck && a->rn == 13 && a->w) {
        gen_helper_v8m_stackcheck(tcg_env, addr);
    }

    if (a->p) {
        TCGv_i32 ofs = load_reg(s, a->rm);
        gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
        if (a->u) {
            tcg_gen_add_i32(addr, addr, ofs);
        } else {
            tcg_gen_sub_i32(addr, addr, ofs);
        }
    }
    return addr;
}

static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
                            TCGv_i32 addr)
{
    if (!a->p) {
        TCGv_i32 ofs = load_reg(s, a->rm);
        gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
        if (a->u) {
            tcg_gen_add_i32(addr, addr, ofs);
        } else {
            tcg_gen_sub_i32(addr, addr, ofs);
        }
    } else if (!a->w) {
        return;
    }
    store_reg(s, a->rn, addr);
}

static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
                       MemOp mop, int mem_idx)
{
    ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
    TCGv_i32 addr, tmp;

    addr = op_addr_rr_pre(s, a);

    tmp = tcg_temp_new_i32();
    gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
    disas_set_da_iss(s, mop, issinfo);

    /*
     * Perform base writeback before the loaded value to
     * ensure correct behavior with overlapping index registers.
     */
    op_addr_rr_post(s, a, addr);
    store_reg_from_load(s, a->rt, tmp);
    return true;
}

static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
                        MemOp mop, int mem_idx)
{
    ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
    TCGv_i32 addr, tmp;

    /*
     * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
     * is either UNPREDICTABLE or has defined behaviour
     */
    if (s->thumb && a->rn == 15) {
        return false;
    }

    addr = op_addr_rr_pre(s, a);

    tmp = load_reg(s, a->rt);
    gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
    disas_set_da_iss(s, mop, issinfo);

    op_addr_rr_post(s, a, addr);
    return true;
}

static void do_ldrd_load(DisasContext *s, TCGv_i32 addr, int rt, int rt2)
{
    /*
     * LDRD is required to be an atomic 64-bit access if the
     * address is 8-aligned, two atomic 32-bit accesses if
     * it's only 4-aligned, and to give an alignment fault
     * if it's not 4-aligned. This is MO_ALIGN_4 | MO_ATOM_SUBALIGN.
     * Rt is always the word from the lower address, and Rt2 the
     * data from the higher address, regardless of endianness.
     * So (like gen_load_exclusive) we avoid gen_aa32_ld_i64()
     * so we don't get its SCTLR_B check, and instead do a 64-bit access
     * using MO_BE if appropriate and then split the two halves.
     *
     * For M-profile, and for A-profile before LPAE, the 64-bit
     * atomicity is not required. We could model that using
     * the looser MO_ATOM_IFALIGN_PAIR, but providing a higher
     * level of atomicity than required is harmless (we would not
     * currently generate better code for IFALIGN_PAIR here).
     *
     * This also gives us the correct behaviour of not updating
     * rt if the load of rt2 faults; this is required for cases
     * like "ldrd r2, r3, [r2]" where rt is also the base register.
     */
    int mem_idx = get_mem_index(s);
    MemOp opc = MO_64 | MO_ALIGN_4 | MO_ATOM_SUBALIGN | s->be_data;
    TCGv taddr = gen_aa32_addr(s, addr, opc);
    TCGv_i64 t64 = tcg_temp_new_i64();
    TCGv_i32 tmp = tcg_temp_new_i32();
    TCGv_i32 tmp2 = tcg_temp_new_i32();

    tcg_gen_qemu_ld_i64(t64, taddr, mem_idx, opc);
    if (s->be_data == MO_BE) {
        tcg_gen_extr_i64_i32(tmp2, tmp, t64);
    } else {
        tcg_gen_extr_i64_i32(tmp, tmp2, t64);
    }
    store_reg(s, rt, tmp);
    store_reg(s, rt2, tmp2);
}

static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
{
    TCGv_i32 addr;

    if (!ENABLE_ARCH_5TE) {
        return false;
    }
    if (a->rt & 1) {
        unallocated_encoding(s);
        return true;
    }
    addr = op_addr_rr_pre(s, a);

    do_ldrd_load(s, addr, a->rt, a->rt + 1);

    /* LDRD w/ base writeback is undefined if the registers overlap.  */
    op_addr_rr_post(s, a, addr);
    return true;
}

static void do_strd_store(DisasContext *s, TCGv_i32 addr, int rt, int rt2)
{
    /*
     * STRD is required to be an atomic 64-bit access if the
     * address is 8-aligned, two atomic 32-bit accesses if
     * it's only 4-aligned, and to give an alignment fault
     * if it's not 4-aligned.
     * Rt is always the word from the lower address, and Rt2 the
     * data from the higher address, regardless of endianness.
     * So (like gen_store_exclusive) we avoid gen_aa32_ld_i64()
     * so we don't get its SCTLR_B check, and instead do a 64-bit access
     * using MO_BE if appropriate, using a value constructed
     * by putting the two halves together in the right order.
     *
     * As with LDRD, the 64-bit atomicity is not required for
     * M-profile, or for A-profile before LPAE, and we provide
     * the higher guarantee always for simplicity.
     */
    int mem_idx = get_mem_index(s);
    MemOp opc = MO_64 | MO_ALIGN_4 | MO_ATOM_SUBALIGN | s->be_data;
    TCGv taddr = gen_aa32_addr(s, addr, opc);
    TCGv_i32 t1 = load_reg(s, rt);
    TCGv_i32 t2 = load_reg(s, rt2);
    TCGv_i64 t64 = tcg_temp_new_i64();

    if (s->be_data == MO_BE) {
        tcg_gen_concat_i32_i64(t64, t2, t1);
    } else {
        tcg_gen_concat_i32_i64(t64, t1, t2);
    }
    tcg_gen_qemu_st_i64(t64, taddr, mem_idx, opc);
}

static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
{
    TCGv_i32 addr;

    if (!ENABLE_ARCH_5TE) {
        return false;
    }
    if (a->rt & 1) {
        unallocated_encoding(s);
        return true;
    }
    addr = op_addr_rr_pre(s, a);

    do_strd_store(s, addr, a->rt, a->rt + 1);

    op_addr_rr_post(s, a, addr);
    return true;
}

/*
 * Load/store immediate index
 */

static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
{
    int ofs = a->imm;

    if (!a->u) {
        ofs = -ofs;
    }

    if (s->v8m_stackcheck && a->rn == 13 && a->w) {
        /*
         * Stackcheck. Here we know 'addr' is the current SP;
         * U is set if we're moving SP up, else down. It is
         * UNKNOWN whether the limit check triggers when SP starts
         * below the limit and ends up above it; we chose to do so.
         */
        if (!a->u) {
            TCGv_i32 newsp = tcg_temp_new_i32();
            tcg_gen_addi_i32(newsp, cpu_R[13], ofs);
            gen_helper_v8m_stackcheck(tcg_env, newsp);
        } else {
            gen_helper_v8m_stackcheck(tcg_env, cpu_R[13]);
        }
    }

    return add_reg_for_lit(s, a->rn, a->p ? ofs : 0);
}

static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
                            TCGv_i32 addr)
{
    int address_offset = 0;
    if (!a->p) {
        if (a->u) {
            address_offset = a->imm;
        } else {
            address_offset = -a->imm;
        }
    } else if (!a->w) {
        return;
    }
    tcg_gen_addi_i32(addr, addr, address_offset);
    store_reg(s, a->rn, addr);
}

static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
                       MemOp mop, int mem_idx)
{
    ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
    TCGv_i32 addr, tmp;

    addr = op_addr_ri_pre(s, a);

    tmp = tcg_temp_new_i32();
    gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
    disas_set_da_iss(s, mop, issinfo);

    /*
     * Perform base writeback before the loaded value to
     * ensure correct behavior with overlapping index registers.
     */
    op_addr_ri_post(s, a, addr);
    store_reg_from_load(s, a->rt, tmp);
    return true;
}

static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
                        MemOp mop, int mem_idx)
{
    ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
    TCGv_i32 addr, tmp;

    /*
     * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
     * is either UNPREDICTABLE or has defined behaviour
     */
    if (s->thumb && a->rn == 15) {
        return false;
    }

    addr = op_addr_ri_pre(s, a);

    tmp = load_reg(s, a->rt);
    gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
    disas_set_da_iss(s, mop, issinfo);

    op_addr_ri_post(s, a, addr);
    return true;
}

static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
{
    TCGv_i32 addr;

    addr = op_addr_ri_pre(s, a);

    do_ldrd_load(s, addr, a->rt, rt2);

    /* LDRD w/ base writeback is undefined if the registers overlap.  */
    op_addr_ri_post(s, a, addr);
    return true;
}

static bool trans_LDRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
{
    if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
        return false;
    }
    return op_ldrd_ri(s, a, a->rt + 1);
}

static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
{
    arg_ldst_ri b = {
        .u = a->u, .w = a->w, .p = a->p,
        .rn = a->rn, .rt = a->rt, .imm = a->imm
    };
    return op_ldrd_ri(s, &b, a->rt2);
}

static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
{
    TCGv_i32 addr;

    addr = op_addr_ri_pre(s, a);

    do_strd_store(s, addr, a->rt, rt2);

    op_addr_ri_post(s, a, addr);
    return true;
}

static bool trans_STRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
{
    if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
        return false;
    }
    return op_strd_ri(s, a, a->rt + 1);
}

static bool trans_STRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
{
    arg_ldst_ri b = {
        .u = a->u, .w = a->w, .p = a->p,
        .rn = a->rn, .rt = a->rt, .imm = a->imm
    };
    return op_strd_ri(s, &b, a->rt2);
}

#define DO_LDST(NAME, WHICH, MEMOP) \
static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a)        \
{                                                                     \
    return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s));            \
}                                                                     \
static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a)       \
{                                                                     \
    return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s));   \
}                                                                     \
static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a)        \
{                                                                     \
    return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s));            \
}                                                                     \
static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a)       \
{                                                                     \
    return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s));   \
}

DO_LDST(LDR, load, MO_UL)
DO_LDST(LDRB, load, MO_UB)
DO_LDST(LDRH, load, MO_UW)
DO_LDST(LDRSB, load, MO_SB)
DO_LDST(LDRSH, load, MO_SW)

DO_LDST(STR, store, MO_UL)
DO_LDST(STRB, store, MO_UB)
DO_LDST(STRH, store, MO_UW)

#undef DO_LDST

/*
 * Synchronization primitives
 */

static bool op_swp(DisasContext *s, arg_SWP *a, MemOp opc)
{
    TCGv_i32 addr, tmp;
    TCGv taddr;

    opc |= s->be_data;
    addr = load_reg(s, a->rn);
    taddr = gen_aa32_addr(s, addr, opc);

    tmp = load_reg(s, a->rt2);
    tcg_gen_atomic_xchg_i32(tmp, taddr, tmp, get_mem_index(s), opc);

    store_reg(s, a->rt, tmp);
    return true;
}

static bool trans_SWP(DisasContext *s, arg_SWP *a)
{
    return op_swp(s, a, MO_UL | MO_ALIGN);
}

static bool trans_SWPB(DisasContext *s, arg_SWP *a)
{
    return op_swp(s, a, MO_UB);
}

/*
 * Load/Store Exclusive and Load-Acquire/Store-Release
 */

static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel)
{
    TCGv_i32 addr;
    /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
    bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);

    /* We UNDEF for these UNPREDICTABLE cases.  */
    if (a->rd == 15 || a->rn == 15 || a->rt == 15
        || a->rd == a->rn || a->rd == a->rt
        || (!v8a && s->thumb && (a->rd == 13 || a->rt == 13))
        || (mop == MO_64
            && (a->rt2 == 15
                || a->rd == a->rt2
                || (!v8a && s->thumb && a->rt2 == 13)))) {
        unallocated_encoding(s);
        return true;
    }

    if (rel) {
        tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
    }

    addr = tcg_temp_new_i32();
    load_reg_var(s, addr, a->rn);
    tcg_gen_addi_i32(addr, addr, a->imm);

    gen_store_exclusive(s, a->rd, a->rt, a->rt2, addr, mop);
    return true;
}

static bool trans_STREX(DisasContext *s, arg_STREX *a)
{
    if (!ENABLE_ARCH_6) {
        return false;
    }
    return op_strex(s, a, MO_32, false);
}

static bool trans_STREXD_a32(DisasContext *s, arg_STREX *a)
{
    if (!ENABLE_ARCH_6K) {
        return false;
    }
    /* We UNDEF for these UNPREDICTABLE cases.  */
    if (a->rt & 1) {
        unallocated_encoding(s);
        return true;
    }
    a->rt2 = a->rt + 1;
    return op_strex(s, a, MO_64, false);
}

static bool trans_STREXD_t32(DisasContext *s, arg_STREX *a)
{
    return op_strex(s, a, MO_64, false);
}

static bool trans_STREXB(DisasContext *s, arg_STREX *a)
{
    if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
        return false;
    }
    return op_strex(s, a, MO_8, false);
}

static bool trans_STREXH(DisasContext *s, arg_STREX *a)
{
    if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
        return false;
    }
    return op_strex(s, a, MO_16, false);
}

static bool trans_STLEX(DisasContext *s, arg_STREX *a)
{
    if (!ENABLE_ARCH_8) {
        return false;
    }
    return op_strex(s, a, MO_32, true);
}

static bool trans_STLEXD_a32(DisasContext *s, arg_STREX *a)
{
    if (!ENABLE_ARCH_8) {
        return false;
    }
    /* We UNDEF for these UNPREDICTABLE cases.  */
    if (a->rt & 1) {
        unallocated_encoding(s);
        return true;
    }
    a->rt2 = a->rt + 1;
    return op_strex(s, a, MO_64, true);
}

static bool trans_STLEXD_t32(DisasContext *s, arg_STREX *a)
{
    if (!ENABLE_ARCH_8) {
        return false;
    }
    return op_strex(s, a, MO_64, true);
}

static bool trans_STLEXB(DisasContext *s, arg_STREX *a)
{
    if (!ENABLE_ARCH_8) {
        return false;
    }
    return op_strex(s, a, MO_8, true);
}

static bool trans_STLEXH(DisasContext *s, arg_STREX *a)
{
    if (!ENABLE_ARCH_8) {
        return false;
    }
    return op_strex(s, a, MO_16, true);
}

static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
{
    TCGv_i32 addr, tmp;

    if (!ENABLE_ARCH_8) {
        return false;
    }
    /* We UNDEF for these UNPREDICTABLE cases.  */
    if (a->rn == 15 || a->rt == 15) {
        unallocated_encoding(s);
        return true;
    }

    addr = load_reg(s, a->rn);
    tmp = load_reg(s, a->rt);
    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
    gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | MO_ALIGN);
    disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);

    return true;
}

static bool trans_STL(DisasContext *s, arg_STL *a)
{
    return op_stl(s, a, MO_UL);
}

static bool trans_STLB(DisasContext *s, arg_STL *a)
{
    return op_stl(s, a, MO_UB);
}

static bool trans_STLH(DisasContext *s, arg_STL *a)
{
    return op_stl(s, a, MO_UW);
}

static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq)
{
    TCGv_i32 addr;
    /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
    bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);

    /* We UNDEF for these UNPREDICTABLE cases.  */
    if (a->rn == 15 || a->rt == 15
        || (!v8a && s->thumb && a->rt == 13)
        || (mop == MO_64
            && (a->rt2 == 15 || a->rt == a->rt2
                || (!v8a && s->thumb && a->rt2 == 13)))) {
        unallocated_encoding(s);
        return true;
    }

    addr = tcg_temp_new_i32();
    load_reg_var(s, addr, a->rn);
    tcg_gen_addi_i32(addr, addr, a->imm);

    gen_load_exclusive(s, a->rt, a->rt2, addr, mop);

    if (acq) {
        tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
    }
    return true;
}

static bool trans_LDREX(DisasContext *s, arg_LDREX *a)
{
    if (!ENABLE_ARCH_6) {
        return false;
    }
    return op_ldrex(s, a, MO_32, false);
}

static bool trans_LDREXD_a32(DisasContext *s, arg_LDREX *a)
{
    if (!ENABLE_ARCH_6K) {
        return false;
    }
    /* We UNDEF for these UNPREDICTABLE cases.  */
    if (a->rt & 1) {
        unallocated_encoding(s);
        return true;
    }
    a->rt2 = a->rt + 1;
    return op_ldrex(s, a, MO_64, false);
}

static bool trans_LDREXD_t32(DisasContext *s, arg_LDREX *a)
{
    return op_ldrex(s, a, MO_64, false);
}

static bool trans_LDREXB(DisasContext *s, arg_LDREX *a)
{
    if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
        return false;
    }
    return op_ldrex(s, a, MO_8, false);
}

static bool trans_LDREXH(DisasContext *s, arg_LDREX *a)
{
    if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
        return false;
    }
    return op_ldrex(s, a, MO_16, false);
}

static bool trans_LDAEX(DisasContext *s, arg_LDREX *a)
{
    if (!ENABLE_ARCH_8) {
        return false;
    }
    return op_ldrex(s, a, MO_32, true);
}

static bool trans_LDAEXD_a32(DisasContext *s, arg_LDREX *a)
{
    if (!ENABLE_ARCH_8) {
        return false;
    }
    /* We UNDEF for these UNPREDICTABLE cases.  */
    if (a->rt & 1) {
        unallocated_encoding(s);
        return true;
    }
    a->rt2 = a->rt + 1;
    return op_ldrex(s, a, MO_64, true);
}

static bool trans_LDAEXD_t32(DisasContext *s, arg_LDREX *a)
{
    if (!ENABLE_ARCH_8) {
        return false;
    }
    return op_ldrex(s, a, MO_64, true);
}

static bool trans_LDAEXB(DisasContext *s, arg_LDREX *a)
{
    if (!ENABLE_ARCH_8) {
        return false;
    }
    return op_ldrex(s, a, MO_8, true);
}

static bool trans_LDAEXH(DisasContext *s, arg_LDREX *a)
{
    if (!ENABLE_ARCH_8) {
        return false;
    }
    return op_ldrex(s, a, MO_16, true);
}

static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
{
    TCGv_i32 addr, tmp;

    if (!ENABLE_ARCH_8) {
        return false;
    }
    /* We UNDEF for these UNPREDICTABLE cases.  */
    if (a->rn == 15 || a->rt == 15) {
        unallocated_encoding(s);
        return true;
    }

    addr = load_reg(s, a->rn);
    tmp = tcg_temp_new_i32();
    gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | MO_ALIGN);
    disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);

    store_reg(s, a->rt, tmp);
    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
    return true;
}

static bool trans_LDA(DisasContext *s, arg_LDA *a)
{
    return op_lda(s, a, MO_UL);
}

static bool trans_LDAB(DisasContext *s, arg_LDA *a)
{
    return op_lda(s, a, MO_UB);
}

static bool trans_LDAH(DisasContext *s, arg_LDA *a)
{
    return op_lda(s, a, MO_UW);
}

/*
 * Media instructions
 */

static bool trans_USADA8(DisasContext *s, arg_USADA8 *a)
{
    TCGv_i32 t1, t2;

    if (!ENABLE_ARCH_6) {
        return false;
    }

    t1 = load_reg(s, a->rn);
    t2 = load_reg(s, a->rm);
    gen_helper_usad8(t1, t1, t2);
    if (a->ra != 15) {
        t2 = load_reg(s, a->ra);
        tcg_gen_add_i32(t1, t1, t2);
    }
    store_reg(s, a->rd, t1);
    return true;
}

static bool op_bfx(DisasContext *s, arg_UBFX *a, bool u)
{
    TCGv_i32 tmp;
    int width = a->widthm1 + 1;
    int shift = a->lsb;

    if (!ENABLE_ARCH_6T2) {
        return false;
    }
    if (shift + width > 32) {
        /* UNPREDICTABLE; we choose to UNDEF */
        unallocated_encoding(s);
        return true;
    }

    tmp = load_reg(s, a->rn);
    if (u) {
        tcg_gen_extract_i32(tmp, tmp, shift, width);
    } else {
        tcg_gen_sextract_i32(tmp, tmp, shift, width);
    }
    store_reg(s, a->rd, tmp);
    return true;
}

static bool trans_SBFX(DisasContext *s, arg_SBFX *a)
{
    return op_bfx(s, a, false);
}

static bool trans_UBFX(DisasContext *s, arg_UBFX *a)
{
    return op_bfx(s, a, true);
}

static bool trans_BFCI(DisasContext *s, arg_BFCI *a)
{
    int msb = a->msb, lsb = a->lsb;
    TCGv_i32 t_in, t_rd;
    int width;

    if (!ENABLE_ARCH_6T2) {
        return false;
    }
    if (msb < lsb) {
        /* UNPREDICTABLE; we choose to UNDEF */
        unallocated_encoding(s);
        return true;
    }

    width = msb + 1 - lsb;
    if (a->rn == 15) {
        /* BFC */
        t_in = tcg_constant_i32(0);
    } else {
        /* BFI */
        t_in = load_reg(s, a->rn);
    }
    t_rd = load_reg(s, a->rd);
    tcg_gen_deposit_i32(t_rd, t_rd, t_in, lsb, width);
    store_reg(s, a->rd, t_rd);
    return true;
}

static bool trans_UDF(DisasContext *s, arg_UDF *a)
{
    unallocated_encoding(s);
    return true;
}

/*
 * Parallel addition and subtraction
 */

static bool op_par_addsub(DisasContext *s, arg_rrr *a,
                          void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
{
    TCGv_i32 t0, t1;

    if (s->thumb
        ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
        : !ENABLE_ARCH_6) {
        return false;
    }

    t0 = load_reg(s, a->rn);
    t1 = load_reg(s, a->rm);

    gen(t0, t0, t1);

    store_reg(s, a->rd, t0);
    return true;
}

static bool op_par_addsub_ge(DisasContext *s, arg_rrr *a,
                             void (*gen)(TCGv_i32, TCGv_i32,
                                         TCGv_i32, TCGv_ptr))
{
    TCGv_i32 t0, t1;
    TCGv_ptr ge;

    if (s->thumb
        ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
        : !ENABLE_ARCH_6) {
        return false;
    }

    t0 = load_reg(s, a->rn);
    t1 = load_reg(s, a->rm);

    ge = tcg_temp_new_ptr();
    tcg_gen_addi_ptr(ge, tcg_env, offsetof(CPUARMState, GE));
    gen(t0, t0, t1, ge);

    store_reg(s, a->rd, t0);
    return true;
}

#define DO_PAR_ADDSUB(NAME, helper) \
static bool trans_##NAME(DisasContext *s, arg_rrr *a)   \
{                                                       \
    return op_par_addsub(s, a, helper);                 \
}

#define DO_PAR_ADDSUB_GE(NAME, helper) \
static bool trans_##NAME(DisasContext *s, arg_rrr *a)   \
{                                                       \
    return op_par_addsub_ge(s, a, helper);              \
}

DO_PAR_ADDSUB_GE(SADD16, gen_helper_sadd16)
DO_PAR_ADDSUB_GE(SASX, gen_helper_saddsubx)
DO_PAR_ADDSUB_GE(SSAX, gen_helper_ssubaddx)
DO_PAR_ADDSUB_GE(SSUB16, gen_helper_ssub16)
DO_PAR_ADDSUB_GE(SADD8, gen_helper_sadd8)
DO_PAR_ADDSUB_GE(SSUB8, gen_helper_ssub8)

DO_PAR_ADDSUB_GE(UADD16, gen_helper_uadd16)
DO_PAR_ADDSUB_GE(UASX, gen_helper_uaddsubx)
DO_PAR_ADDSUB_GE(USAX, gen_helper_usubaddx)
DO_PAR_ADDSUB_GE(USUB16, gen_helper_usub16)
DO_PAR_ADDSUB_GE(UADD8, gen_helper_uadd8)
DO_PAR_ADDSUB_GE(USUB8, gen_helper_usub8)

DO_PAR_ADDSUB(QADD16, gen_helper_qadd16)
DO_PAR_ADDSUB(QASX, gen_helper_qaddsubx)
DO_PAR_ADDSUB(QSAX, gen_helper_qsubaddx)
DO_PAR_ADDSUB(QSUB16, gen_helper_qsub16)
DO_PAR_ADDSUB(QADD8, gen_helper_qadd8)
DO_PAR_ADDSUB(QSUB8, gen_helper_qsub8)

DO_PAR_ADDSUB(UQADD16, gen_helper_uqadd16)
DO_PAR_ADDSUB(UQASX, gen_helper_uqaddsubx)
DO_PAR_ADDSUB(UQSAX, gen_helper_uqsubaddx)
DO_PAR_ADDSUB(UQSUB16, gen_helper_uqsub16)
DO_PAR_ADDSUB(UQADD8, gen_helper_uqadd8)
DO_PAR_ADDSUB(UQSUB8, gen_helper_uqsub8)

DO_PAR_ADDSUB(SHADD16, gen_helper_shadd16)
DO_PAR_ADDSUB(SHASX, gen_helper_shaddsubx)
DO_PAR_ADDSUB(SHSAX, gen_helper_shsubaddx)
DO_PAR_ADDSUB(SHSUB16, gen_helper_shsub16)
DO_PAR_ADDSUB(SHADD8, gen_helper_shadd8)
DO_PAR_ADDSUB(SHSUB8, gen_helper_shsub8)

DO_PAR_ADDSUB(UHADD16, gen_helper_uhadd16)
DO_PAR_ADDSUB(UHASX, gen_helper_uhaddsubx)
DO_PAR_ADDSUB(UHSAX, gen_helper_uhsubaddx)
DO_PAR_ADDSUB(UHSUB16, gen_helper_uhsub16)
DO_PAR_ADDSUB(UHADD8, gen_helper_uhadd8)
DO_PAR_ADDSUB(UHSUB8, gen_helper_uhsub8)

#undef DO_PAR_ADDSUB
#undef DO_PAR_ADDSUB_GE

/*
 * Packing, unpacking, saturation, and reversal
 */

static bool trans_PKH(DisasContext *s, arg_PKH *a)
{
    TCGv_i32 tn, tm;
    int shift = a->imm;

    if (s->thumb
        ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
        : !ENABLE_ARCH_6) {
        return false;
    }

    tn = load_reg(s, a->rn);
    tm = load_reg(s, a->rm);
    if (a->tb) {
        /* PKHTB */
        if (shift == 0) {
            shift = 31;
        }
        tcg_gen_sari_i32(tm, tm, shift);
        tcg_gen_deposit_i32(tn, tn, tm, 0, 16);
    } else {
        /* PKHBT */
        tcg_gen_shli_i32(tm, tm, shift);
        tcg_gen_deposit_i32(tn, tm, tn, 0, 16);
    }
    store_reg(s, a->rd, tn);
    return true;
}

static bool op_sat(DisasContext *s, arg_sat *a,
                   void (*gen)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
{
    TCGv_i32 tmp;
    int shift = a->imm;

    if (!ENABLE_ARCH_6) {
        return false;
    }

    tmp = load_reg(s, a->rn);
    if (a->sh) {
        tcg_gen_sari_i32(tmp, tmp, shift ? shift : 31);
    } else {
        tcg_gen_shli_i32(tmp, tmp, shift);
    }

    gen(tmp, tcg_env, tmp, tcg_constant_i32(a->satimm));

    store_reg(s, a->rd, tmp);
    return true;
}

static bool trans_SSAT(DisasContext *s, arg_sat *a)
{
    return op_sat(s, a, gen_helper_ssat);
}

static bool trans_USAT(DisasContext *s, arg_sat *a)
{
    return op_sat(s, a, gen_helper_usat);
}

static bool trans_SSAT16(DisasContext *s, arg_sat *a)
{
    if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
        return false;
    }
    return op_sat(s, a, gen_helper_ssat16);
}

static bool trans_USAT16(DisasContext *s, arg_sat *a)
{
    if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
        return false;
    }
    return op_sat(s, a, gen_helper_usat16);
}

static bool op_xta(DisasContext *s, arg_rrr_rot *a,
                   void (*gen_extract)(TCGv_i32, TCGv_i32),
                   void (*gen_add)(TCGv_i32, TCGv_i32, TCGv_i32))
{
    TCGv_i32 tmp;

    if (!ENABLE_ARCH_6) {
        return false;
    }

    tmp = load_reg(s, a->rm);
    /*
     * TODO: In many cases we could do a shift instead of a rotate.
     * Combined with a simple extend, that becomes an extract.
     */
    tcg_gen_rotri_i32(tmp, tmp, a->rot * 8);
    gen_extract(tmp, tmp);

    if (a->rn != 15) {
        TCGv_i32 tmp2 = load_reg(s, a->rn);
        gen_add(tmp, tmp, tmp2);
    }
    store_reg(s, a->rd, tmp);
    return true;
}

static bool trans_SXTAB(DisasContext *s, arg_rrr_rot *a)
{
    return op_xta(s, a, tcg_gen_ext8s_i32, tcg_gen_add_i32);
}

static bool trans_SXTAH(DisasContext *s, arg_rrr_rot *a)
{
    return op_xta(s, a, tcg_gen_ext16s_i32, tcg_gen_add_i32);
}

static bool trans_SXTAB16(DisasContext *s, arg_rrr_rot *a)
{
    if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
        return false;
    }
    return op_xta(s, a, gen_helper_sxtb16, gen_add16);
}

static bool trans_UXTAB(DisasContext *s, arg_rrr_rot *a)
{
    return op_xta(s, a, tcg_gen_ext8u_i32, tcg_gen_add_i32);
}

static bool trans_UXTAH(DisasContext *s, arg_rrr_rot *a)
{
    return op_xta(s, a, tcg_gen_ext16u_i32, tcg_gen_add_i32);
}

static bool trans_UXTAB16(DisasContext *s, arg_rrr_rot *a)
{
    if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
        return false;
    }
    return op_xta(s, a, gen_helper_uxtb16, gen_add16);
}

static bool trans_SEL(DisasContext *s, arg_rrr *a)
{
    TCGv_i32 t1, t2, t3;

    if (s->thumb
        ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
        : !ENABLE_ARCH_6) {
        return false;
    }

    t1 = load_reg(s, a->rn);
    t2 = load_reg(s, a->rm);
    t3 = tcg_temp_new_i32();
    tcg_gen_ld_i32(t3, tcg_env, offsetof(CPUARMState, GE));
    gen_helper_sel_flags(t1, t3, t1, t2);
    store_reg(s, a->rd, t1);
    return true;
}

static bool op_rr(DisasContext *s, arg_rr *a,
                  void (*gen)(TCGv_i32, TCGv_i32))
{
    TCGv_i32 tmp;

    tmp = load_reg(s, a->rm);
    gen(tmp, tmp);
    store_reg(s, a->rd, tmp);
    return true;
}

static bool trans_REV(DisasContext *s, arg_rr *a)
{
    if (!ENABLE_ARCH_6) {
        return false;
    }
    return op_rr(s, a, tcg_gen_bswap32_i32);
}

static bool trans_REV16(DisasContext *s, arg_rr *a)
{
    if (!ENABLE_ARCH_6) {
        return false;
    }
    return op_rr(s, a, gen_rev16);
}

static bool trans_REVSH(DisasContext *s, arg_rr *a)
{
    if (!ENABLE_ARCH_6) {
        return false;
    }
    return op_rr(s, a, gen_revsh);
}

static bool trans_RBIT(DisasContext *s, arg_rr *a)
{
    if (!ENABLE_ARCH_6T2) {
        return false;
    }
    return op_rr(s, a, gen_helper_rbit);
}

/*
 * Signed multiply, signed and unsigned divide
 */

static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
{
    TCGv_i32 t1, t2;

    if (!ENABLE_ARCH_6) {
        return false;
    }

    t1 = load_reg(s, a->rn);
    t2 = load_reg(s, a->rm);
    if (m_swap) {
        gen_swap_half(t2, t2);
    }
    gen_smul_dual(t1, t2);

    if (sub) {
        /*
         * This subtraction cannot overflow, so we can do a simple
         * 32-bit subtraction and then a possible 32-bit saturating
         * addition of Ra.
         */
        tcg_gen_sub_i32(t1, t1, t2);

        if (a->ra != 15) {
            t2 = load_reg(s, a->ra);
            gen_helper_add_setq(t1, tcg_env, t1, t2);
        }
    } else if (a->ra == 15) {
        /* Single saturation-checking addition */
        gen_helper_add_setq(t1, tcg_env, t1, t2);
    } else {
        /*
         * We need to add the products and Ra together and then
         * determine whether the final result overflowed. Doing
         * this as two separate add-and-check-overflow steps incorrectly
         * sets Q for cases like (-32768 * -32768) + (-32768 * -32768) + -1.
         * Do all the arithmetic at 64-bits and then check for overflow.
         */
        TCGv_i64 p64, q64;
        TCGv_i32 t3, qf, one;

        p64 = tcg_temp_new_i64();
        q64 = tcg_temp_new_i64();
        tcg_gen_ext_i32_i64(p64, t1);
        tcg_gen_ext_i32_i64(q64, t2);
        tcg_gen_add_i64(p64, p64, q64);
        load_reg_var(s, t2, a->ra);
        tcg_gen_ext_i32_i64(q64, t2);
        tcg_gen_add_i64(p64, p64, q64);

        tcg_gen_extr_i64_i32(t1, t2, p64);
        /*
         * t1 is the low half of the result which goes into Rd.
         * We have overflow and must set Q if the high half (t2)
         * is different from the sign-extension of t1.
         */
        t3 = tcg_temp_new_i32();
        tcg_gen_sari_i32(t3, t1, 31);
        qf = load_cpu_field(QF);
        one = tcg_constant_i32(1);
        tcg_gen_movcond_i32(TCG_COND_NE, qf, t2, t3, one, qf);
        store_cpu_field(qf, QF);
    }
    store_reg(s, a->rd, t1);
    return true;
}

static bool trans_SMLAD(DisasContext *s, arg_rrrr *a)
{
    return op_smlad(s, a, false, false);
}

static bool trans_SMLADX(DisasContext *s, arg_rrrr *a)
{
    return op_smlad(s, a, true, false);
}

static bool trans_SMLSD(DisasContext *s, arg_rrrr *a)
{
    return op_smlad(s, a, false, true);
}

static bool trans_SMLSDX(DisasContext *s, arg_rrrr *a)
{
    return op_smlad(s, a, true, true);
}

static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
{
    TCGv_i32 t1, t2;
    TCGv_i64 l1, l2;

    if (!ENABLE_ARCH_6) {
        return false;
    }

    t1 = load_reg(s, a->rn);
    t2 = load_reg(s, a->rm);
    if (m_swap) {
        gen_swap_half(t2, t2);
    }
    gen_smul_dual(t1, t2);

    l1 = tcg_temp_new_i64();
    l2 = tcg_temp_new_i64();
    tcg_gen_ext_i32_i64(l1, t1);
    tcg_gen_ext_i32_i64(l2, t2);

    if (sub) {
        tcg_gen_sub_i64(l1, l1, l2);
    } else {
        tcg_gen_add_i64(l1, l1, l2);
    }

    gen_addq(s, l1, a->ra, a->rd);
    gen_storeq_reg(s, a->ra, a->rd, l1);
    return true;
}

static bool trans_SMLALD(DisasContext *s, arg_rrrr *a)
{
    return op_smlald(s, a, false, false);
}

static bool trans_SMLALDX(DisasContext *s, arg_rrrr *a)
{
    return op_smlald(s, a, true, false);
}

static bool trans_SMLSLD(DisasContext *s, arg_rrrr *a)
{
    return op_smlald(s, a, false, true);
}

static bool trans_SMLSLDX(DisasContext *s, arg_rrrr *a)
{
    return op_smlald(s, a, true, true);
}

static bool op_smmla(DisasContext *s, arg_rrrr *a, bool round, bool sub)
{
    TCGv_i32 t1, t2;

    if (s->thumb
        ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
        : !ENABLE_ARCH_6) {
        return false;
    }

    t1 = load_reg(s, a->rn);
    t2 = load_reg(s, a->rm);
    tcg_gen_muls2_i32(t2, t1, t1, t2);

    if (a->ra != 15) {
        TCGv_i32 t3 = load_reg(s, a->ra);
        if (sub) {
            /*
             * For SMMLS, we need a 64-bit subtract.  Borrow caused by
             * a non-zero multiplicand lowpart, and the correct result
             * lowpart for rounding.
             */
            tcg_gen_sub2_i32(t2, t1, tcg_constant_i32(0), t3, t2, t1);
        } else {
            tcg_gen_add_i32(t1, t1, t3);
        }
    }
    if (round) {
        /*
         * Adding 0x80000000 to the 64-bit quantity means that we have
         * carry in to the high word when the low word has the msb set.
         */
        tcg_gen_shri_i32(t2, t2, 31);
        tcg_gen_add_i32(t1, t1, t2);
    }
    store_reg(s, a->rd, t1);
    return true;
}

static bool trans_SMMLA(DisasContext *s, arg_rrrr *a)
{
    return op_smmla(s, a, false, false);
}

static bool trans_SMMLAR(DisasContext *s, arg_rrrr *a)
{
    return op_smmla(s, a, true, false);
}

static bool trans_SMMLS(DisasContext *s, arg_rrrr *a)
{
    return op_smmla(s, a, false, true);
}

static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a)
{
    return op_smmla(s, a, true, true);
}

static bool op_div(DisasContext *s, arg_rrr *a, bool u)
{
    TCGv_i32 t1, t2;

    if (s->thumb
        ? !dc_isar_feature(aa32_thumb_div, s)
        : !dc_isar_feature(aa32_arm_div, s)) {
        return false;
    }

    t1 = load_reg(s, a->rn);
    t2 = load_reg(s, a->rm);
    if (u) {
        gen_helper_udiv(t1, tcg_env, t1, t2);
    } else {
        gen_helper_sdiv(t1, tcg_env, t1, t2);
    }
    store_reg(s, a->rd, t1);
    return true;
}

static bool trans_SDIV(DisasContext *s, arg_rrr *a)
{
    return op_div(s, a, false);
}

static bool trans_UDIV(DisasContext *s, arg_rrr *a)
{
    return op_div(s, a, true);
}

/*
 * Block data transfer
 */

static TCGv_i32 op_addr_block_pre(DisasContext *s, arg_ldst_block *a, int n)
{
    TCGv_i32 addr = load_reg(s, a->rn);

    if (a->b) {
        if (a->i) {
            /* pre increment */
            tcg_gen_addi_i32(addr, addr, 4);
        } else {
            /* pre decrement */
            tcg_gen_addi_i32(addr, addr, -(n * 4));
        }
    } else if (!a->i && n != 1) {
        /* post decrement */
        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
    }

    if (s->v8m_stackcheck && a->rn == 13 && a->w) {
        /*
         * If the writeback is incrementing SP rather than
         * decrementing it, and the initial SP is below the
         * stack limit but the final written-back SP would
         * be above, then we must not perform any memory
         * accesses, but it is IMPDEF whether we generate
         * an exception. We choose to do so in this case.
         * At this point 'addr' is the lowest address, so
         * either the original SP (if incrementing) or our
         * final SP (if decrementing), so that's what we check.
         */
        gen_helper_v8m_stackcheck(tcg_env, addr);
    }

    return addr;
}

static void op_addr_block_post(DisasContext *s, arg_ldst_block *a,
                               TCGv_i32 addr, int n)
{
    if (a->w) {
        /* write back */
        if (!a->b) {
            if (a->i) {
                /* post increment */
                tcg_gen_addi_i32(addr, addr, 4);
            } else {
                /* post decrement */
                tcg_gen_addi_i32(addr, addr, -(n * 4));
            }
        } else if (!a->i && n != 1) {
            /* pre decrement */
            tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
        }
        store_reg(s, a->rn, addr);
    }
}

static bool op_stm(DisasContext *s, arg_ldst_block *a)
{
    int i, j, n, list, mem_idx;
    bool user = a->u;
    TCGv_i32 addr, tmp;

    if (user) {
        /* STM (user) */
        if (IS_USER(s)) {
            /* Only usable in supervisor mode.  */
            unallocated_encoding(s);
            return true;
        }
    }

    list = a->list;
    n = ctpop16(list);
    /*
     * This is UNPREDICTABLE for n < 1 in all encodings, and we choose
     * to UNDEF. In the T32 STM encoding n == 1 is also UNPREDICTABLE,
     * but hardware treats it like the A32 version and implements the
     * single-register-store, and some in-the-wild (buggy) software
     * assumes that, so we don't UNDEF on that case.
     */
    if (n < 1 || a->rn == 15) {
        unallocated_encoding(s);
        return true;
    }

    s->eci_handled = true;

    addr = op_addr_block_pre(s, a, n);
    mem_idx = get_mem_index(s);

    for (i = j = 0; i < 16; i++) {
        if (!(list & (1 << i))) {
            continue;
        }

        if (user && i != 15) {
            tmp = tcg_temp_new_i32();
            gen_helper_get_user_reg(tmp, tcg_env, tcg_constant_i32(i));
        } else {
            tmp = load_reg(s, i);
        }
        gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);

        /* No need to add after the last transfer.  */
        if (++j != n) {
            tcg_gen_addi_i32(addr, addr, 4);
        }
    }

    op_addr_block_post(s, a, addr, n);
    clear_eci_state(s);
    return true;
}

static bool trans_STM(DisasContext *s, arg_ldst_block *a)
{
    return op_stm(s, a);
}

static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a)
{
    /* Writeback register in register list is UNPREDICTABLE for T32.  */
    if (a->w && (a->list & (1 << a->rn))) {
        unallocated_encoding(s);
        return true;
    }
    return op_stm(s, a);
}

static bool do_ldm(DisasContext *s, arg_ldst_block *a)
{
    int i, j, n, list, mem_idx;
    bool loaded_base;
    bool user = a->u;
    bool exc_return = false;
    TCGv_i32 addr, tmp, loaded_var;

    if (user) {
        /* LDM (user), LDM (exception return) */
        if (IS_USER(s)) {
            /* Only usable in supervisor mode.  */
            unallocated_encoding(s);
            return true;
        }
        if (extract32(a->list, 15, 1)) {
            exc_return = true;
            user = false;
        } else {
            /* LDM (user) does not allow writeback.  */
            if (a->w) {
                unallocated_encoding(s);
                return true;
            }
        }
    }

    list = a->list;
    n = ctpop16(list);
    /*
     * This is UNPREDICTABLE for n < 1 in all encodings, and we choose
     * to UNDEF. In the T32 LDM encoding n == 1 is also UNPREDICTABLE,
     * but hardware treats it like the A32 version and implements the
     * single-register-load, and some in-the-wild (buggy) software
     * assumes that, so we don't UNDEF on that case.
     */
    if (n < 1 || a->rn == 15) {
        unallocated_encoding(s);
        return true;
    }

    s->eci_handled = true;

    addr = op_addr_block_pre(s, a, n);
    mem_idx = get_mem_index(s);
    loaded_base = false;
    loaded_var = NULL;

    for (i = j = 0; i < 16; i++) {
        if (!(list & (1 << i))) {
            continue;
        }

        tmp = tcg_temp_new_i32();
        gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
        if (user) {
            gen_helper_set_user_reg(tcg_env, tcg_constant_i32(i), tmp);
        } else if (i == a->rn) {
            loaded_var = tmp;
            loaded_base = true;
        } else if (i == 15 && exc_return) {
            store_pc_exc_ret(s, tmp);
        } else {
            store_reg_from_load(s, i, tmp);
        }

        /* No need to add after the last transfer.  */
        if (++j != n) {
            tcg_gen_addi_i32(addr, addr, 4);
        }
    }

    op_addr_block_post(s, a, addr, n);

    if (loaded_base) {
        /* Note that we reject base == pc above.  */
        store_reg(s, a->rn, loaded_var);
    }

    if (exc_return) {
        /* Restore CPSR from SPSR.  */
        tmp = load_cpu_field(spsr);
        translator_io_start(&s->base);
        gen_helper_cpsr_write_eret(tcg_env, tmp);
        /* Must exit loop to check un-masked IRQs */
        s->base.is_jmp = DISAS_EXIT;
    }
    clear_eci_state(s);
    return true;
}

static bool trans_LDM_a32(DisasContext *s, arg_ldst_block *a)
{
    /*
     * Writeback register in register list is UNPREDICTABLE
     * for ArchVersion() >= 7.  Prior to v7, A32 would write
     * an UNKNOWN value to the base register.
     */
    if (ENABLE_ARCH_7 && a->w && (a->list & (1 << a->rn))) {
        unallocated_encoding(s);
        return true;
    }
    return do_ldm(s, a);
}

static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a)
{
    /* Writeback register in register list is UNPREDICTABLE for T32. */
    if (a->w && (a->list & (1 << a->rn))) {
        unallocated_encoding(s);
        return true;
    }
    return do_ldm(s, a);
}

static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
{
    /* Writeback is conditional on the base register not being loaded.  */
    a->w = !(a->list & (1 << a->rn));
    return do_ldm(s, a);
}

static bool trans_CLRM(DisasContext *s, arg_CLRM *a)
{
    int i;
    TCGv_i32 zero;

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

    if (extract32(a->list, 13, 1)) {
        return false;
    }

    if (!a->list) {
        /* UNPREDICTABLE; we choose to UNDEF */
        return false;
    }

    s->eci_handled = true;

    zero = tcg_constant_i32(0);
    for (i = 0; i < 15; i++) {
        if (extract32(a->list, i, 1)) {
            /* Clear R[i] */
            tcg_gen_mov_i32(cpu_R[i], zero);
        }
    }
    if (extract32(a->list, 15, 1)) {
        /*
         * Clear APSR (by calling the MSR helper with the same argument
         * as for "MSR APSR_nzcvqg, Rn": mask = 0b1100, SYSM=0)
         */
        gen_helper_v7m_msr(tcg_env, tcg_constant_i32(0xc00), zero);
    }
    clear_eci_state(s);
    return true;
}

/*
 * Branch, branch with link
 */

static bool trans_B(DisasContext *s, arg_i *a)
{
    gen_jmp(s, jmp_diff(s, a->imm));
    return true;
}

static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a)
{
    /* This has cond from encoding, required to be outside IT block.  */
    if (a->cond >= 0xe) {
        return false;
    }
    if (s->condexec_mask) {
        unallocated_encoding(s);
        return true;
    }
    arm_skip_unless(s, a->cond);
    gen_jmp(s, jmp_diff(s, a->imm));
    return true;
}

static bool trans_BL(DisasContext *s, arg_i *a)
{
    gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | s->thumb);
    gen_jmp(s, jmp_diff(s, a->imm));
    return true;
}

static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
{
    /*
     * BLX <imm> would be useless on M-profile; the encoding space
     * is used for other insns from v8.1M onward, and UNDEFs before that.
     */
    if (arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }

    /* For A32, ARM_FEATURE_V5 is checked near the start of the uncond block. */
    if (s->thumb && (a->imm & 2)) {
        return false;
    }
    gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | s->thumb);
    store_cpu_field_constant(!s->thumb, thumb);
    /* This jump is computed from an aligned PC: subtract off the low bits. */
    gen_jmp(s, jmp_diff(s, a->imm - (s->pc_curr & 3)));
    return true;
}

static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a)
{
    assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
    gen_pc_plus_diff(s, cpu_R[14], jmp_diff(s, a->imm << 12));
    return true;
}

static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a)
{
    TCGv_i32 tmp = tcg_temp_new_i32();

    assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
    tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1);
    gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | 1);
    gen_bx(s, tmp);
    return true;
}

static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
{
    TCGv_i32 tmp;

    assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
    if (!ENABLE_ARCH_5) {
        return false;
    }
    tmp = tcg_temp_new_i32();
    tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
    tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
    gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | 1);
    gen_bx(s, tmp);
    return true;
}

static bool trans_BF(DisasContext *s, arg_BF *a)
{
    /*
     * M-profile branch future insns. The architecture permits an
     * implementation to implement these as NOPs (equivalent to
     * discarding the LO_BRANCH_INFO cache immediately), and we
     * take that IMPDEF option because for QEMU a "real" implementation
     * would be complicated and wouldn't execute any faster.
     */
    if (!dc_isar_feature(aa32_lob, s)) {
        return false;
    }
    if (a->boff == 0) {
        /* SEE "Related encodings" (loop insns) */
        return false;
    }
    /* Handle as NOP */
    return true;
}

static bool trans_DLS(DisasContext *s, arg_DLS *a)
{
    /* M-profile low-overhead loop start */
    TCGv_i32 tmp;

    if (!dc_isar_feature(aa32_lob, s)) {
        return false;
    }
    if (a->rn == 13 || a->rn == 15) {
        /*
         * For DLSTP rn == 15 is a related encoding (LCTP); the
         * other cases caught by this condition are all
         * CONSTRAINED UNPREDICTABLE: we choose to UNDEF
         */
        return false;
    }

    if (a->size != 4) {
        /* DLSTP */
        if (!dc_isar_feature(aa32_mve, s)) {
            return false;
        }
        if (!vfp_access_check(s)) {
            return true;
        }
    }

    /* Not a while loop: set LR to the count, and set LTPSIZE for DLSTP */
    tmp = load_reg(s, a->rn);
    store_reg(s, 14, tmp);
    if (a->size != 4) {
        /* DLSTP: set FPSCR.LTPSIZE */
        store_cpu_field(tcg_constant_i32(a->size), v7m.ltpsize);
        s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
    }
    return true;
}

static bool trans_WLS(DisasContext *s, arg_WLS *a)
{
    /* M-profile low-overhead while-loop start */
    TCGv_i32 tmp;
    DisasLabel nextlabel;

    if (!dc_isar_feature(aa32_lob, s)) {
        return false;
    }
    if (a->rn == 13 || a->rn == 15) {
        /*
         * For WLSTP rn == 15 is a related encoding (LE); the
         * other cases caught by this condition are all
         * CONSTRAINED UNPREDICTABLE: we choose to UNDEF
         */
        return false;
    }
    if (s->condexec_mask) {
        /*
         * WLS in an IT block is CONSTRAINED UNPREDICTABLE;
         * we choose to UNDEF, because otherwise our use of
         * gen_goto_tb(1) would clash with the use of TB exit 1
         * in the dc->condjmp condition-failed codepath in
         * arm_tr_tb_stop() and we'd get an assertion.
         */
        return false;
    }
    if (a->size != 4) {
        /* WLSTP */
        if (!dc_isar_feature(aa32_mve, s)) {
            return false;
        }
        /*
         * We need to check that the FPU is enabled here, but mustn't
         * call vfp_access_check() to do that because we don't want to
         * do the lazy state preservation in the "loop count is zero" case.
         * Do the check-and-raise-exception by hand.
         */
        if (s->fp_excp_el) {
            gen_exception_insn_el(s, 0, EXCP_NOCP,
                                  syn_uncategorized(), s->fp_excp_el);
            return true;
        }
    }

    nextlabel = gen_disas_label(s);
    tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel.label);
    tmp = load_reg(s, a->rn);
    store_reg(s, 14, tmp);
    if (a->size != 4) {
        /*
         * WLSTP: set FPSCR.LTPSIZE. This requires that we do the
         * lazy state preservation, new FP context creation, etc,
         * that vfp_access_check() does. We know that the actual
         * access check will succeed (ie it won't generate code that
         * throws an exception) because we did that check by hand earlier.
         */
        bool ok = vfp_access_check(s);
        assert(ok);
        store_cpu_field(tcg_constant_i32(a->size), v7m.ltpsize);
        /*
         * LTPSIZE updated, but MVE_NO_PRED will always be the same thing (0)
         * when we take this upcoming exit from this TB, so gen_jmp_tb() is OK.
         */
    }
    gen_jmp_tb(s, curr_insn_len(s), 1);

    set_disas_label(s, nextlabel);
    gen_jmp(s, jmp_diff(s, a->imm));
    return true;
}

static bool trans_LE(DisasContext *s, arg_LE *a)
{
    /*
     * M-profile low-overhead loop end. The architecture permits an
     * implementation to discard the LO_BRANCH_INFO cache at any time,
     * and we take the IMPDEF option to never set it in the first place
     * (equivalent to always discarding it immediately), because for QEMU
     * a "real" implementation would be complicated and wouldn't execute
     * any faster.
     */
    TCGv_i32 tmp;
    DisasLabel loopend;
    bool fpu_active;

    if (!dc_isar_feature(aa32_lob, s)) {
        return false;
    }
    if (a->f && a->tp) {
        return false;
    }
    if (s->condexec_mask) {
        /*
         * LE in an IT block is CONSTRAINED UNPREDICTABLE;
         * we choose to UNDEF, because otherwise our use of
         * gen_goto_tb(1) would clash with the use of TB exit 1
         * in the dc->condjmp condition-failed codepath in
         * arm_tr_tb_stop() and we'd get an assertion.
         */
        return false;
    }
    if (a->tp) {
        /* LETP */
        if (!dc_isar_feature(aa32_mve, s)) {
            return false;
        }
        if (!vfp_access_check(s)) {
            s->eci_handled = true;
            return true;
        }
    }

    /* LE/LETP is OK with ECI set and leaves it untouched */
    s->eci_handled = true;

    /*
     * With MVE, LTPSIZE might not be 4, and we must emit an INVSTATE
     * UsageFault exception for the LE insn in that case. Note that we
     * are not directly checking FPSCR.LTPSIZE but instead check the
     * pseudocode LTPSIZE() function, which returns 4 if the FPU is
     * not currently active (ie ActiveFPState() returns false). We
     * can identify not-active purely from our TB state flags, as the
     * FPU is active only if:
     *  the FPU is enabled
     *  AND lazy state preservation is not active
     *  AND we do not need a new fp context (this is the ASPEN/FPCA check)
     *
     * Usually we don't need to care about this distinction between
     * LTPSIZE and FPSCR.LTPSIZE, because the code in vfp_access_check()
     * will either take an exception or clear the conditions that make
     * the FPU not active. But LE is an unusual case of a non-FP insn
     * that looks at LTPSIZE.
     */
    fpu_active = !s->fp_excp_el && !s->v7m_lspact && !s->v7m_new_fp_ctxt_needed;

    if (!a->tp && dc_isar_feature(aa32_mve, s) && fpu_active) {
        /* Need to do a runtime check for LTPSIZE != 4 */
        DisasLabel skipexc = gen_disas_label(s);
        tmp = load_cpu_field(v7m.ltpsize);
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 4, skipexc.label);
        gen_exception_insn(s, 0, EXCP_INVSTATE, syn_uncategorized());
        set_disas_label(s, skipexc);
    }

    if (a->f) {
        /* Loop-forever: just jump back to the loop start */
        gen_jmp(s, jmp_diff(s, -a->imm));
        return true;
    }

    /*
     * Not loop-forever. If LR <= loop-decrement-value this is the last loop.
     * For LE, we know at this point that LTPSIZE must be 4 and the
     * loop decrement value is 1. For LETP we need to calculate the decrement
     * value from LTPSIZE.
     */
    loopend = gen_disas_label(s);
    if (!a->tp) {
        tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, loopend.label);
        tcg_gen_addi_i32(cpu_R[14], cpu_R[14], -1);
    } else {
        /*
         * Decrement by 1 << (4 - LTPSIZE). We need to use a TCG local
         * so that decr stays live after the brcondi.
         */
        TCGv_i32 decr = tcg_temp_new_i32();
        TCGv_i32 ltpsize = load_cpu_field(v7m.ltpsize);
        tcg_gen_sub_i32(decr, tcg_constant_i32(4), ltpsize);
        tcg_gen_shl_i32(decr, tcg_constant_i32(1), decr);

        tcg_gen_brcond_i32(TCG_COND_LEU, cpu_R[14], decr, loopend.label);

        tcg_gen_sub_i32(cpu_R[14], cpu_R[14], decr);
    }
    /* Jump back to the loop start */
    gen_jmp(s, jmp_diff(s, -a->imm));

    set_disas_label(s, loopend);
    if (a->tp) {
        /* Exits from tail-pred loops must reset LTPSIZE to 4 */
        store_cpu_field(tcg_constant_i32(4), v7m.ltpsize);
    }
    /* End TB, continuing to following insn */
    gen_jmp_tb(s, curr_insn_len(s), 1);
    return true;
}

static bool trans_LCTP(DisasContext *s, arg_LCTP *a)
{
    /*
     * M-profile Loop Clear with Tail Predication. Since our implementation
     * doesn't cache branch information, all we need to do is reset
     * FPSCR.LTPSIZE to 4.
     */

    if (!dc_isar_feature(aa32_lob, s) ||
        !dc_isar_feature(aa32_mve, s)) {
        return false;
    }

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

    store_cpu_field_constant(4, v7m.ltpsize);
    return true;
}

static bool trans_VCTP(DisasContext *s, arg_VCTP *a)
{
    /*
     * M-profile Create Vector Tail Predicate. This insn is itself
     * predicated and is subject to beatwise execution.
     */
    TCGv_i32 rn_shifted, masklen;

    if (!dc_isar_feature(aa32_mve, s) || a->rn == 13 || a->rn == 15) {
        return false;
    }

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

    /*
     * We pre-calculate the mask length here to avoid having
     * to have multiple helpers specialized for size.
     * We pass the helper "rn <= (1 << (4 - size)) ? (rn << size) : 16".
     */
    rn_shifted = tcg_temp_new_i32();
    masklen = load_reg(s, a->rn);
    tcg_gen_shli_i32(rn_shifted, masklen, a->size);
    tcg_gen_movcond_i32(TCG_COND_LEU, masklen,
                        masklen, tcg_constant_i32(1 << (4 - a->size)),
                        rn_shifted, tcg_constant_i32(16));
    gen_helper_mve_vctp(tcg_env, masklen);
    /* This insn updates predication bits */
    s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
    mve_update_eci(s);
    return true;
}

static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
{
    TCGv_i32 addr, tmp;

    tmp = load_reg(s, a->rm);
    if (half) {
        tcg_gen_add_i32(tmp, tmp, tmp);
    }
    addr = load_reg(s, a->rn);
    tcg_gen_add_i32(addr, addr, tmp);

    gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), half ? MO_UW : MO_UB);

    tcg_gen_add_i32(tmp, tmp, tmp);
    gen_pc_plus_diff(s, addr, jmp_diff(s, 0));
    tcg_gen_add_i32(tmp, tmp, addr);
    store_reg(s, 15, tmp);
    return true;
}

static bool trans_TBB(DisasContext *s, arg_tbranch *a)
{
    return op_tbranch(s, a, false);
}

static bool trans_TBH(DisasContext *s, arg_tbranch *a)
{
    return op_tbranch(s, a, true);
}

static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
{
    TCGv_i32 tmp = load_reg(s, a->rn);

    arm_gen_condlabel(s);
    tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE,
                        tmp, 0, s->condlabel.label);
    gen_jmp(s, jmp_diff(s, a->imm));
    return true;
}

/*
 * Supervisor call - both T32 & A32 come here so we need to check
 * which mode we are in when checking for semihosting.
 */

static bool trans_SVC(DisasContext *s, arg_SVC *a)
{
    const uint32_t semihost_imm = s->thumb ? 0xab : 0x123456;

    if (!arm_dc_feature(s, ARM_FEATURE_M) &&
        semihosting_enabled(s->current_el == 0) &&
        (a->imm == semihost_imm)) {
        gen_exception_internal_insn(s, EXCP_SEMIHOST);
    } else {
        if (s->fgt_svc) {
            uint32_t syndrome = syn_aa32_svc(a->imm, s->thumb);
            gen_exception_insn_el(s, 0, EXCP_UDEF, syndrome, 2);
        } else {
            gen_update_pc(s, curr_insn_len(s));
            s->svc_imm = a->imm;
            s->base.is_jmp = DISAS_SWI;
        }
    }
    return true;
}

/*
 * Unconditional system instructions
 */

static bool trans_RFE(DisasContext *s, arg_RFE *a)
{
    static const int8_t pre_offset[4] = {
        /* DA */ -4, /* IA */ 0, /* DB */ -8, /* IB */ 4
    };
    static const int8_t post_offset[4] = {
        /* DA */ -8, /* IA */ 4, /* DB */ -4, /* IB */ 0
    };
    TCGv_i32 addr, t1, t2;

    if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    if (IS_USER(s)) {
        unallocated_encoding(s);
        return true;
    }

    addr = load_reg(s, a->rn);
    tcg_gen_addi_i32(addr, addr, pre_offset[a->pu]);

    /* Load PC into tmp and CPSR into tmp2.  */
    t1 = tcg_temp_new_i32();
    gen_aa32_ld_i32(s, t1, addr, get_mem_index(s), MO_UL | MO_ALIGN);
    tcg_gen_addi_i32(addr, addr, 4);
    t2 = tcg_temp_new_i32();
    gen_aa32_ld_i32(s, t2, addr, get_mem_index(s), MO_UL | MO_ALIGN);

    if (a->w) {
        /* Base writeback.  */
        tcg_gen_addi_i32(addr, addr, post_offset[a->pu]);
        store_reg(s, a->rn, addr);
    }
    gen_rfe(s, t1, t2);
    return true;
}

static bool trans_SRS(DisasContext *s, arg_SRS *a)
{
    if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    gen_srs(s, a->mode, a->pu, a->w);
    return true;
}

static bool trans_CPS(DisasContext *s, arg_CPS *a)
{
    uint32_t mask, val;

    if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    if (IS_USER(s)) {
        /* Implemented as NOP in user mode.  */
        return true;
    }
    /* TODO: There are quite a lot of UNPREDICTABLE argument combinations. */

    mask = val = 0;
    if (a->imod & 2) {
        if (a->A) {
            mask |= CPSR_A;
        }
        if (a->I) {
            mask |= CPSR_I;
        }
        if (a->F) {
            mask |= CPSR_F;
        }
        if (a->imod & 1) {
            val |= mask;
        }
    }
    if (a->M) {
        mask |= CPSR_M;
        val |= a->mode;
    }
    if (mask) {
        gen_set_psr_im(s, mask, 0, val);
    }
    return true;
}

static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a)
{
    TCGv_i32 tmp, addr;

    if (!arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    if (IS_USER(s)) {
        /* Implemented as NOP in user mode.  */
        return true;
    }

    tmp = tcg_constant_i32(a->im);
    /* FAULTMASK */
    if (a->F) {
        addr = tcg_constant_i32(19);
        gen_helper_v7m_msr(tcg_env, addr, tmp);
    }
    /* PRIMASK */
    if (a->I) {
        addr = tcg_constant_i32(16);
        gen_helper_v7m_msr(tcg_env, addr, tmp);
    }
    gen_rebuild_hflags(s, false);
    gen_lookup_tb(s);
    return true;
}

/*
 * Clear-Exclusive, Barriers
 */

static bool trans_CLREX(DisasContext *s, arg_CLREX *a)
{
    if (s->thumb
        ? !ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)
        : !ENABLE_ARCH_6K) {
        return false;
    }
    gen_clrex(s);
    return true;
}

static bool trans_DSB(DisasContext *s, arg_DSB *a)
{
    if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
    return true;
}

static bool trans_DMB(DisasContext *s, arg_DMB *a)
{
    return trans_DSB(s, NULL);
}

static bool trans_ISB(DisasContext *s, arg_ISB *a)
{
    if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    /*
     * We need to break the TB after this insn to execute
     * self-modifying code correctly and also to take
     * any pending interrupts immediately.
     */
    s->base.is_jmp = DISAS_TOO_MANY;
    return true;
}

static bool trans_SB(DisasContext *s, arg_SB *a)
{
    if (!dc_isar_feature(aa32_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);
    s->base.is_jmp = DISAS_TOO_MANY;
    return true;
}

static bool trans_SETEND(DisasContext *s, arg_SETEND *a)
{
    if (!ENABLE_ARCH_6) {
        return false;
    }
    if (a->E != (s->be_data == MO_BE)) {
        gen_helper_setend(tcg_env);
        s->base.is_jmp = DISAS_UPDATE_EXIT;
    }
    return true;
}

/*
 * Preload instructions
 * All are nops, contingent on the appropriate arch level.
 */

static bool trans_PLD(DisasContext *s, arg_PLD *a)
{
    return ENABLE_ARCH_5TE;
}

static bool trans_PLDW(DisasContext *s, arg_PLDW *a)
{
    return arm_dc_feature(s, ARM_FEATURE_V7MP);
}

static bool trans_PLI(DisasContext *s, arg_PLI *a)
{
    return ENABLE_ARCH_7;
}

/*
 * If-then
 */

static bool trans_IT(DisasContext *s, arg_IT *a)
{
    int cond_mask = a->cond_mask;

    /*
     * No actual code generated for this insn, just setup state.
     *
     * Combinations of firstcond and mask which set up an 0b1111
     * condition are UNPREDICTABLE; we take the CONSTRAINED
     * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
     * i.e. both meaning "execute always".
     */
    s->condexec_cond = (cond_mask >> 4) & 0xe;
    s->condexec_mask = cond_mask & 0x1f;
    return true;
}

/* v8.1M CSEL/CSINC/CSNEG/CSINV */
static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
{
    TCGv_i32 rn, rm;
    DisasCompare c;

    if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
        return false;
    }

    if (a->rm == 13) {
        /* SEE "Related encodings" (MVE shifts) */
        return false;
    }

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

    /* In this insn input reg fields of 0b1111 mean "zero", not "PC" */
    rn = tcg_temp_new_i32();
    rm = tcg_temp_new_i32();
    if (a->rn == 15) {
        tcg_gen_movi_i32(rn, 0);
    } else {
        load_reg_var(s, rn, a->rn);
    }
    if (a->rm == 15) {
        tcg_gen_movi_i32(rm, 0);
    } else {
        load_reg_var(s, rm, a->rm);
    }

    switch (a->op) {
    case 0: /* CSEL */
        break;
    case 1: /* CSINC */
        tcg_gen_addi_i32(rm, rm, 1);
        break;
    case 2: /* CSINV */
        tcg_gen_not_i32(rm, rm);
        break;
    case 3: /* CSNEG */
        tcg_gen_neg_i32(rm, rm);
        break;
    default:
        g_assert_not_reached();
    }

    arm_test_cc(&c, a->fcond);
    tcg_gen_movcond_i32(c.cond, rn, c.value, tcg_constant_i32(0), rn, rm);

    store_reg(s, a->rd, rn);
    return true;
}

/*
 * Legacy decoder.
 */

static void disas_arm_insn(DisasContext *s, unsigned int insn)
{
    unsigned int cond = insn >> 28;

    /* M variants do not implement ARM mode; this must raise the INVSTATE
     * UsageFault exception.
     */
    if (arm_dc_feature(s, ARM_FEATURE_M)) {
        gen_exception_insn(s, 0, EXCP_INVSTATE, syn_uncategorized());
        return;
    }

    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 (cond == 0xf) {
        /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
         * choose to UNDEF. In ARMv5 and above the space is used
         * for miscellaneous unconditional instructions.
         */
        if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
            unallocated_encoding(s);
            return;
        }

        /* Unconditional instructions.  */
        /* TODO: Perhaps merge these into one decodetree output file.  */
        if (disas_a32_uncond(s, insn) ||
            disas_vfp_uncond(s, insn) ||
            disas_neon_dp(s, insn) ||
            disas_neon_ls(s, insn) ||
            disas_neon_shared(s, insn)) {
            return;
        }
        goto illegal_op;
    }
    if (cond != 0xe) {
        /* if not always execute, we generate a conditional jump to
           next instruction */
        arm_skip_unless(s, cond);
    }

    /* TODO: Perhaps merge these into one decodetree output file.  */
    if (disas_a32(s, insn) ||
        disas_vfp(s, insn)) {
        return;
    }
    /* We didn't match anything in the decoder: UNDEF */

illegal_op:
    unallocated_encoding(s);
}

static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
{
    /*
     * Return true if this is a 16 bit instruction. We must be precise
     * about this (matching the decode).
     */
    if ((insn >> 11) < 0x1d) {
        /* Definitely a 16-bit instruction */
        return true;
    }

    /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
     * first half of a 32-bit Thumb insn. Thumb-1 cores might
     * end up actually treating this as two 16-bit insns, though,
     * if it's half of a bl/blx pair that might span a page boundary.
     */
    if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
        arm_dc_feature(s, ARM_FEATURE_M)) {
        /* Thumb2 cores (including all M profile ones) always treat
         * 32-bit insns as 32-bit.
         */
        return false;
    }

    if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
        /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
         * is not on the next page; we merge this into a 32-bit
         * insn.
         */
        return false;
    }
    /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
     * 0b1111_1xxx_xxxx_xxxx : BL suffix;
     * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
     *  -- handle as single 16 bit insn
     */
    return true;
}

/* Translate a 32-bit thumb instruction. */
static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
{
    /*
     * ARMv6-M supports a limited subset of Thumb2 instructions.
     * Other Thumb1 architectures allow only 32-bit
     * combined BL/BLX prefix and suffix.
     */
    if (arm_dc_feature(s, ARM_FEATURE_M) &&
        !arm_dc_feature(s, ARM_FEATURE_V7)) {
        int i;
        bool found = false;
        static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
                                               0xf3b08040 /* dsb */,
                                               0xf3b08050 /* dmb */,
                                               0xf3b08060 /* isb */,
                                               0xf3e08000 /* mrs */,
                                               0xf000d000 /* bl */};
        static const uint32_t armv6m_mask[] = {0xffe0d000,
                                               0xfff0d0f0,
                                               0xfff0d0f0,
                                               0xfff0d0f0,
                                               0xffe0d000,
                                               0xf800d000};

        for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
            if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
                found = true;
                break;
            }
        }
        if (!found) {
            goto illegal_op;
        }
    } else if ((insn & 0xf800e800) != 0xf000e800)  {
        if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
            unallocated_encoding(s);
            return;
        }
    }

    if (arm_dc_feature(s, ARM_FEATURE_M)) {
        /*
         * NOCP takes precedence over any UNDEF for (almost) the
         * entire wide range of coprocessor-space encodings, so check
         * for it first before proceeding to actually decode eg VFP
         * insns. This decode also handles the few insns which are
         * in copro space but do not have NOCP checks (eg VLLDM, VLSTM).
         */
        if (disas_m_nocp(s, insn)) {
            return;
        }
    }

    if ((insn & 0xef000000) == 0xef000000) {
        /*
         * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
         * transform into
         * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
         */
        uint32_t a32_insn = (insn & 0xe2ffffff) |
            ((insn & (1 << 28)) >> 4) | (1 << 28);

        if (disas_neon_dp(s, a32_insn)) {
            return;
        }
    }

    if ((insn & 0xff100000) == 0xf9000000) {
        /*
         * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
         * transform into
         * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
         */
        uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;

        if (disas_neon_ls(s, a32_insn)) {
            return;
        }
    }

    /*
     * TODO: Perhaps merge these into one decodetree output file.
     * Note disas_vfp is written for a32 with cond field in the
     * top nibble.  The t32 encoding requires 0xe in the top nibble.
     */
    if (disas_t32(s, insn) ||
        disas_vfp_uncond(s, insn) ||
        disas_neon_shared(s, insn) ||
        disas_mve(s, insn) ||
        ((insn >> 28) == 0xe && disas_vfp(s, insn))) {
        return;
    }

illegal_op:
    unallocated_encoding(s);
}

static void disas_thumb_insn(DisasContext *s, uint32_t insn)
{
    if (!disas_t16(s, insn)) {
        unallocated_encoding(s);
    }
}

static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
{
    /* Return true if the insn at dc->base.pc_next might cross a page boundary.
     * (False positives are OK, false negatives are not.)
     * We know this is a Thumb insn, and our caller ensures we are
     * only called if dc->base.pc_next is less than 4 bytes from the page
     * boundary, so we cross the page if the first 16 bits indicate
     * that this is a 32 bit insn.
     */
    uint16_t insn = arm_lduw_code(env, &s->base, s->base.pc_next, s->sctlr_b);

    return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
}

static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
{
    DisasContext *dc = container_of(dcbase, DisasContext, base);
    CPUARMState *env = cpu_env(cs);
    ARMCPU *cpu = env_archcpu(env);
    CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
    uint32_t condexec, core_mmu_idx;

    dc->isar = &cpu->isar;
    dc->condjmp = 0;
    dc->pc_save = dc->base.pc_first;
    dc->aarch64 = false;
    dc->thumb = EX_TBFLAG_AM32(tb_flags, THUMB);
    dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
    condexec = EX_TBFLAG_AM32(tb_flags, CONDEXEC);
    /*
     * the CONDEXEC TB flags are CPSR bits [15:10][26:25]. On A-profile this
     * is always the IT bits. On M-profile, some of the reserved encodings
     * of IT are used instead to indicate either ICI or ECI, which
     * indicate partial progress of a restartable insn that was interrupted
     * partway through by an exception:
     *  * if CONDEXEC[3:0] != 0b0000 : CONDEXEC is IT bits
     *  * if CONDEXEC[3:0] == 0b0000 : CONDEXEC is ICI or ECI bits
     * In all cases CONDEXEC == 0 means "not in IT block or restartable
     * insn, behave normally".
     */
    dc->eci = dc->condexec_mask = dc->condexec_cond = 0;
    dc->eci_handled = false;
    if (condexec & 0xf) {
        dc->condexec_mask = (condexec & 0xf) << 1;
        dc->condexec_cond = condexec >> 4;
    } else {
        if (arm_feature(env, ARM_FEATURE_M)) {
            dc->eci = condexec >> 4;
        }
    }

    core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
    dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
    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);

    if (arm_feature(env, ARM_FEATURE_M)) {
        dc->vfp_enabled = 1;
        dc->be_data = MO_TE;
        dc->v7m_handler_mode = EX_TBFLAG_M32(tb_flags, HANDLER);
        dc->v8m_secure = EX_TBFLAG_M32(tb_flags, SECURE);
        dc->v8m_stackcheck = EX_TBFLAG_M32(tb_flags, STACKCHECK);
        dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(tb_flags, FPCCR_S_WRONG);
        dc->v7m_new_fp_ctxt_needed =
            EX_TBFLAG_M32(tb_flags, NEW_FP_CTXT_NEEDED);
        dc->v7m_lspact = EX_TBFLAG_M32(tb_flags, LSPACT);
        dc->mve_no_pred = EX_TBFLAG_M32(tb_flags, MVE_NO_PRED);
    } else {
        dc->sctlr_b = EX_TBFLAG_A32(tb_flags, SCTLR__B);
        dc->hstr_active = EX_TBFLAG_A32(tb_flags, HSTR_ACTIVE);
        dc->ns = EX_TBFLAG_A32(tb_flags, NS);
        dc->vfp_enabled = EX_TBFLAG_A32(tb_flags, VFPEN);
        dc->vec_len = EX_TBFLAG_A32(tb_flags, VECLEN);
        dc->vec_stride = EX_TBFLAG_A32(tb_flags, VECSTRIDE);
        dc->sme_trap_nonstreaming =
            EX_TBFLAG_A32(tb_flags, SME_TRAP_NONSTREAMING);
    }
    dc->lse2 = false; /* applies only to aarch64 */
    dc->cp_regs = cpu->cp_regs;
    dc->features = env->features;

    /* 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;

    dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;

    /* If architectural single step active, limit to 1.  */
    if (dc->ss_active) {
        dc->base.max_insns = 1;
    }

    /* ARM is a fixed-length ISA.  Bound the number of insns to execute
       to those left on the page.  */
    if (!dc->thumb) {
        int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
        dc->base.max_insns = MIN(dc->base.max_insns, bound);
    }
}

static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
{
    DisasContext *dc = container_of(dcbase, DisasContext, base);

    /* A note on handling of the condexec (IT) bits:
     *
     * We want to avoid the overhead of having to write the updated condexec
     * bits back to the CPUARMState for every instruction in an IT block. So:
     * (1) if the condexec bits are not already zero then we write
     * zero back into the CPUARMState now. This avoids complications trying
     * to do it at the end of the block. (For example if we don't do this
     * it's hard to identify whether we can safely skip writing condexec
     * at the end of the TB, which we definitely want to do for the case
     * where a TB doesn't do anything with the IT state at all.)
     * (2) if we are going to leave the TB then we call gen_set_condexec()
     * which will write the correct value into CPUARMState if zero is wrong.
     * This is done both for leaving the TB at the end, and for leaving
     * it because of an exception we know will happen, which is done in
     * gen_exception_insn(). The latter is necessary because we need to
     * leave the TB with the PC/IT state just prior to execution of the
     * instruction which caused the exception.
     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
     * then the CPUARMState will be wrong and we need to reset it.
     * This is handled in the same way as restoration of the
     * PC in these situations; we save the value of the condexec bits
     * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
     * then uses this to restore them after an exception.
     *
     * Note that there are no instructions which can read the condexec
     * bits, and none which can write non-static values to them, so
     * we don't need to care about whether CPUARMState is correct in the
     * middle of a TB.
     */

    /* Reset the conditional execution bits immediately. This avoids
       complications trying to do it at the end of the block.  */
    if (dc->condexec_mask || dc->condexec_cond) {
        store_cpu_field_constant(0, condexec_bits);
    }
}

static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
{
    DisasContext *dc = container_of(dcbase, DisasContext, base);
    /*
     * The ECI/ICI bits share PSR bits with the IT bits, so we
     * need to reconstitute the bits from the split-out DisasContext
     * fields here.
     */
    uint32_t condexec_bits;
    target_ulong pc_arg = dc->base.pc_next;

    if (tb_cflags(dcbase->tb) & CF_PCREL) {
        pc_arg &= ~TARGET_PAGE_MASK;
    }
    if (dc->eci) {
        condexec_bits = dc->eci << 4;
    } else {
        condexec_bits = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
    }
    tcg_gen_insn_start(pc_arg, condexec_bits, 0);
    dc->insn_start_updated = false;
}

static bool arm_check_kernelpage(DisasContext *dc)
{
#ifdef CONFIG_USER_ONLY
    /* Intercept jump to the magic kernel page.  */
    if (dc->base.pc_next >= 0xffff0000) {
        /* We always get here via a jump, so know we are not in a
           conditional execution block.  */
        gen_exception_internal(EXCP_KERNEL_TRAP);
        dc->base.is_jmp = DISAS_NORETURN;
        return true;
    }
#endif
    return false;
}

static bool arm_check_ss_active(DisasContext *dc)
{
    if (dc->ss_active && !dc->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(dc->base.num_insns == 1);
        gen_swstep_exception(dc, 0, 0);
        dc->base.is_jmp = DISAS_NORETURN;
        return true;
    }

    return false;
}

static void arm_post_translate_insn(DisasContext *dc)
{
    if (dc->condjmp &&
        (dc->base.is_jmp == DISAS_NEXT || dc->base.is_jmp == DISAS_TOO_MANY)) {
        if (dc->pc_save != dc->condlabel.pc_save) {
            gen_update_pc(dc, dc->condlabel.pc_save - dc->pc_save);
        }
        gen_set_label(dc->condlabel.label);
        dc->condjmp = 0;
    }
}

static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
{
    DisasContext *dc = container_of(dcbase, DisasContext, base);
    CPUARMState *env = cpu_env(cpu);
    uint32_t pc = dc->base.pc_next;
    unsigned int insn;

    /* Singlestep exceptions have the highest priority. */
    if (arm_check_ss_active(dc)) {
        dc->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
         * (or the execution of the kernelpage entrypoint). This should only
         * be possible after an indirect branch, at the start of the TB.
         */
        assert(dc->base.num_insns == 1);
        gen_helper_exception_pc_alignment(tcg_env, tcg_constant_vaddr(pc));
        dc->base.is_jmp = DISAS_NORETURN;
        dc->base.pc_next = QEMU_ALIGN_UP(pc, 4);
        return;
    }

    if (arm_check_kernelpage(dc)) {
        dc->base.pc_next = pc + 4;
        return;
    }

    dc->pc_curr = pc;
    insn = arm_ldl_code(env, &dc->base, pc, dc->sctlr_b);
    dc->insn = insn;
    dc->base.pc_next = pc + 4;
    disas_arm_insn(dc, insn);

    arm_post_translate_insn(dc);

    /* ARM is a fixed-length ISA.  We performed the cross-page check
       in init_disas_context by adjusting max_insns.  */
}

static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
{
    /* Return true if this Thumb insn is always unconditional,
     * even inside an IT block. This is true of only a very few
     * instructions: BKPT, HLT, and SG.
     *
     * A larger class of instructions are UNPREDICTABLE if used
     * inside an IT block; we do not need to detect those here, because
     * what we do by default (perform the cc check and update the IT
     * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
     * choice for those situations.
     *
     * insn is either a 16-bit or a 32-bit instruction; the two are
     * distinguishable because for the 16-bit case the top 16 bits
     * are zeroes, and that isn't a valid 32-bit encoding.
     */
    if ((insn & 0xffffff00) == 0xbe00) {
        /* BKPT */
        return true;
    }

    if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
        !arm_dc_feature(s, ARM_FEATURE_M)) {
        /* HLT: v8A only. This is unconditional even when it is going to
         * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
         * For v7 cores this was a plain old undefined encoding and so
         * honours its cc check. (We might be using the encoding as
         * a semihosting trap, but we don't change the cc check behaviour
         * on that account, because a debugger connected to a real v7A
         * core and emulating semihosting traps by catching the UNDEF
         * exception would also only see cases where the cc check passed.
         * No guest code should be trying to do a HLT semihosting trap
         * in an IT block anyway.
         */
        return true;
    }

    if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
        arm_dc_feature(s, ARM_FEATURE_M)) {
        /* SG: v8M only */
        return true;
    }

    return false;
}

static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
{
    DisasContext *dc = container_of(dcbase, DisasContext, base);
    CPUARMState *env = cpu_env(cpu);
    uint32_t pc = dc->base.pc_next;
    uint32_t insn;
    bool is_16bit;
    /* TCG op to rewind to if this turns out to be an invalid ECI state */
    TCGOp *insn_eci_rewind = NULL;
    target_ulong insn_eci_pc_save = -1;

    /* Misaligned thumb PC is architecturally impossible. */
    assert((dc->base.pc_next & 1) == 0);

    if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
        dc->base.pc_next = pc + 2;
        return;
    }

    dc->pc_curr = pc;
    insn = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
    is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
    pc += 2;
    if (!is_16bit) {
        uint32_t insn2 = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
        insn = insn << 16 | insn2;
        pc += 2;
    }
    dc->base.pc_next = pc;
    dc->insn = insn;

    if (dc->pstate_il) {
        /*
         * Illegal execution state. This has priority over BTI
         * exceptions, but comes after instruction abort exceptions.
         */
        gen_exception_insn(dc, 0, EXCP_UDEF, syn_illegalstate());
        return;
    }

    if (dc->eci) {
        /*
         * For M-profile continuable instructions, ECI/ICI handling
         * falls into these cases:
         *  - interrupt-continuable instructions
         *     These are the various load/store multiple insns (both
         *     integer and fp). The ICI bits indicate the register
         *     where the load/store can resume. We make the IMPDEF
         *     choice to always do "instruction restart", ie ignore
         *     the ICI value and always execute the ldm/stm from the
         *     start. So all we need to do is zero PSR.ICI if the
         *     insn executes.
         *  - MVE instructions subject to beat-wise execution
         *     Here the ECI bits indicate which beats have already been
         *     executed, and we must honour this. Each insn of this
         *     type will handle it correctly. We will update PSR.ECI
         *     in the helper function for the insn (some ECI values
         *     mean that the following insn also has been partially
         *     executed).
         *  - Special cases which don't advance ECI
         *     The insns LE, LETP and BKPT leave the ECI/ICI state
         *     bits untouched.
         *  - all other insns (the common case)
         *     Non-zero ECI/ICI means an INVSTATE UsageFault.
         *     We place a rewind-marker here. Insns in the previous
         *     three categories will set a flag in the DisasContext.
         *     If the flag isn't set after we call disas_thumb_insn()
         *     or disas_thumb2_insn() then we know we have a "some other
         *     insn" case. We will rewind to the marker (ie throwing away
         *     all the generated code) and instead emit "take exception".
         */
        insn_eci_rewind = tcg_last_op();
        insn_eci_pc_save = dc->pc_save;
    }

    if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
        uint32_t cond = dc->condexec_cond;

        /*
         * Conditionally skip the insn. Note that both 0xe and 0xf mean
         * "always"; 0xf is not "never".
         */
        if (cond < 0x0e) {
            arm_skip_unless(dc, cond);
        }
    }

    if (is_16bit) {
        disas_thumb_insn(dc, insn);
    } else {
        disas_thumb2_insn(dc, insn);
    }

    /* Advance the Thumb condexec condition.  */
    if (dc->condexec_mask) {
        dc->condexec_cond = ((dc->condexec_cond & 0xe) |
                             ((dc->condexec_mask >> 4) & 1));
        dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
        if (dc->condexec_mask == 0) {
            dc->condexec_cond = 0;
        }
    }

    if (dc->eci && !dc->eci_handled) {
        /*
         * Insn wasn't valid for ECI/ICI at all: undo what we
         * just generated and instead emit an exception
         */
        tcg_remove_ops_after(insn_eci_rewind);
        dc->pc_save = insn_eci_pc_save;
        dc->condjmp = 0;
        gen_exception_insn(dc, 0, EXCP_INVSTATE, syn_uncategorized());
    }

    arm_post_translate_insn(dc);

    /* Thumb is a variable-length ISA.  Stop translation when the next insn
     * will touch a new page.  This ensures that prefetch aborts occur at
     * the right place.
     *
     * We want to stop the TB if the next insn starts in a new page,
     * or if it spans between this page and the next. This means that
     * if we're looking at the last halfword in the page we need to
     * see if it's a 16-bit Thumb insn (which will fit in this TB)
     * or a 32-bit Thumb insn (which won't).
     * This is to avoid generating a silly TB with a single 16-bit insn
     * in it at the end of this page (which would execute correctly
     * but isn't very efficient).
     */
    if (dc->base.is_jmp == DISAS_NEXT
        && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
            || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
                && insn_crosses_page(env, dc)))) {
        dc->base.is_jmp = DISAS_TOO_MANY;
    }
}

static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
{
    DisasContext *dc = container_of(dcbase, DisasContext, base);

    /* At this stage dc->condjmp will only be set when the skipped
       instruction was a conditional branch or trap, and the PC has
       already been written.  */
    gen_set_condexec(dc);
    if (dc->base.is_jmp == DISAS_BX_EXCRET) {
        /* Exception return branches need some special case code at the
         * end of the TB, which is complex enough that it has to
         * handle the single-step vs not and the condition-failed
         * insn codepath itself.
         */
        gen_bx_excret_final_code(dc);
    } else if (unlikely(dc->ss_active)) {
        /* Unconditional and "condition passed" instruction codepath. */
        switch (dc->base.is_jmp) {
        case DISAS_SWI:
            gen_ss_advance(dc);
            gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
            break;
        case DISAS_HVC:
            gen_ss_advance(dc);
            gen_exception_el(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
            break;
        case DISAS_SMC:
            gen_ss_advance(dc);
            gen_exception_el(EXCP_SMC, syn_aa32_smc(), 3);
            break;
        case DISAS_NEXT:
        case DISAS_TOO_MANY:
        case DISAS_UPDATE_EXIT:
        case DISAS_UPDATE_NOCHAIN:
            gen_update_pc(dc, curr_insn_len(dc));
            /* fall through */
        default:
            /* FIXME: Single stepping a WFI insn will not halt the CPU. */
            gen_singlestep_exception(dc);
            break;
        case DISAS_NORETURN:
            break;
        }
    } else {
        /* While branches must always occur at the end of an IT block,
           there are a few other things that can cause us to terminate
           the TB in the middle of an IT block:
            - Exception generating instructions (bkpt, swi, undefined).
            - Page boundaries.
            - Hardware watchpoints.
           Hardware breakpoints have already been handled and skip this code.
         */
        switch (dc->base.is_jmp) {
        case DISAS_NEXT:
        case DISAS_TOO_MANY:
            gen_goto_tb(dc, 1, curr_insn_len(dc));
            break;
        case DISAS_UPDATE_NOCHAIN:
            gen_update_pc(dc, curr_insn_len(dc));
            /* fall through */
        case DISAS_JUMP:
            gen_goto_ptr();
            break;
        case DISAS_UPDATE_EXIT:
            gen_update_pc(dc, curr_insn_len(dc));
            /* fall through */
        default:
            /* indicate that the hash table must be used to find the next TB */
            tcg_gen_exit_tb(NULL, 0);
            break;
        case DISAS_NORETURN:
            /* nothing more to generate */
            break;
        case DISAS_WFI:
            gen_helper_wfi(tcg_env, tcg_constant_i32(curr_insn_len(dc)));
            /*
             * 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;
        case DISAS_WFE:
            gen_helper_wfe(tcg_env);
            break;
        case DISAS_YIELD:
            gen_helper_yield(tcg_env);
            break;
        case DISAS_SWI:
            gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
            break;
        case DISAS_HVC:
            gen_exception_el(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
            break;
        case DISAS_SMC:
            gen_exception_el(EXCP_SMC, syn_aa32_smc(), 3);
            break;
        }
    }

    if (dc->condjmp) {
        /* "Condition failed" instruction codepath for the branch/trap insn */
        set_disas_label(dc, dc->condlabel);
        gen_set_condexec(dc);
        if (unlikely(dc->ss_active)) {
            gen_update_pc(dc, curr_insn_len(dc));
            gen_singlestep_exception(dc);
        } else {
            gen_goto_tb(dc, 1, curr_insn_len(dc));
        }
    }

    emit_delayed_exceptions(dc);
}

static const TranslatorOps arm_translator_ops = {
    .init_disas_context = arm_tr_init_disas_context,
    .tb_start           = arm_tr_tb_start,
    .insn_start         = arm_tr_insn_start,
    .translate_insn     = arm_tr_translate_insn,
    .tb_stop            = arm_tr_tb_stop,
};

static const TranslatorOps thumb_translator_ops = {
    .init_disas_context = arm_tr_init_disas_context,
    .tb_start           = arm_tr_tb_start,
    .insn_start         = arm_tr_insn_start,
    .translate_insn     = thumb_tr_translate_insn,
    .tb_stop            = arm_tr_tb_stop,
};

void arm_translate_code(CPUState *cpu, TranslationBlock *tb,
                        int *max_insns, vaddr pc, void *host_pc)
{
    DisasContext dc = { };
    const TranslatorOps *ops = &arm_translator_ops;
    CPUARMTBFlags tb_flags = arm_tbflags_from_tb(tb);

    if (EX_TBFLAG_AM32(tb_flags, THUMB)) {
        ops = &thumb_translator_ops;
    }
#ifdef TARGET_AARCH64
    if (EX_TBFLAG_ANY(tb_flags, AARCH64_STATE)) {
        ops = &aarch64_translator_ops;
    }
#endif

    translator_loop(cpu, tb, max_insns, pc, host_pc, ops, &dc.base);
}
