qemu/target/arm/translate.c
<<
>>
Prefs
   1/*
   2 *  ARM translation
   3 *
   4 *  Copyright (c) 2003 Fabrice Bellard
   5 *  Copyright (c) 2005-2007 CodeSourcery
   6 *  Copyright (c) 2007 OpenedHand, Ltd.
   7 *
   8 * This library is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU Lesser General Public
  10 * License as published by the Free Software Foundation; either
  11 * version 2 of the License, or (at your option) any later version.
  12 *
  13 * This library is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16 * Lesser General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU Lesser General Public
  19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  20 */
  21#include "qemu/osdep.h"
  22
  23#include "cpu.h"
  24#include "internals.h"
  25#include "disas/disas.h"
  26#include "exec/exec-all.h"
  27#include "tcg-op.h"
  28#include "tcg-op-gvec.h"
  29#include "qemu/log.h"
  30#include "qemu/bitops.h"
  31#include "arm_ldst.h"
  32#include "exec/semihost.h"
  33
  34#include "exec/helper-proto.h"
  35#include "exec/helper-gen.h"
  36
  37#include "trace-tcg.h"
  38#include "exec/log.h"
  39
  40
  41#define ENABLE_ARCH_4T    arm_dc_feature(s, ARM_FEATURE_V4T)
  42#define ENABLE_ARCH_5     arm_dc_feature(s, ARM_FEATURE_V5)
  43/* currently all emulated v5 cores are also v5TE, so don't bother */
  44#define ENABLE_ARCH_5TE   arm_dc_feature(s, ARM_FEATURE_V5)
  45#define ENABLE_ARCH_5J    dc_isar_feature(jazelle, s)
  46#define ENABLE_ARCH_6     arm_dc_feature(s, ARM_FEATURE_V6)
  47#define ENABLE_ARCH_6K    arm_dc_feature(s, ARM_FEATURE_V6K)
  48#define ENABLE_ARCH_6T2   arm_dc_feature(s, ARM_FEATURE_THUMB2)
  49#define ENABLE_ARCH_7     arm_dc_feature(s, ARM_FEATURE_V7)
  50#define ENABLE_ARCH_8     arm_dc_feature(s, ARM_FEATURE_V8)
  51
  52#define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
  53
  54#include "translate.h"
  55
  56#if defined(CONFIG_USER_ONLY)
  57#define IS_USER(s) 1
  58#else
  59#define IS_USER(s) (s->user)
  60#endif
  61
  62/* We reuse the same 64-bit temporaries for efficiency.  */
  63static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
  64static TCGv_i32 cpu_R[16];
  65TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
  66TCGv_i64 cpu_exclusive_addr;
  67TCGv_i64 cpu_exclusive_val;
  68
  69/* FIXME:  These should be removed.  */
  70static TCGv_i32 cpu_F0s, cpu_F1s;
  71static TCGv_i64 cpu_F0d, cpu_F1d;
  72
  73#include "exec/gen-icount.h"
  74
  75static const char * const regnames[] =
  76    { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  77      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
  78
  79/* Function prototypes for gen_ functions calling Neon helpers.  */
  80typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
  81                                 TCGv_i32, TCGv_i32);
  82
  83/* initialize TCG globals.  */
  84void arm_translate_init(void)
  85{
  86    int i;
  87
  88    for (i = 0; i < 16; i++) {
  89        cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
  90                                          offsetof(CPUARMState, regs[i]),
  91                                          regnames[i]);
  92    }
  93    cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
  94    cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
  95    cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
  96    cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
  97
  98    cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
  99        offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
 100    cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
 101        offsetof(CPUARMState, exclusive_val), "exclusive_val");
 102
 103    a64_translate_init();
 104}
 105
 106/* Flags for the disas_set_da_iss info argument:
 107 * lower bits hold the Rt register number, higher bits are flags.
 108 */
 109typedef enum ISSInfo {
 110    ISSNone = 0,
 111    ISSRegMask = 0x1f,
 112    ISSInvalid = (1 << 5),
 113    ISSIsAcqRel = (1 << 6),
 114    ISSIsWrite = (1 << 7),
 115    ISSIs16Bit = (1 << 8),
 116} ISSInfo;
 117
 118/* Save the syndrome information for a Data Abort */
 119static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
 120{
 121    uint32_t syn;
 122    int sas = memop & MO_SIZE;
 123    bool sse = memop & MO_SIGN;
 124    bool is_acqrel = issinfo & ISSIsAcqRel;
 125    bool is_write = issinfo & ISSIsWrite;
 126    bool is_16bit = issinfo & ISSIs16Bit;
 127    int srt = issinfo & ISSRegMask;
 128
 129    if (issinfo & ISSInvalid) {
 130        /* Some callsites want to conditionally provide ISS info,
 131         * eg "only if this was not a writeback"
 132         */
 133        return;
 134    }
 135
 136    if (srt == 15) {
 137        /* For AArch32, insns where the src/dest is R15 never generate
 138         * ISS information. Catching that here saves checking at all
 139         * the call sites.
 140         */
 141        return;
 142    }
 143
 144    syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
 145                                  0, 0, 0, is_write, 0, is_16bit);
 146    disas_set_insn_syndrome(s, syn);
 147}
 148
 149static inline int get_a32_user_mem_index(DisasContext *s)
 150{
 151    /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
 152     * insns:
 153     *  if PL2, UNPREDICTABLE (we choose to implement as if PL0)
 154     *  otherwise, access as if at PL0.
 155     */
 156    switch (s->mmu_idx) {
 157    case ARMMMUIdx_S1E2:        /* this one is UNPREDICTABLE */
 158    case ARMMMUIdx_S12NSE0:
 159    case ARMMMUIdx_S12NSE1:
 160        return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
 161    case ARMMMUIdx_S1E3:
 162    case ARMMMUIdx_S1SE0:
 163    case ARMMMUIdx_S1SE1:
 164        return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
 165    case ARMMMUIdx_MUser:
 166    case ARMMMUIdx_MPriv:
 167        return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
 168    case ARMMMUIdx_MUserNegPri:
 169    case ARMMMUIdx_MPrivNegPri:
 170        return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
 171    case ARMMMUIdx_MSUser:
 172    case ARMMMUIdx_MSPriv:
 173        return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
 174    case ARMMMUIdx_MSUserNegPri:
 175    case ARMMMUIdx_MSPrivNegPri:
 176        return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
 177    case ARMMMUIdx_S2NS:
 178    default:
 179        g_assert_not_reached();
 180    }
 181}
 182
 183static inline TCGv_i32 load_cpu_offset(int offset)
 184{
 185    TCGv_i32 tmp = tcg_temp_new_i32();
 186    tcg_gen_ld_i32(tmp, cpu_env, offset);
 187    return tmp;
 188}
 189
 190#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
 191
 192static inline void store_cpu_offset(TCGv_i32 var, int offset)
 193{
 194    tcg_gen_st_i32(var, cpu_env, offset);
 195    tcg_temp_free_i32(var);
 196}
 197
 198#define store_cpu_field(var, name) \
 199    store_cpu_offset(var, offsetof(CPUARMState, name))
 200
 201/* Set a variable to the value of a CPU register.  */
 202static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
 203{
 204    if (reg == 15) {
 205        uint32_t addr;
 206        /* normally, since we updated PC, we need only to add one insn */
 207        if (s->thumb)
 208            addr = (long)s->pc + 2;
 209        else
 210            addr = (long)s->pc + 4;
 211        tcg_gen_movi_i32(var, addr);
 212    } else {
 213        tcg_gen_mov_i32(var, cpu_R[reg]);
 214    }
 215}
 216
 217/* Create a new temporary and set it to the value of a CPU register.  */
 218static inline TCGv_i32 load_reg(DisasContext *s, int reg)
 219{
 220    TCGv_i32 tmp = tcg_temp_new_i32();
 221    load_reg_var(s, tmp, reg);
 222    return tmp;
 223}
 224
 225/* Set a CPU register.  The source must be a temporary and will be
 226   marked as dead.  */
 227static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
 228{
 229    if (reg == 15) {
 230        /* In Thumb mode, we must ignore bit 0.
 231         * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
 232         * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
 233         * We choose to ignore [1:0] in ARM mode for all architecture versions.
 234         */
 235        tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
 236        s->base.is_jmp = DISAS_JUMP;
 237    }
 238    tcg_gen_mov_i32(cpu_R[reg], var);
 239    tcg_temp_free_i32(var);
 240}
 241
 242/*
 243 * Variant of store_reg which applies v8M stack-limit checks before updating
 244 * SP. If the check fails this will result in an exception being taken.
 245 * We disable the stack checks for CONFIG_USER_ONLY because we have
 246 * no idea what the stack limits should be in that case.
 247 * If stack checking is not being done this just acts like store_reg().
 248 */
 249static void store_sp_checked(DisasContext *s, TCGv_i32 var)
 250{
 251#ifndef CONFIG_USER_ONLY
 252    if (s->v8m_stackcheck) {
 253        gen_helper_v8m_stackcheck(cpu_env, var);
 254    }
 255#endif
 256    store_reg(s, 13, var);
 257}
 258
 259/* Value extensions.  */
 260#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
 261#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
 262#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
 263#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
 264
 265#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
 266#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
 267
 268
 269static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
 270{
 271    TCGv_i32 tmp_mask = tcg_const_i32(mask);
 272    gen_helper_cpsr_write(cpu_env, var, tmp_mask);
 273    tcg_temp_free_i32(tmp_mask);
 274}
 275/* Set NZCV flags from the high 4 bits of var.  */
 276#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
 277
 278static void gen_exception_internal(int excp)
 279{
 280    TCGv_i32 tcg_excp = tcg_const_i32(excp);
 281
 282    assert(excp_is_internal(excp));
 283    gen_helper_exception_internal(cpu_env, tcg_excp);
 284    tcg_temp_free_i32(tcg_excp);
 285}
 286
 287static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
 288{
 289    TCGv_i32 tcg_excp = tcg_const_i32(excp);
 290    TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
 291    TCGv_i32 tcg_el = tcg_const_i32(target_el);
 292
 293    gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
 294                                       tcg_syn, tcg_el);
 295
 296    tcg_temp_free_i32(tcg_el);
 297    tcg_temp_free_i32(tcg_syn);
 298    tcg_temp_free_i32(tcg_excp);
 299}
 300
 301static void gen_step_complete_exception(DisasContext *s)
 302{
 303    /* We just completed step of an insn. Move from Active-not-pending
 304     * to Active-pending, and then also take the swstep exception.
 305     * This corresponds to making the (IMPDEF) choice to prioritize
 306     * swstep exceptions over asynchronous exceptions taken to an exception
 307     * level where debug is disabled. This choice has the advantage that
 308     * we do not need to maintain internal state corresponding to the
 309     * ISV/EX syndrome bits between completion of the step and generation
 310     * of the exception, and our syndrome information is always correct.
 311     */
 312    gen_ss_advance(s);
 313    gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
 314                  default_exception_el(s));
 315    s->base.is_jmp = DISAS_NORETURN;
 316}
 317
 318static void gen_singlestep_exception(DisasContext *s)
 319{
 320    /* Generate the right kind of exception for singlestep, which is
 321     * either the architectural singlestep or EXCP_DEBUG for QEMU's
 322     * gdb singlestepping.
 323     */
 324    if (s->ss_active) {
 325        gen_step_complete_exception(s);
 326    } else {
 327        gen_exception_internal(EXCP_DEBUG);
 328    }
 329}
 330
 331static inline bool is_singlestepping(DisasContext *s)
 332{
 333    /* Return true if we are singlestepping either because of
 334     * architectural singlestep or QEMU gdbstub singlestep. This does
 335     * not include the command line '-singlestep' mode which is rather
 336     * misnamed as it only means "one instruction per TB" and doesn't
 337     * affect the code we generate.
 338     */
 339    return s->base.singlestep_enabled || s->ss_active;
 340}
 341
 342static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
 343{
 344    TCGv_i32 tmp1 = tcg_temp_new_i32();
 345    TCGv_i32 tmp2 = tcg_temp_new_i32();
 346    tcg_gen_ext16s_i32(tmp1, a);
 347    tcg_gen_ext16s_i32(tmp2, b);
 348    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
 349    tcg_temp_free_i32(tmp2);
 350    tcg_gen_sari_i32(a, a, 16);
 351    tcg_gen_sari_i32(b, b, 16);
 352    tcg_gen_mul_i32(b, b, a);
 353    tcg_gen_mov_i32(a, tmp1);
 354    tcg_temp_free_i32(tmp1);
 355}
 356
 357/* Byteswap each halfword.  */
 358static void gen_rev16(TCGv_i32 var)
 359{
 360    TCGv_i32 tmp = tcg_temp_new_i32();
 361    TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
 362    tcg_gen_shri_i32(tmp, var, 8);
 363    tcg_gen_and_i32(tmp, tmp, mask);
 364    tcg_gen_and_i32(var, var, mask);
 365    tcg_gen_shli_i32(var, var, 8);
 366    tcg_gen_or_i32(var, var, tmp);
 367    tcg_temp_free_i32(mask);
 368    tcg_temp_free_i32(tmp);
 369}
 370
 371/* Byteswap low halfword and sign extend.  */
 372static void gen_revsh(TCGv_i32 var)
 373{
 374    tcg_gen_ext16u_i32(var, var);
 375    tcg_gen_bswap16_i32(var, var);
 376    tcg_gen_ext16s_i32(var, var);
 377}
 378
 379/* Return (b << 32) + a. Mark inputs as dead */
 380static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
 381{
 382    TCGv_i64 tmp64 = tcg_temp_new_i64();
 383
 384    tcg_gen_extu_i32_i64(tmp64, b);
 385    tcg_temp_free_i32(b);
 386    tcg_gen_shli_i64(tmp64, tmp64, 32);
 387    tcg_gen_add_i64(a, tmp64, a);
 388
 389    tcg_temp_free_i64(tmp64);
 390    return a;
 391}
 392
 393/* Return (b << 32) - a. Mark inputs as dead. */
 394static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
 395{
 396    TCGv_i64 tmp64 = tcg_temp_new_i64();
 397
 398    tcg_gen_extu_i32_i64(tmp64, b);
 399    tcg_temp_free_i32(b);
 400    tcg_gen_shli_i64(tmp64, tmp64, 32);
 401    tcg_gen_sub_i64(a, tmp64, a);
 402
 403    tcg_temp_free_i64(tmp64);
 404    return a;
 405}
 406
 407/* 32x32->64 multiply.  Marks inputs as dead.  */
 408static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
 409{
 410    TCGv_i32 lo = tcg_temp_new_i32();
 411    TCGv_i32 hi = tcg_temp_new_i32();
 412    TCGv_i64 ret;
 413
 414    tcg_gen_mulu2_i32(lo, hi, a, b);
 415    tcg_temp_free_i32(a);
 416    tcg_temp_free_i32(b);
 417
 418    ret = tcg_temp_new_i64();
 419    tcg_gen_concat_i32_i64(ret, lo, hi);
 420    tcg_temp_free_i32(lo);
 421    tcg_temp_free_i32(hi);
 422
 423    return ret;
 424}
 425
 426static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
 427{
 428    TCGv_i32 lo = tcg_temp_new_i32();
 429    TCGv_i32 hi = tcg_temp_new_i32();
 430    TCGv_i64 ret;
 431
 432    tcg_gen_muls2_i32(lo, hi, a, b);
 433    tcg_temp_free_i32(a);
 434    tcg_temp_free_i32(b);
 435
 436    ret = tcg_temp_new_i64();
 437    tcg_gen_concat_i32_i64(ret, lo, hi);
 438    tcg_temp_free_i32(lo);
 439    tcg_temp_free_i32(hi);
 440
 441    return ret;
 442}
 443
 444/* Swap low and high halfwords.  */
 445static void gen_swap_half(TCGv_i32 var)
 446{
 447    TCGv_i32 tmp = tcg_temp_new_i32();
 448    tcg_gen_shri_i32(tmp, var, 16);
 449    tcg_gen_shli_i32(var, var, 16);
 450    tcg_gen_or_i32(var, var, tmp);
 451    tcg_temp_free_i32(tmp);
 452}
 453
 454/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
 455    tmp = (t0 ^ t1) & 0x8000;
 456    t0 &= ~0x8000;
 457    t1 &= ~0x8000;
 458    t0 = (t0 + t1) ^ tmp;
 459 */
 460
 461static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
 462{
 463    TCGv_i32 tmp = tcg_temp_new_i32();
 464    tcg_gen_xor_i32(tmp, t0, t1);
 465    tcg_gen_andi_i32(tmp, tmp, 0x8000);
 466    tcg_gen_andi_i32(t0, t0, ~0x8000);
 467    tcg_gen_andi_i32(t1, t1, ~0x8000);
 468    tcg_gen_add_i32(t0, t0, t1);
 469    tcg_gen_xor_i32(t0, t0, tmp);
 470    tcg_temp_free_i32(tmp);
 471    tcg_temp_free_i32(t1);
 472}
 473
 474/* Set CF to the top bit of var.  */
 475static void gen_set_CF_bit31(TCGv_i32 var)
 476{
 477    tcg_gen_shri_i32(cpu_CF, var, 31);
 478}
 479
 480/* Set N and Z flags from var.  */
 481static inline void gen_logic_CC(TCGv_i32 var)
 482{
 483    tcg_gen_mov_i32(cpu_NF, var);
 484    tcg_gen_mov_i32(cpu_ZF, var);
 485}
 486
 487/* T0 += T1 + CF.  */
 488static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
 489{
 490    tcg_gen_add_i32(t0, t0, t1);
 491    tcg_gen_add_i32(t0, t0, cpu_CF);
 492}
 493
 494/* dest = T0 + T1 + CF. */
 495static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 496{
 497    tcg_gen_add_i32(dest, t0, t1);
 498    tcg_gen_add_i32(dest, dest, cpu_CF);
 499}
 500
 501/* dest = T0 - T1 + CF - 1.  */
 502static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 503{
 504    tcg_gen_sub_i32(dest, t0, t1);
 505    tcg_gen_add_i32(dest, dest, cpu_CF);
 506    tcg_gen_subi_i32(dest, dest, 1);
 507}
 508
 509/* dest = T0 + T1. Compute C, N, V and Z flags */
 510static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 511{
 512    TCGv_i32 tmp = tcg_temp_new_i32();
 513    tcg_gen_movi_i32(tmp, 0);
 514    tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
 515    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
 516    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
 517    tcg_gen_xor_i32(tmp, t0, t1);
 518    tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
 519    tcg_temp_free_i32(tmp);
 520    tcg_gen_mov_i32(dest, cpu_NF);
 521}
 522
 523/* dest = T0 + T1 + CF.  Compute C, N, V and Z flags */
 524static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 525{
 526    TCGv_i32 tmp = tcg_temp_new_i32();
 527    if (TCG_TARGET_HAS_add2_i32) {
 528        tcg_gen_movi_i32(tmp, 0);
 529        tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
 530        tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
 531    } else {
 532        TCGv_i64 q0 = tcg_temp_new_i64();
 533        TCGv_i64 q1 = tcg_temp_new_i64();
 534        tcg_gen_extu_i32_i64(q0, t0);
 535        tcg_gen_extu_i32_i64(q1, t1);
 536        tcg_gen_add_i64(q0, q0, q1);
 537        tcg_gen_extu_i32_i64(q1, cpu_CF);
 538        tcg_gen_add_i64(q0, q0, q1);
 539        tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
 540        tcg_temp_free_i64(q0);
 541        tcg_temp_free_i64(q1);
 542    }
 543    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
 544    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
 545    tcg_gen_xor_i32(tmp, t0, t1);
 546    tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
 547    tcg_temp_free_i32(tmp);
 548    tcg_gen_mov_i32(dest, cpu_NF);
 549}
 550
 551/* dest = T0 - T1. Compute C, N, V and Z flags */
 552static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 553{
 554    TCGv_i32 tmp;
 555    tcg_gen_sub_i32(cpu_NF, t0, t1);
 556    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
 557    tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
 558    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
 559    tmp = tcg_temp_new_i32();
 560    tcg_gen_xor_i32(tmp, t0, t1);
 561    tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
 562    tcg_temp_free_i32(tmp);
 563    tcg_gen_mov_i32(dest, cpu_NF);
 564}
 565
 566/* dest = T0 + ~T1 + CF.  Compute C, N, V and Z flags */
 567static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 568{
 569    TCGv_i32 tmp = tcg_temp_new_i32();
 570    tcg_gen_not_i32(tmp, t1);
 571    gen_adc_CC(dest, t0, tmp);
 572    tcg_temp_free_i32(tmp);
 573}
 574
 575#define GEN_SHIFT(name)                                               \
 576static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)       \
 577{                                                                     \
 578    TCGv_i32 tmp1, tmp2, tmp3;                                        \
 579    tmp1 = tcg_temp_new_i32();                                        \
 580    tcg_gen_andi_i32(tmp1, t1, 0xff);                                 \
 581    tmp2 = tcg_const_i32(0);                                          \
 582    tmp3 = tcg_const_i32(0x1f);                                       \
 583    tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0);    \
 584    tcg_temp_free_i32(tmp3);                                          \
 585    tcg_gen_andi_i32(tmp1, tmp1, 0x1f);                               \
 586    tcg_gen_##name##_i32(dest, tmp2, tmp1);                           \
 587    tcg_temp_free_i32(tmp2);                                          \
 588    tcg_temp_free_i32(tmp1);                                          \
 589}
 590GEN_SHIFT(shl)
 591GEN_SHIFT(shr)
 592#undef GEN_SHIFT
 593
 594static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 595{
 596    TCGv_i32 tmp1, tmp2;
 597    tmp1 = tcg_temp_new_i32();
 598    tcg_gen_andi_i32(tmp1, t1, 0xff);
 599    tmp2 = tcg_const_i32(0x1f);
 600    tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
 601    tcg_temp_free_i32(tmp2);
 602    tcg_gen_sar_i32(dest, t0, tmp1);
 603    tcg_temp_free_i32(tmp1);
 604}
 605
 606static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
 607{
 608    TCGv_i32 c0 = tcg_const_i32(0);
 609    TCGv_i32 tmp = tcg_temp_new_i32();
 610    tcg_gen_neg_i32(tmp, src);
 611    tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
 612    tcg_temp_free_i32(c0);
 613    tcg_temp_free_i32(tmp);
 614}
 615
 616static void shifter_out_im(TCGv_i32 var, int shift)
 617{
 618    if (shift == 0) {
 619        tcg_gen_andi_i32(cpu_CF, var, 1);
 620    } else {
 621        tcg_gen_shri_i32(cpu_CF, var, shift);
 622        if (shift != 31) {
 623            tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
 624        }
 625    }
 626}
 627
 628/* Shift by immediate.  Includes special handling for shift == 0.  */
 629static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
 630                                    int shift, int flags)
 631{
 632    switch (shiftop) {
 633    case 0: /* LSL */
 634        if (shift != 0) {
 635            if (flags)
 636                shifter_out_im(var, 32 - shift);
 637            tcg_gen_shli_i32(var, var, shift);
 638        }
 639        break;
 640    case 1: /* LSR */
 641        if (shift == 0) {
 642            if (flags) {
 643                tcg_gen_shri_i32(cpu_CF, var, 31);
 644            }
 645            tcg_gen_movi_i32(var, 0);
 646        } else {
 647            if (flags)
 648                shifter_out_im(var, shift - 1);
 649            tcg_gen_shri_i32(var, var, shift);
 650        }
 651        break;
 652    case 2: /* ASR */
 653        if (shift == 0)
 654            shift = 32;
 655        if (flags)
 656            shifter_out_im(var, shift - 1);
 657        if (shift == 32)
 658          shift = 31;
 659        tcg_gen_sari_i32(var, var, shift);
 660        break;
 661    case 3: /* ROR/RRX */
 662        if (shift != 0) {
 663            if (flags)
 664                shifter_out_im(var, shift - 1);
 665            tcg_gen_rotri_i32(var, var, shift); break;
 666        } else {
 667            TCGv_i32 tmp = tcg_temp_new_i32();
 668            tcg_gen_shli_i32(tmp, cpu_CF, 31);
 669            if (flags)
 670                shifter_out_im(var, 0);
 671            tcg_gen_shri_i32(var, var, 1);
 672            tcg_gen_or_i32(var, var, tmp);
 673            tcg_temp_free_i32(tmp);
 674        }
 675    }
 676};
 677
 678static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
 679                                     TCGv_i32 shift, int flags)
 680{
 681    if (flags) {
 682        switch (shiftop) {
 683        case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
 684        case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
 685        case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
 686        case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
 687        }
 688    } else {
 689        switch (shiftop) {
 690        case 0:
 691            gen_shl(var, var, shift);
 692            break;
 693        case 1:
 694            gen_shr(var, var, shift);
 695            break;
 696        case 2:
 697            gen_sar(var, var, shift);
 698            break;
 699        case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
 700                tcg_gen_rotr_i32(var, var, shift); break;
 701        }
 702    }
 703    tcg_temp_free_i32(shift);
 704}
 705
 706#define PAS_OP(pfx) \
 707    switch (op2) {  \
 708    case 0: gen_pas_helper(glue(pfx,add16)); break; \
 709    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
 710    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
 711    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
 712    case 4: gen_pas_helper(glue(pfx,add8)); break; \
 713    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
 714    }
 715static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
 716{
 717    TCGv_ptr tmp;
 718
 719    switch (op1) {
 720#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
 721    case 1:
 722        tmp = tcg_temp_new_ptr();
 723        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
 724        PAS_OP(s)
 725        tcg_temp_free_ptr(tmp);
 726        break;
 727    case 5:
 728        tmp = tcg_temp_new_ptr();
 729        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
 730        PAS_OP(u)
 731        tcg_temp_free_ptr(tmp);
 732        break;
 733#undef gen_pas_helper
 734#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
 735    case 2:
 736        PAS_OP(q);
 737        break;
 738    case 3:
 739        PAS_OP(sh);
 740        break;
 741    case 6:
 742        PAS_OP(uq);
 743        break;
 744    case 7:
 745        PAS_OP(uh);
 746        break;
 747#undef gen_pas_helper
 748    }
 749}
 750#undef PAS_OP
 751
 752/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
 753#define PAS_OP(pfx) \
 754    switch (op1) {  \
 755    case 0: gen_pas_helper(glue(pfx,add8)); break; \
 756    case 1: gen_pas_helper(glue(pfx,add16)); break; \
 757    case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
 758    case 4: gen_pas_helper(glue(pfx,sub8)); break; \
 759    case 5: gen_pas_helper(glue(pfx,sub16)); break; \
 760    case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
 761    }
 762static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
 763{
 764    TCGv_ptr tmp;
 765
 766    switch (op2) {
 767#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
 768    case 0:
 769        tmp = tcg_temp_new_ptr();
 770        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
 771        PAS_OP(s)
 772        tcg_temp_free_ptr(tmp);
 773        break;
 774    case 4:
 775        tmp = tcg_temp_new_ptr();
 776        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
 777        PAS_OP(u)
 778        tcg_temp_free_ptr(tmp);
 779        break;
 780#undef gen_pas_helper
 781#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
 782    case 1:
 783        PAS_OP(q);
 784        break;
 785    case 2:
 786        PAS_OP(sh);
 787        break;
 788    case 5:
 789        PAS_OP(uq);
 790        break;
 791    case 6:
 792        PAS_OP(uh);
 793        break;
 794#undef gen_pas_helper
 795    }
 796}
 797#undef PAS_OP
 798
 799/*
 800 * Generate a conditional based on ARM condition code cc.
 801 * This is common between ARM and Aarch64 targets.
 802 */
 803void arm_test_cc(DisasCompare *cmp, int cc)
 804{
 805    TCGv_i32 value;
 806    TCGCond cond;
 807    bool global = true;
 808
 809    switch (cc) {
 810    case 0: /* eq: Z */
 811    case 1: /* ne: !Z */
 812        cond = TCG_COND_EQ;
 813        value = cpu_ZF;
 814        break;
 815
 816    case 2: /* cs: C */
 817    case 3: /* cc: !C */
 818        cond = TCG_COND_NE;
 819        value = cpu_CF;
 820        break;
 821
 822    case 4: /* mi: N */
 823    case 5: /* pl: !N */
 824        cond = TCG_COND_LT;
 825        value = cpu_NF;
 826        break;
 827
 828    case 6: /* vs: V */
 829    case 7: /* vc: !V */
 830        cond = TCG_COND_LT;
 831        value = cpu_VF;
 832        break;
 833
 834    case 8: /* hi: C && !Z */
 835    case 9: /* ls: !C || Z -> !(C && !Z) */
 836        cond = TCG_COND_NE;
 837        value = tcg_temp_new_i32();
 838        global = false;
 839        /* CF is 1 for C, so -CF is an all-bits-set mask for C;
 840           ZF is non-zero for !Z; so AND the two subexpressions.  */
 841        tcg_gen_neg_i32(value, cpu_CF);
 842        tcg_gen_and_i32(value, value, cpu_ZF);
 843        break;
 844
 845    case 10: /* ge: N == V -> N ^ V == 0 */
 846    case 11: /* lt: N != V -> N ^ V != 0 */
 847        /* Since we're only interested in the sign bit, == 0 is >= 0.  */
 848        cond = TCG_COND_GE;
 849        value = tcg_temp_new_i32();
 850        global = false;
 851        tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
 852        break;
 853
 854    case 12: /* gt: !Z && N == V */
 855    case 13: /* le: Z || N != V */
 856        cond = TCG_COND_NE;
 857        value = tcg_temp_new_i32();
 858        global = false;
 859        /* (N == V) is equal to the sign bit of ~(NF ^ VF).  Propagate
 860         * the sign bit then AND with ZF to yield the result.  */
 861        tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
 862        tcg_gen_sari_i32(value, value, 31);
 863        tcg_gen_andc_i32(value, cpu_ZF, value);
 864        break;
 865
 866    case 14: /* always */
 867    case 15: /* always */
 868        /* Use the ALWAYS condition, which will fold early.
 869         * It doesn't matter what we use for the value.  */
 870        cond = TCG_COND_ALWAYS;
 871        value = cpu_ZF;
 872        goto no_invert;
 873
 874    default:
 875        fprintf(stderr, "Bad condition code 0x%x\n", cc);
 876        abort();
 877    }
 878
 879    if (cc & 1) {
 880        cond = tcg_invert_cond(cond);
 881    }
 882
 883 no_invert:
 884    cmp->cond = cond;
 885    cmp->value = value;
 886    cmp->value_global = global;
 887}
 888
 889void arm_free_cc(DisasCompare *cmp)
 890{
 891    if (!cmp->value_global) {
 892        tcg_temp_free_i32(cmp->value);
 893    }
 894}
 895
 896void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
 897{
 898    tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
 899}
 900
 901void arm_gen_test_cc(int cc, TCGLabel *label)
 902{
 903    DisasCompare cmp;
 904    arm_test_cc(&cmp, cc);
 905    arm_jump_cc(&cmp, label);
 906    arm_free_cc(&cmp);
 907}
 908
 909static const uint8_t table_logic_cc[16] = {
 910    1, /* and */
 911    1, /* xor */
 912    0, /* sub */
 913    0, /* rsb */
 914    0, /* add */
 915    0, /* adc */
 916    0, /* sbc */
 917    0, /* rsc */
 918    1, /* andl */
 919    1, /* xorl */
 920    0, /* cmp */
 921    0, /* cmn */
 922    1, /* orr */
 923    1, /* mov */
 924    1, /* bic */
 925    1, /* mvn */
 926};
 927
 928static inline void gen_set_condexec(DisasContext *s)
 929{
 930    if (s->condexec_mask) {
 931        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
 932        TCGv_i32 tmp = tcg_temp_new_i32();
 933        tcg_gen_movi_i32(tmp, val);
 934        store_cpu_field(tmp, condexec_bits);
 935    }
 936}
 937
 938static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
 939{
 940    tcg_gen_movi_i32(cpu_R[15], val);
 941}
 942
 943/* Set PC and Thumb state from an immediate address.  */
 944static inline void gen_bx_im(DisasContext *s, uint32_t addr)
 945{
 946    TCGv_i32 tmp;
 947
 948    s->base.is_jmp = DISAS_JUMP;
 949    if (s->thumb != (addr & 1)) {
 950        tmp = tcg_temp_new_i32();
 951        tcg_gen_movi_i32(tmp, addr & 1);
 952        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
 953        tcg_temp_free_i32(tmp);
 954    }
 955    tcg_gen_movi_i32(cpu_R[15], addr & ~1);
 956}
 957
 958/* Set PC and Thumb state from var.  var is marked as dead.  */
 959static inline void gen_bx(DisasContext *s, TCGv_i32 var)
 960{
 961    s->base.is_jmp = DISAS_JUMP;
 962    tcg_gen_andi_i32(cpu_R[15], var, ~1);
 963    tcg_gen_andi_i32(var, var, 1);
 964    store_cpu_field(var, thumb);
 965}
 966
 967/* Set PC and Thumb state from var. var is marked as dead.
 968 * For M-profile CPUs, include logic to detect exception-return
 969 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
 970 * and BX reg, and no others, and happens only for code in Handler mode.
 971 */
 972static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
 973{
 974    /* Generate the same code here as for a simple bx, but flag via
 975     * s->base.is_jmp that we need to do the rest of the work later.
 976     */
 977    gen_bx(s, var);
 978    if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
 979        (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
 980        s->base.is_jmp = DISAS_BX_EXCRET;
 981    }
 982}
 983
 984static inline void gen_bx_excret_final_code(DisasContext *s)
 985{
 986    /* Generate the code to finish possible exception return and end the TB */
 987    TCGLabel *excret_label = gen_new_label();
 988    uint32_t min_magic;
 989
 990    if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
 991        /* Covers FNC_RETURN and EXC_RETURN magic */
 992        min_magic = FNC_RETURN_MIN_MAGIC;
 993    } else {
 994        /* EXC_RETURN magic only */
 995        min_magic = EXC_RETURN_MIN_MAGIC;
 996    }
 997
 998    /* Is the new PC value in the magic range indicating exception return? */
 999    tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
1000    /* No: end the TB as we would for a DISAS_JMP */
1001    if (is_singlestepping(s)) {
1002        gen_singlestep_exception(s);
1003    } else {
1004        tcg_gen_exit_tb(NULL, 0);
1005    }
1006    gen_set_label(excret_label);
1007    /* Yes: this is an exception return.
1008     * At this point in runtime env->regs[15] and env->thumb will hold
1009     * the exception-return magic number, which do_v7m_exception_exit()
1010     * will read. Nothing else will be able to see those values because
1011     * the cpu-exec main loop guarantees that we will always go straight
1012     * from raising the exception to the exception-handling code.
1013     *
1014     * gen_ss_advance(s) does nothing on M profile currently but
1015     * calling it is conceptually the right thing as we have executed
1016     * this instruction (compare SWI, HVC, SMC handling).
1017     */
1018    gen_ss_advance(s);
1019    gen_exception_internal(EXCP_EXCEPTION_EXIT);
1020}
1021
1022static inline void gen_bxns(DisasContext *s, int rm)
1023{
1024    TCGv_i32 var = load_reg(s, rm);
1025
1026    /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1027     * we need to sync state before calling it, but:
1028     *  - we don't need to do gen_set_pc_im() because the bxns helper will
1029     *    always set the PC itself
1030     *  - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1031     *    unless it's outside an IT block or the last insn in an IT block,
1032     *    so we know that condexec == 0 (already set at the top of the TB)
1033     *    is correct in the non-UNPREDICTABLE cases, and we can choose
1034     *    "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1035     */
1036    gen_helper_v7m_bxns(cpu_env, var);
1037    tcg_temp_free_i32(var);
1038    s->base.is_jmp = DISAS_EXIT;
1039}
1040
1041static inline void gen_blxns(DisasContext *s, int rm)
1042{
1043    TCGv_i32 var = load_reg(s, rm);
1044
1045    /* We don't need to sync condexec state, for the same reason as bxns.
1046     * We do however need to set the PC, because the blxns helper reads it.
1047     * The blxns helper may throw an exception.
1048     */
1049    gen_set_pc_im(s, s->pc);
1050    gen_helper_v7m_blxns(cpu_env, var);
1051    tcg_temp_free_i32(var);
1052    s->base.is_jmp = DISAS_EXIT;
1053}
1054
1055/* Variant of store_reg which uses branch&exchange logic when storing
1056   to r15 in ARM architecture v7 and above. The source must be a temporary
1057   and will be marked as dead. */
1058static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1059{
1060    if (reg == 15 && ENABLE_ARCH_7) {
1061        gen_bx(s, var);
1062    } else {
1063        store_reg(s, reg, var);
1064    }
1065}
1066
1067/* Variant of store_reg which uses branch&exchange logic when storing
1068 * to r15 in ARM architecture v5T and above. This is used for storing
1069 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1070 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1071static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1072{
1073    if (reg == 15 && ENABLE_ARCH_5) {
1074        gen_bx_excret(s, var);
1075    } else {
1076        store_reg(s, reg, var);
1077    }
1078}
1079
1080#ifdef CONFIG_USER_ONLY
1081#define IS_USER_ONLY 1
1082#else
1083#define IS_USER_ONLY 0
1084#endif
1085
1086/* Abstractions of "generate code to do a guest load/store for
1087 * AArch32", where a vaddr is always 32 bits (and is zero
1088 * extended if we're a 64 bit core) and  data is also
1089 * 32 bits unless specifically doing a 64 bit access.
1090 * These functions work like tcg_gen_qemu_{ld,st}* except
1091 * that the address argument is TCGv_i32 rather than TCGv.
1092 */
1093
1094static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1095{
1096    TCGv addr = tcg_temp_new();
1097    tcg_gen_extu_i32_tl(addr, a32);
1098
1099    /* Not needed for user-mode BE32, where we use MO_BE instead.  */
1100    if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1101        tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1102    }
1103    return addr;
1104}
1105
1106static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1107                            int index, TCGMemOp opc)
1108{
1109    TCGv addr;
1110
1111    if (arm_dc_feature(s, ARM_FEATURE_M) &&
1112        !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1113        opc |= MO_ALIGN;
1114    }
1115
1116    addr = gen_aa32_addr(s, a32, opc);
1117    tcg_gen_qemu_ld_i32(val, addr, index, opc);
1118    tcg_temp_free(addr);
1119}
1120
1121static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1122                            int index, TCGMemOp opc)
1123{
1124    TCGv addr;
1125
1126    if (arm_dc_feature(s, ARM_FEATURE_M) &&
1127        !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1128        opc |= MO_ALIGN;
1129    }
1130
1131    addr = gen_aa32_addr(s, a32, opc);
1132    tcg_gen_qemu_st_i32(val, addr, index, opc);
1133    tcg_temp_free(addr);
1134}
1135
1136#define DO_GEN_LD(SUFF, OPC)                                             \
1137static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val,      \
1138                                     TCGv_i32 a32, int index)            \
1139{                                                                        \
1140    gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data);               \
1141}                                                                        \
1142static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s,              \
1143                                           TCGv_i32 val,                 \
1144                                           TCGv_i32 a32, int index,      \
1145                                           ISSInfo issinfo)              \
1146{                                                                        \
1147    gen_aa32_ld##SUFF(s, val, a32, index);                               \
1148    disas_set_da_iss(s, OPC, issinfo);                                   \
1149}
1150
1151#define DO_GEN_ST(SUFF, OPC)                                             \
1152static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val,      \
1153                                     TCGv_i32 a32, int index)            \
1154{                                                                        \
1155    gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data);               \
1156}                                                                        \
1157static inline void gen_aa32_st##SUFF##_iss(DisasContext *s,              \
1158                                           TCGv_i32 val,                 \
1159                                           TCGv_i32 a32, int index,      \
1160                                           ISSInfo issinfo)              \
1161{                                                                        \
1162    gen_aa32_st##SUFF(s, val, a32, index);                               \
1163    disas_set_da_iss(s, OPC, issinfo | ISSIsWrite);                      \
1164}
1165
1166static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1167{
1168    /* Not needed for user-mode BE32, where we use MO_BE instead.  */
1169    if (!IS_USER_ONLY && s->sctlr_b) {
1170        tcg_gen_rotri_i64(val, val, 32);
1171    }
1172}
1173
1174static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1175                            int index, TCGMemOp opc)
1176{
1177    TCGv addr = gen_aa32_addr(s, a32, opc);
1178    tcg_gen_qemu_ld_i64(val, addr, index, opc);
1179    gen_aa32_frob64(s, val);
1180    tcg_temp_free(addr);
1181}
1182
1183static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1184                                 TCGv_i32 a32, int index)
1185{
1186    gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1187}
1188
1189static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1190                            int index, TCGMemOp opc)
1191{
1192    TCGv addr = gen_aa32_addr(s, a32, opc);
1193
1194    /* Not needed for user-mode BE32, where we use MO_BE instead.  */
1195    if (!IS_USER_ONLY && s->sctlr_b) {
1196        TCGv_i64 tmp = tcg_temp_new_i64();
1197        tcg_gen_rotri_i64(tmp, val, 32);
1198        tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1199        tcg_temp_free_i64(tmp);
1200    } else {
1201        tcg_gen_qemu_st_i64(val, addr, index, opc);
1202    }
1203    tcg_temp_free(addr);
1204}
1205
1206static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1207                                 TCGv_i32 a32, int index)
1208{
1209    gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1210}
1211
1212DO_GEN_LD(8s, MO_SB)
1213DO_GEN_LD(8u, MO_UB)
1214DO_GEN_LD(16s, MO_SW)
1215DO_GEN_LD(16u, MO_UW)
1216DO_GEN_LD(32u, MO_UL)
1217DO_GEN_ST(8, MO_UB)
1218DO_GEN_ST(16, MO_UW)
1219DO_GEN_ST(32, MO_UL)
1220
1221static inline void gen_hvc(DisasContext *s, int imm16)
1222{
1223    /* The pre HVC helper handles cases when HVC gets trapped
1224     * as an undefined insn by runtime configuration (ie before
1225     * the insn really executes).
1226     */
1227    gen_set_pc_im(s, s->pc - 4);
1228    gen_helper_pre_hvc(cpu_env);
1229    /* Otherwise we will treat this as a real exception which
1230     * happens after execution of the insn. (The distinction matters
1231     * for the PC value reported to the exception handler and also
1232     * for single stepping.)
1233     */
1234    s->svc_imm = imm16;
1235    gen_set_pc_im(s, s->pc);
1236    s->base.is_jmp = DISAS_HVC;
1237}
1238
1239static inline void gen_smc(DisasContext *s)
1240{
1241    /* As with HVC, we may take an exception either before or after
1242     * the insn executes.
1243     */
1244    TCGv_i32 tmp;
1245
1246    gen_set_pc_im(s, s->pc - 4);
1247    tmp = tcg_const_i32(syn_aa32_smc());
1248    gen_helper_pre_smc(cpu_env, tmp);
1249    tcg_temp_free_i32(tmp);
1250    gen_set_pc_im(s, s->pc);
1251    s->base.is_jmp = DISAS_SMC;
1252}
1253
1254static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1255{
1256    gen_set_condexec(s);
1257    gen_set_pc_im(s, s->pc - offset);
1258    gen_exception_internal(excp);
1259    s->base.is_jmp = DISAS_NORETURN;
1260}
1261
1262static void gen_exception_insn(DisasContext *s, int offset, int excp,
1263                               int syn, uint32_t target_el)
1264{
1265    gen_set_condexec(s);
1266    gen_set_pc_im(s, s->pc - offset);
1267    gen_exception(excp, syn, target_el);
1268    s->base.is_jmp = DISAS_NORETURN;
1269}
1270
1271static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1272{
1273    TCGv_i32 tcg_syn;
1274
1275    gen_set_condexec(s);
1276    gen_set_pc_im(s, s->pc - offset);
1277    tcg_syn = tcg_const_i32(syn);
1278    gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1279    tcg_temp_free_i32(tcg_syn);
1280    s->base.is_jmp = DISAS_NORETURN;
1281}
1282
1283/* Force a TB lookup after an instruction that changes the CPU state.  */
1284static inline void gen_lookup_tb(DisasContext *s)
1285{
1286    tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1287    s->base.is_jmp = DISAS_EXIT;
1288}
1289
1290static inline void gen_hlt(DisasContext *s, int imm)
1291{
1292    /* HLT. This has two purposes.
1293     * Architecturally, it is an external halting debug instruction.
1294     * Since QEMU doesn't implement external debug, we treat this as
1295     * it is required for halting debug disabled: it will UNDEF.
1296     * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1297     * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1298     * must trigger semihosting even for ARMv7 and earlier, where
1299     * HLT was an undefined encoding.
1300     * In system mode, we don't allow userspace access to
1301     * semihosting, to provide some semblance of security
1302     * (and for consistency with our 32-bit semihosting).
1303     */
1304    if (semihosting_enabled() &&
1305#ifndef CONFIG_USER_ONLY
1306        s->current_el != 0 &&
1307#endif
1308        (imm == (s->thumb ? 0x3c : 0xf000))) {
1309        gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1310        return;
1311    }
1312
1313    gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1314                       default_exception_el(s));
1315}
1316
1317static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1318                                       TCGv_i32 var)
1319{
1320    int val, rm, shift, shiftop;
1321    TCGv_i32 offset;
1322
1323    if (!(insn & (1 << 25))) {
1324        /* immediate */
1325        val = insn & 0xfff;
1326        if (!(insn & (1 << 23)))
1327            val = -val;
1328        if (val != 0)
1329            tcg_gen_addi_i32(var, var, val);
1330    } else {
1331        /* shift/register */
1332        rm = (insn) & 0xf;
1333        shift = (insn >> 7) & 0x1f;
1334        shiftop = (insn >> 5) & 3;
1335        offset = load_reg(s, rm);
1336        gen_arm_shift_im(offset, shiftop, shift, 0);
1337        if (!(insn & (1 << 23)))
1338            tcg_gen_sub_i32(var, var, offset);
1339        else
1340            tcg_gen_add_i32(var, var, offset);
1341        tcg_temp_free_i32(offset);
1342    }
1343}
1344
1345static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1346                                        int extra, TCGv_i32 var)
1347{
1348    int val, rm;
1349    TCGv_i32 offset;
1350
1351    if (insn & (1 << 22)) {
1352        /* immediate */
1353        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1354        if (!(insn & (1 << 23)))
1355            val = -val;
1356        val += extra;
1357        if (val != 0)
1358            tcg_gen_addi_i32(var, var, val);
1359    } else {
1360        /* register */
1361        if (extra)
1362            tcg_gen_addi_i32(var, var, extra);
1363        rm = (insn) & 0xf;
1364        offset = load_reg(s, rm);
1365        if (!(insn & (1 << 23)))
1366            tcg_gen_sub_i32(var, var, offset);
1367        else
1368            tcg_gen_add_i32(var, var, offset);
1369        tcg_temp_free_i32(offset);
1370    }
1371}
1372
1373static TCGv_ptr get_fpstatus_ptr(int neon)
1374{
1375    TCGv_ptr statusptr = tcg_temp_new_ptr();
1376    int offset;
1377    if (neon) {
1378        offset = offsetof(CPUARMState, vfp.standard_fp_status);
1379    } else {
1380        offset = offsetof(CPUARMState, vfp.fp_status);
1381    }
1382    tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1383    return statusptr;
1384}
1385
1386#define VFP_OP2(name)                                                 \
1387static inline void gen_vfp_##name(int dp)                             \
1388{                                                                     \
1389    TCGv_ptr fpst = get_fpstatus_ptr(0);                              \
1390    if (dp) {                                                         \
1391        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst);    \
1392    } else {                                                          \
1393        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst);    \
1394    }                                                                 \
1395    tcg_temp_free_ptr(fpst);                                          \
1396}
1397
1398VFP_OP2(add)
1399VFP_OP2(sub)
1400VFP_OP2(mul)
1401VFP_OP2(div)
1402
1403#undef VFP_OP2
1404
1405static inline void gen_vfp_F1_mul(int dp)
1406{
1407    /* Like gen_vfp_mul() but put result in F1 */
1408    TCGv_ptr fpst = get_fpstatus_ptr(0);
1409    if (dp) {
1410        gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1411    } else {
1412        gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1413    }
1414    tcg_temp_free_ptr(fpst);
1415}
1416
1417static inline void gen_vfp_F1_neg(int dp)
1418{
1419    /* Like gen_vfp_neg() but put result in F1 */
1420    if (dp) {
1421        gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1422    } else {
1423        gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1424    }
1425}
1426
1427static inline void gen_vfp_abs(int dp)
1428{
1429    if (dp)
1430        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1431    else
1432        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1433}
1434
1435static inline void gen_vfp_neg(int dp)
1436{
1437    if (dp)
1438        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1439    else
1440        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1441}
1442
1443static inline void gen_vfp_sqrt(int dp)
1444{
1445    if (dp)
1446        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1447    else
1448        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1449}
1450
1451static inline void gen_vfp_cmp(int dp)
1452{
1453    if (dp)
1454        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1455    else
1456        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1457}
1458
1459static inline void gen_vfp_cmpe(int dp)
1460{
1461    if (dp)
1462        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1463    else
1464        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1465}
1466
1467static inline void gen_vfp_F1_ld0(int dp)
1468{
1469    if (dp)
1470        tcg_gen_movi_i64(cpu_F1d, 0);
1471    else
1472        tcg_gen_movi_i32(cpu_F1s, 0);
1473}
1474
1475#define VFP_GEN_ITOF(name) \
1476static inline void gen_vfp_##name(int dp, int neon) \
1477{ \
1478    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1479    if (dp) { \
1480        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1481    } else { \
1482        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1483    } \
1484    tcg_temp_free_ptr(statusptr); \
1485}
1486
1487VFP_GEN_ITOF(uito)
1488VFP_GEN_ITOF(sito)
1489#undef VFP_GEN_ITOF
1490
1491#define VFP_GEN_FTOI(name) \
1492static inline void gen_vfp_##name(int dp, int neon) \
1493{ \
1494    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1495    if (dp) { \
1496        gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1497    } else { \
1498        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1499    } \
1500    tcg_temp_free_ptr(statusptr); \
1501}
1502
1503VFP_GEN_FTOI(toui)
1504VFP_GEN_FTOI(touiz)
1505VFP_GEN_FTOI(tosi)
1506VFP_GEN_FTOI(tosiz)
1507#undef VFP_GEN_FTOI
1508
1509#define VFP_GEN_FIX(name, round) \
1510static inline void gen_vfp_##name(int dp, int shift, int neon) \
1511{ \
1512    TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1513    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1514    if (dp) { \
1515        gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1516                                        statusptr); \
1517    } else { \
1518        gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1519                                        statusptr); \
1520    } \
1521    tcg_temp_free_i32(tmp_shift); \
1522    tcg_temp_free_ptr(statusptr); \
1523}
1524VFP_GEN_FIX(tosh, _round_to_zero)
1525VFP_GEN_FIX(tosl, _round_to_zero)
1526VFP_GEN_FIX(touh, _round_to_zero)
1527VFP_GEN_FIX(toul, _round_to_zero)
1528VFP_GEN_FIX(shto, )
1529VFP_GEN_FIX(slto, )
1530VFP_GEN_FIX(uhto, )
1531VFP_GEN_FIX(ulto, )
1532#undef VFP_GEN_FIX
1533
1534static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1535{
1536    if (dp) {
1537        gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1538    } else {
1539        gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1540    }
1541}
1542
1543static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1544{
1545    if (dp) {
1546        gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1547    } else {
1548        gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1549    }
1550}
1551
1552static inline long vfp_reg_offset(bool dp, unsigned reg)
1553{
1554    if (dp) {
1555        return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1556    } else {
1557        long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1558        if (reg & 1) {
1559            ofs += offsetof(CPU_DoubleU, l.upper);
1560        } else {
1561            ofs += offsetof(CPU_DoubleU, l.lower);
1562        }
1563        return ofs;
1564    }
1565}
1566
1567/* Return the offset of a 32-bit piece of a NEON register.
1568   zero is the least significant end of the register.  */
1569static inline long
1570neon_reg_offset (int reg, int n)
1571{
1572    int sreg;
1573    sreg = reg * 2 + n;
1574    return vfp_reg_offset(0, sreg);
1575}
1576
1577/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1578 * where 0 is the least significant end of the register.
1579 */
1580static inline long
1581neon_element_offset(int reg, int element, TCGMemOp size)
1582{
1583    int element_size = 1 << size;
1584    int ofs = element * element_size;
1585#ifdef HOST_WORDS_BIGENDIAN
1586    /* Calculate the offset assuming fully little-endian,
1587     * then XOR to account for the order of the 8-byte units.
1588     */
1589    if (element_size < 8) {
1590        ofs ^= 8 - element_size;
1591    }
1592#endif
1593    return neon_reg_offset(reg, 0) + ofs;
1594}
1595
1596static TCGv_i32 neon_load_reg(int reg, int pass)
1597{
1598    TCGv_i32 tmp = tcg_temp_new_i32();
1599    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1600    return tmp;
1601}
1602
1603static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
1604{
1605    long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1606
1607    switch (mop) {
1608    case MO_UB:
1609        tcg_gen_ld8u_i32(var, cpu_env, offset);
1610        break;
1611    case MO_UW:
1612        tcg_gen_ld16u_i32(var, cpu_env, offset);
1613        break;
1614    case MO_UL:
1615        tcg_gen_ld_i32(var, cpu_env, offset);
1616        break;
1617    default:
1618        g_assert_not_reached();
1619    }
1620}
1621
1622static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
1623{
1624    long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1625
1626    switch (mop) {
1627    case MO_UB:
1628        tcg_gen_ld8u_i64(var, cpu_env, offset);
1629        break;
1630    case MO_UW:
1631        tcg_gen_ld16u_i64(var, cpu_env, offset);
1632        break;
1633    case MO_UL:
1634        tcg_gen_ld32u_i64(var, cpu_env, offset);
1635        break;
1636    case MO_Q:
1637        tcg_gen_ld_i64(var, cpu_env, offset);
1638        break;
1639    default:
1640        g_assert_not_reached();
1641    }
1642}
1643
1644static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1645{
1646    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1647    tcg_temp_free_i32(var);
1648}
1649
1650static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
1651{
1652    long offset = neon_element_offset(reg, ele, size);
1653
1654    switch (size) {
1655    case MO_8:
1656        tcg_gen_st8_i32(var, cpu_env, offset);
1657        break;
1658    case MO_16:
1659        tcg_gen_st16_i32(var, cpu_env, offset);
1660        break;
1661    case MO_32:
1662        tcg_gen_st_i32(var, cpu_env, offset);
1663        break;
1664    default:
1665        g_assert_not_reached();
1666    }
1667}
1668
1669static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
1670{
1671    long offset = neon_element_offset(reg, ele, size);
1672
1673    switch (size) {
1674    case MO_8:
1675        tcg_gen_st8_i64(var, cpu_env, offset);
1676        break;
1677    case MO_16:
1678        tcg_gen_st16_i64(var, cpu_env, offset);
1679        break;
1680    case MO_32:
1681        tcg_gen_st32_i64(var, cpu_env, offset);
1682        break;
1683    case MO_64:
1684        tcg_gen_st_i64(var, cpu_env, offset);
1685        break;
1686    default:
1687        g_assert_not_reached();
1688    }
1689}
1690
1691static inline void neon_load_reg64(TCGv_i64 var, int reg)
1692{
1693    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1694}
1695
1696static inline void neon_store_reg64(TCGv_i64 var, int reg)
1697{
1698    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1699}
1700
1701static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1702{
1703    TCGv_ptr ret = tcg_temp_new_ptr();
1704    tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1705    return ret;
1706}
1707
1708#define tcg_gen_ld_f32 tcg_gen_ld_i32
1709#define tcg_gen_ld_f64 tcg_gen_ld_i64
1710#define tcg_gen_st_f32 tcg_gen_st_i32
1711#define tcg_gen_st_f64 tcg_gen_st_i64
1712
1713static inline void gen_mov_F0_vreg(int dp, int reg)
1714{
1715    if (dp)
1716        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1717    else
1718        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1719}
1720
1721static inline void gen_mov_F1_vreg(int dp, int reg)
1722{
1723    if (dp)
1724        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1725    else
1726        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1727}
1728
1729static inline void gen_mov_vreg_F0(int dp, int reg)
1730{
1731    if (dp)
1732        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1733    else
1734        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1735}
1736
1737#define ARM_CP_RW_BIT   (1 << 20)
1738
1739static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1740{
1741    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1742}
1743
1744static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1745{
1746    tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1747}
1748
1749static inline TCGv_i32 iwmmxt_load_creg(int reg)
1750{
1751    TCGv_i32 var = tcg_temp_new_i32();
1752    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1753    return var;
1754}
1755
1756static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1757{
1758    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1759    tcg_temp_free_i32(var);
1760}
1761
1762static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1763{
1764    iwmmxt_store_reg(cpu_M0, rn);
1765}
1766
1767static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1768{
1769    iwmmxt_load_reg(cpu_M0, rn);
1770}
1771
1772static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1773{
1774    iwmmxt_load_reg(cpu_V1, rn);
1775    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1776}
1777
1778static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1779{
1780    iwmmxt_load_reg(cpu_V1, rn);
1781    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1782}
1783
1784static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1785{
1786    iwmmxt_load_reg(cpu_V1, rn);
1787    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1788}
1789
1790#define IWMMXT_OP(name) \
1791static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1792{ \
1793    iwmmxt_load_reg(cpu_V1, rn); \
1794    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1795}
1796
1797#define IWMMXT_OP_ENV(name) \
1798static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1799{ \
1800    iwmmxt_load_reg(cpu_V1, rn); \
1801    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1802}
1803
1804#define IWMMXT_OP_ENV_SIZE(name) \
1805IWMMXT_OP_ENV(name##b) \
1806IWMMXT_OP_ENV(name##w) \
1807IWMMXT_OP_ENV(name##l)
1808
1809#define IWMMXT_OP_ENV1(name) \
1810static inline void gen_op_iwmmxt_##name##_M0(void) \
1811{ \
1812    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1813}
1814
1815IWMMXT_OP(maddsq)
1816IWMMXT_OP(madduq)
1817IWMMXT_OP(sadb)
1818IWMMXT_OP(sadw)
1819IWMMXT_OP(mulslw)
1820IWMMXT_OP(mulshw)
1821IWMMXT_OP(mululw)
1822IWMMXT_OP(muluhw)
1823IWMMXT_OP(macsw)
1824IWMMXT_OP(macuw)
1825
1826IWMMXT_OP_ENV_SIZE(unpackl)
1827IWMMXT_OP_ENV_SIZE(unpackh)
1828
1829IWMMXT_OP_ENV1(unpacklub)
1830IWMMXT_OP_ENV1(unpackluw)
1831IWMMXT_OP_ENV1(unpacklul)
1832IWMMXT_OP_ENV1(unpackhub)
1833IWMMXT_OP_ENV1(unpackhuw)
1834IWMMXT_OP_ENV1(unpackhul)
1835IWMMXT_OP_ENV1(unpacklsb)
1836IWMMXT_OP_ENV1(unpacklsw)
1837IWMMXT_OP_ENV1(unpacklsl)
1838IWMMXT_OP_ENV1(unpackhsb)
1839IWMMXT_OP_ENV1(unpackhsw)
1840IWMMXT_OP_ENV1(unpackhsl)
1841
1842IWMMXT_OP_ENV_SIZE(cmpeq)
1843IWMMXT_OP_ENV_SIZE(cmpgtu)
1844IWMMXT_OP_ENV_SIZE(cmpgts)
1845
1846IWMMXT_OP_ENV_SIZE(mins)
1847IWMMXT_OP_ENV_SIZE(minu)
1848IWMMXT_OP_ENV_SIZE(maxs)
1849IWMMXT_OP_ENV_SIZE(maxu)
1850
1851IWMMXT_OP_ENV_SIZE(subn)
1852IWMMXT_OP_ENV_SIZE(addn)
1853IWMMXT_OP_ENV_SIZE(subu)
1854IWMMXT_OP_ENV_SIZE(addu)
1855IWMMXT_OP_ENV_SIZE(subs)
1856IWMMXT_OP_ENV_SIZE(adds)
1857
1858IWMMXT_OP_ENV(avgb0)
1859IWMMXT_OP_ENV(avgb1)
1860IWMMXT_OP_ENV(avgw0)
1861IWMMXT_OP_ENV(avgw1)
1862
1863IWMMXT_OP_ENV(packuw)
1864IWMMXT_OP_ENV(packul)
1865IWMMXT_OP_ENV(packuq)
1866IWMMXT_OP_ENV(packsw)
1867IWMMXT_OP_ENV(packsl)
1868IWMMXT_OP_ENV(packsq)
1869
1870static void gen_op_iwmmxt_set_mup(void)
1871{
1872    TCGv_i32 tmp;
1873    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1874    tcg_gen_ori_i32(tmp, tmp, 2);
1875    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1876}
1877
1878static void gen_op_iwmmxt_set_cup(void)
1879{
1880    TCGv_i32 tmp;
1881    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1882    tcg_gen_ori_i32(tmp, tmp, 1);
1883    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1884}
1885
1886static void gen_op_iwmmxt_setpsr_nz(void)
1887{
1888    TCGv_i32 tmp = tcg_temp_new_i32();
1889    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1890    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1891}
1892
1893static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1894{
1895    iwmmxt_load_reg(cpu_V1, rn);
1896    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1897    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1898}
1899
1900static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1901                                     TCGv_i32 dest)
1902{
1903    int rd;
1904    uint32_t offset;
1905    TCGv_i32 tmp;
1906
1907    rd = (insn >> 16) & 0xf;
1908    tmp = load_reg(s, rd);
1909
1910    offset = (insn & 0xff) << ((insn >> 7) & 2);
1911    if (insn & (1 << 24)) {
1912        /* Pre indexed */
1913        if (insn & (1 << 23))
1914            tcg_gen_addi_i32(tmp, tmp, offset);
1915        else
1916            tcg_gen_addi_i32(tmp, tmp, -offset);
1917        tcg_gen_mov_i32(dest, tmp);
1918        if (insn & (1 << 21))
1919            store_reg(s, rd, tmp);
1920        else
1921            tcg_temp_free_i32(tmp);
1922    } else if (insn & (1 << 21)) {
1923        /* Post indexed */
1924        tcg_gen_mov_i32(dest, tmp);
1925        if (insn & (1 << 23))
1926            tcg_gen_addi_i32(tmp, tmp, offset);
1927        else
1928            tcg_gen_addi_i32(tmp, tmp, -offset);
1929        store_reg(s, rd, tmp);
1930    } else if (!(insn & (1 << 23)))
1931        return 1;
1932    return 0;
1933}
1934
1935static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1936{
1937    int rd = (insn >> 0) & 0xf;
1938    TCGv_i32 tmp;
1939
1940    if (insn & (1 << 8)) {
1941        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1942            return 1;
1943        } else {
1944            tmp = iwmmxt_load_creg(rd);
1945        }
1946    } else {
1947        tmp = tcg_temp_new_i32();
1948        iwmmxt_load_reg(cpu_V0, rd);
1949        tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1950    }
1951    tcg_gen_andi_i32(tmp, tmp, mask);
1952    tcg_gen_mov_i32(dest, tmp);
1953    tcg_temp_free_i32(tmp);
1954    return 0;
1955}
1956
1957/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occurred
1958   (ie. an undefined instruction).  */
1959static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1960{
1961    int rd, wrd;
1962    int rdhi, rdlo, rd0, rd1, i;
1963    TCGv_i32 addr;
1964    TCGv_i32 tmp, tmp2, tmp3;
1965
1966    if ((insn & 0x0e000e00) == 0x0c000000) {
1967        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1968            wrd = insn & 0xf;
1969            rdlo = (insn >> 12) & 0xf;
1970            rdhi = (insn >> 16) & 0xf;
1971            if (insn & ARM_CP_RW_BIT) {                         /* TMRRC */
1972                iwmmxt_load_reg(cpu_V0, wrd);
1973                tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1974                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1975                tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1976            } else {                                    /* TMCRR */
1977                tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1978                iwmmxt_store_reg(cpu_V0, wrd);
1979                gen_op_iwmmxt_set_mup();
1980            }
1981            return 0;
1982        }
1983
1984        wrd = (insn >> 12) & 0xf;
1985        addr = tcg_temp_new_i32();
1986        if (gen_iwmmxt_address(s, insn, addr)) {
1987            tcg_temp_free_i32(addr);
1988            return 1;
1989        }
1990        if (insn & ARM_CP_RW_BIT) {
1991            if ((insn >> 28) == 0xf) {                  /* WLDRW wCx */
1992                tmp = tcg_temp_new_i32();
1993                gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1994                iwmmxt_store_creg(wrd, tmp);
1995            } else {
1996                i = 1;
1997                if (insn & (1 << 8)) {
1998                    if (insn & (1 << 22)) {             /* WLDRD */
1999                        gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
2000                        i = 0;
2001                    } else {                            /* WLDRW wRd */
2002                        tmp = tcg_temp_new_i32();
2003                        gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2004                    }
2005                } else {
2006                    tmp = tcg_temp_new_i32();
2007                    if (insn & (1 << 22)) {             /* WLDRH */
2008                        gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2009                    } else {                            /* WLDRB */
2010                        gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2011                    }
2012                }
2013                if (i) {
2014                    tcg_gen_extu_i32_i64(cpu_M0, tmp);
2015                    tcg_temp_free_i32(tmp);
2016                }
2017                gen_op_iwmmxt_movq_wRn_M0(wrd);
2018            }
2019        } else {
2020            if ((insn >> 28) == 0xf) {                  /* WSTRW wCx */
2021                tmp = iwmmxt_load_creg(wrd);
2022                gen_aa32_st32(s, tmp, addr, get_mem_index(s));
2023            } else {
2024                gen_op_iwmmxt_movq_M0_wRn(wrd);
2025                tmp = tcg_temp_new_i32();
2026                if (insn & (1 << 8)) {
2027                    if (insn & (1 << 22)) {             /* WSTRD */
2028                        gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
2029                    } else {                            /* WSTRW wRd */
2030                        tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2031                        gen_aa32_st32(s, tmp, addr, get_mem_index(s));
2032                    }
2033                } else {
2034                    if (insn & (1 << 22)) {             /* WSTRH */
2035                        tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2036                        gen_aa32_st16(s, tmp, addr, get_mem_index(s));
2037                    } else {                            /* WSTRB */
2038                        tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2039                        gen_aa32_st8(s, tmp, addr, get_mem_index(s));
2040                    }
2041                }
2042            }
2043            tcg_temp_free_i32(tmp);
2044        }
2045        tcg_temp_free_i32(addr);
2046        return 0;
2047    }
2048
2049    if ((insn & 0x0f000000) != 0x0e000000)
2050        return 1;
2051
2052    switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
2053    case 0x000:                                                 /* WOR */
2054        wrd = (insn >> 12) & 0xf;
2055        rd0 = (insn >> 0) & 0xf;
2056        rd1 = (insn >> 16) & 0xf;
2057        gen_op_iwmmxt_movq_M0_wRn(rd0);
2058        gen_op_iwmmxt_orq_M0_wRn(rd1);
2059        gen_op_iwmmxt_setpsr_nz();
2060        gen_op_iwmmxt_movq_wRn_M0(wrd);
2061        gen_op_iwmmxt_set_mup();
2062        gen_op_iwmmxt_set_cup();
2063        break;
2064    case 0x011:                                                 /* TMCR */
2065        if (insn & 0xf)
2066            return 1;
2067        rd = (insn >> 12) & 0xf;
2068        wrd = (insn >> 16) & 0xf;
2069        switch (wrd) {
2070        case ARM_IWMMXT_wCID:
2071        case ARM_IWMMXT_wCASF:
2072            break;
2073        case ARM_IWMMXT_wCon:
2074            gen_op_iwmmxt_set_cup();
2075            /* Fall through.  */
2076        case ARM_IWMMXT_wCSSF:
2077            tmp = iwmmxt_load_creg(wrd);
2078            tmp2 = load_reg(s, rd);
2079            tcg_gen_andc_i32(tmp, tmp, tmp2);
2080            tcg_temp_free_i32(tmp2);
2081            iwmmxt_store_creg(wrd, tmp);
2082            break;
2083        case ARM_IWMMXT_wCGR0:
2084        case ARM_IWMMXT_wCGR1:
2085        case ARM_IWMMXT_wCGR2:
2086        case ARM_IWMMXT_wCGR3:
2087            gen_op_iwmmxt_set_cup();
2088            tmp = load_reg(s, rd);
2089            iwmmxt_store_creg(wrd, tmp);
2090            break;
2091        default:
2092            return 1;
2093        }
2094        break;
2095    case 0x100:                                                 /* WXOR */
2096        wrd = (insn >> 12) & 0xf;
2097        rd0 = (insn >> 0) & 0xf;
2098        rd1 = (insn >> 16) & 0xf;
2099        gen_op_iwmmxt_movq_M0_wRn(rd0);
2100        gen_op_iwmmxt_xorq_M0_wRn(rd1);
2101        gen_op_iwmmxt_setpsr_nz();
2102        gen_op_iwmmxt_movq_wRn_M0(wrd);
2103        gen_op_iwmmxt_set_mup();
2104        gen_op_iwmmxt_set_cup();
2105        break;
2106    case 0x111:                                                 /* TMRC */
2107        if (insn & 0xf)
2108            return 1;
2109        rd = (insn >> 12) & 0xf;
2110        wrd = (insn >> 16) & 0xf;
2111        tmp = iwmmxt_load_creg(wrd);
2112        store_reg(s, rd, tmp);
2113        break;
2114    case 0x300:                                                 /* WANDN */
2115        wrd = (insn >> 12) & 0xf;
2116        rd0 = (insn >> 0) & 0xf;
2117        rd1 = (insn >> 16) & 0xf;
2118        gen_op_iwmmxt_movq_M0_wRn(rd0);
2119        tcg_gen_neg_i64(cpu_M0, cpu_M0);
2120        gen_op_iwmmxt_andq_M0_wRn(rd1);
2121        gen_op_iwmmxt_setpsr_nz();
2122        gen_op_iwmmxt_movq_wRn_M0(wrd);
2123        gen_op_iwmmxt_set_mup();
2124        gen_op_iwmmxt_set_cup();
2125        break;
2126    case 0x200:                                                 /* WAND */
2127        wrd = (insn >> 12) & 0xf;
2128        rd0 = (insn >> 0) & 0xf;
2129        rd1 = (insn >> 16) & 0xf;
2130        gen_op_iwmmxt_movq_M0_wRn(rd0);
2131        gen_op_iwmmxt_andq_M0_wRn(rd1);
2132        gen_op_iwmmxt_setpsr_nz();
2133        gen_op_iwmmxt_movq_wRn_M0(wrd);
2134        gen_op_iwmmxt_set_mup();
2135        gen_op_iwmmxt_set_cup();
2136        break;
2137    case 0x810: case 0xa10:                             /* WMADD */
2138        wrd = (insn >> 12) & 0xf;
2139        rd0 = (insn >> 0) & 0xf;
2140        rd1 = (insn >> 16) & 0xf;
2141        gen_op_iwmmxt_movq_M0_wRn(rd0);
2142        if (insn & (1 << 21))
2143            gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2144        else
2145            gen_op_iwmmxt_madduq_M0_wRn(rd1);
2146        gen_op_iwmmxt_movq_wRn_M0(wrd);
2147        gen_op_iwmmxt_set_mup();
2148        break;
2149    case 0x10e: case 0x50e: case 0x90e: case 0xd0e:     /* WUNPCKIL */
2150        wrd = (insn >> 12) & 0xf;
2151        rd0 = (insn >> 16) & 0xf;
2152        rd1 = (insn >> 0) & 0xf;
2153        gen_op_iwmmxt_movq_M0_wRn(rd0);
2154        switch ((insn >> 22) & 3) {
2155        case 0:
2156            gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2157            break;
2158        case 1:
2159            gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2160            break;
2161        case 2:
2162            gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2163            break;
2164        case 3:
2165            return 1;
2166        }
2167        gen_op_iwmmxt_movq_wRn_M0(wrd);
2168        gen_op_iwmmxt_set_mup();
2169        gen_op_iwmmxt_set_cup();
2170        break;
2171    case 0x10c: case 0x50c: case 0x90c: case 0xd0c:     /* WUNPCKIH */
2172        wrd = (insn >> 12) & 0xf;
2173        rd0 = (insn >> 16) & 0xf;
2174        rd1 = (insn >> 0) & 0xf;
2175        gen_op_iwmmxt_movq_M0_wRn(rd0);
2176        switch ((insn >> 22) & 3) {
2177        case 0:
2178            gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2179            break;
2180        case 1:
2181            gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2182            break;
2183        case 2:
2184            gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2185            break;
2186        case 3:
2187            return 1;
2188        }
2189        gen_op_iwmmxt_movq_wRn_M0(wrd);
2190        gen_op_iwmmxt_set_mup();
2191        gen_op_iwmmxt_set_cup();
2192        break;
2193    case 0x012: case 0x112: case 0x412: case 0x512:     /* WSAD */
2194        wrd = (insn >> 12) & 0xf;
2195        rd0 = (insn >> 16) & 0xf;
2196        rd1 = (insn >> 0) & 0xf;
2197        gen_op_iwmmxt_movq_M0_wRn(rd0);
2198        if (insn & (1 << 22))
2199            gen_op_iwmmxt_sadw_M0_wRn(rd1);
2200        else
2201            gen_op_iwmmxt_sadb_M0_wRn(rd1);
2202        if (!(insn & (1 << 20)))
2203            gen_op_iwmmxt_addl_M0_wRn(wrd);
2204        gen_op_iwmmxt_movq_wRn_M0(wrd);
2205        gen_op_iwmmxt_set_mup();
2206        break;
2207    case 0x010: case 0x110: case 0x210: case 0x310:     /* WMUL */
2208        wrd = (insn >> 12) & 0xf;
2209        rd0 = (insn >> 16) & 0xf;
2210        rd1 = (insn >> 0) & 0xf;
2211        gen_op_iwmmxt_movq_M0_wRn(rd0);
2212        if (insn & (1 << 21)) {
2213            if (insn & (1 << 20))
2214                gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2215            else
2216                gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2217        } else {
2218            if (insn & (1 << 20))
2219                gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2220            else
2221                gen_op_iwmmxt_mululw_M0_wRn(rd1);
2222        }
2223        gen_op_iwmmxt_movq_wRn_M0(wrd);
2224        gen_op_iwmmxt_set_mup();
2225        break;
2226    case 0x410: case 0x510: case 0x610: case 0x710:     /* WMAC */
2227        wrd = (insn >> 12) & 0xf;
2228        rd0 = (insn >> 16) & 0xf;
2229        rd1 = (insn >> 0) & 0xf;
2230        gen_op_iwmmxt_movq_M0_wRn(rd0);
2231        if (insn & (1 << 21))
2232            gen_op_iwmmxt_macsw_M0_wRn(rd1);
2233        else
2234            gen_op_iwmmxt_macuw_M0_wRn(rd1);
2235        if (!(insn & (1 << 20))) {
2236            iwmmxt_load_reg(cpu_V1, wrd);
2237            tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2238        }
2239        gen_op_iwmmxt_movq_wRn_M0(wrd);
2240        gen_op_iwmmxt_set_mup();
2241        break;
2242    case 0x006: case 0x406: case 0x806: case 0xc06:     /* WCMPEQ */
2243        wrd = (insn >> 12) & 0xf;
2244        rd0 = (insn >> 16) & 0xf;
2245        rd1 = (insn >> 0) & 0xf;
2246        gen_op_iwmmxt_movq_M0_wRn(rd0);
2247        switch ((insn >> 22) & 3) {
2248        case 0:
2249            gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2250            break;
2251        case 1:
2252            gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2253            break;
2254        case 2:
2255            gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2256            break;
2257        case 3:
2258            return 1;
2259        }
2260        gen_op_iwmmxt_movq_wRn_M0(wrd);
2261        gen_op_iwmmxt_set_mup();
2262        gen_op_iwmmxt_set_cup();
2263        break;
2264    case 0x800: case 0x900: case 0xc00: case 0xd00:     /* WAVG2 */
2265        wrd = (insn >> 12) & 0xf;
2266        rd0 = (insn >> 16) & 0xf;
2267        rd1 = (insn >> 0) & 0xf;
2268        gen_op_iwmmxt_movq_M0_wRn(rd0);
2269        if (insn & (1 << 22)) {
2270            if (insn & (1 << 20))
2271                gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2272            else
2273                gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2274        } else {
2275            if (insn & (1 << 20))
2276                gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2277            else
2278                gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2279        }
2280        gen_op_iwmmxt_movq_wRn_M0(wrd);
2281        gen_op_iwmmxt_set_mup();
2282        gen_op_iwmmxt_set_cup();
2283        break;
2284    case 0x802: case 0x902: case 0xa02: case 0xb02:     /* WALIGNR */
2285        wrd = (insn >> 12) & 0xf;
2286        rd0 = (insn >> 16) & 0xf;
2287        rd1 = (insn >> 0) & 0xf;
2288        gen_op_iwmmxt_movq_M0_wRn(rd0);
2289        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2290        tcg_gen_andi_i32(tmp, tmp, 7);
2291        iwmmxt_load_reg(cpu_V1, rd1);
2292        gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2293        tcg_temp_free_i32(tmp);
2294        gen_op_iwmmxt_movq_wRn_M0(wrd);
2295        gen_op_iwmmxt_set_mup();
2296        break;
2297    case 0x601: case 0x605: case 0x609: case 0x60d:     /* TINSR */
2298        if (((insn >> 6) & 3) == 3)
2299            return 1;
2300        rd = (insn >> 12) & 0xf;
2301        wrd = (insn >> 16) & 0xf;
2302        tmp = load_reg(s, rd);
2303        gen_op_iwmmxt_movq_M0_wRn(wrd);
2304        switch ((insn >> 6) & 3) {
2305        case 0:
2306            tmp2 = tcg_const_i32(0xff);
2307            tmp3 = tcg_const_i32((insn & 7) << 3);
2308            break;
2309        case 1:
2310            tmp2 = tcg_const_i32(0xffff);
2311            tmp3 = tcg_const_i32((insn & 3) << 4);
2312            break;
2313        case 2:
2314            tmp2 = tcg_const_i32(0xffffffff);
2315            tmp3 = tcg_const_i32((insn & 1) << 5);
2316            break;
2317        default:
2318            tmp2 = NULL;
2319            tmp3 = NULL;
2320        }
2321        gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2322        tcg_temp_free_i32(tmp3);
2323        tcg_temp_free_i32(tmp2);
2324        tcg_temp_free_i32(tmp);
2325        gen_op_iwmmxt_movq_wRn_M0(wrd);
2326        gen_op_iwmmxt_set_mup();
2327        break;
2328    case 0x107: case 0x507: case 0x907: case 0xd07:     /* TEXTRM */
2329        rd = (insn >> 12) & 0xf;
2330        wrd = (insn >> 16) & 0xf;
2331        if (rd == 15 || ((insn >> 22) & 3) == 3)
2332            return 1;
2333        gen_op_iwmmxt_movq_M0_wRn(wrd);
2334        tmp = tcg_temp_new_i32();
2335        switch ((insn >> 22) & 3) {
2336        case 0:
2337            tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2338            tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2339            if (insn & 8) {
2340                tcg_gen_ext8s_i32(tmp, tmp);
2341            } else {
2342                tcg_gen_andi_i32(tmp, tmp, 0xff);
2343            }
2344            break;
2345        case 1:
2346            tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2347            tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2348            if (insn & 8) {
2349                tcg_gen_ext16s_i32(tmp, tmp);
2350            } else {
2351                tcg_gen_andi_i32(tmp, tmp, 0xffff);
2352            }
2353            break;
2354        case 2:
2355            tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2356            tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2357            break;
2358        }
2359        store_reg(s, rd, tmp);
2360        break;
2361    case 0x117: case 0x517: case 0x917: case 0xd17:     /* TEXTRC */
2362        if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2363            return 1;
2364        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2365        switch ((insn >> 22) & 3) {
2366        case 0:
2367            tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2368            break;
2369        case 1:
2370            tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2371            break;
2372        case 2:
2373            tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2374            break;
2375        }
2376        tcg_gen_shli_i32(tmp, tmp, 28);
2377        gen_set_nzcv(tmp);
2378        tcg_temp_free_i32(tmp);
2379        break;
2380    case 0x401: case 0x405: case 0x409: case 0x40d:     /* TBCST */
2381        if (((insn >> 6) & 3) == 3)
2382            return 1;
2383        rd = (insn >> 12) & 0xf;
2384        wrd = (insn >> 16) & 0xf;
2385        tmp = load_reg(s, rd);
2386        switch ((insn >> 6) & 3) {
2387        case 0:
2388            gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2389            break;
2390        case 1:
2391            gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2392            break;
2393        case 2:
2394            gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2395            break;
2396        }
2397        tcg_temp_free_i32(tmp);
2398        gen_op_iwmmxt_movq_wRn_M0(wrd);
2399        gen_op_iwmmxt_set_mup();
2400        break;
2401    case 0x113: case 0x513: case 0x913: case 0xd13:     /* TANDC */
2402        if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2403            return 1;
2404        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2405        tmp2 = tcg_temp_new_i32();
2406        tcg_gen_mov_i32(tmp2, tmp);
2407        switch ((insn >> 22) & 3) {
2408        case 0:
2409            for (i = 0; i < 7; i ++) {
2410                tcg_gen_shli_i32(tmp2, tmp2, 4);
2411                tcg_gen_and_i32(tmp, tmp, tmp2);
2412            }
2413            break;
2414        case 1:
2415            for (i = 0; i < 3; i ++) {
2416                tcg_gen_shli_i32(tmp2, tmp2, 8);
2417                tcg_gen_and_i32(tmp, tmp, tmp2);
2418            }
2419            break;
2420        case 2:
2421            tcg_gen_shli_i32(tmp2, tmp2, 16);
2422            tcg_gen_and_i32(tmp, tmp, tmp2);
2423            break;
2424        }
2425        gen_set_nzcv(tmp);
2426        tcg_temp_free_i32(tmp2);
2427        tcg_temp_free_i32(tmp);
2428        break;
2429    case 0x01c: case 0x41c: case 0x81c: case 0xc1c:     /* WACC */
2430        wrd = (insn >> 12) & 0xf;
2431        rd0 = (insn >> 16) & 0xf;
2432        gen_op_iwmmxt_movq_M0_wRn(rd0);
2433        switch ((insn >> 22) & 3) {
2434        case 0:
2435            gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2436            break;
2437        case 1:
2438            gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2439            break;
2440        case 2:
2441            gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2442            break;
2443        case 3:
2444            return 1;
2445        }
2446        gen_op_iwmmxt_movq_wRn_M0(wrd);
2447        gen_op_iwmmxt_set_mup();
2448        break;
2449    case 0x115: case 0x515: case 0x915: case 0xd15:     /* TORC */
2450        if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2451            return 1;
2452        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2453        tmp2 = tcg_temp_new_i32();
2454        tcg_gen_mov_i32(tmp2, tmp);
2455        switch ((insn >> 22) & 3) {
2456        case 0:
2457            for (i = 0; i < 7; i ++) {
2458                tcg_gen_shli_i32(tmp2, tmp2, 4);
2459                tcg_gen_or_i32(tmp, tmp, tmp2);
2460            }
2461            break;
2462        case 1:
2463            for (i = 0; i < 3; i ++) {
2464                tcg_gen_shli_i32(tmp2, tmp2, 8);
2465                tcg_gen_or_i32(tmp, tmp, tmp2);
2466            }
2467            break;
2468        case 2:
2469            tcg_gen_shli_i32(tmp2, tmp2, 16);
2470            tcg_gen_or_i32(tmp, tmp, tmp2);
2471            break;
2472        }
2473        gen_set_nzcv(tmp);
2474        tcg_temp_free_i32(tmp2);
2475        tcg_temp_free_i32(tmp);
2476        break;
2477    case 0x103: case 0x503: case 0x903: case 0xd03:     /* TMOVMSK */
2478        rd = (insn >> 12) & 0xf;
2479        rd0 = (insn >> 16) & 0xf;
2480        if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2481            return 1;
2482        gen_op_iwmmxt_movq_M0_wRn(rd0);
2483        tmp = tcg_temp_new_i32();
2484        switch ((insn >> 22) & 3) {
2485        case 0:
2486            gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2487            break;
2488        case 1:
2489            gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2490            break;
2491        case 2:
2492            gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2493            break;
2494        }
2495        store_reg(s, rd, tmp);
2496        break;
2497    case 0x106: case 0x306: case 0x506: case 0x706:     /* WCMPGT */
2498    case 0x906: case 0xb06: case 0xd06: case 0xf06:
2499        wrd = (insn >> 12) & 0xf;
2500        rd0 = (insn >> 16) & 0xf;
2501        rd1 = (insn >> 0) & 0xf;
2502        gen_op_iwmmxt_movq_M0_wRn(rd0);
2503        switch ((insn >> 22) & 3) {
2504        case 0:
2505            if (insn & (1 << 21))
2506                gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2507            else
2508                gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2509            break;
2510        case 1:
2511            if (insn & (1 << 21))
2512                gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2513            else
2514                gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2515            break;
2516        case 2:
2517            if (insn & (1 << 21))
2518                gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2519            else
2520                gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2521            break;
2522        case 3:
2523            return 1;
2524        }
2525        gen_op_iwmmxt_movq_wRn_M0(wrd);
2526        gen_op_iwmmxt_set_mup();
2527        gen_op_iwmmxt_set_cup();
2528        break;
2529    case 0x00e: case 0x20e: case 0x40e: case 0x60e:     /* WUNPCKEL */
2530    case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2531        wrd = (insn >> 12) & 0xf;
2532        rd0 = (insn >> 16) & 0xf;
2533        gen_op_iwmmxt_movq_M0_wRn(rd0);
2534        switch ((insn >> 22) & 3) {
2535        case 0:
2536            if (insn & (1 << 21))
2537                gen_op_iwmmxt_unpacklsb_M0();
2538            else
2539                gen_op_iwmmxt_unpacklub_M0();
2540            break;
2541        case 1:
2542            if (insn & (1 << 21))
2543                gen_op_iwmmxt_unpacklsw_M0();
2544            else
2545                gen_op_iwmmxt_unpackluw_M0();
2546            break;
2547        case 2:
2548            if (insn & (1 << 21))
2549                gen_op_iwmmxt_unpacklsl_M0();
2550            else
2551                gen_op_iwmmxt_unpacklul_M0();
2552            break;
2553        case 3:
2554            return 1;
2555        }
2556        gen_op_iwmmxt_movq_wRn_M0(wrd);
2557        gen_op_iwmmxt_set_mup();
2558        gen_op_iwmmxt_set_cup();
2559        break;
2560    case 0x00c: case 0x20c: case 0x40c: case 0x60c:     /* WUNPCKEH */
2561    case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2562        wrd = (insn >> 12) & 0xf;
2563        rd0 = (insn >> 16) & 0xf;
2564        gen_op_iwmmxt_movq_M0_wRn(rd0);
2565        switch ((insn >> 22) & 3) {
2566        case 0:
2567            if (insn & (1 << 21))
2568                gen_op_iwmmxt_unpackhsb_M0();
2569            else
2570                gen_op_iwmmxt_unpackhub_M0();
2571            break;
2572        case 1:
2573            if (insn & (1 << 21))
2574                gen_op_iwmmxt_unpackhsw_M0();
2575            else
2576                gen_op_iwmmxt_unpackhuw_M0();
2577            break;
2578        case 2:
2579            if (insn & (1 << 21))
2580                gen_op_iwmmxt_unpackhsl_M0();
2581            else
2582                gen_op_iwmmxt_unpackhul_M0();
2583            break;
2584        case 3:
2585            return 1;
2586        }
2587        gen_op_iwmmxt_movq_wRn_M0(wrd);
2588        gen_op_iwmmxt_set_mup();
2589        gen_op_iwmmxt_set_cup();
2590        break;
2591    case 0x204: case 0x604: case 0xa04: case 0xe04:     /* WSRL */
2592    case 0x214: case 0x614: case 0xa14: case 0xe14:
2593        if (((insn >> 22) & 3) == 0)
2594            return 1;
2595        wrd = (insn >> 12) & 0xf;
2596        rd0 = (insn >> 16) & 0xf;
2597        gen_op_iwmmxt_movq_M0_wRn(rd0);
2598        tmp = tcg_temp_new_i32();
2599        if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2600            tcg_temp_free_i32(tmp);
2601            return 1;
2602        }
2603        switch ((insn >> 22) & 3) {
2604        case 1:
2605            gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2606            break;
2607        case 2:
2608            gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2609            break;
2610        case 3:
2611            gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2612            break;
2613        }
2614        tcg_temp_free_i32(tmp);
2615        gen_op_iwmmxt_movq_wRn_M0(wrd);
2616        gen_op_iwmmxt_set_mup();
2617        gen_op_iwmmxt_set_cup();
2618        break;
2619    case 0x004: case 0x404: case 0x804: case 0xc04:     /* WSRA */
2620    case 0x014: case 0x414: case 0x814: case 0xc14:
2621        if (((insn >> 22) & 3) == 0)
2622            return 1;
2623        wrd = (insn >> 12) & 0xf;
2624        rd0 = (insn >> 16) & 0xf;
2625        gen_op_iwmmxt_movq_M0_wRn(rd0);
2626        tmp = tcg_temp_new_i32();
2627        if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2628            tcg_temp_free_i32(tmp);
2629            return 1;
2630        }
2631        switch ((insn >> 22) & 3) {
2632        case 1:
2633            gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2634            break;
2635        case 2:
2636            gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2637            break;
2638        case 3:
2639            gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2640            break;
2641        }
2642        tcg_temp_free_i32(tmp);
2643        gen_op_iwmmxt_movq_wRn_M0(wrd);
2644        gen_op_iwmmxt_set_mup();
2645        gen_op_iwmmxt_set_cup();
2646        break;
2647    case 0x104: case 0x504: case 0x904: case 0xd04:     /* WSLL */
2648    case 0x114: case 0x514: case 0x914: case 0xd14:
2649        if (((insn >> 22) & 3) == 0)
2650            return 1;
2651        wrd = (insn >> 12) & 0xf;
2652        rd0 = (insn >> 16) & 0xf;
2653        gen_op_iwmmxt_movq_M0_wRn(rd0);
2654        tmp = tcg_temp_new_i32();
2655        if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2656            tcg_temp_free_i32(tmp);
2657            return 1;
2658        }
2659        switch ((insn >> 22) & 3) {
2660        case 1:
2661            gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2662            break;
2663        case 2:
2664            gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2665            break;
2666        case 3:
2667            gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2668            break;
2669        }
2670        tcg_temp_free_i32(tmp);
2671        gen_op_iwmmxt_movq_wRn_M0(wrd);
2672        gen_op_iwmmxt_set_mup();
2673        gen_op_iwmmxt_set_cup();
2674        break;
2675    case 0x304: case 0x704: case 0xb04: case 0xf04:     /* WROR */
2676    case 0x314: case 0x714: case 0xb14: case 0xf14:
2677        if (((insn >> 22) & 3) == 0)
2678            return 1;
2679        wrd = (insn >> 12) & 0xf;
2680        rd0 = (insn >> 16) & 0xf;
2681        gen_op_iwmmxt_movq_M0_wRn(rd0);
2682        tmp = tcg_temp_new_i32();
2683        switch ((insn >> 22) & 3) {
2684        case 1:
2685            if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2686                tcg_temp_free_i32(tmp);
2687                return 1;
2688            }
2689            gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2690            break;
2691        case 2:
2692            if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2693                tcg_temp_free_i32(tmp);
2694                return 1;
2695            }
2696            gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2697            break;
2698        case 3:
2699            if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2700                tcg_temp_free_i32(tmp);
2701                return 1;
2702            }
2703            gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2704            break;
2705        }
2706        tcg_temp_free_i32(tmp);
2707        gen_op_iwmmxt_movq_wRn_M0(wrd);
2708        gen_op_iwmmxt_set_mup();
2709        gen_op_iwmmxt_set_cup();
2710        break;
2711    case 0x116: case 0x316: case 0x516: case 0x716:     /* WMIN */
2712    case 0x916: case 0xb16: case 0xd16: case 0xf16:
2713        wrd = (insn >> 12) & 0xf;
2714        rd0 = (insn >> 16) & 0xf;
2715        rd1 = (insn >> 0) & 0xf;
2716        gen_op_iwmmxt_movq_M0_wRn(rd0);
2717        switch ((insn >> 22) & 3) {
2718        case 0:
2719            if (insn & (1 << 21))
2720                gen_op_iwmmxt_minsb_M0_wRn(rd1);
2721            else
2722                gen_op_iwmmxt_minub_M0_wRn(rd1);
2723            break;
2724        case 1:
2725            if (insn & (1 << 21))
2726                gen_op_iwmmxt_minsw_M0_wRn(rd1);
2727            else
2728                gen_op_iwmmxt_minuw_M0_wRn(rd1);
2729            break;
2730        case 2:
2731            if (insn & (1 << 21))
2732                gen_op_iwmmxt_minsl_M0_wRn(rd1);
2733            else
2734                gen_op_iwmmxt_minul_M0_wRn(rd1);
2735            break;
2736        case 3:
2737            return 1;
2738        }
2739        gen_op_iwmmxt_movq_wRn_M0(wrd);
2740        gen_op_iwmmxt_set_mup();
2741        break;
2742    case 0x016: case 0x216: case 0x416: case 0x616:     /* WMAX */
2743    case 0x816: case 0xa16: case 0xc16: case 0xe16:
2744        wrd = (insn >> 12) & 0xf;
2745        rd0 = (insn >> 16) & 0xf;
2746        rd1 = (insn >> 0) & 0xf;
2747        gen_op_iwmmxt_movq_M0_wRn(rd0);
2748        switch ((insn >> 22) & 3) {
2749        case 0:
2750            if (insn & (1 << 21))
2751                gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2752            else
2753                gen_op_iwmmxt_maxub_M0_wRn(rd1);
2754            break;
2755        case 1:
2756            if (insn & (1 << 21))
2757                gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2758            else
2759                gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2760            break;
2761        case 2:
2762            if (insn & (1 << 21))
2763                gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2764            else
2765                gen_op_iwmmxt_maxul_M0_wRn(rd1);
2766            break;
2767        case 3:
2768            return 1;
2769        }
2770        gen_op_iwmmxt_movq_wRn_M0(wrd);
2771        gen_op_iwmmxt_set_mup();
2772        break;
2773    case 0x002: case 0x102: case 0x202: case 0x302:     /* WALIGNI */
2774    case 0x402: case 0x502: case 0x602: case 0x702:
2775        wrd = (insn >> 12) & 0xf;
2776        rd0 = (insn >> 16) & 0xf;
2777        rd1 = (insn >> 0) & 0xf;
2778        gen_op_iwmmxt_movq_M0_wRn(rd0);
2779        tmp = tcg_const_i32((insn >> 20) & 3);
2780        iwmmxt_load_reg(cpu_V1, rd1);
2781        gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2782        tcg_temp_free_i32(tmp);
2783        gen_op_iwmmxt_movq_wRn_M0(wrd);
2784        gen_op_iwmmxt_set_mup();
2785        break;
2786    case 0x01a: case 0x11a: case 0x21a: case 0x31a:     /* WSUB */
2787    case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2788    case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2789    case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2790        wrd = (insn >> 12) & 0xf;
2791        rd0 = (insn >> 16) & 0xf;
2792        rd1 = (insn >> 0) & 0xf;
2793        gen_op_iwmmxt_movq_M0_wRn(rd0);
2794        switch ((insn >> 20) & 0xf) {
2795        case 0x0:
2796            gen_op_iwmmxt_subnb_M0_wRn(rd1);
2797            break;
2798        case 0x1:
2799            gen_op_iwmmxt_subub_M0_wRn(rd1);
2800            break;
2801        case 0x3:
2802            gen_op_iwmmxt_subsb_M0_wRn(rd1);
2803            break;
2804        case 0x4:
2805            gen_op_iwmmxt_subnw_M0_wRn(rd1);
2806            break;
2807        case 0x5:
2808            gen_op_iwmmxt_subuw_M0_wRn(rd1);
2809            break;
2810        case 0x7:
2811            gen_op_iwmmxt_subsw_M0_wRn(rd1);
2812            break;
2813        case 0x8:
2814            gen_op_iwmmxt_subnl_M0_wRn(rd1);
2815            break;
2816        case 0x9:
2817            gen_op_iwmmxt_subul_M0_wRn(rd1);
2818            break;
2819        case 0xb:
2820            gen_op_iwmmxt_subsl_M0_wRn(rd1);
2821            break;
2822        default:
2823            return 1;
2824        }
2825        gen_op_iwmmxt_movq_wRn_M0(wrd);
2826        gen_op_iwmmxt_set_mup();
2827        gen_op_iwmmxt_set_cup();
2828        break;
2829    case 0x01e: case 0x11e: case 0x21e: case 0x31e:     /* WSHUFH */
2830    case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2831    case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2832    case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2833        wrd = (insn >> 12) & 0xf;
2834        rd0 = (insn >> 16) & 0xf;
2835        gen_op_iwmmxt_movq_M0_wRn(rd0);
2836        tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2837        gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2838        tcg_temp_free_i32(tmp);
2839        gen_op_iwmmxt_movq_wRn_M0(wrd);
2840        gen_op_iwmmxt_set_mup();
2841        gen_op_iwmmxt_set_cup();
2842        break;
2843    case 0x018: case 0x118: case 0x218: case 0x318:     /* WADD */
2844    case 0x418: case 0x518: case 0x618: case 0x718:
2845    case 0x818: case 0x918: case 0xa18: case 0xb18:
2846    case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2847        wrd = (insn >> 12) & 0xf;
2848        rd0 = (insn >> 16) & 0xf;
2849        rd1 = (insn >> 0) & 0xf;
2850        gen_op_iwmmxt_movq_M0_wRn(rd0);
2851        switch ((insn >> 20) & 0xf) {
2852        case 0x0:
2853            gen_op_iwmmxt_addnb_M0_wRn(rd1);
2854            break;
2855        case 0x1:
2856            gen_op_iwmmxt_addub_M0_wRn(rd1);
2857            break;
2858        case 0x3:
2859            gen_op_iwmmxt_addsb_M0_wRn(rd1);
2860            break;
2861        case 0x4:
2862            gen_op_iwmmxt_addnw_M0_wRn(rd1);
2863            break;
2864        case 0x5:
2865            gen_op_iwmmxt_adduw_M0_wRn(rd1);
2866            break;
2867        case 0x7:
2868            gen_op_iwmmxt_addsw_M0_wRn(rd1);
2869            break;
2870        case 0x8:
2871            gen_op_iwmmxt_addnl_M0_wRn(rd1);
2872            break;
2873        case 0x9:
2874            gen_op_iwmmxt_addul_M0_wRn(rd1);
2875            break;
2876        case 0xb:
2877            gen_op_iwmmxt_addsl_M0_wRn(rd1);
2878            break;
2879        default:
2880            return 1;
2881        }
2882        gen_op_iwmmxt_movq_wRn_M0(wrd);
2883        gen_op_iwmmxt_set_mup();
2884        gen_op_iwmmxt_set_cup();
2885        break;
2886    case 0x008: case 0x108: case 0x208: case 0x308:     /* WPACK */
2887    case 0x408: case 0x508: case 0x608: case 0x708:
2888    case 0x808: case 0x908: case 0xa08: case 0xb08:
2889    case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2890        if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2891            return 1;
2892        wrd = (insn >> 12) & 0xf;
2893        rd0 = (insn >> 16) & 0xf;
2894        rd1 = (insn >> 0) & 0xf;
2895        gen_op_iwmmxt_movq_M0_wRn(rd0);
2896        switch ((insn >> 22) & 3) {
2897        case 1:
2898            if (insn & (1 << 21))
2899                gen_op_iwmmxt_packsw_M0_wRn(rd1);
2900            else
2901                gen_op_iwmmxt_packuw_M0_wRn(rd1);
2902            break;
2903        case 2:
2904            if (insn & (1 << 21))
2905                gen_op_iwmmxt_packsl_M0_wRn(rd1);
2906            else
2907                gen_op_iwmmxt_packul_M0_wRn(rd1);
2908            break;
2909        case 3:
2910            if (insn & (1 << 21))
2911                gen_op_iwmmxt_packsq_M0_wRn(rd1);
2912            else
2913                gen_op_iwmmxt_packuq_M0_wRn(rd1);
2914            break;
2915        }
2916        gen_op_iwmmxt_movq_wRn_M0(wrd);
2917        gen_op_iwmmxt_set_mup();
2918        gen_op_iwmmxt_set_cup();
2919        break;
2920    case 0x201: case 0x203: case 0x205: case 0x207:
2921    case 0x209: case 0x20b: case 0x20d: case 0x20f:
2922    case 0x211: case 0x213: case 0x215: case 0x217:
2923    case 0x219: case 0x21b: case 0x21d: case 0x21f:
2924        wrd = (insn >> 5) & 0xf;
2925        rd0 = (insn >> 12) & 0xf;
2926        rd1 = (insn >> 0) & 0xf;
2927        if (rd0 == 0xf || rd1 == 0xf)
2928            return 1;
2929        gen_op_iwmmxt_movq_M0_wRn(wrd);
2930        tmp = load_reg(s, rd0);
2931        tmp2 = load_reg(s, rd1);
2932        switch ((insn >> 16) & 0xf) {
2933        case 0x0:                                       /* TMIA */
2934            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2935            break;
2936        case 0x8:                                       /* TMIAPH */
2937            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2938            break;
2939        case 0xc: case 0xd: case 0xe: case 0xf:                 /* TMIAxy */
2940            if (insn & (1 << 16))
2941                tcg_gen_shri_i32(tmp, tmp, 16);
2942            if (insn & (1 << 17))
2943                tcg_gen_shri_i32(tmp2, tmp2, 16);
2944            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2945            break;
2946        default:
2947            tcg_temp_free_i32(tmp2);
2948            tcg_temp_free_i32(tmp);
2949            return 1;
2950        }
2951        tcg_temp_free_i32(tmp2);
2952        tcg_temp_free_i32(tmp);
2953        gen_op_iwmmxt_movq_wRn_M0(wrd);
2954        gen_op_iwmmxt_set_mup();
2955        break;
2956    default:
2957        return 1;
2958    }
2959
2960    return 0;
2961}
2962
2963/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occurred
2964   (ie. an undefined instruction).  */
2965static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2966{
2967    int acc, rd0, rd1, rdhi, rdlo;
2968    TCGv_i32 tmp, tmp2;
2969
2970    if ((insn & 0x0ff00f10) == 0x0e200010) {
2971        /* Multiply with Internal Accumulate Format */
2972        rd0 = (insn >> 12) & 0xf;
2973        rd1 = insn & 0xf;
2974        acc = (insn >> 5) & 7;
2975
2976        if (acc != 0)
2977            return 1;
2978
2979        tmp = load_reg(s, rd0);
2980        tmp2 = load_reg(s, rd1);
2981        switch ((insn >> 16) & 0xf) {
2982        case 0x0:                                       /* MIA */
2983            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2984            break;
2985        case 0x8:                                       /* MIAPH */
2986            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2987            break;
2988        case 0xc:                                       /* MIABB */
2989        case 0xd:                                       /* MIABT */
2990        case 0xe:                                       /* MIATB */
2991        case 0xf:                                       /* MIATT */
2992            if (insn & (1 << 16))
2993                tcg_gen_shri_i32(tmp, tmp, 16);
2994            if (insn & (1 << 17))
2995                tcg_gen_shri_i32(tmp2, tmp2, 16);
2996            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2997            break;
2998        default:
2999            return 1;
3000        }
3001        tcg_temp_free_i32(tmp2);
3002        tcg_temp_free_i32(tmp);
3003
3004        gen_op_iwmmxt_movq_wRn_M0(acc);
3005        return 0;
3006    }
3007
3008    if ((insn & 0x0fe00ff8) == 0x0c400000) {
3009        /* Internal Accumulator Access Format */
3010        rdhi = (insn >> 16) & 0xf;
3011        rdlo = (insn >> 12) & 0xf;
3012        acc = insn & 7;
3013
3014        if (acc != 0)
3015            return 1;
3016
3017        if (insn & ARM_CP_RW_BIT) {                     /* MRA */
3018            iwmmxt_load_reg(cpu_V0, acc);
3019            tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
3020            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
3021            tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
3022            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
3023        } else {                                        /* MAR */
3024            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
3025            iwmmxt_store_reg(cpu_V0, acc);
3026        }
3027        return 0;
3028    }
3029
3030    return 1;
3031}
3032
3033#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
3034#define VFP_SREG(insn, bigbit, smallbit) \
3035  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
3036#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
3037    if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
3038        reg = (((insn) >> (bigbit)) & 0x0f) \
3039              | (((insn) >> ((smallbit) - 4)) & 0x10); \
3040    } else { \
3041        if (insn & (1 << (smallbit))) \
3042            return 1; \
3043        reg = ((insn) >> (bigbit)) & 0x0f; \
3044    }} while (0)
3045
3046#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
3047#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
3048#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
3049#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
3050#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
3051#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
3052
3053/* Move between integer and VFP cores.  */
3054static TCGv_i32 gen_vfp_mrs(void)
3055{
3056    TCGv_i32 tmp = tcg_temp_new_i32();
3057    tcg_gen_mov_i32(tmp, cpu_F0s);
3058    return tmp;
3059}
3060
3061static void gen_vfp_msr(TCGv_i32 tmp)
3062{
3063    tcg_gen_mov_i32(cpu_F0s, tmp);
3064    tcg_temp_free_i32(tmp);
3065}
3066
3067static void gen_neon_dup_low16(TCGv_i32 var)
3068{
3069    TCGv_i32 tmp = tcg_temp_new_i32();
3070    tcg_gen_ext16u_i32(var, var);
3071    tcg_gen_shli_i32(tmp, var, 16);
3072    tcg_gen_or_i32(var, var, tmp);
3073    tcg_temp_free_i32(tmp);
3074}
3075
3076static void gen_neon_dup_high16(TCGv_i32 var)
3077{
3078    TCGv_i32 tmp = tcg_temp_new_i32();
3079    tcg_gen_andi_i32(var, var, 0xffff0000);
3080    tcg_gen_shri_i32(tmp, var, 16);
3081    tcg_gen_or_i32(var, var, tmp);
3082    tcg_temp_free_i32(tmp);
3083}
3084
3085static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
3086                       uint32_t dp)
3087{
3088    uint32_t cc = extract32(insn, 20, 2);
3089
3090    if (dp) {
3091        TCGv_i64 frn, frm, dest;
3092        TCGv_i64 tmp, zero, zf, nf, vf;
3093
3094        zero = tcg_const_i64(0);
3095
3096        frn = tcg_temp_new_i64();
3097        frm = tcg_temp_new_i64();
3098        dest = tcg_temp_new_i64();
3099
3100        zf = tcg_temp_new_i64();
3101        nf = tcg_temp_new_i64();
3102        vf = tcg_temp_new_i64();
3103
3104        tcg_gen_extu_i32_i64(zf, cpu_ZF);
3105        tcg_gen_ext_i32_i64(nf, cpu_NF);
3106        tcg_gen_ext_i32_i64(vf, cpu_VF);
3107
3108        tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3109        tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3110        switch (cc) {
3111        case 0: /* eq: Z */
3112            tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
3113                                frn, frm);
3114            break;
3115        case 1: /* vs: V */
3116            tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
3117                                frn, frm);
3118            break;
3119        case 2: /* ge: N == V -> N ^ V == 0 */
3120            tmp = tcg_temp_new_i64();
3121            tcg_gen_xor_i64(tmp, vf, nf);
3122            tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3123                                frn, frm);
3124            tcg_temp_free_i64(tmp);
3125            break;
3126        case 3: /* gt: !Z && N == V */
3127            tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
3128                                frn, frm);
3129            tmp = tcg_temp_new_i64();
3130            tcg_gen_xor_i64(tmp, vf, nf);
3131            tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3132                                dest, frm);
3133            tcg_temp_free_i64(tmp);
3134            break;
3135        }
3136        tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3137        tcg_temp_free_i64(frn);
3138        tcg_temp_free_i64(frm);
3139        tcg_temp_free_i64(dest);
3140
3141        tcg_temp_free_i64(zf);
3142        tcg_temp_free_i64(nf);
3143        tcg_temp_free_i64(vf);
3144
3145        tcg_temp_free_i64(zero);
3146    } else {
3147        TCGv_i32 frn, frm, dest;
3148        TCGv_i32 tmp, zero;
3149
3150        zero = tcg_const_i32(0);
3151
3152        frn = tcg_temp_new_i32();
3153        frm = tcg_temp_new_i32();
3154        dest = tcg_temp_new_i32();
3155        tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3156        tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3157        switch (cc) {
3158        case 0: /* eq: Z */
3159            tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3160                                frn, frm);
3161            break;
3162        case 1: /* vs: V */
3163            tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3164                                frn, frm);
3165            break;
3166        case 2: /* ge: N == V -> N ^ V == 0 */
3167            tmp = tcg_temp_new_i32();
3168            tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3169            tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3170                                frn, frm);
3171            tcg_temp_free_i32(tmp);
3172            break;
3173        case 3: /* gt: !Z && N == V */
3174            tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3175                                frn, frm);
3176            tmp = tcg_temp_new_i32();
3177            tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3178            tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3179                                dest, frm);
3180            tcg_temp_free_i32(tmp);
3181            break;
3182        }
3183        tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3184        tcg_temp_free_i32(frn);
3185        tcg_temp_free_i32(frm);
3186        tcg_temp_free_i32(dest);
3187
3188        tcg_temp_free_i32(zero);
3189    }
3190
3191    return 0;
3192}
3193
3194static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3195                            uint32_t rm, uint32_t dp)
3196{
3197    uint32_t vmin = extract32(insn, 6, 1);
3198    TCGv_ptr fpst = get_fpstatus_ptr(0);
3199
3200    if (dp) {
3201        TCGv_i64 frn, frm, dest;
3202
3203        frn = tcg_temp_new_i64();
3204        frm = tcg_temp_new_i64();
3205        dest = tcg_temp_new_i64();
3206
3207        tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3208        tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3209        if (vmin) {
3210            gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3211        } else {
3212            gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3213        }
3214        tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3215        tcg_temp_free_i64(frn);
3216        tcg_temp_free_i64(frm);
3217        tcg_temp_free_i64(dest);
3218    } else {
3219        TCGv_i32 frn, frm, dest;
3220
3221        frn = tcg_temp_new_i32();
3222        frm = tcg_temp_new_i32();
3223        dest = tcg_temp_new_i32();
3224
3225        tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3226        tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3227        if (vmin) {
3228            gen_helper_vfp_minnums(dest, frn, frm, fpst);
3229        } else {
3230            gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3231        }
3232        tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3233        tcg_temp_free_i32(frn);
3234        tcg_temp_free_i32(frm);
3235        tcg_temp_free_i32(dest);
3236    }
3237
3238    tcg_temp_free_ptr(fpst);
3239    return 0;
3240}
3241
3242static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3243                        int rounding)
3244{
3245    TCGv_ptr fpst = get_fpstatus_ptr(0);
3246    TCGv_i32 tcg_rmode;
3247
3248    tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3249    gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3250
3251    if (dp) {
3252        TCGv_i64 tcg_op;
3253        TCGv_i64 tcg_res;
3254        tcg_op = tcg_temp_new_i64();
3255        tcg_res = tcg_temp_new_i64();
3256        tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3257        gen_helper_rintd(tcg_res, tcg_op, fpst);
3258        tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3259        tcg_temp_free_i64(tcg_op);
3260        tcg_temp_free_i64(tcg_res);
3261    } else {
3262        TCGv_i32 tcg_op;
3263        TCGv_i32 tcg_res;
3264        tcg_op = tcg_temp_new_i32();
3265        tcg_res = tcg_temp_new_i32();
3266        tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3267        gen_helper_rints(tcg_res, tcg_op, fpst);
3268        tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3269        tcg_temp_free_i32(tcg_op);
3270        tcg_temp_free_i32(tcg_res);
3271    }
3272
3273    gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3274    tcg_temp_free_i32(tcg_rmode);
3275
3276    tcg_temp_free_ptr(fpst);
3277    return 0;
3278}
3279
3280static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3281                       int rounding)
3282{
3283    bool is_signed = extract32(insn, 7, 1);
3284    TCGv_ptr fpst = get_fpstatus_ptr(0);
3285    TCGv_i32 tcg_rmode, tcg_shift;
3286
3287    tcg_shift = tcg_const_i32(0);
3288
3289    tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3290    gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3291
3292    if (dp) {
3293        TCGv_i64 tcg_double, tcg_res;
3294        TCGv_i32 tcg_tmp;
3295        /* Rd is encoded as a single precision register even when the source
3296         * is double precision.
3297         */
3298        rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3299        tcg_double = tcg_temp_new_i64();
3300        tcg_res = tcg_temp_new_i64();
3301        tcg_tmp = tcg_temp_new_i32();
3302        tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3303        if (is_signed) {
3304            gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3305        } else {
3306            gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3307        }
3308        tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3309        tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3310        tcg_temp_free_i32(tcg_tmp);
3311        tcg_temp_free_i64(tcg_res);
3312        tcg_temp_free_i64(tcg_double);
3313    } else {
3314        TCGv_i32 tcg_single, tcg_res;
3315        tcg_single = tcg_temp_new_i32();
3316        tcg_res = tcg_temp_new_i32();
3317        tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3318        if (is_signed) {
3319            gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3320        } else {
3321            gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3322        }
3323        tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3324        tcg_temp_free_i32(tcg_res);
3325        tcg_temp_free_i32(tcg_single);
3326    }
3327
3328    gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3329    tcg_temp_free_i32(tcg_rmode);
3330
3331    tcg_temp_free_i32(tcg_shift);
3332
3333    tcg_temp_free_ptr(fpst);
3334
3335    return 0;
3336}
3337
3338/* Table for converting the most common AArch32 encoding of
3339 * rounding mode to arm_fprounding order (which matches the
3340 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3341 */
3342static const uint8_t fp_decode_rm[] = {
3343    FPROUNDING_TIEAWAY,
3344    FPROUNDING_TIEEVEN,
3345    FPROUNDING_POSINF,
3346    FPROUNDING_NEGINF,
3347};
3348
3349static int disas_vfp_misc_insn(DisasContext *s, uint32_t insn)
3350{
3351    uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3352
3353    if (dp) {
3354        VFP_DREG_D(rd, insn);
3355        VFP_DREG_N(rn, insn);
3356        VFP_DREG_M(rm, insn);
3357    } else {
3358        rd = VFP_SREG_D(insn);
3359        rn = VFP_SREG_N(insn);
3360        rm = VFP_SREG_M(insn);
3361    }
3362
3363    if ((insn & 0x0f800e50) == 0x0e000a00 && dc_isar_feature(aa32_vsel, s)) {
3364        return handle_vsel(insn, rd, rn, rm, dp);
3365    } else if ((insn & 0x0fb00e10) == 0x0e800a00 &&
3366               dc_isar_feature(aa32_vminmaxnm, s)) {
3367        return handle_vminmaxnm(insn, rd, rn, rm, dp);
3368    } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40 &&
3369               dc_isar_feature(aa32_vrint, s)) {
3370        /* VRINTA, VRINTN, VRINTP, VRINTM */
3371        int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3372        return handle_vrint(insn, rd, rm, dp, rounding);
3373    } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40 &&
3374               dc_isar_feature(aa32_vcvt_dr, s)) {
3375        /* VCVTA, VCVTN, VCVTP, VCVTM */
3376        int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3377        return handle_vcvt(insn, rd, rm, dp, rounding);
3378    }
3379    return 1;
3380}
3381
3382/* Disassemble a VFP instruction.  Returns nonzero if an error occurred
3383   (ie. an undefined instruction).  */
3384static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3385{
3386    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3387    int dp, veclen;
3388    TCGv_i32 addr;
3389    TCGv_i32 tmp;
3390    TCGv_i32 tmp2;
3391
3392    if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3393        return 1;
3394    }
3395
3396    /* FIXME: this access check should not take precedence over UNDEF
3397     * for invalid encodings; we will generate incorrect syndrome information
3398     * for attempts to execute invalid vfp/neon encodings with FP disabled.
3399     */
3400    if (s->fp_excp_el) {
3401        gen_exception_insn(s, 4, EXCP_UDEF,
3402                           syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3403        return 0;
3404    }
3405
3406    if (!s->vfp_enabled) {
3407        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
3408        if ((insn & 0x0fe00fff) != 0x0ee00a10)
3409            return 1;
3410        rn = (insn >> 16) & 0xf;
3411        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3412            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3413            return 1;
3414        }
3415    }
3416
3417    if (extract32(insn, 28, 4) == 0xf) {
3418        /*
3419         * Encodings with T=1 (Thumb) or unconditional (ARM):
3420         * only used for the "miscellaneous VFP features" added in v8A
3421         * and v7M (and gated on the MVFR2.FPMisc field).
3422         */
3423        return disas_vfp_misc_insn(s, insn);
3424    }
3425
3426    dp = ((insn & 0xf00) == 0xb00);
3427    switch ((insn >> 24) & 0xf) {
3428    case 0xe:
3429        if (insn & (1 << 4)) {
3430            /* single register transfer */
3431            rd = (insn >> 12) & 0xf;
3432            if (dp) {
3433                int size;
3434                int pass;
3435
3436                VFP_DREG_N(rn, insn);
3437                if (insn & 0xf)
3438                    return 1;
3439                if (insn & 0x00c00060
3440                    && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3441                    return 1;
3442                }
3443
3444                pass = (insn >> 21) & 1;
3445                if (insn & (1 << 22)) {
3446                    size = 0;
3447                    offset = ((insn >> 5) & 3) * 8;
3448                } else if (insn & (1 << 5)) {
3449                    size = 1;
3450                    offset = (insn & (1 << 6)) ? 16 : 0;
3451                } else {
3452                    size = 2;
3453                    offset = 0;
3454                }
3455                if (insn & ARM_CP_RW_BIT) {
3456                    /* vfp->arm */
3457                    tmp = neon_load_reg(rn, pass);
3458                    switch (size) {
3459                    case 0:
3460                        if (offset)
3461                            tcg_gen_shri_i32(tmp, tmp, offset);
3462                        if (insn & (1 << 23))
3463                            gen_uxtb(tmp);
3464                        else
3465                            gen_sxtb(tmp);
3466                        break;
3467                    case 1:
3468                        if (insn & (1 << 23)) {
3469                            if (offset) {
3470                                tcg_gen_shri_i32(tmp, tmp, 16);
3471                            } else {
3472                                gen_uxth(tmp);
3473                            }
3474                        } else {
3475                            if (offset) {
3476                                tcg_gen_sari_i32(tmp, tmp, 16);
3477                            } else {
3478                                gen_sxth(tmp);
3479                            }
3480                        }
3481                        break;
3482                    case 2:
3483                        break;
3484                    }
3485                    store_reg(s, rd, tmp);
3486                } else {
3487                    /* arm->vfp */
3488                    tmp = load_reg(s, rd);
3489                    if (insn & (1 << 23)) {
3490                        /* VDUP */
3491                        int vec_size = pass ? 16 : 8;
3492                        tcg_gen_gvec_dup_i32(size, neon_reg_offset(rn, 0),
3493                                             vec_size, vec_size, tmp);
3494                        tcg_temp_free_i32(tmp);
3495                    } else {
3496                        /* VMOV */
3497                        switch (size) {
3498                        case 0:
3499                            tmp2 = neon_load_reg(rn, pass);
3500                            tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3501                            tcg_temp_free_i32(tmp2);
3502                            break;
3503                        case 1:
3504                            tmp2 = neon_load_reg(rn, pass);
3505                            tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3506                            tcg_temp_free_i32(tmp2);
3507                            break;
3508                        case 2:
3509                            break;
3510                        }
3511                        neon_store_reg(rn, pass, tmp);
3512                    }
3513                }
3514            } else { /* !dp */
3515                if ((insn & 0x6f) != 0x00)
3516                    return 1;
3517                rn = VFP_SREG_N(insn);
3518                if (insn & ARM_CP_RW_BIT) {
3519                    /* vfp->arm */
3520                    if (insn & (1 << 21)) {
3521                        /* system register */
3522                        rn >>= 1;
3523
3524                        switch (rn) {
3525                        case ARM_VFP_FPSID:
3526                            /* VFP2 allows access to FSID from userspace.
3527                               VFP3 restricts all id registers to privileged
3528                               accesses.  */
3529                            if (IS_USER(s)
3530                                && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3531                                return 1;
3532                            }
3533                            tmp = load_cpu_field(vfp.xregs[rn]);
3534                            break;
3535                        case ARM_VFP_FPEXC:
3536                            if (IS_USER(s))
3537                                return 1;
3538                            tmp = load_cpu_field(vfp.xregs[rn]);
3539                            break;
3540                        case ARM_VFP_FPINST:
3541                        case ARM_VFP_FPINST2:
3542                            /* Not present in VFP3.  */
3543                            if (IS_USER(s)
3544                                || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3545                                return 1;
3546                            }
3547                            tmp = load_cpu_field(vfp.xregs[rn]);
3548                            break;
3549                        case ARM_VFP_FPSCR:
3550                            if (rd == 15) {
3551                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3552                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3553                            } else {
3554                                tmp = tcg_temp_new_i32();
3555                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
3556                            }
3557                            break;
3558                        case ARM_VFP_MVFR2:
3559                            if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3560                                return 1;
3561                            }
3562                            /* fall through */
3563                        case ARM_VFP_MVFR0:
3564                        case ARM_VFP_MVFR1:
3565                            if (IS_USER(s)
3566                                || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3567                                return 1;
3568                            }
3569                            tmp = load_cpu_field(vfp.xregs[rn]);
3570                            break;
3571                        default:
3572                            return 1;
3573                        }
3574                    } else {
3575                        gen_mov_F0_vreg(0, rn);
3576                        tmp = gen_vfp_mrs();
3577                    }
3578                    if (rd == 15) {
3579                        /* Set the 4 flag bits in the CPSR.  */
3580                        gen_set_nzcv(tmp);
3581                        tcg_temp_free_i32(tmp);
3582                    } else {
3583                        store_reg(s, rd, tmp);
3584                    }
3585                } else {
3586                    /* arm->vfp */
3587                    if (insn & (1 << 21)) {
3588                        rn >>= 1;
3589                        /* system register */
3590                        switch (rn) {
3591                        case ARM_VFP_FPSID:
3592                        case ARM_VFP_MVFR0:
3593                        case ARM_VFP_MVFR1:
3594                            /* Writes are ignored.  */
3595                            break;
3596                        case ARM_VFP_FPSCR:
3597                            tmp = load_reg(s, rd);
3598                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
3599                            tcg_temp_free_i32(tmp);
3600                            gen_lookup_tb(s);
3601                            break;
3602                        case ARM_VFP_FPEXC:
3603                            if (IS_USER(s))
3604                                return 1;
3605                            /* TODO: VFP subarchitecture support.
3606                             * For now, keep the EN bit only */
3607                            tmp = load_reg(s, rd);
3608                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3609                            store_cpu_field(tmp, vfp.xregs[rn]);
3610                            gen_lookup_tb(s);
3611                            break;
3612                        case ARM_VFP_FPINST:
3613                        case ARM_VFP_FPINST2:
3614                            if (IS_USER(s)) {
3615                                return 1;
3616                            }
3617                            tmp = load_reg(s, rd);
3618                            store_cpu_field(tmp, vfp.xregs[rn]);
3619                            break;
3620                        default:
3621                            return 1;
3622                        }
3623                    } else {
3624                        tmp = load_reg(s, rd);
3625                        gen_vfp_msr(tmp);
3626                        gen_mov_vreg_F0(0, rn);
3627                    }
3628                }
3629            }
3630        } else {
3631            /* data processing */
3632            bool rd_is_dp = dp;
3633            bool rm_is_dp = dp;
3634            bool no_output = false;
3635
3636            /* The opcode is in bits 23, 21, 20 and 6.  */
3637            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3638            rn = VFP_SREG_N(insn);
3639
3640            if (op == 15) {
3641                /* rn is opcode, encoded as per VFP_SREG_N. */
3642                switch (rn) {
3643                case 0x00: /* vmov */
3644                case 0x01: /* vabs */
3645                case 0x02: /* vneg */
3646                case 0x03: /* vsqrt */
3647                    break;
3648
3649                case 0x04: /* vcvtb.f64.f16, vcvtb.f32.f16 */
3650                case 0x05: /* vcvtt.f64.f16, vcvtt.f32.f16 */
3651                    /*
3652                     * VCVTB, VCVTT: only present with the halfprec extension
3653                     * UNPREDICTABLE if bit 8 is set prior to ARMv8
3654                     * (we choose to UNDEF)
3655                     */
3656                    if (dp) {
3657                        if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
3658                            return 1;
3659                        }
3660                    } else {
3661                        if (!dc_isar_feature(aa32_fp16_spconv, s)) {
3662                            return 1;
3663                        }
3664                    }
3665                    rm_is_dp = false;
3666                    break;
3667                case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3668                case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3669                    if (dp) {
3670                        if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
3671                            return 1;
3672                        }
3673                    } else {
3674                        if (!dc_isar_feature(aa32_fp16_spconv, s)) {
3675                            return 1;
3676                        }
3677                    }
3678                    rd_is_dp = false;
3679                    break;
3680
3681                case 0x08: case 0x0a: /* vcmp, vcmpz */
3682                case 0x09: case 0x0b: /* vcmpe, vcmpez */
3683                    no_output = true;
3684                    break;
3685
3686                case 0x0c: /* vrintr */
3687                case 0x0d: /* vrintz */
3688                case 0x0e: /* vrintx */
3689                    break;
3690
3691                case 0x0f: /* vcvt double<->single */
3692                    rd_is_dp = !dp;
3693                    break;
3694
3695                case 0x10: /* vcvt.fxx.u32 */
3696                case 0x11: /* vcvt.fxx.s32 */
3697                    rm_is_dp = false;
3698                    break;
3699                case 0x18: /* vcvtr.u32.fxx */
3700                case 0x19: /* vcvtz.u32.fxx */
3701                case 0x1a: /* vcvtr.s32.fxx */
3702                case 0x1b: /* vcvtz.s32.fxx */
3703                    rd_is_dp = false;
3704                    break;
3705
3706                case 0x14: /* vcvt fp <-> fixed */
3707                case 0x15:
3708                case 0x16:
3709                case 0x17:
3710                case 0x1c:
3711                case 0x1d:
3712                case 0x1e:
3713                case 0x1f:
3714                    if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3715                        return 1;
3716                    }
3717                    /* Immediate frac_bits has same format as SREG_M.  */
3718                    rm_is_dp = false;
3719                    break;
3720
3721                case 0x13: /* vjcvt */
3722                    if (!dp || !dc_isar_feature(aa32_jscvt, s)) {
3723                        return 1;
3724                    }
3725                    rd_is_dp = false;
3726                    break;
3727
3728                default:
3729                    return 1;
3730                }
3731            } else if (dp) {
3732                /* rn is register number */
3733                VFP_DREG_N(rn, insn);
3734            }
3735
3736            if (rd_is_dp) {
3737                VFP_DREG_D(rd, insn);
3738            } else {
3739                rd = VFP_SREG_D(insn);
3740            }
3741            if (rm_is_dp) {
3742                VFP_DREG_M(rm, insn);
3743            } else {
3744                rm = VFP_SREG_M(insn);
3745            }
3746
3747            veclen = s->vec_len;
3748            if (op == 15 && rn > 3) {
3749                veclen = 0;
3750            }
3751
3752            /* Shut up compiler warnings.  */
3753            delta_m = 0;
3754            delta_d = 0;
3755            bank_mask = 0;
3756
3757            if (veclen > 0) {
3758                if (dp)
3759                    bank_mask = 0xc;
3760                else
3761                    bank_mask = 0x18;
3762
3763                /* Figure out what type of vector operation this is.  */
3764                if ((rd & bank_mask) == 0) {
3765                    /* scalar */
3766                    veclen = 0;
3767                } else {
3768                    if (dp)
3769                        delta_d = (s->vec_stride >> 1) + 1;
3770                    else
3771                        delta_d = s->vec_stride + 1;
3772
3773                    if ((rm & bank_mask) == 0) {
3774                        /* mixed scalar/vector */
3775                        delta_m = 0;
3776                    } else {
3777                        /* vector */
3778                        delta_m = delta_d;
3779                    }
3780                }
3781            }
3782
3783            /* Load the initial operands.  */
3784            if (op == 15) {
3785                switch (rn) {
3786                case 0x08: case 0x09: /* Compare */
3787                    gen_mov_F0_vreg(dp, rd);
3788                    gen_mov_F1_vreg(dp, rm);
3789                    break;
3790                case 0x0a: case 0x0b: /* Compare with zero */
3791                    gen_mov_F0_vreg(dp, rd);
3792                    gen_vfp_F1_ld0(dp);
3793                    break;
3794                case 0x14: /* vcvt fp <-> fixed */
3795                case 0x15:
3796                case 0x16:
3797                case 0x17:
3798                case 0x1c:
3799                case 0x1d:
3800                case 0x1e:
3801                case 0x1f:
3802                    /* Source and destination the same.  */
3803                    gen_mov_F0_vreg(dp, rd);
3804                    break;
3805                default:
3806                    /* One source operand.  */
3807                    gen_mov_F0_vreg(rm_is_dp, rm);
3808                    break;
3809                }
3810            } else {
3811                /* Two source operands.  */
3812                gen_mov_F0_vreg(dp, rn);
3813                gen_mov_F1_vreg(dp, rm);
3814            }
3815
3816            for (;;) {
3817                /* Perform the calculation.  */
3818                switch (op) {
3819                case 0: /* VMLA: fd + (fn * fm) */
3820                    /* Note that order of inputs to the add matters for NaNs */
3821                    gen_vfp_F1_mul(dp);
3822                    gen_mov_F0_vreg(dp, rd);
3823                    gen_vfp_add(dp);
3824                    break;
3825                case 1: /* VMLS: fd + -(fn * fm) */
3826                    gen_vfp_mul(dp);
3827                    gen_vfp_F1_neg(dp);
3828                    gen_mov_F0_vreg(dp, rd);
3829                    gen_vfp_add(dp);
3830                    break;
3831                case 2: /* VNMLS: -fd + (fn * fm) */
3832                    /* Note that it isn't valid to replace (-A + B) with (B - A)
3833                     * or similar plausible looking simplifications
3834                     * because this will give wrong results for NaNs.
3835                     */
3836                    gen_vfp_F1_mul(dp);
3837                    gen_mov_F0_vreg(dp, rd);
3838                    gen_vfp_neg(dp);
3839                    gen_vfp_add(dp);
3840                    break;
3841                case 3: /* VNMLA: -fd + -(fn * fm) */
3842                    gen_vfp_mul(dp);
3843                    gen_vfp_F1_neg(dp);
3844                    gen_mov_F0_vreg(dp, rd);
3845                    gen_vfp_neg(dp);
3846                    gen_vfp_add(dp);
3847                    break;
3848                case 4: /* mul: fn * fm */
3849                    gen_vfp_mul(dp);
3850                    break;
3851                case 5: /* nmul: -(fn * fm) */
3852                    gen_vfp_mul(dp);
3853                    gen_vfp_neg(dp);
3854                    break;
3855                case 6: /* add: fn + fm */
3856                    gen_vfp_add(dp);
3857                    break;
3858                case 7: /* sub: fn - fm */
3859                    gen_vfp_sub(dp);
3860                    break;
3861                case 8: /* div: fn / fm */
3862                    gen_vfp_div(dp);
3863                    break;
3864                case 10: /* VFNMA : fd = muladd(-fd,  fn, fm) */
3865                case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3866                case 12: /* VFMA  : fd = muladd( fd,  fn, fm) */
3867                case 13: /* VFMS  : fd = muladd( fd, -fn, fm) */
3868                    /* These are fused multiply-add, and must be done as one
3869                     * floating point operation with no rounding between the
3870                     * multiplication and addition steps.
3871                     * NB that doing the negations here as separate steps is
3872                     * correct : an input NaN should come out with its sign bit
3873                     * flipped if it is a negated-input.
3874                     */
3875                    if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3876                        return 1;
3877                    }
3878                    if (dp) {
3879                        TCGv_ptr fpst;
3880                        TCGv_i64 frd;
3881                        if (op & 1) {
3882                            /* VFNMS, VFMS */
3883                            gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3884                        }
3885                        frd = tcg_temp_new_i64();
3886                        tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3887                        if (op & 2) {
3888                            /* VFNMA, VFNMS */
3889                            gen_helper_vfp_negd(frd, frd);
3890                        }
3891                        fpst = get_fpstatus_ptr(0);
3892                        gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3893                                               cpu_F1d, frd, fpst);
3894                        tcg_temp_free_ptr(fpst);
3895                        tcg_temp_free_i64(frd);
3896                    } else {
3897                        TCGv_ptr fpst;
3898                        TCGv_i32 frd;
3899                        if (op & 1) {
3900                            /* VFNMS, VFMS */
3901                            gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3902                        }
3903                        frd = tcg_temp_new_i32();
3904                        tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3905                        if (op & 2) {
3906                            gen_helper_vfp_negs(frd, frd);
3907                        }
3908                        fpst = get_fpstatus_ptr(0);
3909                        gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3910                                               cpu_F1s, frd, fpst);
3911                        tcg_temp_free_ptr(fpst);
3912                        tcg_temp_free_i32(frd);
3913                    }
3914                    break;
3915                case 14: /* fconst */
3916                    if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3917                        return 1;
3918                    }
3919
3920                    n = (insn << 12) & 0x80000000;
3921                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
3922                    if (dp) {
3923                        if (i & 0x40)
3924                            i |= 0x3f80;
3925                        else
3926                            i |= 0x4000;
3927                        n |= i << 16;
3928                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3929                    } else {
3930                        if (i & 0x40)
3931                            i |= 0x780;
3932                        else
3933                            i |= 0x800;
3934                        n |= i << 19;
3935                        tcg_gen_movi_i32(cpu_F0s, n);
3936                    }
3937                    break;
3938                case 15: /* extension space */
3939                    switch (rn) {
3940                    case 0: /* cpy */
3941                        /* no-op */
3942                        break;
3943                    case 1: /* abs */
3944                        gen_vfp_abs(dp);
3945                        break;
3946                    case 2: /* neg */
3947                        gen_vfp_neg(dp);
3948                        break;
3949                    case 3: /* sqrt */
3950                        gen_vfp_sqrt(dp);
3951                        break;
3952                    case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3953                    {
3954                        TCGv_ptr fpst = get_fpstatus_ptr(false);
3955                        TCGv_i32 ahp_mode = get_ahp_flag();
3956                        tmp = gen_vfp_mrs();
3957                        tcg_gen_ext16u_i32(tmp, tmp);
3958                        if (dp) {
3959                            gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3960                                                           fpst, ahp_mode);
3961                        } else {
3962                            gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3963                                                           fpst, ahp_mode);
3964                        }
3965                        tcg_temp_free_i32(ahp_mode);
3966                        tcg_temp_free_ptr(fpst);
3967                        tcg_temp_free_i32(tmp);
3968                        break;
3969                    }
3970                    case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3971                    {
3972                        TCGv_ptr fpst = get_fpstatus_ptr(false);
3973                        TCGv_i32 ahp = get_ahp_flag();
3974                        tmp = gen_vfp_mrs();
3975                        tcg_gen_shri_i32(tmp, tmp, 16);
3976                        if (dp) {
3977                            gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3978                                                           fpst, ahp);
3979                        } else {
3980                            gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3981                                                           fpst, ahp);
3982                        }
3983                        tcg_temp_free_i32(tmp);
3984                        tcg_temp_free_i32(ahp);
3985                        tcg_temp_free_ptr(fpst);
3986                        break;
3987                    }
3988                    case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3989                    {
3990                        TCGv_ptr fpst = get_fpstatus_ptr(false);
3991                        TCGv_i32 ahp = get_ahp_flag();
3992                        tmp = tcg_temp_new_i32();
3993
3994                        if (dp) {
3995                            gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3996                                                           fpst, ahp);
3997                        } else {
3998                            gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3999                                                           fpst, ahp);
4000                        }
4001                        tcg_temp_free_i32(ahp);
4002                        tcg_temp_free_ptr(fpst);
4003                        gen_mov_F0_vreg(0, rd);
4004                        tmp2 = gen_vfp_mrs();
4005                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
4006                        tcg_gen_or_i32(tmp, tmp, tmp2);
4007                        tcg_temp_free_i32(tmp2);
4008                        gen_vfp_msr(tmp);
4009                        break;
4010                    }
4011                    case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
4012                    {
4013                        TCGv_ptr fpst = get_fpstatus_ptr(false);
4014                        TCGv_i32 ahp = get_ahp_flag();
4015                        tmp = tcg_temp_new_i32();
4016                        if (dp) {
4017                            gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
4018                                                           fpst, ahp);
4019                        } else {
4020                            gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
4021                                                           fpst, ahp);
4022                        }
4023                        tcg_temp_free_i32(ahp);
4024                        tcg_temp_free_ptr(fpst);
4025                        tcg_gen_shli_i32(tmp, tmp, 16);
4026                        gen_mov_F0_vreg(0, rd);
4027                        tmp2 = gen_vfp_mrs();
4028                        tcg_gen_ext16u_i32(tmp2, tmp2);
4029                        tcg_gen_or_i32(tmp, tmp, tmp2);
4030                        tcg_temp_free_i32(tmp2);
4031                        gen_vfp_msr(tmp);
4032                        break;
4033                    }
4034                    case 8: /* cmp */
4035                        gen_vfp_cmp(dp);
4036                        break;
4037                    case 9: /* cmpe */
4038                        gen_vfp_cmpe(dp);
4039                        break;
4040                    case 10: /* cmpz */
4041                        gen_vfp_cmp(dp);
4042                        break;
4043                    case 11: /* cmpez */
4044                        gen_vfp_F1_ld0(dp);
4045                        gen_vfp_cmpe(dp);
4046                        break;
4047                    case 12: /* vrintr */
4048                    {
4049                        TCGv_ptr fpst = get_fpstatus_ptr(0);
4050                        if (dp) {
4051                            gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
4052                        } else {
4053                            gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
4054                        }
4055                        tcg_temp_free_ptr(fpst);
4056                        break;
4057                    }
4058                    case 13: /* vrintz */
4059                    {
4060                        TCGv_ptr fpst = get_fpstatus_ptr(0);
4061                        TCGv_i32 tcg_rmode;
4062                        tcg_rmode = tcg_const_i32(float_round_to_zero);
4063                        gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
4064                        if (dp) {
4065                            gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
4066                        } else {
4067                            gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
4068                        }
4069                        gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
4070                        tcg_temp_free_i32(tcg_rmode);
4071                        tcg_temp_free_ptr(fpst);
4072                        break;
4073                    }
4074                    case 14: /* vrintx */
4075                    {
4076                        TCGv_ptr fpst = get_fpstatus_ptr(0);
4077                        if (dp) {
4078                            gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
4079                        } else {
4080                            gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
4081                        }
4082                        tcg_temp_free_ptr(fpst);
4083                        break;
4084                    }
4085                    case 15: /* single<->double conversion */
4086                        if (dp) {
4087                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
4088                        } else {
4089                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
4090                        }
4091                        break;
4092                    case 16: /* fuito */
4093                        gen_vfp_uito(dp, 0);
4094                        break;
4095                    case 17: /* fsito */
4096                        gen_vfp_sito(dp, 0);
4097                        break;
4098                    case 19: /* vjcvt */
4099                        gen_helper_vjcvt(cpu_F0s, cpu_F0d, cpu_env);
4100                        break;
4101                    case 20: /* fshto */
4102                        gen_vfp_shto(dp, 16 - rm, 0);
4103                        break;
4104                    case 21: /* fslto */
4105                        gen_vfp_slto(dp, 32 - rm, 0);
4106                        break;
4107                    case 22: /* fuhto */
4108                        gen_vfp_uhto(dp, 16 - rm, 0);
4109                        break;
4110                    case 23: /* fulto */
4111                        gen_vfp_ulto(dp, 32 - rm, 0);
4112                        break;
4113                    case 24: /* ftoui */
4114                        gen_vfp_toui(dp, 0);
4115                        break;
4116                    case 25: /* ftouiz */
4117                        gen_vfp_touiz(dp, 0);
4118                        break;
4119                    case 26: /* ftosi */
4120                        gen_vfp_tosi(dp, 0);
4121                        break;
4122                    case 27: /* ftosiz */
4123                        gen_vfp_tosiz(dp, 0);
4124                        break;
4125                    case 28: /* ftosh */
4126                        gen_vfp_tosh(dp, 16 - rm, 0);
4127                        break;
4128                    case 29: /* ftosl */
4129                        gen_vfp_tosl(dp, 32 - rm, 0);
4130                        break;
4131                    case 30: /* ftouh */
4132                        gen_vfp_touh(dp, 16 - rm, 0);
4133                        break;
4134                    case 31: /* ftoul */
4135                        gen_vfp_toul(dp, 32 - rm, 0);
4136                        break;
4137                    default: /* undefined */
4138                        g_assert_not_reached();
4139                    }
4140                    break;
4141                default: /* undefined */
4142                    return 1;
4143                }
4144
4145                /* Write back the result, if any.  */
4146                if (!no_output) {
4147                    gen_mov_vreg_F0(rd_is_dp, rd);
4148                }
4149
4150                /* break out of the loop if we have finished  */
4151                if (veclen == 0) {
4152                    break;
4153                }
4154
4155                if (op == 15 && delta_m == 0) {
4156                    /* single source one-many */
4157                    while (veclen--) {
4158                        rd = ((rd + delta_d) & (bank_mask - 1))
4159                             | (rd & bank_mask);
4160                        gen_mov_vreg_F0(dp, rd);
4161                    }
4162                    break;
4163                }
4164                /* Setup the next operands.  */
4165                veclen--;
4166                rd = ((rd + delta_d) & (bank_mask - 1))
4167                     | (rd & bank_mask);
4168
4169                if (op == 15) {
4170                    /* One source operand.  */
4171                    rm = ((rm + delta_m) & (bank_mask - 1))
4172                         | (rm & bank_mask);
4173                    gen_mov_F0_vreg(dp, rm);
4174                } else {
4175                    /* Two source operands.  */
4176                    rn = ((rn + delta_d) & (bank_mask - 1))
4177                         | (rn & bank_mask);
4178                    gen_mov_F0_vreg(dp, rn);
4179                    if (delta_m) {
4180                        rm = ((rm + delta_m) & (bank_mask - 1))
4181                             | (rm & bank_mask);
4182                        gen_mov_F1_vreg(dp, rm);
4183                    }
4184                }
4185            }
4186        }
4187        break;
4188    case 0xc:
4189    case 0xd:
4190        if ((insn & 0x03e00000) == 0x00400000) {
4191            /* two-register transfer */
4192            rn = (insn >> 16) & 0xf;
4193            rd = (insn >> 12) & 0xf;
4194            if (dp) {
4195                VFP_DREG_M(rm, insn);
4196            } else {
4197                rm = VFP_SREG_M(insn);
4198            }
4199
4200            if (insn & ARM_CP_RW_BIT) {
4201                /* vfp->arm */
4202                if (dp) {
4203                    gen_mov_F0_vreg(0, rm * 2);
4204                    tmp = gen_vfp_mrs();
4205                    store_reg(s, rd, tmp);
4206                    gen_mov_F0_vreg(0, rm * 2 + 1);
4207                    tmp = gen_vfp_mrs();
4208                    store_reg(s, rn, tmp);
4209                } else {
4210                    gen_mov_F0_vreg(0, rm);
4211                    tmp = gen_vfp_mrs();
4212                    store_reg(s, rd, tmp);
4213                    gen_mov_F0_vreg(0, rm + 1);
4214                    tmp = gen_vfp_mrs();
4215                    store_reg(s, rn, tmp);
4216                }
4217            } else {
4218                /* arm->vfp */
4219                if (dp) {
4220                    tmp = load_reg(s, rd);
4221                    gen_vfp_msr(tmp);
4222                    gen_mov_vreg_F0(0, rm * 2);
4223                    tmp = load_reg(s, rn);
4224                    gen_vfp_msr(tmp);
4225                    gen_mov_vreg_F0(0, rm * 2 + 1);
4226                } else {
4227                    tmp = load_reg(s, rd);
4228                    gen_vfp_msr(tmp);
4229                    gen_mov_vreg_F0(0, rm);
4230                    tmp = load_reg(s, rn);
4231                    gen_vfp_msr(tmp);
4232                    gen_mov_vreg_F0(0, rm + 1);
4233                }
4234            }
4235        } else {
4236            /* Load/store */
4237            rn = (insn >> 16) & 0xf;
4238            if (dp)
4239                VFP_DREG_D(rd, insn);
4240            else
4241                rd = VFP_SREG_D(insn);
4242            if ((insn & 0x01200000) == 0x01000000) {
4243                /* Single load/store */
4244                offset = (insn & 0xff) << 2;
4245                if ((insn & (1 << 23)) == 0)
4246                    offset = -offset;
4247                if (s->thumb && rn == 15) {
4248                    /* This is actually UNPREDICTABLE */
4249                    addr = tcg_temp_new_i32();
4250                    tcg_gen_movi_i32(addr, s->pc & ~2);
4251                } else {
4252                    addr = load_reg(s, rn);
4253                }
4254                tcg_gen_addi_i32(addr, addr, offset);
4255                if (insn & (1 << 20)) {
4256                    gen_vfp_ld(s, dp, addr);
4257                    gen_mov_vreg_F0(dp, rd);
4258                } else {
4259                    gen_mov_F0_vreg(dp, rd);
4260                    gen_vfp_st(s, dp, addr);
4261                }
4262                tcg_temp_free_i32(addr);
4263            } else {
4264                /* load/store multiple */
4265                int w = insn & (1 << 21);
4266                if (dp)
4267                    n = (insn >> 1) & 0x7f;
4268                else
4269                    n = insn & 0xff;
4270
4271                if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4272                    /* P == U , W == 1  => UNDEF */
4273                    return 1;
4274                }
4275                if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4276                    /* UNPREDICTABLE cases for bad immediates: we choose to
4277                     * UNDEF to avoid generating huge numbers of TCG ops
4278                     */
4279                    return 1;
4280                }
4281                if (rn == 15 && w) {
4282                    /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4283                    return 1;
4284                }
4285
4286                if (s->thumb && rn == 15) {
4287                    /* This is actually UNPREDICTABLE */
4288                    addr = tcg_temp_new_i32();
4289                    tcg_gen_movi_i32(addr, s->pc & ~2);
4290                } else {
4291                    addr = load_reg(s, rn);
4292                }
4293                if (insn & (1 << 24)) /* pre-decrement */
4294                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4295
4296                if (s->v8m_stackcheck && rn == 13 && w) {
4297                    /*
4298                     * Here 'addr' is the lowest address we will store to,
4299                     * and is either the old SP (if post-increment) or
4300                     * the new SP (if pre-decrement). For post-increment
4301                     * where the old value is below the limit and the new
4302                     * value is above, it is UNKNOWN whether the limit check
4303                     * triggers; we choose to trigger.
4304                     */
4305                    gen_helper_v8m_stackcheck(cpu_env, addr);
4306                }
4307
4308                if (dp)
4309                    offset = 8;
4310                else
4311                    offset = 4;
4312                for (i = 0; i < n; i++) {
4313                    if (insn & ARM_CP_RW_BIT) {
4314                        /* load */
4315                        gen_vfp_ld(s, dp, addr);
4316                        gen_mov_vreg_F0(dp, rd + i);
4317                    } else {
4318                        /* store */
4319                        gen_mov_F0_vreg(dp, rd + i);
4320                        gen_vfp_st(s, dp, addr);
4321                    }
4322                    tcg_gen_addi_i32(addr, addr, offset);
4323                }
4324                if (w) {
4325                    /* writeback */
4326                    if (insn & (1 << 24))
4327                        offset = -offset * n;
4328                    else if (dp && (insn & 1))
4329                        offset = 4;
4330                    else
4331                        offset = 0;
4332
4333                    if (offset != 0)
4334                        tcg_gen_addi_i32(addr, addr, offset);
4335                    store_reg(s, rn, addr);
4336                } else {
4337                    tcg_temp_free_i32(addr);
4338                }
4339            }
4340        }
4341        break;
4342    default:
4343        /* Should never happen.  */
4344        return 1;
4345    }
4346    return 0;
4347}
4348
4349static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4350{
4351#ifndef CONFIG_USER_ONLY
4352    return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4353           ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4354#else
4355    return true;
4356#endif
4357}
4358
4359static void gen_goto_ptr(void)
4360{
4361    tcg_gen_lookup_and_goto_ptr();
4362}
4363
4364/* This will end the TB but doesn't guarantee we'll return to
4365 * cpu_loop_exec. Any live exit_requests will be processed as we
4366 * enter the next TB.
4367 */
4368static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4369{
4370    if (use_goto_tb(s, dest)) {
4371        tcg_gen_goto_tb(n);
4372        gen_set_pc_im(s, dest);
4373        tcg_gen_exit_tb(s->base.tb, n);
4374    } else {
4375        gen_set_pc_im(s, dest);
4376        gen_goto_ptr();
4377    }
4378    s->base.is_jmp = DISAS_NORETURN;
4379}
4380
4381static inline void gen_jmp (DisasContext *s, uint32_t dest)
4382{
4383    if (unlikely(is_singlestepping(s))) {
4384        /* An indirect jump so that we still trigger the debug exception.  */
4385        if (s->thumb)
4386            dest |= 1;
4387        gen_bx_im(s, dest);
4388    } else {
4389        gen_goto_tb(s, 0, dest);
4390    }
4391}
4392
4393static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4394{
4395    if (x)
4396        tcg_gen_sari_i32(t0, t0, 16);
4397    else
4398        gen_sxth(t0);
4399    if (y)
4400        tcg_gen_sari_i32(t1, t1, 16);
4401    else
4402        gen_sxth(t1);
4403    tcg_gen_mul_i32(t0, t0, t1);
4404}
4405
4406/* Return the mask of PSR bits set by a MSR instruction.  */
4407static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4408{
4409    uint32_t mask;
4410
4411    mask = 0;
4412    if (flags & (1 << 0))
4413        mask |= 0xff;
4414    if (flags & (1 << 1))
4415        mask |= 0xff00;
4416    if (flags & (1 << 2))
4417        mask |= 0xff0000;
4418    if (flags & (1 << 3))
4419        mask |= 0xff000000;
4420
4421    /* Mask out undefined bits.  */
4422    mask &= ~CPSR_RESERVED;
4423    if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4424        mask &= ~CPSR_T;
4425    }
4426    if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4427        mask &= ~CPSR_Q; /* V5TE in reality*/
4428    }
4429    if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4430        mask &= ~(CPSR_E | CPSR_GE);
4431    }
4432    if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4433        mask &= ~CPSR_IT;
4434    }
4435    /* Mask out execution state and reserved bits.  */
4436    if (!spsr) {
4437        mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4438    }
4439    /* Mask out privileged bits.  */
4440    if (IS_USER(s))
4441        mask &= CPSR_USER;
4442    return mask;
4443}
4444
4445/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4446static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4447{
4448    TCGv_i32 tmp;
4449    if (spsr) {
4450        /* ??? This is also undefined in system mode.  */
4451        if (IS_USER(s))
4452            return 1;
4453
4454        tmp = load_cpu_field(spsr);
4455        tcg_gen_andi_i32(tmp, tmp, ~mask);
4456        tcg_gen_andi_i32(t0, t0, mask);
4457        tcg_gen_or_i32(tmp, tmp, t0);
4458        store_cpu_field(tmp, spsr);
4459    } else {
4460        gen_set_cpsr(t0, mask);
4461    }
4462    tcg_temp_free_i32(t0);
4463    gen_lookup_tb(s);
4464    return 0;
4465}
4466
4467/* Returns nonzero if access to the PSR is not permitted.  */
4468static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4469{
4470    TCGv_i32 tmp;
4471    tmp = tcg_temp_new_i32();
4472    tcg_gen_movi_i32(tmp, val);
4473    return gen_set_psr(s, mask, spsr, tmp);
4474}
4475
4476static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4477                                     int *tgtmode, int *regno)
4478{
4479    /* Decode the r and sysm fields of MSR/MRS banked accesses into
4480     * the target mode and register number, and identify the various
4481     * unpredictable cases.
4482     * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4483     *  + executed in user mode
4484     *  + using R15 as the src/dest register
4485     *  + accessing an unimplemented register
4486     *  + accessing a register that's inaccessible at current PL/security state*
4487     *  + accessing a register that you could access with a different insn
4488     * We choose to UNDEF in all these cases.
4489     * Since we don't know which of the various AArch32 modes we are in
4490     * we have to defer some checks to runtime.
4491     * Accesses to Monitor mode registers from Secure EL1 (which implies
4492     * that EL3 is AArch64) must trap to EL3.
4493     *
4494     * If the access checks fail this function will emit code to take
4495     * an exception and return false. Otherwise it will return true,
4496     * and set *tgtmode and *regno appropriately.
4497     */
4498    int exc_target = default_exception_el(s);
4499
4500    /* These instructions are present only in ARMv8, or in ARMv7 with the
4501     * Virtualization Extensions.
4502     */
4503    if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4504        !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4505        goto undef;
4506    }
4507
4508    if (IS_USER(s) || rn == 15) {
4509        goto undef;
4510    }
4511
4512    /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4513     * of registers into (r, sysm).
4514     */
4515    if (r) {
4516        /* SPSRs for other modes */
4517        switch (sysm) {
4518        case 0xe: /* SPSR_fiq */
4519            *tgtmode = ARM_CPU_MODE_FIQ;
4520            break;
4521        case 0x10: /* SPSR_irq */
4522            *tgtmode = ARM_CPU_MODE_IRQ;
4523            break;
4524        case 0x12: /* SPSR_svc */
4525            *tgtmode = ARM_CPU_MODE_SVC;
4526            break;
4527        case 0x14: /* SPSR_abt */
4528            *tgtmode = ARM_CPU_MODE_ABT;
4529            break;
4530        case 0x16: /* SPSR_und */
4531            *tgtmode = ARM_CPU_MODE_UND;
4532            break;
4533        case 0x1c: /* SPSR_mon */
4534            *tgtmode = ARM_CPU_MODE_MON;
4535            break;
4536        case 0x1e: /* SPSR_hyp */
4537            *tgtmode = ARM_CPU_MODE_HYP;
4538            break;
4539        default: /* unallocated */
4540            goto undef;
4541        }
4542        /* We arbitrarily assign SPSR a register number of 16. */
4543        *regno = 16;
4544    } else {
4545        /* general purpose registers for other modes */
4546        switch (sysm) {
4547        case 0x0 ... 0x6:   /* 0b00xxx : r8_usr ... r14_usr */
4548            *tgtmode = ARM_CPU_MODE_USR;
4549            *regno = sysm + 8;
4550            break;
4551        case 0x8 ... 0xe:   /* 0b01xxx : r8_fiq ... r14_fiq */
4552            *tgtmode = ARM_CPU_MODE_FIQ;
4553            *regno = sysm;
4554            break;
4555        case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4556            *tgtmode = ARM_CPU_MODE_IRQ;
4557            *regno = sysm & 1 ? 13 : 14;
4558            break;
4559        case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4560            *tgtmode = ARM_CPU_MODE_SVC;
4561            *regno = sysm & 1 ? 13 : 14;
4562            break;
4563        case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4564            *tgtmode = ARM_CPU_MODE_ABT;
4565            *regno = sysm & 1 ? 13 : 14;
4566            break;
4567        case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4568            *tgtmode = ARM_CPU_MODE_UND;
4569            *regno = sysm & 1 ? 13 : 14;
4570            break;
4571        case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4572            *tgtmode = ARM_CPU_MODE_MON;
4573            *regno = sysm & 1 ? 13 : 14;
4574            break;
4575        case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4576            *tgtmode = ARM_CPU_MODE_HYP;
4577            /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4578            *regno = sysm & 1 ? 13 : 17;
4579            break;
4580        default: /* unallocated */
4581            goto undef;
4582        }
4583    }
4584
4585    /* Catch the 'accessing inaccessible register' cases we can detect
4586     * at translate time.
4587     */
4588    switch (*tgtmode) {
4589    case ARM_CPU_MODE_MON:
4590        if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4591            goto undef;
4592        }
4593        if (s->current_el == 1) {
4594            /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4595             * then accesses to Mon registers trap to EL3
4596             */
4597            exc_target = 3;
4598            goto undef;
4599        }
4600        break;
4601    case ARM_CPU_MODE_HYP:
4602        /*
4603         * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
4604         * (and so we can forbid accesses from EL2 or below). elr_hyp
4605         * can be accessed also from Hyp mode, so forbid accesses from
4606         * EL0 or EL1.
4607         */
4608        if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
4609            (s->current_el < 3 && *regno != 17)) {
4610            goto undef;
4611        }
4612        break;
4613    default:
4614        break;
4615    }
4616
4617    return true;
4618
4619undef:
4620    /* If we get here then some access check did not pass */
4621    gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4622    return false;
4623}
4624
4625static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4626{
4627    TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4628    int tgtmode = 0, regno = 0;
4629
4630    if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4631        return;
4632    }
4633
4634    /* Sync state because msr_banked() can raise exceptions */
4635    gen_set_condexec(s);
4636    gen_set_pc_im(s, s->pc - 4);
4637    tcg_reg = load_reg(s, rn);
4638    tcg_tgtmode = tcg_const_i32(tgtmode);
4639    tcg_regno = tcg_const_i32(regno);
4640    gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4641    tcg_temp_free_i32(tcg_tgtmode);
4642    tcg_temp_free_i32(tcg_regno);
4643    tcg_temp_free_i32(tcg_reg);
4644    s->base.is_jmp = DISAS_UPDATE;
4645}
4646
4647static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4648{
4649    TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4650    int tgtmode = 0, regno = 0;
4651
4652    if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4653        return;
4654    }
4655
4656    /* Sync state because mrs_banked() can raise exceptions */
4657    gen_set_condexec(s);
4658    gen_set_pc_im(s, s->pc - 4);
4659    tcg_reg = tcg_temp_new_i32();
4660    tcg_tgtmode = tcg_const_i32(tgtmode);
4661    tcg_regno = tcg_const_i32(regno);
4662    gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4663    tcg_temp_free_i32(tcg_tgtmode);
4664    tcg_temp_free_i32(tcg_regno);
4665    store_reg(s, rn, tcg_reg);
4666    s->base.is_jmp = DISAS_UPDATE;
4667}
4668
4669/* Store value to PC as for an exception return (ie don't
4670 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4671 * will do the masking based on the new value of the Thumb bit.
4672 */
4673static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4674{
4675    tcg_gen_mov_i32(cpu_R[15], pc);
4676    tcg_temp_free_i32(pc);
4677}
4678
4679/* Generate a v6 exception return.  Marks both values as dead.  */
4680static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4681{
4682    store_pc_exc_ret(s, pc);
4683    /* The cpsr_write_eret helper will mask the low bits of PC
4684     * appropriately depending on the new Thumb bit, so it must
4685     * be called after storing the new PC.
4686     */
4687    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4688        gen_io_start();
4689    }
4690    gen_helper_cpsr_write_eret(cpu_env, cpsr);
4691    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4692        gen_io_end();
4693    }
4694    tcg_temp_free_i32(cpsr);
4695    /* Must exit loop to check un-masked IRQs */
4696    s->base.is_jmp = DISAS_EXIT;
4697}
4698
4699/* Generate an old-style exception return. Marks pc as dead. */
4700static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4701{
4702    gen_rfe(s, pc, load_cpu_field(spsr));
4703}
4704
4705/*
4706 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4707 * only call the helper when running single threaded TCG code to ensure
4708 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4709 * just skip this instruction. Currently the SEV/SEVL instructions
4710 * which are *one* of many ways to wake the CPU from WFE are not
4711 * implemented so we can't sleep like WFI does.
4712 */
4713static void gen_nop_hint(DisasContext *s, int val)
4714{
4715    switch (val) {
4716        /* When running in MTTCG we don't generate jumps to the yield and
4717         * WFE helpers as it won't affect the scheduling of other vCPUs.
4718         * If we wanted to more completely model WFE/SEV so we don't busy
4719         * spin unnecessarily we would need to do something more involved.
4720         */
4721    case 1: /* yield */
4722        if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4723            gen_set_pc_im(s, s->pc);
4724            s->base.is_jmp = DISAS_YIELD;
4725        }
4726        break;
4727    case 3: /* wfi */
4728        gen_set_pc_im(s, s->pc);
4729        s->base.is_jmp = DISAS_WFI;
4730        break;
4731    case 2: /* wfe */
4732        if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4733            gen_set_pc_im(s, s->pc);
4734            s->base.is_jmp = DISAS_WFE;
4735        }
4736        break;
4737    case 4: /* sev */
4738    case 5: /* sevl */
4739        /* TODO: Implement SEV, SEVL and WFE.  May help SMP performance.  */
4740    default: /* nop */
4741        break;
4742    }
4743}
4744
4745#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4746
4747static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4748{
4749    switch (size) {
4750    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4751    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4752    case 2: tcg_gen_add_i32(t0, t0, t1); break;
4753    default: abort();
4754    }
4755}
4756
4757static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4758{
4759    switch (size) {
4760    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4761    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4762    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4763    default: return;
4764    }
4765}
4766
4767/* 32-bit pairwise ops end up the same as the elementwise versions.  */
4768#define gen_helper_neon_pmax_s32  tcg_gen_smax_i32
4769#define gen_helper_neon_pmax_u32  tcg_gen_umax_i32
4770#define gen_helper_neon_pmin_s32  tcg_gen_smin_i32
4771#define gen_helper_neon_pmin_u32  tcg_gen_umin_i32
4772
4773#define GEN_NEON_INTEGER_OP_ENV(name) do { \
4774    switch ((size << 1) | u) { \
4775    case 0: \
4776        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4777        break; \
4778    case 1: \
4779        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4780        break; \
4781    case 2: \
4782        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4783        break; \
4784    case 3: \
4785        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4786        break; \
4787    case 4: \
4788        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4789        break; \
4790    case 5: \
4791        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4792        break; \
4793    default: return 1; \
4794    }} while (0)
4795
4796#define GEN_NEON_INTEGER_OP(name) do { \
4797    switch ((size << 1) | u) { \
4798    case 0: \
4799        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4800        break; \
4801    case 1: \
4802        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4803        break; \
4804    case 2: \
4805        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4806        break; \
4807    case 3: \
4808        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4809        break; \
4810    case 4: \
4811        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4812        break; \
4813    case 5: \
4814        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4815        break; \
4816    default: return 1; \
4817    }} while (0)
4818
4819static TCGv_i32 neon_load_scratch(int scratch)
4820{
4821    TCGv_i32 tmp = tcg_temp_new_i32();
4822    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4823    return tmp;
4824}
4825
4826static void neon_store_scratch(int scratch, TCGv_i32 var)
4827{
4828    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4829    tcg_temp_free_i32(var);
4830}
4831
4832static inline TCGv_i32 neon_get_scalar(int size, int reg)
4833{
4834    TCGv_i32 tmp;
4835    if (size == 1) {
4836        tmp = neon_load_reg(reg & 7, reg >> 4);
4837        if (reg & 8) {
4838            gen_neon_dup_high16(tmp);
4839        } else {
4840            gen_neon_dup_low16(tmp);
4841        }
4842    } else {
4843        tmp = neon_load_reg(reg & 15, reg >> 4);
4844    }
4845    return tmp;
4846}
4847
4848static int gen_neon_unzip(int rd, int rm, int size, int q)
4849{
4850    TCGv_ptr pd, pm;
4851    
4852    if (!q && size == 2) {
4853        return 1;
4854    }
4855    pd = vfp_reg_ptr(true, rd);
4856    pm = vfp_reg_ptr(true, rm);
4857    if (q) {
4858        switch (size) {
4859        case 0:
4860            gen_helper_neon_qunzip8(pd, pm);
4861            break;
4862        case 1:
4863            gen_helper_neon_qunzip16(pd, pm);
4864            break;
4865        case 2:
4866            gen_helper_neon_qunzip32(pd, pm);
4867            break;
4868        default:
4869            abort();
4870        }
4871    } else {
4872        switch (size) {
4873        case 0:
4874            gen_helper_neon_unzip8(pd, pm);
4875            break;
4876        case 1:
4877            gen_helper_neon_unzip16(pd, pm);
4878            break;
4879        default:
4880            abort();
4881        }
4882    }
4883    tcg_temp_free_ptr(pd);
4884    tcg_temp_free_ptr(pm);
4885    return 0;
4886}
4887
4888static int gen_neon_zip(int rd, int rm, int size, int q)
4889{
4890    TCGv_ptr pd, pm;
4891
4892    if (!q && size == 2) {
4893        return 1;
4894    }
4895    pd = vfp_reg_ptr(true, rd);
4896    pm = vfp_reg_ptr(true, rm);
4897    if (q) {
4898        switch (size) {
4899        case 0:
4900            gen_helper_neon_qzip8(pd, pm);
4901            break;
4902        case 1:
4903            gen_helper_neon_qzip16(pd, pm);
4904            break;
4905        case 2:
4906            gen_helper_neon_qzip32(pd, pm);
4907            break;
4908        default:
4909            abort();
4910        }
4911    } else {
4912        switch (size) {
4913        case 0:
4914            gen_helper_neon_zip8(pd, pm);
4915            break;
4916        case 1:
4917            gen_helper_neon_zip16(pd, pm);
4918            break;
4919        default:
4920            abort();
4921        }
4922    }
4923    tcg_temp_free_ptr(pd);
4924    tcg_temp_free_ptr(pm);
4925    return 0;
4926}
4927
4928static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4929{
4930    TCGv_i32 rd, tmp;
4931
4932    rd = tcg_temp_new_i32();
4933    tmp = tcg_temp_new_i32();
4934
4935    tcg_gen_shli_i32(rd, t0, 8);
4936    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4937    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4938    tcg_gen_or_i32(rd, rd, tmp);
4939
4940    tcg_gen_shri_i32(t1, t1, 8);
4941    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4942    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4943    tcg_gen_or_i32(t1, t1, tmp);
4944    tcg_gen_mov_i32(t0, rd);
4945
4946    tcg_temp_free_i32(tmp);
4947    tcg_temp_free_i32(rd);
4948}
4949
4950static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4951{
4952    TCGv_i32 rd, tmp;
4953
4954    rd = tcg_temp_new_i32();
4955    tmp = tcg_temp_new_i32();
4956
4957    tcg_gen_shli_i32(rd, t0, 16);
4958    tcg_gen_andi_i32(tmp, t1, 0xffff);
4959    tcg_gen_or_i32(rd, rd, tmp);
4960    tcg_gen_shri_i32(t1, t1, 16);
4961    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4962    tcg_gen_or_i32(t1, t1, tmp);
4963    tcg_gen_mov_i32(t0, rd);
4964
4965    tcg_temp_free_i32(tmp);
4966    tcg_temp_free_i32(rd);
4967}
4968
4969
4970static struct {
4971    int nregs;
4972    int interleave;
4973    int spacing;
4974} const neon_ls_element_type[11] = {
4975    {1, 4, 1},
4976    {1, 4, 2},
4977    {4, 1, 1},
4978    {2, 2, 2},
4979    {1, 3, 1},
4980    {1, 3, 2},
4981    {3, 1, 1},
4982    {1, 1, 1},
4983    {1, 2, 1},
4984    {1, 2, 2},
4985    {2, 1, 1}
4986};
4987
4988/* Translate a NEON load/store element instruction.  Return nonzero if the
4989   instruction is invalid.  */
4990static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4991{
4992    int rd, rn, rm;
4993    int op;
4994    int nregs;
4995    int interleave;
4996    int spacing;
4997    int stride;
4998    int size;
4999    int reg;
5000    int load;
5001    int n;
5002    int vec_size;
5003    int mmu_idx;
5004    TCGMemOp endian;
5005    TCGv_i32 addr;
5006    TCGv_i32 tmp;
5007    TCGv_i32 tmp2;
5008    TCGv_i64 tmp64;
5009
5010    /* FIXME: this access check should not take precedence over UNDEF
5011     * for invalid encodings; we will generate incorrect syndrome information
5012     * for attempts to execute invalid vfp/neon encodings with FP disabled.
5013     */
5014    if (s->fp_excp_el) {
5015        gen_exception_insn(s, 4, EXCP_UDEF,
5016                           syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
5017        return 0;
5018    }
5019
5020    if (!s->vfp_enabled)
5021      return 1;
5022    VFP_DREG_D(rd, insn);
5023    rn = (insn >> 16) & 0xf;
5024    rm = insn & 0xf;
5025    load = (insn & (1 << 21)) != 0;
5026    endian = s->be_data;
5027    mmu_idx = get_mem_index(s);
5028    if ((insn & (1 << 23)) == 0) {
5029        /* Load store all elements.  */
5030        op = (insn >> 8) & 0xf;
5031        size = (insn >> 6) & 3;
5032        if (op > 10)
5033            return 1;
5034        /* Catch UNDEF cases for bad values of align field */
5035        switch (op & 0xc) {
5036        case 4:
5037            if (((insn >> 5) & 1) == 1) {
5038                return 1;
5039            }
5040            break;
5041        case 8:
5042            if (((insn >> 4) & 3) == 3) {
5043                return 1;
5044            }
5045            break;
5046        default:
5047            break;
5048        }
5049        nregs = neon_ls_element_type[op].nregs;
5050        interleave = neon_ls_element_type[op].interleave;
5051        spacing = neon_ls_element_type[op].spacing;
5052        if (size == 3 && (interleave | spacing) != 1) {
5053            return 1;
5054        }
5055        /* For our purposes, bytes are always little-endian.  */
5056        if (size == 0) {
5057            endian = MO_LE;
5058        }
5059        /* Consecutive little-endian elements from a single register
5060         * can be promoted to a larger little-endian operation.
5061         */
5062        if (interleave == 1 && endian == MO_LE) {
5063            size = 3;
5064        }
5065        tmp64 = tcg_temp_new_i64();
5066        addr = tcg_temp_new_i32();
5067        tmp2 = tcg_const_i32(1 << size);
5068        load_reg_var(s, addr, rn);
5069        for (reg = 0; reg < nregs; reg++) {
5070            for (n = 0; n < 8 >> size; n++) {
5071                int xs;
5072                for (xs = 0; xs < interleave; xs++) {
5073                    int tt = rd + reg + spacing * xs;
5074
5075                    if (load) {
5076                        gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
5077                        neon_store_element64(tt, n, size, tmp64);
5078                    } else {
5079                        neon_load_element64(tmp64, tt, n, size);
5080                        gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
5081                    }
5082                    tcg_gen_add_i32(addr, addr, tmp2);
5083                }
5084            }
5085        }
5086        tcg_temp_free_i32(addr);
5087        tcg_temp_free_i32(tmp2);
5088        tcg_temp_free_i64(tmp64);
5089        stride = nregs * interleave * 8;
5090    } else {
5091        size = (insn >> 10) & 3;
5092        if (size == 3) {
5093            /* Load single element to all lanes.  */
5094            int a = (insn >> 4) & 1;
5095            if (!load) {
5096                return 1;
5097            }
5098            size = (insn >> 6) & 3;
5099            nregs = ((insn >> 8) & 3) + 1;
5100
5101            if (size == 3) {
5102                if (nregs != 4 || a == 0) {
5103                    return 1;
5104                }
5105                /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5106                size = 2;
5107            }
5108            if (nregs == 1 && a == 1 && size == 0) {
5109                return 1;
5110            }
5111            if (nregs == 3 && a == 1) {
5112                return 1;
5113            }
5114            addr = tcg_temp_new_i32();
5115            load_reg_var(s, addr, rn);
5116
5117            /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
5118             * VLD2/3/4 to all lanes: bit 5 indicates register stride.
5119             */
5120            stride = (insn & (1 << 5)) ? 2 : 1;
5121            vec_size = nregs == 1 ? stride * 8 : 8;
5122
5123            tmp = tcg_temp_new_i32();
5124            for (reg = 0; reg < nregs; reg++) {
5125                gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
5126                                s->be_data | size);
5127                if ((rd & 1) && vec_size == 16) {
5128                    /* We cannot write 16 bytes at once because the
5129                     * destination is unaligned.
5130                     */
5131                    tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
5132                                         8, 8, tmp);
5133                    tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
5134                                     neon_reg_offset(rd, 0), 8, 8);
5135                } else {
5136                    tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
5137                                         vec_size, vec_size, tmp);
5138                }
5139                tcg_gen_addi_i32(addr, addr, 1 << size);
5140                rd += stride;
5141            }
5142            tcg_temp_free_i32(tmp);
5143            tcg_temp_free_i32(addr);
5144            stride = (1 << size) * nregs;
5145        } else {
5146            /* Single element.  */
5147            int idx = (insn >> 4) & 0xf;
5148            int reg_idx;
5149            switch (size) {
5150            case 0:
5151                reg_idx = (insn >> 5) & 7;
5152                stride = 1;
5153                break;
5154            case 1:
5155                reg_idx = (insn >> 6) & 3;
5156                stride = (insn & (1 << 5)) ? 2 : 1;
5157                break;
5158            case 2:
5159                reg_idx = (insn >> 7) & 1;
5160                stride = (insn & (1 << 6)) ? 2 : 1;
5161                break;
5162            default:
5163                abort();
5164            }
5165            nregs = ((insn >> 8) & 3) + 1;
5166            /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5167            switch (nregs) {
5168            case 1:
5169                if (((idx & (1 << size)) != 0) ||
5170                    (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5171                    return 1;
5172                }
5173                break;
5174            case 3:
5175                if ((idx & 1) != 0) {
5176                    return 1;
5177                }
5178                /* fall through */
5179            case 2:
5180                if (size == 2 && (idx & 2) != 0) {
5181                    return 1;
5182                }
5183                break;
5184            case 4:
5185                if ((size == 2) && ((idx & 3) == 3)) {
5186                    return 1;
5187                }
5188                break;
5189            default:
5190                abort();
5191            }
5192            if ((rd + stride * (nregs - 1)) > 31) {
5193                /* Attempts to write off the end of the register file
5194                 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5195                 * the neon_load_reg() would write off the end of the array.
5196                 */
5197                return 1;
5198            }
5199            tmp = tcg_temp_new_i32();
5200            addr = tcg_temp_new_i32();
5201            load_reg_var(s, addr, rn);
5202            for (reg = 0; reg < nregs; reg++) {
5203                if (load) {
5204                    gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
5205                                    s->be_data | size);
5206                    neon_store_element(rd, reg_idx, size, tmp);
5207                } else { /* Store */
5208                    neon_load_element(tmp, rd, reg_idx, size);
5209                    gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
5210                                    s->be_data | size);
5211                }
5212                rd += stride;
5213                tcg_gen_addi_i32(addr, addr, 1 << size);
5214            }
5215            tcg_temp_free_i32(addr);
5216            tcg_temp_free_i32(tmp);
5217            stride = nregs * (1 << size);
5218        }
5219    }
5220    if (rm != 15) {
5221        TCGv_i32 base;
5222
5223        base = load_reg(s, rn);
5224        if (rm == 13) {
5225            tcg_gen_addi_i32(base, base, stride);
5226        } else {
5227            TCGv_i32 index;
5228            index = load_reg(s, rm);
5229            tcg_gen_add_i32(base, base, index);
5230            tcg_temp_free_i32(index);
5231        }
5232        store_reg(s, rn, base);
5233    }
5234    return 0;
5235}
5236
5237static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5238{
5239    switch (size) {
5240    case 0: gen_helper_neon_narrow_u8(dest, src); break;
5241    case 1: gen_helper_neon_narrow_u16(dest, src); break;
5242    case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5243    default: abort();
5244    }
5245}
5246
5247static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5248{
5249    switch (size) {
5250    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5251    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5252    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5253    default: abort();
5254    }
5255}
5256
5257static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5258{
5259    switch (size) {
5260    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5261    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5262    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5263    default: abort();
5264    }
5265}
5266
5267static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5268{
5269    switch (size) {
5270    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5271    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5272    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5273    default: abort();
5274    }
5275}
5276
5277static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5278                                         int q, int u)
5279{
5280    if (q) {
5281        if (u) {
5282            switch (size) {
5283            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5284            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5285            default: abort();
5286            }
5287        } else {
5288            switch (size) {
5289            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5290            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5291            default: abort();
5292            }
5293        }
5294    } else {
5295        if (u) {
5296            switch (size) {
5297            case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5298            case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5299            default: abort();
5300            }
5301        } else {
5302            switch (size) {
5303            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5304            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5305            default: abort();
5306            }
5307        }
5308    }
5309}
5310
5311static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5312{
5313    if (u) {
5314        switch (size) {
5315        case 0: gen_helper_neon_widen_u8(dest, src); break;
5316        case 1: gen_helper_neon_widen_u16(dest, src); break;
5317        case 2: tcg_gen_extu_i32_i64(dest, src); break;
5318        default: abort();
5319        }
5320    } else {
5321        switch (size) {
5322        case 0: gen_helper_neon_widen_s8(dest, src); break;
5323        case 1: gen_helper_neon_widen_s16(dest, src); break;
5324        case 2: tcg_gen_ext_i32_i64(dest, src); break;
5325        default: abort();
5326        }
5327    }
5328    tcg_temp_free_i32(src);
5329}
5330
5331static inline void gen_neon_addl(int size)
5332{
5333    switch (size) {
5334    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5335    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5336    case 2: tcg_gen_add_i64(CPU_V001); break;
5337    default: abort();
5338    }
5339}
5340
5341static inline void gen_neon_subl(int size)
5342{
5343    switch (size) {
5344    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5345    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5346    case 2: tcg_gen_sub_i64(CPU_V001); break;
5347    default: abort();
5348    }
5349}
5350
5351static inline void gen_neon_negl(TCGv_i64 var, int size)
5352{
5353    switch (size) {
5354    case 0: gen_helper_neon_negl_u16(var, var); break;
5355    case 1: gen_helper_neon_negl_u32(var, var); break;
5356    case 2:
5357        tcg_gen_neg_i64(var, var);
5358        break;
5359    default: abort();
5360    }
5361}
5362
5363static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5364{
5365    switch (size) {
5366    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5367    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5368    default: abort();
5369    }
5370}
5371
5372static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5373                                 int size, int u)
5374{
5375    TCGv_i64 tmp;
5376
5377    switch ((size << 1) | u) {
5378    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5379    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5380    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5381    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5382    case 4:
5383        tmp = gen_muls_i64_i32(a, b);
5384        tcg_gen_mov_i64(dest, tmp);
5385        tcg_temp_free_i64(tmp);
5386        break;
5387    case 5:
5388        tmp = gen_mulu_i64_i32(a, b);
5389        tcg_gen_mov_i64(dest, tmp);
5390        tcg_temp_free_i64(tmp);
5391        break;
5392    default: abort();
5393    }
5394
5395    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5396       Don't forget to clean them now.  */
5397    if (size < 2) {
5398        tcg_temp_free_i32(a);
5399        tcg_temp_free_i32(b);
5400    }
5401}
5402
5403static void gen_neon_narrow_op(int op, int u, int size,
5404                               TCGv_i32 dest, TCGv_i64 src)
5405{
5406    if (op) {
5407        if (u) {
5408            gen_neon_unarrow_sats(size, dest, src);
5409        } else {
5410            gen_neon_narrow(size, dest, src);
5411        }
5412    } else {
5413        if (u) {
5414            gen_neon_narrow_satu(size, dest, src);
5415        } else {
5416            gen_neon_narrow_sats(size, dest, src);
5417        }
5418    }
5419}
5420
5421/* Symbolic constants for op fields for Neon 3-register same-length.
5422 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5423 * table A7-9.
5424 */
5425#define NEON_3R_VHADD 0
5426#define NEON_3R_VQADD 1
5427#define NEON_3R_VRHADD 2
5428#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5429#define NEON_3R_VHSUB 4
5430#define NEON_3R_VQSUB 5
5431#define NEON_3R_VCGT 6
5432#define NEON_3R_VCGE 7
5433#define NEON_3R_VSHL 8
5434#define NEON_3R_VQSHL 9
5435#define NEON_3R_VRSHL 10
5436#define NEON_3R_VQRSHL 11
5437#define NEON_3R_VMAX 12
5438#define NEON_3R_VMIN 13
5439#define NEON_3R_VABD 14
5440#define NEON_3R_VABA 15
5441#define NEON_3R_VADD_VSUB 16
5442#define NEON_3R_VTST_VCEQ 17
5443#define NEON_3R_VML 18 /* VMLA, VMLS */
5444#define NEON_3R_VMUL 19
5445#define NEON_3R_VPMAX 20
5446#define NEON_3R_VPMIN 21
5447#define NEON_3R_VQDMULH_VQRDMULH 22
5448#define NEON_3R_VPADD_VQRDMLAH 23
5449#define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5450#define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5451#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5452#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5453#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5454#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5455#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5456#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5457
5458static const uint8_t neon_3r_sizes[] = {
5459    [NEON_3R_VHADD] = 0x7,
5460    [NEON_3R_VQADD] = 0xf,
5461    [NEON_3R_VRHADD] = 0x7,
5462    [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5463    [NEON_3R_VHSUB] = 0x7,
5464    [NEON_3R_VQSUB] = 0xf,
5465    [NEON_3R_VCGT] = 0x7,
5466    [NEON_3R_VCGE] = 0x7,
5467    [NEON_3R_VSHL] = 0xf,
5468    [NEON_3R_VQSHL] = 0xf,
5469    [NEON_3R_VRSHL] = 0xf,
5470    [NEON_3R_VQRSHL] = 0xf,
5471    [NEON_3R_VMAX] = 0x7,
5472    [NEON_3R_VMIN] = 0x7,
5473    [NEON_3R_VABD] = 0x7,
5474    [NEON_3R_VABA] = 0x7,
5475    [NEON_3R_VADD_VSUB] = 0xf,
5476    [NEON_3R_VTST_VCEQ] = 0x7,
5477    [NEON_3R_VML] = 0x7,
5478    [NEON_3R_VMUL] = 0x7,
5479    [NEON_3R_VPMAX] = 0x7,
5480    [NEON_3R_VPMIN] = 0x7,
5481    [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5482    [NEON_3R_VPADD_VQRDMLAH] = 0x7,
5483    [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5484    [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
5485    [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5486    [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5487    [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5488    [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5489    [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5490    [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5491};
5492
5493/* Symbolic constants for op fields for Neon 2-register miscellaneous.
5494 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5495 * table A7-13.
5496 */
5497#define NEON_2RM_VREV64 0
5498#define NEON_2RM_VREV32 1
5499#define NEON_2RM_VREV16 2
5500#define NEON_2RM_VPADDL 4
5501#define NEON_2RM_VPADDL_U 5
5502#define NEON_2RM_AESE 6 /* Includes AESD */
5503#define NEON_2RM_AESMC 7 /* Includes AESIMC */
5504#define NEON_2RM_VCLS 8
5505#define NEON_2RM_VCLZ 9
5506#define NEON_2RM_VCNT 10
5507#define NEON_2RM_VMVN 11
5508#define NEON_2RM_VPADAL 12
5509#define NEON_2RM_VPADAL_U 13
5510#define NEON_2RM_VQABS 14
5511#define NEON_2RM_VQNEG 15
5512#define NEON_2RM_VCGT0 16
5513#define NEON_2RM_VCGE0 17
5514#define NEON_2RM_VCEQ0 18
5515#define NEON_2RM_VCLE0 19
5516#define NEON_2RM_VCLT0 20
5517#define NEON_2RM_SHA1H 21
5518#define NEON_2RM_VABS 22
5519#define NEON_2RM_VNEG 23
5520#define NEON_2RM_VCGT0_F 24
5521#define NEON_2RM_VCGE0_F 25
5522#define NEON_2RM_VCEQ0_F 26
5523#define NEON_2RM_VCLE0_F 27
5524#define NEON_2RM_VCLT0_F 28
5525#define NEON_2RM_VABS_F 30
5526#define NEON_2RM_VNEG_F 31
5527#define NEON_2RM_VSWP 32
5528#define NEON_2RM_VTRN 33
5529#define NEON_2RM_VUZP 34
5530#define NEON_2RM_VZIP 35
5531#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5532#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5533#define NEON_2RM_VSHLL 38
5534#define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5535#define NEON_2RM_VRINTN 40
5536#define NEON_2RM_VRINTX 41
5537#define NEON_2RM_VRINTA 42
5538#define NEON_2RM_VRINTZ 43
5539#define NEON_2RM_VCVT_F16_F32 44
5540#define NEON_2RM_VRINTM 45
5541#define NEON_2RM_VCVT_F32_F16 46
5542#define NEON_2RM_VRINTP 47
5543#define NEON_2RM_VCVTAU 48
5544#define NEON_2RM_VCVTAS 49
5545#define NEON_2RM_VCVTNU 50
5546#define NEON_2RM_VCVTNS 51
5547#define NEON_2RM_VCVTPU 52
5548#define NEON_2RM_VCVTPS 53
5549#define NEON_2RM_VCVTMU 54
5550#define NEON_2RM_VCVTMS 55
5551#define NEON_2RM_VRECPE 56
5552#define NEON_2RM_VRSQRTE 57
5553#define NEON_2RM_VRECPE_F 58
5554#define NEON_2RM_VRSQRTE_F 59
5555#define NEON_2RM_VCVT_FS 60
5556#define NEON_2RM_VCVT_FU 61
5557#define NEON_2RM_VCVT_SF 62
5558#define NEON_2RM_VCVT_UF 63
5559
5560static int neon_2rm_is_float_op(int op)
5561{
5562    /* Return true if this neon 2reg-misc op is float-to-float */
5563    return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5564            (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5565            op == NEON_2RM_VRINTM ||
5566            (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5567            op >= NEON_2RM_VRECPE_F);
5568}
5569
5570static bool neon_2rm_is_v8_op(int op)
5571{
5572    /* Return true if this neon 2reg-misc op is ARMv8 and up */
5573    switch (op) {
5574    case NEON_2RM_VRINTN:
5575    case NEON_2RM_VRINTA:
5576    case NEON_2RM_VRINTM:
5577    case NEON_2RM_VRINTP:
5578    case NEON_2RM_VRINTZ:
5579    case NEON_2RM_VRINTX:
5580    case NEON_2RM_VCVTAU:
5581    case NEON_2RM_VCVTAS:
5582    case NEON_2RM_VCVTNU:
5583    case NEON_2RM_VCVTNS:
5584    case NEON_2RM_VCVTPU:
5585    case NEON_2RM_VCVTPS:
5586    case NEON_2RM_VCVTMU:
5587    case NEON_2RM_VCVTMS:
5588        return true;
5589    default:
5590        return false;
5591    }
5592}
5593
5594/* Each entry in this array has bit n set if the insn allows
5595 * size value n (otherwise it will UNDEF). Since unallocated
5596 * op values will have no bits set they always UNDEF.
5597 */
5598static const uint8_t neon_2rm_sizes[] = {
5599    [NEON_2RM_VREV64] = 0x7,
5600    [NEON_2RM_VREV32] = 0x3,
5601    [NEON_2RM_VREV16] = 0x1,
5602    [NEON_2RM_VPADDL] = 0x7,
5603    [NEON_2RM_VPADDL_U] = 0x7,
5604    [NEON_2RM_AESE] = 0x1,
5605    [NEON_2RM_AESMC] = 0x1,
5606    [NEON_2RM_VCLS] = 0x7,
5607    [NEON_2RM_VCLZ] = 0x7,
5608    [NEON_2RM_VCNT] = 0x1,
5609    [NEON_2RM_VMVN] = 0x1,
5610    [NEON_2RM_VPADAL] = 0x7,
5611    [NEON_2RM_VPADAL_U] = 0x7,
5612    [NEON_2RM_VQABS] = 0x7,
5613    [NEON_2RM_VQNEG] = 0x7,
5614    [NEON_2RM_VCGT0] = 0x7,
5615    [NEON_2RM_VCGE0] = 0x7,
5616    [NEON_2RM_VCEQ0] = 0x7,
5617    [NEON_2RM_VCLE0] = 0x7,
5618    [NEON_2RM_VCLT0] = 0x7,
5619    [NEON_2RM_SHA1H] = 0x4,
5620    [NEON_2RM_VABS] = 0x7,
5621    [NEON_2RM_VNEG] = 0x7,
5622    [NEON_2RM_VCGT0_F] = 0x4,
5623    [NEON_2RM_VCGE0_F] = 0x4,
5624    [NEON_2RM_VCEQ0_F] = 0x4,
5625    [NEON_2RM_VCLE0_F] = 0x4,
5626    [NEON_2RM_VCLT0_F] = 0x4,
5627    [NEON_2RM_VABS_F] = 0x4,
5628    [NEON_2RM_VNEG_F] = 0x4,
5629    [NEON_2RM_VSWP] = 0x1,
5630    [NEON_2RM_VTRN] = 0x7,
5631    [NEON_2RM_VUZP] = 0x7,
5632    [NEON_2RM_VZIP] = 0x7,
5633    [NEON_2RM_VMOVN] = 0x7,
5634    [NEON_2RM_VQMOVN] = 0x7,
5635    [NEON_2RM_VSHLL] = 0x7,
5636    [NEON_2RM_SHA1SU1] = 0x4,
5637    [NEON_2RM_VRINTN] = 0x4,
5638    [NEON_2RM_VRINTX] = 0x4,
5639    [NEON_2RM_VRINTA] = 0x4,
5640    [NEON_2RM_VRINTZ] = 0x4,
5641    [NEON_2RM_VCVT_F16_F32] = 0x2,
5642    [NEON_2RM_VRINTM] = 0x4,
5643    [NEON_2RM_VCVT_F32_F16] = 0x2,
5644    [NEON_2RM_VRINTP] = 0x4,
5645    [NEON_2RM_VCVTAU] = 0x4,
5646    [NEON_2RM_VCVTAS] = 0x4,
5647    [NEON_2RM_VCVTNU] = 0x4,
5648    [NEON_2RM_VCVTNS] = 0x4,
5649    [NEON_2RM_VCVTPU] = 0x4,
5650    [NEON_2RM_VCVTPS] = 0x4,
5651    [NEON_2RM_VCVTMU] = 0x4,
5652    [NEON_2RM_VCVTMS] = 0x4,
5653    [NEON_2RM_VRECPE] = 0x4,
5654    [NEON_2RM_VRSQRTE] = 0x4,
5655    [NEON_2RM_VRECPE_F] = 0x4,
5656    [NEON_2RM_VRSQRTE_F] = 0x4,
5657    [NEON_2RM_VCVT_FS] = 0x4,
5658    [NEON_2RM_VCVT_FU] = 0x4,
5659    [NEON_2RM_VCVT_SF] = 0x4,
5660    [NEON_2RM_VCVT_UF] = 0x4,
5661};
5662
5663
5664/* Expand v8.1 simd helper.  */
5665static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
5666                         int q, int rd, int rn, int rm)
5667{
5668    if (dc_isar_feature(aa32_rdm, s)) {
5669        int opr_sz = (1 + q) * 8;
5670        tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
5671                           vfp_reg_offset(1, rn),
5672                           vfp_reg_offset(1, rm), cpu_env,
5673                           opr_sz, opr_sz, 0, fn);
5674        return 0;
5675    }
5676    return 1;
5677}
5678
5679/*
5680 * Expanders for VBitOps_VBIF, VBIT, VBSL.
5681 */
5682static void gen_bsl_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5683{
5684    tcg_gen_xor_i64(rn, rn, rm);
5685    tcg_gen_and_i64(rn, rn, rd);
5686    tcg_gen_xor_i64(rd, rm, rn);
5687}
5688
5689static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5690{
5691    tcg_gen_xor_i64(rn, rn, rd);
5692    tcg_gen_and_i64(rn, rn, rm);
5693    tcg_gen_xor_i64(rd, rd, rn);
5694}
5695
5696static void gen_bif_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5697{
5698    tcg_gen_xor_i64(rn, rn, rd);
5699    tcg_gen_andc_i64(rn, rn, rm);
5700    tcg_gen_xor_i64(rd, rd, rn);
5701}
5702
5703static void gen_bsl_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5704{
5705    tcg_gen_xor_vec(vece, rn, rn, rm);
5706    tcg_gen_and_vec(vece, rn, rn, rd);
5707    tcg_gen_xor_vec(vece, rd, rm, rn);
5708}
5709
5710static void gen_bit_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5711{
5712    tcg_gen_xor_vec(vece, rn, rn, rd);
5713    tcg_gen_and_vec(vece, rn, rn, rm);
5714    tcg_gen_xor_vec(vece, rd, rd, rn);
5715}
5716
5717static void gen_bif_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5718{
5719    tcg_gen_xor_vec(vece, rn, rn, rd);
5720    tcg_gen_andc_vec(vece, rn, rn, rm);
5721    tcg_gen_xor_vec(vece, rd, rd, rn);
5722}
5723
5724const GVecGen3 bsl_op = {
5725    .fni8 = gen_bsl_i64,
5726    .fniv = gen_bsl_vec,
5727    .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5728    .load_dest = true
5729};
5730
5731const GVecGen3 bit_op = {
5732    .fni8 = gen_bit_i64,
5733    .fniv = gen_bit_vec,
5734    .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5735    .load_dest = true
5736};
5737
5738const GVecGen3 bif_op = {
5739    .fni8 = gen_bif_i64,
5740    .fniv = gen_bif_vec,
5741    .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5742    .load_dest = true
5743};
5744
5745static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5746{
5747    tcg_gen_vec_sar8i_i64(a, a, shift);
5748    tcg_gen_vec_add8_i64(d, d, a);
5749}
5750
5751static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5752{
5753    tcg_gen_vec_sar16i_i64(a, a, shift);
5754    tcg_gen_vec_add16_i64(d, d, a);
5755}
5756
5757static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5758{
5759    tcg_gen_sari_i32(a, a, shift);
5760    tcg_gen_add_i32(d, d, a);
5761}
5762
5763static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5764{
5765    tcg_gen_sari_i64(a, a, shift);
5766    tcg_gen_add_i64(d, d, a);
5767}
5768
5769static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5770{
5771    tcg_gen_sari_vec(vece, a, a, sh);
5772    tcg_gen_add_vec(vece, d, d, a);
5773}
5774
5775const GVecGen2i ssra_op[4] = {
5776    { .fni8 = gen_ssra8_i64,
5777      .fniv = gen_ssra_vec,
5778      .load_dest = true,
5779      .opc = INDEX_op_sari_vec,
5780      .vece = MO_8 },
5781    { .fni8 = gen_ssra16_i64,
5782      .fniv = gen_ssra_vec,
5783      .load_dest = true,
5784      .opc = INDEX_op_sari_vec,
5785      .vece = MO_16 },
5786    { .fni4 = gen_ssra32_i32,
5787      .fniv = gen_ssra_vec,
5788      .load_dest = true,
5789      .opc = INDEX_op_sari_vec,
5790      .vece = MO_32 },
5791    { .fni8 = gen_ssra64_i64,
5792      .fniv = gen_ssra_vec,
5793      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5794      .load_dest = true,
5795      .opc = INDEX_op_sari_vec,
5796      .vece = MO_64 },
5797};
5798
5799static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5800{
5801    tcg_gen_vec_shr8i_i64(a, a, shift);
5802    tcg_gen_vec_add8_i64(d, d, a);
5803}
5804
5805static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5806{
5807    tcg_gen_vec_shr16i_i64(a, a, shift);
5808    tcg_gen_vec_add16_i64(d, d, a);
5809}
5810
5811static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5812{
5813    tcg_gen_shri_i32(a, a, shift);
5814    tcg_gen_add_i32(d, d, a);
5815}
5816
5817static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5818{
5819    tcg_gen_shri_i64(a, a, shift);
5820    tcg_gen_add_i64(d, d, a);
5821}
5822
5823static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5824{
5825    tcg_gen_shri_vec(vece, a, a, sh);
5826    tcg_gen_add_vec(vece, d, d, a);
5827}
5828
5829const GVecGen2i usra_op[4] = {
5830    { .fni8 = gen_usra8_i64,
5831      .fniv = gen_usra_vec,
5832      .load_dest = true,
5833      .opc = INDEX_op_shri_vec,
5834      .vece = MO_8, },
5835    { .fni8 = gen_usra16_i64,
5836      .fniv = gen_usra_vec,
5837      .load_dest = true,
5838      .opc = INDEX_op_shri_vec,
5839      .vece = MO_16, },
5840    { .fni4 = gen_usra32_i32,
5841      .fniv = gen_usra_vec,
5842      .load_dest = true,
5843      .opc = INDEX_op_shri_vec,
5844      .vece = MO_32, },
5845    { .fni8 = gen_usra64_i64,
5846      .fniv = gen_usra_vec,
5847      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5848      .load_dest = true,
5849      .opc = INDEX_op_shri_vec,
5850      .vece = MO_64, },
5851};
5852
5853static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5854{
5855    uint64_t mask = dup_const(MO_8, 0xff >> shift);
5856    TCGv_i64 t = tcg_temp_new_i64();
5857
5858    tcg_gen_shri_i64(t, a, shift);
5859    tcg_gen_andi_i64(t, t, mask);
5860    tcg_gen_andi_i64(d, d, ~mask);
5861    tcg_gen_or_i64(d, d, t);
5862    tcg_temp_free_i64(t);
5863}
5864
5865static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5866{
5867    uint64_t mask = dup_const(MO_16, 0xffff >> shift);
5868    TCGv_i64 t = tcg_temp_new_i64();
5869
5870    tcg_gen_shri_i64(t, a, shift);
5871    tcg_gen_andi_i64(t, t, mask);
5872    tcg_gen_andi_i64(d, d, ~mask);
5873    tcg_gen_or_i64(d, d, t);
5874    tcg_temp_free_i64(t);
5875}
5876
5877static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5878{
5879    tcg_gen_shri_i32(a, a, shift);
5880    tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
5881}
5882
5883static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5884{
5885    tcg_gen_shri_i64(a, a, shift);
5886    tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
5887}
5888
5889static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5890{
5891    if (sh == 0) {
5892        tcg_gen_mov_vec(d, a);
5893    } else {
5894        TCGv_vec t = tcg_temp_new_vec_matching(d);
5895        TCGv_vec m = tcg_temp_new_vec_matching(d);
5896
5897        tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
5898        tcg_gen_shri_vec(vece, t, a, sh);
5899        tcg_gen_and_vec(vece, d, d, m);
5900        tcg_gen_or_vec(vece, d, d, t);
5901
5902        tcg_temp_free_vec(t);
5903        tcg_temp_free_vec(m);
5904    }
5905}
5906
5907const GVecGen2i sri_op[4] = {
5908    { .fni8 = gen_shr8_ins_i64,
5909      .fniv = gen_shr_ins_vec,
5910      .load_dest = true,
5911      .opc = INDEX_op_shri_vec,
5912      .vece = MO_8 },
5913    { .fni8 = gen_shr16_ins_i64,
5914      .fniv = gen_shr_ins_vec,
5915      .load_dest = true,
5916      .opc = INDEX_op_shri_vec,
5917      .vece = MO_16 },
5918    { .fni4 = gen_shr32_ins_i32,
5919      .fniv = gen_shr_ins_vec,
5920      .load_dest = true,
5921      .opc = INDEX_op_shri_vec,
5922      .vece = MO_32 },
5923    { .fni8 = gen_shr64_ins_i64,
5924      .fniv = gen_shr_ins_vec,
5925      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5926      .load_dest = true,
5927      .opc = INDEX_op_shri_vec,
5928      .vece = MO_64 },
5929};
5930
5931static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5932{
5933    uint64_t mask = dup_const(MO_8, 0xff << shift);
5934    TCGv_i64 t = tcg_temp_new_i64();
5935
5936    tcg_gen_shli_i64(t, a, shift);
5937    tcg_gen_andi_i64(t, t, mask);
5938    tcg_gen_andi_i64(d, d, ~mask);
5939    tcg_gen_or_i64(d, d, t);
5940    tcg_temp_free_i64(t);
5941}
5942
5943static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5944{
5945    uint64_t mask = dup_const(MO_16, 0xffff << shift);
5946    TCGv_i64 t = tcg_temp_new_i64();
5947
5948    tcg_gen_shli_i64(t, a, shift);
5949    tcg_gen_andi_i64(t, t, mask);
5950    tcg_gen_andi_i64(d, d, ~mask);
5951    tcg_gen_or_i64(d, d, t);
5952    tcg_temp_free_i64(t);
5953}
5954
5955static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5956{
5957    tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
5958}
5959
5960static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5961{
5962    tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
5963}
5964
5965static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5966{
5967    if (sh == 0) {
5968        tcg_gen_mov_vec(d, a);
5969    } else {
5970        TCGv_vec t = tcg_temp_new_vec_matching(d);
5971        TCGv_vec m = tcg_temp_new_vec_matching(d);
5972
5973        tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
5974        tcg_gen_shli_vec(vece, t, a, sh);
5975        tcg_gen_and_vec(vece, d, d, m);
5976        tcg_gen_or_vec(vece, d, d, t);
5977
5978        tcg_temp_free_vec(t);
5979        tcg_temp_free_vec(m);
5980    }
5981}
5982
5983const GVecGen2i sli_op[4] = {
5984    { .fni8 = gen_shl8_ins_i64,
5985      .fniv = gen_shl_ins_vec,
5986      .load_dest = true,
5987      .opc = INDEX_op_shli_vec,
5988      .vece = MO_8 },
5989    { .fni8 = gen_shl16_ins_i64,
5990      .fniv = gen_shl_ins_vec,
5991      .load_dest = true,
5992      .opc = INDEX_op_shli_vec,
5993      .vece = MO_16 },
5994    { .fni4 = gen_shl32_ins_i32,
5995      .fniv = gen_shl_ins_vec,
5996      .load_dest = true,
5997      .opc = INDEX_op_shli_vec,
5998      .vece = MO_32 },
5999    { .fni8 = gen_shl64_ins_i64,
6000      .fniv = gen_shl_ins_vec,
6001      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6002      .load_dest = true,
6003      .opc = INDEX_op_shli_vec,
6004      .vece = MO_64 },
6005};
6006
6007static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6008{
6009    gen_helper_neon_mul_u8(a, a, b);
6010    gen_helper_neon_add_u8(d, d, a);
6011}
6012
6013static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6014{
6015    gen_helper_neon_mul_u8(a, a, b);
6016    gen_helper_neon_sub_u8(d, d, a);
6017}
6018
6019static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6020{
6021    gen_helper_neon_mul_u16(a, a, b);
6022    gen_helper_neon_add_u16(d, d, a);
6023}
6024
6025static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6026{
6027    gen_helper_neon_mul_u16(a, a, b);
6028    gen_helper_neon_sub_u16(d, d, a);
6029}
6030
6031static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6032{
6033    tcg_gen_mul_i32(a, a, b);
6034    tcg_gen_add_i32(d, d, a);
6035}
6036
6037static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6038{
6039    tcg_gen_mul_i32(a, a, b);
6040    tcg_gen_sub_i32(d, d, a);
6041}
6042
6043static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
6044{
6045    tcg_gen_mul_i64(a, a, b);
6046    tcg_gen_add_i64(d, d, a);
6047}
6048
6049static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
6050{
6051    tcg_gen_mul_i64(a, a, b);
6052    tcg_gen_sub_i64(d, d, a);
6053}
6054
6055static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
6056{
6057    tcg_gen_mul_vec(vece, a, a, b);
6058    tcg_gen_add_vec(vece, d, d, a);
6059}
6060
6061static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
6062{
6063    tcg_gen_mul_vec(vece, a, a, b);
6064    tcg_gen_sub_vec(vece, d, d, a);
6065}
6066
6067/* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
6068 * these tables are shared with AArch64 which does support them.
6069 */
6070const GVecGen3 mla_op[4] = {
6071    { .fni4 = gen_mla8_i32,
6072      .fniv = gen_mla_vec,
6073      .opc = INDEX_op_mul_vec,
6074      .load_dest = true,
6075      .vece = MO_8 },
6076    { .fni4 = gen_mla16_i32,
6077      .fniv = gen_mla_vec,
6078      .opc = INDEX_op_mul_vec,
6079      .load_dest = true,
6080      .vece = MO_16 },
6081    { .fni4 = gen_mla32_i32,
6082      .fniv = gen_mla_vec,
6083      .opc = INDEX_op_mul_vec,
6084      .load_dest = true,
6085      .vece = MO_32 },
6086    { .fni8 = gen_mla64_i64,
6087      .fniv = gen_mla_vec,
6088      .opc = INDEX_op_mul_vec,
6089      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6090      .load_dest = true,
6091      .vece = MO_64 },
6092};
6093
6094const GVecGen3 mls_op[4] = {
6095    { .fni4 = gen_mls8_i32,
6096      .fniv = gen_mls_vec,
6097      .opc = INDEX_op_mul_vec,
6098      .load_dest = true,
6099      .vece = MO_8 },
6100    { .fni4 = gen_mls16_i32,
6101      .fniv = gen_mls_vec,
6102      .opc = INDEX_op_mul_vec,
6103      .load_dest = true,
6104      .vece = MO_16 },
6105    { .fni4 = gen_mls32_i32,
6106      .fniv = gen_mls_vec,
6107      .opc = INDEX_op_mul_vec,
6108      .load_dest = true,
6109      .vece = MO_32 },
6110    { .fni8 = gen_mls64_i64,
6111      .fniv = gen_mls_vec,
6112      .opc = INDEX_op_mul_vec,
6113      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6114      .load_dest = true,
6115      .vece = MO_64 },
6116};
6117
6118/* CMTST : test is "if (X & Y != 0)". */
6119static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6120{
6121    tcg_gen_and_i32(d, a, b);
6122    tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
6123    tcg_gen_neg_i32(d, d);
6124}
6125
6126void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
6127{
6128    tcg_gen_and_i64(d, a, b);
6129    tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
6130    tcg_gen_neg_i64(d, d);
6131}
6132
6133static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
6134{
6135    tcg_gen_and_vec(vece, d, a, b);
6136    tcg_gen_dupi_vec(vece, a, 0);
6137    tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
6138}
6139
6140const GVecGen3 cmtst_op[4] = {
6141    { .fni4 = gen_helper_neon_tst_u8,
6142      .fniv = gen_cmtst_vec,
6143      .vece = MO_8 },
6144    { .fni4 = gen_helper_neon_tst_u16,
6145      .fniv = gen_cmtst_vec,
6146      .vece = MO_16 },
6147    { .fni4 = gen_cmtst_i32,
6148      .fniv = gen_cmtst_vec,
6149      .vece = MO_32 },
6150    { .fni8 = gen_cmtst_i64,
6151      .fniv = gen_cmtst_vec,
6152      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6153      .vece = MO_64 },
6154};
6155
6156static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
6157                          TCGv_vec a, TCGv_vec b)
6158{
6159    TCGv_vec x = tcg_temp_new_vec_matching(t);
6160    tcg_gen_add_vec(vece, x, a, b);
6161    tcg_gen_usadd_vec(vece, t, a, b);
6162    tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
6163    tcg_gen_or_vec(vece, sat, sat, x);
6164    tcg_temp_free_vec(x);
6165}
6166
6167const GVecGen4 uqadd_op[4] = {
6168    { .fniv = gen_uqadd_vec,
6169      .fno = gen_helper_gvec_uqadd_b,
6170      .opc = INDEX_op_usadd_vec,
6171      .write_aofs = true,
6172      .vece = MO_8 },
6173    { .fniv = gen_uqadd_vec,
6174      .fno = gen_helper_gvec_uqadd_h,
6175      .opc = INDEX_op_usadd_vec,
6176      .write_aofs = true,
6177      .vece = MO_16 },
6178    { .fniv = gen_uqadd_vec,
6179      .fno = gen_helper_gvec_uqadd_s,
6180      .opc = INDEX_op_usadd_vec,
6181      .write_aofs = true,
6182      .vece = MO_32 },
6183    { .fniv = gen_uqadd_vec,
6184      .fno = gen_helper_gvec_uqadd_d,
6185      .opc = INDEX_op_usadd_vec,
6186      .write_aofs = true,
6187      .vece = MO_64 },
6188};
6189
6190static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
6191                          TCGv_vec a, TCGv_vec b)
6192{
6193    TCGv_vec x = tcg_temp_new_vec_matching(t);
6194    tcg_gen_add_vec(vece, x, a, b);
6195    tcg_gen_ssadd_vec(vece, t, a, b);
6196    tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
6197    tcg_gen_or_vec(vece, sat, sat, x);
6198    tcg_temp_free_vec(x);
6199}
6200
6201const GVecGen4 sqadd_op[4] = {
6202    { .fniv = gen_sqadd_vec,
6203      .fno = gen_helper_gvec_sqadd_b,
6204      .opc = INDEX_op_ssadd_vec,
6205      .write_aofs = true,
6206      .vece = MO_8 },
6207    { .fniv = gen_sqadd_vec,
6208      .fno = gen_helper_gvec_sqadd_h,
6209      .opc = INDEX_op_ssadd_vec,
6210      .write_aofs = true,
6211      .vece = MO_16 },
6212    { .fniv = gen_sqadd_vec,
6213      .fno = gen_helper_gvec_sqadd_s,
6214      .opc = INDEX_op_ssadd_vec,
6215      .write_aofs = true,
6216      .vece = MO_32 },
6217    { .fniv = gen_sqadd_vec,
6218      .fno = gen_helper_gvec_sqadd_d,
6219      .opc = INDEX_op_ssadd_vec,
6220      .write_aofs = true,
6221      .vece = MO_64 },
6222};
6223
6224static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
6225                          TCGv_vec a, TCGv_vec b)
6226{
6227    TCGv_vec x = tcg_temp_new_vec_matching(t);
6228    tcg_gen_sub_vec(vece, x, a, b);
6229    tcg_gen_ussub_vec(vece, t, a, b);
6230    tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
6231    tcg_gen_or_vec(vece, sat, sat, x);
6232    tcg_temp_free_vec(x);
6233}
6234
6235const GVecGen4 uqsub_op[4] = {
6236    { .fniv = gen_uqsub_vec,
6237      .fno = gen_helper_gvec_uqsub_b,
6238      .opc = INDEX_op_ussub_vec,
6239      .write_aofs = true,
6240      .vece = MO_8 },
6241    { .fniv = gen_uqsub_vec,
6242      .fno = gen_helper_gvec_uqsub_h,
6243      .opc = INDEX_op_ussub_vec,
6244      .write_aofs = true,
6245      .vece = MO_16 },
6246    { .fniv = gen_uqsub_vec,
6247      .fno = gen_helper_gvec_uqsub_s,
6248      .opc = INDEX_op_ussub_vec,
6249      .write_aofs = true,
6250      .vece = MO_32 },
6251    { .fniv = gen_uqsub_vec,
6252      .fno = gen_helper_gvec_uqsub_d,
6253      .opc = INDEX_op_ussub_vec,
6254      .write_aofs = true,
6255      .vece = MO_64 },
6256};
6257
6258static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
6259                          TCGv_vec a, TCGv_vec b)
6260{
6261    TCGv_vec x = tcg_temp_new_vec_matching(t);
6262    tcg_gen_sub_vec(vece, x, a, b);
6263    tcg_gen_sssub_vec(vece, t, a, b);
6264    tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
6265    tcg_gen_or_vec(vece, sat, sat, x);
6266    tcg_temp_free_vec(x);
6267}
6268
6269const GVecGen4 sqsub_op[4] = {
6270    { .fniv = gen_sqsub_vec,
6271      .fno = gen_helper_gvec_sqsub_b,
6272      .opc = INDEX_op_sssub_vec,
6273      .write_aofs = true,
6274      .vece = MO_8 },
6275    { .fniv = gen_sqsub_vec,
6276      .fno = gen_helper_gvec_sqsub_h,
6277      .opc = INDEX_op_sssub_vec,
6278      .write_aofs = true,
6279      .vece = MO_16 },
6280    { .fniv = gen_sqsub_vec,
6281      .fno = gen_helper_gvec_sqsub_s,
6282      .opc = INDEX_op_sssub_vec,
6283      .write_aofs = true,
6284      .vece = MO_32 },
6285    { .fniv = gen_sqsub_vec,
6286      .fno = gen_helper_gvec_sqsub_d,
6287      .opc = INDEX_op_sssub_vec,
6288      .write_aofs = true,
6289      .vece = MO_64 },
6290};
6291
6292/* Translate a NEON data processing instruction.  Return nonzero if the
6293   instruction is invalid.
6294   We process data in a mixture of 32-bit and 64-bit chunks.
6295   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
6296
6297static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
6298{
6299    int op;
6300    int q;
6301    int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
6302    int size;
6303    int shift;
6304    int pass;
6305    int count;
6306    int pairwise;
6307    int u;
6308    int vec_size;
6309    uint32_t imm;
6310    TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
6311    TCGv_ptr ptr1, ptr2, ptr3;
6312    TCGv_i64 tmp64;
6313
6314    /* FIXME: this access check should not take precedence over UNDEF
6315     * for invalid encodings; we will generate incorrect syndrome information
6316     * for attempts to execute invalid vfp/neon encodings with FP disabled.
6317     */
6318    if (s->fp_excp_el) {
6319        gen_exception_insn(s, 4, EXCP_UDEF,
6320                           syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6321        return 0;
6322    }
6323
6324    if (!s->vfp_enabled)
6325      return 1;
6326    q = (insn & (1 << 6)) != 0;
6327    u = (insn >> 24) & 1;
6328    VFP_DREG_D(rd, insn);
6329    VFP_DREG_N(rn, insn);
6330    VFP_DREG_M(rm, insn);
6331    size = (insn >> 20) & 3;
6332    vec_size = q ? 16 : 8;
6333    rd_ofs = neon_reg_offset(rd, 0);
6334    rn_ofs = neon_reg_offset(rn, 0);
6335    rm_ofs = neon_reg_offset(rm, 0);
6336
6337    if ((insn & (1 << 23)) == 0) {
6338        /* Three register same length.  */
6339        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
6340        /* Catch invalid op and bad size combinations: UNDEF */
6341        if ((neon_3r_sizes[op] & (1 << size)) == 0) {
6342            return 1;
6343        }
6344        /* All insns of this form UNDEF for either this condition or the
6345         * superset of cases "Q==1"; we catch the latter later.
6346         */
6347        if (q && ((rd | rn | rm) & 1)) {
6348            return 1;
6349        }
6350        switch (op) {
6351        case NEON_3R_SHA:
6352            /* The SHA-1/SHA-256 3-register instructions require special
6353             * treatment here, as their size field is overloaded as an
6354             * op type selector, and they all consume their input in a
6355             * single pass.
6356             */
6357            if (!q) {
6358                return 1;
6359            }
6360            if (!u) { /* SHA-1 */
6361                if (!dc_isar_feature(aa32_sha1, s)) {
6362                    return 1;
6363                }
6364                ptr1 = vfp_reg_ptr(true, rd);
6365                ptr2 = vfp_reg_ptr(true, rn);
6366                ptr3 = vfp_reg_ptr(true, rm);
6367                tmp4 = tcg_const_i32(size);
6368                gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
6369                tcg_temp_free_i32(tmp4);
6370            } else { /* SHA-256 */
6371                if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
6372                    return 1;
6373                }
6374                ptr1 = vfp_reg_ptr(true, rd);
6375                ptr2 = vfp_reg_ptr(true, rn);
6376                ptr3 = vfp_reg_ptr(true, rm);
6377                switch (size) {
6378                case 0:
6379                    gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
6380                    break;
6381                case 1:
6382                    gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
6383                    break;
6384                case 2:
6385                    gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
6386                    break;
6387                }
6388            }
6389            tcg_temp_free_ptr(ptr1);
6390            tcg_temp_free_ptr(ptr2);
6391            tcg_temp_free_ptr(ptr3);
6392            return 0;
6393
6394        case NEON_3R_VPADD_VQRDMLAH:
6395            if (!u) {
6396                break;  /* VPADD */
6397            }
6398            /* VQRDMLAH */
6399            switch (size) {
6400            case 1:
6401                return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
6402                                     q, rd, rn, rm);
6403            case 2:
6404                return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
6405                                     q, rd, rn, rm);
6406            }
6407            return 1;
6408
6409        case NEON_3R_VFM_VQRDMLSH:
6410            if (!u) {
6411                /* VFM, VFMS */
6412                if (size == 1) {
6413                    return 1;
6414                }
6415                break;
6416            }
6417            /* VQRDMLSH */
6418            switch (size) {
6419            case 1:
6420                return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
6421                                     q, rd, rn, rm);
6422            case 2:
6423                return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
6424                                     q, rd, rn, rm);
6425            }
6426            return 1;
6427
6428        case NEON_3R_LOGIC: /* Logic ops.  */
6429            switch ((u << 2) | size) {
6430            case 0: /* VAND */
6431                tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
6432                                 vec_size, vec_size);
6433                break;
6434            case 1: /* VBIC */
6435                tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
6436                                  vec_size, vec_size);
6437                break;
6438            case 2: /* VORR */
6439                tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
6440                                vec_size, vec_size);
6441                break;
6442            case 3: /* VORN */
6443                tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
6444                                 vec_size, vec_size);
6445                break;
6446            case 4: /* VEOR */
6447                tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
6448                                 vec_size, vec_size);
6449                break;
6450            case 5: /* VBSL */
6451                tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6452                               vec_size, vec_size, &bsl_op);
6453                break;
6454            case 6: /* VBIT */
6455                tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6456                               vec_size, vec_size, &bit_op);
6457                break;
6458            case 7: /* VBIF */
6459                tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6460                               vec_size, vec_size, &bif_op);
6461                break;
6462            }
6463            return 0;
6464
6465        case NEON_3R_VADD_VSUB:
6466            if (u) {
6467                tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
6468                                 vec_size, vec_size);
6469            } else {
6470                tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
6471                                 vec_size, vec_size);
6472            }
6473            return 0;
6474
6475        case NEON_3R_VQADD:
6476            tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
6477                           rn_ofs, rm_ofs, vec_size, vec_size,
6478                           (u ? uqadd_op : sqadd_op) + size);
6479            break;
6480
6481        case NEON_3R_VQSUB:
6482            tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
6483                           rn_ofs, rm_ofs, vec_size, vec_size,
6484                           (u ? uqsub_op : sqsub_op) + size);
6485            break;
6486
6487        case NEON_3R_VMUL: /* VMUL */
6488            if (u) {
6489                /* Polynomial case allows only P8 and is handled below.  */
6490                if (size != 0) {
6491                    return 1;
6492                }
6493            } else {
6494                tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
6495                                 vec_size, vec_size);
6496                return 0;
6497            }
6498            break;
6499
6500        case NEON_3R_VML: /* VMLA, VMLS */
6501            tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
6502                           u ? &mls_op[size] : &mla_op[size]);
6503            return 0;
6504
6505        case NEON_3R_VTST_VCEQ:
6506            if (u) { /* VCEQ */
6507                tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
6508                                 vec_size, vec_size);
6509            } else { /* VTST */
6510                tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6511                               vec_size, vec_size, &cmtst_op[size]);
6512            }
6513            return 0;
6514
6515        case NEON_3R_VCGT:
6516            tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
6517                             rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
6518            return 0;
6519
6520        case NEON_3R_VCGE:
6521            tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
6522                             rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
6523            return 0;
6524
6525        case NEON_3R_VMAX:
6526            if (u) {
6527                tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
6528                                  vec_size, vec_size);
6529            } else {
6530                tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
6531                                  vec_size, vec_size);
6532            }
6533            return 0;
6534        case NEON_3R_VMIN:
6535            if (u) {
6536                tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
6537                                  vec_size, vec_size);
6538            } else {
6539                tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
6540                                  vec_size, vec_size);
6541            }
6542            return 0;
6543        }
6544
6545        if (size == 3) {
6546            /* 64-bit element instructions. */
6547            for (pass = 0; pass < (q ? 2 : 1); pass++) {
6548                neon_load_reg64(cpu_V0, rn + pass);
6549                neon_load_reg64(cpu_V1, rm + pass);
6550                switch (op) {
6551                case NEON_3R_VSHL:
6552                    if (u) {
6553                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
6554                    } else {
6555                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
6556                    }
6557                    break;
6558                case NEON_3R_VQSHL:
6559                    if (u) {
6560                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6561                                                 cpu_V1, cpu_V0);
6562                    } else {
6563                        gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6564                                                 cpu_V1, cpu_V0);
6565                    }
6566                    break;
6567                case NEON_3R_VRSHL:
6568                    if (u) {
6569                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
6570                    } else {
6571                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
6572                    }
6573                    break;
6574                case NEON_3R_VQRSHL:
6575                    if (u) {
6576                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
6577                                                  cpu_V1, cpu_V0);
6578                    } else {
6579                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
6580                                                  cpu_V1, cpu_V0);
6581                    }
6582                    break;
6583                default:
6584                    abort();
6585                }
6586                neon_store_reg64(cpu_V0, rd + pass);
6587            }
6588            return 0;
6589        }
6590        pairwise = 0;
6591        switch (op) {
6592        case NEON_3R_VSHL:
6593        case NEON_3R_VQSHL:
6594        case NEON_3R_VRSHL:
6595        case NEON_3R_VQRSHL:
6596            {
6597                int rtmp;
6598                /* Shift instruction operands are reversed.  */
6599                rtmp = rn;
6600                rn = rm;
6601                rm = rtmp;
6602            }
6603            break;
6604        case NEON_3R_VPADD_VQRDMLAH:
6605        case NEON_3R_VPMAX:
6606        case NEON_3R_VPMIN:
6607            pairwise = 1;
6608            break;
6609        case NEON_3R_FLOAT_ARITH:
6610            pairwise = (u && size < 2); /* if VPADD (float) */
6611            break;
6612        case NEON_3R_FLOAT_MINMAX:
6613            pairwise = u; /* if VPMIN/VPMAX (float) */
6614            break;
6615        case NEON_3R_FLOAT_CMP:
6616            if (!u && size) {
6617                /* no encoding for U=0 C=1x */
6618                return 1;
6619            }
6620            break;
6621        case NEON_3R_FLOAT_ACMP:
6622            if (!u) {
6623                return 1;
6624            }
6625            break;
6626        case NEON_3R_FLOAT_MISC:
6627            /* VMAXNM/VMINNM in ARMv8 */
6628            if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
6629                return 1;
6630            }
6631            break;
6632        case NEON_3R_VFM_VQRDMLSH:
6633            if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
6634                return 1;
6635            }
6636            break;
6637        default:
6638            break;
6639        }
6640
6641        if (pairwise && q) {
6642            /* All the pairwise insns UNDEF if Q is set */
6643            return 1;
6644        }
6645
6646        for (pass = 0; pass < (q ? 4 : 2); pass++) {
6647
6648        if (pairwise) {
6649            /* Pairwise.  */
6650            if (pass < 1) {
6651                tmp = neon_load_reg(rn, 0);
6652                tmp2 = neon_load_reg(rn, 1);
6653            } else {
6654                tmp = neon_load_reg(rm, 0);
6655                tmp2 = neon_load_reg(rm, 1);
6656            }
6657        } else {
6658            /* Elementwise.  */
6659            tmp = neon_load_reg(rn, pass);
6660            tmp2 = neon_load_reg(rm, pass);
6661        }
6662        switch (op) {
6663        case NEON_3R_VHADD:
6664            GEN_NEON_INTEGER_OP(hadd);
6665            break;
6666        case NEON_3R_VRHADD:
6667            GEN_NEON_INTEGER_OP(rhadd);
6668            break;
6669        case NEON_3R_VHSUB:
6670            GEN_NEON_INTEGER_OP(hsub);
6671            break;
6672        case NEON_3R_VSHL:
6673            GEN_NEON_INTEGER_OP(shl);
6674            break;
6675        case NEON_3R_VQSHL:
6676            GEN_NEON_INTEGER_OP_ENV(qshl);
6677            break;
6678        case NEON_3R_VRSHL:
6679            GEN_NEON_INTEGER_OP(rshl);
6680            break;
6681        case NEON_3R_VQRSHL:
6682            GEN_NEON_INTEGER_OP_ENV(qrshl);
6683            break;
6684        case NEON_3R_VABD:
6685            GEN_NEON_INTEGER_OP(abd);
6686            break;
6687        case NEON_3R_VABA:
6688            GEN_NEON_INTEGER_OP(abd);
6689            tcg_temp_free_i32(tmp2);
6690            tmp2 = neon_load_reg(rd, pass);
6691            gen_neon_add(size, tmp, tmp2);
6692            break;
6693        case NEON_3R_VMUL:
6694            /* VMUL.P8; other cases already eliminated.  */
6695            gen_helper_neon_mul_p8(tmp, tmp, tmp2);
6696            break;
6697        case NEON_3R_VPMAX:
6698            GEN_NEON_INTEGER_OP(pmax);
6699            break;
6700        case NEON_3R_VPMIN:
6701            GEN_NEON_INTEGER_OP(pmin);
6702            break;
6703        case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high.  */
6704            if (!u) { /* VQDMULH */
6705                switch (size) {
6706                case 1:
6707                    gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6708                    break;
6709                case 2:
6710                    gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6711                    break;
6712                default: abort();
6713                }
6714            } else { /* VQRDMULH */
6715                switch (size) {
6716                case 1:
6717                    gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6718                    break;
6719                case 2:
6720                    gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6721                    break;
6722                default: abort();
6723                }
6724            }
6725            break;
6726        case NEON_3R_VPADD_VQRDMLAH:
6727            switch (size) {
6728            case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6729            case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6730            case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6731            default: abort();
6732            }
6733            break;
6734        case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6735        {
6736            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6737            switch ((u << 2) | size) {
6738            case 0: /* VADD */
6739            case 4: /* VPADD */
6740                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6741                break;
6742            case 2: /* VSUB */
6743                gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6744                break;
6745            case 6: /* VABD */
6746                gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6747                break;
6748            default:
6749                abort();
6750            }
6751            tcg_temp_free_ptr(fpstatus);
6752            break;
6753        }
6754        case NEON_3R_FLOAT_MULTIPLY:
6755        {
6756            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6757            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6758            if (!u) {
6759                tcg_temp_free_i32(tmp2);
6760                tmp2 = neon_load_reg(rd, pass);
6761                if (size == 0) {
6762                    gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6763                } else {
6764                    gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6765                }
6766            }
6767            tcg_temp_free_ptr(fpstatus);
6768            break;
6769        }
6770        case NEON_3R_FLOAT_CMP:
6771        {
6772            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6773            if (!u) {
6774                gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6775            } else {
6776                if (size == 0) {
6777                    gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6778                } else {
6779                    gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6780                }
6781            }
6782            tcg_temp_free_ptr(fpstatus);
6783            break;
6784        }
6785        case NEON_3R_FLOAT_ACMP:
6786        {
6787            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6788            if (size == 0) {
6789                gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6790            } else {
6791                gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6792            }
6793            tcg_temp_free_ptr(fpstatus);
6794            break;
6795        }
6796        case NEON_3R_FLOAT_MINMAX:
6797        {
6798            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6799            if (size == 0) {
6800                gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6801            } else {
6802                gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6803            }
6804            tcg_temp_free_ptr(fpstatus);
6805            break;
6806        }
6807        case NEON_3R_FLOAT_MISC:
6808            if (u) {
6809                /* VMAXNM/VMINNM */
6810                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6811                if (size == 0) {
6812                    gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6813                } else {
6814                    gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6815                }
6816                tcg_temp_free_ptr(fpstatus);
6817            } else {
6818                if (size == 0) {
6819                    gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6820                } else {
6821                    gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6822              }
6823            }
6824            break;
6825        case NEON_3R_VFM_VQRDMLSH:
6826        {
6827            /* VFMA, VFMS: fused multiply-add */
6828            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6829            TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6830            if (size) {
6831                /* VFMS */
6832                gen_helper_vfp_negs(tmp, tmp);
6833            }
6834            gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6835            tcg_temp_free_i32(tmp3);
6836            tcg_temp_free_ptr(fpstatus);
6837            break;
6838        }
6839        default:
6840            abort();
6841        }
6842        tcg_temp_free_i32(tmp2);
6843
6844        /* Save the result.  For elementwise operations we can put it
6845           straight into the destination register.  For pairwise operations
6846           we have to be careful to avoid clobbering the source operands.  */
6847        if (pairwise && rd == rm) {
6848            neon_store_scratch(pass, tmp);
6849        } else {
6850            neon_store_reg(rd, pass, tmp);
6851        }
6852
6853        } /* for pass */
6854        if (pairwise && rd == rm) {
6855            for (pass = 0; pass < (q ? 4 : 2); pass++) {
6856                tmp = neon_load_scratch(pass);
6857                neon_store_reg(rd, pass, tmp);
6858            }
6859        }
6860        /* End of 3 register same size operations.  */
6861    } else if (insn & (1 << 4)) {
6862        if ((insn & 0x00380080) != 0) {
6863            /* Two registers and shift.  */
6864            op = (insn >> 8) & 0xf;
6865            if (insn & (1 << 7)) {
6866                /* 64-bit shift. */
6867                if (op > 7) {
6868                    return 1;
6869                }
6870                size = 3;
6871            } else {
6872                size = 2;
6873                while ((insn & (1 << (size + 19))) == 0)
6874                    size--;
6875            }
6876            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6877            if (op < 8) {
6878                /* Shift by immediate:
6879                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
6880                if (q && ((rd | rm) & 1)) {
6881                    return 1;
6882                }
6883                if (!u && (op == 4 || op == 6)) {
6884                    return 1;
6885                }
6886                /* Right shifts are encoded as N - shift, where N is the
6887                   element size in bits.  */
6888                if (op <= 4) {
6889                    shift = shift - (1 << (size + 3));
6890                }
6891
6892                switch (op) {
6893                case 0:  /* VSHR */
6894                    /* Right shift comes here negative.  */
6895                    shift = -shift;
6896                    /* Shifts larger than the element size are architecturally
6897                     * valid.  Unsigned results in all zeros; signed results
6898                     * in all sign bits.
6899                     */
6900                    if (!u) {
6901                        tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
6902                                          MIN(shift, (8 << size) - 1),
6903                                          vec_size, vec_size);
6904                    } else if (shift >= 8 << size) {
6905                        tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6906                    } else {
6907                        tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
6908                                          vec_size, vec_size);
6909                    }
6910                    return 0;
6911
6912                case 1:  /* VSRA */
6913                    /* Right shift comes here negative.  */
6914                    shift = -shift;
6915                    /* Shifts larger than the element size are architecturally
6916                     * valid.  Unsigned results in all zeros; signed results
6917                     * in all sign bits.
6918                     */
6919                    if (!u) {
6920                        tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6921                                        MIN(shift, (8 << size) - 1),
6922                                        &ssra_op[size]);
6923                    } else if (shift >= 8 << size) {
6924                        /* rd += 0 */
6925                    } else {
6926                        tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6927                                        shift, &usra_op[size]);
6928                    }
6929                    return 0;
6930
6931                case 4: /* VSRI */
6932                    if (!u) {
6933                        return 1;
6934                    }
6935                    /* Right shift comes here negative.  */
6936                    shift = -shift;
6937                    /* Shift out of range leaves destination unchanged.  */
6938                    if (shift < 8 << size) {
6939                        tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6940                                        shift, &sri_op[size]);
6941                    }
6942                    return 0;
6943
6944                case 5: /* VSHL, VSLI */
6945                    if (u) { /* VSLI */
6946                        /* Shift out of range leaves destination unchanged.  */
6947                        if (shift < 8 << size) {
6948                            tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
6949                                            vec_size, shift, &sli_op[size]);
6950                        }
6951                    } else { /* VSHL */
6952                        /* Shifts larger than the element size are
6953                         * architecturally valid and results in zero.
6954                         */
6955                        if (shift >= 8 << size) {
6956                            tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6957                        } else {
6958                            tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
6959                                              vec_size, vec_size);
6960                        }
6961                    }
6962                    return 0;
6963                }
6964
6965                if (size == 3) {
6966                    count = q + 1;
6967                } else {
6968                    count = q ? 4: 2;
6969                }
6970
6971                /* To avoid excessive duplication of ops we implement shift
6972                 * by immediate using the variable shift operations.
6973                  */
6974                imm = dup_const(size, shift);
6975
6976                for (pass = 0; pass < count; pass++) {
6977                    if (size == 3) {
6978                        neon_load_reg64(cpu_V0, rm + pass);
6979                        tcg_gen_movi_i64(cpu_V1, imm);
6980                        switch (op) {
6981                        case 2: /* VRSHR */
6982                        case 3: /* VRSRA */
6983                            if (u)
6984                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6985                            else
6986                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6987                            break;
6988                        case 6: /* VQSHLU */
6989                            gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6990                                                      cpu_V0, cpu_V1);
6991                            break;
6992                        case 7: /* VQSHL */
6993                            if (u) {
6994                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6995                                                         cpu_V0, cpu_V1);
6996                            } else {
6997                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6998                                                         cpu_V0, cpu_V1);
6999                            }
7000                            break;
7001                        default:
7002                            g_assert_not_reached();
7003                        }
7004                        if (op == 3) {
7005                            /* Accumulate.  */
7006                            neon_load_reg64(cpu_V1, rd + pass);
7007                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
7008                        }
7009                        neon_store_reg64(cpu_V0, rd + pass);
7010                    } else { /* size < 3 */
7011                        /* Operands in T0 and T1.  */
7012                        tmp = neon_load_reg(rm, pass);
7013                        tmp2 = tcg_temp_new_i32();
7014                        tcg_gen_movi_i32(tmp2, imm);
7015                        switch (op) {
7016                        case 2: /* VRSHR */
7017                        case 3: /* VRSRA */
7018                            GEN_NEON_INTEGER_OP(rshl);
7019                            break;
7020                        case 6: /* VQSHLU */
7021                            switch (size) {
7022                            case 0:
7023                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
7024                                                         tmp, tmp2);
7025                                break;
7026                            case 1:
7027                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
7028                                                          tmp, tmp2);
7029                                break;
7030                            case 2:
7031                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
7032                                                          tmp, tmp2);
7033                                break;
7034                            default:
7035                                abort();
7036                            }
7037                            break;
7038                        case 7: /* VQSHL */
7039                            GEN_NEON_INTEGER_OP_ENV(qshl);
7040                            break;
7041                        default:
7042                            g_assert_not_reached();
7043                        }
7044                        tcg_temp_free_i32(tmp2);
7045
7046                        if (op == 3) {
7047                            /* Accumulate.  */
7048                            tmp2 = neon_load_reg(rd, pass);
7049                            gen_neon_add(size, tmp, tmp2);
7050                            tcg_temp_free_i32(tmp2);
7051                        }
7052                        neon_store_reg(rd, pass, tmp);
7053                    }
7054                } /* for pass */
7055            } else if (op < 10) {
7056                /* Shift by immediate and narrow:
7057                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
7058                int input_unsigned = (op == 8) ? !u : u;
7059                if (rm & 1) {
7060                    return 1;
7061                }
7062                shift = shift - (1 << (size + 3));
7063                size++;
7064                if (size == 3) {
7065                    tmp64 = tcg_const_i64(shift);
7066                    neon_load_reg64(cpu_V0, rm);
7067                    neon_load_reg64(cpu_V1, rm + 1);
7068                    for (pass = 0; pass < 2; pass++) {
7069                        TCGv_i64 in;
7070                        if (pass == 0) {
7071                            in = cpu_V0;
7072                        } else {
7073                            in = cpu_V1;
7074                        }
7075                        if (q) {
7076                            if (input_unsigned) {
7077                                gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
7078                            } else {
7079                                gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
7080                            }
7081                        } else {
7082                            if (input_unsigned) {
7083                                gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
7084                            } else {
7085                                gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
7086                            }
7087                        }
7088                        tmp = tcg_temp_new_i32();
7089                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
7090                        neon_store_reg(rd, pass, tmp);
7091                    } /* for pass */
7092                    tcg_temp_free_i64(tmp64);
7093                } else {
7094                    if (size == 1) {
7095                        imm = (uint16_t)shift;
7096                        imm |= imm << 16;
7097                    } else {
7098                        /* size == 2 */
7099                        imm = (uint32_t)shift;
7100                    }
7101                    tmp2 = tcg_const_i32(imm);
7102                    tmp4 = neon_load_reg(rm + 1, 0);
7103                    tmp5 = neon_load_reg(rm + 1, 1);
7104                    for (pass = 0; pass < 2; pass++) {
7105                        if (pass == 0) {
7106                            tmp = neon_load_reg(rm, 0);
7107                        } else {
7108                            tmp = tmp4;
7109                        }
7110                        gen_neon_shift_narrow(size, tmp, tmp2, q,
7111                                              input_unsigned);
7112                        if (pass == 0) {
7113                            tmp3 = neon_load_reg(rm, 1);
7114                        } else {
7115                            tmp3 = tmp5;
7116                        }
7117                        gen_neon_shift_narrow(size, tmp3, tmp2, q,
7118                                              input_unsigned);
7119                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
7120                        tcg_temp_free_i32(tmp);
7121                        tcg_temp_free_i32(tmp3);
7122                        tmp = tcg_temp_new_i32();
7123                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
7124                        neon_store_reg(rd, pass, tmp);
7125                    } /* for pass */
7126                    tcg_temp_free_i32(tmp2);
7127                }
7128            } else if (op == 10) {
7129                /* VSHLL, VMOVL */
7130                if (q || (rd & 1)) {
7131                    return 1;
7132                }
7133                tmp = neon_load_reg(rm, 0);
7134                tmp2 = neon_load_reg(rm, 1);
7135                for (pass = 0; pass < 2; pass++) {
7136                    if (pass == 1)
7137                        tmp = tmp2;
7138
7139                    gen_neon_widen(cpu_V0, tmp, size, u);
7140
7141                    if (shift != 0) {
7142                        /* The shift is less than the width of the source
7143                           type, so we can just shift the whole register.  */
7144                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
7145                        /* Widen the result of shift: we need to clear
7146                         * the potential overflow bits resulting from
7147                         * left bits of the narrow input appearing as
7148                         * right bits of left the neighbour narrow
7149                         * input.  */
7150                        if (size < 2 || !u) {
7151                            uint64_t imm64;
7152                            if (size == 0) {
7153                                imm = (0xffu >> (8 - shift));
7154                                imm |= imm << 16;
7155                            } else if (size == 1) {
7156                                imm = 0xffff >> (16 - shift);
7157                            } else {
7158                                /* size == 2 */
7159                                imm = 0xffffffff >> (32 - shift);
7160                            }
7161                            if (size < 2) {
7162                                imm64 = imm | (((uint64_t)imm) << 32);
7163                            } else {
7164                                imm64 = imm;
7165                            }
7166                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
7167                        }
7168                    }
7169                    neon_store_reg64(cpu_V0, rd + pass);
7170                }
7171            } else if (op >= 14) {
7172                /* VCVT fixed-point.  */
7173                if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
7174                    return 1;
7175                }
7176                /* We have already masked out the must-be-1 top bit of imm6,
7177                 * hence this 32-shift where the ARM ARM has 64-imm6.
7178                 */
7179                shift = 32 - shift;
7180                for (pass = 0; pass < (q ? 4 : 2); pass++) {
7181                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
7182                    if (!(op & 1)) {
7183                        if (u)
7184                            gen_vfp_ulto(0, shift, 1);
7185                        else
7186                            gen_vfp_slto(0, shift, 1);
7187                    } else {
7188                        if (u)
7189                            gen_vfp_toul(0, shift, 1);
7190                        else
7191                            gen_vfp_tosl(0, shift, 1);
7192                    }
7193                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
7194                }
7195            } else {
7196                return 1;
7197            }
7198        } else { /* (insn & 0x00380080) == 0 */
7199            int invert, reg_ofs, vec_size;
7200
7201            if (q && (rd & 1)) {
7202                return 1;
7203            }
7204
7205            op = (insn >> 8) & 0xf;
7206            /* One register and immediate.  */
7207            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
7208            invert = (insn & (1 << 5)) != 0;
7209            /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
7210             * We choose to not special-case this and will behave as if a
7211             * valid constant encoding of 0 had been given.
7212             */
7213            switch (op) {
7214            case 0: case 1:
7215                /* no-op */
7216                break;
7217            case 2: case 3:
7218                imm <<= 8;
7219                break;
7220            case 4: case 5:
7221                imm <<= 16;
7222                break;
7223            case 6: case 7:
7224                imm <<= 24;
7225                break;
7226            case 8: case 9:
7227                imm |= imm << 16;
7228                break;
7229            case 10: case 11:
7230                imm = (imm << 8) | (imm << 24);
7231                break;
7232            case 12:
7233                imm = (imm << 8) | 0xff;
7234                break;
7235            case 13:
7236                imm = (imm << 16) | 0xffff;
7237                break;
7238            case 14:
7239                imm |= (imm << 8) | (imm << 16) | (imm << 24);
7240                if (invert) {
7241                    imm = ~imm;
7242                }
7243                break;
7244            case 15:
7245                if (invert) {
7246                    return 1;
7247                }
7248                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
7249                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
7250                break;
7251            }
7252            if (invert) {
7253                imm = ~imm;
7254            }
7255
7256            reg_ofs = neon_reg_offset(rd, 0);
7257            vec_size = q ? 16 : 8;
7258
7259            if (op & 1 && op < 12) {
7260                if (invert) {
7261                    /* The immediate value has already been inverted,
7262                     * so BIC becomes AND.
7263                     */
7264                    tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
7265                                      vec_size, vec_size);
7266                } else {
7267                    tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
7268                                     vec_size, vec_size);
7269                }
7270            } else {
7271                /* VMOV, VMVN.  */
7272                if (op == 14 && invert) {
7273                    TCGv_i64 t64 = tcg_temp_new_i64();
7274
7275                    for (pass = 0; pass <= q; ++pass) {
7276                        uint64_t val = 0;
7277                        int n;
7278
7279                        for (n = 0; n < 8; n++) {
7280                            if (imm & (1 << (n + pass * 8))) {
7281                                val |= 0xffull << (n * 8);
7282                            }
7283                        }
7284                        tcg_gen_movi_i64(t64, val);
7285                        neon_store_reg64(t64, rd + pass);
7286                    }
7287                    tcg_temp_free_i64(t64);
7288                } else {
7289                    tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
7290                }
7291            }
7292        }
7293    } else { /* (insn & 0x00800010 == 0x00800000) */
7294        if (size != 3) {
7295            op = (insn >> 8) & 0xf;
7296            if ((insn & (1 << 6)) == 0) {
7297                /* Three registers of different lengths.  */
7298                int src1_wide;
7299                int src2_wide;
7300                int prewiden;
7301                /* undefreq: bit 0 : UNDEF if size == 0
7302                 *           bit 1 : UNDEF if size == 1
7303                 *           bit 2 : UNDEF if size == 2
7304                 *           bit 3 : UNDEF if U == 1
7305                 * Note that [2:0] set implies 'always UNDEF'
7306                 */
7307                int undefreq;
7308                /* prewiden, src1_wide, src2_wide, undefreq */
7309                static const int neon_3reg_wide[16][4] = {
7310                    {1, 0, 0, 0}, /* VADDL */
7311                    {1, 1, 0, 0}, /* VADDW */
7312                    {1, 0, 0, 0}, /* VSUBL */
7313                    {1, 1, 0, 0}, /* VSUBW */
7314                    {0, 1, 1, 0}, /* VADDHN */
7315                    {0, 0, 0, 0}, /* VABAL */
7316                    {0, 1, 1, 0}, /* VSUBHN */
7317                    {0, 0, 0, 0}, /* VABDL */
7318                    {0, 0, 0, 0}, /* VMLAL */
7319                    {0, 0, 0, 9}, /* VQDMLAL */
7320                    {0, 0, 0, 0}, /* VMLSL */
7321                    {0, 0, 0, 9}, /* VQDMLSL */
7322                    {0, 0, 0, 0}, /* Integer VMULL */
7323                    {0, 0, 0, 1}, /* VQDMULL */
7324                    {0, 0, 0, 0xa}, /* Polynomial VMULL */
7325                    {0, 0, 0, 7}, /* Reserved: always UNDEF */
7326                };
7327
7328                prewiden = neon_3reg_wide[op][0];
7329                src1_wide = neon_3reg_wide[op][1];
7330                src2_wide = neon_3reg_wide[op][2];
7331                undefreq = neon_3reg_wide[op][3];
7332
7333                if ((undefreq & (1 << size)) ||
7334                    ((undefreq & 8) && u)) {
7335                    return 1;
7336                }
7337                if ((src1_wide && (rn & 1)) ||
7338                    (src2_wide && (rm & 1)) ||
7339                    (!src2_wide && (rd & 1))) {
7340                    return 1;
7341                }
7342
7343                /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
7344                 * outside the loop below as it only performs a single pass.
7345                 */
7346                if (op == 14 && size == 2) {
7347                    TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
7348
7349                    if (!dc_isar_feature(aa32_pmull, s)) {
7350                        return 1;
7351                    }
7352                    tcg_rn = tcg_temp_new_i64();
7353                    tcg_rm = tcg_temp_new_i64();
7354                    tcg_rd = tcg_temp_new_i64();
7355                    neon_load_reg64(tcg_rn, rn);
7356                    neon_load_reg64(tcg_rm, rm);
7357                    gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
7358                    neon_store_reg64(tcg_rd, rd);
7359                    gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
7360                    neon_store_reg64(tcg_rd, rd + 1);
7361                    tcg_temp_free_i64(tcg_rn);
7362                    tcg_temp_free_i64(tcg_rm);
7363                    tcg_temp_free_i64(tcg_rd);
7364                    return 0;
7365                }
7366
7367                /* Avoid overlapping operands.  Wide source operands are
7368                   always aligned so will never overlap with wide
7369                   destinations in problematic ways.  */
7370                if (rd == rm && !src2_wide) {
7371                    tmp = neon_load_reg(rm, 1);
7372                    neon_store_scratch(2, tmp);
7373                } else if (rd == rn && !src1_wide) {
7374                    tmp = neon_load_reg(rn, 1);
7375                    neon_store_scratch(2, tmp);
7376                }
7377                tmp3 = NULL;
7378                for (pass = 0; pass < 2; pass++) {
7379                    if (src1_wide) {
7380                        neon_load_reg64(cpu_V0, rn + pass);
7381                        tmp = NULL;
7382                    } else {
7383                        if (pass == 1 && rd == rn) {
7384                            tmp = neon_load_scratch(2);
7385                        } else {
7386                            tmp = neon_load_reg(rn, pass);
7387                        }
7388                        if (prewiden) {
7389                            gen_neon_widen(cpu_V0, tmp, size, u);
7390                        }
7391                    }
7392                    if (src2_wide) {
7393                        neon_load_reg64(cpu_V1, rm + pass);
7394                        tmp2 = NULL;
7395                    } else {
7396                        if (pass == 1 && rd == rm) {
7397                            tmp2 = neon_load_scratch(2);
7398                        } else {
7399                            tmp2 = neon_load_reg(rm, pass);
7400                        }
7401                        if (prewiden) {
7402                            gen_neon_widen(cpu_V1, tmp2, size, u);
7403                        }
7404                    }
7405                    switch (op) {
7406                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
7407                        gen_neon_addl(size);
7408                        break;
7409                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
7410                        gen_neon_subl(size);
7411                        break;
7412                    case 5: case 7: /* VABAL, VABDL */
7413                        switch ((size << 1) | u) {
7414                        case 0:
7415                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
7416                            break;
7417                        case 1:
7418                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
7419                            break;
7420                        case 2:
7421                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
7422                            break;
7423                        case 3:
7424                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
7425                            break;
7426                        case 4:
7427                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
7428                            break;
7429                        case 5:
7430                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
7431                            break;
7432                        default: abort();
7433                        }
7434                        tcg_temp_free_i32(tmp2);
7435                        tcg_temp_free_i32(tmp);
7436                        break;
7437                    case 8: case 9: case 10: case 11: case 12: case 13:
7438                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
7439                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7440                        break;
7441                    case 14: /* Polynomial VMULL */
7442                        gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
7443                        tcg_temp_free_i32(tmp2);
7444                        tcg_temp_free_i32(tmp);
7445                        break;
7446                    default: /* 15 is RESERVED: caught earlier  */
7447                        abort();
7448                    }
7449                    if (op == 13) {
7450                        /* VQDMULL */
7451                        gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7452                        neon_store_reg64(cpu_V0, rd + pass);
7453                    } else if (op == 5 || (op >= 8 && op <= 11)) {
7454                        /* Accumulate.  */
7455                        neon_load_reg64(cpu_V1, rd + pass);
7456                        switch (op) {
7457                        case 10: /* VMLSL */
7458                            gen_neon_negl(cpu_V0, size);
7459                            /* Fall through */
7460                        case 5: case 8: /* VABAL, VMLAL */
7461                            gen_neon_addl(size);
7462                            break;
7463                        case 9: case 11: /* VQDMLAL, VQDMLSL */
7464                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7465                            if (op == 11) {
7466                                gen_neon_negl(cpu_V0, size);
7467                            }
7468                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7469                            break;
7470                        default:
7471                            abort();
7472                        }
7473                        neon_store_reg64(cpu_V0, rd + pass);
7474                    } else if (op == 4 || op == 6) {
7475                        /* Narrowing operation.  */
7476                        tmp = tcg_temp_new_i32();
7477                        if (!u) {
7478                            switch (size) {
7479                            case 0:
7480                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
7481                                break;
7482                            case 1:
7483                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
7484                                break;
7485                            case 2:
7486                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
7487                                tcg_gen_extrl_i64_i32(tmp, cpu_V0);
7488                                break;
7489                            default: abort();
7490                            }
7491                        } else {
7492                            switch (size) {
7493                            case 0:
7494                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
7495                                break;
7496                            case 1:
7497                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
7498                                break;
7499                            case 2:
7500                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
7501                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
7502                                tcg_gen_extrl_i64_i32(tmp, cpu_V0);
7503                                break;
7504                            default: abort();
7505                            }
7506                        }
7507                        if (pass == 0) {
7508                            tmp3 = tmp;
7509                        } else {
7510                            neon_store_reg(rd, 0, tmp3);
7511                            neon_store_reg(rd, 1, tmp);
7512                        }
7513                    } else {
7514                        /* Write back the result.  */
7515                        neon_store_reg64(cpu_V0, rd + pass);
7516                    }
7517                }
7518            } else {
7519                /* Two registers and a scalar. NB that for ops of this form
7520                 * the ARM ARM labels bit 24 as Q, but it is in our variable
7521                 * 'u', not 'q'.
7522                 */
7523                if (size == 0) {
7524                    return 1;
7525                }
7526                switch (op) {
7527                case 1: /* Float VMLA scalar */
7528                case 5: /* Floating point VMLS scalar */
7529                case 9: /* Floating point VMUL scalar */
7530                    if (size == 1) {
7531                        return 1;
7532                    }
7533                    /* fall through */
7534                case 0: /* Integer VMLA scalar */
7535                case 4: /* Integer VMLS scalar */
7536                case 8: /* Integer VMUL scalar */
7537                case 12: /* VQDMULH scalar */
7538                case 13: /* VQRDMULH scalar */
7539                    if (u && ((rd | rn) & 1)) {
7540                        return 1;
7541                    }
7542                    tmp = neon_get_scalar(size, rm);
7543                    neon_store_scratch(0, tmp);
7544                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
7545                        tmp = neon_load_scratch(0);
7546                        tmp2 = neon_load_reg(rn, pass);
7547                        if (op == 12) {
7548                            if (size == 1) {
7549                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
7550                            } else {
7551                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
7552                            }
7553                        } else if (op == 13) {
7554                            if (size == 1) {
7555                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
7556                            } else {
7557                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
7558                            }
7559                        } else if (op & 1) {
7560                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7561                            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
7562                            tcg_temp_free_ptr(fpstatus);
7563                        } else {
7564                            switch (size) {
7565                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
7566                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
7567                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
7568                            default: abort();
7569                            }
7570                        }
7571                        tcg_temp_free_i32(tmp2);
7572                        if (op < 8) {
7573                            /* Accumulate.  */
7574                            tmp2 = neon_load_reg(rd, pass);
7575                            switch (op) {
7576                            case 0:
7577                                gen_neon_add(size, tmp, tmp2);
7578                                break;
7579                            case 1:
7580                            {
7581                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7582                                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
7583                                tcg_temp_free_ptr(fpstatus);
7584                                break;
7585                            }
7586                            case 4:
7587                                gen_neon_rsb(size, tmp, tmp2);
7588                                break;
7589                            case 5:
7590                            {
7591                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7592                                gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
7593                                tcg_temp_free_ptr(fpstatus);
7594                                break;
7595                            }
7596                            default:
7597                                abort();
7598                            }
7599                            tcg_temp_free_i32(tmp2);
7600                        }
7601                        neon_store_reg(rd, pass, tmp);
7602                    }
7603                    break;
7604                case 3: /* VQDMLAL scalar */
7605                case 7: /* VQDMLSL scalar */
7606                case 11: /* VQDMULL scalar */
7607                    if (u == 1) {
7608                        return 1;
7609                    }
7610                    /* fall through */
7611                case 2: /* VMLAL sclar */
7612                case 6: /* VMLSL scalar */
7613                case 10: /* VMULL scalar */
7614                    if (rd & 1) {
7615                        return 1;
7616                    }
7617                    tmp2 = neon_get_scalar(size, rm);
7618                    /* We need a copy of tmp2 because gen_neon_mull
7619                     * deletes it during pass 0.  */
7620                    tmp4 = tcg_temp_new_i32();
7621                    tcg_gen_mov_i32(tmp4, tmp2);
7622                    tmp3 = neon_load_reg(rn, 1);
7623
7624                    for (pass = 0; pass < 2; pass++) {
7625                        if (pass == 0) {
7626                            tmp = neon_load_reg(rn, 0);
7627                        } else {
7628                            tmp = tmp3;
7629                            tmp2 = tmp4;
7630                        }
7631                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7632                        if (op != 11) {
7633                            neon_load_reg64(cpu_V1, rd + pass);
7634                        }
7635                        switch (op) {
7636                        case 6:
7637                            gen_neon_negl(cpu_V0, size);
7638                            /* Fall through */
7639                        case 2:
7640                            gen_neon_addl(size);
7641                            break;
7642                        case 3: case 7:
7643                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7644                            if (op == 7) {
7645                                gen_neon_negl(cpu_V0, size);
7646                            }
7647                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7648                            break;
7649                        case 10:
7650                            /* no-op */
7651                            break;
7652                        case 11:
7653                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7654                            break;
7655                        default:
7656                            abort();
7657                        }
7658                        neon_store_reg64(cpu_V0, rd + pass);
7659                    }
7660                    break;
7661                case 14: /* VQRDMLAH scalar */
7662                case 15: /* VQRDMLSH scalar */
7663                    {
7664                        NeonGenThreeOpEnvFn *fn;
7665
7666                        if (!dc_isar_feature(aa32_rdm, s)) {
7667                            return 1;
7668                        }
7669                        if (u && ((rd | rn) & 1)) {
7670                            return 1;
7671                        }
7672                        if (op == 14) {
7673                            if (size == 1) {
7674                                fn = gen_helper_neon_qrdmlah_s16;
7675                            } else {
7676                                fn = gen_helper_neon_qrdmlah_s32;
7677                            }
7678                        } else {
7679                            if (size == 1) {
7680                                fn = gen_helper_neon_qrdmlsh_s16;
7681                            } else {
7682                                fn = gen_helper_neon_qrdmlsh_s32;
7683                            }
7684                        }
7685
7686                        tmp2 = neon_get_scalar(size, rm);
7687                        for (pass = 0; pass < (u ? 4 : 2); pass++) {
7688                            tmp = neon_load_reg(rn, pass);
7689                            tmp3 = neon_load_reg(rd, pass);
7690                            fn(tmp, cpu_env, tmp, tmp2, tmp3);
7691                            tcg_temp_free_i32(tmp3);
7692                            neon_store_reg(rd, pass, tmp);
7693                        }
7694                        tcg_temp_free_i32(tmp2);
7695                    }
7696                    break;
7697                default:
7698                    g_assert_not_reached();
7699                }
7700            }
7701        } else { /* size == 3 */
7702            if (!u) {
7703                /* Extract.  */
7704                imm = (insn >> 8) & 0xf;
7705
7706                if (imm > 7 && !q)
7707                    return 1;
7708
7709                if (q && ((rd | rn | rm) & 1)) {
7710                    return 1;
7711                }
7712
7713                if (imm == 0) {
7714                    neon_load_reg64(cpu_V0, rn);
7715                    if (q) {
7716                        neon_load_reg64(cpu_V1, rn + 1);
7717                    }
7718                } else if (imm == 8) {
7719                    neon_load_reg64(cpu_V0, rn + 1);
7720                    if (q) {
7721                        neon_load_reg64(cpu_V1, rm);
7722                    }
7723                } else if (q) {
7724                    tmp64 = tcg_temp_new_i64();
7725                    if (imm < 8) {
7726                        neon_load_reg64(cpu_V0, rn);
7727                        neon_load_reg64(tmp64, rn + 1);
7728                    } else {
7729                        neon_load_reg64(cpu_V0, rn + 1);
7730                        neon_load_reg64(tmp64, rm);
7731                    }
7732                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
7733                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
7734                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7735                    if (imm < 8) {
7736                        neon_load_reg64(cpu_V1, rm);
7737                    } else {
7738                        neon_load_reg64(cpu_V1, rm + 1);
7739                        imm -= 8;
7740                    }
7741                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7742                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
7743                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
7744                    tcg_temp_free_i64(tmp64);
7745                } else {
7746                    /* BUGFIX */
7747                    neon_load_reg64(cpu_V0, rn);
7748                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
7749                    neon_load_reg64(cpu_V1, rm);
7750                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7751                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7752                }
7753                neon_store_reg64(cpu_V0, rd);
7754                if (q) {
7755                    neon_store_reg64(cpu_V1, rd + 1);
7756                }
7757            } else if ((insn & (1 << 11)) == 0) {
7758                /* Two register misc.  */
7759                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7760                size = (insn >> 18) & 3;
7761                /* UNDEF for unknown op values and bad op-size combinations */
7762                if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7763                    return 1;
7764                }
7765                if (neon_2rm_is_v8_op(op) &&
7766                    !arm_dc_feature(s, ARM_FEATURE_V8)) {
7767                    return 1;
7768                }
7769                if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7770                    q && ((rm | rd) & 1)) {
7771                    return 1;
7772                }
7773                switch (op) {
7774                case NEON_2RM_VREV64:
7775                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
7776                        tmp = neon_load_reg(rm, pass * 2);
7777                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
7778                        switch (size) {
7779                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7780                        case 1: gen_swap_half(tmp); break;
7781                        case 2: /* no-op */ break;
7782                        default: abort();
7783                        }
7784                        neon_store_reg(rd, pass * 2 + 1, tmp);
7785                        if (size == 2) {
7786                            neon_store_reg(rd, pass * 2, tmp2);
7787                        } else {
7788                            switch (size) {
7789                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7790                            case 1: gen_swap_half(tmp2); break;
7791                            default: abort();
7792                            }
7793                            neon_store_reg(rd, pass * 2, tmp2);
7794                        }
7795                    }
7796                    break;
7797                case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7798                case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7799                    for (pass = 0; pass < q + 1; pass++) {
7800                        tmp = neon_load_reg(rm, pass * 2);
7801                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
7802                        tmp = neon_load_reg(rm, pass * 2 + 1);
7803                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
7804                        switch (size) {
7805                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7806                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7807                        case 2: tcg_gen_add_i64(CPU_V001); break;
7808                        default: abort();
7809                        }
7810                        if (op >= NEON_2RM_VPADAL) {
7811                            /* Accumulate.  */
7812                            neon_load_reg64(cpu_V1, rd + pass);
7813                            gen_neon_addl(size);
7814                        }
7815                        neon_store_reg64(cpu_V0, rd + pass);
7816                    }
7817                    break;
7818                case NEON_2RM_VTRN:
7819                    if (size == 2) {
7820                        int n;
7821                        for (n = 0; n < (q ? 4 : 2); n += 2) {
7822                            tmp = neon_load_reg(rm, n);
7823                            tmp2 = neon_load_reg(rd, n + 1);
7824                            neon_store_reg(rm, n, tmp2);
7825                            neon_store_reg(rd, n + 1, tmp);
7826                        }
7827                    } else {
7828                        goto elementwise;
7829                    }
7830                    break;
7831                case NEON_2RM_VUZP:
7832                    if (gen_neon_unzip(rd, rm, size, q)) {
7833                        return 1;
7834                    }
7835                    break;
7836                case NEON_2RM_VZIP:
7837                    if (gen_neon_zip(rd, rm, size, q)) {
7838                        return 1;
7839                    }
7840                    break;
7841                case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7842                    /* also VQMOVUN; op field and mnemonics don't line up */
7843                    if (rm & 1) {
7844                        return 1;
7845                    }
7846                    tmp2 = NULL;
7847                    for (pass = 0; pass < 2; pass++) {
7848                        neon_load_reg64(cpu_V0, rm + pass);
7849                        tmp = tcg_temp_new_i32();
7850                        gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7851                                           tmp, cpu_V0);
7852                        if (pass == 0) {
7853                            tmp2 = tmp;
7854                        } else {
7855                            neon_store_reg(rd, 0, tmp2);
7856                            neon_store_reg(rd, 1, tmp);
7857                        }
7858                    }
7859                    break;
7860                case NEON_2RM_VSHLL:
7861                    if (q || (rd & 1)) {
7862                        return 1;
7863                    }
7864                    tmp = neon_load_reg(rm, 0);
7865                    tmp2 = neon_load_reg(rm, 1);
7866                    for (pass = 0; pass < 2; pass++) {
7867                        if (pass == 1)
7868                            tmp = tmp2;
7869                        gen_neon_widen(cpu_V0, tmp, size, 1);
7870                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7871                        neon_store_reg64(cpu_V0, rd + pass);
7872                    }
7873                    break;
7874                case NEON_2RM_VCVT_F16_F32:
7875                {
7876                    TCGv_ptr fpst;
7877                    TCGv_i32 ahp;
7878
7879                    if (!dc_isar_feature(aa32_fp16_spconv, s) ||
7880                        q || (rm & 1)) {
7881                        return 1;
7882                    }
7883                    tmp = tcg_temp_new_i32();
7884                    tmp2 = tcg_temp_new_i32();
7885                    fpst = get_fpstatus_ptr(true);
7886                    ahp = get_ahp_flag();
7887                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7888                    gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7889                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7890                    gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7891                    tcg_gen_shli_i32(tmp2, tmp2, 16);
7892                    tcg_gen_or_i32(tmp2, tmp2, tmp);
7893                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7894                    gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7895                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7896                    neon_store_reg(rd, 0, tmp2);
7897                    tmp2 = tcg_temp_new_i32();
7898                    gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7899                    tcg_gen_shli_i32(tmp2, tmp2, 16);
7900                    tcg_gen_or_i32(tmp2, tmp2, tmp);
7901                    neon_store_reg(rd, 1, tmp2);
7902                    tcg_temp_free_i32(tmp);
7903                    tcg_temp_free_i32(ahp);
7904                    tcg_temp_free_ptr(fpst);
7905                    break;
7906                }
7907                case NEON_2RM_VCVT_F32_F16:
7908                {
7909                    TCGv_ptr fpst;
7910                    TCGv_i32 ahp;
7911                    if (!dc_isar_feature(aa32_fp16_spconv, s) ||
7912                        q || (rd & 1)) {
7913                        return 1;
7914                    }
7915                    fpst = get_fpstatus_ptr(true);
7916                    ahp = get_ahp_flag();
7917                    tmp3 = tcg_temp_new_i32();
7918                    tmp = neon_load_reg(rm, 0);
7919                    tmp2 = neon_load_reg(rm, 1);
7920                    tcg_gen_ext16u_i32(tmp3, tmp);
7921                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7922                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7923                    tcg_gen_shri_i32(tmp3, tmp, 16);
7924                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7925                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7926                    tcg_temp_free_i32(tmp);
7927                    tcg_gen_ext16u_i32(tmp3, tmp2);
7928                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7929                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7930                    tcg_gen_shri_i32(tmp3, tmp2, 16);
7931                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7932                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7933                    tcg_temp_free_i32(tmp2);
7934                    tcg_temp_free_i32(tmp3);
7935                    tcg_temp_free_i32(ahp);
7936                    tcg_temp_free_ptr(fpst);
7937                    break;
7938                }
7939                case NEON_2RM_AESE: case NEON_2RM_AESMC:
7940                    if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
7941                        return 1;
7942                    }
7943                    ptr1 = vfp_reg_ptr(true, rd);
7944                    ptr2 = vfp_reg_ptr(true, rm);
7945
7946                     /* Bit 6 is the lowest opcode bit; it distinguishes between
7947                      * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7948                      */
7949                    tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7950
7951                    if (op == NEON_2RM_AESE) {
7952                        gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7953                    } else {
7954                        gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7955                    }
7956                    tcg_temp_free_ptr(ptr1);
7957                    tcg_temp_free_ptr(ptr2);
7958                    tcg_temp_free_i32(tmp3);
7959                    break;
7960                case NEON_2RM_SHA1H:
7961                    if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
7962                        return 1;
7963                    }
7964                    ptr1 = vfp_reg_ptr(true, rd);
7965                    ptr2 = vfp_reg_ptr(true, rm);
7966
7967                    gen_helper_crypto_sha1h(ptr1, ptr2);
7968
7969                    tcg_temp_free_ptr(ptr1);
7970                    tcg_temp_free_ptr(ptr2);
7971                    break;
7972                case NEON_2RM_SHA1SU1:
7973                    if ((rm | rd) & 1) {
7974                            return 1;
7975                    }
7976                    /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7977                    if (q) {
7978                        if (!dc_isar_feature(aa32_sha2, s)) {
7979                            return 1;
7980                        }
7981                    } else if (!dc_isar_feature(aa32_sha1, s)) {
7982                        return 1;
7983                    }
7984                    ptr1 = vfp_reg_ptr(true, rd);
7985                    ptr2 = vfp_reg_ptr(true, rm);
7986                    if (q) {
7987                        gen_helper_crypto_sha256su0(ptr1, ptr2);
7988                    } else {
7989                        gen_helper_crypto_sha1su1(ptr1, ptr2);
7990                    }
7991                    tcg_temp_free_ptr(ptr1);
7992                    tcg_temp_free_ptr(ptr2);
7993                    break;
7994
7995                case NEON_2RM_VMVN:
7996                    tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
7997                    break;
7998                case NEON_2RM_VNEG:
7999                    tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
8000                    break;
8001
8002                default:
8003                elementwise:
8004                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
8005                        if (neon_2rm_is_float_op(op)) {
8006                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
8007                                           neon_reg_offset(rm, pass));
8008                            tmp = NULL;
8009                        } else {
8010                            tmp = neon_load_reg(rm, pass);
8011                        }
8012                        switch (op) {
8013                        case NEON_2RM_VREV32:
8014                            switch (size) {
8015                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8016                            case 1: gen_swap_half(tmp); break;
8017                            default: abort();
8018                            }
8019                            break;
8020                        case NEON_2RM_VREV16:
8021                            gen_rev16(tmp);
8022                            break;
8023                        case NEON_2RM_VCLS:
8024                            switch (size) {
8025                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
8026                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
8027                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
8028                            default: abort();
8029                            }
8030                            break;
8031                        case NEON_2RM_VCLZ:
8032                            switch (size) {
8033                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
8034                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
8035                            case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
8036                            default: abort();
8037                            }
8038                            break;
8039                        case NEON_2RM_VCNT:
8040                            gen_helper_neon_cnt_u8(tmp, tmp);
8041                            break;
8042                        case NEON_2RM_VQABS:
8043                            switch (size) {
8044                            case 0:
8045                                gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
8046                                break;
8047                            case 1:
8048                                gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
8049                                break;
8050                            case 2:
8051                                gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
8052                                break;
8053                            default: abort();
8054                            }
8055                            break;
8056                        case NEON_2RM_VQNEG:
8057                            switch (size) {
8058                            case 0:
8059                                gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
8060                                break;
8061                            case 1:
8062                                gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
8063                                break;
8064                            case 2:
8065                                gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
8066                                break;
8067                            default: abort();
8068                            }
8069                            break;
8070                        case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
8071                            tmp2 = tcg_const_i32(0);
8072                            switch(size) {
8073                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
8074                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
8075                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
8076                            default: abort();
8077                            }
8078                            tcg_temp_free_i32(tmp2);
8079                            if (op == NEON_2RM_VCLE0) {
8080                                tcg_gen_not_i32(tmp, tmp);
8081                            }
8082                            break;
8083                        case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
8084                            tmp2 = tcg_const_i32(0);
8085                            switch(size) {
8086                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
8087                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
8088                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
8089                            default: abort();
8090                            }
8091                            tcg_temp_free_i32(tmp2);
8092                            if (op == NEON_2RM_VCLT0) {
8093                                tcg_gen_not_i32(tmp, tmp);
8094                            }
8095                            break;
8096                        case NEON_2RM_VCEQ0:
8097                            tmp2 = tcg_const_i32(0);
8098                            switch(size) {
8099                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
8100                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
8101                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
8102                            default: abort();
8103                            }
8104                            tcg_temp_free_i32(tmp2);
8105                            break;
8106                        case NEON_2RM_VABS:
8107                            switch(size) {
8108                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
8109                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
8110                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
8111                            default: abort();
8112                            }
8113                            break;
8114                        case NEON_2RM_VCGT0_F:
8115                        {
8116                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8117                            tmp2 = tcg_const_i32(0);
8118                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
8119                            tcg_temp_free_i32(tmp2);
8120                            tcg_temp_free_ptr(fpstatus);
8121                            break;
8122                        }
8123                        case NEON_2RM_VCGE0_F:
8124                        {
8125                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8126                            tmp2 = tcg_const_i32(0);
8127                            gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
8128                            tcg_temp_free_i32(tmp2);
8129                            tcg_temp_free_ptr(fpstatus);
8130                            break;
8131                        }
8132                        case NEON_2RM_VCEQ0_F:
8133                        {
8134                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8135                            tmp2 = tcg_const_i32(0);
8136                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
8137                            tcg_temp_free_i32(tmp2);
8138                            tcg_temp_free_ptr(fpstatus);
8139                            break;
8140                        }
8141                        case NEON_2RM_VCLE0_F:
8142                        {
8143                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8144                            tmp2 = tcg_const_i32(0);
8145                            gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
8146                            tcg_temp_free_i32(tmp2);
8147                            tcg_temp_free_ptr(fpstatus);
8148                            break;
8149                        }
8150                        case NEON_2RM_VCLT0_F:
8151                        {
8152                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8153                            tmp2 = tcg_const_i32(0);
8154                            gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
8155                            tcg_temp_free_i32(tmp2);
8156                            tcg_temp_free_ptr(fpstatus);
8157                            break;
8158                        }
8159                        case NEON_2RM_VABS_F:
8160                            gen_vfp_abs(0);
8161                            break;
8162                        case NEON_2RM_VNEG_F:
8163                            gen_vfp_neg(0);
8164                            break;
8165                        case NEON_2RM_VSWP:
8166                            tmp2 = neon_load_reg(rd, pass);
8167                            neon_store_reg(rm, pass, tmp2);
8168                            break;
8169                        case NEON_2RM_VTRN:
8170                            tmp2 = neon_load_reg(rd, pass);
8171                            switch (size) {
8172                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
8173                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
8174                            default: abort();
8175                            }
8176                            neon_store_reg(rm, pass, tmp2);
8177                            break;
8178                        case NEON_2RM_VRINTN:
8179                        case NEON_2RM_VRINTA:
8180                        case NEON_2RM_VRINTM:
8181                        case NEON_2RM_VRINTP:
8182                        case NEON_2RM_VRINTZ:
8183                        {
8184                            TCGv_i32 tcg_rmode;
8185                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8186                            int rmode;
8187
8188                            if (op == NEON_2RM_VRINTZ) {
8189                                rmode = FPROUNDING_ZERO;
8190                            } else {
8191                                rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
8192                            }
8193
8194                            tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
8195                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8196                                                      cpu_env);
8197                            gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
8198                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8199                                                      cpu_env);
8200                            tcg_temp_free_ptr(fpstatus);
8201                            tcg_temp_free_i32(tcg_rmode);
8202                            break;
8203                        }
8204                        case NEON_2RM_VRINTX:
8205                        {
8206                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8207                            gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
8208                            tcg_temp_free_ptr(fpstatus);
8209                            break;
8210                        }
8211                        case NEON_2RM_VCVTAU:
8212                        case NEON_2RM_VCVTAS:
8213                        case NEON_2RM_VCVTNU:
8214                        case NEON_2RM_VCVTNS:
8215                        case NEON_2RM_VCVTPU:
8216                        case NEON_2RM_VCVTPS:
8217                        case NEON_2RM_VCVTMU:
8218                        case NEON_2RM_VCVTMS:
8219                        {
8220                            bool is_signed = !extract32(insn, 7, 1);
8221                            TCGv_ptr fpst = get_fpstatus_ptr(1);
8222                            TCGv_i32 tcg_rmode, tcg_shift;
8223                            int rmode = fp_decode_rm[extract32(insn, 8, 2)];
8224
8225                            tcg_shift = tcg_const_i32(0);
8226                            tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
8227                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8228                                                      cpu_env);
8229
8230                            if (is_signed) {
8231                                gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
8232                                                     tcg_shift, fpst);
8233                            } else {
8234                                gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
8235                                                     tcg_shift, fpst);
8236                            }
8237
8238                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8239                                                      cpu_env);
8240                            tcg_temp_free_i32(tcg_rmode);
8241                            tcg_temp_free_i32(tcg_shift);
8242                            tcg_temp_free_ptr(fpst);
8243                            break;
8244                        }
8245                        case NEON_2RM_VRECPE:
8246                        {
8247                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8248                            gen_helper_recpe_u32(tmp, tmp, fpstatus);
8249                            tcg_temp_free_ptr(fpstatus);
8250                            break;
8251                        }
8252                        case NEON_2RM_VRSQRTE:
8253                        {
8254                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8255                            gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
8256                            tcg_temp_free_ptr(fpstatus);
8257                            break;
8258                        }
8259                        case NEON_2RM_VRECPE_F:
8260                        {
8261                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8262                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
8263                            tcg_temp_free_ptr(fpstatus);
8264                            break;
8265                        }
8266                        case NEON_2RM_VRSQRTE_F:
8267                        {
8268                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8269                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
8270                            tcg_temp_free_ptr(fpstatus);
8271                            break;
8272                        }
8273                        case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
8274                            gen_vfp_sito(0, 1);
8275                            break;
8276                        case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
8277                            gen_vfp_uito(0, 1);
8278                            break;
8279                        case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
8280                            gen_vfp_tosiz(0, 1);
8281                            break;
8282                        case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
8283                            gen_vfp_touiz(0, 1);
8284                            break;
8285                        default:
8286                            /* Reserved op values were caught by the
8287                             * neon_2rm_sizes[] check earlier.
8288                             */
8289                            abort();
8290                        }
8291                        if (neon_2rm_is_float_op(op)) {
8292                            tcg_gen_st_f32(cpu_F0s, cpu_env,
8293                                           neon_reg_offset(rd, pass));
8294                        } else {
8295                            neon_store_reg(rd, pass, tmp);
8296                        }
8297                    }
8298                    break;
8299                }
8300            } else if ((insn & (1 << 10)) == 0) {
8301                /* VTBL, VTBX.  */
8302                int n = ((insn >> 8) & 3) + 1;
8303                if ((rn + n) > 32) {
8304                    /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
8305                     * helper function running off the end of the register file.
8306                     */
8307                    return 1;
8308                }
8309                n <<= 3;
8310                if (insn & (1 << 6)) {
8311                    tmp = neon_load_reg(rd, 0);
8312                } else {
8313                    tmp = tcg_temp_new_i32();
8314                    tcg_gen_movi_i32(tmp, 0);
8315                }
8316                tmp2 = neon_load_reg(rm, 0);
8317                ptr1 = vfp_reg_ptr(true, rn);
8318                tmp5 = tcg_const_i32(n);
8319                gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
8320                tcg_temp_free_i32(tmp);
8321                if (insn & (1 << 6)) {
8322                    tmp = neon_load_reg(rd, 1);
8323                } else {
8324                    tmp = tcg_temp_new_i32();
8325                    tcg_gen_movi_i32(tmp, 0);
8326                }
8327                tmp3 = neon_load_reg(rm, 1);
8328                gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
8329                tcg_temp_free_i32(tmp5);
8330                tcg_temp_free_ptr(ptr1);
8331                neon_store_reg(rd, 0, tmp2);
8332                neon_store_reg(rd, 1, tmp3);
8333                tcg_temp_free_i32(tmp);
8334            } else if ((insn & 0x380) == 0) {
8335                /* VDUP */
8336                int element;
8337                TCGMemOp size;
8338
8339                if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
8340                    return 1;
8341                }
8342                if (insn & (1 << 16)) {
8343                    size = MO_8;
8344                    element = (insn >> 17) & 7;
8345                } else if (insn & (1 << 17)) {
8346                    size = MO_16;
8347                    element = (insn >> 18) & 3;
8348                } else {
8349                    size = MO_32;
8350                    element = (insn >> 19) & 1;
8351                }
8352                tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
8353                                     neon_element_offset(rm, element, size),
8354                                     q ? 16 : 8, q ? 16 : 8);
8355            } else {
8356                return 1;
8357            }
8358        }
8359    }
8360    return 0;
8361}
8362
8363/* Advanced SIMD three registers of the same length extension.
8364 *  31           25    23  22    20   16   12  11   10   9    8        3     0
8365 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
8366 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
8367 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
8368 */
8369static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
8370{
8371    gen_helper_gvec_3 *fn_gvec = NULL;
8372    gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
8373    int rd, rn, rm, opr_sz;
8374    int data = 0;
8375    int off_rn, off_rm;
8376    bool is_long = false, q = extract32(insn, 6, 1);
8377    bool ptr_is_env = false;
8378
8379    if ((insn & 0xfe200f10) == 0xfc200800) {
8380        /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
8381        int size = extract32(insn, 20, 1);
8382        data = extract32(insn, 23, 2); /* rot */
8383        if (!dc_isar_feature(aa32_vcma, s)
8384            || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
8385            return 1;
8386        }
8387        fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
8388    } else if ((insn & 0xfea00f10) == 0xfc800800) {
8389        /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
8390        int size = extract32(insn, 20, 1);
8391        data = extract32(insn, 24, 1); /* rot */
8392        if (!dc_isar_feature(aa32_vcma, s)
8393            || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
8394            return 1;
8395        }
8396        fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
8397    } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
8398        /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
8399        bool u = extract32(insn, 4, 1);
8400        if (!dc_isar_feature(aa32_dp, s)) {
8401            return 1;
8402        }
8403        fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
8404    } else if ((insn & 0xff300f10) == 0xfc200810) {
8405        /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
8406        int is_s = extract32(insn, 23, 1);
8407        if (!dc_isar_feature(aa32_fhm, s)) {
8408            return 1;
8409        }
8410        is_long = true;
8411        data = is_s; /* is_2 == 0 */
8412        fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
8413        ptr_is_env = true;
8414    } else {
8415        return 1;
8416    }
8417
8418    VFP_DREG_D(rd, insn);
8419    if (rd & q) {
8420        return 1;
8421    }
8422    if (q || !is_long) {
8423        VFP_DREG_N(rn, insn);
8424        VFP_DREG_M(rm, insn);
8425        if ((rn | rm) & q & !is_long) {
8426            return 1;
8427        }
8428        off_rn = vfp_reg_offset(1, rn);
8429        off_rm = vfp_reg_offset(1, rm);
8430    } else {
8431        rn = VFP_SREG_N(insn);
8432        rm = VFP_SREG_M(insn);
8433        off_rn = vfp_reg_offset(0, rn);
8434        off_rm = vfp_reg_offset(0, rm);
8435    }
8436
8437    if (s->fp_excp_el) {
8438        gen_exception_insn(s, 4, EXCP_UDEF,
8439                           syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
8440        return 0;
8441    }
8442    if (!s->vfp_enabled) {
8443        return 1;
8444    }
8445
8446    opr_sz = (1 + q) * 8;
8447    if (fn_gvec_ptr) {
8448        TCGv_ptr ptr;
8449        if (ptr_is_env) {
8450            ptr = cpu_env;
8451        } else {
8452            ptr = get_fpstatus_ptr(1);
8453        }
8454        tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
8455                           opr_sz, opr_sz, data, fn_gvec_ptr);
8456        if (!ptr_is_env) {
8457            tcg_temp_free_ptr(ptr);
8458        }
8459    } else {
8460        tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
8461                           opr_sz, opr_sz, data, fn_gvec);
8462    }
8463    return 0;
8464}
8465
8466/* Advanced SIMD two registers and a scalar extension.
8467 *  31             24   23  22   20   16   12  11   10   9    8        3     0
8468 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
8469 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
8470 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
8471 *
8472 */
8473
8474static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
8475{
8476    gen_helper_gvec_3 *fn_gvec = NULL;
8477    gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
8478    int rd, rn, rm, opr_sz, data;
8479    int off_rn, off_rm;
8480    bool is_long = false, q = extract32(insn, 6, 1);
8481    bool ptr_is_env = false;
8482
8483    if ((insn & 0xff000f10) == 0xfe000800) {
8484        /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
8485        int rot = extract32(insn, 20, 2);
8486        int size = extract32(insn, 23, 1);
8487        int index;
8488
8489        if (!dc_isar_feature(aa32_vcma, s)) {
8490            return 1;
8491        }
8492        if (size == 0) {
8493            if (!dc_isar_feature(aa32_fp16_arith, s)) {
8494                return 1;
8495            }
8496            /* For fp16, rm is just Vm, and index is M.  */
8497            rm = extract32(insn, 0, 4);
8498            index = extract32(insn, 5, 1);
8499        } else {
8500            /* For fp32, rm is the usual M:Vm, and index is 0.  */
8501            VFP_DREG_M(rm, insn);
8502            index = 0;
8503        }
8504        data = (index << 2) | rot;
8505        fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
8506                       : gen_helper_gvec_fcmlah_idx);
8507    } else if ((insn & 0xffb00f00) == 0xfe200d00) {
8508        /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
8509        int u = extract32(insn, 4, 1);
8510
8511        if (!dc_isar_feature(aa32_dp, s)) {
8512            return 1;
8513        }
8514        fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
8515        /* rm is just Vm, and index is M.  */
8516        data = extract32(insn, 5, 1); /* index */
8517        rm = extract32(insn, 0, 4);
8518    } else if ((insn & 0xffa00f10) == 0xfe000810) {
8519        /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
8520        int is_s = extract32(insn, 20, 1);
8521        int vm20 = extract32(insn, 0, 3);
8522        int vm3 = extract32(insn, 3, 1);
8523        int m = extract32(insn, 5, 1);
8524        int index;
8525
8526        if (!dc_isar_feature(aa32_fhm, s)) {
8527            return 1;
8528        }
8529        if (q) {
8530            rm = vm20;
8531            index = m * 2 + vm3;
8532        } else {
8533            rm = vm20 * 2 + m;
8534            index = vm3;
8535        }
8536        is_long = true;
8537        data = (index << 2) | is_s; /* is_2 == 0 */
8538        fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
8539        ptr_is_env = true;
8540    } else {
8541        return 1;
8542    }
8543
8544    VFP_DREG_D(rd, insn);
8545    if (rd & q) {
8546        return 1;
8547    }
8548    if (q || !is_long) {
8549        VFP_DREG_N(rn, insn);
8550        if (rn & q & !is_long) {
8551            return 1;
8552        }
8553        off_rn = vfp_reg_offset(1, rn);
8554        off_rm = vfp_reg_offset(1, rm);
8555    } else {
8556        rn = VFP_SREG_N(insn);
8557        off_rn = vfp_reg_offset(0, rn);
8558        off_rm = vfp_reg_offset(0, rm);
8559    }
8560    if (s->fp_excp_el) {
8561        gen_exception_insn(s, 4, EXCP_UDEF,
8562                           syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
8563        return 0;
8564    }
8565    if (!s->vfp_enabled) {
8566        return 1;
8567    }
8568
8569    opr_sz = (1 + q) * 8;
8570    if (fn_gvec_ptr) {
8571        TCGv_ptr ptr;
8572        if (ptr_is_env) {
8573            ptr = cpu_env;
8574        } else {
8575            ptr = get_fpstatus_ptr(1);
8576        }
8577        tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
8578                           opr_sz, opr_sz, data, fn_gvec_ptr);
8579        if (!ptr_is_env) {
8580            tcg_temp_free_ptr(ptr);
8581        }
8582    } else {
8583        tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
8584                           opr_sz, opr_sz, data, fn_gvec);
8585    }
8586    return 0;
8587}
8588
8589static int disas_coproc_insn(DisasContext *s, uint32_t insn)
8590{
8591    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
8592    const ARMCPRegInfo *ri;
8593
8594    cpnum = (insn >> 8) & 0xf;
8595
8596    /* First check for coprocessor space used for XScale/iwMMXt insns */
8597    if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
8598        if (extract32(s->c15_cpar, cpnum, 1) == 0) {
8599            return 1;
8600        }
8601        if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8602            return disas_iwmmxt_insn(s, insn);
8603        } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
8604            return disas_dsp_insn(s, insn);
8605        }
8606        return 1;
8607    }
8608
8609    /* Otherwise treat as a generic register access */
8610    is64 = (insn & (1 << 25)) == 0;
8611    if (!is64 && ((insn & (1 << 4)) == 0)) {
8612        /* cdp */
8613        return 1;
8614    }
8615
8616    crm = insn & 0xf;
8617    if (is64) {
8618        crn = 0;
8619        opc1 = (insn >> 4) & 0xf;
8620        opc2 = 0;
8621        rt2 = (insn >> 16) & 0xf;
8622    } else {
8623        crn = (insn >> 16) & 0xf;
8624        opc1 = (insn >> 21) & 7;
8625        opc2 = (insn >> 5) & 7;
8626        rt2 = 0;
8627    }
8628    isread = (insn >> 20) & 1;
8629    rt = (insn >> 12) & 0xf;
8630
8631    ri = get_arm_cp_reginfo(s->cp_regs,
8632            ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
8633    if (ri) {
8634        /* Check access permissions */
8635        if (!cp_access_ok(s->current_el, ri, isread)) {
8636            return 1;
8637        }
8638
8639        if (ri->accessfn ||
8640            (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
8641            /* Emit code to perform further access permissions checks at
8642             * runtime; this may result in an exception.
8643             * Note that on XScale all cp0..c13 registers do an access check
8644             * call in order to handle c15_cpar.
8645             */
8646            TCGv_ptr tmpptr;
8647            TCGv_i32 tcg_syn, tcg_isread;
8648            uint32_t syndrome;
8649
8650            /* Note that since we are an implementation which takes an
8651             * exception on a trapped conditional instruction only if the
8652             * instruction passes its condition code check, we can take
8653             * advantage of the clause in the ARM ARM that allows us to set
8654             * the COND field in the instruction to 0xE in all cases.
8655             * We could fish the actual condition out of the insn (ARM)
8656             * or the condexec bits (Thumb) but it isn't necessary.
8657             */
8658            switch (cpnum) {
8659            case 14:
8660                if (is64) {
8661                    syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8662                                                 isread, false);
8663                } else {
8664                    syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8665                                                rt, isread, false);
8666                }
8667                break;
8668            case 15:
8669                if (is64) {
8670                    syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8671                                                 isread, false);
8672                } else {
8673                    syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8674                                                rt, isread, false);
8675                }
8676                break;
8677            default:
8678                /* ARMv8 defines that only coprocessors 14 and 15 exist,
8679                 * so this can only happen if this is an ARMv7 or earlier CPU,
8680                 * in which case the syndrome information won't actually be
8681                 * guest visible.
8682                 */
8683                assert(!arm_dc_feature(s, ARM_FEATURE_V8));
8684                syndrome = syn_uncategorized();
8685                break;
8686            }
8687
8688            gen_set_condexec(s);
8689            gen_set_pc_im(s, s->pc - 4);
8690            tmpptr = tcg_const_ptr(ri);
8691            tcg_syn = tcg_const_i32(syndrome);
8692            tcg_isread = tcg_const_i32(isread);
8693            gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
8694                                           tcg_isread);
8695            tcg_temp_free_ptr(tmpptr);
8696            tcg_temp_free_i32(tcg_syn);
8697            tcg_temp_free_i32(tcg_isread);
8698        }
8699
8700        /* Handle special cases first */
8701        switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
8702        case ARM_CP_NOP:
8703            return 0;
8704        case ARM_CP_WFI:
8705            if (isread) {
8706                return 1;
8707            }
8708            gen_set_pc_im(s, s->pc);
8709            s->base.is_jmp = DISAS_WFI;
8710            return 0;
8711        default:
8712            break;
8713        }
8714
8715        if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8716            gen_io_start();
8717        }
8718
8719        if (isread) {
8720            /* Read */
8721            if (is64) {
8722                TCGv_i64 tmp64;
8723                TCGv_i32 tmp;
8724                if (ri->type & ARM_CP_CONST) {
8725                    tmp64 = tcg_const_i64(ri->resetvalue);
8726                } else if (ri->readfn) {
8727                    TCGv_ptr tmpptr;
8728                    tmp64 = tcg_temp_new_i64();
8729                    tmpptr = tcg_const_ptr(ri);
8730                    gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
8731                    tcg_temp_free_ptr(tmpptr);
8732                } else {
8733                    tmp64 = tcg_temp_new_i64();
8734                    tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
8735                }
8736                tmp = tcg_temp_new_i32();
8737                tcg_gen_extrl_i64_i32(tmp, tmp64);
8738                store_reg(s, rt, tmp);
8739                tcg_gen_shri_i64(tmp64, tmp64, 32);
8740                tmp = tcg_temp_new_i32();
8741                tcg_gen_extrl_i64_i32(tmp, tmp64);
8742                tcg_temp_free_i64(tmp64);
8743                store_reg(s, rt2, tmp);
8744            } else {
8745                TCGv_i32 tmp;
8746                if (ri->type & ARM_CP_CONST) {
8747                    tmp = tcg_const_i32(ri->resetvalue);
8748                } else if (ri->readfn) {
8749                    TCGv_ptr tmpptr;
8750                    tmp = tcg_temp_new_i32();
8751                    tmpptr = tcg_const_ptr(ri);
8752                    gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
8753                    tcg_temp_free_ptr(tmpptr);
8754                } else {
8755                    tmp = load_cpu_offset(ri->fieldoffset);
8756                }
8757                if (rt == 15) {
8758                    /* Destination register of r15 for 32 bit loads sets
8759                     * the condition codes from the high 4 bits of the value
8760                     */
8761                    gen_set_nzcv(tmp);
8762                    tcg_temp_free_i32(tmp);
8763                } else {
8764                    store_reg(s, rt, tmp);
8765                }
8766            }
8767        } else {
8768            /* Write */
8769            if (ri->type & ARM_CP_CONST) {
8770                /* If not forbidden by access permissions, treat as WI */
8771                return 0;
8772            }
8773
8774            if (is64) {
8775                TCGv_i32 tmplo, tmphi;
8776                TCGv_i64 tmp64 = tcg_temp_new_i64();
8777                tmplo = load_reg(s, rt);
8778                tmphi = load_reg(s, rt2);
8779                tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
8780                tcg_temp_free_i32(tmplo);
8781                tcg_temp_free_i32(tmphi);
8782                if (ri->writefn) {
8783                    TCGv_ptr tmpptr = tcg_const_ptr(ri);
8784                    gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
8785                    tcg_temp_free_ptr(tmpptr);
8786                } else {
8787                    tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
8788                }
8789                tcg_temp_free_i64(tmp64);
8790            } else {
8791                if (ri->writefn) {
8792                    TCGv_i32 tmp;
8793                    TCGv_ptr tmpptr;
8794                    tmp = load_reg(s, rt);
8795                    tmpptr = tcg_const_ptr(ri);
8796                    gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
8797                    tcg_temp_free_ptr(tmpptr);
8798                    tcg_temp_free_i32(tmp);
8799                } else {
8800                    TCGv_i32 tmp = load_reg(s, rt);
8801                    store_cpu_offset(tmp, ri->fieldoffset);
8802                }
8803            }
8804        }
8805
8806        if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8807            /* I/O operations must end the TB here (whether read or write) */
8808            gen_io_end();
8809            gen_lookup_tb(s);
8810        } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
8811            /* We default to ending the TB on a coprocessor register write,
8812             * but allow this to be suppressed by the register definition
8813             * (usually only necessary to work around guest bugs).
8814             */
8815            gen_lookup_tb(s);
8816        }
8817
8818        return 0;
8819    }
8820
8821    /* Unknown register; this might be a guest error or a QEMU
8822     * unimplemented feature.
8823     */
8824    if (is64) {
8825        qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8826                      "64 bit system register cp:%d opc1: %d crm:%d "
8827                      "(%s)\n",
8828                      isread ? "read" : "write", cpnum, opc1, crm,
8829                      s->ns ? "non-secure" : "secure");
8830    } else {
8831        qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8832                      "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8833                      "(%s)\n",
8834                      isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8835                      s->ns ? "non-secure" : "secure");
8836    }
8837
8838    return 1;
8839}
8840
8841
8842/* Store a 64-bit value to a register pair.  Clobbers val.  */
8843static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8844{
8845    TCGv_i32 tmp;
8846    tmp = tcg_temp_new_i32();
8847    tcg_gen_extrl_i64_i32(tmp, val);
8848    store_reg(s, rlow, tmp);
8849    tmp = tcg_temp_new_i32();
8850    tcg_gen_shri_i64(val, val, 32);
8851    tcg_gen_extrl_i64_i32(tmp, val);
8852    store_reg(s, rhigh, tmp);
8853}
8854
8855/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
8856static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8857{
8858    TCGv_i64 tmp;
8859    TCGv_i32 tmp2;
8860
8861    /* Load value and extend to 64 bits.  */
8862    tmp = tcg_temp_new_i64();
8863    tmp2 = load_reg(s, rlow);
8864    tcg_gen_extu_i32_i64(tmp, tmp2);
8865    tcg_temp_free_i32(tmp2);
8866    tcg_gen_add_i64(val, val, tmp);
8867    tcg_temp_free_i64(tmp);
8868}
8869
8870/* load and add a 64-bit value from a register pair.  */
8871static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8872{
8873    TCGv_i64 tmp;
8874    TCGv_i32 tmpl;
8875    TCGv_i32 tmph;
8876
8877    /* Load 64-bit value rd:rn.  */
8878    tmpl = load_reg(s, rlow);
8879    tmph = load_reg(s, rhigh);
8880    tmp = tcg_temp_new_i64();
8881    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8882    tcg_temp_free_i32(tmpl);
8883    tcg_temp_free_i32(tmph);
8884    tcg_gen_add_i64(val, val, tmp);
8885    tcg_temp_free_i64(tmp);
8886}
8887
8888/* Set N and Z flags from hi|lo.  */
8889static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8890{
8891    tcg_gen_mov_i32(cpu_NF, hi);
8892    tcg_gen_or_i32(cpu_ZF, lo, hi);
8893}
8894
8895/* Load/Store exclusive instructions are implemented by remembering
8896   the value/address loaded, and seeing if these are the same
8897   when the store is performed.  This should be sufficient to implement
8898   the architecturally mandated semantics, and avoids having to monitor
8899   regular stores.  The compare vs the remembered value is done during
8900   the cmpxchg operation, but we must compare the addresses manually.  */
8901static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8902                               TCGv_i32 addr, int size)
8903{
8904    TCGv_i32 tmp = tcg_temp_new_i32();
8905    TCGMemOp opc = size | MO_ALIGN | s->be_data;
8906
8907    s->is_ldex = true;
8908
8909    if (size == 3) {
8910        TCGv_i32 tmp2 = tcg_temp_new_i32();
8911        TCGv_i64 t64 = tcg_temp_new_i64();
8912
8913        /* For AArch32, architecturally the 32-bit word at the lowest
8914         * address is always Rt and the one at addr+4 is Rt2, even if
8915         * the CPU is big-endian. That means we don't want to do a
8916         * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8917         * for an architecturally 64-bit access, but instead do a
8918         * 64-bit access using MO_BE if appropriate and then split
8919         * the two halves.
8920         * This only makes a difference for BE32 user-mode, where
8921         * frob64() must not flip the two halves of the 64-bit data
8922         * but this code must treat BE32 user-mode like BE32 system.
8923         */
8924        TCGv taddr = gen_aa32_addr(s, addr, opc);
8925
8926        tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8927        tcg_temp_free(taddr);
8928        tcg_gen_mov_i64(cpu_exclusive_val, t64);
8929        if (s->be_data == MO_BE) {
8930            tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8931        } else {
8932            tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8933        }
8934        tcg_temp_free_i64(t64);
8935
8936        store_reg(s, rt2, tmp2);
8937    } else {
8938        gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8939        tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8940    }
8941
8942    store_reg(s, rt, tmp);
8943    tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8944}
8945
8946static void gen_clrex(DisasContext *s)
8947{
8948    tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8949}
8950
8951static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8952                                TCGv_i32 addr, int size)
8953{
8954    TCGv_i32 t0, t1, t2;
8955    TCGv_i64 extaddr;
8956    TCGv taddr;
8957    TCGLabel *done_label;
8958    TCGLabel *fail_label;
8959    TCGMemOp opc = size | MO_ALIGN | s->be_data;
8960
8961    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8962         [addr] = {Rt};
8963         {Rd} = 0;
8964       } else {
8965         {Rd} = 1;
8966       } */
8967    fail_label = gen_new_label();
8968    done_label = gen_new_label();
8969    extaddr = tcg_temp_new_i64();
8970    tcg_gen_extu_i32_i64(extaddr, addr);
8971    tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8972    tcg_temp_free_i64(extaddr);
8973
8974    taddr = gen_aa32_addr(s, addr, opc);
8975    t0 = tcg_temp_new_i32();
8976    t1 = load_reg(s, rt);
8977    if (size == 3) {
8978        TCGv_i64 o64 = tcg_temp_new_i64();
8979        TCGv_i64 n64 = tcg_temp_new_i64();
8980
8981        t2 = load_reg(s, rt2);
8982        /* For AArch32, architecturally the 32-bit word at the lowest
8983         * address is always Rt and the one at addr+4 is Rt2, even if
8984         * the CPU is big-endian. Since we're going to treat this as a
8985         * single 64-bit BE store, we need to put the two halves in the
8986         * opposite order for BE to LE, so that they end up in the right
8987         * places.
8988         * We don't want gen_aa32_frob64() because that does the wrong
8989         * thing for BE32 usermode.
8990         */
8991        if (s->be_data == MO_BE) {
8992            tcg_gen_concat_i32_i64(n64, t2, t1);
8993        } else {
8994            tcg_gen_concat_i32_i64(n64, t1, t2);
8995        }
8996        tcg_temp_free_i32(t2);
8997
8998        tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8999                                   get_mem_index(s), opc);
9000        tcg_temp_free_i64(n64);
9001
9002        tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
9003        tcg_gen_extrl_i64_i32(t0, o64);
9004
9005        tcg_temp_free_i64(o64);
9006    } else {
9007        t2 = tcg_temp_new_i32();
9008        tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
9009        tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
9010        tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
9011        tcg_temp_free_i32(t2);
9012    }
9013    tcg_temp_free_i32(t1);
9014    tcg_temp_free(taddr);
9015    tcg_gen_mov_i32(cpu_R[rd], t0);
9016    tcg_temp_free_i32(t0);
9017    tcg_gen_br(done_label);
9018
9019    gen_set_label(fail_label);
9020    tcg_gen_movi_i32(cpu_R[rd], 1);
9021    gen_set_label(done_label);
9022    tcg_gen_movi_i64(cpu_exclusive_addr, -1);
9023}
9024
9025/* gen_srs:
9026 * @env: CPUARMState
9027 * @s: DisasContext
9028 * @mode: mode field from insn (which stack to store to)
9029 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
9030 * @writeback: true if writeback bit set
9031 *
9032 * Generate code for the SRS (Store Return State) insn.
9033 */
9034static void gen_srs(DisasContext *s,
9035                    uint32_t mode, uint32_t amode, bool writeback)
9036{
9037    int32_t offset;
9038    TCGv_i32 addr, tmp;
9039    bool undef = false;
9040
9041    /* SRS is:
9042     * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
9043     *   and specified mode is monitor mode
9044     * - UNDEFINED in Hyp mode
9045     * - UNPREDICTABLE in User or System mode
9046     * - UNPREDICTABLE if the specified mode is:
9047     * -- not implemented
9048     * -- not a valid mode number
9049     * -- a mode that's at a higher exception level
9050     * -- Monitor, if we are Non-secure
9051     * For the UNPREDICTABLE cases we choose to UNDEF.
9052     */
9053    if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
9054        gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
9055        return;
9056    }
9057
9058    if (s->current_el == 0 || s->current_el == 2) {
9059        undef = true;
9060    }
9061
9062    switch (mode) {
9063    case ARM_CPU_MODE_USR:
9064    case ARM_CPU_MODE_FIQ:
9065    case ARM_CPU_MODE_IRQ:
9066    case ARM_CPU_MODE_SVC:
9067    case ARM_CPU_MODE_ABT:
9068    case ARM_CPU_MODE_UND:
9069    case ARM_CPU_MODE_SYS:
9070        break;
9071    case ARM_CPU_MODE_HYP:
9072        if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
9073            undef = true;
9074        }
9075        break;
9076    case ARM_CPU_MODE_MON:
9077        /* No need to check specifically for "are we non-secure" because
9078         * we've already made EL0 UNDEF and handled the trap for S-EL1;
9079         * so if this isn't EL3 then we must be non-secure.
9080         */
9081        if (s->current_el != 3) {
9082            undef = true;
9083        }
9084        break;
9085    default:
9086        undef = true;
9087    }
9088
9089    if (undef) {
9090        gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9091                           default_exception_el(s));
9092        return;
9093    }
9094
9095    addr = tcg_temp_new_i32();
9096    tmp = tcg_const_i32(mode);
9097    /* get_r13_banked() will raise an exception if called from System mode */
9098    gen_set_condexec(s);
9099    gen_set_pc_im(s, s->pc - 4);
9100    gen_helper_get_r13_banked(addr, cpu_env, tmp);
9101    tcg_temp_free_i32(tmp);
9102    switch (amode) {
9103    case 0: /* DA */
9104        offset = -4;
9105        break;
9106    case 1: /* IA */
9107        offset = 0;
9108        break;
9109    case 2: /* DB */
9110        offset = -8;
9111        break;
9112    case 3: /* IB */
9113        offset = 4;
9114        break;
9115    default:
9116        abort();
9117    }
9118    tcg_gen_addi_i32(addr, addr, offset);
9119    tmp = load_reg(s, 14);
9120    gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9121    tcg_temp_free_i32(tmp);
9122    tmp = load_cpu_field(spsr);
9123    tcg_gen_addi_i32(addr, addr, 4);
9124    gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9125    tcg_temp_free_i32(tmp);
9126    if (writeback) {
9127        switch (amode) {
9128        case 0:
9129            offset = -8;
9130            break;
9131        case 1:
9132            offset = 4;
9133            break;
9134        case 2:
9135            offset = -4;
9136            break;
9137        case 3:
9138            offset = 0;
9139            break;
9140        default:
9141            abort();
9142        }
9143        tcg_gen_addi_i32(addr, addr, offset);
9144        tmp = tcg_const_i32(mode);
9145        gen_helper_set_r13_banked(cpu_env, tmp, addr);
9146        tcg_temp_free_i32(tmp);
9147    }
9148    tcg_temp_free_i32(addr);
9149    s->base.is_jmp = DISAS_UPDATE;
9150}
9151
9152/* Generate a label used for skipping this instruction */
9153static void arm_gen_condlabel(DisasContext *s)
9154{
9155    if (!s->condjmp) {
9156        s->condlabel = gen_new_label();
9157        s->condjmp = 1;
9158    }
9159}
9160
9161/* Skip this instruction if the ARM condition is false */
9162static void arm_skip_unless(DisasContext *s, uint32_t cond)
9163{
9164    arm_gen_condlabel(s);
9165    arm_gen_test_cc(cond ^ 1, s->condlabel);
9166}
9167
9168static void disas_arm_insn(DisasContext *s, unsigned int insn)
9169{
9170    unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
9171    TCGv_i32 tmp;
9172    TCGv_i32 tmp2;
9173    TCGv_i32 tmp3;
9174    TCGv_i32 addr;
9175    TCGv_i64 tmp64;
9176
9177    /* M variants do not implement ARM mode; this must raise the INVSTATE
9178     * UsageFault exception.
9179     */
9180    if (arm_dc_feature(s, ARM_FEATURE_M)) {
9181        gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
9182                           default_exception_el(s));
9183        return;
9184    }
9185    cond = insn >> 28;
9186    if (cond == 0xf){
9187        /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
9188         * choose to UNDEF. In ARMv5 and above the space is used
9189         * for miscellaneous unconditional instructions.
9190         */
9191        ARCH(5);
9192
9193        /* Unconditional instructions.  */
9194        if (((insn >> 25) & 7) == 1) {
9195            /* NEON Data processing.  */
9196            if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
9197                goto illegal_op;
9198            }
9199
9200            if (disas_neon_data_insn(s, insn)) {
9201                goto illegal_op;
9202            }
9203            return;
9204        }
9205        if ((insn & 0x0f100000) == 0x04000000) {
9206            /* NEON load/store.  */
9207            if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
9208                goto illegal_op;
9209            }
9210
9211            if (disas_neon_ls_insn(s, insn)) {
9212                goto illegal_op;
9213            }
9214            return;
9215        }
9216        if ((insn & 0x0f000e10) == 0x0e000a00) {
9217            /* VFP.  */
9218            if (disas_vfp_insn(s, insn)) {
9219                goto illegal_op;
9220            }
9221            return;
9222        }
9223        if (((insn & 0x0f30f000) == 0x0510f000) ||
9224            ((insn & 0x0f30f010) == 0x0710f000)) {
9225            if ((insn & (1 << 22)) == 0) {
9226                /* PLDW; v7MP */
9227                if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
9228                    goto illegal_op;
9229                }
9230            }
9231            /* Otherwise PLD; v5TE+ */
9232            ARCH(5TE);
9233            return;
9234        }
9235        if (((insn & 0x0f70f000) == 0x0450f000) ||
9236            ((insn & 0x0f70f010) == 0x0650f000)) {
9237            ARCH(7);
9238            return; /* PLI; V7 */
9239        }
9240        if (((insn & 0x0f700000) == 0x04100000) ||
9241            ((insn & 0x0f700010) == 0x06100000)) {
9242            if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
9243                goto illegal_op;
9244            }
9245            return; /* v7MP: Unallocated memory hint: must NOP */
9246        }
9247
9248        if ((insn & 0x0ffffdff) == 0x01010000) {
9249            ARCH(6);
9250            /* setend */
9251            if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
9252                gen_helper_setend(cpu_env);
9253                s->base.is_jmp = DISAS_UPDATE;
9254            }
9255            return;
9256        } else if ((insn & 0x0fffff00) == 0x057ff000) {
9257            switch ((insn >> 4) & 0xf) {
9258            case 1: /* clrex */
9259                ARCH(6K);
9260                gen_clrex(s);
9261                return;
9262            case 4: /* dsb */
9263            case 5: /* dmb */
9264                ARCH(7);
9265                tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
9266                return;
9267            case 6: /* isb */
9268                /* We need to break the TB after this insn to execute
9269                 * self-modifying code correctly and also to take
9270                 * any pending interrupts immediately.
9271                 */
9272                gen_goto_tb(s, 0, s->pc & ~1);
9273                return;
9274            case 7: /* sb */
9275                if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
9276                    goto illegal_op;
9277                }
9278                /*
9279                 * TODO: There is no speculation barrier opcode
9280                 * for TCG; MB and end the TB instead.
9281                 */
9282                tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
9283                gen_goto_tb(s, 0, s->pc & ~1);
9284                return;
9285            default:
9286                goto illegal_op;
9287            }
9288        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
9289            /* srs */
9290            ARCH(6);
9291            gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
9292            return;
9293        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
9294            /* rfe */
9295            int32_t offset;
9296            if (IS_USER(s))
9297                goto illegal_op;
9298            ARCH(6);
9299            rn = (insn >> 16) & 0xf;
9300            addr = load_reg(s, rn);
9301            i = (insn >> 23) & 3;
9302            switch (i) {
9303            case 0: offset = -4; break; /* DA */
9304            case 1: offset = 0; break; /* IA */
9305            case 2: offset = -8; break; /* DB */
9306            case 3: offset = 4; break; /* IB */
9307            default: abort();
9308            }
9309            if (offset)
9310                tcg_gen_addi_i32(addr, addr, offset);
9311            /* Load PC into tmp and CPSR into tmp2.  */
9312            tmp = tcg_temp_new_i32();
9313            gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9314            tcg_gen_addi_i32(addr, addr, 4);
9315            tmp2 = tcg_temp_new_i32();
9316            gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9317            if (insn & (1 << 21)) {
9318                /* Base writeback.  */
9319                switch (i) {
9320                case 0: offset = -8; break;
9321                case 1: offset = 4; break;
9322                case 2: offset = -4; break;
9323                case 3: offset = 0; break;
9324                default: abort();
9325                }
9326                if (offset)
9327                    tcg_gen_addi_i32(addr, addr, offset);
9328                store_reg(s, rn, addr);
9329            } else {
9330                tcg_temp_free_i32(addr);
9331            }
9332            gen_rfe(s, tmp, tmp2);
9333            return;
9334        } else if ((insn & 0x0e000000) == 0x0a000000) {
9335            /* branch link and change to thumb (blx <offset>) */
9336            int32_t offset;
9337
9338            val = (uint32_t)s->pc;
9339            tmp = tcg_temp_new_i32();
9340            tcg_gen_movi_i32(tmp, val);
9341            store_reg(s, 14, tmp);
9342            /* Sign-extend the 24-bit offset */
9343            offset = (((int32_t)insn) << 8) >> 8;
9344            /* offset * 4 + bit24 * 2 + (thumb bit) */
9345            val += (offset << 2) | ((insn >> 23) & 2) | 1;
9346            /* pipeline offset */
9347            val += 4;
9348            /* protected by ARCH(5); above, near the start of uncond block */
9349            gen_bx_im(s, val);
9350            return;
9351        } else if ((insn & 0x0e000f00) == 0x0c000100) {
9352            if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
9353                /* iWMMXt register transfer.  */
9354                if (extract32(s->c15_cpar, 1, 1)) {
9355                    if (!disas_iwmmxt_insn(s, insn)) {
9356                        return;
9357                    }
9358                }
9359            }
9360        } else if ((insn & 0x0e000a00) == 0x0c000800
9361                   && arm_dc_feature(s, ARM_FEATURE_V8)) {
9362            if (disas_neon_insn_3same_ext(s, insn)) {
9363                goto illegal_op;
9364            }
9365            return;
9366        } else if ((insn & 0x0f000a00) == 0x0e000800
9367                   && arm_dc_feature(s, ARM_FEATURE_V8)) {
9368            if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
9369                goto illegal_op;
9370            }
9371            return;
9372        } else if ((insn & 0x0fe00000) == 0x0c400000) {
9373            /* Coprocessor double register transfer.  */
9374            ARCH(5TE);
9375        } else if ((insn & 0x0f000010) == 0x0e000010) {
9376            /* Additional coprocessor register transfer.  */
9377        } else if ((insn & 0x0ff10020) == 0x01000000) {
9378            uint32_t mask;
9379            uint32_t val;
9380            /* cps (privileged) */
9381            if (IS_USER(s))
9382                return;
9383            mask = val = 0;
9384            if (insn & (1 << 19)) {
9385                if (insn & (1 << 8))
9386                    mask |= CPSR_A;
9387                if (insn & (1 << 7))
9388                    mask |= CPSR_I;
9389                if (insn & (1 << 6))
9390                    mask |= CPSR_F;
9391                if (insn & (1 << 18))
9392                    val |= mask;
9393            }
9394            if (insn & (1 << 17)) {
9395                mask |= CPSR_M;
9396                val |= (insn & 0x1f);
9397            }
9398            if (mask) {
9399                gen_set_psr_im(s, mask, 0, val);
9400            }
9401            return;
9402        }
9403        goto illegal_op;
9404    }
9405    if (cond != 0xe) {
9406        /* if not always execute, we generate a conditional jump to
9407           next instruction */
9408        arm_skip_unless(s, cond);
9409    }
9410    if ((insn & 0x0f900000) == 0x03000000) {
9411        if ((insn & (1 << 21)) == 0) {
9412            ARCH(6T2);
9413            rd = (insn >> 12) & 0xf;
9414            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
9415            if ((insn & (1 << 22)) == 0) {
9416                /* MOVW */
9417                tmp = tcg_temp_new_i32();
9418                tcg_gen_movi_i32(tmp, val);
9419            } else {
9420                /* MOVT */
9421                tmp = load_reg(s, rd);
9422                tcg_gen_ext16u_i32(tmp, tmp);
9423                tcg_gen_ori_i32(tmp, tmp, val << 16);
9424            }
9425            store_reg(s, rd, tmp);
9426        } else {
9427            if (((insn >> 12) & 0xf) != 0xf)
9428                goto illegal_op;
9429            if (((insn >> 16) & 0xf) == 0) {
9430                gen_nop_hint(s, insn & 0xff);
9431            } else {
9432                /* CPSR = immediate */
9433                val = insn & 0xff;
9434                shift = ((insn >> 8) & 0xf) * 2;
9435                if (shift)
9436                    val = (val >> shift) | (val << (32 - shift));
9437                i = ((insn & (1 << 22)) != 0);
9438                if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
9439                                   i, val)) {
9440                    goto illegal_op;
9441                }
9442            }
9443        }
9444    } else if ((insn & 0x0f900000) == 0x01000000
9445               && (insn & 0x00000090) != 0x00000090) {
9446        /* miscellaneous instructions */
9447        op1 = (insn >> 21) & 3;
9448        sh = (insn >> 4) & 0xf;
9449        rm = insn & 0xf;
9450        switch (sh) {
9451        case 0x0: /* MSR, MRS */
9452            if (insn & (1 << 9)) {
9453                /* MSR (banked) and MRS (banked) */
9454                int sysm = extract32(insn, 16, 4) |
9455                    (extract32(insn, 8, 1) << 4);
9456                int r = extract32(insn, 22, 1);
9457
9458                if (op1 & 1) {
9459                    /* MSR (banked) */
9460                    gen_msr_banked(s, r, sysm, rm);
9461                } else {
9462                    /* MRS (banked) */
9463                    int rd = extract32(insn, 12, 4);
9464
9465                    gen_mrs_banked(s, r, sysm, rd);
9466                }
9467                break;
9468            }
9469
9470            /* MSR, MRS (for PSRs) */
9471            if (op1 & 1) {
9472                /* PSR = reg */
9473                tmp = load_reg(s, rm);
9474                i = ((op1 & 2) != 0);
9475                if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
9476                    goto illegal_op;
9477            } else {
9478                /* reg = PSR */
9479                rd = (insn >> 12) & 0xf;
9480                if (op1 & 2) {
9481                    if (IS_USER(s))
9482                        goto illegal_op;
9483                    tmp = load_cpu_field(spsr);
9484                } else {
9485                    tmp = tcg_temp_new_i32();
9486                    gen_helper_cpsr_read(tmp, cpu_env);
9487                }
9488                store_reg(s, rd, tmp);
9489            }
9490            break;
9491        case 0x1:
9492            if (op1 == 1) {
9493                /* branch/exchange thumb (bx).  */
9494                ARCH(4T);
9495                tmp = load_reg(s, rm);
9496                gen_bx(s, tmp);
9497            } else if (op1 == 3) {
9498                /* clz */
9499                ARCH(5);
9500                rd = (insn >> 12) & 0xf;
9501                tmp = load_reg(s, rm);
9502                tcg_gen_clzi_i32(tmp, tmp, 32);
9503                store_reg(s, rd, tmp);
9504            } else {
9505                goto illegal_op;
9506            }
9507            break;
9508        case 0x2:
9509            if (op1 == 1) {
9510                ARCH(5J); /* bxj */
9511                /* Trivial implementation equivalent to bx.  */
9512                tmp = load_reg(s, rm);
9513                gen_bx(s, tmp);
9514            } else {
9515                goto illegal_op;
9516            }
9517            break;
9518        case 0x3:
9519            if (op1 != 1)
9520              goto illegal_op;
9521
9522            ARCH(5);
9523            /* branch link/exchange thumb (blx) */
9524            tmp = load_reg(s, rm);
9525            tmp2 = tcg_temp_new_i32();
9526            tcg_gen_movi_i32(tmp2, s->pc);
9527            store_reg(s, 14, tmp2);
9528            gen_bx(s, tmp);
9529            break;
9530        case 0x4:
9531        {
9532            /* crc32/crc32c */
9533            uint32_t c = extract32(insn, 8, 4);
9534
9535            /* Check this CPU supports ARMv8 CRC instructions.
9536             * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
9537             * Bits 8, 10 and 11 should be zero.
9538             */
9539            if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
9540                goto illegal_op;
9541            }
9542
9543            rn = extract32(insn, 16, 4);
9544            rd = extract32(insn, 12, 4);
9545
9546            tmp = load_reg(s, rn);
9547            tmp2 = load_reg(s, rm);
9548            if (op1 == 0) {
9549                tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9550            } else if (op1 == 1) {
9551                tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9552            }
9553            tmp3 = tcg_const_i32(1 << op1);
9554            if (c & 0x2) {
9555                gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9556            } else {
9557                gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9558            }
9559            tcg_temp_free_i32(tmp2);
9560            tcg_temp_free_i32(tmp3);
9561            store_reg(s, rd, tmp);
9562            break;
9563        }
9564        case 0x5: /* saturating add/subtract */
9565            ARCH(5TE);
9566            rd = (insn >> 12) & 0xf;
9567            rn = (insn >> 16) & 0xf;
9568            tmp = load_reg(s, rm);
9569            tmp2 = load_reg(s, rn);
9570            if (op1 & 2)
9571                gen_helper_double_saturate(tmp2, cpu_env, tmp2);
9572            if (op1 & 1)
9573                gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
9574            else
9575                gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9576            tcg_temp_free_i32(tmp2);
9577            store_reg(s, rd, tmp);
9578            break;
9579        case 0x6: /* ERET */
9580            if (op1 != 3) {
9581                goto illegal_op;
9582            }
9583            if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
9584                goto illegal_op;
9585            }
9586            if ((insn & 0x000fff0f) != 0x0000000e) {
9587                /* UNPREDICTABLE; we choose to UNDEF */
9588                goto illegal_op;
9589            }
9590
9591            if (s->current_el == 2) {
9592                tmp = load_cpu_field(elr_el[2]);
9593            } else {
9594                tmp = load_reg(s, 14);
9595            }
9596            gen_exception_return(s, tmp);
9597            break;
9598        case 7:
9599        {
9600            int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
9601            switch (op1) {
9602            case 0:
9603                /* HLT */
9604                gen_hlt(s, imm16);
9605                break;
9606            case 1:
9607                /* bkpt */
9608                ARCH(5);
9609                gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
9610                break;
9611            case 2:
9612                /* Hypervisor call (v7) */
9613                ARCH(7);
9614                if (IS_USER(s)) {
9615                    goto illegal_op;
9616                }
9617                gen_hvc(s, imm16);
9618                break;
9619            case 3:
9620                /* Secure monitor call (v6+) */
9621                ARCH(6K);
9622                if (IS_USER(s)) {
9623                    goto illegal_op;
9624                }
9625                gen_smc(s);
9626                break;
9627            default:
9628                g_assert_not_reached();
9629            }
9630            break;
9631        }
9632        case 0x8: /* signed multiply */
9633        case 0xa:
9634        case 0xc:
9635        case 0xe:
9636            ARCH(5TE);
9637            rs = (insn >> 8) & 0xf;
9638            rn = (insn >> 12) & 0xf;
9639            rd = (insn >> 16) & 0xf;
9640            if (op1 == 1) {
9641                /* (32 * 16) >> 16 */
9642                tmp = load_reg(s, rm);
9643                tmp2 = load_reg(s, rs);
9644                if (sh & 4)
9645                    tcg_gen_sari_i32(tmp2, tmp2, 16);
9646                else
9647                    gen_sxth(tmp2);
9648                tmp64 = gen_muls_i64_i32(tmp, tmp2);
9649                tcg_gen_shri_i64(tmp64, tmp64, 16);
9650                tmp = tcg_temp_new_i32();
9651                tcg_gen_extrl_i64_i32(tmp, tmp64);
9652                tcg_temp_free_i64(tmp64);
9653                if ((sh & 2) == 0) {
9654                    tmp2 = load_reg(s, rn);
9655                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9656                    tcg_temp_free_i32(tmp2);
9657                }
9658                store_reg(s, rd, tmp);
9659            } else {
9660                /* 16 * 16 */
9661                tmp = load_reg(s, rm);
9662                tmp2 = load_reg(s, rs);
9663                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
9664                tcg_temp_free_i32(tmp2);
9665                if (op1 == 2) {
9666                    tmp64 = tcg_temp_new_i64();
9667                    tcg_gen_ext_i32_i64(tmp64, tmp);
9668                    tcg_temp_free_i32(tmp);
9669                    gen_addq(s, tmp64, rn, rd);
9670                    gen_storeq_reg(s, rn, rd, tmp64);
9671                    tcg_temp_free_i64(tmp64);
9672                } else {
9673                    if (op1 == 0) {
9674                        tmp2 = load_reg(s, rn);
9675                        gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9676                        tcg_temp_free_i32(tmp2);
9677                    }
9678                    store_reg(s, rd, tmp);
9679                }
9680            }
9681            break;
9682        default:
9683            goto illegal_op;
9684        }
9685    } else if (((insn & 0x0e000000) == 0 &&
9686                (insn & 0x00000090) != 0x90) ||
9687               ((insn & 0x0e000000) == (1 << 25))) {
9688        int set_cc, logic_cc, shiftop;
9689
9690        op1 = (insn >> 21) & 0xf;
9691        set_cc = (insn >> 20) & 1;
9692        logic_cc = table_logic_cc[op1] & set_cc;
9693
9694        /* data processing instruction */
9695        if (insn & (1 << 25)) {
9696            /* immediate operand */
9697            val = insn & 0xff;
9698            shift = ((insn >> 8) & 0xf) * 2;
9699            if (shift) {
9700                val = (val >> shift) | (val << (32 - shift));
9701            }
9702            tmp2 = tcg_temp_new_i32();
9703            tcg_gen_movi_i32(tmp2, val);
9704            if (logic_cc && shift) {
9705                gen_set_CF_bit31(tmp2);
9706            }
9707        } else {
9708            /* register */
9709            rm = (insn) & 0xf;
9710            tmp2 = load_reg(s, rm);
9711            shiftop = (insn >> 5) & 3;
9712            if (!(insn & (1 << 4))) {
9713                shift = (insn >> 7) & 0x1f;
9714                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9715            } else {
9716                rs = (insn >> 8) & 0xf;
9717                tmp = load_reg(s, rs);
9718                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
9719            }
9720        }
9721        if (op1 != 0x0f && op1 != 0x0d) {
9722            rn = (insn >> 16) & 0xf;
9723            tmp = load_reg(s, rn);
9724        } else {
9725            tmp = NULL;
9726        }
9727        rd = (insn >> 12) & 0xf;
9728        switch(op1) {
9729        case 0x00:
9730            tcg_gen_and_i32(tmp, tmp, tmp2);
9731            if (logic_cc) {
9732                gen_logic_CC(tmp);
9733            }
9734            store_reg_bx(s, rd, tmp);
9735            break;
9736        case 0x01:
9737            tcg_gen_xor_i32(tmp, tmp, tmp2);
9738            if (logic_cc) {
9739                gen_logic_CC(tmp);
9740            }
9741            store_reg_bx(s, rd, tmp);
9742            break;
9743        case 0x02:
9744            if (set_cc && rd == 15) {
9745                /* SUBS r15, ... is used for exception return.  */
9746                if (IS_USER(s)) {
9747                    goto illegal_op;
9748                }
9749                gen_sub_CC(tmp, tmp, tmp2);
9750                gen_exception_return(s, tmp);
9751            } else {
9752                if (set_cc) {
9753                    gen_sub_CC(tmp, tmp, tmp2);
9754                } else {
9755                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9756                }
9757                store_reg_bx(s, rd, tmp);
9758            }
9759            break;
9760        case 0x03:
9761            if (set_cc) {
9762                gen_sub_CC(tmp, tmp2, tmp);
9763            } else {
9764                tcg_gen_sub_i32(tmp, tmp2, tmp);
9765            }
9766            store_reg_bx(s, rd, tmp);
9767            break;
9768        case 0x04:
9769            if (set_cc) {
9770                gen_add_CC(tmp, tmp, tmp2);
9771            } else {
9772                tcg_gen_add_i32(tmp, tmp, tmp2);
9773            }
9774            store_reg_bx(s, rd, tmp);
9775            break;
9776        case 0x05:
9777            if (set_cc) {
9778                gen_adc_CC(tmp, tmp, tmp2);
9779            } else {
9780                gen_add_carry(tmp, tmp, tmp2);
9781            }
9782            store_reg_bx(s, rd, tmp);
9783            break;
9784        case 0x06:
9785            if (set_cc) {
9786                gen_sbc_CC(tmp, tmp, tmp2);
9787            } else {
9788                gen_sub_carry(tmp, tmp, tmp2);
9789            }
9790            store_reg_bx(s, rd, tmp);
9791            break;
9792        case 0x07:
9793            if (set_cc) {
9794                gen_sbc_CC(tmp, tmp2, tmp);
9795            } else {
9796                gen_sub_carry(tmp, tmp2, tmp);
9797            }
9798            store_reg_bx(s, rd, tmp);
9799            break;
9800        case 0x08:
9801            if (set_cc) {
9802                tcg_gen_and_i32(tmp, tmp, tmp2);
9803                gen_logic_CC(tmp);
9804            }
9805            tcg_temp_free_i32(tmp);
9806            break;
9807        case 0x09:
9808            if (set_cc) {
9809                tcg_gen_xor_i32(tmp, tmp, tmp2);
9810                gen_logic_CC(tmp);
9811            }
9812            tcg_temp_free_i32(tmp);
9813            break;
9814        case 0x0a:
9815            if (set_cc) {
9816                gen_sub_CC(tmp, tmp, tmp2);
9817            }
9818            tcg_temp_free_i32(tmp);
9819            break;
9820        case 0x0b:
9821            if (set_cc) {
9822                gen_add_CC(tmp, tmp, tmp2);
9823            }
9824            tcg_temp_free_i32(tmp);
9825            break;
9826        case 0x0c:
9827            tcg_gen_or_i32(tmp, tmp, tmp2);
9828            if (logic_cc) {
9829                gen_logic_CC(tmp);
9830            }
9831            store_reg_bx(s, rd, tmp);
9832            break;
9833        case 0x0d:
9834            if (logic_cc && rd == 15) {
9835                /* MOVS r15, ... is used for exception return.  */
9836                if (IS_USER(s)) {
9837                    goto illegal_op;
9838                }
9839                gen_exception_return(s, tmp2);
9840            } else {
9841                if (logic_cc) {
9842                    gen_logic_CC(tmp2);
9843                }
9844                store_reg_bx(s, rd, tmp2);
9845            }
9846            break;
9847        case 0x0e:
9848            tcg_gen_andc_i32(tmp, tmp, tmp2);
9849            if (logic_cc) {
9850                gen_logic_CC(tmp);
9851            }
9852            store_reg_bx(s, rd, tmp);
9853            break;
9854        default:
9855        case 0x0f:
9856            tcg_gen_not_i32(tmp2, tmp2);
9857            if (logic_cc) {
9858                gen_logic_CC(tmp2);
9859            }
9860            store_reg_bx(s, rd, tmp2);
9861            break;
9862        }
9863        if (op1 != 0x0f && op1 != 0x0d) {
9864            tcg_temp_free_i32(tmp2);
9865        }
9866    } else {
9867        /* other instructions */
9868        op1 = (insn >> 24) & 0xf;
9869        switch(op1) {
9870        case 0x0:
9871        case 0x1:
9872            /* multiplies, extra load/stores */
9873            sh = (insn >> 5) & 3;
9874            if (sh == 0) {
9875                if (op1 == 0x0) {
9876                    rd = (insn >> 16) & 0xf;
9877                    rn = (insn >> 12) & 0xf;
9878                    rs = (insn >> 8) & 0xf;
9879                    rm = (insn) & 0xf;
9880                    op1 = (insn >> 20) & 0xf;
9881                    switch (op1) {
9882                    case 0: case 1: case 2: case 3: case 6:
9883                        /* 32 bit mul */
9884                        tmp = load_reg(s, rs);
9885                        tmp2 = load_reg(s, rm);
9886                        tcg_gen_mul_i32(tmp, tmp, tmp2);
9887                        tcg_temp_free_i32(tmp2);
9888                        if (insn & (1 << 22)) {
9889                            /* Subtract (mls) */
9890                            ARCH(6T2);
9891                            tmp2 = load_reg(s, rn);
9892                            tcg_gen_sub_i32(tmp, tmp2, tmp);
9893                            tcg_temp_free_i32(tmp2);
9894                        } else if (insn & (1 << 21)) {
9895                            /* Add */
9896                            tmp2 = load_reg(s, rn);
9897                            tcg_gen_add_i32(tmp, tmp, tmp2);
9898                            tcg_temp_free_i32(tmp2);
9899                        }
9900                        if (insn & (1 << 20))
9901                            gen_logic_CC(tmp);
9902                        store_reg(s, rd, tmp);
9903                        break;
9904                    case 4:
9905                        /* 64 bit mul double accumulate (UMAAL) */
9906                        ARCH(6);
9907                        tmp = load_reg(s, rs);
9908                        tmp2 = load_reg(s, rm);
9909                        tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9910                        gen_addq_lo(s, tmp64, rn);
9911                        gen_addq_lo(s, tmp64, rd);
9912                        gen_storeq_reg(s, rn, rd, tmp64);
9913                        tcg_temp_free_i64(tmp64);
9914                        break;
9915                    case 8: case 9: case 10: case 11:
9916                    case 12: case 13: case 14: case 15:
9917                        /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9918                        tmp = load_reg(s, rs);
9919                        tmp2 = load_reg(s, rm);
9920                        if (insn & (1 << 22)) {
9921                            tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9922                        } else {
9923                            tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9924                        }
9925                        if (insn & (1 << 21)) { /* mult accumulate */
9926                            TCGv_i32 al = load_reg(s, rn);
9927                            TCGv_i32 ah = load_reg(s, rd);
9928                            tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9929                            tcg_temp_free_i32(al);
9930                            tcg_temp_free_i32(ah);
9931                        }
9932                        if (insn & (1 << 20)) {
9933                            gen_logicq_cc(tmp, tmp2);
9934                        }
9935                        store_reg(s, rn, tmp);
9936                        store_reg(s, rd, tmp2);
9937                        break;
9938                    default:
9939                        goto illegal_op;
9940                    }
9941                } else {
9942                    rn = (insn >> 16) & 0xf;
9943                    rd = (insn >> 12) & 0xf;
9944                    if (insn & (1 << 23)) {
9945                        /* load/store exclusive */
9946                        bool is_ld = extract32(insn, 20, 1);
9947                        bool is_lasr = !extract32(insn, 8, 1);
9948                        int op2 = (insn >> 8) & 3;
9949                        op1 = (insn >> 21) & 0x3;
9950
9951                        switch (op2) {
9952                        case 0: /* lda/stl */
9953                            if (op1 == 1) {
9954                                goto illegal_op;
9955                            }
9956                            ARCH(8);
9957                            break;
9958                        case 1: /* reserved */
9959                            goto illegal_op;
9960                        case 2: /* ldaex/stlex */
9961                            ARCH(8);
9962                            break;
9963                        case 3: /* ldrex/strex */
9964                            if (op1) {
9965                                ARCH(6K);
9966                            } else {
9967                                ARCH(6);
9968                            }
9969                            break;
9970                        }
9971
9972                        addr = tcg_temp_local_new_i32();
9973                        load_reg_var(s, addr, rn);
9974
9975                        if (is_lasr && !is_ld) {
9976                            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9977                        }
9978
9979                        if (op2 == 0) {
9980                            if (is_ld) {
9981                                tmp = tcg_temp_new_i32();
9982                                switch (op1) {
9983                                case 0: /* lda */
9984                                    gen_aa32_ld32u_iss(s, tmp, addr,
9985                                                       get_mem_index(s),
9986                                                       rd | ISSIsAcqRel);
9987                                    break;
9988                                case 2: /* ldab */
9989                                    gen_aa32_ld8u_iss(s, tmp, addr,
9990                                                      get_mem_index(s),
9991                                                      rd | ISSIsAcqRel);
9992                                    break;
9993                                case 3: /* ldah */
9994                                    gen_aa32_ld16u_iss(s, tmp, addr,
9995                                                       get_mem_index(s),
9996                                                       rd | ISSIsAcqRel);
9997                                    break;
9998                                default:
9999                                    abort();
10000                                }
10001                                store_reg(s, rd, tmp);
10002                            } else {
10003                                rm = insn & 0xf;
10004                                tmp = load_reg(s, rm);
10005                                switch (op1) {
10006                                case 0: /* stl */
10007                                    gen_aa32_st32_iss(s, tmp, addr,
10008                                                      get_mem_index(s),
10009                                                      rm | ISSIsAcqRel);
10010                                    break;
10011                                case 2: /* stlb */
10012                                    gen_aa32_st8_iss(s, tmp, addr,
10013                                                     get_mem_index(s),
10014                                                     rm | ISSIsAcqRel);
10015                                    break;
10016                                case 3: /* stlh */
10017                                    gen_aa32_st16_iss(s, tmp, addr,
10018                                                      get_mem_index(s),
10019                                                      rm | ISSIsAcqRel);
10020                                    break;
10021                                default:
10022                                    abort();
10023                                }
10024                                tcg_temp_free_i32(tmp);
10025                            }
10026                        } else if (is_ld) {
10027                            switch (op1) {
10028                            case 0: /* ldrex */
10029                                gen_load_exclusive(s, rd, 15, addr, 2);
10030                                break;
10031                            case 1: /* ldrexd */
10032                                gen_load_exclusive(s, rd, rd + 1, addr, 3);
10033                                break;
10034                            case 2: /* ldrexb */
10035                                gen_load_exclusive(s, rd, 15, addr, 0);
10036                                break;
10037                            case 3: /* ldrexh */
10038                                gen_load_exclusive(s, rd, 15, addr, 1);
10039                                break;
10040                            default:
10041                                abort();
10042                            }
10043                        } else {
10044                            rm = insn & 0xf;
10045                            switch (op1) {
10046                            case 0:  /*  strex */
10047                                gen_store_exclusive(s, rd, rm, 15, addr, 2);
10048                                break;
10049                            case 1: /*  strexd */
10050                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
10051                                break;
10052                            case 2: /*  strexb */
10053                                gen_store_exclusive(s, rd, rm, 15, addr, 0);
10054                                break;
10055                            case 3: /* strexh */
10056                                gen_store_exclusive(s, rd, rm, 15, addr, 1);
10057                                break;
10058                            default:
10059                                abort();
10060                            }
10061                        }
10062                        tcg_temp_free_i32(addr);
10063
10064                        if (is_lasr && is_ld) {
10065                            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
10066                        }
10067                    } else if ((insn & 0x00300f00) == 0) {
10068                        /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
10069                        *  - SWP, SWPB
10070                        */
10071
10072                        TCGv taddr;
10073                        TCGMemOp opc = s->be_data;
10074
10075                        rm = (insn) & 0xf;
10076
10077                        if (insn & (1 << 22)) {
10078                            opc |= MO_UB;
10079                        } else {
10080                            opc |= MO_UL | MO_ALIGN;
10081                        }
10082
10083                        addr = load_reg(s, rn);
10084                        taddr = gen_aa32_addr(s, addr, opc);
10085                        tcg_temp_free_i32(addr);
10086
10087                        tmp = load_reg(s, rm);
10088                        tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
10089                                                get_mem_index(s), opc);
10090                        tcg_temp_free(taddr);
10091                        store_reg(s, rd, tmp);
10092                    } else {
10093                        goto illegal_op;
10094                    }
10095                }
10096            } else {
10097                int address_offset;
10098                bool load = insn & (1 << 20);
10099                bool wbit = insn & (1 << 21);
10100                bool pbit = insn & (1 << 24);
10101                bool doubleword = false;
10102                ISSInfo issinfo;
10103
10104                /* Misc load/store */
10105                rn = (insn >> 16) & 0xf;
10106                rd = (insn >> 12) & 0xf;
10107
10108                /* ISS not valid if writeback */
10109                issinfo = (pbit & !wbit) ? rd : ISSInvalid;
10110
10111                if (!load && (sh & 2)) {
10112                    /* doubleword */
10113                    ARCH(5TE);
10114                    if (rd & 1) {
10115                        /* UNPREDICTABLE; we choose to UNDEF */
10116                        goto illegal_op;
10117                    }
10118                    load = (sh & 1) == 0;
10119                    doubleword = true;
10120                }
10121
10122                addr = load_reg(s, rn);
10123                if (pbit) {
10124                    gen_add_datah_offset(s, insn, 0, addr);
10125                }
10126                address_offset = 0;
10127
10128                if (doubleword) {
10129                    if (!load) {
10130                        /* store */
10131                        tmp = load_reg(s, rd);
10132                        gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10133                        tcg_temp_free_i32(tmp);
10134                        tcg_gen_addi_i32(addr, addr, 4);
10135                        tmp = load_reg(s, rd + 1);
10136                        gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10137                        tcg_temp_free_i32(tmp);
10138                    } else {
10139                        /* load */
10140                        tmp = tcg_temp_new_i32();
10141                        gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10142                        store_reg(s, rd, tmp);
10143                        tcg_gen_addi_i32(addr, addr, 4);
10144                        tmp = tcg_temp_new_i32();
10145                        gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10146                        rd++;
10147                    }
10148                    address_offset = -4;
10149                } else if (load) {
10150                    /* load */
10151                    tmp = tcg_temp_new_i32();
10152                    switch (sh) {
10153                    case 1:
10154                        gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10155                                           issinfo);
10156                        break;
10157                    case 2:
10158                        gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
10159                                          issinfo);
10160                        break;
10161                    default:
10162                    case 3:
10163                        gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
10164                                           issinfo);
10165                        break;
10166                    }
10167                } else {
10168                    /* store */
10169                    tmp = load_reg(s, rd);
10170                    gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
10171                    tcg_temp_free_i32(tmp);
10172                }
10173                /* Perform base writeback before the loaded value to
10174                   ensure correct behavior with overlapping index registers.
10175                   ldrd with base writeback is undefined if the
10176                   destination and index registers overlap.  */
10177                if (!pbit) {
10178                    gen_add_datah_offset(s, insn, address_offset, addr);
10179                    store_reg(s, rn, addr);
10180                } else if (wbit) {
10181                    if (address_offset)
10182                        tcg_gen_addi_i32(addr, addr, address_offset);
10183                    store_reg(s, rn, addr);
10184                } else {
10185                    tcg_temp_free_i32(addr);
10186                }
10187                if (load) {
10188                    /* Complete the load.  */
10189                    store_reg(s, rd, tmp);
10190                }
10191            }
10192            break;
10193        case 0x4:
10194        case 0x5:
10195            goto do_ldst;
10196        case 0x6:
10197        case 0x7:
10198            if (insn & (1 << 4)) {
10199                ARCH(6);
10200                /* Armv6 Media instructions.  */
10201                rm = insn & 0xf;
10202                rn = (insn >> 16) & 0xf;
10203                rd = (insn >> 12) & 0xf;
10204                rs = (insn >> 8) & 0xf;
10205                switch ((insn >> 23) & 3) {
10206                case 0: /* Parallel add/subtract.  */
10207                    op1 = (insn >> 20) & 7;
10208                    tmp = load_reg(s, rn);
10209                    tmp2 = load_reg(s, rm);
10210                    sh = (insn >> 5) & 7;
10211                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
10212                        goto illegal_op;
10213                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
10214                    tcg_temp_free_i32(tmp2);
10215                    store_reg(s, rd, tmp);
10216                    break;
10217                case 1:
10218                    if ((insn & 0x00700020) == 0) {
10219                        /* Halfword pack.  */
10220                        tmp = load_reg(s, rn);
10221                        tmp2 = load_reg(s, rm);
10222                        shift = (insn >> 7) & 0x1f;
10223                        if (insn & (1 << 6)) {
10224                            /* pkhtb */
10225                            if (shift == 0)
10226                                shift = 31;
10227                            tcg_gen_sari_i32(tmp2, tmp2, shift);
10228                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10229                            tcg_gen_ext16u_i32(tmp2, tmp2);
10230                        } else {
10231                            /* pkhbt */
10232                            if (shift)
10233                                tcg_gen_shli_i32(tmp2, tmp2, shift);
10234                            tcg_gen_ext16u_i32(tmp, tmp);
10235                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10236                        }
10237                        tcg_gen_or_i32(tmp, tmp, tmp2);
10238                        tcg_temp_free_i32(tmp2);
10239                        store_reg(s, rd, tmp);
10240                    } else if ((insn & 0x00200020) == 0x00200000) {
10241                        /* [us]sat */
10242                        tmp = load_reg(s, rm);
10243                        shift = (insn >> 7) & 0x1f;
10244                        if (insn & (1 << 6)) {
10245                            if (shift == 0)
10246                                shift = 31;
10247                            tcg_gen_sari_i32(tmp, tmp, shift);
10248                        } else {
10249                            tcg_gen_shli_i32(tmp, tmp, shift);
10250                        }
10251                        sh = (insn >> 16) & 0x1f;
10252                        tmp2 = tcg_const_i32(sh);
10253                        if (insn & (1 << 22))
10254                          gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10255                        else
10256                          gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10257                        tcg_temp_free_i32(tmp2);
10258                        store_reg(s, rd, tmp);
10259                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
10260                        /* [us]sat16 */
10261                        tmp = load_reg(s, rm);
10262                        sh = (insn >> 16) & 0x1f;
10263                        tmp2 = tcg_const_i32(sh);
10264                        if (insn & (1 << 22))
10265                          gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10266                        else
10267                          gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10268                        tcg_temp_free_i32(tmp2);
10269                        store_reg(s, rd, tmp);
10270                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
10271                        /* Select bytes.  */
10272                        tmp = load_reg(s, rn);
10273                        tmp2 = load_reg(s, rm);
10274                        tmp3 = tcg_temp_new_i32();
10275                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10276                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10277                        tcg_temp_free_i32(tmp3);
10278                        tcg_temp_free_i32(tmp2);
10279                        store_reg(s, rd, tmp);
10280                    } else if ((insn & 0x000003e0) == 0x00000060) {
10281                        tmp = load_reg(s, rm);
10282                        shift = (insn >> 10) & 3;
10283                        /* ??? In many cases it's not necessary to do a
10284                           rotate, a shift is sufficient.  */
10285                        if (shift != 0)
10286                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10287                        op1 = (insn >> 20) & 7;
10288                        switch (op1) {
10289                        case 0: gen_sxtb16(tmp);  break;
10290                        case 2: gen_sxtb(tmp);    break;
10291                        case 3: gen_sxth(tmp);    break;
10292                        case 4: gen_uxtb16(tmp);  break;
10293                        case 6: gen_uxtb(tmp);    break;
10294                        case 7: gen_uxth(tmp);    break;
10295                        default: goto illegal_op;
10296                        }
10297                        if (rn != 15) {
10298                            tmp2 = load_reg(s, rn);
10299                            if ((op1 & 3) == 0) {
10300                                gen_add16(tmp, tmp2);
10301                            } else {
10302                                tcg_gen_add_i32(tmp, tmp, tmp2);
10303                                tcg_temp_free_i32(tmp2);
10304                            }
10305                        }
10306                        store_reg(s, rd, tmp);
10307                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
10308                        /* rev */
10309                        tmp = load_reg(s, rm);
10310                        if (insn & (1 << 22)) {
10311                            if (insn & (1 << 7)) {
10312                                gen_revsh(tmp);
10313                            } else {
10314                                ARCH(6T2);
10315                                gen_helper_rbit(tmp, tmp);
10316                            }
10317                        } else {
10318                            if (insn & (1 << 7))
10319                                gen_rev16(tmp);
10320                            else
10321                                tcg_gen_bswap32_i32(tmp, tmp);
10322                        }
10323                        store_reg(s, rd, tmp);
10324                    } else {
10325                        goto illegal_op;
10326                    }
10327                    break;
10328                case 2: /* Multiplies (Type 3).  */
10329                    switch ((insn >> 20) & 0x7) {
10330                    case 5:
10331                        if (((insn >> 6) ^ (insn >> 7)) & 1) {
10332                            /* op2 not 00x or 11x : UNDEF */
10333                            goto illegal_op;
10334                        }
10335                        /* Signed multiply most significant [accumulate].
10336                           (SMMUL, SMMLA, SMMLS) */
10337                        tmp = load_reg(s, rm);
10338                        tmp2 = load_reg(s, rs);
10339                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
10340
10341                        if (rd != 15) {
10342                            tmp = load_reg(s, rd);
10343                            if (insn & (1 << 6)) {
10344                                tmp64 = gen_subq_msw(tmp64, tmp);
10345                            } else {
10346                                tmp64 = gen_addq_msw(tmp64, tmp);
10347                            }
10348                        }
10349                        if (insn & (1 << 5)) {
10350                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10351                        }
10352                        tcg_gen_shri_i64(tmp64, tmp64, 32);
10353                        tmp = tcg_temp_new_i32();
10354                        tcg_gen_extrl_i64_i32(tmp, tmp64);
10355                        tcg_temp_free_i64(tmp64);
10356                        store_reg(s, rn, tmp);
10357                        break;
10358                    case 0:
10359                    case 4:
10360                        /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
10361                        if (insn & (1 << 7)) {
10362                            goto illegal_op;
10363                        }
10364                        tmp = load_reg(s, rm);
10365                        tmp2 = load_reg(s, rs);
10366                        if (insn & (1 << 5))
10367                            gen_swap_half(tmp2);
10368                        gen_smul_dual(tmp, tmp2);
10369                        if (insn & (1 << 22)) {
10370                            /* smlald, smlsld */
10371                            TCGv_i64 tmp64_2;
10372
10373                            tmp64 = tcg_temp_new_i64();
10374                            tmp64_2 = tcg_temp_new_i64();
10375                            tcg_gen_ext_i32_i64(tmp64, tmp);
10376                            tcg_gen_ext_i32_i64(tmp64_2, tmp2);
10377                            tcg_temp_free_i32(tmp);
10378                            tcg_temp_free_i32(tmp2);
10379                            if (insn & (1 << 6)) {
10380                                tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
10381                            } else {
10382                                tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
10383                            }
10384                            tcg_temp_free_i64(tmp64_2);
10385                            gen_addq(s, tmp64, rd, rn);
10386                            gen_storeq_reg(s, rd, rn, tmp64);
10387                            tcg_temp_free_i64(tmp64);
10388                        } else {
10389                            /* smuad, smusd, smlad, smlsd */
10390                            if (insn & (1 << 6)) {
10391                                /* This subtraction cannot overflow. */
10392                                tcg_gen_sub_i32(tmp, tmp, tmp2);
10393                            } else {
10394                                /* This addition cannot overflow 32 bits;
10395                                 * however it may overflow considered as a
10396                                 * signed operation, in which case we must set
10397                                 * the Q flag.
10398                                 */
10399                                gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10400                            }
10401                            tcg_temp_free_i32(tmp2);
10402                            if (rd != 15)
10403                              {
10404                                tmp2 = load_reg(s, rd);
10405                                gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10406                                tcg_temp_free_i32(tmp2);
10407                              }
10408                            store_reg(s, rn, tmp);
10409                        }
10410                        break;
10411                    case 1:
10412                    case 3:
10413                        /* SDIV, UDIV */
10414                        if (!dc_isar_feature(arm_div, s)) {
10415                            goto illegal_op;
10416                        }
10417                        if (((insn >> 5) & 7) || (rd != 15)) {
10418                            goto illegal_op;
10419                        }
10420                        tmp = load_reg(s, rm);
10421                        tmp2 = load_reg(s, rs);
10422                        if (insn & (1 << 21)) {
10423                            gen_helper_udiv(tmp, tmp, tmp2);
10424                        } else {
10425                            gen_helper_sdiv(tmp, tmp, tmp2);
10426                        }
10427                        tcg_temp_free_i32(tmp2);
10428                        store_reg(s, rn, tmp);
10429                        break;
10430                    default:
10431                        goto illegal_op;
10432                    }
10433                    break;
10434                case 3:
10435                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
10436                    switch (op1) {
10437                    case 0: /* Unsigned sum of absolute differences.  */
10438                        ARCH(6);
10439                        tmp = load_reg(s, rm);
10440                        tmp2 = load_reg(s, rs);
10441                        gen_helper_usad8(tmp, tmp, tmp2);
10442                        tcg_temp_free_i32(tmp2);
10443                        if (rd != 15) {
10444                            tmp2 = load_reg(s, rd);
10445                            tcg_gen_add_i32(tmp, tmp, tmp2);
10446                            tcg_temp_free_i32(tmp2);
10447                        }
10448                        store_reg(s, rn, tmp);
10449                        break;
10450                    case 0x20: case 0x24: case 0x28: case 0x2c:
10451                        /* Bitfield insert/clear.  */
10452                        ARCH(6T2);
10453                        shift = (insn >> 7) & 0x1f;
10454                        i = (insn >> 16) & 0x1f;
10455                        if (i < shift) {
10456                            /* UNPREDICTABLE; we choose to UNDEF */
10457                            goto illegal_op;
10458                        }
10459                        i = i + 1 - shift;
10460                        if (rm == 15) {
10461                            tmp = tcg_temp_new_i32();
10462                            tcg_gen_movi_i32(tmp, 0);
10463                        } else {
10464                            tmp = load_reg(s, rm);
10465                        }
10466                        if (i != 32) {
10467                            tmp2 = load_reg(s, rd);
10468                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
10469                            tcg_temp_free_i32(tmp2);
10470                        }
10471                        store_reg(s, rd, tmp);
10472                        break;
10473                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
10474                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
10475                        ARCH(6T2);
10476                        tmp = load_reg(s, rm);
10477                        shift = (insn >> 7) & 0x1f;
10478                        i = ((insn >> 16) & 0x1f) + 1;
10479                        if (shift + i > 32)
10480                            goto illegal_op;
10481                        if (i < 32) {
10482                            if (op1 & 0x20) {
10483                                tcg_gen_extract_i32(tmp, tmp, shift, i);
10484                            } else {
10485                                tcg_gen_sextract_i32(tmp, tmp, shift, i);
10486                            }
10487                        }
10488                        store_reg(s, rd, tmp);
10489                        break;
10490                    default:
10491                        goto illegal_op;
10492                    }
10493                    break;
10494                }
10495                break;
10496            }
10497        do_ldst:
10498            /* Check for undefined extension instructions
10499             * per the ARM Bible IE:
10500             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
10501             */
10502            sh = (0xf << 20) | (0xf << 4);
10503            if (op1 == 0x7 && ((insn & sh) == sh))
10504            {
10505                goto illegal_op;
10506            }
10507            /* load/store byte/word */
10508            rn = (insn >> 16) & 0xf;
10509            rd = (insn >> 12) & 0xf;
10510            tmp2 = load_reg(s, rn);
10511            if ((insn & 0x01200000) == 0x00200000) {
10512                /* ldrt/strt */
10513                i = get_a32_user_mem_index(s);
10514            } else {
10515                i = get_mem_index(s);
10516            }
10517            if (insn & (1 << 24))
10518                gen_add_data_offset(s, insn, tmp2);
10519            if (insn & (1 << 20)) {
10520                /* load */
10521                tmp = tcg_temp_new_i32();
10522                if (insn & (1 << 22)) {
10523                    gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
10524                } else {
10525                    gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
10526                }
10527            } else {
10528                /* store */
10529                tmp = load_reg(s, rd);
10530                if (insn & (1 << 22)) {
10531                    gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
10532                } else {
10533                    gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
10534                }
10535                tcg_temp_free_i32(tmp);
10536            }
10537            if (!(insn & (1 << 24))) {
10538                gen_add_data_offset(s, insn, tmp2);
10539                store_reg(s, rn, tmp2);
10540            } else if (insn & (1 << 21)) {
10541                store_reg(s, rn, tmp2);
10542            } else {
10543                tcg_temp_free_i32(tmp2);
10544            }
10545            if (insn & (1 << 20)) {
10546                /* Complete the load.  */
10547                store_reg_from_load(s, rd, tmp);
10548            }
10549            break;
10550        case 0x08:
10551        case 0x09:
10552            {
10553                int j, n, loaded_base;
10554                bool exc_return = false;
10555                bool is_load = extract32(insn, 20, 1);
10556                bool user = false;
10557                TCGv_i32 loaded_var;
10558                /* load/store multiple words */
10559                /* XXX: store correct base if write back */
10560                if (insn & (1 << 22)) {
10561                    /* LDM (user), LDM (exception return) and STM (user) */
10562                    if (IS_USER(s))
10563                        goto illegal_op; /* only usable in supervisor mode */
10564
10565                    if (is_load && extract32(insn, 15, 1)) {
10566                        exc_return = true;
10567                    } else {
10568                        user = true;
10569                    }
10570                }
10571                rn = (insn >> 16) & 0xf;
10572                addr = load_reg(s, rn);
10573
10574                /* compute total size */
10575                loaded_base = 0;
10576                loaded_var = NULL;
10577                n = 0;
10578                for(i=0;i<16;i++) {
10579                    if (insn & (1 << i))
10580                        n++;
10581                }
10582                /* XXX: test invalid n == 0 case ? */
10583                if (insn & (1 << 23)) {
10584                    if (insn & (1 << 24)) {
10585                        /* pre increment */
10586                        tcg_gen_addi_i32(addr, addr, 4);
10587                    } else {
10588                        /* post increment */
10589                    }
10590                } else {
10591                    if (insn & (1 << 24)) {
10592                        /* pre decrement */
10593                        tcg_gen_addi_i32(addr, addr, -(n * 4));
10594                    } else {
10595                        /* post decrement */
10596                        if (n != 1)
10597                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10598                    }
10599                }
10600                j = 0;
10601                for(i=0;i<16;i++) {
10602                    if (insn & (1 << i)) {
10603                        if (is_load) {
10604                            /* load */
10605                            tmp = tcg_temp_new_i32();
10606                            gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10607                            if (user) {
10608                                tmp2 = tcg_const_i32(i);
10609                                gen_helper_set_user_reg(cpu_env, tmp2, tmp);
10610                                tcg_temp_free_i32(tmp2);
10611                                tcg_temp_free_i32(tmp);
10612                            } else if (i == rn) {
10613                                loaded_var = tmp;
10614                                loaded_base = 1;
10615                            } else if (i == 15 && exc_return) {
10616                                store_pc_exc_ret(s, tmp);
10617                            } else {
10618                                store_reg_from_load(s, i, tmp);
10619                            }
10620                        } else {
10621                            /* store */
10622                            if (i == 15) {
10623                                /* special case: r15 = PC + 8 */
10624                                val = (long)s->pc + 4;
10625                                tmp = tcg_temp_new_i32();
10626                                tcg_gen_movi_i32(tmp, val);
10627                            } else if (user) {
10628                                tmp = tcg_temp_new_i32();
10629                                tmp2 = tcg_const_i32(i);
10630                                gen_helper_get_user_reg(tmp, cpu_env, tmp2);
10631                                tcg_temp_free_i32(tmp2);
10632                            } else {
10633                                tmp = load_reg(s, i);
10634                            }
10635                            gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10636                            tcg_temp_free_i32(tmp);
10637                        }
10638                        j++;
10639                        /* no need to add after the last transfer */
10640                        if (j != n)
10641                            tcg_gen_addi_i32(addr, addr, 4);
10642                    }
10643                }
10644                if (insn & (1 << 21)) {
10645                    /* write back */
10646                    if (insn & (1 << 23)) {
10647                        if (insn & (1 << 24)) {
10648                            /* pre increment */
10649                        } else {
10650                            /* post increment */
10651                            tcg_gen_addi_i32(addr, addr, 4);
10652                        }
10653                    } else {
10654                        if (insn & (1 << 24)) {
10655                            /* pre decrement */
10656                            if (n != 1)
10657                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10658                        } else {
10659                            /* post decrement */
10660                            tcg_gen_addi_i32(addr, addr, -(n * 4));
10661                        }
10662                    }
10663                    store_reg(s, rn, addr);
10664                } else {
10665                    tcg_temp_free_i32(addr);
10666                }
10667                if (loaded_base) {
10668                    store_reg(s, rn, loaded_var);
10669                }
10670                if (exc_return) {
10671                    /* Restore CPSR from SPSR.  */
10672                    tmp = load_cpu_field(spsr);
10673                    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10674                        gen_io_start();
10675                    }
10676                    gen_helper_cpsr_write_eret(cpu_env, tmp);
10677                    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10678                        gen_io_end();
10679                    }
10680                    tcg_temp_free_i32(tmp);
10681                    /* Must exit loop to check un-masked IRQs */
10682                    s->base.is_jmp = DISAS_EXIT;
10683                }
10684            }
10685            break;
10686        case 0xa:
10687        case 0xb:
10688            {
10689                int32_t offset;
10690
10691                /* branch (and link) */
10692                val = (int32_t)s->pc;
10693                if (insn & (1 << 24)) {
10694                    tmp = tcg_temp_new_i32();
10695                    tcg_gen_movi_i32(tmp, val);
10696                    store_reg(s, 14, tmp);
10697                }
10698                offset = sextract32(insn << 2, 0, 26);
10699                val += offset + 4;
10700                gen_jmp(s, val);
10701            }
10702            break;
10703        case 0xc:
10704        case 0xd:
10705        case 0xe:
10706            if (((insn >> 8) & 0xe) == 10) {
10707                /* VFP.  */
10708                if (disas_vfp_insn(s, insn)) {
10709                    goto illegal_op;
10710                }
10711            } else if (disas_coproc_insn(s, insn)) {
10712                /* Coprocessor.  */
10713                goto illegal_op;
10714            }
10715            break;
10716        case 0xf:
10717            /* swi */
10718            gen_set_pc_im(s, s->pc);
10719            s->svc_imm = extract32(insn, 0, 24);
10720            s->base.is_jmp = DISAS_SWI;
10721            break;
10722        default:
10723        illegal_op:
10724            gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
10725                               default_exception_el(s));
10726            break;
10727        }
10728    }
10729}
10730
10731static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
10732{
10733    /* Return true if this is a 16 bit instruction. We must be precise
10734     * about this (matching the decode).  We assume that s->pc still
10735     * points to the first 16 bits of the insn.
10736     */
10737    if ((insn >> 11) < 0x1d) {
10738        /* Definitely a 16-bit instruction */
10739        return true;
10740    }
10741
10742    /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10743     * first half of a 32-bit Thumb insn. Thumb-1 cores might
10744     * end up actually treating this as two 16-bit insns, though,
10745     * if it's half of a bl/blx pair that might span a page boundary.
10746     */
10747    if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10748        arm_dc_feature(s, ARM_FEATURE_M)) {
10749        /* Thumb2 cores (including all M profile ones) always treat
10750         * 32-bit insns as 32-bit.
10751         */
10752        return false;
10753    }
10754
10755    if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10756        /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10757         * is not on the next page; we merge this into a 32-bit
10758         * insn.
10759         */
10760        return false;
10761    }
10762    /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10763     * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10764     * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10765     *  -- handle as single 16 bit insn
10766     */
10767    return true;
10768}
10769
10770/* Return true if this is a Thumb-2 logical op.  */
10771static int
10772thumb2_logic_op(int op)
10773{
10774    return (op < 8);
10775}
10776
10777/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
10778   then set condition code flags based on the result of the operation.
10779   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10780   to the high bit of T1.
10781   Returns zero if the opcode is valid.  */
10782
10783static int
10784gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
10785                   TCGv_i32 t0, TCGv_i32 t1)
10786{
10787    int logic_cc;
10788
10789    logic_cc = 0;
10790    switch (op) {
10791    case 0: /* and */
10792        tcg_gen_and_i32(t0, t0, t1);
10793        logic_cc = conds;
10794        break;
10795    case 1: /* bic */
10796        tcg_gen_andc_i32(t0, t0, t1);
10797        logic_cc = conds;
10798        break;
10799    case 2: /* orr */
10800        tcg_gen_or_i32(t0, t0, t1);
10801        logic_cc = conds;
10802        break;
10803    case 3: /* orn */
10804        tcg_gen_orc_i32(t0, t0, t1);
10805        logic_cc = conds;
10806        break;
10807    case 4: /* eor */
10808        tcg_gen_xor_i32(t0, t0, t1);
10809        logic_cc = conds;
10810        break;
10811    case 8: /* add */
10812        if (conds)
10813            gen_add_CC(t0, t0, t1);
10814        else
10815            tcg_gen_add_i32(t0, t0, t1);
10816        break;
10817    case 10: /* adc */
10818        if (conds)
10819            gen_adc_CC(t0, t0, t1);
10820        else
10821            gen_adc(t0, t1);
10822        break;
10823    case 11: /* sbc */
10824        if (conds) {
10825            gen_sbc_CC(t0, t0, t1);
10826        } else {
10827            gen_sub_carry(t0, t0, t1);
10828        }
10829        break;
10830    case 13: /* sub */
10831        if (conds)
10832            gen_sub_CC(t0, t0, t1);
10833        else
10834            tcg_gen_sub_i32(t0, t0, t1);
10835        break;
10836    case 14: /* rsb */
10837        if (conds)
10838            gen_sub_CC(t0, t1, t0);
10839        else
10840            tcg_gen_sub_i32(t0, t1, t0);
10841        break;
10842    default: /* 5, 6, 7, 9, 12, 15. */
10843        return 1;
10844    }
10845    if (logic_cc) {
10846        gen_logic_CC(t0);
10847        if (shifter_out)
10848            gen_set_CF_bit31(t1);
10849    }
10850    return 0;
10851}
10852
10853/* Translate a 32-bit thumb instruction. */
10854static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10855{
10856    uint32_t imm, shift, offset;
10857    uint32_t rd, rn, rm, rs;
10858    TCGv_i32 tmp;
10859    TCGv_i32 tmp2;
10860    TCGv_i32 tmp3;
10861    TCGv_i32 addr;
10862    TCGv_i64 tmp64;
10863    int op;
10864    int shiftop;
10865    int conds;
10866    int logic_cc;
10867
10868    /*
10869     * ARMv6-M supports a limited subset of Thumb2 instructions.
10870     * Other Thumb1 architectures allow only 32-bit
10871     * combined BL/BLX prefix and suffix.
10872     */
10873    if (arm_dc_feature(s, ARM_FEATURE_M) &&
10874        !arm_dc_feature(s, ARM_FEATURE_V7)) {
10875        int i;
10876        bool found = false;
10877        static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10878                                               0xf3b08040 /* dsb */,
10879                                               0xf3b08050 /* dmb */,
10880                                               0xf3b08060 /* isb */,
10881                                               0xf3e08000 /* mrs */,
10882                                               0xf000d000 /* bl */};
10883        static const uint32_t armv6m_mask[] = {0xffe0d000,
10884                                               0xfff0d0f0,
10885                                               0xfff0d0f0,
10886                                               0xfff0d0f0,
10887                                               0xffe0d000,
10888                                               0xf800d000};
10889
10890        for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10891            if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10892                found = true;
10893                break;
10894            }
10895        }
10896        if (!found) {
10897            goto illegal_op;
10898        }
10899    } else if ((insn & 0xf800e800) != 0xf000e800)  {
10900        ARCH(6T2);
10901    }
10902
10903    rn = (insn >> 16) & 0xf;
10904    rs = (insn >> 12) & 0xf;
10905    rd = (insn >> 8) & 0xf;
10906    rm = insn & 0xf;
10907    switch ((insn >> 25) & 0xf) {
10908    case 0: case 1: case 2: case 3:
10909        /* 16-bit instructions.  Should never happen.  */
10910        abort();
10911    case 4:
10912        if (insn & (1 << 22)) {
10913            /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10914             * - load/store doubleword, load/store exclusive, ldacq/strel,
10915             *   table branch, TT.
10916             */
10917            if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10918                arm_dc_feature(s, ARM_FEATURE_V8)) {
10919                /* 0b1110_1001_0111_1111_1110_1001_0111_111
10920                 *  - SG (v8M only)
10921                 * The bulk of the behaviour for this instruction is implemented
10922                 * in v7m_handle_execute_nsc(), which deals with the insn when
10923                 * it is executed by a CPU in non-secure state from memory
10924                 * which is Secure & NonSecure-Callable.
10925                 * Here we only need to handle the remaining cases:
10926                 *  * in NS memory (including the "security extension not
10927                 *    implemented" case) : NOP
10928                 *  * in S memory but CPU already secure (clear IT bits)
10929                 * We know that the attribute for the memory this insn is
10930                 * in must match the current CPU state, because otherwise
10931                 * get_phys_addr_pmsav8 would have generated an exception.
10932                 */
10933                if (s->v8m_secure) {
10934                    /* Like the IT insn, we don't need to generate any code */
10935                    s->condexec_cond = 0;
10936                    s->condexec_mask = 0;
10937                }
10938            } else if (insn & 0x01200000) {
10939                /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10940                 *  - load/store dual (post-indexed)
10941                 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10942                 *  - load/store dual (literal and immediate)
10943                 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10944                 *  - load/store dual (pre-indexed)
10945                 */
10946                bool wback = extract32(insn, 21, 1);
10947
10948                if (rn == 15) {
10949                    if (insn & (1 << 21)) {
10950                        /* UNPREDICTABLE */
10951                        goto illegal_op;
10952                    }
10953                    addr = tcg_temp_new_i32();
10954                    tcg_gen_movi_i32(addr, s->pc & ~3);
10955                } else {
10956                    addr = load_reg(s, rn);
10957                }
10958                offset = (insn & 0xff) * 4;
10959                if ((insn & (1 << 23)) == 0) {
10960                    offset = -offset;
10961                }
10962
10963                if (s->v8m_stackcheck && rn == 13 && wback) {
10964                    /*
10965                     * Here 'addr' is the current SP; if offset is +ve we're
10966                     * moving SP up, else down. It is UNKNOWN whether the limit
10967                     * check triggers when SP starts below the limit and ends
10968                     * up above it; check whichever of the current and final
10969                     * SP is lower, so QEMU will trigger in that situation.
10970                     */
10971                    if ((int32_t)offset < 0) {
10972                        TCGv_i32 newsp = tcg_temp_new_i32();
10973
10974                        tcg_gen_addi_i32(newsp, addr, offset);
10975                        gen_helper_v8m_stackcheck(cpu_env, newsp);
10976                        tcg_temp_free_i32(newsp);
10977                    } else {
10978                        gen_helper_v8m_stackcheck(cpu_env, addr);
10979                    }
10980                }
10981
10982                if (insn & (1 << 24)) {
10983                    tcg_gen_addi_i32(addr, addr, offset);
10984                    offset = 0;
10985                }
10986                if (insn & (1 << 20)) {
10987                    /* ldrd */
10988                    tmp = tcg_temp_new_i32();
10989                    gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10990                    store_reg(s, rs, tmp);
10991                    tcg_gen_addi_i32(addr, addr, 4);
10992                    tmp = tcg_temp_new_i32();
10993                    gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10994                    store_reg(s, rd, tmp);
10995                } else {
10996                    /* strd */
10997                    tmp = load_reg(s, rs);
10998                    gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10999                    tcg_temp_free_i32(tmp);
11000                    tcg_gen_addi_i32(addr, addr, 4);
11001                    tmp = load_reg(s, rd);
11002                    gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11003                    tcg_temp_free_i32(tmp);
11004                }
11005                if (wback) {
11006                    /* Base writeback.  */
11007                    tcg_gen_addi_i32(addr, addr, offset - 4);
11008                    store_reg(s, rn, addr);
11009                } else {
11010                    tcg_temp_free_i32(addr);
11011                }
11012            } else if ((insn & (1 << 23)) == 0) {
11013                /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
11014                 * - load/store exclusive word
11015                 * - TT (v8M only)
11016                 */
11017                if (rs == 15) {
11018                    if (!(insn & (1 << 20)) &&
11019                        arm_dc_feature(s, ARM_FEATURE_M) &&
11020                        arm_dc_feature(s, ARM_FEATURE_V8)) {
11021                        /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
11022                         *  - TT (v8M only)
11023                         */
11024                        bool alt = insn & (1 << 7);
11025                        TCGv_i32 addr, op, ttresp;
11026
11027                        if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
11028                            /* we UNDEF for these UNPREDICTABLE cases */
11029                            goto illegal_op;
11030                        }
11031
11032                        if (alt && !s->v8m_secure) {
11033                            goto illegal_op;
11034                        }
11035
11036                        addr = load_reg(s, rn);
11037                        op = tcg_const_i32(extract32(insn, 6, 2));
11038                        ttresp = tcg_temp_new_i32();
11039                        gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
11040                        tcg_temp_free_i32(addr);
11041                        tcg_temp_free_i32(op);
11042                        store_reg(s, rd, ttresp);
11043                        break;
11044                    }
11045                    goto illegal_op;
11046                }
11047                addr = tcg_temp_local_new_i32();
11048                load_reg_var(s, addr, rn);
11049                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
11050                if (insn & (1 << 20)) {
11051                    gen_load_exclusive(s, rs, 15, addr, 2);
11052                } else {
11053                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
11054                }
11055                tcg_temp_free_i32(addr);
11056            } else if ((insn & (7 << 5)) == 0) {
11057                /* Table Branch.  */
11058                if (rn == 15) {
11059                    addr = tcg_temp_new_i32();
11060                    tcg_gen_movi_i32(addr, s->pc);
11061                } else {
11062                    addr = load_reg(s, rn);
11063                }
11064                tmp = load_reg(s, rm);
11065                tcg_gen_add_i32(addr, addr, tmp);
11066                if (insn & (1 << 4)) {
11067                    /* tbh */
11068                    tcg_gen_add_i32(addr, addr, tmp);
11069                    tcg_temp_free_i32(tmp);
11070                    tmp = tcg_temp_new_i32();
11071                    gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
11072                } else { /* tbb */
11073                    tcg_temp_free_i32(tmp);
11074                    tmp = tcg_temp_new_i32();
11075                    gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
11076                }
11077                tcg_temp_free_i32(addr);
11078                tcg_gen_shli_i32(tmp, tmp, 1);
11079                tcg_gen_addi_i32(tmp, tmp, s->pc);
11080                store_reg(s, 15, tmp);
11081            } else {
11082                bool is_lasr = false;
11083                bool is_ld = extract32(insn, 20, 1);
11084                int op2 = (insn >> 6) & 0x3;
11085                op = (insn >> 4) & 0x3;
11086                switch (op2) {
11087                case 0:
11088                    goto illegal_op;
11089                case 1:
11090                    /* Load/store exclusive byte/halfword/doubleword */
11091                    if (op == 2) {
11092                        goto illegal_op;
11093                    }
11094                    ARCH(7);
11095                    break;
11096                case 2:
11097                    /* Load-acquire/store-release */
11098                    if (op == 3) {
11099                        goto illegal_op;
11100                    }
11101                    /* Fall through */
11102                case 3:
11103                    /* Load-acquire/store-release exclusive */
11104                    ARCH(8);
11105                    is_lasr = true;
11106                    break;
11107                }
11108
11109                if (is_lasr && !is_ld) {
11110                    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
11111                }
11112
11113                addr = tcg_temp_local_new_i32();
11114                load_reg_var(s, addr, rn);
11115                if (!(op2 & 1)) {
11116                    if (is_ld) {
11117                        tmp = tcg_temp_new_i32();
11118                        switch (op) {
11119                        case 0: /* ldab */
11120                            gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
11121                                              rs | ISSIsAcqRel);
11122                            break;
11123                        case 1: /* ldah */
11124                            gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
11125                                               rs | ISSIsAcqRel);
11126                            break;
11127                        case 2: /* lda */
11128                            gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11129                                               rs | ISSIsAcqRel);
11130                            break;
11131                        default:
11132                            abort();
11133                        }
11134                        store_reg(s, rs, tmp);
11135                    } else {
11136                        tmp = load_reg(s, rs);
11137                        switch (op) {
11138                        case 0: /* stlb */
11139                            gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
11140                                             rs | ISSIsAcqRel);
11141                            break;
11142                        case 1: /* stlh */
11143                            gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
11144                                              rs | ISSIsAcqRel);
11145                            break;
11146                        case 2: /* stl */
11147                            gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
11148                                              rs | ISSIsAcqRel);
11149                            break;
11150                        default:
11151                            abort();
11152                        }
11153                        tcg_temp_free_i32(tmp);
11154                    }
11155                } else if (is_ld) {
11156                    gen_load_exclusive(s, rs, rd, addr, op);
11157                } else {
11158                    gen_store_exclusive(s, rm, rs, rd, addr, op);
11159                }
11160                tcg_temp_free_i32(addr);
11161
11162                if (is_lasr && is_ld) {
11163                    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
11164                }
11165            }
11166        } else {
11167            /* Load/store multiple, RFE, SRS.  */
11168            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
11169                /* RFE, SRS: not available in user mode or on M profile */
11170                if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11171                    goto illegal_op;
11172                }
11173                if (insn & (1 << 20)) {
11174                    /* rfe */
11175                    addr = load_reg(s, rn);
11176                    if ((insn & (1 << 24)) == 0)
11177                        tcg_gen_addi_i32(addr, addr, -8);
11178                    /* Load PC into tmp and CPSR into tmp2.  */
11179                    tmp = tcg_temp_new_i32();
11180                    gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11181                    tcg_gen_addi_i32(addr, addr, 4);
11182                    tmp2 = tcg_temp_new_i32();
11183                    gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
11184                    if (insn & (1 << 21)) {
11185                        /* Base writeback.  */
11186                        if (insn & (1 << 24)) {
11187                            tcg_gen_addi_i32(addr, addr, 4);
11188                        } else {
11189                            tcg_gen_addi_i32(addr, addr, -4);
11190                        }
11191                        store_reg(s, rn, addr);
11192                    } else {
11193                        tcg_temp_free_i32(addr);
11194                    }
11195                    gen_rfe(s, tmp, tmp2);
11196                } else {
11197                    /* srs */
11198                    gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
11199                            insn & (1 << 21));
11200                }
11201            } else {
11202                int i, loaded_base = 0;
11203                TCGv_i32 loaded_var;
11204                bool wback = extract32(insn, 21, 1);
11205                /* Load/store multiple.  */
11206                addr = load_reg(s, rn);
11207                offset = 0;
11208                for (i = 0; i < 16; i++) {
11209                    if (insn & (1 << i))
11210                        offset += 4;
11211                }
11212
11213                if (insn & (1 << 24)) {
11214                    tcg_gen_addi_i32(addr, addr, -offset);
11215                }
11216
11217                if (s->v8m_stackcheck && rn == 13 && wback) {
11218                    /*
11219                     * If the writeback is incrementing SP rather than
11220                     * decrementing it, and the initial SP is below the
11221                     * stack limit but the final written-back SP would
11222                     * be above, then then we must not perform any memory
11223                     * accesses, but it is IMPDEF whether we generate
11224                     * an exception. We choose to do so in this case.
11225                     * At this point 'addr' is the lowest address, so
11226                     * either the original SP (if incrementing) or our
11227                     * final SP (if decrementing), so that's what we check.
11228                     */
11229                    gen_helper_v8m_stackcheck(cpu_env, addr);
11230                }
11231
11232                loaded_var = NULL;
11233                for (i = 0; i < 16; i++) {
11234                    if ((insn & (1 << i)) == 0)
11235                        continue;
11236                    if (insn & (1 << 20)) {
11237                        /* Load.  */
11238                        tmp = tcg_temp_new_i32();
11239                        gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11240                        if (i == 15) {
11241                            gen_bx_excret(s, tmp);
11242                        } else if (i == rn) {
11243                            loaded_var = tmp;
11244                            loaded_base = 1;
11245                        } else {
11246                            store_reg(s, i, tmp);
11247                        }
11248                    } else {
11249                        /* Store.  */
11250                        tmp = load_reg(s, i);
11251                        gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11252                        tcg_temp_free_i32(tmp);
11253                    }
11254                    tcg_gen_addi_i32(addr, addr, 4);
11255                }
11256                if (loaded_base) {
11257                    store_reg(s, rn, loaded_var);
11258                }
11259                if (wback) {
11260                    /* Base register writeback.  */
11261                    if (insn & (1 << 24)) {
11262                        tcg_gen_addi_i32(addr, addr, -offset);
11263                    }
11264                    /* Fault if writeback register is in register list.  */
11265                    if (insn & (1 << rn))
11266                        goto illegal_op;
11267                    store_reg(s, rn, addr);
11268                } else {
11269                    tcg_temp_free_i32(addr);
11270                }
11271            }
11272        }
11273        break;
11274    case 5:
11275
11276        op = (insn >> 21) & 0xf;
11277        if (op == 6) {
11278            if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11279                goto illegal_op;
11280            }
11281            /* Halfword pack.  */
11282            tmp = load_reg(s, rn);
11283            tmp2 = load_reg(s, rm);
11284            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
11285            if (insn & (1 << 5)) {
11286                /* pkhtb */
11287                if (shift == 0)
11288                    shift = 31;
11289                tcg_gen_sari_i32(tmp2, tmp2, shift);
11290                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
11291                tcg_gen_ext16u_i32(tmp2, tmp2);
11292            } else {
11293                /* pkhbt */
11294                if (shift)
11295                    tcg_gen_shli_i32(tmp2, tmp2, shift);
11296                tcg_gen_ext16u_i32(tmp, tmp);
11297                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
11298            }
11299            tcg_gen_or_i32(tmp, tmp, tmp2);
11300            tcg_temp_free_i32(tmp2);
11301            store_reg(s, rd, tmp);
11302        } else {
11303            /* Data processing register constant shift.  */
11304            if (rn == 15) {
11305                tmp = tcg_temp_new_i32();
11306                tcg_gen_movi_i32(tmp, 0);
11307            } else {
11308                tmp = load_reg(s, rn);
11309            }
11310            tmp2 = load_reg(s, rm);
11311
11312            shiftop = (insn >> 4) & 3;
11313            shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11314            conds = (insn & (1 << 20)) != 0;
11315            logic_cc = (conds && thumb2_logic_op(op));
11316            gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
11317            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
11318                goto illegal_op;
11319            tcg_temp_free_i32(tmp2);
11320            if (rd == 13 &&
11321                ((op == 2 && rn == 15) ||
11322                 (op == 8 && rn == 13) ||
11323                 (op == 13 && rn == 13))) {
11324                /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
11325                store_sp_checked(s, tmp);
11326            } else if (rd != 15) {
11327                store_reg(s, rd, tmp);
11328            } else {
11329                tcg_temp_free_i32(tmp);
11330            }
11331        }
11332        break;
11333    case 13: /* Misc data processing.  */
11334        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
11335        if (op < 4 && (insn & 0xf000) != 0xf000)
11336            goto illegal_op;
11337        switch (op) {
11338        case 0: /* Register controlled shift.  */
11339            tmp = load_reg(s, rn);
11340            tmp2 = load_reg(s, rm);
11341            if ((insn & 0x70) != 0)
11342                goto illegal_op;
11343            /*
11344             * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
11345             *  - MOV, MOVS (register-shifted register), flagsetting
11346             */
11347            op = (insn >> 21) & 3;
11348            logic_cc = (insn & (1 << 20)) != 0;
11349            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
11350            if (logic_cc)
11351                gen_logic_CC(tmp);
11352            store_reg(s, rd, tmp);
11353            break;
11354        case 1: /* Sign/zero extend.  */
11355            op = (insn >> 20) & 7;
11356            switch (op) {
11357            case 0: /* SXTAH, SXTH */
11358            case 1: /* UXTAH, UXTH */
11359            case 4: /* SXTAB, SXTB */
11360            case 5: /* UXTAB, UXTB */
11361                break;
11362            case 2: /* SXTAB16, SXTB16 */
11363            case 3: /* UXTAB16, UXTB16 */
11364                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11365                    goto illegal_op;
11366                }
11367                break;
11368            default:
11369                goto illegal_op;
11370            }
11371            if (rn != 15) {
11372                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11373                    goto illegal_op;
11374                }
11375            }
11376            tmp = load_reg(s, rm);
11377            shift = (insn >> 4) & 3;
11378            /* ??? In many cases it's not necessary to do a
11379               rotate, a shift is sufficient.  */
11380            if (shift != 0)
11381                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
11382            op = (insn >> 20) & 7;
11383            switch (op) {
11384            case 0: gen_sxth(tmp);   break;
11385            case 1: gen_uxth(tmp);   break;
11386            case 2: gen_sxtb16(tmp); break;
11387            case 3: gen_uxtb16(tmp); break;
11388            case 4: gen_sxtb(tmp);   break;
11389            case 5: gen_uxtb(tmp);   break;
11390            default:
11391                g_assert_not_reached();
11392            }
11393            if (rn != 15) {
11394                tmp2 = load_reg(s, rn);
11395                if ((op >> 1) == 1) {
11396                    gen_add16(tmp, tmp2);
11397                } else {
11398                    tcg_gen_add_i32(tmp, tmp, tmp2);
11399                    tcg_temp_free_i32(tmp2);
11400                }
11401            }
11402            store_reg(s, rd, tmp);
11403            break;
11404        case 2: /* SIMD add/subtract.  */
11405            if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11406                goto illegal_op;
11407            }
11408            op = (insn >> 20) & 7;
11409            shift = (insn >> 4) & 7;
11410            if ((op & 3) == 3 || (shift & 3) == 3)
11411                goto illegal_op;
11412            tmp = load_reg(s, rn);
11413            tmp2 = load_reg(s, rm);
11414            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
11415            tcg_temp_free_i32(tmp2);
11416            store_reg(s, rd, tmp);
11417            break;
11418        case 3: /* Other data processing.  */
11419            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
11420            if (op < 4) {
11421                /* Saturating add/subtract.  */
11422                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11423                    goto illegal_op;
11424                }
11425                tmp = load_reg(s, rn);
11426                tmp2 = load_reg(s, rm);
11427                if (op & 1)
11428                    gen_helper_double_saturate(tmp, cpu_env, tmp);
11429                if (op & 2)
11430                    gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
11431                else
11432                    gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
11433                tcg_temp_free_i32(tmp2);
11434            } else {
11435                switch (op) {
11436                case 0x0a: /* rbit */
11437                case 0x08: /* rev */
11438                case 0x09: /* rev16 */
11439                case 0x0b: /* revsh */
11440                case 0x18: /* clz */
11441                    break;
11442                case 0x10: /* sel */
11443                    if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11444                        goto illegal_op;
11445                    }
11446                    break;
11447                case 0x20: /* crc32/crc32c */
11448                case 0x21:
11449                case 0x22:
11450                case 0x28:
11451                case 0x29:
11452                case 0x2a:
11453                    if (!dc_isar_feature(aa32_crc32, s)) {
11454                        goto illegal_op;
11455                    }
11456                    break;
11457                default:
11458                    goto illegal_op;
11459                }
11460                tmp = load_reg(s, rn);
11461                switch (op) {
11462                case 0x0a: /* rbit */
11463                    gen_helper_rbit(tmp, tmp);
11464                    break;
11465                case 0x08: /* rev */
11466                    tcg_gen_bswap32_i32(tmp, tmp);
11467                    break;
11468                case 0x09: /* rev16 */
11469                    gen_rev16(tmp);
11470                    break;
11471                case 0x0b: /* revsh */
11472                    gen_revsh(tmp);
11473                    break;
11474                case 0x10: /* sel */
11475                    tmp2 = load_reg(s, rm);
11476                    tmp3 = tcg_temp_new_i32();
11477                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
11478                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
11479                    tcg_temp_free_i32(tmp3);
11480                    tcg_temp_free_i32(tmp2);
11481                    break;
11482                case 0x18: /* clz */
11483                    tcg_gen_clzi_i32(tmp, tmp, 32);
11484                    break;
11485                case 0x20:
11486                case 0x21:
11487                case 0x22:
11488                case 0x28:
11489                case 0x29:
11490                case 0x2a:
11491                {
11492                    /* crc32/crc32c */
11493                    uint32_t sz = op & 0x3;
11494                    uint32_t c = op & 0x8;
11495
11496                    tmp2 = load_reg(s, rm);
11497                    if (sz == 0) {
11498                        tcg_gen_andi_i32(tmp2, tmp2, 0xff);
11499                    } else if (sz == 1) {
11500                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
11501                    }
11502                    tmp3 = tcg_const_i32(1 << sz);
11503                    if (c) {
11504                        gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
11505                    } else {
11506                        gen_helper_crc32(tmp, tmp, tmp2, tmp3);
11507                    }
11508                    tcg_temp_free_i32(tmp2);
11509                    tcg_temp_free_i32(tmp3);
11510                    break;
11511                }
11512                default:
11513                    g_assert_not_reached();
11514                }
11515            }
11516            store_reg(s, rd, tmp);
11517            break;
11518        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
11519            switch ((insn >> 20) & 7) {
11520            case 0: /* 32 x 32 -> 32 */
11521            case 7: /* Unsigned sum of absolute differences.  */
11522                break;
11523            case 1: /* 16 x 16 -> 32 */
11524            case 2: /* Dual multiply add.  */
11525            case 3: /* 32 * 16 -> 32msb */
11526            case 4: /* Dual multiply subtract.  */
11527            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11528                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11529                    goto illegal_op;
11530                }
11531                break;
11532            }
11533            op = (insn >> 4) & 0xf;
11534            tmp = load_reg(s, rn);
11535            tmp2 = load_reg(s, rm);
11536            switch ((insn >> 20) & 7) {
11537            case 0: /* 32 x 32 -> 32 */
11538                tcg_gen_mul_i32(tmp, tmp, tmp2);
11539                tcg_temp_free_i32(tmp2);
11540                if (rs != 15) {
11541                    tmp2 = load_reg(s, rs);
11542                    if (op)
11543                        tcg_gen_sub_i32(tmp, tmp2, tmp);
11544                    else
11545                        tcg_gen_add_i32(tmp, tmp, tmp2);
11546                    tcg_temp_free_i32(tmp2);
11547                }
11548                break;
11549            case 1: /* 16 x 16 -> 32 */
11550                gen_mulxy(tmp, tmp2, op & 2, op & 1);
11551                tcg_temp_free_i32(tmp2);
11552                if (rs != 15) {
11553                    tmp2 = load_reg(s, rs);
11554                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11555                    tcg_temp_free_i32(tmp2);
11556                }
11557                break;
11558            case 2: /* Dual multiply add.  */
11559            case 4: /* Dual multiply subtract.  */
11560                if (op)
11561                    gen_swap_half(tmp2);
11562                gen_smul_dual(tmp, tmp2);
11563                if (insn & (1 << 22)) {
11564                    /* This subtraction cannot overflow. */
11565                    tcg_gen_sub_i32(tmp, tmp, tmp2);
11566                } else {
11567                    /* This addition cannot overflow 32 bits;
11568                     * however it may overflow considered as a signed
11569                     * operation, in which case we must set the Q flag.
11570                     */
11571                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11572                }
11573                tcg_temp_free_i32(tmp2);
11574                if (rs != 15)
11575                  {
11576                    tmp2 = load_reg(s, rs);
11577                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11578                    tcg_temp_free_i32(tmp2);
11579                  }
11580                break;
11581            case 3: /* 32 * 16 -> 32msb */
11582                if (op)
11583                    tcg_gen_sari_i32(tmp2, tmp2, 16);
11584                else
11585                    gen_sxth(tmp2);
11586                tmp64 = gen_muls_i64_i32(tmp, tmp2);
11587                tcg_gen_shri_i64(tmp64, tmp64, 16);
11588                tmp = tcg_temp_new_i32();
11589                tcg_gen_extrl_i64_i32(tmp, tmp64);
11590                tcg_temp_free_i64(tmp64);
11591                if (rs != 15)
11592                  {
11593                    tmp2 = load_reg(s, rs);
11594                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11595                    tcg_temp_free_i32(tmp2);
11596                  }
11597                break;
11598            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11599                tmp64 = gen_muls_i64_i32(tmp, tmp2);
11600                if (rs != 15) {
11601                    tmp = load_reg(s, rs);
11602                    if (insn & (1 << 20)) {
11603                        tmp64 = gen_addq_msw(tmp64, tmp);
11604                    } else {
11605                        tmp64 = gen_subq_msw(tmp64, tmp);
11606                    }
11607                }
11608                if (insn & (1 << 4)) {
11609                    tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
11610                }
11611                tcg_gen_shri_i64(tmp64, tmp64, 32);
11612                tmp = tcg_temp_new_i32();
11613                tcg_gen_extrl_i64_i32(tmp, tmp64);
11614                tcg_temp_free_i64(tmp64);
11615                break;
11616            case 7: /* Unsigned sum of absolute differences.  */
11617                gen_helper_usad8(tmp, tmp, tmp2);
11618                tcg_temp_free_i32(tmp2);
11619                if (rs != 15) {
11620                    tmp2 = load_reg(s, rs);
11621                    tcg_gen_add_i32(tmp, tmp, tmp2);
11622                    tcg_temp_free_i32(tmp2);
11623                }
11624                break;
11625            }
11626            store_reg(s, rd, tmp);
11627            break;
11628        case 6: case 7: /* 64-bit multiply, Divide.  */
11629            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
11630            tmp = load_reg(s, rn);
11631            tmp2 = load_reg(s, rm);
11632            if ((op & 0x50) == 0x10) {
11633                /* sdiv, udiv */
11634                if (!dc_isar_feature(thumb_div, s)) {
11635                    goto illegal_op;
11636                }
11637                if (op & 0x20)
11638                    gen_helper_udiv(tmp, tmp, tmp2);
11639                else
11640                    gen_helper_sdiv(tmp, tmp, tmp2);
11641                tcg_temp_free_i32(tmp2);
11642                store_reg(s, rd, tmp);
11643            } else if ((op & 0xe) == 0xc) {
11644                /* Dual multiply accumulate long.  */
11645                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11646                    tcg_temp_free_i32(tmp);
11647                    tcg_temp_free_i32(tmp2);
11648                    goto illegal_op;
11649                }
11650                if (op & 1)
11651                    gen_swap_half(tmp2);
11652                gen_smul_dual(tmp, tmp2);
11653                if (op & 0x10) {
11654                    tcg_gen_sub_i32(tmp, tmp, tmp2);
11655                } else {
11656                    tcg_gen_add_i32(tmp, tmp, tmp2);
11657                }
11658                tcg_temp_free_i32(tmp2);
11659                /* BUGFIX */
11660                tmp64 = tcg_temp_new_i64();
11661                tcg_gen_ext_i32_i64(tmp64, tmp);
11662                tcg_temp_free_i32(tmp);
11663                gen_addq(s, tmp64, rs, rd);
11664                gen_storeq_reg(s, rs, rd, tmp64);
11665                tcg_temp_free_i64(tmp64);
11666            } else {
11667                if (op & 0x20) {
11668                    /* Unsigned 64-bit multiply  */
11669                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
11670                } else {
11671                    if (op & 8) {
11672                        /* smlalxy */
11673                        if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11674                            tcg_temp_free_i32(tmp2);
11675                            tcg_temp_free_i32(tmp);
11676                            goto illegal_op;
11677                        }
11678                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
11679                        tcg_temp_free_i32(tmp2);
11680                        tmp64 = tcg_temp_new_i64();
11681                        tcg_gen_ext_i32_i64(tmp64, tmp);
11682                        tcg_temp_free_i32(tmp);
11683                    } else {
11684                        /* Signed 64-bit multiply  */
11685                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
11686                    }
11687                }
11688                if (op & 4) {
11689                    /* umaal */
11690                    if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11691                        tcg_temp_free_i64(tmp64);
11692                        goto illegal_op;
11693                    }
11694                    gen_addq_lo(s, tmp64, rs);
11695                    gen_addq_lo(s, tmp64, rd);
11696                } else if (op & 0x40) {
11697                    /* 64-bit accumulate.  */
11698                    gen_addq(s, tmp64, rs, rd);
11699                }
11700                gen_storeq_reg(s, rs, rd, tmp64);
11701                tcg_temp_free_i64(tmp64);
11702            }
11703            break;
11704        }
11705        break;
11706    case 6: case 7: case 14: case 15:
11707        /* Coprocessor.  */
11708        if (arm_dc_feature(s, ARM_FEATURE_M)) {
11709            /* We don't currently implement M profile FP support,
11710             * so this entire space should give a NOCP fault, with
11711             * the exception of the v8M VLLDM and VLSTM insns, which
11712             * must be NOPs in Secure state and UNDEF in Nonsecure state.
11713             */
11714            if (arm_dc_feature(s, ARM_FEATURE_V8) &&
11715                (insn & 0xffa00f00) == 0xec200a00) {
11716                /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
11717                 *  - VLLDM, VLSTM
11718                 * We choose to UNDEF if the RAZ bits are non-zero.
11719                 */
11720                if (!s->v8m_secure || (insn & 0x0040f0ff)) {
11721                    goto illegal_op;
11722                }
11723                /* Just NOP since FP support is not implemented */
11724                break;
11725            }
11726            /* All other insns: NOCP */
11727            gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
11728                               default_exception_el(s));
11729            break;
11730        }
11731        if ((insn & 0xfe000a00) == 0xfc000800
11732            && arm_dc_feature(s, ARM_FEATURE_V8)) {
11733            /* The Thumb2 and ARM encodings are identical.  */
11734            if (disas_neon_insn_3same_ext(s, insn)) {
11735                goto illegal_op;
11736            }
11737        } else if ((insn & 0xff000a00) == 0xfe000800
11738                   && arm_dc_feature(s, ARM_FEATURE_V8)) {
11739            /* The Thumb2 and ARM encodings are identical.  */
11740            if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
11741                goto illegal_op;
11742            }
11743        } else if (((insn >> 24) & 3) == 3) {
11744            /* Translate into the equivalent ARM encoding.  */
11745            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
11746            if (disas_neon_data_insn(s, insn)) {
11747                goto illegal_op;
11748            }
11749        } else if (((insn >> 8) & 0xe) == 10) {
11750            if (disas_vfp_insn(s, insn)) {
11751                goto illegal_op;
11752            }
11753        } else {
11754            if (insn & (1 << 28))
11755                goto illegal_op;
11756            if (disas_coproc_insn(s, insn)) {
11757                goto illegal_op;
11758            }
11759        }
11760        break;
11761    case 8: case 9: case 10: case 11:
11762        if (insn & (1 << 15)) {
11763            /* Branches, misc control.  */
11764            if (insn & 0x5000) {
11765                /* Unconditional branch.  */
11766                /* signextend(hw1[10:0]) -> offset[:12].  */
11767                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
11768                /* hw1[10:0] -> offset[11:1].  */
11769                offset |= (insn & 0x7ff) << 1;
11770                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11771                   offset[24:22] already have the same value because of the
11772                   sign extension above.  */
11773                offset ^= ((~insn) & (1 << 13)) << 10;
11774                offset ^= ((~insn) & (1 << 11)) << 11;
11775
11776                if (insn & (1 << 14)) {
11777                    /* Branch and link.  */
11778                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
11779                }
11780
11781                offset += s->pc;
11782                if (insn & (1 << 12)) {
11783                    /* b/bl */
11784                    gen_jmp(s, offset);
11785                } else {
11786                    /* blx */
11787                    offset &= ~(uint32_t)2;
11788                    /* thumb2 bx, no need to check */
11789                    gen_bx_im(s, offset);
11790                }
11791            } else if (((insn >> 23) & 7) == 7) {
11792                /* Misc control */
11793                if (insn & (1 << 13))
11794                    goto illegal_op;
11795
11796                if (insn & (1 << 26)) {
11797                    if (arm_dc_feature(s, ARM_FEATURE_M)) {
11798                        goto illegal_op;
11799                    }
11800                    if (!(insn & (1 << 20))) {
11801                        /* Hypervisor call (v7) */
11802                        int imm16 = extract32(insn, 16, 4) << 12
11803                            | extract32(insn, 0, 12);
11804                        ARCH(7);
11805                        if (IS_USER(s)) {
11806                            goto illegal_op;
11807                        }
11808                        gen_hvc(s, imm16);
11809                    } else {
11810                        /* Secure monitor call (v6+) */
11811                        ARCH(6K);
11812                        if (IS_USER(s)) {
11813                            goto illegal_op;
11814                        }
11815                        gen_smc(s);
11816                    }
11817                } else {
11818                    op = (insn >> 20) & 7;
11819                    switch (op) {
11820                    case 0: /* msr cpsr.  */
11821                        if (arm_dc_feature(s, ARM_FEATURE_M)) {
11822                            tmp = load_reg(s, rn);
11823                            /* the constant is the mask and SYSm fields */
11824                            addr = tcg_const_i32(insn & 0xfff);
11825                            gen_helper_v7m_msr(cpu_env, addr, tmp);
11826                            tcg_temp_free_i32(addr);
11827                            tcg_temp_free_i32(tmp);
11828                            gen_lookup_tb(s);
11829                            break;
11830                        }
11831                        /* fall through */
11832                    case 1: /* msr spsr.  */
11833                        if (arm_dc_feature(s, ARM_FEATURE_M)) {
11834                            goto illegal_op;
11835                        }
11836
11837                        if (extract32(insn, 5, 1)) {
11838                            /* MSR (banked) */
11839                            int sysm = extract32(insn, 8, 4) |
11840                                (extract32(insn, 4, 1) << 4);
11841                            int r = op & 1;
11842
11843                            gen_msr_banked(s, r, sysm, rm);
11844                            break;
11845                        }
11846
11847                        /* MSR (for PSRs) */
11848                        tmp = load_reg(s, rn);
11849                        if (gen_set_psr(s,
11850                              msr_mask(s, (insn >> 8) & 0xf, op == 1),
11851                              op == 1, tmp))
11852                            goto illegal_op;
11853                        break;
11854                    case 2: /* cps, nop-hint.  */
11855                        if (((insn >> 8) & 7) == 0) {
11856                            gen_nop_hint(s, insn & 0xff);
11857                        }
11858                        /* Implemented as NOP in user mode.  */
11859                        if (IS_USER(s))
11860                            break;
11861                        offset = 0;
11862                        imm = 0;
11863                        if (insn & (1 << 10)) {
11864                            if (insn & (1 << 7))
11865                                offset |= CPSR_A;
11866                            if (insn & (1 << 6))
11867                                offset |= CPSR_I;
11868                            if (insn & (1 << 5))
11869                                offset |= CPSR_F;
11870                            if (insn & (1 << 9))
11871                                imm = CPSR_A | CPSR_I | CPSR_F;
11872                        }
11873                        if (insn & (1 << 8)) {
11874                            offset |= 0x1f;
11875                            imm |= (insn & 0x1f);
11876                        }
11877                        if (offset) {
11878                            gen_set_psr_im(s, offset, 0, imm);
11879                        }
11880                        break;
11881                    case 3: /* Special control operations.  */
11882                        if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
11883                            !arm_dc_feature(s, ARM_FEATURE_M)) {
11884                            goto illegal_op;
11885                        }
11886                        op = (insn >> 4) & 0xf;
11887                        switch (op) {
11888                        case 2: /* clrex */
11889                            gen_clrex(s);
11890                            break;
11891                        case 4: /* dsb */
11892                        case 5: /* dmb */
11893                            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11894                            break;
11895                        case 6: /* isb */
11896                            /* We need to break the TB after this insn
11897                             * to execute self-modifying code correctly
11898                             * and also to take any pending interrupts
11899                             * immediately.
11900                             */
11901                            gen_goto_tb(s, 0, s->pc & ~1);
11902                            break;
11903                        case 7: /* sb */
11904                            if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
11905                                goto illegal_op;
11906                            }
11907                            /*
11908                             * TODO: There is no speculation barrier opcode
11909                             * for TCG; MB and end the TB instead.
11910                             */
11911                            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11912                            gen_goto_tb(s, 0, s->pc & ~1);
11913                            break;
11914                        default:
11915                            goto illegal_op;
11916                        }
11917                        break;
11918                    case 4: /* bxj */
11919                        /* Trivial implementation equivalent to bx.
11920                         * This instruction doesn't exist at all for M-profile.
11921                         */
11922                        if (arm_dc_feature(s, ARM_FEATURE_M)) {
11923                            goto illegal_op;
11924                        }
11925                        tmp = load_reg(s, rn);
11926                        gen_bx(s, tmp);
11927                        break;
11928                    case 5: /* Exception return.  */
11929                        if (IS_USER(s)) {
11930                            goto illegal_op;
11931                        }
11932                        if (rn != 14 || rd != 15) {
11933                            goto illegal_op;
11934                        }
11935                        if (s->current_el == 2) {
11936                            /* ERET from Hyp uses ELR_Hyp, not LR */
11937                            if (insn & 0xff) {
11938                                goto illegal_op;
11939                            }
11940                            tmp = load_cpu_field(elr_el[2]);
11941                        } else {
11942                            tmp = load_reg(s, rn);
11943                            tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
11944                        }
11945                        gen_exception_return(s, tmp);
11946                        break;
11947                    case 6: /* MRS */
11948                        if (extract32(insn, 5, 1) &&
11949                            !arm_dc_feature(s, ARM_FEATURE_M)) {
11950                            /* MRS (banked) */
11951                            int sysm = extract32(insn, 16, 4) |
11952                                (extract32(insn, 4, 1) << 4);
11953
11954                            gen_mrs_banked(s, 0, sysm, rd);
11955                            break;
11956                        }
11957
11958                        if (extract32(insn, 16, 4) != 0xf) {
11959                            goto illegal_op;
11960                        }
11961                        if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11962                            extract32(insn, 0, 8) != 0) {
11963                            goto illegal_op;
11964                        }
11965
11966                        /* mrs cpsr */
11967                        tmp = tcg_temp_new_i32();
11968                        if (arm_dc_feature(s, ARM_FEATURE_M)) {
11969                            addr = tcg_const_i32(insn & 0xff);
11970                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
11971                            tcg_temp_free_i32(addr);
11972                        } else {
11973                            gen_helper_cpsr_read(tmp, cpu_env);
11974                        }
11975                        store_reg(s, rd, tmp);
11976                        break;
11977                    case 7: /* MRS */
11978                        if (extract32(insn, 5, 1) &&
11979                            !arm_dc_feature(s, ARM_FEATURE_M)) {
11980                            /* MRS (banked) */
11981                            int sysm = extract32(insn, 16, 4) |
11982                                (extract32(insn, 4, 1) << 4);
11983
11984                            gen_mrs_banked(s, 1, sysm, rd);
11985                            break;
11986                        }
11987
11988                        /* mrs spsr.  */
11989                        /* Not accessible in user mode.  */
11990                        if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11991                            goto illegal_op;
11992                        }
11993
11994                        if (extract32(insn, 16, 4) != 0xf ||
11995                            extract32(insn, 0, 8) != 0) {
11996                            goto illegal_op;
11997                        }
11998
11999                        tmp = load_cpu_field(spsr);
12000                        store_reg(s, rd, tmp);
12001                        break;
12002                    }
12003                }
12004            } else {
12005                /* Conditional branch.  */
12006                op = (insn >> 22) & 0xf;
12007                /* Generate a conditional jump to next instruction.  */
12008                arm_skip_unless(s, op);
12009
12010                /* offset[11:1] = insn[10:0] */
12011                offset = (insn & 0x7ff) << 1;
12012                /* offset[17:12] = insn[21:16].  */
12013                offset |= (insn & 0x003f0000) >> 4;
12014                /* offset[31:20] = insn[26].  */
12015                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
12016                /* offset[18] = insn[13].  */
12017                offset |= (insn & (1 << 13)) << 5;
12018                /* offset[19] = insn[11].  */
12019                offset |= (insn & (1 << 11)) << 8;
12020
12021                /* jump to the offset */
12022                gen_jmp(s, s->pc + offset);
12023            }
12024        } else {
12025            /*
12026             * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
12027             *  - Data-processing (modified immediate, plain binary immediate)
12028             */
12029            if (insn & (1 << 25)) {
12030                /*
12031                 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
12032                 *  - Data-processing (plain binary immediate)
12033                 */
12034                if (insn & (1 << 24)) {
12035                    if (insn & (1 << 20))
12036                        goto illegal_op;
12037                    /* Bitfield/Saturate.  */
12038                    op = (insn >> 21) & 7;
12039                    imm = insn & 0x1f;
12040                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
12041                    if (rn == 15) {
12042                        tmp = tcg_temp_new_i32();
12043                        tcg_gen_movi_i32(tmp, 0);
12044                    } else {
12045                        tmp = load_reg(s, rn);
12046                    }
12047                    switch (op) {
12048                    case 2: /* Signed bitfield extract.  */
12049                        imm++;
12050                        if (shift + imm > 32)
12051                            goto illegal_op;
12052                        if (imm < 32) {
12053                            tcg_gen_sextract_i32(tmp, tmp, shift, imm);
12054                        }
12055                        break;
12056                    case 6: /* Unsigned bitfield extract.  */
12057                        imm++;
12058                        if (shift + imm > 32)
12059                            goto illegal_op;
12060                        if (imm < 32) {
12061                            tcg_gen_extract_i32(tmp, tmp, shift, imm);
12062                        }
12063                        break;
12064                    case 3: /* Bitfield insert/clear.  */
12065                        if (imm < shift)
12066                            goto illegal_op;
12067                        imm = imm + 1 - shift;
12068                        if (imm != 32) {
12069                            tmp2 = load_reg(s, rd);
12070                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
12071                            tcg_temp_free_i32(tmp2);
12072                        }
12073                        break;
12074                    case 7:
12075                        goto illegal_op;
12076                    default: /* Saturate.  */
12077                        if (shift) {
12078                            if (op & 1)
12079                                tcg_gen_sari_i32(tmp, tmp, shift);
12080                            else
12081                                tcg_gen_shli_i32(tmp, tmp, shift);
12082                        }
12083                        tmp2 = tcg_const_i32(imm);
12084                        if (op & 4) {
12085                            /* Unsigned.  */
12086                            if ((op & 1) && shift == 0) {
12087                                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
12088                                    tcg_temp_free_i32(tmp);
12089                                    tcg_temp_free_i32(tmp2);
12090                                    goto illegal_op;
12091                                }
12092                                gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
12093                            } else {
12094                                gen_helper_usat(tmp, cpu_env, tmp, tmp2);
12095                            }
12096                        } else {
12097                            /* Signed.  */
12098                            if ((op & 1) && shift == 0) {
12099                                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
12100                                    tcg_temp_free_i32(tmp);
12101                                    tcg_temp_free_i32(tmp2);
12102                                    goto illegal_op;
12103                                }
12104                                gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
12105                            } else {
12106                                gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
12107                            }
12108                        }
12109                        tcg_temp_free_i32(tmp2);
12110                        break;
12111                    }
12112                    store_reg(s, rd, tmp);
12113                } else {
12114                    imm = ((insn & 0x04000000) >> 15)
12115                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
12116                    if (insn & (1 << 22)) {
12117                        /* 16-bit immediate.  */
12118                        imm |= (insn >> 4) & 0xf000;
12119                        if (insn & (1 << 23)) {
12120                            /* movt */
12121                            tmp = load_reg(s, rd);
12122                            tcg_gen_ext16u_i32(tmp, tmp);
12123                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
12124                        } else {
12125                            /* movw */
12126                            tmp = tcg_temp_new_i32();
12127                            tcg_gen_movi_i32(tmp, imm);
12128                        }
12129                        store_reg(s, rd, tmp);
12130                    } else {
12131                        /* Add/sub 12-bit immediate.  */
12132                        if (rn == 15) {
12133                            offset = s->pc & ~(uint32_t)3;
12134                            if (insn & (1 << 23))
12135                                offset -= imm;
12136                            else
12137                                offset += imm;
12138                            tmp = tcg_temp_new_i32();
12139                            tcg_gen_movi_i32(tmp, offset);
12140                            store_reg(s, rd, tmp);
12141                        } else {
12142                            tmp = load_reg(s, rn);
12143                            if (insn & (1 << 23))
12144                                tcg_gen_subi_i32(tmp, tmp, imm);
12145                            else
12146                                tcg_gen_addi_i32(tmp, tmp, imm);
12147                            if (rn == 13 && rd == 13) {
12148                                /* ADD SP, SP, imm or SUB SP, SP, imm */
12149                                store_sp_checked(s, tmp);
12150                            } else {
12151                                store_reg(s, rd, tmp);
12152                            }
12153                        }
12154                    }
12155                }
12156            } else {
12157                /*
12158                 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
12159                 *  - Data-processing (modified immediate)
12160                 */
12161                int shifter_out = 0;
12162                /* modified 12-bit immediate.  */
12163                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
12164                imm = (insn & 0xff);
12165                switch (shift) {
12166                case 0: /* XY */
12167                    /* Nothing to do.  */
12168                    break;
12169                case 1: /* 00XY00XY */
12170                    imm |= imm << 16;
12171                    break;
12172                case 2: /* XY00XY00 */
12173                    imm |= imm << 16;
12174                    imm <<= 8;
12175                    break;
12176                case 3: /* XYXYXYXY */
12177                    imm |= imm << 16;
12178                    imm |= imm << 8;
12179                    break;
12180                default: /* Rotated constant.  */
12181                    shift = (shift << 1) | (imm >> 7);
12182                    imm |= 0x80;
12183                    imm = imm << (32 - shift);
12184                    shifter_out = 1;
12185                    break;
12186                }
12187                tmp2 = tcg_temp_new_i32();
12188                tcg_gen_movi_i32(tmp2, imm);
12189                rn = (insn >> 16) & 0xf;
12190                if (rn == 15) {
12191                    tmp = tcg_temp_new_i32();
12192                    tcg_gen_movi_i32(tmp, 0);
12193                } else {
12194                    tmp = load_reg(s, rn);
12195                }
12196                op = (insn >> 21) & 0xf;
12197                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
12198                                       shifter_out, tmp, tmp2))
12199                    goto illegal_op;
12200                tcg_temp_free_i32(tmp2);
12201                rd = (insn >> 8) & 0xf;
12202                if (rd == 13 && rn == 13
12203                    && (op == 8 || op == 13)) {
12204                    /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
12205                    store_sp_checked(s, tmp);
12206                } else if (rd != 15) {
12207                    store_reg(s, rd, tmp);
12208                } else {
12209                    tcg_temp_free_i32(tmp);
12210                }
12211            }
12212        }
12213        break;
12214    case 12: /* Load/store single data item.  */
12215        {
12216        int postinc = 0;
12217        int writeback = 0;
12218        int memidx;
12219        ISSInfo issinfo;
12220
12221        if ((insn & 0x01100000) == 0x01000000) {
12222            if (disas_neon_ls_insn(s, insn)) {
12223                goto illegal_op;
12224            }
12225            break;
12226        }
12227        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
12228        if (rs == 15) {
12229            if (!(insn & (1 << 20))) {
12230                goto illegal_op;
12231            }
12232            if (op != 2) {
12233                /* Byte or halfword load space with dest == r15 : memory hints.
12234                 * Catch them early so we don't emit pointless addressing code.
12235                 * This space is a mix of:
12236                 *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike
12237                 *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
12238                 *     cores)
12239                 *  unallocated hints, which must be treated as NOPs
12240                 *  UNPREDICTABLE space, which we NOP or UNDEF depending on
12241                 *     which is easiest for the decoding logic
12242                 *  Some space which must UNDEF
12243                 */
12244                int op1 = (insn >> 23) & 3;
12245                int op2 = (insn >> 6) & 0x3f;
12246                if (op & 2) {
12247                    goto illegal_op;
12248                }
12249                if (rn == 15) {
12250                    /* UNPREDICTABLE, unallocated hint or
12251                     * PLD/PLDW/PLI (literal)
12252                     */
12253                    return;
12254                }
12255                if (op1 & 1) {
12256                    return; /* PLD/PLDW/PLI or unallocated hint */
12257                }
12258                if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
12259                    return; /* PLD/PLDW/PLI or unallocated hint */
12260                }
12261                /* UNDEF space, or an UNPREDICTABLE */
12262                goto illegal_op;
12263            }
12264        }
12265        memidx = get_mem_index(s);
12266        if (rn == 15) {
12267            addr = tcg_temp_new_i32();
12268            /* PC relative.  */
12269            /* s->pc has already been incremented by 4.  */
12270            imm = s->pc & 0xfffffffc;
12271            if (insn & (1 << 23))
12272                imm += insn & 0xfff;
12273            else
12274                imm -= insn & 0xfff;
12275            tcg_gen_movi_i32(addr, imm);
12276        } else {
12277            addr = load_reg(s, rn);
12278            if (insn & (1 << 23)) {
12279                /* Positive offset.  */
12280                imm = insn & 0xfff;
12281                tcg_gen_addi_i32(addr, addr, imm);
12282            } else {
12283                imm = insn & 0xff;
12284                switch ((insn >> 8) & 0xf) {
12285                case 0x0: /* Shifted Register.  */
12286                    shift = (insn >> 4) & 0xf;
12287                    if (shift > 3) {
12288                        tcg_temp_free_i32(addr);
12289                        goto illegal_op;
12290                    }
12291                    tmp = load_reg(s, rm);
12292                    if (shift)
12293                        tcg_gen_shli_i32(tmp, tmp, shift);
12294                    tcg_gen_add_i32(addr, addr, tmp);
12295                    tcg_temp_free_i32(tmp);
12296                    break;
12297                case 0xc: /* Negative offset.  */
12298                    tcg_gen_addi_i32(addr, addr, -imm);
12299                    break;
12300                case 0xe: /* User privilege.  */
12301                    tcg_gen_addi_i32(addr, addr, imm);
12302                    memidx = get_a32_user_mem_index(s);
12303                    break;
12304                case 0x9: /* Post-decrement.  */
12305                    imm = -imm;
12306                    /* Fall through.  */
12307                case 0xb: /* Post-increment.  */
12308                    postinc = 1;
12309                    writeback = 1;
12310                    break;
12311                case 0xd: /* Pre-decrement.  */
12312                    imm = -imm;
12313                    /* Fall through.  */
12314                case 0xf: /* Pre-increment.  */
12315                    writeback = 1;
12316                    break;
12317                default:
12318                    tcg_temp_free_i32(addr);
12319                    goto illegal_op;
12320                }
12321            }
12322        }
12323
12324        issinfo = writeback ? ISSInvalid : rs;
12325
12326        if (s->v8m_stackcheck && rn == 13 && writeback) {
12327            /*
12328             * Stackcheck. Here we know 'addr' is the current SP;
12329             * if imm is +ve we're moving SP up, else down. It is
12330             * UNKNOWN whether the limit check triggers when SP starts
12331             * below the limit and ends up above it; we chose to do so.
12332             */
12333            if ((int32_t)imm < 0) {
12334                TCGv_i32 newsp = tcg_temp_new_i32();
12335
12336                tcg_gen_addi_i32(newsp, addr, imm);
12337                gen_helper_v8m_stackcheck(cpu_env, newsp);
12338                tcg_temp_free_i32(newsp);
12339            } else {
12340                gen_helper_v8m_stackcheck(cpu_env, addr);
12341            }
12342        }
12343
12344        if (writeback && !postinc) {
12345            tcg_gen_addi_i32(addr, addr, imm);
12346        }
12347
12348        if (insn & (1 << 20)) {
12349            /* Load.  */
12350            tmp = tcg_temp_new_i32();
12351            switch (op) {
12352            case 0:
12353                gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
12354                break;
12355            case 4:
12356                gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
12357                break;
12358            case 1:
12359                gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
12360                break;
12361            case 5:
12362                gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
12363                break;
12364            case 2:
12365                gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
12366                break;
12367            default:
12368                tcg_temp_free_i32(tmp);
12369                tcg_temp_free_i32(addr);
12370                goto illegal_op;
12371            }
12372            if (rs == 15) {
12373                gen_bx_excret(s, tmp);
12374            } else {
12375                store_reg(s, rs, tmp);
12376            }
12377        } else {
12378            /* Store.  */
12379            tmp = load_reg(s, rs);
12380            switch (op) {
12381            case 0:
12382                gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
12383                break;
12384            case 1:
12385                gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
12386                break;
12387            case 2:
12388                gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
12389                break;
12390            default:
12391                tcg_temp_free_i32(tmp);
12392                tcg_temp_free_i32(addr);
12393                goto illegal_op;
12394            }
12395            tcg_temp_free_i32(tmp);
12396        }
12397        if (postinc)
12398            tcg_gen_addi_i32(addr, addr, imm);
12399        if (writeback) {
12400            store_reg(s, rn, addr);
12401        } else {
12402            tcg_temp_free_i32(addr);
12403        }
12404        }
12405        break;
12406    default:
12407        goto illegal_op;
12408    }
12409    return;
12410illegal_op:
12411    gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
12412                       default_exception_el(s));
12413}
12414
12415static void disas_thumb_insn(DisasContext *s, uint32_t insn)
12416{
12417    uint32_t val, op, rm, rn, rd, shift, cond;
12418    int32_t offset;
12419    int i;
12420    TCGv_i32 tmp;
12421    TCGv_i32 tmp2;
12422    TCGv_i32 addr;
12423
12424    switch (insn >> 12) {
12425    case 0: case 1:
12426
12427        rd = insn & 7;
12428        op = (insn >> 11) & 3;
12429        if (op == 3) {
12430            /*
12431             * 0b0001_1xxx_xxxx_xxxx
12432             *  - Add, subtract (three low registers)
12433             *  - Add, subtract (two low registers and immediate)
12434             */
12435            rn = (insn >> 3) & 7;
12436            tmp = load_reg(s, rn);
12437            if (insn & (1 << 10)) {
12438                /* immediate */
12439                tmp2 = tcg_temp_new_i32();
12440                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
12441            } else {
12442                /* reg */
12443                rm = (insn >> 6) & 7;
12444                tmp2 = load_reg(s, rm);
12445            }
12446            if (insn & (1 << 9)) {
12447                if (s->condexec_mask)
12448                    tcg_gen_sub_i32(tmp, tmp, tmp2);
12449                else
12450                    gen_sub_CC(tmp, tmp, tmp2);
12451            } else {
12452                if (s->condexec_mask)
12453                    tcg_gen_add_i32(tmp, tmp, tmp2);
12454                else
12455                    gen_add_CC(tmp, tmp, tmp2);
12456            }
12457            tcg_temp_free_i32(tmp2);
12458            store_reg(s, rd, tmp);
12459        } else {
12460            /* shift immediate */
12461            rm = (insn >> 3) & 7;
12462            shift = (insn >> 6) & 0x1f;
12463            tmp = load_reg(s, rm);
12464            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
12465            if (!s->condexec_mask)
12466                gen_logic_CC(tmp);
12467            store_reg(s, rd, tmp);
12468        }
12469        break;
12470    case 2: case 3:
12471        /*
12472         * 0b001x_xxxx_xxxx_xxxx
12473         *  - Add, subtract, compare, move (one low register and immediate)
12474         */
12475        op = (insn >> 11) & 3;
12476        rd = (insn >> 8) & 0x7;
12477        if (op == 0) { /* mov */
12478            tmp = tcg_temp_new_i32();
12479            tcg_gen_movi_i32(tmp, insn & 0xff);
12480            if (!s->condexec_mask)
12481                gen_logic_CC(tmp);
12482            store_reg(s, rd, tmp);
12483        } else {
12484            tmp = load_reg(s, rd);
12485            tmp2 = tcg_temp_new_i32();
12486            tcg_gen_movi_i32(tmp2, insn & 0xff);
12487            switch (op) {
12488            case 1: /* cmp */
12489                gen_sub_CC(tmp, tmp, tmp2);
12490                tcg_temp_free_i32(tmp);
12491                tcg_temp_free_i32(tmp2);
12492                break;
12493            case 2: /* add */
12494                if (s->condexec_mask)
12495                    tcg_gen_add_i32(tmp, tmp, tmp2);
12496                else
12497                    gen_add_CC(tmp, tmp, tmp2);
12498                tcg_temp_free_i32(tmp2);
12499                store_reg(s, rd, tmp);
12500                break;
12501            case 3: /* sub */
12502                if (s->condexec_mask)
12503                    tcg_gen_sub_i32(tmp, tmp, tmp2);
12504                else
12505                    gen_sub_CC(tmp, tmp, tmp2);
12506                tcg_temp_free_i32(tmp2);
12507                store_reg(s, rd, tmp);
12508                break;
12509            }
12510        }
12511        break;
12512    case 4:
12513        if (insn & (1 << 11)) {
12514            rd = (insn >> 8) & 7;
12515            /* load pc-relative.  Bit 1 of PC is ignored.  */
12516            val = s->pc + 2 + ((insn & 0xff) * 4);
12517            val &= ~(uint32_t)2;
12518            addr = tcg_temp_new_i32();
12519            tcg_gen_movi_i32(addr, val);
12520            tmp = tcg_temp_new_i32();
12521            gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
12522                               rd | ISSIs16Bit);
12523            tcg_temp_free_i32(addr);
12524            store_reg(s, rd, tmp);
12525            break;
12526        }
12527        if (insn & (1 << 10)) {
12528            /* 0b0100_01xx_xxxx_xxxx
12529             * - data processing extended, branch and exchange
12530             */
12531            rd = (insn & 7) | ((insn >> 4) & 8);
12532            rm = (insn >> 3) & 0xf;
12533            op = (insn >> 8) & 3;
12534            switch (op) {
12535            case 0: /* add */
12536                tmp = load_reg(s, rd);
12537                tmp2 = load_reg(s, rm);
12538                tcg_gen_add_i32(tmp, tmp, tmp2);
12539                tcg_temp_free_i32(tmp2);
12540                if (rd == 13) {
12541                    /* ADD SP, SP, reg */
12542                    store_sp_checked(s, tmp);
12543                } else {
12544                    store_reg(s, rd, tmp);
12545                }
12546                break;
12547            case 1: /* cmp */
12548                tmp = load_reg(s, rd);
12549                tmp2 = load_reg(s, rm);
12550                gen_sub_CC(tmp, tmp, tmp2);
12551                tcg_temp_free_i32(tmp2);
12552                tcg_temp_free_i32(tmp);
12553                break;
12554            case 2: /* mov/cpy */
12555                tmp = load_reg(s, rm);
12556                if (rd == 13) {
12557                    /* MOV SP, reg */
12558                    store_sp_checked(s, tmp);
12559                } else {
12560                    store_reg(s, rd, tmp);
12561                }
12562                break;
12563            case 3:
12564            {
12565                /* 0b0100_0111_xxxx_xxxx
12566                 * - branch [and link] exchange thumb register
12567                 */
12568                bool link = insn & (1 << 7);
12569
12570                if (insn & 3) {
12571                    goto undef;
12572                }
12573                if (link) {
12574                    ARCH(5);
12575                }
12576                if ((insn & 4)) {
12577                    /* BXNS/BLXNS: only exists for v8M with the
12578                     * security extensions, and always UNDEF if NonSecure.
12579                     * We don't implement these in the user-only mode
12580                     * either (in theory you can use them from Secure User
12581                     * mode but they are too tied in to system emulation.)
12582                     */
12583                    if (!s->v8m_secure || IS_USER_ONLY) {
12584                        goto undef;
12585                    }
12586                    if (link) {
12587                        gen_blxns(s, rm);
12588                    } else {
12589                        gen_bxns(s, rm);
12590                    }
12591                    break;
12592                }
12593                /* BLX/BX */
12594                tmp = load_reg(s, rm);
12595                if (link) {
12596                    val = (uint32_t)s->pc | 1;
12597                    tmp2 = tcg_temp_new_i32();
12598                    tcg_gen_movi_i32(tmp2, val);
12599                    store_reg(s, 14, tmp2);
12600                    gen_bx(s, tmp);
12601                } else {
12602                    /* Only BX works as exception-return, not BLX */
12603                    gen_bx_excret(s, tmp);
12604                }
12605                break;
12606            }
12607            }
12608            break;
12609        }
12610
12611        /*
12612         * 0b0100_00xx_xxxx_xxxx
12613         *  - Data-processing (two low registers)
12614         */
12615        rd = insn & 7;
12616        rm = (insn >> 3) & 7;
12617        op = (insn >> 6) & 0xf;
12618        if (op == 2 || op == 3 || op == 4 || op == 7) {
12619            /* the shift/rotate ops want the operands backwards */
12620            val = rm;
12621            rm = rd;
12622            rd = val;
12623            val = 1;
12624        } else {
12625            val = 0;
12626        }
12627
12628        if (op == 9) { /* neg */
12629            tmp = tcg_temp_new_i32();
12630            tcg_gen_movi_i32(tmp, 0);
12631        } else if (op != 0xf) { /* mvn doesn't read its first operand */
12632            tmp = load_reg(s, rd);
12633        } else {
12634            tmp = NULL;
12635        }
12636
12637        tmp2 = load_reg(s, rm);
12638        switch (op) {
12639        case 0x0: /* and */
12640            tcg_gen_and_i32(tmp, tmp, tmp2);
12641            if (!s->condexec_mask)
12642                gen_logic_CC(tmp);
12643            break;
12644        case 0x1: /* eor */
12645            tcg_gen_xor_i32(tmp, tmp, tmp2);
12646            if (!s->condexec_mask)
12647                gen_logic_CC(tmp);
12648            break;
12649        case 0x2: /* lsl */
12650            if (s->condexec_mask) {
12651                gen_shl(tmp2, tmp2, tmp);
12652            } else {
12653                gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
12654                gen_logic_CC(tmp2);
12655            }
12656            break;
12657        case 0x3: /* lsr */
12658            if (s->condexec_mask) {
12659                gen_shr(tmp2, tmp2, tmp);
12660            } else {
12661                gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
12662                gen_logic_CC(tmp2);
12663            }
12664            break;
12665        case 0x4: /* asr */
12666            if (s->condexec_mask) {
12667                gen_sar(tmp2, tmp2, tmp);
12668            } else {
12669                gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
12670                gen_logic_CC(tmp2);
12671            }
12672            break;
12673        case 0x5: /* adc */
12674            if (s->condexec_mask) {
12675                gen_adc(tmp, tmp2);
12676            } else {
12677                gen_adc_CC(tmp, tmp, tmp2);
12678            }
12679            break;
12680        case 0x6: /* sbc */
12681            if (s->condexec_mask) {
12682                gen_sub_carry(tmp, tmp, tmp2);
12683            } else {
12684                gen_sbc_CC(tmp, tmp, tmp2);
12685            }
12686            break;
12687        case 0x7: /* ror */
12688            if (s->condexec_mask) {
12689                tcg_gen_andi_i32(tmp, tmp, 0x1f);
12690                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
12691            } else {
12692                gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
12693                gen_logic_CC(tmp2);
12694            }
12695            break;
12696        case 0x8: /* tst */
12697            tcg_gen_and_i32(tmp, tmp, tmp2);
12698            gen_logic_CC(tmp);
12699            rd = 16;
12700            break;
12701        case 0x9: /* neg */
12702            if (s->condexec_mask)
12703                tcg_gen_neg_i32(tmp, tmp2);
12704            else
12705                gen_sub_CC(tmp, tmp, tmp2);
12706            break;
12707        case 0xa: /* cmp */
12708            gen_sub_CC(tmp, tmp, tmp2);
12709            rd = 16;
12710            break;
12711        case 0xb: /* cmn */
12712            gen_add_CC(tmp, tmp, tmp2);
12713            rd = 16;
12714            break;
12715        case 0xc: /* orr */
12716            tcg_gen_or_i32(tmp, tmp, tmp2);
12717            if (!s->condexec_mask)
12718                gen_logic_CC(tmp);
12719            break;
12720        case 0xd: /* mul */
12721            tcg_gen_mul_i32(tmp, tmp, tmp2);
12722            if (!s->condexec_mask)
12723                gen_logic_CC(tmp);
12724            break;
12725        case 0xe: /* bic */
12726            tcg_gen_andc_i32(tmp, tmp, tmp2);
12727            if (!s->condexec_mask)
12728                gen_logic_CC(tmp);
12729            break;
12730        case 0xf: /* mvn */
12731            tcg_gen_not_i32(tmp2, tmp2);
12732            if (!s->condexec_mask)
12733                gen_logic_CC(tmp2);
12734            val = 1;
12735            rm = rd;
12736            break;
12737        }
12738        if (rd != 16) {
12739            if (val) {
12740                store_reg(s, rm, tmp2);
12741                if (op != 0xf)
12742                    tcg_temp_free_i32(tmp);
12743            } else {
12744                store_reg(s, rd, tmp);
12745                tcg_temp_free_i32(tmp2);
12746            }
12747        } else {
12748            tcg_temp_free_i32(tmp);
12749            tcg_temp_free_i32(tmp2);
12750        }
12751        break;
12752
12753    case 5:
12754        /* load/store register offset.  */
12755        rd = insn & 7;
12756        rn = (insn >> 3) & 7;
12757        rm = (insn >> 6) & 7;
12758        op = (insn >> 9) & 7;
12759        addr = load_reg(s, rn);
12760        tmp = load_reg(s, rm);
12761        tcg_gen_add_i32(addr, addr, tmp);
12762        tcg_temp_free_i32(tmp);
12763
12764        if (op < 3) { /* store */
12765            tmp = load_reg(s, rd);
12766        } else {
12767            tmp = tcg_temp_new_i32();
12768        }
12769
12770        switch (op) {
12771        case 0: /* str */
12772            gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12773            break;
12774        case 1: /* strh */
12775            gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12776            break;
12777        case 2: /* strb */
12778            gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12779            break;
12780        case 3: /* ldrsb */
12781            gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12782            break;
12783        case 4: /* ldr */
12784            gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12785            break;
12786        case 5: /* ldrh */
12787            gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12788            break;
12789        case 6: /* ldrb */
12790            gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12791            break;
12792        case 7: /* ldrsh */
12793            gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12794            break;
12795        }
12796        if (op >= 3) { /* load */
12797            store_reg(s, rd, tmp);
12798        } else {
12799            tcg_temp_free_i32(tmp);
12800        }
12801        tcg_temp_free_i32(addr);
12802        break;
12803
12804    case 6:
12805        /* load/store word immediate offset */
12806        rd = insn & 7;
12807        rn = (insn >> 3) & 7;
12808        addr = load_reg(s, rn);
12809        val = (insn >> 4) & 0x7c;
12810        tcg_gen_addi_i32(addr, addr, val);
12811
12812        if (insn & (1 << 11)) {
12813            /* load */
12814            tmp = tcg_temp_new_i32();
12815            gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12816            store_reg(s, rd, tmp);
12817        } else {
12818            /* store */
12819            tmp = load_reg(s, rd);
12820            gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12821            tcg_temp_free_i32(tmp);
12822        }
12823        tcg_temp_free_i32(addr);
12824        break;
12825
12826    case 7:
12827        /* load/store byte immediate offset */
12828        rd = insn & 7;
12829        rn = (insn >> 3) & 7;
12830        addr = load_reg(s, rn);
12831        val = (insn >> 6) & 0x1f;
12832        tcg_gen_addi_i32(addr, addr, val);
12833
12834        if (insn & (1 << 11)) {
12835            /* load */
12836            tmp = tcg_temp_new_i32();
12837            gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12838            store_reg(s, rd, tmp);
12839        } else {
12840            /* store */
12841            tmp = load_reg(s, rd);
12842            gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12843            tcg_temp_free_i32(tmp);
12844        }
12845        tcg_temp_free_i32(addr);
12846        break;
12847
12848    case 8:
12849        /* load/store halfword immediate offset */
12850        rd = insn & 7;
12851        rn = (insn >> 3) & 7;
12852        addr = load_reg(s, rn);
12853        val = (insn >> 5) & 0x3e;
12854        tcg_gen_addi_i32(addr, addr, val);
12855
12856        if (insn & (1 << 11)) {
12857            /* load */
12858            tmp = tcg_temp_new_i32();
12859            gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12860            store_reg(s, rd, tmp);
12861        } else {
12862            /* store */
12863            tmp = load_reg(s, rd);
12864            gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12865            tcg_temp_free_i32(tmp);
12866        }
12867        tcg_temp_free_i32(addr);
12868        break;
12869
12870    case 9:
12871        /* load/store from stack */
12872        rd = (insn >> 8) & 7;
12873        addr = load_reg(s, 13);
12874        val = (insn & 0xff) * 4;
12875        tcg_gen_addi_i32(addr, addr, val);
12876
12877        if (insn & (1 << 11)) {
12878            /* load */
12879            tmp = tcg_temp_new_i32();
12880            gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12881            store_reg(s, rd, tmp);
12882        } else {
12883            /* store */
12884            tmp = load_reg(s, rd);
12885            gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12886            tcg_temp_free_i32(tmp);
12887        }
12888        tcg_temp_free_i32(addr);
12889        break;
12890
12891    case 10:
12892        /*
12893         * 0b1010_xxxx_xxxx_xxxx
12894         *  - Add PC/SP (immediate)
12895         */
12896        rd = (insn >> 8) & 7;
12897        if (insn & (1 << 11)) {
12898            /* SP */
12899            tmp = load_reg(s, 13);
12900        } else {
12901            /* PC. bit 1 is ignored.  */
12902            tmp = tcg_temp_new_i32();
12903            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
12904        }
12905        val = (insn & 0xff) * 4;
12906        tcg_gen_addi_i32(tmp, tmp, val);
12907        store_reg(s, rd, tmp);
12908        break;
12909
12910    case 11:
12911        /* misc */
12912        op = (insn >> 8) & 0xf;
12913        switch (op) {
12914        case 0:
12915            /*
12916             * 0b1011_0000_xxxx_xxxx
12917             *  - ADD (SP plus immediate)
12918             *  - SUB (SP minus immediate)
12919             */
12920            tmp = load_reg(s, 13);
12921            val = (insn & 0x7f) * 4;
12922            if (insn & (1 << 7))
12923                val = -(int32_t)val;
12924            tcg_gen_addi_i32(tmp, tmp, val);
12925            store_sp_checked(s, tmp);
12926            break;
12927
12928        case 2: /* sign/zero extend.  */
12929            ARCH(6);
12930            rd = insn & 7;
12931            rm = (insn >> 3) & 7;
12932            tmp = load_reg(s, rm);
12933            switch ((insn >> 6) & 3) {
12934            case 0: gen_sxth(tmp); break;
12935            case 1: gen_sxtb(tmp); break;
12936            case 2: gen_uxth(tmp); break;
12937            case 3: gen_uxtb(tmp); break;
12938            }
12939            store_reg(s, rd, tmp);
12940            break;
12941        case 4: case 5: case 0xc: case 0xd:
12942            /*
12943             * 0b1011_x10x_xxxx_xxxx
12944             *  - push/pop
12945             */
12946            addr = load_reg(s, 13);
12947            if (insn & (1 << 8))
12948                offset = 4;
12949            else
12950                offset = 0;
12951            for (i = 0; i < 8; i++) {
12952                if (insn & (1 << i))
12953                    offset += 4;
12954            }
12955            if ((insn & (1 << 11)) == 0) {
12956                tcg_gen_addi_i32(addr, addr, -offset);
12957            }
12958
12959            if (s->v8m_stackcheck) {
12960                /*
12961                 * Here 'addr' is the lower of "old SP" and "new SP";
12962                 * if this is a pop that starts below the limit and ends
12963                 * above it, it is UNKNOWN whether the limit check triggers;
12964                 * we choose to trigger.
12965                 */
12966                gen_helper_v8m_stackcheck(cpu_env, addr);
12967            }
12968
12969            for (i = 0; i < 8; i++) {
12970                if (insn & (1 << i)) {
12971                    if (insn & (1 << 11)) {
12972                        /* pop */
12973                        tmp = tcg_temp_new_i32();
12974                        gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12975                        store_reg(s, i, tmp);
12976                    } else {
12977                        /* push */
12978                        tmp = load_reg(s, i);
12979                        gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12980                        tcg_temp_free_i32(tmp);
12981                    }
12982                    /* advance to the next address.  */
12983                    tcg_gen_addi_i32(addr, addr, 4);
12984                }
12985            }
12986            tmp = NULL;
12987            if (insn & (1 << 8)) {
12988                if (insn & (1 << 11)) {
12989                    /* pop pc */
12990                    tmp = tcg_temp_new_i32();
12991                    gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12992                    /* don't set the pc until the rest of the instruction
12993                       has completed */
12994                } else {
12995                    /* push lr */
12996                    tmp = load_reg(s, 14);
12997                    gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12998                    tcg_temp_free_i32(tmp);
12999                }
13000                tcg_gen_addi_i32(addr, addr, 4);
13001            }
13002            if ((insn & (1 << 11)) == 0) {
13003                tcg_gen_addi_i32(addr, addr, -offset);
13004            }
13005            /* write back the new stack pointer */
13006            store_reg(s, 13, addr);
13007            /* set the new PC value */
13008            if ((insn & 0x0900) == 0x0900) {
13009                store_reg_from_load(s, 15, tmp);
13010            }
13011            break;
13012
13013        case 1: case 3: case 9: case 11: /* czb */
13014            rm = insn & 7;
13015            tmp = load_reg(s, rm);
13016            arm_gen_condlabel(s);
13017            if (insn & (1 << 11))
13018                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
13019            else
13020                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
13021            tcg_temp_free_i32(tmp);
13022            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
13023            val = (uint32_t)s->pc + 2;
13024            val += offset;
13025            gen_jmp(s, val);
13026            break;
13027
13028        case 15: /* IT, nop-hint.  */
13029            if ((insn & 0xf) == 0) {
13030                gen_nop_hint(s, (insn >> 4) & 0xf);
13031                break;
13032            }
13033            /* If Then.  */
13034            s->condexec_cond = (insn >> 4) & 0xe;
13035            s->condexec_mask = insn & 0x1f;
13036            /* No actual code generated for this insn, just setup state.  */
13037            break;
13038
13039        case 0xe: /* bkpt */
13040        {
13041            int imm8 = extract32(insn, 0, 8);
13042            ARCH(5);
13043            gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
13044            break;
13045        }
13046
13047        case 0xa: /* rev, and hlt */
13048        {
13049            int op1 = extract32(insn, 6, 2);
13050
13051            if (op1 == 2) {
13052                /* HLT */
13053                int imm6 = extract32(insn, 0, 6);
13054
13055                gen_hlt(s, imm6);
13056                break;
13057            }
13058
13059            /* Otherwise this is rev */
13060            ARCH(6);
13061            rn = (insn >> 3) & 0x7;
13062            rd = insn & 0x7;
13063            tmp = load_reg(s, rn);
13064            switch (op1) {
13065            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
13066            case 1: gen_rev16(tmp); break;
13067            case 3: gen_revsh(tmp); break;
13068            default:
13069                g_assert_not_reached();
13070            }
13071            store_reg(s, rd, tmp);
13072            break;
13073        }
13074
13075        case 6:
13076            switch ((insn >> 5) & 7) {
13077            case 2:
13078                /* setend */
13079                ARCH(6);
13080                if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
13081                    gen_helper_setend(cpu_env);
13082                    s->base.is_jmp = DISAS_UPDATE;
13083                }
13084                break;
13085            case 3:
13086                /* cps */
13087                ARCH(6);
13088                if (IS_USER(s)) {
13089                    break;
13090                }
13091                if (arm_dc_feature(s, ARM_FEATURE_M)) {
13092                    tmp = tcg_const_i32((insn & (1 << 4)) != 0);
13093                    /* FAULTMASK */
13094                    if (insn & 1) {
13095                        addr = tcg_const_i32(19);
13096                        gen_helper_v7m_msr(cpu_env, addr, tmp);
13097                        tcg_temp_free_i32(addr);
13098                    }
13099                    /* PRIMASK */
13100                    if (insn & 2) {
13101                        addr = tcg_const_i32(16);
13102                        gen_helper_v7m_msr(cpu_env, addr, tmp);
13103                        tcg_temp_free_i32(addr);
13104                    }
13105                    tcg_temp_free_i32(tmp);
13106                    gen_lookup_tb(s);
13107                } else {
13108                    if (insn & (1 << 4)) {
13109                        shift = CPSR_A | CPSR_I | CPSR_F;
13110                    } else {
13111                        shift = 0;
13112                    }
13113                    gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
13114                }
13115                break;
13116            default:
13117                goto undef;
13118            }
13119            break;
13120
13121        default:
13122            goto undef;
13123        }
13124        break;
13125
13126    case 12:
13127    {
13128        /* load/store multiple */
13129        TCGv_i32 loaded_var = NULL;
13130        rn = (insn >> 8) & 0x7;
13131        addr = load_reg(s, rn);
13132        for (i = 0; i < 8; i++) {
13133            if (insn & (1 << i)) {
13134                if (insn & (1 << 11)) {
13135                    /* load */
13136                    tmp = tcg_temp_new_i32();
13137                    gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
13138                    if (i == rn) {
13139                        loaded_var = tmp;
13140                    } else {
13141                        store_reg(s, i, tmp);
13142                    }
13143                } else {
13144                    /* store */
13145                    tmp = load_reg(s, i);
13146                    gen_aa32_st32(s, tmp, addr, get_mem_index(s));
13147                    tcg_temp_free_i32(tmp);
13148                }
13149                /* advance to the next address */
13150                tcg_gen_addi_i32(addr, addr, 4);
13151            }
13152        }
13153        if ((insn & (1 << rn)) == 0) {
13154            /* base reg not in list: base register writeback */
13155            store_reg(s, rn, addr);
13156        } else {
13157            /* base reg in list: if load, complete it now */
13158            if (insn & (1 << 11)) {
13159                store_reg(s, rn, loaded_var);
13160            }
13161            tcg_temp_free_i32(addr);
13162        }
13163        break;
13164    }
13165    case 13:
13166        /* conditional branch or swi */
13167        cond = (insn >> 8) & 0xf;
13168        if (cond == 0xe)
13169            goto undef;
13170
13171        if (cond == 0xf) {
13172            /* swi */
13173            gen_set_pc_im(s, s->pc);
13174            s->svc_imm = extract32(insn, 0, 8);
13175            s->base.is_jmp = DISAS_SWI;
13176            break;
13177        }
13178        /* generate a conditional jump to next instruction */
13179        arm_skip_unless(s, cond);
13180
13181        /* jump to the offset */
13182        val = (uint32_t)s->pc + 2;
13183        offset = ((int32_t)insn << 24) >> 24;
13184        val += offset << 1;
13185        gen_jmp(s, val);
13186        break;
13187
13188    case 14:
13189        if (insn & (1 << 11)) {
13190            /* thumb_insn_is_16bit() ensures we can't get here for
13191             * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
13192             * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
13193             */
13194            assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
13195            ARCH(5);
13196            offset = ((insn & 0x7ff) << 1);
13197            tmp = load_reg(s, 14);
13198            tcg_gen_addi_i32(tmp, tmp, offset);
13199            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
13200
13201            tmp2 = tcg_temp_new_i32();
13202            tcg_gen_movi_i32(tmp2, s->pc | 1);
13203            store_reg(s, 14, tmp2);
13204            gen_bx(s, tmp);
13205            break;
13206        }
13207        /* unconditional branch */
13208        val = (uint32_t)s->pc;
13209        offset = ((int32_t)insn << 21) >> 21;
13210        val += (offset << 1) + 2;
13211        gen_jmp(s, val);
13212        break;
13213
13214    case 15:
13215        /* thumb_insn_is_16bit() ensures we can't get here for
13216         * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
13217         */
13218        assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
13219
13220        if (insn & (1 << 11)) {
13221            /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
13222            offset = ((insn & 0x7ff) << 1) | 1;
13223            tmp = load_reg(s, 14);
13224            tcg_gen_addi_i32(tmp, tmp, offset);
13225
13226            tmp2 = tcg_temp_new_i32();
13227            tcg_gen_movi_i32(tmp2, s->pc | 1);
13228            store_reg(s, 14, tmp2);
13229            gen_bx(s, tmp);
13230        } else {
13231            /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
13232            uint32_t uoffset = ((int32_t)insn << 21) >> 9;
13233
13234            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
13235        }
13236        break;
13237    }
13238    return;
13239illegal_op:
13240undef:
13241    gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
13242                       default_exception_el(s));
13243}
13244
13245static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
13246{
13247    /* Return true if the insn at dc->pc might cross a page boundary.
13248     * (False positives are OK, false negatives are not.)
13249     * We know this is a Thumb insn, and our caller ensures we are
13250     * only called if dc->pc is less than 4 bytes from the page
13251     * boundary, so we cross the page if the first 16 bits indicate
13252     * that this is a 32 bit insn.
13253     */
13254    uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
13255
13256    return !thumb_insn_is_16bit(s, insn);
13257}
13258
13259static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
13260{
13261    DisasContext *dc = container_of(dcbase, DisasContext, base);
13262    CPUARMState *env = cs->env_ptr;
13263    ARMCPU *cpu = arm_env_get_cpu(env);
13264    uint32_t tb_flags = dc->base.tb->flags;
13265    uint32_t condexec, core_mmu_idx;
13266
13267    dc->isar = &cpu->isar;
13268    dc->pc = dc->base.pc_first;
13269    dc->condjmp = 0;
13270
13271    dc->aarch64 = 0;
13272    /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
13273     * there is no secure EL1, so we route exceptions to EL3.
13274     */
13275    dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
13276                               !arm_el_is_aa64(env, 3);
13277    dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
13278    dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
13279    dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
13280    condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
13281    dc->condexec_mask = (condexec & 0xf) << 1;
13282    dc->condexec_cond = condexec >> 4;
13283    core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
13284    dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
13285    dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
13286#if !defined(CONFIG_USER_ONLY)
13287    dc->user = (dc->current_el == 0);
13288#endif
13289    dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
13290    dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
13291    dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
13292    dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
13293    dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
13294    dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
13295    dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
13296    dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
13297        regime_is_secure(env, dc->mmu_idx);
13298    dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
13299    dc->cp_regs = cpu->cp_regs;
13300    dc->features = env->features;
13301
13302    /* Single step state. The code-generation logic here is:
13303     *  SS_ACTIVE == 0:
13304     *   generate code with no special handling for single-stepping (except
13305     *   that anything that can make us go to SS_ACTIVE == 1 must end the TB;
13306     *   this happens anyway because those changes are all system register or
13307     *   PSTATE writes).
13308     *  SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
13309     *   emit code for one insn
13310     *   emit code to clear PSTATE.SS
13311     *   emit code to generate software step exception for completed step
13312     *   end TB (as usual for having generated an exception)
13313     *  SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
13314     *   emit code to generate a software step exception
13315     *   end the TB
13316     */
13317    dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
13318    dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
13319    dc->is_ldex = false;
13320    dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
13321
13322    dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
13323
13324    /* If architectural single step active, limit to 1.  */
13325    if (is_singlestepping(dc)) {
13326        dc->base.max_insns = 1;
13327    }
13328
13329    /* ARM is a fixed-length ISA.  Bound the number of insns to execute
13330       to those left on the page.  */
13331    if (!dc->thumb) {
13332        int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
13333        dc->base.max_insns = MIN(dc->base.max_insns, bound);
13334    }
13335
13336    cpu_F0s = tcg_temp_new_i32();
13337    cpu_F1s = tcg_temp_new_i32();
13338    cpu_F0d = tcg_temp_new_i64();
13339    cpu_F1d = tcg_temp_new_i64();
13340    cpu_V0 = cpu_F0d;
13341    cpu_V1 = cpu_F1d;
13342    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
13343    cpu_M0 = tcg_temp_new_i64();
13344}
13345
13346static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
13347{
13348    DisasContext *dc = container_of(dcbase, DisasContext, base);
13349
13350    /* A note on handling of the condexec (IT) bits:
13351     *
13352     * We want to avoid the overhead of having to write the updated condexec
13353     * bits back to the CPUARMState for every instruction in an IT block. So:
13354     * (1) if the condexec bits are not already zero then we write
13355     * zero back into the CPUARMState now. This avoids complications trying
13356     * to do it at the end of the block. (For example if we don't do this
13357     * it's hard to identify whether we can safely skip writing condexec
13358     * at the end of the TB, which we definitely want to do for the case
13359     * where a TB doesn't do anything with the IT state at all.)
13360     * (2) if we are going to leave the TB then we call gen_set_condexec()
13361     * which will write the correct value into CPUARMState if zero is wrong.
13362     * This is done both for leaving the TB at the end, and for leaving
13363     * it because of an exception we know will happen, which is done in
13364     * gen_exception_insn(). The latter is necessary because we need to
13365     * leave the TB with the PC/IT state just prior to execution of the
13366     * instruction which caused the exception.
13367     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
13368     * then the CPUARMState will be wrong and we need to reset it.
13369     * This is handled in the same way as restoration of the
13370     * PC in these situations; we save the value of the condexec bits
13371     * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
13372     * then uses this to restore them after an exception.
13373     *
13374     * Note that there are no instructions which can read the condexec
13375     * bits, and none which can write non-static values to them, so
13376     * we don't need to care about whether CPUARMState is correct in the
13377     * middle of a TB.
13378     */
13379
13380    /* Reset the conditional execution bits immediately. This avoids
13381       complications trying to do it at the end of the block.  */
13382    if (dc->condexec_mask || dc->condexec_cond) {
13383        TCGv_i32 tmp = tcg_temp_new_i32();
13384        tcg_gen_movi_i32(tmp, 0);
13385        store_cpu_field(tmp, condexec_bits);
13386    }
13387}
13388
13389static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
13390{
13391    DisasContext *dc = container_of(dcbase, DisasContext, base);
13392
13393    tcg_gen_insn_start(dc->pc,
13394                       (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
13395                       0);
13396    dc->insn_start = tcg_last_op();
13397}
13398
13399static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
13400                                    const CPUBreakpoint *bp)
13401{
13402    DisasContext *dc = container_of(dcbase, DisasContext, base);
13403
13404    if (bp->flags & BP_CPU) {
13405        gen_set_condexec(dc);
13406        gen_set_pc_im(dc, dc->pc);
13407        gen_helper_check_breakpoints(cpu_env);
13408        /* End the TB early; it's likely not going to be executed */
13409        dc->base.is_jmp = DISAS_TOO_MANY;
13410    } else {
13411        gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
13412        /* The address covered by the breakpoint must be
13413           included in [tb->pc, tb->pc + tb->size) in order
13414           to for it to be properly cleared -- thus we
13415           increment the PC here so that the logic setting
13416           tb->size below does the right thing.  */
13417        /* TODO: Advance PC by correct instruction length to
13418         * avoid disassembler error messages */
13419        dc->pc += 2;
13420        dc->base.is_jmp = DISAS_NORETURN;
13421    }
13422
13423    return true;
13424}
13425
13426static bool arm_pre_translate_insn(DisasContext *dc)
13427{
13428#ifdef CONFIG_USER_ONLY
13429    /* Intercept jump to the magic kernel page.  */
13430    if (dc->pc >= 0xffff0000) {
13431        /* We always get here via a jump, so know we are not in a
13432           conditional execution block.  */
13433        gen_exception_internal(EXCP_KERNEL_TRAP);
13434        dc->base.is_jmp = DISAS_NORETURN;
13435        return true;
13436    }
13437#endif
13438
13439    if (dc->ss_active && !dc->pstate_ss) {
13440        /* Singlestep state is Active-pending.
13441         * If we're in this state at the start of a TB then either
13442         *  a) we just took an exception to an EL which is being debugged
13443         *     and this is the first insn in the exception handler
13444         *  b) debug exceptions were masked and we just unmasked them
13445         *     without changing EL (eg by clearing PSTATE.D)
13446         * In either case we're going to take a swstep exception in the
13447         * "did not step an insn" case, and so the syndrome ISV and EX
13448         * bits should be zero.
13449         */
13450        assert(dc->base.num_insns == 1);
13451        gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
13452                      default_exception_el(dc));
13453        dc->base.is_jmp = DISAS_NORETURN;
13454        return true;
13455    }
13456
13457    return false;
13458}
13459
13460static void arm_post_translate_insn(DisasContext *dc)
13461{
13462    if (dc->condjmp && !dc->base.is_jmp) {
13463        gen_set_label(dc->condlabel);
13464        dc->condjmp = 0;
13465    }
13466    dc->base.pc_next = dc->pc;
13467    translator_loop_temp_check(&dc->base);
13468}
13469
13470static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
13471{
13472    DisasContext *dc = container_of(dcbase, DisasContext, base);
13473    CPUARMState *env = cpu->env_ptr;
13474    unsigned int insn;
13475
13476    if (arm_pre_translate_insn(dc)) {
13477        return;
13478    }
13479
13480    insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
13481    dc->insn = insn;
13482    dc->pc += 4;
13483    disas_arm_insn(dc, insn);
13484
13485    arm_post_translate_insn(dc);
13486
13487    /* ARM is a fixed-length ISA.  We performed the cross-page check
13488       in init_disas_context by adjusting max_insns.  */
13489}
13490
13491static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
13492{
13493    /* Return true if this Thumb insn is always unconditional,
13494     * even inside an IT block. This is true of only a very few
13495     * instructions: BKPT, HLT, and SG.
13496     *
13497     * A larger class of instructions are UNPREDICTABLE if used
13498     * inside an IT block; we do not need to detect those here, because
13499     * what we do by default (perform the cc check and update the IT
13500     * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
13501     * choice for those situations.
13502     *
13503     * insn is either a 16-bit or a 32-bit instruction; the two are
13504     * distinguishable because for the 16-bit case the top 16 bits
13505     * are zeroes, and that isn't a valid 32-bit encoding.
13506     */
13507    if ((insn & 0xffffff00) == 0xbe00) {
13508        /* BKPT */
13509        return true;
13510    }
13511
13512    if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
13513        !arm_dc_feature(s, ARM_FEATURE_M)) {
13514        /* HLT: v8A only. This is unconditional even when it is going to
13515         * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
13516         * For v7 cores this was a plain old undefined encoding and so
13517         * honours its cc check. (We might be using the encoding as
13518         * a semihosting trap, but we don't change the cc check behaviour
13519         * on that account, because a debugger connected to a real v7A
13520         * core and emulating semihosting traps by catching the UNDEF
13521         * exception would also only see cases where the cc check passed.
13522         * No guest code should be trying to do a HLT semihosting trap
13523         * in an IT block anyway.
13524         */
13525        return true;
13526    }
13527
13528    if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
13529        arm_dc_feature(s, ARM_FEATURE_M)) {
13530        /* SG: v8M only */
13531        return true;
13532    }
13533
13534    return false;
13535}
13536
13537static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
13538{
13539    DisasContext *dc = container_of(dcbase, DisasContext, base);
13540    CPUARMState *env = cpu->env_ptr;
13541    uint32_t insn;
13542    bool is_16bit;
13543
13544    if (arm_pre_translate_insn(dc)) {
13545        return;
13546    }
13547
13548    insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
13549    is_16bit = thumb_insn_is_16bit(dc, insn);
13550    dc->pc += 2;
13551    if (!is_16bit) {
13552        uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
13553
13554        insn = insn << 16 | insn2;
13555        dc->pc += 2;
13556    }
13557    dc->insn = insn;
13558
13559    if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
13560        uint32_t cond = dc->condexec_cond;
13561
13562        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
13563            arm_skip_unless(dc, cond);
13564        }
13565    }
13566
13567    if (is_16bit) {
13568        disas_thumb_insn(dc, insn);
13569    } else {
13570        disas_thumb2_insn(dc, insn);
13571    }
13572
13573    /* Advance the Thumb condexec condition.  */
13574    if (dc->condexec_mask) {
13575        dc->condexec_cond = ((dc->condexec_cond & 0xe) |
13576                             ((dc->condexec_mask >> 4) & 1));
13577        dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
13578        if (dc->condexec_mask == 0) {
13579            dc->condexec_cond = 0;
13580        }
13581    }
13582
13583    arm_post_translate_insn(dc);
13584
13585    /* Thumb is a variable-length ISA.  Stop translation when the next insn
13586     * will touch a new page.  This ensures that prefetch aborts occur at
13587     * the right place.
13588     *
13589     * We want to stop the TB if the next insn starts in a new page,
13590     * or if it spans between this page and the next. This means that
13591     * if we're looking at the last halfword in the page we need to
13592     * see if it's a 16-bit Thumb insn (which will fit in this TB)
13593     * or a 32-bit Thumb insn (which won't).
13594     * This is to avoid generating a silly TB with a single 16-bit insn
13595     * in it at the end of this page (which would execute correctly
13596     * but isn't very efficient).
13597     */
13598    if (dc->base.is_jmp == DISAS_NEXT
13599        && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
13600            || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
13601                && insn_crosses_page(env, dc)))) {
13602        dc->base.is_jmp = DISAS_TOO_MANY;
13603    }
13604}
13605
13606static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
13607{
13608    DisasContext *dc = container_of(dcbase, DisasContext, base);
13609
13610    if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
13611        /* FIXME: This can theoretically happen with self-modifying code. */
13612        cpu_abort(cpu, "IO on conditional branch instruction");
13613    }
13614
13615    /* At this stage dc->condjmp will only be set when the skipped
13616       instruction was a conditional branch or trap, and the PC has
13617       already been written.  */
13618    gen_set_condexec(dc);
13619    if (dc->base.is_jmp == DISAS_BX_EXCRET) {
13620        /* Exception return branches need some special case code at the
13621         * end of the TB, which is complex enough that it has to
13622         * handle the single-step vs not and the condition-failed
13623         * insn codepath itself.
13624         */
13625        gen_bx_excret_final_code(dc);
13626    } else if (unlikely(is_singlestepping(dc))) {
13627        /* Unconditional and "condition passed" instruction codepath. */
13628        switch (dc->base.is_jmp) {
13629        case DISAS_SWI:
13630            gen_ss_advance(dc);
13631            gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13632                          default_exception_el(dc));
13633            break;
13634        case DISAS_HVC:
13635            gen_ss_advance(dc);
13636            gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13637            break;
13638        case DISAS_SMC:
13639            gen_ss_advance(dc);
13640            gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13641            break;
13642        case DISAS_NEXT:
13643        case DISAS_TOO_MANY:
13644        case DISAS_UPDATE:
13645            gen_set_pc_im(dc, dc->pc);
13646            /* fall through */
13647        default:
13648            /* FIXME: Single stepping a WFI insn will not halt the CPU. */
13649            gen_singlestep_exception(dc);
13650            break;
13651        case DISAS_NORETURN:
13652            break;
13653        }
13654    } else {
13655        /* While branches must always occur at the end of an IT block,
13656           there are a few other things that can cause us to terminate
13657           the TB in the middle of an IT block:
13658            - Exception generating instructions (bkpt, swi, undefined).
13659            - Page boundaries.
13660            - Hardware watchpoints.
13661           Hardware breakpoints have already been handled and skip this code.
13662         */
13663        switch(dc->base.is_jmp) {
13664        case DISAS_NEXT:
13665        case DISAS_TOO_MANY:
13666            gen_goto_tb(dc, 1, dc->pc);
13667            break;
13668        case DISAS_JUMP:
13669            gen_goto_ptr();
13670            break;
13671        case DISAS_UPDATE:
13672            gen_set_pc_im(dc, dc->pc);
13673            /* fall through */
13674        default:
13675            /* indicate that the hash table must be used to find the next TB */
13676            tcg_gen_exit_tb(NULL, 0);
13677            break;
13678        case DISAS_NORETURN:
13679            /* nothing more to generate */
13680            break;
13681        case DISAS_WFI:
13682        {
13683            TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
13684                                          !(dc->insn & (1U << 31))) ? 2 : 4);
13685
13686            gen_helper_wfi(cpu_env, tmp);
13687            tcg_temp_free_i32(tmp);
13688            /* The helper doesn't necessarily throw an exception, but we
13689             * must go back to the main loop to check for interrupts anyway.
13690             */
13691            tcg_gen_exit_tb(NULL, 0);
13692            break;
13693        }
13694        case DISAS_WFE:
13695            gen_helper_wfe(cpu_env);
13696            break;
13697        case DISAS_YIELD:
13698            gen_helper_yield(cpu_env);
13699            break;
13700        case DISAS_SWI:
13701            gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13702                          default_exception_el(dc));
13703            break;
13704        case DISAS_HVC:
13705            gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13706            break;
13707        case DISAS_SMC:
13708            gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13709            break;
13710        }
13711    }
13712
13713    if (dc->condjmp) {
13714        /* "Condition failed" instruction codepath for the branch/trap insn */
13715        gen_set_label(dc->condlabel);
13716        gen_set_condexec(dc);
13717        if (unlikely(is_singlestepping(dc))) {
13718            gen_set_pc_im(dc, dc->pc);
13719            gen_singlestep_exception(dc);
13720        } else {
13721            gen_goto_tb(dc, 1, dc->pc);
13722        }
13723    }
13724
13725    /* Functions above can change dc->pc, so re-align db->pc_next */
13726    dc->base.pc_next = dc->pc;
13727}
13728
13729static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
13730{
13731    DisasContext *dc = container_of(dcbase, DisasContext, base);
13732
13733    qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
13734    log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
13735}
13736
13737static const TranslatorOps arm_translator_ops = {
13738    .init_disas_context = arm_tr_init_disas_context,
13739    .tb_start           = arm_tr_tb_start,
13740    .insn_start         = arm_tr_insn_start,
13741    .breakpoint_check   = arm_tr_breakpoint_check,
13742    .translate_insn     = arm_tr_translate_insn,
13743    .tb_stop            = arm_tr_tb_stop,
13744    .disas_log          = arm_tr_disas_log,
13745};
13746
13747static const TranslatorOps thumb_translator_ops = {
13748    .init_disas_context = arm_tr_init_disas_context,
13749    .tb_start           = arm_tr_tb_start,
13750    .insn_start         = arm_tr_insn_start,
13751    .breakpoint_check   = arm_tr_breakpoint_check,
13752    .translate_insn     = thumb_tr_translate_insn,
13753    .tb_stop            = arm_tr_tb_stop,
13754    .disas_log          = arm_tr_disas_log,
13755};
13756
13757/* generate intermediate code for basic block 'tb'.  */
13758void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
13759{
13760    DisasContext dc;
13761    const TranslatorOps *ops = &arm_translator_ops;
13762
13763    if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
13764        ops = &thumb_translator_ops;
13765    }
13766#ifdef TARGET_AARCH64
13767    if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
13768        ops = &aarch64_translator_ops;
13769    }
13770#endif
13771
13772    translator_loop(ops, &dc.base, cpu, tb);
13773}
13774
13775void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
13776                        int flags)
13777{
13778    ARMCPU *cpu = ARM_CPU(cs);
13779    CPUARMState *env = &cpu->env;
13780    int i;
13781
13782    if (is_a64(env)) {
13783        aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
13784        return;
13785    }
13786
13787    for(i=0;i<16;i++) {
13788        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
13789        if ((i % 4) == 3)
13790            cpu_fprintf(f, "\n");
13791        else
13792            cpu_fprintf(f, " ");
13793    }
13794
13795    if (arm_feature(env, ARM_FEATURE_M)) {
13796        uint32_t xpsr = xpsr_read(env);
13797        const char *mode;
13798        const char *ns_status = "";
13799
13800        if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
13801            ns_status = env->v7m.secure ? "S " : "NS ";
13802        }
13803
13804        if (xpsr & XPSR_EXCP) {
13805            mode = "handler";
13806        } else {
13807            if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
13808                mode = "unpriv-thread";
13809            } else {
13810                mode = "priv-thread";
13811            }
13812        }
13813
13814        cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
13815                    xpsr,
13816                    xpsr & XPSR_N ? 'N' : '-',
13817                    xpsr & XPSR_Z ? 'Z' : '-',
13818                    xpsr & XPSR_C ? 'C' : '-',
13819                    xpsr & XPSR_V ? 'V' : '-',
13820                    xpsr & XPSR_T ? 'T' : 'A',
13821                    ns_status,
13822                    mode);
13823    } else {
13824        uint32_t psr = cpsr_read(env);
13825        const char *ns_status = "";
13826
13827        if (arm_feature(env, ARM_FEATURE_EL3) &&
13828            (psr & CPSR_M) != ARM_CPU_MODE_MON) {
13829            ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
13830        }
13831
13832        cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13833                    psr,
13834                    psr & CPSR_N ? 'N' : '-',
13835                    psr & CPSR_Z ? 'Z' : '-',
13836                    psr & CPSR_C ? 'C' : '-',
13837                    psr & CPSR_V ? 'V' : '-',
13838                    psr & CPSR_T ? 'T' : 'A',
13839                    ns_status,
13840                    aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
13841    }
13842
13843    if (flags & CPU_DUMP_FPU) {
13844        int numvfpregs = 0;
13845        if (arm_feature(env, ARM_FEATURE_VFP)) {
13846            numvfpregs += 16;
13847        }
13848        if (arm_feature(env, ARM_FEATURE_VFP3)) {
13849            numvfpregs += 16;
13850        }
13851        for (i = 0; i < numvfpregs; i++) {
13852            uint64_t v = *aa32_vfp_dreg(env, i);
13853            cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
13854                        i * 2, (uint32_t)v,
13855                        i * 2 + 1, (uint32_t)(v >> 32),
13856                        i, v);
13857        }
13858        cpu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env));
13859    }
13860}
13861
13862void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
13863                          target_ulong *data)
13864{
13865    if (is_a64(env)) {
13866        env->pc = data[0];
13867        env->condexec_bits = 0;
13868        env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13869    } else {
13870        env->regs[15] = data[0];
13871        env->condexec_bits = data[1];
13872        env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13873    }
13874}
13875